tx · 6DTzEA44SWcHcNDfVyGKGtw4hw6jdf7LxfKsu3TFXq2k 3N4tNdENPb2VFETsH8cGpDfeQyXipHwPSxh: -0.01000000 Waves 2023.11.10 16:10 [2837287] smart account 3N4tNdENPb2VFETsH8cGpDfeQyXipHwPSxh > SELF 0.00000000 Waves
{ "type": 13, "id": "6DTzEA44SWcHcNDfVyGKGtw4hw6jdf7LxfKsu3TFXq2k", "fee": 1000000, "feeAssetId": null, "timestamp": 1699621848398, "version": 1, "sender": "3N4tNdENPb2VFETsH8cGpDfeQyXipHwPSxh", "senderPublicKey": "39es6Fq1xg53UXbXQUZPE7uMuZvyEJMmJYzQdxFVKCem", "proofs": [ "2b3x9X24WbGFdxPwv6CW7vPkEm78YYb7awYMb1KdETtqC2JUg6CVwxvssia6ew4niKDUegBmXEeBB87VWuUCxGN5" ], "script": "base64:BgISCAISAwoBBBIDCgEIEgQKAggCXAADU0VQAgJfXwAHV0FWRVNJRAEEE6vZMwAGV0FWRVNEAIDC1y8BDGdldFN0ck9yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAAQxnZXRJbnRPckZhaWwCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUHYWRkcmVzcwUDa2V5CQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFB2FkZHJlc3MJAMwIAgIBLgkAzAgCBQNrZXkJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAENZ2V0Qm9vbE9yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmwgCBQdhZGRyZXNzBQNrZXkJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUHYWRkcmVzcwkAzAgCAgEuCQDMCAIFA2tleQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAABBhbGxvd2VkQXNzZXRzS2V5AhglcyVzX19jZmdfX2FsbG93ZWRBc3NldHMAEWFzc2V0c0RlY2ltYWxzS2V5AhklcyVzX19jZmdfX2Fzc2V0c0RlY2ltYWxzAA5iZXREaXZpZGVyc0tleQIcJXMlc19fY2ZnX19hc3NldHNCZXREaXZpZGVycwAOUlNBUFVCTElDNjRLRVkCFiVzJXNfX2NmZ19fcnNhUHVibGljNjQAEFNFUlZFUkFERFJFU1NLRVkCFiVzJXNfX2NmZ19fYmVuekFkZHJlc3MAEFJBTkRUSU1FRlJBTUVLRVkCHCVzJXNfX2NmZ19fd2l0aGRyYXdUaW1lRnJhbWUAD0dBTUVTQ09VTlRFUktFWQIWJXMlc19fcnVudGltZV9fZ2FtZU51bQAKYmxvY2tlZEtleQIgJXMlc19fcnVudGltZV9fY29udHJhY3RJc0Jsb2NrZWQAEnJlc2VydmVkQW1vdW50c0tleQIeJXMlc19fcnVudGltZV9fcmVzZXJ2ZWRBbW91bnRzAQtnZXRJbnRBcnJheQEDa2V5BAFhCQEMZ2V0U3RyT3JGYWlsAgUEdGhpcwUDa2V5CgEGZmlsbGVyAgNhY2MCZWwJAM0IAgUDYWNjCQENcGFyc2VJbnRWYWx1ZQEFAmVsCgACJGwJALUJAgUBYQUDU0VQCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQZmaWxsZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoBCWdldEFzc2V0cwAJALUJAgkBDGdldFN0ck9yRmFpbAIFBHRoaXMFEGFsbG93ZWRBc3NldHNLZXkFA1NFUAAGQVNTRVRTCQEJZ2V0QXNzZXRzAAAIREVDSU1BTFMJAQtnZXRJbnRBcnJheQEFEWFzc2V0c0RlY2ltYWxzS2V5AAtCRVRESVZJREVSUwkBC2dldEludEFycmF5AQUOYmV0RGl2aWRlcnNLZXkBE1JFU0VSVkFUSU9OS0VZQllTVFIBCGFzc2V0U3RyCQCsAgICESRSRVNFUlZFRF9BTU9VTlRfBQhhc3NldFN0cgEOUkVTRVJWQVRJT05LRVkBCGFzc2V0SWR4CQETUkVTRVJWQVRJT05LRVlCWVNUUgEJAJEDAgUGQVNTRVRTBQhhc3NldElkeAALTUlORkVFV0FWRVMJAGkCCQBoAgAFBQZXQVZFU0QA6AcACWlkeEFzc2V0cwAAAAtpZHhEZWNpbWFscwABAAtpZHhEaXZpZGVycwACAA5pZHhSZXNlcnZhdGlvbgADAQlnZXRCZXRNaW4BB2Fzc2V0SWQJAGkCCQBoAgABCQCRAwIFCERFQ0lNQUxTBQdhc3NldElkAAIBCWdldEJldE1heAEHYXNzZXRJZAkAaAIABgkAkQMCBQhERUNJTUFMUwUHYXNzZXRJZAEKZ2V0QmV0U3RlcAEHYXNzZXRJZAkAaQIJAGgCAAEJAJEDAgUIREVDSU1BTFMFB2Fzc2V0SWQACgAJUFJFQ0lTSU9OAJBOAAVSMU1BWABgAAVSMU1JTgBeAANSMUsAhE0ABVIyTUFYAF0ABVIyTUlOAFcAA1IySwDITAAFUjNNQVgAVgAFUjNNSU4AVgADUjNLAJZMAAVSNE1BWABVAAVSNE1JTgBUAANSNEsAxksABVI1TUFYAFMABVI1TUlOAFMAA1I1SwCeSwAFUjZNQVgAUgAFUjZNSU4AQwADUjZLAIpLAAVSN01BWABCAAVSN01JTgA4AANSN0sA2EoABVI4TUFYADcABVI4TUlOACYAA1I4SwCcSgAFUjlNQVgAJQAFUjlNSU4AAwADUjlLAMpIAAZSMTBNQVgAAgAGUjEwTUlOAAEABFIxMEsAhE0ADElkeEdhbWVTdGF0ZQAAAA9JZHhQbGF5ZXJDaG9pY2UAAQARSWR4UGxheWVyUHViS2V5NTgAAgAQSWR4U3RhcnRlZEhlaWdodAADAAxJZHhXaW5BbW91bnQABAAKSWR4QXNzZXRJZAAFAA5TVEFURVNVQk1JVFRFRAIJU1VCTUlUVEVEAAhTVEFURVdPTgIDV09OAAlTVEFURUxPU1QCBExPU1QBD2dldFN0cmluZ09yRmFpbAEDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwUDa2V5CQCsAgIFA2tleQIjIGtleSBpcyBub3Qgc3BlY2lmaWVkIGluIHRoaXMuc3RhdGUACVJTQVBVQkxJQwkA2wQBCQEPZ2V0U3RyaW5nT3JGYWlsAQUOUlNBUFVCTElDNjRLRVkABlNFUlZFUgkBEUBleHRyTmF0aXZlKDEwNjIpAQkBD2dldFN0cmluZ09yRmFpbAEFEFNFUlZFUkFERFJFU1NLRVkAE1JBTkRPUkFDTEVUSU1FRlJBTUUJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUQUkFORFRJTUVGUkFNRUtFWQCgOAEIZ2V0SW50T3ICA2tleQdkZWZhdWx0AwkBCWlzRGVmaW5lZAEJAJ8IAQUDa2V5CQERQGV4dHJOYXRpdmUoMTA1NSkBBQNrZXkFB2RlZmF1bHQBBnNldEludAIDa2V5BXZhbHVlCQEMSW50ZWdlckVudHJ5AgUDa2V5BQV2YWx1ZQEMaW5jcmVtZW50SW50AQNrZXkJAQZzZXRJbnQCBQNrZXkJAGQCCQEIZ2V0SW50T3ICBQNrZXkA////////////AQABAQljaGFuZ2VJbnQCA2tleQJieQkBBnNldEludAIFA2tleQkAZAIJAQhnZXRJbnRPcgIFA2tleQAABQJieQEMYXNzZXRJZFRvU3RyAQ1hc3NldElkT3JVbml0BAckbWF0Y2gwBQ1hc3NldElkT3JVbml0AwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAWIFByRtYXRjaDAJANgEAQUBYgIFV0FWRVMBDmFzc2V0SWRGcm9tU3RyAQphc3NldElkU3RyAwkAAAIFCmFzc2V0SWRTdHICBVdBVkVTBQR1bml0CQDZBAEFCmFzc2V0SWRTdHIBD2dldEFzc2V0QmFsYW5jZQENYXNzZXRJZE9yVW5pdAQHJG1hdGNoMAUNYXNzZXRJZE9yVW5pdAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAdhc3NldElkBQckbWF0Y2gwCQDwBwIFBHRoaXMFB2Fzc2V0SWQICQDvBwEFBHRoaXMJYXZhaWxhYmxlARVpbmNyZWFzZVJlc2VydmVBbW91bnQCCXdpbkFtb3VudAhhc3NldElkeAQKYXNzZXRJZFN0cgkAkQMCBQZBU1NFVFMFCGFzc2V0SWR4BBFuZXdSZXNlcnZlZEFtb3VudAkAZAIJAQhnZXRJbnRPcgIJAQ5SRVNFUlZBVElPTktFWQEFCGFzc2V0SWR4AAAFCXdpbkFtb3VudAMJAGYCBRFuZXdSZXNlcnZlZEFtb3VudAkBD2dldEFzc2V0QmFsYW5jZQEJAQ5hc3NldElkRnJvbVN0cgEFCmFzc2V0SWRTdHIJAAIBAlRJbnN1ZmZpY2llbnQgZnVuZHMgb24gRGljZSBSb2xsZXIgYWNjb3VudC4gVHJhbnNhY3Rpb24gd2FzIHJlamVjdGVkIGZvciB5b3VyIHNhZmV0eS4FEW5ld1Jlc2VydmVkQW1vdW50ARZkZWNyZWFzZVJlc2VydmVkQW1vdW50AwZnYW1lSWQIYXNzZXRJZHgJd2luQW1vdW50AwkAZgIAAAkAZQIJAQhnZXRJbnRPcgIJAQ5SRVNFUlZBVElPTktFWQEFCGFzc2V0SWR4AAAFCXdpbkFtb3VudAkAAgECQkludmFsaWQgRGljZSBSb2xsZXIgYWNjb3VudCBzdGF0ZSAtIHJlc2VydmVkIGFtb3VudCBpcyBsZXNzIHRoYW4gMAkBCWNoYW5nZUludAIJAQ5SRVNFUlZBVElPTktFWQEFCGFzc2V0SWR4CQEBLQEFCXdpbkFtb3VudAEWdmFsaWRhdGVBbmRHZXRBc3NldElkeAEKYXNzZXRJZFN0cgQDaWR4CQDPCAIFBkFTU0VUUwUKYXNzZXRJZFN0cgMJAQEhAQkBCWlzRGVmaW5lZAEFA2lkeAkAAgECFUludmFsaWQgcGF5bWVudCBhc3NldAkBBXZhbHVlAQUDaWR4ARp2YWxpZGF0ZUJldEFuZEdldFdpbkFtb3VudAMDYmV0EGludGVybmFsQXNzZXRJZHgMcGxheWVyQ2hvaWNlBAZCRVRNSU4JAQlnZXRCZXRNaW4BBRBpbnRlcm5hbEFzc2V0SWR4BAZCRVRNQVgJAQlnZXRCZXRNYXgBBRBpbnRlcm5hbEFzc2V0SWR4BAdCRVRTVEVQCQEKZ2V0QmV0U3RlcAEFEGludGVybmFsQXNzZXRJZHgED3BsYXllckNob2ljZUludAkBDXBhcnNlSW50VmFsdWUBBQxwbGF5ZXJDaG9pY2UEDmJldEFtb3VudFZhbGlkAwMJAGcCBQNiZXQFBkJFVE1JTgkAZwIFBkJFVE1BWAUDYmV0BwkAAAIJAGoCBQNiZXQFB0JFVFNURVAAAAcEEXBsYXllckNob2ljZVZhbGlkAwkAZwIFD3BsYXllckNob2ljZUludAABCQBnAgBgBQ9wbGF5ZXJDaG9pY2VJbnQHAwkBASEBBQ5iZXRBbW91bnRWYWxpZAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAiNCZXQgYW1vdW50IGlzIG5vdCBpbiByYW5nZTogbWluQmV0PQkApAMBBQZCRVRNSU4CCCBtYXhCZXQ9CQCkAwEFBkJFVE1BWAIJIGJldFN0ZXA9CQCkAwEFB0JFVFNURVADCQEBIQEFEXBsYXllckNob2ljZVZhbGlkCQACAQI+UGxheWVyIGNob2ljZSBpcyBvdXQgb2YgdGhlIGNvbmRpdGlvbiBiZWxvdzogMSA8PSBjaG9pY2UgPD0gOTYEDFJLeFByZWNpc2lvbgMDCQBnAgUFUjFNQVgFD3BsYXllckNob2ljZUludAkAZwIFD3BsYXllckNob2ljZUludAUFUjFNSU4HBQNSMUsDAwkAZwIFBVIyTUFYBQ9wbGF5ZXJDaG9pY2VJbnQJAGcCBQ9wbGF5ZXJDaG9pY2VJbnQFBVIyTUlOBwUDUjJLAwMJAGcCBQVSM01BWAUPcGxheWVyQ2hvaWNlSW50CQBnAgUPcGxheWVyQ2hvaWNlSW50BQVSM01JTgcFA1IzSwMDCQBnAgUFUjRNQVgFD3BsYXllckNob2ljZUludAkAZwIFD3BsYXllckNob2ljZUludAUFUjRNSU4HBQNSNEsDAwkAZwIFBVI1TUFYBQ9wbGF5ZXJDaG9pY2VJbnQJAGcCBQ9wbGF5ZXJDaG9pY2VJbnQFBVI1TUlOBwUDUjVLAwMJAGcCBQVSNk1BWAUPcGxheWVyQ2hvaWNlSW50CQBnAgUPcGxheWVyQ2hvaWNlSW50BQVSNk1JTgcFA1I2SwMDCQBnAgUFUjdNQVgFD3BsYXllckNob2ljZUludAkAZwIFD3BsYXllckNob2ljZUludAUFUjdNSU4HBQNSN0sDAwkAZwIFBVI4TUFYBQ9wbGF5ZXJDaG9pY2VJbnQJAGcCBQ9wbGF5ZXJDaG9pY2VJbnQFBVI4TUlOBwUDUjhLAwMJAGcCBQVSOU1BWAUPcGxheWVyQ2hvaWNlSW50CQBnAgUPcGxheWVyQ2hvaWNlSW50BQVSOU1JTgcFA1I5SwMDCQBnAgUGUjEwTUFYBQ9wbGF5ZXJDaG9pY2VJbnQJAGcCBQ9wbGF5ZXJDaG9pY2VJbnQFBlIxME1JTgcFBFIxMEsJAAIBCQCsAgICJENvdWxkbid0IGRlZmluZSByYW5nZTogcGxheWVyQ2hvaWNlPQUMcGxheWVyQ2hvaWNlCQBpAgkAaAIJAGkCCQBoAgBkBQxSS3hQcmVjaXNpb24FD3BsYXllckNob2ljZUludAUDYmV0BQlQUkVDSVNJT04BCXJhbmRUb1N0cgEBcgMDCQBnAgUBcgABCQBnAgBkBQFyBwkApAMBBQFyCQACAQkArAICAjxVbnN1cHBvcnRlZCByIHBhcmFtZXRlciBwYXNzZWQ6IGV4cGVjdGVkPVsxLC4uLiwxMDBdIGFjdHVhbD0JAKQDAQUBcgESZ2VuZXJhdGVSYW5kQ2hvaXNlAgZnYW1lSWQHcnNhU2lnbgQLcnNhU2lnVmFsaWQJAKgUBAUGU0hBMjU2CQCbAwEFBmdhbWVJZAUHcnNhU2lnbgUJUlNBUFVCTElDAwkBASEBBQtyc2FTaWdWYWxpZAkAAgECFUludmFsaWQgUlNBIHNpZ25hdHVyZQQEcmFuZAkAagIJALEJAQkA9wMBBQdyc2FTaWduAGQECm1vZHVsZVJhbmQDCQBmAgAABQRyYW5kCQBoAgD///////////8BBQRyYW5kBQRyYW5kBAlmaW5hbFJhbmQJAGQCBQptb2R1bGVSYW5kAAEEDGZpbmFsUmFuZFN0cgkApAMBBQlmaW5hbFJhbmQDAwkAZgIAAQUJZmluYWxSYW5kBgkAZgIFCWZpbmFsUmFuZABkCQACAQkArAICAjxVbnN1cHBvcnRlZCByIHBhcmFtZXRlciBwYXNzZWQ6IGV4cGVjdGVkPVsxLC4uLiwxMDBdIGFjdHVhbD0FDGZpbmFsUmFuZFN0cgUMZmluYWxSYW5kU3RyAQtpc1BsYXllcldpbgIMcGxheWVyQ2hvaWNlCnJhbmRDaG9pY2UED3BsYXllckNob2ljZUludAkBDXBhcnNlSW50VmFsdWUBBQxwbGF5ZXJDaG9pY2UEDXJhbmRDaG9pY2VJbnQJAQ1wYXJzZUludFZhbHVlAQUKcmFuZENob2ljZQkAZwIFD3BsYXllckNob2ljZUludAUNcmFuZENob2ljZUludAEPZm9ybWF0R2FtZURhdGFTBwpnYW1lU3RhdHVzDHBsYXllckNob2ljZQ5wbGF5ZXJQdWJLZXk1OA1zdGFydGVkSGVpZ2h0CXdpbkFtb3VudAhhc3NldElkeAtyYW5kT3JFbXB0eQkAuQkCCQDMCAIFCmdhbWVTdGF0dXMJAMwIAgUMcGxheWVyQ2hvaWNlCQDMCAIFDnBsYXllclB1YktleTU4CQDMCAIFDXN0YXJ0ZWRIZWlnaHQJAMwIAgUJd2luQW1vdW50CQDMCAIFCGFzc2V0SWR4CQDMCAIDCQAAAgULcmFuZE9yRW1wdHkCAAIABQtyYW5kT3JFbXB0eQUDbmlsAgFfAQ5mb3JtYXRHYW1lRGF0YQcKZ2FtZVN0YXR1cwxwbGF5ZXJDaG9pY2UOcGxheWVyUHViS2V5NTgNc3RhcnRlZEhlaWdodAl3aW5BbW91bnQIYXNzZXRJZHgLcmFuZE9yRW1wdHkJAQ9mb3JtYXRHYW1lRGF0YVMHBQpnYW1lU3RhdHVzBQxwbGF5ZXJDaG9pY2UFDnBsYXllclB1YktleTU4CQCkAwEFDXN0YXJ0ZWRIZWlnaHQJAKQDAQUJd2luQW1vdW50CQCkAwEFCGFzc2V0SWR4BQtyYW5kT3JFbXB0eQEOZmluaXNoR2FtZURhdGEEDG9yaWdHYW1lRGF0YQpnYW1lU3RhdHVzBHJhbmQMd2luQnlUaW1lb3V0BA5maW5pc2hHYW1lRGF0YQkBD2Zvcm1hdEdhbWVEYXRhUwcFCmdhbWVTdGF0dXMJAJEDAgUMb3JpZ0dhbWVEYXRhBQ9JZHhQbGF5ZXJDaG9pY2UJAJEDAgUMb3JpZ0dhbWVEYXRhBRFJZHhQbGF5ZXJQdWJLZXk1OAkAkQMCBQxvcmlnR2FtZURhdGEFEElkeFN0YXJ0ZWRIZWlnaHQJAJEDAgUMb3JpZ0dhbWVEYXRhBQxJZHhXaW5BbW91bnQJAJEDAgUMb3JpZ0dhbWVEYXRhBQpJZHhBc3NldElkBQRyYW5kAwUMd2luQnlUaW1lb3V0CQCsAgIFDmZpbmlzaEdhbWVEYXRhAghfVElNRU9VVAUOZmluaXNoR2FtZURhdGEBD2V4dHJhY3RHYW1lRGF0YQEGZ2FtZUlkCQC1CQIEByRtYXRjaDAJAJ0IAgUEdGhpcwUGZ2FtZUlkAwkAAQIFByRtYXRjaDACBlN0cmluZwQDc3RyBQckbWF0Y2gwBQNzdHIJAAIBCQCsAgIJAKwCAgIGR2FtZTogBQZnYW1lSWQCCyBub3QgZm91bmQuAgFfAwFpAQttYWludGVuYW5jZQEHYmxvY2tlZAMJAQIhPQIIBQFpBmNhbGxlcgUGU0VSVkVSCQACAQIObm90IGF1dGhvcml6ZWQJAMwIAgkBDEJvb2xlYW5FbnRyeQIFCmJsb2NrZWRLZXkFB2Jsb2NrZWQFA25pbAFpAQNiZXQBDHBsYXllckNob2ljZQMJAQt2YWx1ZU9yRWxzZQIJAKAIAQUKYmxvY2tlZEtleQcJAAIBAh9HYW1lIGlzIHN0b3BwZWQgZm9yIG1haW50ZW5lbmNlBAZnYW1lSWQJANgEAQgFAWkNdHJhbnNhY3Rpb25JZAMJAGcCAAEJAJADAQgFAWkIcGF5bWVudHMJAAIBAhsyIHBheW1lbnRzIG11c3QgYmUgYXR0YWNoZWQDCQEJaXNEZWZpbmVkAQkAnQgCBQR0aGlzBQZnYW1lSWQJAAIBCQCsAgIJAKwCAgIJQmV0IGZvcjogBQZnYW1lSWQCEiB3YXMgYWxyZWFkeSBtYWRlLgQGYmV0UG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAEBmZlZVBtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwABAwkBCWlzRGVmaW5lZAEIBQZmZWVQbXQHYXNzZXRJZAkAAgECLWZlZVBtdCAoMm5kIHBheW1lbnQpIGFzc2V0SWQgbXVzdCBiZSBpbiBXYXZlcwMJAGYCBQtNSU5GRUVXQVZFUwgFBmZlZVBtdAZhbW91bnQJAAIBAitmZWVQbXQgKDJuZCBwYXltZW50KSBtdXN0IGJlID49IDAuMDA1IFdhdmVzBAphc3NldElkU3RyCQEMYXNzZXRJZFRvU3RyAQgFBmJldFBtdAdhc3NldElkBBBpbnRlcm5hbEFzc2V0SWR4CQEWdmFsaWRhdGVBbmRHZXRBc3NldElkeAEFCmFzc2V0SWRTdHIECmNvbW1pc3Npb24IBQZmZWVQbXQGYW1vdW50BAl3aW5BbW91bnQJARp2YWxpZGF0ZUJldEFuZEdldFdpbkFtb3VudAMIBQZiZXRQbXQGYW1vdW50BRBpbnRlcm5hbEFzc2V0SWR4BQxwbGF5ZXJDaG9pY2UEDnBsYXllclB1YktleTU4CQDYBAEIBQFpD2NhbGxlclB1YmxpY0tleQQIZ2FtZURhdGEJAQ5mb3JtYXRHYW1lRGF0YQcFDlNUQVRFU1VCTUlUVEVEBQxwbGF5ZXJDaG9pY2UFDnBsYXllclB1YktleTU4BQZoZWlnaHQFCXdpbkFtb3VudAUQaW50ZXJuYWxBc3NldElkeAIACQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEOUkVTRVJWQVRJT05LRVkBBRBpbnRlcm5hbEFzc2V0SWR4CQEVaW5jcmVhc2VSZXNlcnZlQW1vdW50AgUJd2luQW1vdW50BRBpbnRlcm5hbEFzc2V0SWR4CQDMCAIJAQxpbmNyZW1lbnRJbnQBBQ9HQU1FU0NPVU5URVJLRVkJAMwIAgkBC1N0cmluZ0VudHJ5AgUGZ2FtZUlkBQhnYW1lRGF0YQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQZTRVJWRVIFCmNvbW1pc3Npb24IBQZmZWVQbXQHYXNzZXRJZAUDbmlsAWkBCHdpdGhkcmF3AgZnYW1lSWQHcnNhU2lnbgQIZ2FtZURhdGEJAQ9leHRyYWN0R2FtZURhdGEBBQZnYW1lSWQECWdhbWVTdGF0ZQkAkQMCBQhnYW1lRGF0YQUMSWR4R2FtZVN0YXRlBAxwbGF5ZXJDaG9pY2UJAJEDAgUIZ2FtZURhdGEFD0lkeFBsYXllckNob2ljZQQNc3RhcnRlZEhlaWdodAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGdhbWVEYXRhBRBJZHhTdGFydGVkSGVpZ2h0BAl3aW5BbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhnYW1lRGF0YQUMSWR4V2luQW1vdW50BAhhc3NldElkeAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGdhbWVEYXRhBQpJZHhBc3NldElkBA5wbGF5ZXJQdWJLZXk1OAkAkQMCBQhnYW1lRGF0YQURSWR4UGxheWVyUHViS2V5NTgEDXBsYXllckFkZHJlc3MJAKcIAQkA2QQBBQ5wbGF5ZXJQdWJLZXk1OAMJAQIhPQIFCWdhbWVTdGF0ZQUOU1RBVEVTVUJNSVRURUQJAAIBAiRJbnZhbGlkIGdhbWUgc3RhdGUgZm9yIHBhc3NlZCBnYW1lSWQDCQECIT0CCAUBaQZjYWxsZXIFBlNFUlZFUgkAAgECK1JlZ3VsYXIgd2l0aGRyYXcgY2FuIGJlIGRvbmUgYnkgc2VydmVyIG9ubHkEDHdpbkJ5VGltZW91dAkAZgIJAGUCBQZoZWlnaHQFDXN0YXJ0ZWRIZWlnaHQFE1JBTkRPUkFDTEVUSU1FRlJBTUUECnJhbmRDaG9pc2UDBQx3aW5CeVRpbWVvdXQFDHBsYXllckNob2ljZQkBEmdlbmVyYXRlUmFuZENob2lzZQIFBmdhbWVJZAUHcnNhU2lnbgQJcGxheWVyV2luCQELaXNQbGF5ZXJXaW4CBQxwbGF5ZXJDaG9pY2UFCnJhbmRDaG9pc2UEDW5ld0dhbWVTdGF0dXMDBQlwbGF5ZXJXaW4FCFNUQVRFV09OBQlTVEFURUxPU1QEC25ld0dhbWVEYXRhCQEOZmluaXNoR2FtZURhdGEEBQhnYW1lRGF0YQUNbmV3R2FtZVN0YXR1cwUKcmFuZENob2lzZQUMd2luQnlUaW1lb3V0CQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgUGZ2FtZUlkBQtuZXdHYW1lRGF0YQkAzAgCCQEWZGVjcmVhc2VSZXNlcnZlZEFtb3VudAMFBmdhbWVJZAUIYXNzZXRJZHgFCXdpbkFtb3VudAUDbmlsAwUJcGxheWVyV2luCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFDXBsYXllckFkZHJlc3MFCXdpbkFtb3VudAkBDmFzc2V0SWRGcm9tU3RyAQkAkQMCBQZBU1NFVFMFCGFzc2V0SWR4BQNuaWwFA25pbAECdHgBBnZlcmlmeQADCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAACAUCdHgPc2VuZGVyUHVibGljS2V5BAckbWF0Y2gwBQJ0eAMJAAECBQckbWF0Y2gwAhNUcmFuc2ZlclRyYW5zYWN0aW9uBAN0dHgFByRtYXRjaDAECGFzc2V0SWR4CQEWdmFsaWRhdGVBbmRHZXRBc3NldElkeAEJAQxhc3NldElkVG9TdHIBCAUDdHR4B2Fzc2V0SWQJAGcCCQBlAgkBD2dldEFzc2V0QmFsYW5jZQEIBQN0dHgHYXNzZXRJZAgFA3R0eAZhbW91bnQJAQhnZXRJbnRPcgIJAQ5SRVNFUlZBVElPTktFWQEFCGFzc2V0SWR4AAADCQABAgUHJG1hdGNoMAIUU2V0U2NyaXB0VHJhbnNhY3Rpb24EA3N0eAUHJG1hdGNoMAoBB2NoZWNrZXICA2FjYwJlbAMFA2FjYwkAAAIJAQhnZXRJbnRPcgIJARNSRVNFUlZBVElPTktFWUJZU1RSAQUCZWwAAAAABwoAAiRsBQZBU1NFVFMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBgoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHY2hlY2tlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgcHRbpbyw==", "chainId": 84, "height": 2837287, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
Old | New | Differences | |
---|---|---|---|
1 | - | # no script | |
1 | + | {-# STDLIB_VERSION 6 #-} | |
2 | + | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | + | {-# CONTENT_TYPE DAPP #-} | |
4 | + | let SEP = "__" | |
5 | + | ||
6 | + | let WAVESID = base58'WAVES' | |
7 | + | ||
8 | + | let WAVESD = 100000000 | |
9 | + | ||
10 | + | func getStrOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], "")) | |
11 | + | ||
12 | + | ||
13 | + | func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], "")) | |
14 | + | ||
15 | + | ||
16 | + | func getBoolOrFail (address,key) = valueOrErrorMessage(getBoolean(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], "")) | |
17 | + | ||
18 | + | ||
19 | + | let allowedAssetsKey = "%s%s__cfg__allowedAssets" | |
20 | + | ||
21 | + | let assetsDecimalsKey = "%s%s__cfg__assetsDecimals" | |
22 | + | ||
23 | + | let betDividersKey = "%s%s__cfg__assetsBetDividers" | |
24 | + | ||
25 | + | let RSAPUBLIC64KEY = "%s%s__cfg__rsaPublic64" | |
26 | + | ||
27 | + | let SERVERADDRESSKEY = "%s%s__cfg__benzAddress" | |
28 | + | ||
29 | + | let RANDTIMEFRAMEKEY = "%s%s__cfg__withdrawTimeFrame" | |
30 | + | ||
31 | + | let GAMESCOUNTERKEY = "%s%s__runtime__gameNum" | |
32 | + | ||
33 | + | let blockedKey = "%s%s__runtime__contractIsBlocked" | |
34 | + | ||
35 | + | let reservedAmountsKey = "%s%s__runtime__reservedAmounts" | |
36 | + | ||
37 | + | func getIntArray (key) = { | |
38 | + | let a = getStrOrFail(this, key) | |
39 | + | func filler (acc,el) = (acc :+ parseIntValue(el)) | |
40 | + | ||
41 | + | let $l = split(a, SEP) | |
42 | + | let $s = size($l) | |
43 | + | let $acc0 = nil | |
44 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
45 | + | then $a | |
46 | + | else filler($a, $l[$i]) | |
47 | + | ||
48 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
49 | + | then $a | |
50 | + | else throw("List size exceeds 10") | |
51 | + | ||
52 | + | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10) | |
53 | + | } | |
54 | + | ||
55 | + | ||
56 | + | func getAssets () = split(getStrOrFail(this, allowedAssetsKey), SEP) | |
57 | + | ||
58 | + | ||
59 | + | let ASSETS = getAssets() | |
60 | + | ||
61 | + | let DECIMALS = getIntArray(assetsDecimalsKey) | |
62 | + | ||
63 | + | let BETDIVIDERS = getIntArray(betDividersKey) | |
64 | + | ||
65 | + | func RESERVATIONKEYBYSTR (assetStr) = ("$RESERVED_AMOUNT_" + assetStr) | |
66 | + | ||
67 | + | ||
68 | + | func RESERVATIONKEY (assetIdx) = RESERVATIONKEYBYSTR(ASSETS[assetIdx]) | |
69 | + | ||
70 | + | ||
71 | + | let MINFEEWAVES = ((5 * WAVESD) / 1000) | |
72 | + | ||
73 | + | let idxAssets = 0 | |
74 | + | ||
75 | + | let idxDecimals = 1 | |
76 | + | ||
77 | + | let idxDividers = 2 | |
78 | + | ||
79 | + | let idxReservation = 3 | |
80 | + | ||
81 | + | func getBetMin (assetId) = ((1 * DECIMALS[assetId]) / 2) | |
82 | + | ||
83 | + | ||
84 | + | func getBetMax (assetId) = (6 * DECIMALS[assetId]) | |
85 | + | ||
86 | + | ||
87 | + | func getBetStep (assetId) = ((1 * DECIMALS[assetId]) / 10) | |
88 | + | ||
89 | + | ||
90 | + | let PRECISION = 10000 | |
91 | + | ||
92 | + | let R1MAX = 96 | |
93 | + | ||
94 | + | let R1MIN = 94 | |
95 | + | ||
96 | + | let R1K = 9860 | |
97 | + | ||
98 | + | let R2MAX = 93 | |
99 | + | ||
100 | + | let R2MIN = 87 | |
101 | + | ||
102 | + | let R2K = 9800 | |
103 | + | ||
104 | + | let R3MAX = 86 | |
105 | + | ||
106 | + | let R3MIN = 86 | |
107 | + | ||
108 | + | let R3K = 9750 | |
109 | + | ||
110 | + | let R4MAX = 85 | |
111 | + | ||
112 | + | let R4MIN = 84 | |
113 | + | ||
114 | + | let R4K = 9670 | |
115 | + | ||
116 | + | let R5MAX = 83 | |
117 | + | ||
118 | + | let R5MIN = 83 | |
119 | + | ||
120 | + | let R5K = 9630 | |
121 | + | ||
122 | + | let R6MAX = 82 | |
123 | + | ||
124 | + | let R6MIN = 67 | |
125 | + | ||
126 | + | let R6K = 9610 | |
127 | + | ||
128 | + | let R7MAX = 66 | |
129 | + | ||
130 | + | let R7MIN = 56 | |
131 | + | ||
132 | + | let R7K = 9560 | |
133 | + | ||
134 | + | let R8MAX = 55 | |
135 | + | ||
136 | + | let R8MIN = 38 | |
137 | + | ||
138 | + | let R8K = 9500 | |
139 | + | ||
140 | + | let R9MAX = 37 | |
141 | + | ||
142 | + | let R9MIN = 3 | |
143 | + | ||
144 | + | let R9K = 9290 | |
145 | + | ||
146 | + | let R10MAX = 2 | |
147 | + | ||
148 | + | let R10MIN = 1 | |
149 | + | ||
150 | + | let R10K = 9860 | |
151 | + | ||
152 | + | let IdxGameState = 0 | |
153 | + | ||
154 | + | let IdxPlayerChoice = 1 | |
155 | + | ||
156 | + | let IdxPlayerPubKey58 = 2 | |
157 | + | ||
158 | + | let IdxStartedHeight = 3 | |
159 | + | ||
160 | + | let IdxWinAmount = 4 | |
161 | + | ||
162 | + | let IdxAssetId = 5 | |
163 | + | ||
164 | + | let STATESUBMITTED = "SUBMITTED" | |
165 | + | ||
166 | + | let STATEWON = "WON" | |
167 | + | ||
168 | + | let STATELOST = "LOST" | |
169 | + | ||
170 | + | func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), (key + " key is not specified in this.state")) | |
171 | + | ||
172 | + | ||
173 | + | let RSAPUBLIC = fromBase64String(getStringOrFail(RSAPUBLIC64KEY)) | |
174 | + | ||
175 | + | let SERVER = addressFromStringValue(getStringOrFail(SERVERADDRESSKEY)) | |
176 | + | ||
177 | + | let RANDORACLETIMEFRAME = valueOrElse(getInteger(this, RANDTIMEFRAMEKEY), 7200) | |
178 | + | ||
179 | + | func getIntOr (key,default) = if (isDefined(getInteger(key))) | |
180 | + | then getIntegerValue(key) | |
181 | + | else default | |
182 | + | ||
183 | + | ||
184 | + | func setInt (key,value) = IntegerEntry(key, value) | |
185 | + | ||
186 | + | ||
187 | + | func incrementInt (key) = setInt(key, (getIntOr(key, -1) + 1)) | |
188 | + | ||
189 | + | ||
190 | + | func changeInt (key,by) = setInt(key, (getIntOr(key, 0) + by)) | |
191 | + | ||
192 | + | ||
193 | + | func assetIdToStr (assetIdOrUnit) = match assetIdOrUnit { | |
194 | + | case b: ByteVector => | |
195 | + | toBase58String(b) | |
196 | + | case _ => | |
197 | + | "WAVES" | |
198 | + | } | |
199 | + | ||
200 | + | ||
201 | + | func assetIdFromStr (assetIdStr) = if ((assetIdStr == "WAVES")) | |
202 | + | then unit | |
203 | + | else fromBase58String(assetIdStr) | |
204 | + | ||
205 | + | ||
206 | + | func getAssetBalance (assetIdOrUnit) = match assetIdOrUnit { | |
207 | + | case assetId: ByteVector => | |
208 | + | assetBalance(this, assetId) | |
209 | + | case _ => | |
210 | + | wavesBalance(this).available | |
211 | + | } | |
212 | + | ||
213 | + | ||
214 | + | func increaseReserveAmount (winAmount,assetIdx) = { | |
215 | + | let assetIdStr = ASSETS[assetIdx] | |
216 | + | let newReservedAmount = (getIntOr(RESERVATIONKEY(assetIdx), 0) + winAmount) | |
217 | + | if ((newReservedAmount > getAssetBalance(assetIdFromStr(assetIdStr)))) | |
218 | + | then throw("Insufficient funds on Dice Roller account. Transaction was rejected for your safety.") | |
219 | + | else newReservedAmount | |
220 | + | } | |
221 | + | ||
222 | + | ||
223 | + | func decreaseReservedAmount (gameId,assetIdx,winAmount) = if ((0 > (getIntOr(RESERVATIONKEY(assetIdx), 0) - winAmount))) | |
224 | + | then throw("Invalid Dice Roller account state - reserved amount is less than 0") | |
225 | + | else changeInt(RESERVATIONKEY(assetIdx), -(winAmount)) | |
226 | + | ||
227 | + | ||
228 | + | func validateAndGetAssetIdx (assetIdStr) = { | |
229 | + | let idx = indexOf(ASSETS, assetIdStr) | |
230 | + | if (!(isDefined(idx))) | |
231 | + | then throw("Invalid payment asset") | |
232 | + | else value(idx) | |
233 | + | } | |
234 | + | ||
235 | + | ||
236 | + | func validateBetAndGetWinAmount (bet,internalAssetIdx,playerChoice) = { | |
237 | + | let BETMIN = getBetMin(internalAssetIdx) | |
238 | + | let BETMAX = getBetMax(internalAssetIdx) | |
239 | + | let BETSTEP = getBetStep(internalAssetIdx) | |
240 | + | let playerChoiceInt = parseIntValue(playerChoice) | |
241 | + | let betAmountValid = if (if ((bet >= BETMIN)) | |
242 | + | then (BETMAX >= bet) | |
243 | + | else false) | |
244 | + | then ((bet % BETSTEP) == 0) | |
245 | + | else false | |
246 | + | let playerChoiceValid = if ((playerChoiceInt >= 1)) | |
247 | + | then (96 >= playerChoiceInt) | |
248 | + | else false | |
249 | + | if (!(betAmountValid)) | |
250 | + | then throw(((((("Bet amount is not in range: minBet=" + toString(BETMIN)) + " maxBet=") + toString(BETMAX)) + " betStep=") + toString(BETSTEP))) | |
251 | + | else if (!(playerChoiceValid)) | |
252 | + | then throw("Player choice is out of the condition below: 1 <= choice <= 96") | |
253 | + | else { | |
254 | + | let RKxPrecision = if (if ((R1MAX >= playerChoiceInt)) | |
255 | + | then (playerChoiceInt >= R1MIN) | |
256 | + | else false) | |
257 | + | then R1K | |
258 | + | else if (if ((R2MAX >= playerChoiceInt)) | |
259 | + | then (playerChoiceInt >= R2MIN) | |
260 | + | else false) | |
261 | + | then R2K | |
262 | + | else if (if ((R3MAX >= playerChoiceInt)) | |
263 | + | then (playerChoiceInt >= R3MIN) | |
264 | + | else false) | |
265 | + | then R3K | |
266 | + | else if (if ((R4MAX >= playerChoiceInt)) | |
267 | + | then (playerChoiceInt >= R4MIN) | |
268 | + | else false) | |
269 | + | then R4K | |
270 | + | else if (if ((R5MAX >= playerChoiceInt)) | |
271 | + | then (playerChoiceInt >= R5MIN) | |
272 | + | else false) | |
273 | + | then R5K | |
274 | + | else if (if ((R6MAX >= playerChoiceInt)) | |
275 | + | then (playerChoiceInt >= R6MIN) | |
276 | + | else false) | |
277 | + | then R6K | |
278 | + | else if (if ((R7MAX >= playerChoiceInt)) | |
279 | + | then (playerChoiceInt >= R7MIN) | |
280 | + | else false) | |
281 | + | then R7K | |
282 | + | else if (if ((R8MAX >= playerChoiceInt)) | |
283 | + | then (playerChoiceInt >= R8MIN) | |
284 | + | else false) | |
285 | + | then R8K | |
286 | + | else if (if ((R9MAX >= playerChoiceInt)) | |
287 | + | then (playerChoiceInt >= R9MIN) | |
288 | + | else false) | |
289 | + | then R9K | |
290 | + | else if (if ((R10MAX >= playerChoiceInt)) | |
291 | + | then (playerChoiceInt >= R10MIN) | |
292 | + | else false) | |
293 | + | then R10K | |
294 | + | else throw(("Couldn't define range: playerChoice=" + playerChoice)) | |
295 | + | ((((100 * RKxPrecision) / playerChoiceInt) * bet) / PRECISION) | |
296 | + | } | |
297 | + | } | |
298 | + | ||
299 | + | ||
300 | + | func randToStr (r) = if (if ((r >= 1)) | |
301 | + | then (100 >= r) | |
302 | + | else false) | |
303 | + | then toString(r) | |
304 | + | else throw(("Unsupported r parameter passed: expected=[1,...,100] actual=" + toString(r))) | |
305 | + | ||
306 | + | ||
307 | + | func generateRandChoise (gameId,rsaSign) = { | |
308 | + | let rsaSigValid = rsaVerify_16Kb(SHA256, toBytes(gameId), rsaSign, RSAPUBLIC) | |
309 | + | if (!(rsaSigValid)) | |
310 | + | then throw("Invalid RSA signature") | |
311 | + | else { | |
312 | + | let rand = (toInt(sha256(rsaSign)) % 100) | |
313 | + | let moduleRand = if ((0 > rand)) | |
314 | + | then (-1 * rand) | |
315 | + | else rand | |
316 | + | let finalRand = (moduleRand + 1) | |
317 | + | let finalRandStr = toString(finalRand) | |
318 | + | if (if ((1 > finalRand)) | |
319 | + | then true | |
320 | + | else (finalRand > 100)) | |
321 | + | then throw(("Unsupported r parameter passed: expected=[1,...,100] actual=" + finalRandStr)) | |
322 | + | else finalRandStr | |
323 | + | } | |
324 | + | } | |
325 | + | ||
326 | + | ||
327 | + | func isPlayerWin (playerChoice,randChoice) = { | |
328 | + | let playerChoiceInt = parseIntValue(playerChoice) | |
329 | + | let randChoiceInt = parseIntValue(randChoice) | |
330 | + | (playerChoiceInt >= randChoiceInt) | |
331 | + | } | |
332 | + | ||
333 | + | ||
334 | + | func formatGameDataS (gameStatus,playerChoice,playerPubKey58,startedHeight,winAmount,assetIdx,randOrEmpty) = makeString([gameStatus, playerChoice, playerPubKey58, startedHeight, winAmount, assetIdx, if ((randOrEmpty == "")) | |
335 | + | then "" | |
336 | + | else randOrEmpty], "_") | |
337 | + | ||
338 | + | ||
339 | + | func formatGameData (gameStatus,playerChoice,playerPubKey58,startedHeight,winAmount,assetIdx,randOrEmpty) = formatGameDataS(gameStatus, playerChoice, playerPubKey58, toString(startedHeight), toString(winAmount), toString(assetIdx), randOrEmpty) | |
340 | + | ||
341 | + | ||
342 | + | func finishGameData (origGameData,gameStatus,rand,winByTimeout) = { | |
343 | + | let finishGameData = formatGameDataS(gameStatus, origGameData[IdxPlayerChoice], origGameData[IdxPlayerPubKey58], origGameData[IdxStartedHeight], origGameData[IdxWinAmount], origGameData[IdxAssetId], rand) | |
344 | + | if (winByTimeout) | |
345 | + | then (finishGameData + "_TIMEOUT") | |
346 | + | else finishGameData | |
347 | + | } | |
348 | + | ||
349 | + | ||
350 | + | func extractGameData (gameId) = split(match getString(this, gameId) { | |
351 | + | case str: String => | |
352 | + | str | |
353 | + | case _ => | |
354 | + | throw((("Game: " + gameId) + " not found.")) | |
355 | + | }, "_") | |
356 | + | ||
357 | + | ||
358 | + | @Callable(i) | |
359 | + | func maintenance (blocked) = if ((i.caller != SERVER)) | |
360 | + | then throw("not authorized") | |
361 | + | else [BooleanEntry(blockedKey, blocked)] | |
362 | + | ||
363 | + | ||
364 | + | ||
365 | + | @Callable(i) | |
366 | + | func bet (playerChoice) = if (valueOrElse(getBoolean(blockedKey), false)) | |
367 | + | then throw("Game is stopped for maintenence") | |
368 | + | else { | |
369 | + | let gameId = toBase58String(i.transactionId) | |
370 | + | if ((1 >= size(i.payments))) | |
371 | + | then throw("2 payments must be attached") | |
372 | + | else if (isDefined(getString(this, gameId))) | |
373 | + | then throw((("Bet for: " + gameId) + " was already made.")) | |
374 | + | else { | |
375 | + | let betPmt = value(i.payments[0]) | |
376 | + | let feePmt = value(i.payments[1]) | |
377 | + | if (isDefined(feePmt.assetId)) | |
378 | + | then throw("feePmt (2nd payment) assetId must be in Waves") | |
379 | + | else if ((MINFEEWAVES > feePmt.amount)) | |
380 | + | then throw("feePmt (2nd payment) must be >= 0.005 Waves") | |
381 | + | else { | |
382 | + | let assetIdStr = assetIdToStr(betPmt.assetId) | |
383 | + | let internalAssetIdx = validateAndGetAssetIdx(assetIdStr) | |
384 | + | let commission = feePmt.amount | |
385 | + | let winAmount = validateBetAndGetWinAmount(betPmt.amount, internalAssetIdx, playerChoice) | |
386 | + | let playerPubKey58 = toBase58String(i.callerPublicKey) | |
387 | + | let gameData = formatGameData(STATESUBMITTED, playerChoice, playerPubKey58, height, winAmount, internalAssetIdx, "") | |
388 | + | [IntegerEntry(RESERVATIONKEY(internalAssetIdx), increaseReserveAmount(winAmount, internalAssetIdx)), incrementInt(GAMESCOUNTERKEY), StringEntry(gameId, gameData), ScriptTransfer(SERVER, commission, feePmt.assetId)] | |
389 | + | } | |
390 | + | } | |
391 | + | } | |
392 | + | ||
393 | + | ||
394 | + | ||
395 | + | @Callable(i) | |
396 | + | func withdraw (gameId,rsaSign) = { | |
397 | + | let gameData = extractGameData(gameId) | |
398 | + | let gameState = gameData[IdxGameState] | |
399 | + | let playerChoice = gameData[IdxPlayerChoice] | |
400 | + | let startedHeight = parseIntValue(gameData[IdxStartedHeight]) | |
401 | + | let winAmount = parseIntValue(gameData[IdxWinAmount]) | |
402 | + | let assetIdx = parseIntValue(gameData[IdxAssetId]) | |
403 | + | let playerPubKey58 = gameData[IdxPlayerPubKey58] | |
404 | + | let playerAddress = addressFromPublicKey(fromBase58String(playerPubKey58)) | |
405 | + | if ((gameState != STATESUBMITTED)) | |
406 | + | then throw("Invalid game state for passed gameId") | |
407 | + | else if ((i.caller != SERVER)) | |
408 | + | then throw("Regular withdraw can be done by server only") | |
409 | + | else { | |
410 | + | let winByTimeout = ((height - startedHeight) > RANDORACLETIMEFRAME) | |
411 | + | let randChoise = if (winByTimeout) | |
412 | + | then playerChoice | |
413 | + | else generateRandChoise(gameId, rsaSign) | |
414 | + | let playerWin = isPlayerWin(playerChoice, randChoise) | |
415 | + | let newGameStatus = if (playerWin) | |
416 | + | then STATEWON | |
417 | + | else STATELOST | |
418 | + | let newGameData = finishGameData(gameData, newGameStatus, randChoise, winByTimeout) | |
419 | + | ([StringEntry(gameId, newGameData), decreaseReservedAmount(gameId, assetIdx, winAmount)] ++ (if (playerWin) | |
420 | + | then [ScriptTransfer(playerAddress, winAmount, assetIdFromStr(ASSETS[assetIdx]))] | |
421 | + | else nil)) | |
422 | + | } | |
423 | + | } | |
424 | + | ||
425 | + | ||
426 | + | @Verifier(tx) | |
427 | + | func verify () = if (sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)) | |
428 | + | then match tx { | |
429 | + | case ttx: TransferTransaction => | |
430 | + | let assetIdx = validateAndGetAssetIdx(assetIdToStr(ttx.assetId)) | |
431 | + | ((getAssetBalance(ttx.assetId) - ttx.amount) >= getIntOr(RESERVATIONKEY(assetIdx), 0)) | |
432 | + | case stx: SetScriptTransaction => | |
433 | + | func checker (acc,el) = if (acc) | |
434 | + | then (getIntOr(RESERVATIONKEYBYSTR(el), 0) == 0) | |
435 | + | else false | |
436 | + | ||
437 | + | let $l = ASSETS | |
438 | + | let $s = size($l) | |
439 | + | let $acc0 = true | |
440 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
441 | + | then $a | |
442 | + | else checker($a, $l[$i]) | |
443 | + | ||
444 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
445 | + | then $a | |
446 | + | else throw("List size exceeds 10") | |
447 | + | ||
448 | + | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10) | |
449 | + | case _ => | |
450 | + | false | |
451 | + | } | |
452 | + | else false | |
453 | + |
github/deemru/w8io/169f3d6 25.22 ms ◑