tx · 8SW79yERkseQURvtRNdZpXn41YYvGyR7r9wgcsRYQe8h

3N4Kzbxu521DHPxcgrmZ4XUqN2kF6TqLTzs:  -0.01000000 Waves

2023.09.01 15:52 [2736333] smart account 3N4Kzbxu521DHPxcgrmZ4XUqN2kF6TqLTzs > SELF 0.00000000 Waves

{ "type": 13, "id": "8SW79yERkseQURvtRNdZpXn41YYvGyR7r9wgcsRYQe8h", "fee": 1000000, "feeAssetId": null, "timestamp": 1693572747622, "version": 2, "chainId": 84, "sender": "3N4Kzbxu521DHPxcgrmZ4XUqN2kF6TqLTzs", "senderPublicKey": "8yQuxvQ2qLzXJrgbKZHbsfnNNjuU5wfHheyVujdALGsF", "proofs": [ "24vED4nXBsc6j7EcBBvPK1pbE77CUUFYPEWPaHF3QX5jzh1PVMyuDtmhD6a2sD8tCHQQY7Fd3M7i7ScivyPaPeci" ], "script": "base64:BgIfCAISABIECgIIARIGCgQIAQEIEgQKAggBEgUKAwgICBIADmxvdHRlcnlBc3NldElECQDZBAECLDNMejIzbVNVdlQxRXN3Y0JuMnNVUllKRzJhdDhyRzVhRnVVclRBd2FQTTZRAAp0aWNrZXRTaXplAAEBEGdldEludGVnZXJPckVsc2UCA2tleQN2YWwJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUDa2V5BQN2YWwBD2dldFN0cmluZ09yRWxzZQIDa2V5A3ZhbAkBC3ZhbHVlT3JFbHNlAgkAoggBBQNrZXkFA3ZhbAECbWsBAXgJALkJAgUBeAIBXwERa2V5QWRyVG90YWxTdGFrZWQBA2FkcgkBAm1rAQkAzAgCAgNhZHIJAMwIAgUDYWRyCQDMCAICC3RvdGFsU3Rha2VkBQNuaWwBFWtleUxvdHRlcnlUb3RhbFN0YWtlZAELbG90dGVyeU5hbWUJAQJtawEJAMwIAgIHbG90dGVyeQkAzAgCBQtsb3R0ZXJ5TmFtZQkAzAgCAgt0b3RhbFN0YWtlZAUDbmlsARNrZXlMb3R0ZXJ5QWRyU3Rha2VkAgtsb3R0ZXJ5TmFtZQNhZHIJAQJtawEJAMwIAgIHbG90dGVyeQkAzAgCBQtsb3R0ZXJ5TmFtZQkAzAgCAgNhZHIJAMwIAgUDYWRyCQDMCAICBnN0YWtlZAUDbmlsARNrZXlMb3R0ZXJ5QWRyTG9ja2VkAgtsb3R0ZXJ5TmFtZQNhZHIJAQJtawEJAMwIAgIHbG90dGVyeQkAzAgCBQtsb3R0ZXJ5TmFtZQkAzAgCAgNhZHIJAMwIAgUDYWRyCQDMCAICBmxvY2tlZAUDbmlsARVrZXlMb3R0ZXJ5RmluYWxIZWlnaHQBC2xvdHRlcnlOYW1lCQECbWsBCQDMCAICB2xvdHRlcnkJAMwIAgULbG90dGVyeU5hbWUJAMwIAgILZmluYWxIZWlnaHQFA25pbAEUa2V5TG90dGVyeVByaXplVmFsdWUCC2xvdHRlcnlOYW1lB3ByaXplSUQJAQJtawEJAMwIAgIHbG90dGVyeQkAzAgCBQtsb3R0ZXJ5TmFtZQkAzAgCAgVwcml6ZQkAzAgCCQCkAwEFB3ByaXplSUQJAMwIAgIFdmFsdWUFA25pbAEYa2V5TG90dGVyeVByaXplVGhyZXNob2xkAgtsb3R0ZXJ5TmFtZQdwcml6ZUlECQECbWsBCQDMCAICB2xvdHRlcnkJAMwIAgULbG90dGVyeU5hbWUJAMwIAgIFcHJpemUJAMwIAgkApAMBBQdwcml6ZUlECQDMCAICCXRocmVzaG9sZAUDbmlsARVrZXlMb3R0ZXJ5UHJpemVDaG9pY2UCC2xvdHRlcnlOYW1lB3ByaXplSUQJAQJtawEJAMwIAgIHbG90dGVyeQkAzAgCBQtsb3R0ZXJ5TmFtZQkAzAgCAgVwcml6ZQkAzAgCCQCkAwEFB3ByaXplSUQJAMwIAgIGY2hvaWNlBQNuaWwBFWtleUxvdHRlcnlQcml6ZVJhbmRvbQILbG90dGVyeU5hbWUHcHJpemVJRAkBAm1rAQkAzAgCAgdsb3R0ZXJ5CQDMCAIFC2xvdHRlcnlOYW1lCQDMCAICBXByaXplCQDMCAIJAKQDAQUHcHJpemVJRAkAzAgCAgZyYW5kb20FA25pbAEWa2V5TG90dGVyeVRpY2tldHNPd25lcgMLbG90dGVyeU5hbWUEZnJvbQJ0bwkBAm1rAQkAzAgCAgdsb3R0ZXJ5CQDMCAIFC2xvdHRlcnlOYW1lCQDMCAICBGZyb20JAMwIAgkApAMBBQRmcm9tCQDMCAICAnRvCQDMCAIJAKQDAQUCdG8JAMwIAgIFb3duZXIFA25pbAASX2FjdGl2ZUxvdHRlcnlOYW1lCQECbWsBCQDMCAICBXBhcmFtCQDMCAICEWFjdGl2ZUxvdHRlcnlOYW1lBQNuaWwAEl9nbG9iYWxUb3RhbFN0YWtlZAkBAm1rAQkAzAgCAgVwYXJhbQkAzAgCAhFnbG9iYWxUb3RhbFN0YWtlZAUDbmlsARFhY3RpdmVMb3R0ZXJ5TmFtZQAEC2xvdHRlcnlOYW1lCQEPZ2V0U3RyaW5nT3JFbHNlAgUSX2FjdGl2ZUxvdHRlcnlOYW1lAgADCQAAAgULbG90dGVyeU5hbWUCAAIABBJsb3R0ZXJ5RmluYWxIZWlnaHQJARFAZXh0ck5hdGl2ZSgxMDU1KQEJARVrZXlMb3R0ZXJ5RmluYWxIZWlnaHQBBQtsb3R0ZXJ5TmFtZQMJAGcCBQZoZWlnaHQFEmxvdHRlcnlGaW5hbEhlaWdodAIABQtsb3R0ZXJ5TmFtZQUBaQEFc3Rha2UABAtsb3R0ZXJ5TmFtZQkBEWFjdGl2ZUxvdHRlcnlOYW1lAAMJAAACBQtsb3R0ZXJ5TmFtZQIACQACAQISTG90dGVyeSBub3QgYWN0aXZlAwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECEE5vIHBheW1lbnQgYWRkZWQDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhdUb28gbWFueSBwYXltZW50cyBhZGRlZAMJAQIhPQIICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAUObG90dGVyeUFzc2V0SUQJAAIBAhVXcm9uZyBwYXltZW50IGFzc2V0SWQEBmFtb3VudAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQEDHRpY2tldEFtb3VudAkAaQIFBmFtb3VudAUKdGlja2V0U2l6ZQMJAAACBQx0aWNrZXRBbW91bnQAAAkAAgECJU5vdCBlbm91Z2ggdG8gYnV5IGF0IGxlYXN0IG9uZSB0aWNrZXQEDWNhbGxlckFkZHJlc3MJAKUIAQgFAWkGY2FsbGVyBBNfbG90dGVyeVRvdGFsU3Rha2VkCQEVa2V5TG90dGVyeVRvdGFsU3Rha2VkAQULbG90dGVyeU5hbWUEEmxvdHRlcnlUb3RhbFN0YWtlZAkBEGdldEludGVnZXJPckVsc2UCBRNfbG90dGVyeVRvdGFsU3Rha2VkAAAEBl9vd25lcgkBFmtleUxvdHRlcnlUaWNrZXRzT3duZXIDBQtsb3R0ZXJ5TmFtZQUSbG90dGVyeVRvdGFsU3Rha2VkCQBlAgkAZAIFEmxvdHRlcnlUb3RhbFN0YWtlZAUMdGlja2V0QW1vdW50AAEED19hZHJUb3RhbFN0YWtlZAkBEWtleUFkclRvdGFsU3Rha2VkAQUNY2FsbGVyQWRkcmVzcwQOYWRyVG90YWxTdGFrZWQJARBnZXRJbnRlZ2VyT3JFbHNlAgUPX2FkclRvdGFsU3Rha2VkAAAEEV9sb3R0ZXJ5QWRyU3Rha2VkCQETa2V5TG90dGVyeUFkclN0YWtlZAIFC2xvdHRlcnlOYW1lBQ1jYWxsZXJBZGRyZXNzBBVhZHJMb3R0ZXJ5VG90YWxTdGFrZWQJARBnZXRJbnRlZ2VyT3JFbHNlAgURX2xvdHRlcnlBZHJTdGFrZWQAAAQGY2hhbmdlCQBlAgUGYW1vdW50CQBoAgUMdGlja2V0QW1vdW50BQp0aWNrZXRTaXplBBFnbG9iYWxUb3RhbFN0YWtlZAkBEGdldEludGVnZXJPckVsc2UCBRJfZ2xvYmFsVG90YWxTdGFrZWQAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFBmNoYW5nZQUObG90dGVyeUFzc2V0SUQJAMwIAgkBC1N0cmluZ0VudHJ5AgUGX293bmVyBQ1jYWxsZXJBZGRyZXNzCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRJfZ2xvYmFsVG90YWxTdGFrZWQJAGQCBRFnbG9iYWxUb3RhbFN0YWtlZAUMdGlja2V0QW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRNfbG90dGVyeVRvdGFsU3Rha2VkCQBkAgUSbG90dGVyeVRvdGFsU3Rha2VkBQx0aWNrZXRBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFD19hZHJUb3RhbFN0YWtlZAkAZAIFDmFkclRvdGFsU3Rha2VkBQx0aWNrZXRBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFEV9sb3R0ZXJ5QWRyU3Rha2VkCQBkAgUVYWRyTG90dGVyeVRvdGFsU3Rha2VkBQx0aWNrZXRBbW91bnQFA25pbAFpAQxzdGFydExvdHRlcnkCC2xvdHRlcnlOYW1lEmxvdHRlcnlGaW5hbEhlaWdodAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECCkFkbWluIG9ubHkJAMwIAgkBC1N0cmluZ0VudHJ5AgUSX2FjdGl2ZUxvdHRlcnlOYW1lBQtsb3R0ZXJ5TmFtZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFWtleUxvdHRlcnlGaW5hbEhlaWdodAEFC2xvdHRlcnlOYW1lBRJsb3R0ZXJ5RmluYWxIZWlnaHQFA25pbAFpAQxkZWNsYXJlUHJpemUEC2xvdHRlcnlOYW1lB3ByaXplSWQOcHJpemVUaHJlc2hvbGQKcHJpemVWYWx1ZQMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECCkFkbWluIG9ubHkJAMwIAgkBDEludGVnZXJFbnRyeQIJARhrZXlMb3R0ZXJ5UHJpemVUaHJlc2hvbGQCBQtsb3R0ZXJ5TmFtZQUHcHJpemVJZAUOcHJpemVUaHJlc2hvbGQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFGtleUxvdHRlcnlQcml6ZVZhbHVlAgULbG90dGVyeU5hbWUFB3ByaXplSWQFCnByaXplVmFsdWUFA25pbAFpARRmaW5hbGFpemVQcml6ZVJhbmRvbQILbG90dGVyeU5hbWUHcHJpemVJZAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECCkFkbWluIG9ubHkEEmxvdHRlcnlGaW5hbEhlaWdodAkBEUBleHRyTmF0aXZlKDEwNTUpAQkBFWtleUxvdHRlcnlGaW5hbEhlaWdodAEFC2xvdHRlcnlOYW1lAwkAZgIJAGQCBRJsb3R0ZXJ5RmluYWxIZWlnaHQAAQUGaGVpZ2h0CQACAQIXTG90dGVyeSBpcyBub3Qgb3ZlciB5ZXQEEWxvdHRlcnlQcml6ZVZhbHVlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBFGtleUxvdHRlcnlQcml6ZVZhbHVlAgULbG90dGVyeU5hbWUFB3ByaXplSWQCFFByaXplIGRvZXMgbm90IGV4aXN0BAtmaW5hbEJsb2NrMAkBBXZhbHVlAQkA7QcBBRJsb3R0ZXJ5RmluYWxIZWlnaHQEC2ZpbmFsQmxvY2sxCQEFdmFsdWUBCQDtBwEJAGQCBRJsb3R0ZXJ5RmluYWxIZWlnaHQAAQQOcHJpemVSYW5kb21SYXcJAJ4DAQkA9wMBCQDLAQIJAMsBAgkAywECAQl2h2WWWi216vIJAJoDAQUHcHJpemVJZAkBBXZhbHVlAQgFC2ZpbmFsQmxvY2swA3ZyZgkBBXZhbHVlAQgFC2ZpbmFsQmxvY2sxA3ZyZgQLcHJpemVSYW5kb20DCQC/AgIJALYCAQAABQ5wcml6ZVJhbmRvbVJhdwkAvgIBBQ5wcml6ZVJhbmRvbVJhdwUOcHJpemVSYW5kb21SYXcJAMwIAgkBC1N0cmluZ0VudHJ5AgkBFWtleUxvdHRlcnlQcml6ZVJhbmRvbQIFC2xvdHRlcnlOYW1lBQdwcml6ZUlkCQCmAwEFC3ByaXplUmFuZG9tBQNuaWwBaQESZGVjbGFyZVByaXplV2lubmVyAwtsb3R0ZXJ5TmFtZQdwcml6ZUlkCXdpbm5lckFkcgMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECCkFkbWluIG9ubHkJAMwIAgkBC1N0cmluZ0VudHJ5AgIAAgAFA25pbAECdHgBBnZlcmlmeQAJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAIBQJ0eA9zZW5kZXJQdWJsaWNLZXld86KR", "height": 2736333, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: G7NkxgAfk2ZZCr5khc1QMJ5s799kj65gXxtJ7pm1dWZz Next: DN7jhGs21wgMBEH7XJMegDU6v1WdtCuPm2SnXkVY747P Diff:
OldNewDifferences
2020 func keyLotteryTotalStaked (lotteryName) = mk(["lottery", lotteryName, "totalStaked"])
2121
2222
23-func keyAdrLotteryTotalStaked (lotteryName,adr) = mk(["lottery", lotteryName, "adr", adr, "totalStaked"])
23+func keyLotteryAdrStaked (lotteryName,adr) = mk(["lottery", lotteryName, "adr", adr, "staked"])
24+
25+
26+func keyLotteryAdrLocked (lotteryName,adr) = mk(["lottery", lotteryName, "adr", adr, "locked"])
2427
2528
2629 func keyLotteryFinalHeight (lotteryName) = mk(["lottery", lotteryName, "finalHeight"])
2730
2831
29-func keyLotteryPrizeValue (lotteryName,prizeID) = mk(["lottery", lotteryName, "prize", prizeID, "value"])
32+func keyLotteryPrizeValue (lotteryName,prizeID) = mk(["lottery", lotteryName, "prize", toString(prizeID), "value"])
3033
3134
32-func keyLotteryPrizeChoice (lotteryName,prizeID) = mk(["lottery", lotteryName, "prize", prizeID, "choice"])
35+func keyLotteryPrizeThreshold (lotteryName,prizeID) = mk(["lottery", lotteryName, "prize", toString(prizeID), "threshold"])
36+
37+
38+func keyLotteryPrizeChoice (lotteryName,prizeID) = mk(["lottery", lotteryName, "prize", toString(prizeID), "choice"])
39+
40+
41+func keyLotteryPrizeRandom (lotteryName,prizeID) = mk(["lottery", lotteryName, "prize", toString(prizeID), "random"])
42+
43+
44+func keyLotteryTicketsOwner (lotteryName,from,to) = mk(["lottery", lotteryName, "from", toString(from), "to", toString(to), "owner"])
3345
3446
3547 let _activeLotteryName = mk(["param", "activeLotteryName"])
48+
49+let _globalTotalStaked = mk(["param", "globalTotalStaked"])
3650
3751 func activeLotteryName () = {
3852 let lotteryName = getStringOrElse(_activeLotteryName, "")
4054 then ""
4155 else {
4256 let lotteryFinalHeight = getIntegerValue(keyLotteryFinalHeight(lotteryName))
43- if (((height - 1) >= lotteryFinalHeight))
57+ if ((height >= lotteryFinalHeight))
4458 then ""
4559 else lotteryName
4660 }
6074 then throw("Wrong payment assetId")
6175 else {
6276 let amount = i.payments[0].amount
63- let ticketAmount = 2305843009213688951
77+ let ticketAmount = (amount / ticketSize)
6478 if ((ticketAmount == 0))
6579 then throw("Not enough to buy at least one ticket")
6680 else {
6781 let callerAddress = toString(i.caller)
6882 let _lotteryTotalStaked = keyLotteryTotalStaked(lotteryName)
69- let lotteryTotalStaked = getIntegerValue(_lotteryTotalStaked)
70- let _owner = mk(["lottery", lotteryName, "from", toString(lotteryTotalStaked), "to", toString(((lotteryTotalStaked + ticketAmount) - 1)), "owner"])
83+ let lotteryTotalStaked = getIntegerOrElse(_lotteryTotalStaked, 0)
84+ let _owner = keyLotteryTicketsOwner(lotteryName, lotteryTotalStaked, ((lotteryTotalStaked + ticketAmount) - 1))
7185 let _adrTotalStaked = keyAdrTotalStaked(callerAddress)
7286 let adrTotalStaked = getIntegerOrElse(_adrTotalStaked, 0)
73- let _adrLotteryTotalStaked = keyAdrLotteryTotalStaked(lotteryName, callerAddress)
74- let adrLotteryTotalStaked = getIntegerOrElse(_adrLotteryTotalStaked, 0)
87+ let _lotteryAdrStaked = keyLotteryAdrStaked(lotteryName, callerAddress)
88+ let adrLotteryTotalStaked = getIntegerOrElse(_lotteryAdrStaked, 0)
7589 let change = (amount - (ticketAmount * ticketSize))
76-[IntegerEntry(_lotteryTotalStaked, (lotteryTotalStaked + ticketAmount)), StringEntry(_owner, callerAddress), IntegerEntry(_adrTotalStaked, (adrTotalStaked + ticketAmount)), IntegerEntry(_adrLotteryTotalStaked, (adrLotteryTotalStaked + ticketAmount))]
90+ let globalTotalStaked = getIntegerOrElse(_globalTotalStaked, 0)
91+[ScriptTransfer(i.caller, change, lotteryAssetID), StringEntry(_owner, callerAddress), IntegerEntry(_globalTotalStaked, (globalTotalStaked + ticketAmount)), IntegerEntry(_lotteryTotalStaked, (lotteryTotalStaked + ticketAmount)), IntegerEntry(_adrTotalStaked, (adrTotalStaked + ticketAmount)), IntegerEntry(_lotteryAdrStaked, (adrLotteryTotalStaked + ticketAmount))]
7792 }
7893 }
7994 }
8196
8297
8398 @Callable(i)
84-func claim () = if ((size(i.payments) > 0))
85- then throw("No payments needed")
99+func startLottery (lotteryName,lotteryFinalHeight) = if ((i.caller != this))
100+ then throw("Admin only")
101+ else [StringEntry(_activeLotteryName, lotteryName), IntegerEntry(keyLotteryFinalHeight(lotteryName), lotteryFinalHeight)]
102+
103+
104+
105+@Callable(i)
106+func declarePrize (lotteryName,prizeId,prizeThreshold,prizeValue) = if ((i.caller != this))
107+ then throw("Admin only")
108+ else [IntegerEntry(keyLotteryPrizeThreshold(lotteryName, prizeId), prizeThreshold), StringEntry(keyLotteryPrizeValue(lotteryName, prizeId), prizeValue)]
109+
110+
111+
112+@Callable(i)
113+func finalaizePrizeRandom (lotteryName,prizeId) = if ((i.caller != this))
114+ then throw("Admin only")
86115 else {
87- let callerAddress = toString(i.caller)
88- let lotteryName = activeLotteryName()
89- let stakedInActiveLottery = if ((lotteryName == ""))
90- then 0
91- else getIntegerOrElse(keyAdrLotteryTotalStaked(lotteryName, callerAddress), 0)
92- let _adrTotalStaked = keyAdrTotalStaked(callerAddress)
93- let adrTotalStaked = getIntegerOrElse(_adrTotalStaked, 0)
94- let available = (adrTotalStaked - stakedInActiveLottery)
95- if ((0 >= available))
96- then throw("No assets available for claim")
97- else [ScriptTransfer(i.caller, available, lotteryAssetID), IntegerEntry(_adrTotalStaked, (adrTotalStaked - available))]
116+ let lotteryFinalHeight = getIntegerValue(keyLotteryFinalHeight(lotteryName))
117+ if (((lotteryFinalHeight + 1) > height))
118+ then throw("Lottery is not over yet")
119+ else {
120+ let lotteryPrizeValue = valueOrErrorMessage(getString(keyLotteryPrizeValue(lotteryName, prizeId)), "Prize does not exist")
121+ let finalBlock0 = value(blockInfoByHeight(lotteryFinalHeight))
122+ let finalBlock1 = value(blockInfoByHeight((lotteryFinalHeight + 1)))
123+ let prizeRandomRaw = toBigInt(sha256((((base58'2WWKxchwx7zBB' + toBytes(prizeId)) + value(finalBlock0.vrf)) + value(finalBlock1.vrf))))
124+ let prizeRandom = if ((toBigInt(0) > prizeRandomRaw))
125+ then -(prizeRandomRaw)
126+ else prizeRandomRaw
127+[StringEntry(keyLotteryPrizeRandom(lotteryName, prizeId), toString(prizeRandom))]
128+ }
98129 }
99130
100131
101132
102133 @Callable(i)
103-func startLottery (lotteryName,lotteryFinalHeight) = if ((i.caller != this))
134+func declarePrizeWinner (lotteryName,prizeId,winnerAdr) = if ((i.caller != this))
104135 then throw("Admin only")
105- else [StringEntry(_activeLotteryName, lotteryName), IntegerEntry(keyLotteryFinalHeight(lotteryName), lotteryFinalHeight), IntegerEntry(keyLotteryTotalStaked(lotteryName), 0)]
106-
107-
108-
109-@Callable(i)
110-func declarePrize (lotteryName,prizeId,prizeValue) = if ((i.caller != this))
111- then throw("Admin only")
112- else [StringEntry(keyLotteryPrizeValue(lotteryName, prizeId), prizeValue)]
113-
114-
115-
116-@Callable(i)
117-func finalaizePrizeChoice (lotteryName,prizeId) = if ((i.caller != this))
118- then throw("Admin only")
119- else {
120- let lotteryFinalHeight = getIntegerValue(keyLotteryFinalHeight(lotteryName))
121- if ((lotteryFinalHeight > height))
122- then throw("Lottery is not over yet")
123- else {
124- let lotteryTotalStaked = getIntegerValue(keyLotteryTotalStaked(lotteryName))
125- if ((lotteryTotalStaked == 0))
126- then throw("No one entered the lottery")
127- else {
128- let lotteryPrizeValue = getStringOrElse(keyLotteryPrizeValue(lotteryName, prizeId), "")
129- if ((lotteryPrizeValue == ""))
130- then throw("prize does not exist")
131- else {
132- let finalBlock = value(blockInfoByHeight(lotteryFinalHeight))
133- let randomHash = sha256(((toBytes(prizeId) + value(finalBlock.vrf)) + base58'2WWKxchwx7zBB'))
134- let rawChoice = toInt((toBigInt(randomHash) % toBigInt(lotteryTotalStaked)))
135- let choice = if ((0 > rawChoice))
136- then -(rawChoice)
137- else rawChoice
138-[StringEntry("lastHash", toString(toBigInt(randomHash))), IntegerEntry(keyLotteryPrizeChoice(lotteryName, prizeId), choice)]
139- }
140- }
141- }
142- }
136+ else [StringEntry("", "")]
143137
144138
145139 @Verifier(tx)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let lotteryAssetID = fromBase58String("3Lz23mSUvT1EswcBn2sURYJG2at8rG5aFuUrTAwaPM6Q")
55
66 let ticketSize = 1
77
88 func getIntegerOrElse (key,val) = valueOrElse(getInteger(key), val)
99
1010
1111 func getStringOrElse (key,val) = valueOrElse(getString(key), val)
1212
1313
1414 func mk (x) = makeString(x, "_")
1515
1616
1717 func keyAdrTotalStaked (adr) = mk(["adr", adr, "totalStaked"])
1818
1919
2020 func keyLotteryTotalStaked (lotteryName) = mk(["lottery", lotteryName, "totalStaked"])
2121
2222
23-func keyAdrLotteryTotalStaked (lotteryName,adr) = mk(["lottery", lotteryName, "adr", adr, "totalStaked"])
23+func keyLotteryAdrStaked (lotteryName,adr) = mk(["lottery", lotteryName, "adr", adr, "staked"])
24+
25+
26+func keyLotteryAdrLocked (lotteryName,adr) = mk(["lottery", lotteryName, "adr", adr, "locked"])
2427
2528
2629 func keyLotteryFinalHeight (lotteryName) = mk(["lottery", lotteryName, "finalHeight"])
2730
2831
29-func keyLotteryPrizeValue (lotteryName,prizeID) = mk(["lottery", lotteryName, "prize", prizeID, "value"])
32+func keyLotteryPrizeValue (lotteryName,prizeID) = mk(["lottery", lotteryName, "prize", toString(prizeID), "value"])
3033
3134
32-func keyLotteryPrizeChoice (lotteryName,prizeID) = mk(["lottery", lotteryName, "prize", prizeID, "choice"])
35+func keyLotteryPrizeThreshold (lotteryName,prizeID) = mk(["lottery", lotteryName, "prize", toString(prizeID), "threshold"])
36+
37+
38+func keyLotteryPrizeChoice (lotteryName,prizeID) = mk(["lottery", lotteryName, "prize", toString(prizeID), "choice"])
39+
40+
41+func keyLotteryPrizeRandom (lotteryName,prizeID) = mk(["lottery", lotteryName, "prize", toString(prizeID), "random"])
42+
43+
44+func keyLotteryTicketsOwner (lotteryName,from,to) = mk(["lottery", lotteryName, "from", toString(from), "to", toString(to), "owner"])
3345
3446
3547 let _activeLotteryName = mk(["param", "activeLotteryName"])
48+
49+let _globalTotalStaked = mk(["param", "globalTotalStaked"])
3650
3751 func activeLotteryName () = {
3852 let lotteryName = getStringOrElse(_activeLotteryName, "")
3953 if ((lotteryName == ""))
4054 then ""
4155 else {
4256 let lotteryFinalHeight = getIntegerValue(keyLotteryFinalHeight(lotteryName))
43- if (((height - 1) >= lotteryFinalHeight))
57+ if ((height >= lotteryFinalHeight))
4458 then ""
4559 else lotteryName
4660 }
4761 }
4862
4963
5064 @Callable(i)
5165 func stake () = {
5266 let lotteryName = activeLotteryName()
5367 if ((lotteryName == ""))
5468 then throw("Lottery not active")
5569 else if ((size(i.payments) == 0))
5670 then throw("No payment added")
5771 else if ((size(i.payments) != 1))
5872 then throw("Too many payments added")
5973 else if ((i.payments[0].assetId != lotteryAssetID))
6074 then throw("Wrong payment assetId")
6175 else {
6276 let amount = i.payments[0].amount
63- let ticketAmount = 2305843009213688951
77+ let ticketAmount = (amount / ticketSize)
6478 if ((ticketAmount == 0))
6579 then throw("Not enough to buy at least one ticket")
6680 else {
6781 let callerAddress = toString(i.caller)
6882 let _lotteryTotalStaked = keyLotteryTotalStaked(lotteryName)
69- let lotteryTotalStaked = getIntegerValue(_lotteryTotalStaked)
70- let _owner = mk(["lottery", lotteryName, "from", toString(lotteryTotalStaked), "to", toString(((lotteryTotalStaked + ticketAmount) - 1)), "owner"])
83+ let lotteryTotalStaked = getIntegerOrElse(_lotteryTotalStaked, 0)
84+ let _owner = keyLotteryTicketsOwner(lotteryName, lotteryTotalStaked, ((lotteryTotalStaked + ticketAmount) - 1))
7185 let _adrTotalStaked = keyAdrTotalStaked(callerAddress)
7286 let adrTotalStaked = getIntegerOrElse(_adrTotalStaked, 0)
73- let _adrLotteryTotalStaked = keyAdrLotteryTotalStaked(lotteryName, callerAddress)
74- let adrLotteryTotalStaked = getIntegerOrElse(_adrLotteryTotalStaked, 0)
87+ let _lotteryAdrStaked = keyLotteryAdrStaked(lotteryName, callerAddress)
88+ let adrLotteryTotalStaked = getIntegerOrElse(_lotteryAdrStaked, 0)
7589 let change = (amount - (ticketAmount * ticketSize))
76-[IntegerEntry(_lotteryTotalStaked, (lotteryTotalStaked + ticketAmount)), StringEntry(_owner, callerAddress), IntegerEntry(_adrTotalStaked, (adrTotalStaked + ticketAmount)), IntegerEntry(_adrLotteryTotalStaked, (adrLotteryTotalStaked + ticketAmount))]
90+ let globalTotalStaked = getIntegerOrElse(_globalTotalStaked, 0)
91+[ScriptTransfer(i.caller, change, lotteryAssetID), StringEntry(_owner, callerAddress), IntegerEntry(_globalTotalStaked, (globalTotalStaked + ticketAmount)), IntegerEntry(_lotteryTotalStaked, (lotteryTotalStaked + ticketAmount)), IntegerEntry(_adrTotalStaked, (adrTotalStaked + ticketAmount)), IntegerEntry(_lotteryAdrStaked, (adrLotteryTotalStaked + ticketAmount))]
7792 }
7893 }
7994 }
8095
8196
8297
8398 @Callable(i)
84-func claim () = if ((size(i.payments) > 0))
85- then throw("No payments needed")
99+func startLottery (lotteryName,lotteryFinalHeight) = if ((i.caller != this))
100+ then throw("Admin only")
101+ else [StringEntry(_activeLotteryName, lotteryName), IntegerEntry(keyLotteryFinalHeight(lotteryName), lotteryFinalHeight)]
102+
103+
104+
105+@Callable(i)
106+func declarePrize (lotteryName,prizeId,prizeThreshold,prizeValue) = if ((i.caller != this))
107+ then throw("Admin only")
108+ else [IntegerEntry(keyLotteryPrizeThreshold(lotteryName, prizeId), prizeThreshold), StringEntry(keyLotteryPrizeValue(lotteryName, prizeId), prizeValue)]
109+
110+
111+
112+@Callable(i)
113+func finalaizePrizeRandom (lotteryName,prizeId) = if ((i.caller != this))
114+ then throw("Admin only")
86115 else {
87- let callerAddress = toString(i.caller)
88- let lotteryName = activeLotteryName()
89- let stakedInActiveLottery = if ((lotteryName == ""))
90- then 0
91- else getIntegerOrElse(keyAdrLotteryTotalStaked(lotteryName, callerAddress), 0)
92- let _adrTotalStaked = keyAdrTotalStaked(callerAddress)
93- let adrTotalStaked = getIntegerOrElse(_adrTotalStaked, 0)
94- let available = (adrTotalStaked - stakedInActiveLottery)
95- if ((0 >= available))
96- then throw("No assets available for claim")
97- else [ScriptTransfer(i.caller, available, lotteryAssetID), IntegerEntry(_adrTotalStaked, (adrTotalStaked - available))]
116+ let lotteryFinalHeight = getIntegerValue(keyLotteryFinalHeight(lotteryName))
117+ if (((lotteryFinalHeight + 1) > height))
118+ then throw("Lottery is not over yet")
119+ else {
120+ let lotteryPrizeValue = valueOrErrorMessage(getString(keyLotteryPrizeValue(lotteryName, prizeId)), "Prize does not exist")
121+ let finalBlock0 = value(blockInfoByHeight(lotteryFinalHeight))
122+ let finalBlock1 = value(blockInfoByHeight((lotteryFinalHeight + 1)))
123+ let prizeRandomRaw = toBigInt(sha256((((base58'2WWKxchwx7zBB' + toBytes(prizeId)) + value(finalBlock0.vrf)) + value(finalBlock1.vrf))))
124+ let prizeRandom = if ((toBigInt(0) > prizeRandomRaw))
125+ then -(prizeRandomRaw)
126+ else prizeRandomRaw
127+[StringEntry(keyLotteryPrizeRandom(lotteryName, prizeId), toString(prizeRandom))]
128+ }
98129 }
99130
100131
101132
102133 @Callable(i)
103-func startLottery (lotteryName,lotteryFinalHeight) = if ((i.caller != this))
134+func declarePrizeWinner (lotteryName,prizeId,winnerAdr) = if ((i.caller != this))
104135 then throw("Admin only")
105- else [StringEntry(_activeLotteryName, lotteryName), IntegerEntry(keyLotteryFinalHeight(lotteryName), lotteryFinalHeight), IntegerEntry(keyLotteryTotalStaked(lotteryName), 0)]
106-
107-
108-
109-@Callable(i)
110-func declarePrize (lotteryName,prizeId,prizeValue) = if ((i.caller != this))
111- then throw("Admin only")
112- else [StringEntry(keyLotteryPrizeValue(lotteryName, prizeId), prizeValue)]
113-
114-
115-
116-@Callable(i)
117-func finalaizePrizeChoice (lotteryName,prizeId) = if ((i.caller != this))
118- then throw("Admin only")
119- else {
120- let lotteryFinalHeight = getIntegerValue(keyLotteryFinalHeight(lotteryName))
121- if ((lotteryFinalHeight > height))
122- then throw("Lottery is not over yet")
123- else {
124- let lotteryTotalStaked = getIntegerValue(keyLotteryTotalStaked(lotteryName))
125- if ((lotteryTotalStaked == 0))
126- then throw("No one entered the lottery")
127- else {
128- let lotteryPrizeValue = getStringOrElse(keyLotteryPrizeValue(lotteryName, prizeId), "")
129- if ((lotteryPrizeValue == ""))
130- then throw("prize does not exist")
131- else {
132- let finalBlock = value(blockInfoByHeight(lotteryFinalHeight))
133- let randomHash = sha256(((toBytes(prizeId) + value(finalBlock.vrf)) + base58'2WWKxchwx7zBB'))
134- let rawChoice = toInt((toBigInt(randomHash) % toBigInt(lotteryTotalStaked)))
135- let choice = if ((0 > rawChoice))
136- then -(rawChoice)
137- else rawChoice
138-[StringEntry("lastHash", toString(toBigInt(randomHash))), IntegerEntry(keyLotteryPrizeChoice(lotteryName, prizeId), choice)]
139- }
140- }
141- }
142- }
136+ else [StringEntry("", "")]
143137
144138
145139 @Verifier(tx)
146140 func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
147141

github/deemru/w8io/169f3d6 
37.35 ms