tx · EzkncbAfPAMFL7pHEye5HMDz51ASkLNDPprVp3SHupHH

3Mr1FdiZzG9iTQUtPmQEs1hBVbyQhG6LU93:  -0.01000000 Waves

2023.10.30 20:01 [2821645] smart account 3Mr1FdiZzG9iTQUtPmQEs1hBVbyQhG6LU93 > SELF 0.00000000 Waves

{ "type": 13, "id": "EzkncbAfPAMFL7pHEye5HMDz51ASkLNDPprVp3SHupHH", "fee": 1000000, "feeAssetId": null, "timestamp": 1698685315422, "version": 2, "chainId": 84, "sender": "3Mr1FdiZzG9iTQUtPmQEs1hBVbyQhG6LU93", "senderPublicKey": "De2GV53Brxd2GCQnLJWRugSidGtrVvPL9kJn2Dh4NTpJ", "proofs": [ "2B8kwLgDN3qPjwqWRKWVEFuqahwuUmrReM1ZCE6u7HnmYTQCkGZ6f51KFMMRFji7tLwbraJMniqyYqwwpYeaUWFa" ], "script": null, "height": 2821645, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 6ihkpsxMytTz4d8TyTBAxjQzBqDja3ZmrzvXgXKQGey2 Next: 7YL5FjnKr7H67npTjVz73YdDvaCXmd5jPgtviTggjT3Z Full:
OldNewDifferences
1-{-# STDLIB_VERSION 4 #-}
2-{-# SCRIPT_TYPE ACCOUNT #-}
3-{-# CONTENT_TYPE DAPP #-}
4-let WAVESD = 100000000
5-
6-let USDND = 1000000
7-
8-let EGGD = 100
9-
10-let DECIMALS = [WAVESD, USDND, EGGD]
11-
12-let ASSETS = [unit, fromBase58String("25FEqEjRkqK6yCkiT7Lz6SAYz7gUFCtxfCChnrVFD5AT"), fromBase58String("HsEwWuuQjUohrX26Fx8tg5eiL4LDD7um6jqNqFgERx6g")]
13-
14-let BETDIVIDERS = [1, 1, 10]
15-
16-let MINFEEWAVES = ((5 * WAVESD) / 1000)
17-
18-let BET1 = 1
19-
20-let BET2 = 2
21-
22-let BET4 = 4
23-
24-let BET8 = 8
25-
26-let BET14 = 14
27-
28-let RATEMULT = 10000
29-
30-let RATE1 = 39655
31-
32-let RATE2 = 24600
33-
34-let RATE3 = 19000
35-
36-let RATE4 = 14200
37-
38-let RATE5 = 11400
39-
40-let RATES = [RATE1, RATE2, RATE3, RATE4, RATE5]
41-
42-let BETS = [BET1, BET2, BET4, BET8, BET14]
43-
44-let IdxGameState = 0
45-
46-let IdxPlayerChoice = 1
47-
48-let IdxPlayerPubKey58 = 2
49-
50-let IdxStartedHeight = 3
51-
52-let IdxWinAmount = 4
53-
54-let IdxAssetId = 5
55-
56-let RESERVATIONKEY = ["$RESERVED_AMOUNT_WAVES", "$RESERVED_AMOUNT_USDN", "$RESERVED_AMOUNT_EGG"]
57-
58-let GAMESCOUNTERKEY = "$GAME_NUM"
59-
60-let RSAPUBLIC64KEY = "$RSA_PUBLIC64"
61-
62-let SERVERADDRESSKEY = "$BENZ_ADDRESS"
63-
64-let RANDTIMEFRAMEKEY = "$RAND_ORACLE_TIMEFRAME"
65-
66-let STATESUBMITTED = "SUBMITTED"
67-
68-let STATEWON = "WON"
69-
70-let STATELOST = "LOST"
71-
72-func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), (key + " key is not specified in this.state"))
73-
74-
75-let RSAPUBLIC = fromBase64String(getStringOrFail(RSAPUBLIC64KEY))
76-
77-let SERVER = addressFromStringValue(getStringOrFail(SERVERADDRESSKEY))
78-
79-let RANDORACLETIMEFRAME = valueOrElse(getInteger(this, RANDTIMEFRAMEKEY), 7200)
80-
81-func getIntOr (key,default) = if (isDefined(getInteger(this, key)))
82- then getIntegerValue(this, key)
83- else default
84-
85-
86-func setInt (key,value) = IntegerEntry(key, value)
87-
88-
89-func incrementInt (key) = setInt(key, (getIntOr(key, -1) + 1))
90-
91-
92-func changeInt (key,by) = setInt(key, (getIntOr(key, 0) + by))
93-
94-
95-func getAssetBalance (assetIdOrUnit) = match assetIdOrUnit {
96- case assetId: ByteVector =>
97- assetBalance(this, assetId)
98- case _ =>
99- wavesBalance(this).available
100-}
101-
102-
103-func increaseReserveAmount (winAmount,assetId) = {
104- let newReservedAmount = (getIntOr(RESERVATIONKEY[assetId], 0) + winAmount)
105- if ((newReservedAmount > getAssetBalance(ASSETS[assetId])))
106- then throw("Insufficient funds on Dice Roller account. Transaction was rejected for your safety.")
107- else newReservedAmount
108- }
109-
110-
111-func decreaseReservedAmount (gameId,assetId,winAmount) = if ((0 > (getIntOr(RESERVATIONKEY[assetId], 0) - winAmount)))
112- then throw("Invalid Dice Roller account state - reserved amount is less than 0")
113- else changeInt(RESERVATIONKEY[assetId], -(winAmount))
114-
115-
116-func validateAndGetAssetId (assetId) = if ((assetId == ASSETS[0]))
117- then 0
118- else if ((assetId == ASSETS[1]))
119- then 1
120- else if ((assetId == ASSETS[2]))
121- then 2
122- else throw("Invalid payment asset")
123-
124-
125-func validateBetAndGetWinAmount (bet,internalAssetId,playerChoice) = {
126- let dicesCount = size(playerChoice)
127- func checkAmount (a,x) = if (a)
128- then true
129- else (bet == ((x * DECIMALS[internalAssetId]) / BETDIVIDERS[internalAssetId]))
130-
131- if (!({
132- let $l = BETS
133- let $s = size($l)
134- let $acc0 = false
135- func 1 ($a,$i) = if (($i >= $s))
136- then $a
137- else checkAmount($a, $l[$i])
138-
139- func 2 ($a,$i) = if (($i >= $s))
140- then $a
141- else throw("List size exceeds 5")
142-
143- 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5)
144- }))
145- then throw("Bet amount is not valid")
146- else if ((parseInt(playerChoice) == unit))
147- then throw("Invalid player's choice")
148- else if (if ((1 > dicesCount))
149- then true
150- else (dicesCount > 5))
151- then throw("Invalid dices count in player's choice")
152- else ((bet * RATES[(dicesCount - 1)]) / RATEMULT)
153- }
154-
155-
156-func generateRandChoise (gameId,rsaSign) = {
157- let rsaSigValid = rsaVerify_16Kb(SHA256, toBytes(gameId), rsaSign, RSAPUBLIC)
158- if (!(rsaSigValid))
159- then throw("Invalid RSA signature")
160- else {
161- let rand = (toInt(sha256(rsaSign)) % 6)
162- let result = if ((0 > rand))
163- then (-1 * rand)
164- else rand
165- toString((result + 1))
166- }
167- }
168-
169-
170-func isPlayerWin (playerChoice,randChoise) = {
171- let s = size(playerChoice)
172- func check (a,x) = if (a)
173- then true
174- else if ((s >= x))
175- then (take(drop(playerChoice, (x - 1)), 1) == randChoise)
176- else false
177-
178- let $l = [1, 2, 3, 4, 5]
179- let $s = size($l)
180- let $acc0 = false
181- func 1 ($a,$i) = if (($i >= $s))
182- then $a
183- else check($a, $l[$i])
184-
185- func 2 ($a,$i) = if (($i >= $s))
186- then $a
187- else throw("List size exceeds 5")
188-
189- 2(1(1(1(1(1($acc0, 0), 1), 2), 3), 4), 5)
190- }
191-
192-
193-func formatGameDataS (gameStatus,playerChoice,playerPubKey58,startedHeight,winAmount,assetId,randOrEmpty) = makeString([gameStatus, playerChoice, playerPubKey58, startedHeight, winAmount, assetId, if ((randOrEmpty == ""))
194- then ""
195- else randOrEmpty], "_")
196-
197-
198-func formatGameData (gameStatus,playerChoice,playerPubKey58,startedHeight,winAmount,assetId,randOrEmpty) = formatGameDataS(gameStatus, playerChoice, playerPubKey58, toString(startedHeight), toString(winAmount), toString(assetId), randOrEmpty)
199-
200-
201-func finishGameData (origGameData,gameStatus,rand,winByTimeout) = {
202- let finishGameData = formatGameDataS(gameStatus, origGameData[IdxPlayerChoice], origGameData[IdxPlayerPubKey58], origGameData[IdxStartedHeight], origGameData[IdxWinAmount], origGameData[IdxAssetId], rand)
203- if (winByTimeout)
204- then (finishGameData + "_TIMEOUT")
205- else finishGameData
206- }
207-
208-
209-func extractGameData (gameId) = split(match getString(this, gameId) {
210- case str: String =>
211- str
212- case _ =>
213- throw((("Game: " + gameId) + " not found."))
214-}, "_")
215-
216-
217-@Callable(i)
218-func constructor (rsaPublic64,benzAddress,randOracleTimeFrame) = if ((addressFromPublicKey(i.callerPublicKey) != this))
219- then throw("not authorized")
220- else [StringEntry(RSAPUBLIC64KEY, rsaPublic64), StringEntry(SERVERADDRESSKEY, benzAddress), IntegerEntry(RANDTIMEFRAMEKEY, randOracleTimeFrame)]
221-
222-
223-
224-@Callable(i)
225-func bet (playerChoice) = {
226- let gameId = toBase58String(i.transactionId)
227- if ((1 >= size(i.payments)))
228- then throw("2 payments must be attached")
229- else if (isDefined(getString(this, gameId)))
230- then throw((("Bet for: " + gameId) + " was already made."))
231- else {
232- let betPmt = value(i.payments[0])
233- let feePmt = value(i.payments[1])
234- if (isDefined(feePmt.assetId))
235- then throw("feePmt (2nd payment) assetId must be in Waves")
236- else if ((MINFEEWAVES > feePmt.amount))
237- then throw("feePmt (2nd payment) must be >= 0.005 Waves")
238- else {
239- let internalAssetId = validateAndGetAssetId(betPmt.assetId)
240- let commission = feePmt.amount
241- let winAmount = validateBetAndGetWinAmount(betPmt.amount, internalAssetId, playerChoice)
242- let playerPubKey58 = toBase58String(i.callerPublicKey)
243- let gameData = formatGameData(STATESUBMITTED, playerChoice, playerPubKey58, height, winAmount, internalAssetId, "")
244-[IntegerEntry(RESERVATIONKEY[internalAssetId], increaseReserveAmount(winAmount, internalAssetId)), incrementInt(GAMESCOUNTERKEY), StringEntry(gameId, gameData), ScriptTransfer(SERVER, commission, feePmt.assetId)]
245- }
246- }
247- }
248-
249-
250-
251-@Callable(i)
252-func withdraw (gameId,rsaSign) = {
253- let gameData = extractGameData(gameId)
254- let gameState = gameData[IdxGameState]
255- let playerChoice = gameData[IdxPlayerChoice]
256- let startedHeight = parseIntValue(gameData[IdxStartedHeight])
257- let winAmount = parseIntValue(gameData[IdxWinAmount])
258- let assetId = parseIntValue(gameData[IdxAssetId])
259- let playerPubKey58 = gameData[IdxPlayerPubKey58]
260- let playerAddress = addressFromPublicKey(fromBase58String(playerPubKey58))
261- if ((gameState != STATESUBMITTED))
262- then throw("Invalid game state for passed gameId")
263- else if ((i.caller != SERVER))
264- then throw("Regular withdraw can be done by server only")
265- else {
266- let winByTimeout = ((height - startedHeight) > RANDORACLETIMEFRAME)
267- let randChoise = if (winByTimeout)
268- then take(playerChoice, 1)
269- else generateRandChoise(gameId, rsaSign)
270- let playerWin = isPlayerWin(playerChoice, randChoise)
271- let newGameStatus = if (playerWin)
272- then STATEWON
273- else STATELOST
274- let newGameData = finishGameData(gameData, newGameStatus, randChoise, winByTimeout)
275- ([StringEntry(gameId, newGameData), decreaseReservedAmount(gameId, assetId, winAmount)] ++ (if (playerWin)
276- then [ScriptTransfer(playerAddress, winAmount, ASSETS[assetId])]
277- else nil))
278- }
279- }
280-
281-
282-@Verifier(tx)
283-func verify () = if (sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey))
284- then match tx {
285- case ttx: TransferTransaction =>
286- let assetId = validateAndGetAssetId(ttx.assetId)
287- ((getAssetBalance(ttx.assetId) - ttx.amount) >= getIntOr(RESERVATIONKEY[assetId], 0))
288- case stx: SetScriptTransaction =>
289- if (if ((getIntOr(RESERVATIONKEY[0], 0) == 0))
290- then (getIntOr(RESERVATIONKEY[1], 0) == 0)
291- else false)
292- then (getIntOr(RESERVATIONKEY[2], 0) == 0)
293- else false
294- case _ =>
295- false
296- }
297- else false
298-
1+# no script

github/deemru/w8io/3ef1775 
38.97 ms