tx · 8icnVbJR6Fws6qEwH1XpXYhenGANTmaWS6a9fN6PDScv

3NC2gxrsMW5rEBsJCVMjJwBhcB3nnBrUG4f:  -0.01000000 Waves

2023.11.20 12:46 [2851546] smart account 3NC2gxrsMW5rEBsJCVMjJwBhcB3nnBrUG4f > SELF 0.00000000 Waves

{ "type": 13, "id": "8icnVbJR6Fws6qEwH1XpXYhenGANTmaWS6a9fN6PDScv", "fee": 1000000, "feeAssetId": null, "timestamp": 1700473628112, "version": 2, "chainId": 84, "sender": "3NC2gxrsMW5rEBsJCVMjJwBhcB3nnBrUG4f", "senderPublicKey": "E1AzspvmVgU66Pn9sgPQTc586F4eJ4nnWDadbPWyqqXN", "proofs": [ "nTvMUMyvXFraKF2RqGyXdC6uozC43n1BU7PBzeyanmsEtj3i7hK7AfLt4risXaJ5xUAxZzPkdHbCGBwGqmZbHuv" ], "script": null, "height": 2851546, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: A2rM6otoebBz8613pNXWwx6WGV7jsjspKmBNDar2z9NW Next: 9QHYnCp1MV4EcZZd9fZxFZhRfhA4LP1FukHWVCsGY3Pq Full:
OldNewDifferences
1-{-# STDLIB_VERSION 6 #-}
2-{-# SCRIPT_TYPE ACCOUNT #-}
3-{-# CONTENT_TYPE DAPP #-}
4-let SEP = "__"
5-
6-let WAVESID = base58'WAVES'
7-
8-let WAVESD = 100000000
9-
10-let GAME_NAME = "Card of the Day"
11-
12-let RANDOM_RANGE = 40
13-
14-let NUM_BETS = 1
15-
16-func getStrOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
17-
18-
19-func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
20-
21-
22-func getBoolOrFail (address,key) = valueOrErrorMessage(getBoolean(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
23-
24-
25-let allowedAssetsKey = "%s%s__cfg__allowedAssets"
26-
27-let assetsDecimalsKey = "%s%s__cfg__assetsDecimals"
28-
29-let betDividersKey = "%s%s__cfg__assetsBetDividers"
30-
31-let RSAPUBLIC64KEY = "%s%s__cfg__rsaPublic64"
32-
33-let SERVERADDRESSKEY = "%s%s__cfg__benzAddress"
34-
35-let RANDTIMEFRAMEKEY = "%s%s__cfg__withdrawTimeFrame"
36-
37-let GAMESCOUNTERKEY = "%s%s__runtime__gameNum"
38-
39-let blockedKey = "%s%s__runtime__contractIsBlocked"
40-
41-func getIntArray (key) = {
42- let a = getStrOrFail(this, key)
43- func filler (acc,el) = (acc :+ parseIntValue(el))
44-
45- let $l = split(a, SEP)
46- let $s = size($l)
47- let $acc0 = nil
48- func $f0_1 ($a,$i) = if (($i >= $s))
49- then $a
50- else filler($a, $l[$i])
51-
52- func $f0_2 ($a,$i) = if (($i >= $s))
53- then $a
54- else throw("List size exceeds 10")
55-
56- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
57- }
58-
59-
60-let ASSETS = split(getStrOrFail(this, allowedAssetsKey), SEP)
61-
62-let DECIMALS = getIntArray(assetsDecimalsKey)
63-
64-let BETDIVIDERS = getIntArray(betDividersKey)
65-
66-func keyReservationByAssetStr (assetStr) = ("$RESERVED_AMOUNT_" + assetStr)
67-
68-
69-func keyReservationByAssetIdx (assetIdx) = keyReservationByAssetStr(ASSETS[assetIdx])
70-
71-
72-let MINFEEWAVES = ((5 * WAVESD) / 1000)
73-
74-let idxAssets = 0
75-
76-let idxDecimals = 1
77-
78-let idxDividers = 2
79-
80-let BET1 = 1
81-
82-let BET2 = 2
83-
84-let BET4 = 4
85-
86-let BET8 = 8
87-
88-let BET14 = 14
89-
90-let RATEMULT = 10000
91-
92-let RATE = 100000
93-
94-let BETS = [BET2]
95-
96-let IdxGameState = 0
97-
98-let IdxPlayerChoice = 1
99-
100-let IdxPlayerPubKey58 = 2
101-
102-let IdxStartedHeight = 3
103-
104-let IdxWinAmount = 4
105-
106-let IdxAssetId = 5
107-
108-let STATESUBMITTED = "SUBMITTED"
109-
110-let STATEWON = "WON"
111-
112-let STATELOST = "LOST"
113-
114-func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), (key + " key is not specified in this.state"))
115-
116-
117-let RSAPUBLIC = fromBase64String(getStringOrFail(RSAPUBLIC64KEY))
118-
119-let SERVER = addressFromStringValue(getStringOrFail(SERVERADDRESSKEY))
120-
121-let RANDORACLETIMEFRAME = valueOrElse(getInteger(this, RANDTIMEFRAMEKEY), 7200)
122-
123-func getIntOr (key,default) = if (isDefined(getInteger(key)))
124- then getIntegerValue(key)
125- else default
126-
127-
128-func setInt (key,value) = IntegerEntry(key, value)
129-
130-
131-func incrementInt (key) = setInt(key, (getIntOr(key, -1) + 1))
132-
133-
134-func changeInt (key,by) = setInt(key, (getIntOr(key, 0) + by))
135-
136-
137-func assetIdToStr (assetIdOrUnit) = match assetIdOrUnit {
138- case b: ByteVector =>
139- toBase58String(b)
140- case _ =>
141- "WAVES"
142-}
143-
144-
145-func assetIdFromStr (assetIdStr) = if ((assetIdStr == "WAVES"))
146- then unit
147- else fromBase58String(assetIdStr)
148-
149-
150-func getAssetBalance (assetIdOrUnit) = match assetIdOrUnit {
151- case assetId: ByteVector =>
152- assetBalance(this, assetId)
153- case _ =>
154- wavesBalance(this).available
155-}
156-
157-
158-func increaseReserveAmount (winAmount,assetIdx) = {
159- let assetIdStr = ASSETS[assetIdx]
160- let newReservedAmount = (getIntOr(keyReservationByAssetIdx(assetIdx), 0) + winAmount)
161- if ((newReservedAmount > getAssetBalance(assetIdFromStr(assetIdStr))))
162- then throw((("Insufficient funds on " + GAME_NAME) + " account. Transaction was rejected for your safety."))
163- else newReservedAmount
164- }
165-
166-
167-func decreaseReservedAmount (gameId,assetIdx,winAmount) = if ((0 > (getIntOr(keyReservationByAssetIdx(assetIdx), 0) - winAmount)))
168- then throw((("Invalid " + GAME_NAME) + " account state - reserved amount is less than 0"))
169- else changeInt(keyReservationByAssetIdx(assetIdx), -(winAmount))
170-
171-
172-func validateAndGetAssetIdx (assetIdStr) = {
173- let idx = indexOf(ASSETS, assetIdStr)
174- if (!(isDefined(idx)))
175- then throw("Invalid payment asset")
176- else value(idx)
177- }
178-
179-
180-func validateBetAndGetWinAmount (bet,internalAssetIdx,playerChoice) = {
181- let dicesCount = size(playerChoice)
182- func checkAmount (a,x) = if (a)
183- then true
184- else (bet == ((x * DECIMALS[internalAssetIdx]) / BETDIVIDERS[internalAssetIdx]))
185-
186- if (!({
187- let $l = BETS
188- let $s = size($l)
189- let $acc0 = false
190- func $f0_1 ($a,$i) = if (($i >= $s))
191- then $a
192- else checkAmount($a, $l[$i])
193-
194- func $f0_2 ($a,$i) = if (($i >= $s))
195- then $a
196- else throw("List size exceeds 5")
197-
198- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
199- }))
200- then throw("Bet amount is not valid")
201- else if ((parseInt(playerChoice) == unit))
202- then throw("Invalid player's choice")
203- else if ((dicesCount != NUM_BETS))
204- then throw("Invalid length of player's choice")
205- else fraction(bet, RATE, RATEMULT)
206- }
207-
208-
209-func generateRandChoice (gameId,rsaSign,playerChoice) = {
210- let rsaSigValid = rsaVerify_16Kb(SHA256, toBytes(gameId), rsaSign, RSAPUBLIC)
211- if (!(rsaSigValid))
212- then throw("Invalid RSA signature")
213- else {
214- let rand = (toInt(sha256((rsaSign + toBytes(playerChoice)))) % RANDOM_RANGE)
215- toString(rand)
216- }
217- }
218-
219-
220-func isPlayerWin (playerChoice,randChoise) = if ((size(playerChoice) == NUM_BETS))
221- then (playerChoice == randChoise)
222- else false
223-
224-
225-func formatGameDataS (gameStatus,playerChoice,playerPubKey58,startedHeight,winAmount,assetIdx,randOrEmpty) = makeString([gameStatus, playerChoice, playerPubKey58, startedHeight, winAmount, assetIdx, if ((randOrEmpty == ""))
226- then ""
227- else randOrEmpty], "_")
228-
229-
230-func formatGameData (gameStatus,playerChoice,playerPubKey58,startedHeight,winAmount,assetIdx,randOrEmpty) = formatGameDataS(gameStatus, playerChoice, playerPubKey58, toString(startedHeight), toString(winAmount), toString(assetIdx), randOrEmpty)
231-
232-
233-func finishGameData (origGameData,gameStatus,rand,winByTimeout) = {
234- let finishGameData = formatGameDataS(gameStatus, origGameData[IdxPlayerChoice], origGameData[IdxPlayerPubKey58], origGameData[IdxStartedHeight], origGameData[IdxWinAmount], origGameData[IdxAssetId], rand)
235- if (winByTimeout)
236- then (finishGameData + "_TIMEOUT")
237- else finishGameData
238- }
239-
240-
241-func extractGameData (gameId) = split(match getString(this, gameId) {
242- case str: String =>
243- str
244- case _ =>
245- throw((("Game: " + gameId) + " not found."))
246-}, "_")
247-
248-
249-@Callable(i)
250-func constructorV1 (rsaPublic64,benzAddress,randOracleTimeFrame,tokensDescriptor) = if ((i.caller != SERVER))
251- then throw("not authorized")
252- else {
253- func splitter (acc,elem) = {
254- let tokList = split(elem, ":")
255- if ((size(tokList) != 4))
256- then throw("Invalid asset record")
257- else $Tuple3((acc._1 :+ tokList[idxAssets]), (acc._2 :+ tokList[idxDecimals]), (acc._3 :+ tokList[idxDividers]))
258- }
259-
260- let r = {
261- let $l = split_4C(tokensDescriptor, "_")
262- let $s = size($l)
263- let $acc0 = $Tuple3(nil, nil, nil)
264- func $f0_1 ($a,$i) = if (($i >= $s))
265- then $a
266- else splitter($a, $l[$i])
267-
268- func $f0_2 ($a,$i) = if (($i >= $s))
269- then $a
270- else throw("List size exceeds 10")
271-
272- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
273- }
274-[StringEntry(RSAPUBLIC64KEY, rsaPublic64), StringEntry(SERVERADDRESSKEY, benzAddress), IntegerEntry(RANDTIMEFRAMEKEY, randOracleTimeFrame), StringEntry(allowedAssetsKey, makeString_2C(r._1, SEP)), StringEntry(assetsDecimalsKey, makeString(r._2, SEP)), StringEntry(betDividersKey, makeString(r._3, SEP))]
275- }
276-
277-
278-
279-@Callable(i)
280-func maintenance (blocked) = if ((i.caller != SERVER))
281- then throw("not authorized")
282- else [BooleanEntry(blockedKey, blocked)]
283-
284-
285-
286-@Callable(i)
287-func bet (playerChoice) = if (valueOrElse(getBoolean(blockedKey), false))
288- then throw("Game is stopped for maintenence")
289- else {
290- let gameId = toBase58String(i.transactionId)
291- if ((1 >= size(i.payments)))
292- then throw("2 payments must be attached")
293- else if (isDefined(getString(this, gameId)))
294- then throw((("Bet for: " + gameId) + " was already made."))
295- else {
296- let betPmt = value(i.payments[0])
297- let feePmt = value(i.payments[1])
298- if (isDefined(feePmt.assetId))
299- then throw("feePmt (2nd payment) assetId must be in Waves")
300- else if ((MINFEEWAVES > feePmt.amount))
301- then throw("feePmt (2nd payment) must be >= 0.005 Waves")
302- else {
303- let assetIdStr = assetIdToStr(betPmt.assetId)
304- let internalAssetIdx = validateAndGetAssetIdx(assetIdStr)
305- let commission = feePmt.amount
306- let winAmount = validateBetAndGetWinAmount(betPmt.amount, internalAssetIdx, playerChoice)
307- let playerPubKey58 = toBase58String(i.callerPublicKey)
308- let gameData = formatGameData(STATESUBMITTED, playerChoice, playerPubKey58, height, winAmount, internalAssetIdx, "")
309-[IntegerEntry(keyReservationByAssetIdx(internalAssetIdx), increaseReserveAmount(winAmount, internalAssetIdx)), incrementInt(GAMESCOUNTERKEY), StringEntry(gameId, gameData), ScriptTransfer(SERVER, commission, feePmt.assetId)]
310- }
311- }
312- }
313-
314-
315-
316-@Callable(i)
317-func withdraw (gameId,rsaSign) = {
318- let gameData = extractGameData(gameId)
319- let gameState = gameData[IdxGameState]
320- let playerChoice = gameData[IdxPlayerChoice]
321- let startedHeight = parseIntValue(gameData[IdxStartedHeight])
322- let winAmount = parseIntValue(gameData[IdxWinAmount])
323- let assetIdx = parseIntValue(gameData[IdxAssetId])
324- let playerPubKey58 = gameData[IdxPlayerPubKey58]
325- let playerAddress = addressFromPublicKey(fromBase58String(playerPubKey58))
326- if ((gameState != STATESUBMITTED))
327- then throw("Invalid game state for passed gameId")
328- else if ((i.caller != SERVER))
329- then throw("Regular withdraw can be done by server only")
330- else {
331- let winByTimeout = ((height - startedHeight) > RANDORACLETIMEFRAME)
332- let randChoise = if (winByTimeout)
333- then playerChoice
334- else generateRandChoice(gameId, rsaSign, playerChoice)
335- let playerWin = isPlayerWin(playerChoice, randChoise)
336- let newGameStatus = if (playerWin)
337- then STATEWON
338- else STATELOST
339- let newGameData = finishGameData(gameData, newGameStatus, randChoise, winByTimeout)
340- ([StringEntry(gameId, newGameData), decreaseReservedAmount(gameId, assetIdx, winAmount)] ++ (if (playerWin)
341- then [ScriptTransfer(playerAddress, winAmount, assetIdFromStr(ASSETS[assetIdx]))]
342- else nil))
343- }
344- }
345-
346-
1+# no script

github/deemru/w8io/03bedc9 
82.16 ms