tx · EbZsck9ofC6chtUBMqNUduEHB5L7feHPrWnYfaUwfVpN

3N2tusqAtDctK8iSTXS6F9rimmftmSuwLUX:  -0.05000000 Waves

2019.10.30 13:54 [742787] smart account 3N2tusqAtDctK8iSTXS6F9rimmftmSuwLUX > SELF 0.00000000 Waves

{ "type": 13, "id": "EbZsck9ofC6chtUBMqNUduEHB5L7feHPrWnYfaUwfVpN", "fee": 5000000, "feeAssetId": null, "timestamp": 1572432929629, "version": 1, "sender": "3N2tusqAtDctK8iSTXS6F9rimmftmSuwLUX", "senderPublicKey": "ACfUG5PwG2GssMuyEwVEhkYAbbbP1geSHR8XoNxLyu6V", "proofs": [ "531u5UmxTmnh24YGAgxz8kVfJAsguVmQbMpnRQ8rDJe2gDJdgYPcBqNQ8vRCCsrTvr4pbRTKc59E6hFdvtjX1eud" ], "script": "base64:AAIDAAAAAAAAAAkIARIAEgMKAQEAAAAEAAAAAA5SRVNFUlZBVElPTktFWQIAAAAQJFJFU0VSVkVEX0FNT1VOVAAAAAAEV0JFVAEAAAAgOkBptoM8ze1CVUAoYBmqau186uSZP0x2SswaAYBAj68BAAAAEkV4dHJhY3RSZXNlcnZlZEFtdAAAAAAEAAAAByRtYXRjaDAJAAQaAAAAAgUAAAAEdGhpcwUAAAAOUkVTRVJWQVRJT05LRVkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAA0ludAQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQAAAAAAAAAAAAEAAAAQRXh0cmFjdFBsYXllckFtdAAAAAEAAAAGd2FsbGV0BAAAAAckbWF0Y2gwCQAEGgAAAAIFAAAABHRoaXMFAAAABndhbGxldAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAADSW50BAAAAAFhBQAAAAckbWF0Y2gwBQAAAAFhAAAAAAAAAAAAAAAAAgAAAAFpAQAAAAdkZXBvc2l0AAAAAAQAAAAHcGF5bWVudAkBAAAAB2V4dHJhY3QAAAABCAUAAAABaQAAAAdwYXltZW50AwkBAAAAAiE9AAAAAggFAAAAB3BheW1lbnQAAAAHYXNzZXRJZAUAAAAEV0JFVAkAAAIAAAABAgAAABpQYXltZW50IHNob3VsZCBiZSBpbiBXYmV0LgQAAAAGd2FsbGV0CQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgQAAAAPbmV3UGxheWVyQW1vdW50CQAAZAAAAAIJAQAAABBFeHRyYWN0UGxheWVyQW10AAAAAQUAAAAGd2FsbGV0CAUAAAAHcGF5bWVudAAAAAZhbW91bnQEAAAAEW5ld1Jlc2VydmVkQW1vdW50CQAAZAAAAAIJAQAAABJFeHRyYWN0UmVzZXJ2ZWRBbXQAAAAACAUAAAAHcGF5bWVudAAAAAZhbW91bnQJAQAAAAxTY3JpcHRSZXN1bHQAAAACCQEAAAAIV3JpdGVTZXQAAAABCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACBQAAAA5SRVNFUlZBVElPTktFWQUAAAARbmV3UmVzZXJ2ZWRBbW91bnQJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIFAAAABndhbGxldAUAAAAPbmV3UGxheWVyQW1vdW50BQAAAANuaWwJAQAAAAtUcmFuc2ZlclNldAAAAAEFAAAAA25pbAAAAAFpAQAAAAh3aXRoZHJhdwAAAAEAAAAGYW1vdW50BAAAAAZ3YWxsZXQJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBAAAAAxwbGF5ZXJBbW91bnQJAQAAABBFeHRyYWN0UGxheWVyQW10AAAAAQUAAAAGd2FsbGV0AwkAAGYAAAACBQAAAAZhbW91bnQFAAAADHBsYXllckFtb3VudAkAAAIAAAABAgAAAD1UaGVyZSBpcyBub3QgZW5vdWdoIGJhbGFuY2UgdG8gd2l0aGRyYXcgdGhlIGFtb3VudCByZXF1ZXN0ZWQuBAAAAA9uZXdQbGF5ZXJBbW91bnQJAABlAAAAAgUAAAAMcGxheWVyQW1vdW50BQAAAAZhbW91bnQEAAAAEW5ld1Jlc2VydmVkQW1vdW50CQAAZQAAAAIJAQAAABJFeHRyYWN0UmVzZXJ2ZWRBbXQAAAAABQAAAAZhbW91bnQJAQAAAAxTY3JpcHRSZXN1bHQAAAACCQEAAAAIV3JpdGVTZXQAAAABCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACBQAAAA5SRVNFUlZBVElPTktFWQUAAAARbmV3UmVzZXJ2ZWRBbW91bnQJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIFAAAABndhbGxldAUAAAAPbmV3UGxheWVyQW1vdW50BQAAAANuaWwJAQAAAAtUcmFuc2ZlclNldAAAAAEJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAZhbW91bnQFAAAABFdCRVQFAAAAA25pbAAAAABbjjpz", "chainId": 84, "height": 742787, "spentComplexity": 0 } View: original | compacted Prev: 3EeGYFg14w8rP7G6zzZLd2RBSQJbvUNttjf5eLumEagr Next: FFdkm8c4aYMyHyycA8YtXpQ98QZeQtN2NppBq8bia24B Full:
OldNewDifferences
11 {-# STDLIB_VERSION 3 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let RSAPUBLIC = fromBase64String("base64:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAg4dAR6XbBDAS9hr/Ej3dJv6Ffc466x/mOGMWU3lrABs3qa8BHmuJGnkfbpEf2vAwYTOWPvvzfM10OBbfloSyq3c9MKvyTe1luBLGqW4vZUXIyvSgz1liyUVefIQy3dyF9jbeTZbC0bbcT/7O3DEL+01z6A+rDCacSZ0lGolSQ6AnhLxzIkVpOQJbrBmC+x+ZuZPCMWzJynd5aeOn7jaj/mkRVyxe6g/0OhWz4NiiZXeuMRB+8mKy0fWD/UlIlZWHsAS2ZmrkXKqjLq0/0wr8ILJkznjSqdnI5Ibjg3uQrj/4AN+i9r28aQ73/ZkPtY5Sbw0AOiABBu7gHmq9ayVxZQIDAQAB")
4+let RESERVATIONKEY = "$RESERVED_AMOUNT"
55
6-let GAMESCOUNTERKEY = "$GAME_NUM"
6+let WBET = base58'4vPcbA5yiwpWBVPALPGXus6fNdGEuYTpe4hAeSxM9Kj4'
77
8-let WBET = base58'23vgV9p9pD83A7CFbsDEc4zjanep7UeFo4ZRS6oGorhv'
9-
10-let FEEWAVESBET = 4
11-
12-let FEEMCAFEE = 2
13-
14-let WAVELET = 100000000
15-
16-let STATESUBMITTED = "SUBMITTED"
17-
18-let STATEACCEPTED = "ACCEPTED"
19-
20-let STATEFINISHED = "FINISHED"
21-
22-let STATECANCELED = "CANCELED"
23-
24-let COINRED = "RED"
25-
26-let COINBLUE = "BLUE"
27-
28-let BETMINWAVES = ((1 * WAVELET) / 2)
29-
30-let BETMINWBET = (100 * WAVELET)
31-
32-let IdxGameState = 0
33-
34-let IdxPlayerACoin = 1
35-
36-let IdxPlayerAPubKey58 = 2
37-
38-let IdxPayType = 3
39-
40-let IdxPayAmt = 4
41-
42-let IdxWinAmt = 5
43-
44-let IdxPlayerBCoin = 6
45-
46-let IdxPlayerBPubKey58 = 7
47-
48-let IdxLuckyCoin = 8
49-
50-func IncrementGameNum () = {
51- let gameNum = match getInteger(this, GAMESCOUNTERKEY) {
52- case num: Int =>
53- num
54- case _ =>
55- 0
56- }
57- (gameNum + 1)
58- }
8+func ExtractReservedAmt () = match getInteger(this, RESERVATIONKEY) {
9+ case a: Int =>
10+ a
11+ case _ =>
12+ 0
13+}
5914
6015
61-func generateNumber (inv,max,min) = {
62- let lastPlay = match getBinary(this, "lastPlay") {
63- case s: ByteVector =>
64- s
65- case a: Unit =>
66- base58'2ee4oFDYriWJ9EMeR'
67- case _ =>
68- throw()
69- }
70- let rand = (((((lastPlay + inv.transactionId) + inv.callerPublicKey) + lastBlock.generationSignature) + toBytes(lastBlock.timestamp)) + toBytes(lastBlock.height))
71- (((toInt(sha256(rand)) % 1000) % ((max - min) + 1)) + 1)
72- }
73-
74-
75-func GenerateRandInt (gameId,rsaSign) = {
76- let rsaSigValid = rsaVerify(SHA256, toBytes(gameId), rsaSign, RSAPUBLIC)
77- if (rsaSigValid)
78- then {
79- let rand = (toInt(sha256(rsaSign)) % 100)
80- if ((0 > rand))
81- then ((-1 * rand) + 1)
82- else (rand + 1)
83- }
84- else throw("Invalid RSA signature")
85- }
86-
87-
88-func paymentType (payment) = if ((payment.assetId == WBET))
89- then "WBET"
90- else "WAVES"
91-
92-
93-func tokenType (token) = if ((token == "WBET"))
94- then WBET
95- else unit
96-
97-
98-func FormatGameDataParam (p) = {
99- let s = size(p)
100- if ((s == 0))
101- then throw("Parameter size must be greater then 0")
102- else if ((s > 99))
103- then throw("Parameter size must be less then 100")
104- else if ((10 > s))
105- then (("0" + toString(s)) + p)
106- else (toString(s) + p)
107- }
108-
109-
110-func FormatGameDataStr (gameState,playerACoin,playerAPubKey58,payType,payAmount,winAmt,playerBCoin,playerBPubKey58,luckyCoin) = {
111- let fullStateStr = ((((((((((FormatGameDataParam(gameState) + "_") + FormatGameDataParam(playerACoin)) + "_") + FormatGameDataParam(playerAPubKey58)) + "_") + FormatGameDataParam(payType)) + "_") + FormatGameDataParam(toString(payAmount))) + "_") + FormatGameDataParam(toString(winAmt)))
112- if (if (if ((playerBCoin == ""))
113- then true
114- else (playerBPubKey58 == ""))
115- then true
116- else (luckyCoin == ""))
117- then fullStateStr
118- else ((((((fullStateStr + "_") + FormatGameDataParam(playerBCoin)) + "_") + FormatGameDataParam(playerBPubKey58)) + "_") + FormatGameDataParam(luckyCoin))
119- }
120-
121-
122-func RemoveUnderscoreIfPresent (remaining) = if ((size(remaining) > 0))
123- then drop(remaining, 1)
124- else remaining
125-
126-
127-func ParseNextAttribute (remaining) = {
128- let s = size(remaining)
129- if ((s > 0))
130- then {
131- let nn = parseIntValue(take(remaining, 2))
132- let v = take(drop(remaining, 2), nn)
133- let tmpRemaining = drop(remaining, (nn + 2))
134- let remainingState = RemoveUnderscoreIfPresent(tmpRemaining)
135-[v, remainingState]
136- }
137- else throw("Empty string was passed into parseNextAttribute func")
138- }
139-
140-
141-func ParseGameRawDataStr (rawStateStr) = {
142- let gameState = ParseNextAttribute(rawStateStr)
143- let paCoin = ParseNextAttribute(gameState[1])
144- let paPubKey58 = ParseNextAttribute(paCoin[1])
145- let payType = ParseNextAttribute(paPubKey58[1])
146- let payAmt = ParseNextAttribute(payType[1])
147- let winAmt = ParseNextAttribute(payAmt[1])
148-[gameState[0], paCoin[0], paPubKey58[0], payType[0], payAmt[0], winAmt[0]]
149- }
150-
151-
152-func ExtractGameDataList (gameId) = {
153- let rawDataStr = match getString(this, gameId) {
154- case str: String =>
155- str
156- case _ =>
157- throw(("Couldn't find game by " + gameId))
158- }
159- ParseGameRawDataStr(rawDataStr)
160- }
161-
162-
163-func ValidateBetAndDefineWinAmt (amount,playerCoin,paymentType) = if (if ((playerCoin != COINRED))
164- then (playerCoin != COINBLUE)
165- else false)
166- then throw("Invalid play, change your bet to RED or BLUE coin. Game aborted.")
167- else if (if ((paymentType == "WBET"))
168- then (BETMINWBET > amount)
169- else false)
170- then throw(("The minimum bet on Wbet is " + toString((BETMINWBET / WAVELET))))
171- else if (if ((paymentType == "WAVES"))
172- then (BETMINWAVES > amount)
173- else false)
174- then throw(("The minimum bet on Waves is " + toString((BETMINWAVES / WAVELET))))
175- else (((amount * 2) * (100 - (FEEWAVESBET + FEEMCAFEE))) / 100)
16+func ExtractPlayerAmt (wallet) = match getInteger(this, wallet) {
17+ case a: Int =>
18+ a
19+ case _ =>
20+ 0
21+}
17622
17723
17824 @Callable(i)
179-func playCoin (paCoin) = {
180- let gameId = toBase58String(i.transactionId)
181- let gameIdUsed = isDefined(getString(this, gameId))
25+func deposit () = {
18226 let payment = extract(i.payment)
183- let feeAssetId = isDefined(i.feeAssetId)
184- if (if ((payment.assetId != assetInfo(base58'WAVES')))
185- then (payment.assetId != WBET)
186- else false)
187- then throw("Payment should be in Wbet or Waves. Game aborted.")
188- else if (feeAssetId)
189- then throw("Transaction's fee must be in Waves. Game aborted.")
190- else if (gameIdUsed)
191- then throw("Passed gameId had been used before. Game aborted.")
192- else if ((i.caller == this))
193- then throw("Coinflip contract cannot create a game. Game aborted.")
194- else {
195- let newGameNum = IncrementGameNum()
196- let playerAPubKey58 = toBase58String(i.callerPublicKey)
197- let payType = paymentType(payment)
198- let winAmt = ValidateBetAndDefineWinAmt(payment.amount, paCoin, payType)
199- let gameDataStr = FormatGameDataStr(STATESUBMITTED, paCoin, playerAPubKey58, payType, payment.amount, winAmt, "", "", "")
200- ScriptResult(WriteSet([DataEntry(GAMESCOUNTERKEY, newGameNum), DataEntry(gameId, gameDataStr)]), TransferSet(nil))
201- }
27+ if ((payment.assetId != WBET))
28+ then throw("Payment should be in Wbet.")
29+ else {
30+ let wallet = toString(i.caller)
31+ let newPlayerAmount = (ExtractPlayerAmt(wallet) + payment.amount)
32+ let newReservedAmount = (ExtractReservedAmt() + payment.amount)
33+ ScriptResult(WriteSet([DataEntry(RESERVATIONKEY, newReservedAmount), DataEntry(wallet, newPlayerAmount)]), TransferSet(nil))
34+ }
20235 }
20336
20437
20538
20639 @Callable(i)
207-func acceptCoinChallenge (gameId,rsaSig) = {
208- let gameDataList = ExtractGameDataList(gameId)
209- let gameState = gameDataList[IdxGameState]
210- let paCoin = gameDataList[IdxPlayerACoin]
211- let paPubKey58 = gameDataList[IdxPlayerAPubKey58]
212- let payType = gameDataList[IdxPayType]
213- let payAmt = parseIntValue(gameDataList[IdxPayAmt])
214- let winAmt = parseIntValue(gameDataList[IdxWinAmt])
215- let payment = extract(i.payment)
216- let feeAssetId = isDefined(i.feeAssetId)
217- let pbPubKey58 = toBase58String(i.callerPublicKey)
218- let payTypeB = paymentType(payment)
219- if (if ((payment.assetId != assetInfo(base58'WAVES')))
220- then (payment.assetId != WBET)
221- else false)
222- then throw("Payment should be in Wbet or Waves. Game aborted.")
223- else if (feeAssetId)
224- then throw("Transaction's fee must be in Waves. Game aborted.")
225- else if ((paPubKey58 == pbPubKey58))
226- then throw("You can't accept a challenge created by yourself. Game aborted.")
227- else if ((payType != payTypeB))
228- then throw("Payment must be made in the same currency token as the bet, WBET/WBET or WAVES/WAVES. Game aborted.")
229- else if ((payAmt != payment.amount))
230- then throw("Payout must be equal to the challenger bet amount. Game aborted.")
231- else if ((gameState != STATESUBMITTED))
232- then throw("Invalid game state for passed gameId. Game aborted.")
233- else if ((i.caller == this))
234- then throw("Coinflip contract cannot accept a game. Game aborted.")
235- else {
236- let rand = generateNumber(i, 100, 0)
237- let luckyCoin = if ((rand > 50))
238- then COINRED
239- else COINBLUE
240- let pbCoin = if ((paCoin == COINRED))
241- then COINBLUE
242- else COINRED
243- let tokenAssetId = tokenType(payType)
244- let newGameDataStr = FormatGameDataStr(STATEACCEPTED, paCoin, paPubKey58, payType, payAmt, winAmt, pbCoin, pbPubKey58, luckyCoin)
245- ScriptResult(WriteSet([DataEntry(gameId, newGameDataStr)]), TransferSet(nil))
246- }
247- }
248-
249-
250-
251-@Callable(i)
252-func cancelCoinChallenge (gameId) = {
253- let gameDataList = ExtractGameDataList(gameId)
254- let gameState = gameDataList[IdxGameState]
255- let paCoin = gameDataList[IdxPlayerACoin]
256- let paPubKey58 = gameDataList[IdxPlayerAPubKey58]
257- let payType = gameDataList[IdxPayType]
258- let payAmt = parseIntValue(gameDataList[IdxPayAmt])
259- let winAmt = parseIntValue(gameDataList[IdxWinAmt])
260- let pubKey58 = toBase58String(i.callerPublicKey)
261- let feeAssetId = isDefined(i.feeAssetId)
262- if (feeAssetId)
263- then throw("Transaction's fee must be in Waves. Game aborted.")
264- else if ((gameState != STATESUBMITTED))
265- then throw("Invalid game state for passed gameId. Game aborted.")
266- else if ((paPubKey58 != pubKey58))
267- then throw("You cannot cancel a game created by another player. Game aborted.")
268- else if ((i.caller == this))
269- then throw("Coinflip contract cannot cancel a game. Game aborted.")
270- else {
271- let newGameDataStr = FormatGameDataStr(STATECANCELED, paCoin, paPubKey58, payType, payAmt, winAmt, "", "", "")
272- let refundAmt = (payAmt - ((payAmt * FEEWAVESBET) / 100))
273- let refundWallet = addressFromPublicKey(fromBase58String(paPubKey58))
274- let refundToken = tokenType(payType)
275- ScriptResult(WriteSet([DataEntry(gameId, newGameDataStr)]), TransferSet([ScriptTransfer(refundWallet, refundAmt, refundToken)]))
276- }
40+func withdraw (amount) = {
41+ let wallet = toString(i.caller)
42+ let playerAmount = ExtractPlayerAmt(wallet)
43+ if ((amount > playerAmount))
44+ then throw("There is not enough balance to withdraw the amount requested.")
45+ else {
46+ let newPlayerAmount = (playerAmount - amount)
47+ let newReservedAmount = (ExtractReservedAmt() - amount)
48+ ScriptResult(WriteSet([DataEntry(RESERVATIONKEY, newReservedAmount), DataEntry(wallet, newPlayerAmount)]), TransferSet([ScriptTransfer(i.caller, amount, WBET)]))
49+ }
27750 }
27851
27952

github/deemru/w8io/873ac7e 
57.68 ms