tx · FCk9jqnhrbfpy4RAE5C7kahBzZGftQw7rKWw6f78ZH27

3Mt6NEJ6ZK6TFZs14tvnR5iAgemnomy2m1V:  -0.01700000 Waves

2022.09.13 12:06 [2227124] smart account 3Mt6NEJ6ZK6TFZs14tvnR5iAgemnomy2m1V > SELF 0.00000000 Waves

{ "type": 13, "id": "FCk9jqnhrbfpy4RAE5C7kahBzZGftQw7rKWw6f78ZH27", "fee": 1700000, "feeAssetId": null, "timestamp": 1663059992532, "version": 2, "chainId": 84, "sender": "3Mt6NEJ6ZK6TFZs14tvnR5iAgemnomy2m1V", "senderPublicKey": "5f9EawB8nxaLg7KKhyqV2RDBMwRBG6o69D8zc9myAzrY", "proofs": [ "2Q3bNvzYfk3NWwtA44CtWCxjHke1wa6MmtkcpGKygQu5ihkriWjfQEwtZjtLLLQVFUAzUfjFBtto77QqEFXLph1c" ], "script": "base64:AAIFAAAAAAAAAB0IAhIAEgASBAoCCAESAwoBCBIECgIIARIECgIICAAAACwAAAAABXdoZWVsCQAETAAAAAIAAAAAAAAAAAUJAARMAAAAAgAAAAAAAAAAGAkABEwAAAACAAAAAAAAAAAQCQAETAAAAAIAAAAAAAAAACEJAARMAAAAAgAAAAAAAAAAAQkABEwAAAACAAAAAAAAAAAUCQAETAAAAAIAAAAAAAAAAA4JAARMAAAAAgAAAAAAAAAAHwkABEwAAAACAAAAAAAAAAAJCQAETAAAAAIAAAAAAAAAABYJAARMAAAAAgAAAAAAAAAAEgkABEwAAAACAAAAAAAAAAAdCQAETAAAAAIAAAAAAAAAAAcJAARMAAAAAgAAAAAAAAAAHAkABEwAAAACAAAAAAAAAAAMCQAETAAAAAIAAAAAAAAAACMJAARMAAAAAgAAAAAAAAAAAwkABEwAAAACAAAAAAAAAAAaCQAETAAAAAIAAAAAAAAAAAAJAARMAAAAAgAAAAAAAAAAIAkABEwAAAACAAAAAAAAAAAPCQAETAAAAAIAAAAAAAAAABMJAARMAAAAAgAAAAAAAAAABAkABEwAAAACAAAAAAAAAAAVCQAETAAAAAIAAAAAAAAAAAIJAARMAAAAAgAAAAAAAAAAGQkABEwAAAACAAAAAAAAAAARCQAETAAAAAIAAAAAAAAAACIJAARMAAAAAgAAAAAAAAAABgkABEwAAAACAAAAAAAAAAAbCQAETAAAAAIAAAAAAAAAAA0JAARMAAAAAgAAAAAAAAAAJAkABEwAAAACAAAAAAAAAAALCQAETAAAAAIAAAAAAAAAAB4JAARMAAAAAgAAAAAAAAAACAkABEwAAAACAAAAAAAAAAAXCQAETAAAAAIAAAAAAAAAAAoFAAAAA25pbAAAAAAFYmxhY2sJAARMAAAAAgAAAAAAAAAAAgkABEwAAAACAAAAAAAAAAAECQAETAAAAAIAAAAAAAAAAAYJAARMAAAAAgAAAAAAAAAACAkABEwAAAACAAAAAAAAAAAKCQAETAAAAAIAAAAAAAAAAAsJAARMAAAAAgAAAAAAAAAADQkABEwAAAACAAAAAAAAAAAPCQAETAAAAAIAAAAAAAAAABEJAARMAAAAAgAAAAAAAAAAFAkABEwAAAACAAAAAAAAAAAWCQAETAAAAAIAAAAAAAAAABgJAARMAAAAAgAAAAAAAAAAGgkABEwAAAACAAAAAAAAAAAcCQAETAAAAAIAAAAAAAAAAB0JAARMAAAAAgAAAAAAAAAAHwkABEwAAAACAAAAAAAAAAAhCQAETAAAAAIAAAAAAAAAACMFAAAAA25pbAAAAAADcmVkCQAETAAAAAIAAAAAAAAAAAEJAARMAAAAAgAAAAAAAAAAAwkABEwAAAACAAAAAAAAAAAFCQAETAAAAAIAAAAAAAAAAAcJAARMAAAAAgAAAAAAAAAACQkABEwAAAACAAAAAAAAAAAMCQAETAAAAAIAAAAAAAAAAA4JAARMAAAAAgAAAAAAAAAAEAkABEwAAAACAAAAAAAAAAASCQAETAAAAAIAAAAAAAAAABMJAARMAAAAAgAAAAAAAAAAFQkABEwAAAACAAAAAAAAAAAXCQAETAAAAAIAAAAAAAAAABkJAARMAAAAAgAAAAAAAAAAGwkABEwAAAACAAAAAAAAAAAeCQAETAAAAAIAAAAAAAAAACAJAARMAAAAAgAAAAAAAAAAIgkABEwAAAACAAAAAAAAAAAkBQAAAANuaWwAAAAABGNvbDEJAARMAAAAAgAAAAAAAAAAAQkABEwAAAACAAAAAAAAAAAECQAETAAAAAIAAAAAAAAAAAcJAARMAAAAAgAAAAAAAAAACgkABEwAAAACAAAAAAAAAAANCQAETAAAAAIAAAAAAAAAABAJAARMAAAAAgAAAAAAAAAAEwkABEwAAAACAAAAAAAAAAAWCQAETAAAAAIAAAAAAAAAABkJAARMAAAAAgAAAAAAAAAAHAkABEwAAAACAAAAAAAAAAAfCQAETAAAAAIAAAAAAAAAACIFAAAAA25pbAAAAAAEY29sMgkABEwAAAACAAAAAAAAAAACCQAETAAAAAIAAAAAAAAAAAUJAARMAAAAAgAAAAAAAAAACAkABEwAAAACAAAAAAAAAAALCQAETAAAAAIAAAAAAAAAAA4JAARMAAAAAgAAAAAAAAAAEQkABEwAAAACAAAAAAAAAAAUCQAETAAAAAIAAAAAAAAAABcJAARMAAAAAgAAAAAAAAAAGgkABEwAAAACAAAAAAAAAAAdCQAETAAAAAIAAAAAAAAAACAJAARMAAAAAgAAAAAAAAAAIwUAAAADbmlsAAAAAARjb2wzCQAETAAAAAIAAAAAAAAAAAMJAARMAAAAAgAAAAAAAAAABgkABEwAAAACAAAAAAAAAAAJCQAETAAAAAIAAAAAAAAAAAwJAARMAAAAAgAAAAAAAAAADwkABEwAAAACAAAAAAAAAAASCQAETAAAAAIAAAAAAAAAABUJAARMAAAAAgAAAAAAAAAAGAkABEwAAAACAAAAAAAAAAAbCQAETAAAAAIAAAAAAAAAAB4JAARMAAAAAgAAAAAAAAAAIQkABEwAAAACAAAAAAAAAAAkBQAAAANuaWwAAAAAE2dhbWVNYXN0ZXJQdWJsaWNLZXkJAAJZAAAAAQIAAAAYPGdhbWUtbWFzdGVyLXB1YmxpYy1rZXk+AAAAABBnYW1lQ291bnRlckxhYmVsAgAAAA5HX0dBTUVTQ09VTlRFUgAAAAASZ2FtZVRvdGFsQmV0c0xhYmVsAgAAAAtHX1RPVEFMQkVUUwAAAAAWZ2FtZVByb2Nlc3NlZEJldHNMYWJlbAIAAAAPR19QUk9DRVNTRURCRVRTAAAAAA9nYW1lTWluQmV0TGFiZWwCAAAACEdfTUlOQkVUAAAAAA9nYW1lTWF4QmV0TGFiZWwCAAAACEdfTUFYQkVUAAAAABJnYW1lUlNBUHVibGljTGFiZWwCAAAAC0dfUlNBUFVCTElDAAAAABhnYW1lTWFzdGVyUHVibGljS2V5TGFiZWwCAAAAF0dfR0FNRU1BU1RFUl9QVUJMSUNfS0VZAAAAAA5nYW1lVG9rZW5MYWJlbAIAAAAJR19UT0tFTklEAQAAAA9nYW1lc0dldENvdW50ZXIAAAAACQAEGgAAAAIFAAAABHRoaXMFAAAAEGdhbWVDb3VudGVyTGFiZWwBAAAADmdhbWVzVG90YWxCZXRzAAAAAAkABBoAAAACBQAAAAR0aGlzBQAAABJnYW1lVG90YWxCZXRzTGFiZWwBAAAAEmdhbWVzUHJvY2Vzc2VkQmV0cwAAAAAJAAQaAAAAAgUAAAAEdGhpcwUAAAAWZ2FtZVByb2Nlc3NlZEJldHNMYWJlbAEAAAALZ2FtZXNNaW5CZXQAAAAACQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAAR0aGlzBQAAAA9nYW1lTWluQmV0TGFiZWwBAAAAC2dhbWVzTWF4QmV0AAAAAAkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAA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dGNoMQkBAAAADGdhbWVHZXRTdGF0ZQAAAAEFAAAADEdBTUVTQ09VTlRFUgMJAAABAAAAAgUAAAAHJG1hdGNoMQIAAAADSW50BAAAAAlnYW1lU3RhdGUFAAAAByRtYXRjaDEDCQAAAAAAAAIFAAAACWdhbWVTdGF0ZQAAAAAAAAAAAAkAAAIAAAABAgAAAB9MYXN0IGdhbWUgaGFzIG5vdCBmaW5pc2hlZCB5ZXQuCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABBnYW1lQ291bnRlckxhYmVsBQAAAA5uZXdHYW1lQ291bnRlcgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAFGdhbWVTdGFydEhlaWdodExhYmVsAAAAAQUAAAAObmV3R2FtZUNvdW50ZXIIBQAAAAlsYXN0QmxvY2sAAAAGaGVpZ2h0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAASZ2FtZUVuZEhlaWdodExhYmVsAAAAAQUAAAAObmV3R2FtZUNvdW50ZXIJAABkAAAAAgUAAAAGaGVpZ2h0BQAAAAxibG9ja0luUm91bmQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA5nYW1lU3RhdGVMYWJlbAAAAAEFAAAADm5ld0dhbWVDb3VudGVyAAAAAAAAAAAACQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAAA9nYW1lU3VtU2hhTGFiZWwAAAABBQAAAA5uZXdHYW1lQ291bnRlcgkAAlgAAAABCQAB9wAAAAEJAAJbAAAAAQUAAAAKcmFuZG9tSGFzaAUAAAADbmlsCQAAAgAAAAECAAAAFUdhbWUgc3RhdGUgbm90IGZvdW5kLgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAQZ2FtZUNvdW50ZXJMYWJlbAUAAAAObmV3R2FtZUNvdW50ZXIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABRnYW1lU3RhcnRIZWlnaHRMYWJlbAAAAAEFAAAADm5ld0dhbWVDb3VudGVyCAUAAAAJbGFzdEJsb2NrAAAABmhlaWdodAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAA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IG5vdCBleGlzdCBvciBoYXMgYWxyZWFkeSBlbmRlZAAAAAFpAQAAAAxzZXRQYXJhbWV0ZXIAAAACAAAADXBhcmFtZXRlck5hbWUAAAAOcGFyYW1ldGVyVmFsdWUDCQEAAAAPY2hlY2tQZXJtaXNzaW9uAAAAAQgFAAAAAWkAAAAPY2FsbGVyUHVibGljS2V5CQAAAgAAAAECAAAAFnNldFBhcmFtZXRlcl9GT1JCQklERU4DCQAAAAAAAAIFAAAADXBhcmFtZXRlck5hbWUCAAAACWNoYW5nZU1heAQAAAAMbWF4aW11bVZhbHVlCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEFAAAADnBhcmFtZXRlclZhbHVlBAAAAAxtaW5pbXVtVmFsdWUJAQAAAAtnYW1lc01pbkJldAAAAAADCQAAZgAAAAIAAAAAAAAAAAAFAAAADG1heGltdW1WYWx1ZQkAAAIAAAABAgAAABx2YWx1ZSBjYW5ub3QgYmUgbG93ZXIgdGhhbiAwAwkAAGcAAAACBQAAAAxtaW5pbXVtVmFsdWUFAAAADG1heGltdW1WYWx1ZQkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgIAAAAtdmFsdWUgY2Fubm90IGJlIGxvd2VyIG9yIGVxdWFsIHRoYW4gbWluIGJldCAoCQABpAAAAAEFAAAADG1pbmltdW1WYWx1ZQIAAAABKQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAPZ2FtZU1heEJldExhYmVsBQAAAAxtYXhpbXVtVmFsdWUFAAAAA25pbAMJAAAAAAAAAgUAAAANcGFyYW1ldGVyTmFtZQIAAAAJY2hhbmdlTWluBAAAAAxtYXhpbXVtVmFsdWUJAQAAAAtnYW1lc01heEJldAAAAAAEAAAADG1pbmltdW1WYWx1ZQkBAAAADXBhcnNlSW50VmFsdWUAAAABBQAAAA5wYXJhbWV0ZXJWYWx1ZQMJAABmAAAAAgAAAAAAAAAAAAUAAAAMbWluaW11bVZhbHVlCQAAAgAAAAECAAAAHHZhbHVlIGNhbm5vdCBiZSBsb3dlciB0aGFuIDADCQAAZwAAAAIFAAAADG1pbmltdW1WYWx1ZQUAAAAMbWF4aW11bVZhbHVlCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACAgAAAC92YWx1ZSBjYW5ub3QgYmUgZ3JlYXRlciBvciBlcXVhbCB0aGFuIG1pbiBiZXQgKAkAAaQAAAABBQAAAAxtYXhpbXVtVmFsdWUCAAAAASkJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAD2dhbWVNaW5CZXRMYWJlbAUAAAAMbWluaW11bVZhbHVlBQAAAANuaWwDCQAAAAAAAAIFAAAADXBhcmFtZXRlck5hbWUCAAAACWNoYW5nZVJTQQQAAAAHJG1hdGNoMAkBAAAAD2dhbWVzR2V0Q291bnRlcgAAAAADCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAA0ludAQAAAAMR0FNRVNDT1VOVEVSBQAAAAckbWF0Y2gwBAAAAAckbWF0Y2gxCQEAAAAMZ2FtZUdldFN0YXRlAAAAAQUAAAAMR0FNRVNDT1VOVEVSAwkAAAEAAAACBQAAAAckbWF0Y2gxAgAAAANJbnQEAAAABXN0YXRlBQAAAAckbWF0Y2gxAwkBAAAAAiE9AAAAAgUAAAAFc3RhdGUAAAAAAAAAAAEJAAACAAAAAQIAAAAYR2FtZSBoYXMgdG8gYmUgZmluaXNoZWQuCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAEmdhbWVSU0FQdWJsaWNMYWJlbAUAAAAOcGFyYW1ldGVyVmFsdWUFAAAAA25pbAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAABJnYW1lUlNBUHVibGljTGFiZWwFAAAADnBhcmFtZXRlclZhbHVlBQAAAANuaWwJAAACAAAAAQIAAAAdR2FtZSBuZWVkcyB0byBiZSBpbml0aWFsaXplZC4JAAACAAAAAQIAAABJU2V0dGluZyBub3QgZm91bmQuIEFsbG93ZWQ6IGNoYW5nZU1heCwgY2hhbmdlTWluLCBjaGFuZ2VSU0EsIGNoYW5nZVB1YktleQAAAAEAAAACdHgBAAAABnZlcmlmeQAAAAAJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAACAUAAAACdHgAAAAPc2VuZGVyUHVibGljS2V5Dx/p9Q==", "height": 2227124, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 59pAUTAXhHGoTvkSJCWrRWBHbWcfBUyoUbn84kR1cMPG Next: GYW4ctUkrBUmdcoyoM6uiZaZBx36b6r48sjM95DTuRZF Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let gameTokenLabel = "G_TOKENID"
4+let wheel = [5, 24, 16, 33, 1, 20, 14, 31, 9, 22, 18, 29, 7, 28, 12, 35, 3, 26, 0, 32, 15, 19, 4, 21, 2, 25, 17, 34, 6, 27, 13, 36, 11, 30, 8, 23, 10]
55
6-let gameBalanceLabel = "G_BALANCE"
6+let black = [2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 29, 31, 33, 35]
77
8-let gameCommunityPotLabel = "G_COMMUNITYPOT"
8+let red = [1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36]
99
10-let gamePrizePotLabel = "G_PRIZEPOT"
10+let col1 = [1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34]
1111
12-let gamePrizeShareAmountLabel = "G_PRIZESHAREAMOUNT"
12+let col2 = [2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35]
13+
14+let col3 = [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36]
15+
16+let gameMasterPublicKey = fromBase58String("<game-master-public-key>")
1317
1418 let gameCounterLabel = "G_GAMESCOUNTER"
1519
1721
1822 let gameProcessedBetsLabel = "G_PROCESSEDBETS"
1923
20-let gameWinnersCounterLabel = "G_WINNERSCOUNT"
24+let gameMinBetLabel = "G_MINBET"
2125
22-let gameProcessedWinnersLabel = "G_PROCESSEDWINNERS"
26+let gameMaxBetLabel = "G_MAXBET"
2327
24-func gameResultLabel (gameNumber) = (("G_" + toString(gameNumber)) + "_RESULT")
28+let gameRSAPublicLabel = "G_RSAPUBLIC"
2529
30+let gameMasterPublicKeyLabel = "G_GAMEMASTER_PUBLIC_KEY"
2631
27-func betDetailsLabel (betNumber) = (("B_" + toString(betNumber)) + "_BETDETAILS")
28-
29-
30-func winnerDetailsLabel (winnerNumber) = (("W_" + toString(winnerNumber)) + "_WINNERDETAILS")
31-
32-
33-func gameBalance () = getInteger(this, gameBalanceLabel)
34-
35-
36-func gameCommunityPot () = getInteger(this, gameCommunityPotLabel)
37-
38-
39-func gamePrizePot () = getInteger(this, gamePrizePotLabel)
40-
41-
42-func gamePrizeShareAmount () = getInteger(this, gamePrizeShareAmountLabel)
43-
32+let gameTokenLabel = "G_TOKENID"
4433
4534 func gamesGetCounter () = getInteger(this, gameCounterLabel)
4635
4736
48-func gameTotalBets () = getInteger(this, gameTotalBetsLabel)
37+func gamesTotalBets () = getInteger(this, gameTotalBetsLabel)
4938
5039
51-func gameProcessedBets () = getInteger(this, gameProcessedBetsLabel)
40+func gamesProcessedBets () = getInteger(this, gameProcessedBetsLabel)
5241
5342
54-func gameWinnersCounter () = getInteger(this, gameWinnersCounterLabel)
43+func gamesMinBet () = getIntegerValue(this, gameMinBetLabel)
5544
5645
57-func gameProcessedWinners () = getInteger(this, gameProcessedWinnersLabel)
46+func gamesMaxBet () = getIntegerValue(this, gameMaxBetLabel)
5847
5948
60-func gameGetResult (gameNumber) = getStringValue(this, gameResultLabel(gameNumber))
49+func gameRSAPublicString () = getStringValue(this, gameRSAPublicLabel)
6150
6251
63-func betDetails (betNumber) = getStringValue(this, betDetailsLabel(betNumber))
64-
65-
66-func winnerDetails (winnerNumber) = getStringValue(this, winnerDetailsLabel(winnerNumber))
52+func gameRSAPublic () = fromBase64String(gameRSAPublicString())
6753
6854
6955 func gameToken () = match getString(this, gameTokenLabel) {
7662 }
7763
7864
65+func betDetailsLabel (betNumber) = (("B_" + toString(betNumber)) + "_BETDETAILS")
66+
67+
68+func betWinStateLabel (betNumber) = (("B_" + toString(betNumber)) + "_WINSTATE")
69+
70+
71+func betWinAmountLabel (betNumber) = (("B_" + toString(betNumber)) + "_WINAMOUNT")
72+
73+
74+func betGameLabel (betNumber) = (("B_" + toString(betNumber)) + "_GAME")
75+
76+
77+func betPayoutLabel (betNumber) = (("B_" + toString(betNumber)) + "_PAYOUT")
78+
79+
80+func betDetailsResult (betNumber) = getStringValue(this, betDetailsLabel(betNumber))
81+
82+
83+func betGameResult (betNumber) = getIntegerValue(this, betGameLabel(betNumber))
84+
85+
86+func gameStateLabel (gameNumber) = (("G_" + toString(gameNumber)) + "_STATE")
87+
88+
89+func gameStartHeightLabel (gameNumber) = (("G_" + toString(gameNumber)) + "_STARTHEIGHT")
90+
91+
92+func gameEndHeightLabel (gameNumber) = (("G_" + toString(gameNumber)) + "_ENDHEIGHT")
93+
94+
95+func gameSumShaLabel (gameNumber) = (("G_" + toString(gameNumber)) + "_SUMSHA")
96+
97+
98+func gameResultLabel (gameNumber) = (("G_" + toString(gameNumber)) + "_RESULT")
99+
100+
101+func gameRandomHashLabel (gameNumber) = (("G_" + toString(gameNumber)) + "_RANDOMHASH")
102+
103+
104+func gameGetState (gameNumber) = getInteger(this, gameStateLabel(gameNumber))
105+
106+
107+func gameGetEndHeight (gameNumber) = getInteger(this, gameEndHeightLabel(gameNumber))
108+
109+
110+func gameGetSumSha (gameNumber) = getString(this, gameSumShaLabel(gameNumber))
111+
112+
113+func gameGetResult (gameNumber) = getIntegerValue(this, gameResultLabel(gameNumber))
114+
115+
116+func checkPermission (callerPublicKey) = (callerPublicKey != gameMasterPublicKey)
117+
118+
119+func gameInBaseToken (token) = (token == unit)
120+
121+
122+func getMultiple (numberPlaced) = if ((numberPlaced == 1))
123+ then 36
124+ else if ((numberPlaced == 2))
125+ then 18
126+ else if ((numberPlaced == 3))
127+ then 12
128+ else if ((numberPlaced == 4))
129+ then 9
130+ else if ((numberPlaced == 5))
131+ then 7
132+ else if ((numberPlaced == 6))
133+ then 6
134+ else 0
135+
136+
137+func getWinnings (bet,result) = {
138+ let betStringList = split(bet, "-")
139+ let amountBet = value(parseInt(betStringList[1]))
140+ let betType = betStringList[2]
141+ if ((betType == "numbers"))
142+ then {
143+ let allNumberBets = removeByIndex(removeByIndex(removeByIndex(betStringList, 0), 0), 0)
144+ if (containsElement(allNumberBets, toString(result)))
145+ then (amountBet * getMultiple(size(allNumberBets)))
146+ else 0
147+ }
148+ else if ((betType == "color"))
149+ then if ((betStringList[3] == "red"))
150+ then if (containsElement(red, result))
151+ then (amountBet * 2)
152+ else 0
153+ else if (containsElement(black, result))
154+ then (amountBet * 2)
155+ else 0
156+ else if ((betType == "column"))
157+ then if ((betStringList[3] == "1"))
158+ then if (containsElement(col1, result))
159+ then (amountBet * 3)
160+ else 0
161+ else if ((betStringList[3] == "2"))
162+ then if (containsElement(col2, result))
163+ then (amountBet * 3)
164+ else 0
165+ else if ((betStringList[3] == "3"))
166+ then if (containsElement(col3, result))
167+ then (amountBet * 3)
168+ else 0
169+ else 0
170+ else if ((betType == "dozen"))
171+ then if ((betStringList[3] == "1"))
172+ then if (if ((result >= 1))
173+ then (12 >= result)
174+ else false)
175+ then (amountBet * 3)
176+ else 0
177+ else if ((betStringList[3] == "2"))
178+ then if (if ((result >= 13))
179+ then (24 >= result)
180+ else false)
181+ then (amountBet * 3)
182+ else 0
183+ else if ((betStringList[3] == "3"))
184+ then if (if ((result >= 25))
185+ then (36 >= result)
186+ else false)
187+ then (amountBet * 3)
188+ else 0
189+ else 0
190+ else if ((betType == "oddeven"))
191+ then if ((result == 0))
192+ then 0
193+ else if ((betStringList[3] == "even"))
194+ then if (if (((result % 2) == 0))
195+ then (result != 0)
196+ else false)
197+ then (amountBet * 2)
198+ else 0
199+ else if (((result % 2) == 1))
200+ then (amountBet * 2)
201+ else 0
202+ else if ((betType == "lowhigh"))
203+ then if ((result == 0))
204+ then 0
205+ else if ((betStringList[3] == "low"))
206+ then if (if ((result >= 1))
207+ then (18 >= result)
208+ else false)
209+ then (amountBet * 2)
210+ else 0
211+ else if (if ((result >= 19))
212+ then (36 >= result)
213+ else false)
214+ then (amountBet * 2)
215+ else 0
216+ else 0
217+ }
218+
219+
79220 @Callable(i)
80-func initGame () = [IntegerEntry(gameBalanceLabel, 0), IntegerEntry(gameCommunityPotLabel, 0), IntegerEntry(gamePrizePotLabel, 10000000), IntegerEntry(gamePrizeShareAmountLabel, 0), IntegerEntry(gameCounterLabel, 0), IntegerEntry(gameTotalBetsLabel, 0), IntegerEntry(gameProcessedBetsLabel, 0), IntegerEntry(gameWinnersCounterLabel, 0), IntegerEntry(gameProcessedWinnersLabel, 0)]
221+func processNextBet () = if (checkPermission(i.callerPublicKey))
222+ then throw("processNextBet_FORBBIDEN")
223+ else match gamesTotalBets() {
224+ case totalBets: Int =>
225+ match gamesProcessedBets() {
226+ case lastProcessedBet: Int =>
227+ let nextBet = (lastProcessedBet + 1)
228+ if ((nextBet > totalBets))
229+ then throw("Next bet has not been placed.")
230+ else {
231+ let gameNumber = betGameResult(nextBet)
232+ match gameGetState(gameNumber) {
233+ case state: Int =>
234+ if ((state == 1))
235+ then {
236+ let result = gameGetResult(gameNumber)
237+ let betDetails = betDetailsResult(nextBet)
238+ let betPlacer = split(betDetails, "-")[0]
239+ let address = value(addressFromString(betPlacer))
240+ let winnings = getWinnings(betDetails, result)
241+[ScriptTransfer(address, winnings, gameToken()), IntegerEntry(gameProcessedBetsLabel, (lastProcessedBet + 1)), IntegerEntry(betPayoutLabel(nextBet), winnings)]
242+ }
243+ else throw("Game has not finished.")
244+ case _ =>
245+ throw("Game does not exist or has already ended.")
246+ }
247+ }
248+ case _ =>
249+ throw("Game has not been initialized, next bets not found")
250+ }
251+ case _ =>
252+ throw("Game has not been initialized, total bets not found")
253+ }
81254
82255
83256
84257 @Callable(i)
85-func startGame () = match gamesGetCounter() {
86- case currentGame: Int =>
87- let newGame = (currentGame + 1)
88-[IntegerEntry(gameCounterLabel, newGame)]
89- case _ =>
90- throw("Game has not been initialized, total games not found")
91-}
258+func initGame () = if (checkPermission(i.callerPublicKey))
259+ then throw("initGame_FORBBIDEN")
260+ else match gamesGetCounter() {
261+ case GAMESCOUNTER: Int =>
262+ throw("INIT_ALREADY_DONE")
263+ case _ =>
264+[IntegerEntry(gameCounterLabel, 0), IntegerEntry(gameTotalBetsLabel, 0), IntegerEntry(gameProcessedBetsLabel, 0), IntegerEntry(gameMinBetLabel, 100000000), IntegerEntry(gameMaxBetLabel, 2500000000), StringEntry(gameRSAPublicLabel, "base64:<gameRSAPublicLabel>"), StringEntry(gameTokenLabel, "")]
265+ }
92266
93267
94268
95269 @Callable(i)
96-func placeBet () = match gamesGetCounter() {
97- case currentGame: Int =>
98- match gameTotalBets() {
99- case totalBets: Int =>
100- let newBet = (totalBets + 1)
101- let bet = "1,2,3"
102-[IntegerEntry(gameTotalBetsLabel, newBet), StringEntry(betDetailsLabel(newBet), ((("G" + toString(currentGame)) + "-") + bet))]
103- case _ =>
104- throw("Game has not been initialized, total bets not found")
105- }
106- case _ =>
107- throw("Game has not been initialized, total games not found")
108-}
270+func startGame (randomHash,blockInRound) = if (checkPermission(i.callerPublicKey))
271+ then throw("startGame_FORBBIDEN")
272+ else match gamesGetCounter() {
273+ case GAMESCOUNTER: Int =>
274+ let newGameCounter = (GAMESCOUNTER + 1)
275+ if ((GAMESCOUNTER > 0))
276+ then match gameGetState(GAMESCOUNTER) {
277+ case gameState: Int =>
278+ if ((gameState == 0))
279+ then throw("Last game has not finished yet.")
280+ else [IntegerEntry(gameCounterLabel, newGameCounter), IntegerEntry(gameStartHeightLabel(newGameCounter), lastBlock.height), IntegerEntry(gameEndHeightLabel(newGameCounter), (height + blockInRound)), IntegerEntry(gameStateLabel(newGameCounter), 0), StringEntry(gameSumShaLabel(newGameCounter), toBase58String(sha256(fromBase64String(randomHash))))]
281+ case _ =>
282+ throw("Game state not found.")
283+ }
284+ else [IntegerEntry(gameCounterLabel, newGameCounter), IntegerEntry(gameStartHeightLabel(newGameCounter), lastBlock.height), IntegerEntry(gameEndHeightLabel(newGameCounter), (height + blockInRound)), IntegerEntry(gameStateLabel(newGameCounter), 0), StringEntry(gameSumShaLabel(newGameCounter), toBase58String(sha256(fromBase64String(randomHash))))]
285+ case _ =>
286+ throw("INIT_NEEDED")
287+ }
109288
110289
111290
112291 @Callable(i)
113-func endGame () = match gamesGetCounter() {
114- case currentGame: Int =>
115-[StringEntry(gameResultLabel(currentGame), ((("G" + toString(currentGame)) + "-") + "1,2,3"))]
116- case _ =>
117- throw("Game has not been initialized, total games not found")
118-}
292+func placeBet (bet) = {
293+ let assetId = gameToken()
294+ if ((i.feeAssetId != assetId))
295+ then throw("Fee is not in correct assetId")
296+ else {
297+ let betStringList = split(bet, "-")
298+ let betType = betStringList[0]
299+ if (if (if (if (if (if ((betType != "numbers"))
300+ then (betType != "column")
301+ else false)
302+ then (betType != "color")
303+ else false)
304+ then (betType != "dozen")
305+ else false)
306+ then (betType != "oddeven")
307+ else false)
308+ then (betType != "lowhigh")
309+ else false)
310+ then throw("Bet type is not valid.")
311+ else match gamesGetCounter() {
312+ case GAMESCOUNTER: Int =>
313+ match gameGetState(GAMESCOUNTER) {
314+ case state: Int =>
315+ if ((state == 1))
316+ then throw("Game is finished and next game has not started.")
317+ else if ((size(i.payments) != 1))
318+ then throw("Payment not attached or there is more then one payment")
319+ else {
320+ let p = i.payments[0]
321+ let amount = p.amount
322+ if (if (if ((value(gamesMaxBet()) >= amount))
323+ then (amount >= value(gamesMinBet()))
324+ else false)
325+ then (i.payments[0].assetId == assetId)
326+ else false)
327+ then match gameGetEndHeight(GAMESCOUNTER) {
328+ case endHeight: Int =>
329+ if ((endHeight > height))
330+ then match gamesTotalBets() {
331+ case totalBets: Int =>
332+ let thisBetNumber = (totalBets + 1)
333+ if ((assetId == unit))
334+ then [IntegerEntry(gameTotalBetsLabel, (totalBets + 1)), StringEntry(betDetailsLabel(thisBetNumber), ((((toBase58String(i.caller.bytes) + "-") + toString(amount)) + "-") + bet)), IntegerEntry(betGameLabel(thisBetNumber), GAMESCOUNTER)]
335+ else [IntegerEntry(gameTotalBetsLabel, (totalBets + 1)), StringEntry(betDetailsLabel(thisBetNumber), ((((toBase58String(i.caller.bytes) + "-") + toString(amount)) + "-") + bet)), IntegerEntry(betGameLabel(thisBetNumber), GAMESCOUNTER)]
336+ case _ =>
337+ throw("Game has not been initalized.")
338+ }
339+ else throw("Game has already exceeded betting round")
340+ case _ =>
341+ throw("End height has not been defined.")
342+ }
343+ else throw((((((("Bet (" + toString(amount)) + ") is greater than maximum bet (") + toString(gamesMaxBet())) + "), lower than minimum (") + toString(gamesMinBet())) + ") or payment is not in correct assetId."))
344+ }
345+ case _ =>
346+ throw("Game does not exist or has already ended.")
347+ }
348+ case _ =>
349+ throw("Game needs to be initialized.")
350+ }
351+ }
352+ }
119353
120354
121355
122356 @Callable(i)
123-func processNextBet () = match gameTotalBets() {
124- case totalBets: Int =>
125- match gameProcessedBets() {
126- case lastProcessedBet: Int =>
127- let nextBet = (lastProcessedBet + 1)
128- if ((nextBet > totalBets))
129- then throw("Next bet has not been placed.")
130- else match gamesGetCounter() {
131- case gameNumber: Int =>
132- match gameWinnersCounter() {
133- case winnersCount: Int =>
134- let result = gameGetResult(gameNumber)
135- let betDetail = betDetails(nextBet)
136- if ((betDetail == result))
137- then {
138- let newWinnersCount = (winnersCount + 1)
139-[IntegerEntry(gameProcessedBetsLabel, nextBet), IntegerEntry(gameWinnersCounterLabel, (winnersCount + 1)), StringEntry(winnerDetailsLabel(newWinnersCount), toBase58String(i.caller.bytes))]
140- }
141- else [IntegerEntry(gameProcessedBetsLabel, nextBet)]
357+func endGame (rsaSign,gameNumber) = if (checkPermission(i.callerPublicKey))
358+ then throw("endGame_FORBBIDEN")
359+ else match gameGetState(gameNumber) {
360+ case state: Int =>
361+ if ((state == 1))
362+ then throw("Game is finished")
363+ else match gameGetEndHeight(gameNumber) {
364+ case gameHeight: Int =>
365+ if ((gameHeight > height))
366+ then throw(("Not enough blocks have past since game has started, game ends at block " + toString(gameHeight)))
367+ else match gameGetSumSha(gameNumber) {
368+ case SUMSHA: String =>
369+ let sig = fromBase64String(rsaSign)
370+ let rsaSigValid = rsaVerify(SHA256, fromBase58String(SUMSHA), sig, gameRSAPublic())
371+ match blockInfoByHeight(gameHeight) {
372+ case previousBlock: BlockInfo =>
373+ let randomHash = sha256((take(sig, 32) + take(previousBlock.generationSignature, 32)))
374+ if (!(rsaSigValid))
375+ then throw("INVALID_RSA_SIGN")
376+ else {
377+ let index = wheel[((toInt(randomHash) + value(gameNumber)) % 37)]
378+[IntegerEntry(gameStateLabel(gameNumber), 1), IntegerEntry(gameResultLabel(gameNumber), index), StringEntry(gameRandomHashLabel(gameNumber), toBase64String(randomHash))]
379+ }
380+ case _ =>
381+ throw("Last block does not exist.")
382+ }
142383 case _ =>
143- throw("Game has not been initialized, total winners not found")
384+ throw("SHA does not exist")
144385 }
145- case _ =>
146- throw("Game has not been initialized, total games not found")
147- }
148- case _ =>
149- throw("Game has not been initialized, total processed bets not found")
150- }
151- case _ =>
152- throw("Game has not been initialized, total bets not found")
153-}
386+ case _ =>
387+ throw("Cannot get game height.")
388+ }
389+ case _ =>
390+ throw("Game does not exist or has already ended")
391+ }
154392
155393
156394
157395 @Callable(i)
158-func calculatePrize () = match gameWinnersCounter() {
159- case winnersCount: Int =>
160- if ((winnersCount == 0))
161- then throw("There are no winners this round.")
162- else match gamePrizePot() {
163- case prizePotAmount: Int =>
164- let prizePot = gamePrizePot()
165- let prizeShareAmount = (prizePotAmount / winnersCount)
166-[IntegerEntry(gamePrizeShareAmountLabel, prizeShareAmount)]
167- case _ =>
168- throw("Game has not been initialized, total games not found")
396+func setParameter (parameterName,parameterValue) = if (checkPermission(i.callerPublicKey))
397+ then throw("setParameter_FORBBIDEN")
398+ else if ((parameterName == "changeMax"))
399+ then {
400+ let maximumValue = parseIntValue(parameterValue)
401+ let minimumValue = gamesMinBet()
402+ if ((0 > maximumValue))
403+ then throw("value cannot be lower than 0")
404+ else if ((minimumValue >= maximumValue))
405+ then throw((("value cannot be lower or equal than min bet (" + toString(minimumValue)) + ")"))
406+ else [IntegerEntry(gameMaxBetLabel, maximumValue)]
169407 }
170- case _ =>
171- throw("Game has not been initialized, total winners not found")
172-}
408+ else if ((parameterName == "changeMin"))
409+ then {
410+ let maximumValue = gamesMaxBet()
411+ let minimumValue = parseIntValue(parameterValue)
412+ if ((0 > minimumValue))
413+ then throw("value cannot be lower than 0")
414+ else if ((minimumValue >= maximumValue))
415+ then throw((("value cannot be greater or equal than min bet (" + toString(maximumValue)) + ")"))
416+ else [IntegerEntry(gameMinBetLabel, minimumValue)]
417+ }
418+ else if ((parameterName == "changeRSA"))
419+ then match gamesGetCounter() {
420+ case GAMESCOUNTER: Int =>
421+ match gameGetState(GAMESCOUNTER) {
422+ case state: Int =>
423+ if ((state != 1))
424+ then throw("Game has to be finished.")
425+ else [StringEntry(gameRSAPublicLabel, parameterValue)]
426+ case _ =>
427+[StringEntry(gameRSAPublicLabel, parameterValue)]
428+ }
429+ case _ =>
430+ throw("Game needs to be initialized.")
431+ }
432+ else throw("Setting not found. Allowed: changeMax, changeMin, changeRSA, changePubKey")
173433
174434
175-
176-@Callable(i)
177-func processNextWinner () = match gameWinnersCounter() {
178- case totalWinners: Int =>
179- if ((totalWinners == 0))
180- then throw("There are no winners this round.")
181- else match gameProcessedWinners() {
182- case lastProcessedWinner: Int =>
183- let nextWinner = (lastProcessedWinner + 1)
184- if ((nextWinner > totalWinners))
185- then throw("No more winners to be processed.")
186- else match gamePrizeShareAmount() {
187- case prizeShareAmount: Int =>
188- let betPlacer = winnerDetails(nextWinner)
189- let address = value(addressFromString(betPlacer))
190- let winnings = gamePrizeShareAmount()
191-[ScriptTransfer(address, prizeShareAmount, gameToken())]
192- case _ =>
193- throw("Game has not been initialized, prize share amount not found")
194- }
195- case _ =>
196- throw("Game has not been initialized, total processed winners not found")
197- }
198- case _ =>
199- throw("Game has not been initialized, total winners not found")
200-}
201-
435+@Verifier(tx)
436+func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
202437
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let gameTokenLabel = "G_TOKENID"
4+let wheel = [5, 24, 16, 33, 1, 20, 14, 31, 9, 22, 18, 29, 7, 28, 12, 35, 3, 26, 0, 32, 15, 19, 4, 21, 2, 25, 17, 34, 6, 27, 13, 36, 11, 30, 8, 23, 10]
55
6-let gameBalanceLabel = "G_BALANCE"
6+let black = [2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 29, 31, 33, 35]
77
8-let gameCommunityPotLabel = "G_COMMUNITYPOT"
8+let red = [1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36]
99
10-let gamePrizePotLabel = "G_PRIZEPOT"
10+let col1 = [1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34]
1111
12-let gamePrizeShareAmountLabel = "G_PRIZESHAREAMOUNT"
12+let col2 = [2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35]
13+
14+let col3 = [3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36]
15+
16+let gameMasterPublicKey = fromBase58String("<game-master-public-key>")
1317
1418 let gameCounterLabel = "G_GAMESCOUNTER"
1519
1620 let gameTotalBetsLabel = "G_TOTALBETS"
1721
1822 let gameProcessedBetsLabel = "G_PROCESSEDBETS"
1923
20-let gameWinnersCounterLabel = "G_WINNERSCOUNT"
24+let gameMinBetLabel = "G_MINBET"
2125
22-let gameProcessedWinnersLabel = "G_PROCESSEDWINNERS"
26+let gameMaxBetLabel = "G_MAXBET"
2327
24-func gameResultLabel (gameNumber) = (("G_" + toString(gameNumber)) + "_RESULT")
28+let gameRSAPublicLabel = "G_RSAPUBLIC"
2529
30+let gameMasterPublicKeyLabel = "G_GAMEMASTER_PUBLIC_KEY"
2631
27-func betDetailsLabel (betNumber) = (("B_" + toString(betNumber)) + "_BETDETAILS")
28-
29-
30-func winnerDetailsLabel (winnerNumber) = (("W_" + toString(winnerNumber)) + "_WINNERDETAILS")
31-
32-
33-func gameBalance () = getInteger(this, gameBalanceLabel)
34-
35-
36-func gameCommunityPot () = getInteger(this, gameCommunityPotLabel)
37-
38-
39-func gamePrizePot () = getInteger(this, gamePrizePotLabel)
40-
41-
42-func gamePrizeShareAmount () = getInteger(this, gamePrizeShareAmountLabel)
43-
32+let gameTokenLabel = "G_TOKENID"
4433
4534 func gamesGetCounter () = getInteger(this, gameCounterLabel)
4635
4736
48-func gameTotalBets () = getInteger(this, gameTotalBetsLabel)
37+func gamesTotalBets () = getInteger(this, gameTotalBetsLabel)
4938
5039
51-func gameProcessedBets () = getInteger(this, gameProcessedBetsLabel)
40+func gamesProcessedBets () = getInteger(this, gameProcessedBetsLabel)
5241
5342
54-func gameWinnersCounter () = getInteger(this, gameWinnersCounterLabel)
43+func gamesMinBet () = getIntegerValue(this, gameMinBetLabel)
5544
5645
57-func gameProcessedWinners () = getInteger(this, gameProcessedWinnersLabel)
46+func gamesMaxBet () = getIntegerValue(this, gameMaxBetLabel)
5847
5948
60-func gameGetResult (gameNumber) = getStringValue(this, gameResultLabel(gameNumber))
49+func gameRSAPublicString () = getStringValue(this, gameRSAPublicLabel)
6150
6251
63-func betDetails (betNumber) = getStringValue(this, betDetailsLabel(betNumber))
64-
65-
66-func winnerDetails (winnerNumber) = getStringValue(this, winnerDetailsLabel(winnerNumber))
52+func gameRSAPublic () = fromBase64String(gameRSAPublicString())
6753
6854
6955 func gameToken () = match getString(this, gameTokenLabel) {
7056 case tokenId: String =>
7157 if ((tokenId == ""))
7258 then unit
7359 else fromBase58String(tokenId)
7460 case _ =>
7561 unit
7662 }
7763
7864
65+func betDetailsLabel (betNumber) = (("B_" + toString(betNumber)) + "_BETDETAILS")
66+
67+
68+func betWinStateLabel (betNumber) = (("B_" + toString(betNumber)) + "_WINSTATE")
69+
70+
71+func betWinAmountLabel (betNumber) = (("B_" + toString(betNumber)) + "_WINAMOUNT")
72+
73+
74+func betGameLabel (betNumber) = (("B_" + toString(betNumber)) + "_GAME")
75+
76+
77+func betPayoutLabel (betNumber) = (("B_" + toString(betNumber)) + "_PAYOUT")
78+
79+
80+func betDetailsResult (betNumber) = getStringValue(this, betDetailsLabel(betNumber))
81+
82+
83+func betGameResult (betNumber) = getIntegerValue(this, betGameLabel(betNumber))
84+
85+
86+func gameStateLabel (gameNumber) = (("G_" + toString(gameNumber)) + "_STATE")
87+
88+
89+func gameStartHeightLabel (gameNumber) = (("G_" + toString(gameNumber)) + "_STARTHEIGHT")
90+
91+
92+func gameEndHeightLabel (gameNumber) = (("G_" + toString(gameNumber)) + "_ENDHEIGHT")
93+
94+
95+func gameSumShaLabel (gameNumber) = (("G_" + toString(gameNumber)) + "_SUMSHA")
96+
97+
98+func gameResultLabel (gameNumber) = (("G_" + toString(gameNumber)) + "_RESULT")
99+
100+
101+func gameRandomHashLabel (gameNumber) = (("G_" + toString(gameNumber)) + "_RANDOMHASH")
102+
103+
104+func gameGetState (gameNumber) = getInteger(this, gameStateLabel(gameNumber))
105+
106+
107+func gameGetEndHeight (gameNumber) = getInteger(this, gameEndHeightLabel(gameNumber))
108+
109+
110+func gameGetSumSha (gameNumber) = getString(this, gameSumShaLabel(gameNumber))
111+
112+
113+func gameGetResult (gameNumber) = getIntegerValue(this, gameResultLabel(gameNumber))
114+
115+
116+func checkPermission (callerPublicKey) = (callerPublicKey != gameMasterPublicKey)
117+
118+
119+func gameInBaseToken (token) = (token == unit)
120+
121+
122+func getMultiple (numberPlaced) = if ((numberPlaced == 1))
123+ then 36
124+ else if ((numberPlaced == 2))
125+ then 18
126+ else if ((numberPlaced == 3))
127+ then 12
128+ else if ((numberPlaced == 4))
129+ then 9
130+ else if ((numberPlaced == 5))
131+ then 7
132+ else if ((numberPlaced == 6))
133+ then 6
134+ else 0
135+
136+
137+func getWinnings (bet,result) = {
138+ let betStringList = split(bet, "-")
139+ let amountBet = value(parseInt(betStringList[1]))
140+ let betType = betStringList[2]
141+ if ((betType == "numbers"))
142+ then {
143+ let allNumberBets = removeByIndex(removeByIndex(removeByIndex(betStringList, 0), 0), 0)
144+ if (containsElement(allNumberBets, toString(result)))
145+ then (amountBet * getMultiple(size(allNumberBets)))
146+ else 0
147+ }
148+ else if ((betType == "color"))
149+ then if ((betStringList[3] == "red"))
150+ then if (containsElement(red, result))
151+ then (amountBet * 2)
152+ else 0
153+ else if (containsElement(black, result))
154+ then (amountBet * 2)
155+ else 0
156+ else if ((betType == "column"))
157+ then if ((betStringList[3] == "1"))
158+ then if (containsElement(col1, result))
159+ then (amountBet * 3)
160+ else 0
161+ else if ((betStringList[3] == "2"))
162+ then if (containsElement(col2, result))
163+ then (amountBet * 3)
164+ else 0
165+ else if ((betStringList[3] == "3"))
166+ then if (containsElement(col3, result))
167+ then (amountBet * 3)
168+ else 0
169+ else 0
170+ else if ((betType == "dozen"))
171+ then if ((betStringList[3] == "1"))
172+ then if (if ((result >= 1))
173+ then (12 >= result)
174+ else false)
175+ then (amountBet * 3)
176+ else 0
177+ else if ((betStringList[3] == "2"))
178+ then if (if ((result >= 13))
179+ then (24 >= result)
180+ else false)
181+ then (amountBet * 3)
182+ else 0
183+ else if ((betStringList[3] == "3"))
184+ then if (if ((result >= 25))
185+ then (36 >= result)
186+ else false)
187+ then (amountBet * 3)
188+ else 0
189+ else 0
190+ else if ((betType == "oddeven"))
191+ then if ((result == 0))
192+ then 0
193+ else if ((betStringList[3] == "even"))
194+ then if (if (((result % 2) == 0))
195+ then (result != 0)
196+ else false)
197+ then (amountBet * 2)
198+ else 0
199+ else if (((result % 2) == 1))
200+ then (amountBet * 2)
201+ else 0
202+ else if ((betType == "lowhigh"))
203+ then if ((result == 0))
204+ then 0
205+ else if ((betStringList[3] == "low"))
206+ then if (if ((result >= 1))
207+ then (18 >= result)
208+ else false)
209+ then (amountBet * 2)
210+ else 0
211+ else if (if ((result >= 19))
212+ then (36 >= result)
213+ else false)
214+ then (amountBet * 2)
215+ else 0
216+ else 0
217+ }
218+
219+
79220 @Callable(i)
80-func initGame () = [IntegerEntry(gameBalanceLabel, 0), IntegerEntry(gameCommunityPotLabel, 0), IntegerEntry(gamePrizePotLabel, 10000000), IntegerEntry(gamePrizeShareAmountLabel, 0), IntegerEntry(gameCounterLabel, 0), IntegerEntry(gameTotalBetsLabel, 0), IntegerEntry(gameProcessedBetsLabel, 0), IntegerEntry(gameWinnersCounterLabel, 0), IntegerEntry(gameProcessedWinnersLabel, 0)]
221+func processNextBet () = if (checkPermission(i.callerPublicKey))
222+ then throw("processNextBet_FORBBIDEN")
223+ else match gamesTotalBets() {
224+ case totalBets: Int =>
225+ match gamesProcessedBets() {
226+ case lastProcessedBet: Int =>
227+ let nextBet = (lastProcessedBet + 1)
228+ if ((nextBet > totalBets))
229+ then throw("Next bet has not been placed.")
230+ else {
231+ let gameNumber = betGameResult(nextBet)
232+ match gameGetState(gameNumber) {
233+ case state: Int =>
234+ if ((state == 1))
235+ then {
236+ let result = gameGetResult(gameNumber)
237+ let betDetails = betDetailsResult(nextBet)
238+ let betPlacer = split(betDetails, "-")[0]
239+ let address = value(addressFromString(betPlacer))
240+ let winnings = getWinnings(betDetails, result)
241+[ScriptTransfer(address, winnings, gameToken()), IntegerEntry(gameProcessedBetsLabel, (lastProcessedBet + 1)), IntegerEntry(betPayoutLabel(nextBet), winnings)]
242+ }
243+ else throw("Game has not finished.")
244+ case _ =>
245+ throw("Game does not exist or has already ended.")
246+ }
247+ }
248+ case _ =>
249+ throw("Game has not been initialized, next bets not found")
250+ }
251+ case _ =>
252+ throw("Game has not been initialized, total bets not found")
253+ }
81254
82255
83256
84257 @Callable(i)
85-func startGame () = match gamesGetCounter() {
86- case currentGame: Int =>
87- let newGame = (currentGame + 1)
88-[IntegerEntry(gameCounterLabel, newGame)]
89- case _ =>
90- throw("Game has not been initialized, total games not found")
91-}
258+func initGame () = if (checkPermission(i.callerPublicKey))
259+ then throw("initGame_FORBBIDEN")
260+ else match gamesGetCounter() {
261+ case GAMESCOUNTER: Int =>
262+ throw("INIT_ALREADY_DONE")
263+ case _ =>
264+[IntegerEntry(gameCounterLabel, 0), IntegerEntry(gameTotalBetsLabel, 0), IntegerEntry(gameProcessedBetsLabel, 0), IntegerEntry(gameMinBetLabel, 100000000), IntegerEntry(gameMaxBetLabel, 2500000000), StringEntry(gameRSAPublicLabel, "base64:<gameRSAPublicLabel>"), StringEntry(gameTokenLabel, "")]
265+ }
92266
93267
94268
95269 @Callable(i)
96-func placeBet () = match gamesGetCounter() {
97- case currentGame: Int =>
98- match gameTotalBets() {
99- case totalBets: Int =>
100- let newBet = (totalBets + 1)
101- let bet = "1,2,3"
102-[IntegerEntry(gameTotalBetsLabel, newBet), StringEntry(betDetailsLabel(newBet), ((("G" + toString(currentGame)) + "-") + bet))]
103- case _ =>
104- throw("Game has not been initialized, total bets not found")
105- }
106- case _ =>
107- throw("Game has not been initialized, total games not found")
108-}
270+func startGame (randomHash,blockInRound) = if (checkPermission(i.callerPublicKey))
271+ then throw("startGame_FORBBIDEN")
272+ else match gamesGetCounter() {
273+ case GAMESCOUNTER: Int =>
274+ let newGameCounter = (GAMESCOUNTER + 1)
275+ if ((GAMESCOUNTER > 0))
276+ then match gameGetState(GAMESCOUNTER) {
277+ case gameState: Int =>
278+ if ((gameState == 0))
279+ then throw("Last game has not finished yet.")
280+ else [IntegerEntry(gameCounterLabel, newGameCounter), IntegerEntry(gameStartHeightLabel(newGameCounter), lastBlock.height), IntegerEntry(gameEndHeightLabel(newGameCounter), (height + blockInRound)), IntegerEntry(gameStateLabel(newGameCounter), 0), StringEntry(gameSumShaLabel(newGameCounter), toBase58String(sha256(fromBase64String(randomHash))))]
281+ case _ =>
282+ throw("Game state not found.")
283+ }
284+ else [IntegerEntry(gameCounterLabel, newGameCounter), IntegerEntry(gameStartHeightLabel(newGameCounter), lastBlock.height), IntegerEntry(gameEndHeightLabel(newGameCounter), (height + blockInRound)), IntegerEntry(gameStateLabel(newGameCounter), 0), StringEntry(gameSumShaLabel(newGameCounter), toBase58String(sha256(fromBase64String(randomHash))))]
285+ case _ =>
286+ throw("INIT_NEEDED")
287+ }
109288
110289
111290
112291 @Callable(i)
113-func endGame () = match gamesGetCounter() {
114- case currentGame: Int =>
115-[StringEntry(gameResultLabel(currentGame), ((("G" + toString(currentGame)) + "-") + "1,2,3"))]
116- case _ =>
117- throw("Game has not been initialized, total games not found")
118-}
292+func placeBet (bet) = {
293+ let assetId = gameToken()
294+ if ((i.feeAssetId != assetId))
295+ then throw("Fee is not in correct assetId")
296+ else {
297+ let betStringList = split(bet, "-")
298+ let betType = betStringList[0]
299+ if (if (if (if (if (if ((betType != "numbers"))
300+ then (betType != "column")
301+ else false)
302+ then (betType != "color")
303+ else false)
304+ then (betType != "dozen")
305+ else false)
306+ then (betType != "oddeven")
307+ else false)
308+ then (betType != "lowhigh")
309+ else false)
310+ then throw("Bet type is not valid.")
311+ else match gamesGetCounter() {
312+ case GAMESCOUNTER: Int =>
313+ match gameGetState(GAMESCOUNTER) {
314+ case state: Int =>
315+ if ((state == 1))
316+ then throw("Game is finished and next game has not started.")
317+ else if ((size(i.payments) != 1))
318+ then throw("Payment not attached or there is more then one payment")
319+ else {
320+ let p = i.payments[0]
321+ let amount = p.amount
322+ if (if (if ((value(gamesMaxBet()) >= amount))
323+ then (amount >= value(gamesMinBet()))
324+ else false)
325+ then (i.payments[0].assetId == assetId)
326+ else false)
327+ then match gameGetEndHeight(GAMESCOUNTER) {
328+ case endHeight: Int =>
329+ if ((endHeight > height))
330+ then match gamesTotalBets() {
331+ case totalBets: Int =>
332+ let thisBetNumber = (totalBets + 1)
333+ if ((assetId == unit))
334+ then [IntegerEntry(gameTotalBetsLabel, (totalBets + 1)), StringEntry(betDetailsLabel(thisBetNumber), ((((toBase58String(i.caller.bytes) + "-") + toString(amount)) + "-") + bet)), IntegerEntry(betGameLabel(thisBetNumber), GAMESCOUNTER)]
335+ else [IntegerEntry(gameTotalBetsLabel, (totalBets + 1)), StringEntry(betDetailsLabel(thisBetNumber), ((((toBase58String(i.caller.bytes) + "-") + toString(amount)) + "-") + bet)), IntegerEntry(betGameLabel(thisBetNumber), GAMESCOUNTER)]
336+ case _ =>
337+ throw("Game has not been initalized.")
338+ }
339+ else throw("Game has already exceeded betting round")
340+ case _ =>
341+ throw("End height has not been defined.")
342+ }
343+ else throw((((((("Bet (" + toString(amount)) + ") is greater than maximum bet (") + toString(gamesMaxBet())) + "), lower than minimum (") + toString(gamesMinBet())) + ") or payment is not in correct assetId."))
344+ }
345+ case _ =>
346+ throw("Game does not exist or has already ended.")
347+ }
348+ case _ =>
349+ throw("Game needs to be initialized.")
350+ }
351+ }
352+ }
119353
120354
121355
122356 @Callable(i)
123-func processNextBet () = match gameTotalBets() {
124- case totalBets: Int =>
125- match gameProcessedBets() {
126- case lastProcessedBet: Int =>
127- let nextBet = (lastProcessedBet + 1)
128- if ((nextBet > totalBets))
129- then throw("Next bet has not been placed.")
130- else match gamesGetCounter() {
131- case gameNumber: Int =>
132- match gameWinnersCounter() {
133- case winnersCount: Int =>
134- let result = gameGetResult(gameNumber)
135- let betDetail = betDetails(nextBet)
136- if ((betDetail == result))
137- then {
138- let newWinnersCount = (winnersCount + 1)
139-[IntegerEntry(gameProcessedBetsLabel, nextBet), IntegerEntry(gameWinnersCounterLabel, (winnersCount + 1)), StringEntry(winnerDetailsLabel(newWinnersCount), toBase58String(i.caller.bytes))]
140- }
141- else [IntegerEntry(gameProcessedBetsLabel, nextBet)]
357+func endGame (rsaSign,gameNumber) = if (checkPermission(i.callerPublicKey))
358+ then throw("endGame_FORBBIDEN")
359+ else match gameGetState(gameNumber) {
360+ case state: Int =>
361+ if ((state == 1))
362+ then throw("Game is finished")
363+ else match gameGetEndHeight(gameNumber) {
364+ case gameHeight: Int =>
365+ if ((gameHeight > height))
366+ then throw(("Not enough blocks have past since game has started, game ends at block " + toString(gameHeight)))
367+ else match gameGetSumSha(gameNumber) {
368+ case SUMSHA: String =>
369+ let sig = fromBase64String(rsaSign)
370+ let rsaSigValid = rsaVerify(SHA256, fromBase58String(SUMSHA), sig, gameRSAPublic())
371+ match blockInfoByHeight(gameHeight) {
372+ case previousBlock: BlockInfo =>
373+ let randomHash = sha256((take(sig, 32) + take(previousBlock.generationSignature, 32)))
374+ if (!(rsaSigValid))
375+ then throw("INVALID_RSA_SIGN")
376+ else {
377+ let index = wheel[((toInt(randomHash) + value(gameNumber)) % 37)]
378+[IntegerEntry(gameStateLabel(gameNumber), 1), IntegerEntry(gameResultLabel(gameNumber), index), StringEntry(gameRandomHashLabel(gameNumber), toBase64String(randomHash))]
379+ }
380+ case _ =>
381+ throw("Last block does not exist.")
382+ }
142383 case _ =>
143- throw("Game has not been initialized, total winners not found")
384+ throw("SHA does not exist")
144385 }
145- case _ =>
146- throw("Game has not been initialized, total games not found")
147- }
148- case _ =>
149- throw("Game has not been initialized, total processed bets not found")
150- }
151- case _ =>
152- throw("Game has not been initialized, total bets not found")
153-}
386+ case _ =>
387+ throw("Cannot get game height.")
388+ }
389+ case _ =>
390+ throw("Game does not exist or has already ended")
391+ }
154392
155393
156394
157395 @Callable(i)
158-func calculatePrize () = match gameWinnersCounter() {
159- case winnersCount: Int =>
160- if ((winnersCount == 0))
161- then throw("There are no winners this round.")
162- else match gamePrizePot() {
163- case prizePotAmount: Int =>
164- let prizePot = gamePrizePot()
165- let prizeShareAmount = (prizePotAmount / winnersCount)
166-[IntegerEntry(gamePrizeShareAmountLabel, prizeShareAmount)]
167- case _ =>
168- throw("Game has not been initialized, total games not found")
396+func setParameter (parameterName,parameterValue) = if (checkPermission(i.callerPublicKey))
397+ then throw("setParameter_FORBBIDEN")
398+ else if ((parameterName == "changeMax"))
399+ then {
400+ let maximumValue = parseIntValue(parameterValue)
401+ let minimumValue = gamesMinBet()
402+ if ((0 > maximumValue))
403+ then throw("value cannot be lower than 0")
404+ else if ((minimumValue >= maximumValue))
405+ then throw((("value cannot be lower or equal than min bet (" + toString(minimumValue)) + ")"))
406+ else [IntegerEntry(gameMaxBetLabel, maximumValue)]
169407 }
170- case _ =>
171- throw("Game has not been initialized, total winners not found")
172-}
408+ else if ((parameterName == "changeMin"))
409+ then {
410+ let maximumValue = gamesMaxBet()
411+ let minimumValue = parseIntValue(parameterValue)
412+ if ((0 > minimumValue))
413+ then throw("value cannot be lower than 0")
414+ else if ((minimumValue >= maximumValue))
415+ then throw((("value cannot be greater or equal than min bet (" + toString(maximumValue)) + ")"))
416+ else [IntegerEntry(gameMinBetLabel, minimumValue)]
417+ }
418+ else if ((parameterName == "changeRSA"))
419+ then match gamesGetCounter() {
420+ case GAMESCOUNTER: Int =>
421+ match gameGetState(GAMESCOUNTER) {
422+ case state: Int =>
423+ if ((state != 1))
424+ then throw("Game has to be finished.")
425+ else [StringEntry(gameRSAPublicLabel, parameterValue)]
426+ case _ =>
427+[StringEntry(gameRSAPublicLabel, parameterValue)]
428+ }
429+ case _ =>
430+ throw("Game needs to be initialized.")
431+ }
432+ else throw("Setting not found. Allowed: changeMax, changeMin, changeRSA, changePubKey")
173433
174434
175-
176-@Callable(i)
177-func processNextWinner () = match gameWinnersCounter() {
178- case totalWinners: Int =>
179- if ((totalWinners == 0))
180- then throw("There are no winners this round.")
181- else match gameProcessedWinners() {
182- case lastProcessedWinner: Int =>
183- let nextWinner = (lastProcessedWinner + 1)
184- if ((nextWinner > totalWinners))
185- then throw("No more winners to be processed.")
186- else match gamePrizeShareAmount() {
187- case prizeShareAmount: Int =>
188- let betPlacer = winnerDetails(nextWinner)
189- let address = value(addressFromString(betPlacer))
190- let winnings = gamePrizeShareAmount()
191-[ScriptTransfer(address, prizeShareAmount, gameToken())]
192- case _ =>
193- throw("Game has not been initialized, prize share amount not found")
194- }
195- case _ =>
196- throw("Game has not been initialized, total processed winners not found")
197- }
198- case _ =>
199- throw("Game has not been initialized, total winners not found")
200-}
201-
435+@Verifier(tx)
436+func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
202437

github/deemru/w8io/169f3d6 
56.26 ms