tx · CN8pxEUGxWwQTBLb5JpN4huLZfzWk5tU6no8RX71duEP

3N1BEXuoepNEwqkbeZYKviaLQfvBQV3ibYE:  -0.02400000 Waves

2024.08.19 13:56 [3245611] smart account 3N1BEXuoepNEwqkbeZYKviaLQfvBQV3ibYE > SELF 0.00000000 Waves

{ "type": 13, "id": "CN8pxEUGxWwQTBLb5JpN4huLZfzWk5tU6no8RX71duEP", "fee": 2400000, "feeAssetId": null, "timestamp": 1724065030303, "version": 2, "chainId": 84, "sender": "3N1BEXuoepNEwqkbeZYKviaLQfvBQV3ibYE", "senderPublicKey": "6t3vrhP1jCmG7CeKBmL8hUibtdP3cMXGC2XtPYEPPC5w", "proofs": [ "4iTTfs5ZVo3xus2ZbVffWVWK5HfqAit4xRRNnB3eRhw4Ak96JjxoJK293FNfiKYhHNdJCQyeAPGvtcH8nRqRr1nt" ], "script": "base64:BgIrCAISBQoDCAEIEgMKAQgSBAoCCAQSAwoBCBIDCgEIEgUKAwgBCBIECgIIATYACXNlcGFyYXRvcgICX18ABU1VTFQ4AIDC1y8AC3dhdmVzU3RyaW5nAgVXQVZFUwAQc3RhdHVzSW5Qcm9ncmVzcwIKaW5Qcm9ncmVzcwAOc3RhdHVzQWNjZXB0ZWQCCGFjY2VwdGVkAA5zdGF0dXNSZWplY3RlZAIIcmVqZWN0ZWQBB3dyYXBFcnIBA21zZwkAuQkCCQDMCAICGHZvdGluZ192ZXJpZmllZF92Mi5yaWRlOgkAzAgCBQNtc2cFA25pbAIBIAEIdGhyb3dFcnIBA21zZwkAAgEJAQd3cmFwRXJyAQUDbXNnAQVhc0ludAEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIDSW50BAZ2YWxJbnQFByRtYXRjaDAFBnZhbEludAkAAgECG0ZhaWxlZCB0byBjYXN0IGludG8gSW50ZWdlcgEMcGFyc2VBc3NldElkAQVpbnB1dAMJAAACBQVpbnB1dAULd2F2ZXNTdHJpbmcFBHVuaXQJANkEAQUFaW5wdXQBD2Fzc2V0SWRUb1N0cmluZwEFaW5wdXQDCQAAAgUFaW5wdXQFBHVuaXQFC3dhdmVzU3RyaW5nCQDYBAEJAQV2YWx1ZQEFBWlucHV0ARBnZXRJbnRlZ2VyT3JaZXJvAgdhZGRyZXNzA2tleQkBC3ZhbHVlT3JFbHNlAgkAmggCBQdhZGRyZXNzBQNrZXkAAAEQZ2V0SW50ZWdlck9yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQdhZGRyZXNzBQNrZXkJAQd3cmFwRXJyAQkArAICBQNrZXkCDyBpcyBub3QgZGVmaW5lZAEQZ2V0U3RyaW5nT3JFbXB0eQIHYWRkcmVzcwNrZXkJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUHYWRkcmVzcwUDa2V5AgABD2dldFN0cmluZ09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJAQd3cmFwRXJyAQkArAICBQNrZXkCDyBpcyBub3QgZGVmaW5lZAATa2V5Qm9vc3RpbmdDb250cmFjdAkAuQkCCQDMCAICAiVzCQDMCAICEGJvb3N0aW5nQ29udHJhY3QFA25pbAUJc2VwYXJhdG9yABNrZXlFbWlzc2lvbkNvbnRyYWN0CQC5CQIJAMwIAgICJXMJAMwIAgIQZW1pc3Npb25Db250cmFjdAUDbmlsBQlzZXBhcmF0b3IAFmtleUFzc2V0c1N0b3JlQ29udHJhY3QJALkJAgkAzAgCAgIlcwkAzAgCAhNhc3NldHNTdG9yZUNvbnRyYWN0BQNuaWwFCXNlcGFyYXRvcgAQYm9vc3RpbmdDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTgpAQUTa2V5Qm9vc3RpbmdDb250cmFjdAAQZW1pc3Npb25Db250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTgpAQUTa2V5RW1pc3Npb25Db250cmFjdAATYXNzZXRzU3RvcmVDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTgpAQUWa2V5QXNzZXRzU3RvcmVDb250cmFjdAARa2V5RW1pc3Npb25Db25maWcJALkJAgkAzAgCAgIlcwkAzAgCAgZjb25maWcFA25pbAUJc2VwYXJhdG9yAAx3eEFzc2V0SWRTdHIJAJEDAgkAtQkCCQEPZ2V0U3RyaW5nT3JGYWlsAgUQZW1pc3Npb25Db250cmFjdAURa2V5RW1pc3Npb25Db25maWcFCXNlcGFyYXRvcgABAAl3eEFzc2V0SWQJAQxwYXJzZUFzc2V0SWQBBQx3eEFzc2V0SWRTdHIAFWtleVZvdGluZ1RocmVzaG9sZEFkZAkAuQkCCQDMCAICBCVzJXMJAMwIAgIPdm90aW5nVGhyZXNob2xkCQDMCAICA2FkZAUDbmlsBQlzZXBhcmF0b3IAGGtleVZvdGluZ1RocmVzaG9sZFJlbW92ZQkAuQkCCQDMCAICBCVzJXMJAMwIAgIPdm90aW5nVGhyZXNob2xkCQDMCAICBnJlbW92ZQUDbmlsBQlzZXBhcmF0b3IAFWtleVBlcmlvZExlbmd0aFJlbW92ZQkAuQkCCQDMCAICAiVzCQDMCAICEnBlcmlvZExlbmd0aFJlbW92ZQUDbmlsBQlzZXBhcmF0b3IAEmtleU1heFBlcmlvZExlbmd0aAkAuQkCCQDMCAICAiVzCQDMCAICD21heFBlcmlvZExlbmd0aAUDbmlsBQlzZXBhcmF0b3IAEmtleU1pblBlcmlvZExlbmd0aAkAuQkCCQDMCAICAiVzCQDMCAICD21pblBlcmlvZExlbmd0aAUDbmlsBQlzZXBhcmF0b3IBFmtleVZvdGluZ1Jld2FyZEFzc2V0SWQCB2Fzc2V0SWQFaW5kZXgJALkJAgkAzAgCAgYlcyVzJWQJAMwIAgITdm90aW5nUmV3YXJkQXNzZXRJZAkAzAgCBQdhc3NldElkCQDMCAIJAKQDAQUFaW5kZXgFA25pbAUJc2VwYXJhdG9yAQ9rZXlWb3RpbmdSZXdhcmQDC3VzZXJBZGRyZXNzB2Fzc2V0SWQFaW5kZXgJALkJAgkAzAgCAgglcyVzJXMlZAkAzAgCAgx2b3RpbmdSZXdhcmQJAMwIAgkApQgBBQt1c2VyQWRkcmVzcwkAzAgCBQdhc3NldElkCQDMCAIJAKQDAQUFaW5kZXgFA25pbAUJc2VwYXJhdG9yARRrZXlUb3RhbFZvdGluZ1Jld2FyZAIHYXNzZXRJZAVpbmRleAkAuQkCCQDMCAICBiVzJXMlZAkAzAgCAhF0b3RhbFZvdGluZ1Jld2FyZAkAzAgCBQdhc3NldElkCQDMCAIJAKQDAQUFaW5kZXgFA25pbAUJc2VwYXJhdG9yABtrZXlGaW5hbGl6ZUNhbGxSZXdhcmRBbW91bnQJALkJAgkAzAgCAgIlcwkAzAgCAhhmaW5hbGl6ZUNhbGxSZXdhcmRBbW91bnQFA25pbAUJc2VwYXJhdG9yABprZXlNaW5TdWdnZXN0UmVtb3ZlQmFsYW5jZQkAuQkCCQDMCAICAiVzCQDMCAICF21pblN1Z2dlc3RSZW1vdmVCYWxhbmNlBQNuaWwFCXNlcGFyYXRvcgEPa2V5Q3VycmVudEluZGV4AQdhc3NldElkCQC5CQIJAMwIAgIEJXMlcwkAzAgCAgxjdXJyZW50SW5kZXgJAMwIAgUHYXNzZXRJZAUDbmlsBQlzZXBhcmF0b3IBB2tleVZvdGUDB2Fzc2V0SWQFaW5kZXgGY2FsbGVyCQC5CQIJAMwIAgIIJXMlcyVkJXMJAMwIAgIEdm90ZQkAzAgCBQdhc3NldElkCQDMCAIJAKQDAQUFaW5kZXgJAMwIAgkApQgBBQZjYWxsZXIFA25pbAUJc2VwYXJhdG9yAQl2b3RlVmFsdWUCB2luRmF2b3IJZ3d4QW1vdW50CQC5CQIJAMwIAgIEJXMlZAkAzAgCCQClAwEFB2luRmF2b3IJAMwIAgkApAMBBQlnd3hBbW91bnQFA25pbAUJc2VwYXJhdG9yARBrZXlTdWdnZXN0SXNzdWVyAgdhc3NldElkBWluZGV4CQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICDXN1Z2dlc3RJc3N1ZXIJAMwIAgUHYXNzZXRJZAkAzAgCCQCkAwEFBWluZGV4BQNuaWwFCXNlcGFyYXRvcgEPa2V5Q2xhaW1IaXN0b3J5Awt1c2VyQWRkcmVzcwdhc3NldElkBWluZGV4CQC5CQIJAMwIAgIIJXMlcyVzJWQJAMwIAgIHaGlzdG9yeQkAzAgCCQClCAEFC3VzZXJBZGRyZXNzCQDMCAIFB2Fzc2V0SWQJAMwIAgkApAMBBQVpbmRleAUDbmlsBQlzZXBhcmF0b3IADmtleUZlZVBlckJsb2NrCQC5CQIJAMwIAgICJXMJAMwIAgILZmVlUGVyQmxvY2sFA25pbAUJc2VwYXJhdG9yAAtmZWVQZXJCbG9jawkBEGdldEludGVnZXJPckZhaWwCBQR0aGlzBQ5rZXlGZWVQZXJCbG9jawAma2V5TWluV3hNaW5Gb3JTdWdnZXN0QWRkQW1vdW50UmVxdWlyZWQJALkJAgkAzAgCAgIlcwkAzAgCAiB3eE1pbkZvclN1Z2dlc3RBZGRBbW91bnRSZXF1aXJlZAUDbmlsBQlzZXBhcmF0b3IAI2tleVd4Rm9yU3VnZ2VzdFJlbW92ZUFtb3VudFJlcXVpcmVkCQC5CQIJAMwIAgICJXMJAMwIAgIgd3hGb3JTdWdnZXN0UmVtb3ZlQW1vdW50UmVxdWlyZWQFA25pbAUJc2VwYXJhdG9yAQ1rZXlWb3RpbmdJbmZvAgdhc3NldElkBWluZGV4CQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICCnZvdGluZ0luZm8JAMwIAgUHYXNzZXRJZAkAzAgCCQCkAwEFBWluZGV4BQNuaWwFCXNlcGFyYXRvcgEPdm90aW5nSW5mb1ZhbHVlCg1pc1Jld2FyZEV4aXN0DXJld2FyZEFzc2V0SWQMcmV3YXJkQW1vdW50CnZvdGluZ1R5cGUGc3RhdHVzEXZvdGluZ1N0YXJ0SGVpZ2h0D3ZvdGluZ0VuZEhlaWdodAt2b3Rlc1F1b3J1bQh2b3Rlc0Zvcgx2b3Rlc0FnYWluc3QJALkJAgkAzAgCAhQlcyVzJWQlcyVzJWQlZCVkJWQlZAkAzAgCCQClAwEFDWlzUmV3YXJkRXhpc3QJAMwIAgUNcmV3YXJkQXNzZXRJZAkAzAgCCQCkAwEFDHJld2FyZEFtb3VudAkAzAgCBQp2b3RpbmdUeXBlCQDMCAIFBnN0YXR1cwkAzAgCCQCkAwEFEXZvdGluZ1N0YXJ0SGVpZ2h0CQDMCAIJAKQDAQUPdm90aW5nRW5kSGVpZ2h0CQDMCAIJAKQDAQULdm90ZXNRdW9ydW0JAMwIAgkApAMBBQh2b3Rlc0ZvcgkAzAgCCQCkAwEFDHZvdGVzQWdhaW5zdAUDbmlsBQlzZXBhcmF0b3IBDWtleUFzc2V0SW1hZ2UBB2Fzc2V0SWQJALkJAgkAzAgCAgQlcyVzCQDMCAICCmFzc2V0SW1hZ2UJAMwIAgUHYXNzZXRJZAUDbmlsBQlzZXBhcmF0b3IBGGdldFVzZXJHd3hBbW91bnRBdEhlaWdodAILdXNlckFkZHJlc3MMdGFyZ2V0SGVpZ2h0BAlnd3hBbW91bnQJAPwHBAUQYm9vc3RpbmdDb250cmFjdAIgZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0UkVBRE9OTFkJAMwIAgULdXNlckFkZHJlc3MJAMwIAgUMdGFyZ2V0SGVpZ2h0BQNuaWwFA25pbAkBBWFzSW50AQUJZ3d4QW1vdW50ARZrZXlNYW5hZ2VyVmF1bHRBZGRyZXNzAAIXJXNfX21hbmFnZXJWYXVsdEFkZHJlc3MBE2tleU1hbmFnZXJQdWJsaWNLZXkAAhQlc19fbWFuYWdlclB1YmxpY0tleQEcZ2V0TWFuYWdlclZhdWx0QWRkcmVzc09yVGhpcwAEByRtYXRjaDAJAKIIAQkBFmtleU1hbmFnZXJWYXVsdEFkZHJlc3MAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkBEUBleHRyTmF0aXZlKDEwNjIpAQUBcwUEdGhpcwEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAAEE21hbmFnZXJWYXVsdEFkZHJlc3MJARxnZXRNYW5hZ2VyVmF1bHRBZGRyZXNzT3JUaGlzAAQHJG1hdGNoMAkAnQgCBRNtYW5hZ2VyVmF1bHRBZGRyZXNzCQETa2V5TWFuYWdlclB1YmxpY0tleQADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQDZBAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yARJnZXRWb3RpbmdJbmZvUGFydHMBCnZvdGluZ0luZm8ED3ZvdGluZ0luZm9QYXJ0cwkAtQkCBQp2b3RpbmdJbmZvBQlzZXBhcmF0b3IEEGlzUmV3YXJkRXhpc3RTdHIJAJEDAgUPdm90aW5nSW5mb1BhcnRzAAEEDWlzUmV3YXJkRXhpc3QDCQAAAgUQaXNSZXdhcmRFeGlzdFN0cgIEdHJ1ZQYHBA1yZXdhcmRBc3NldElkCQCRAwIFD3ZvdGluZ0luZm9QYXJ0cwACBAxyZXdhcmRBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ92b3RpbmdJbmZvUGFydHMAAwQKdm90aW5nVHlwZQkAkQMCBQ92b3RpbmdJbmZvUGFydHMABAQGc3RhdHVzCQCRAwIFD3ZvdGluZ0luZm9QYXJ0cwAFBBF2b3RpbmdTdGFydEhlaWdodAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD3ZvdGluZ0luZm9QYXJ0cwAGBA92b3RpbmdFbmRIZWlnaHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ92b3RpbmdJbmZvUGFydHMABwQLdm90ZXNRdW9ydW0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ92b3RpbmdJbmZvUGFydHMACAQIdm90ZXNGb3IJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ92b3RpbmdJbmZvUGFydHMACQQMdm90ZXNBZ2FpbnN0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPdm90aW5nSW5mb1BhcnRzAAoJAJwKCgUNaXNSZXdhcmRFeGlzdAUNcmV3YXJkQXNzZXRJZAUMcmV3YXJkQW1vdW50BQp2b3RpbmdUeXBlBQZzdGF0dXMFEXZvdGluZ1N0YXJ0SGVpZ2h0BQ92b3RpbmdFbmRIZWlnaHQFC3ZvdGVzUXVvcnVtBQh2b3Rlc0ZvcgUMdm90ZXNBZ2FpbnN0ARF2b3RpbmdFeGlzdENoZWNrcwIHYXNzZXRJZAxjdXJyZW50SW5kZXgECnZvdGluZ0luZm8JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQENa2V5Vm90aW5nSW5mbwIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAkBB3dyYXBFcnIBAhV2b3RpbmcgaW5mbyBub3QgZm91bmQED3ZvdGluZ0luZm9BcnJheQkAtQkCBQp2b3RpbmdJbmZvBQlzZXBhcmF0b3IEBnN0YXR1cwkAkQMCBQ92b3RpbmdJbmZvQXJyYXkABQQPdm90aW5nRW5kSGVpZ2h0CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ92b3RpbmdJbmZvQXJyYXkABwkBB3dyYXBFcnIBAh12b3Rpbmcgc3RhcnQgaGVpZ2h0IG5vdCBmb3VuZAQNc3VnZ2VzdElzc3VlcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJARBrZXlTdWdnZXN0SXNzdWVyAgUHYXNzZXRJZAUMY3VycmVudEluZGV4CQEHd3JhcEVycgECF3ZvdGluZyBpc3N1ZXIgbm90IGZvdW5kBAZjaGVja3MJAMwIAgMJAAACBQZzdGF0dXMFEHN0YXR1c0luUHJvZ3Jlc3MGCQEIdGhyb3dFcnIBAhVubyB2b3RpbmcgaW4gcHJvZ3Jlc3MJAMwIAgMJAGYCBQ92b3RpbmdFbmRIZWlnaHQFBmhlaWdodAYJAQh0aHJvd0VycgECDnZvdGluZyBleHBpcmVkBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MJAJUKAwUGc3RhdHVzBQ92b3RpbmdFbmRIZWlnaHQFDXN1Z2dlc3RJc3N1ZXIJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BD2NhbGN1bGF0ZVJld2FyZAMFdm90ZXIHYXNzZXRJZAVpbmRleAQHdm90ZUtleQkBB2tleVZvdGUDBQdhc3NldElkBQVpbmRleAUFdm90ZXIECGxhc3RWb3RlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQUHdm90ZUtleQkBB3dyYXBFcnIBAhJ5b3UgaGF2ZSBub3Qgdm90ZWQEDWxhc3RWb3RlUGFydHMJALUJAgUIbGFzdFZvdGUFCXNlcGFyYXRvcgQJZ3d4QW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUNbGFzdFZvdGVQYXJ0cwACBA12b3RpbmdJbmZvU3RyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBDWtleVZvdGluZ0luZm8CBQdhc3NldElkBQVpbmRleAkBB3dyYXBFcnIBAhV2b3RpbmcgaW5mbyBub3QgZm91bmQEC3ZvdGluZ1BhcnRzCQESZ2V0Vm90aW5nSW5mb1BhcnRzAQUNdm90aW5nSW5mb1N0cgQGc3RhdHVzCAULdm90aW5nUGFydHMCXzUECHZvdGVzRm9yCAULdm90aW5nUGFydHMCXzkEDHZvdGVzQWdhaW5zdAgFC3ZvdGluZ1BhcnRzA18xMAQVcGFydE9mVGhlVG90YWxWb3Rlc1g4CQBrAwUJZ3d4QW1vdW50BQVNVUxUOAkAZAIFCHZvdGVzRm9yBQx2b3Rlc0FnYWluc3QEEXRvdGFsVm90aW5nUmV3YXJkCQELdmFsdWVPckVsc2UCCQCfCAEJARRrZXlUb3RhbFZvdGluZ1Jld2FyZAIFB2Fzc2V0SWQFBWluZGV4AAAEEXZvdGVyUmV3YXJkQW1vdW50CQBuBAUVcGFydE9mVGhlVG90YWxWb3Rlc1g4BRF0b3RhbFZvdGluZ1Jld2FyZAUFTVVMVDgFBUZMT09SBAhjYW5DbGFpbQMJAAACBQZzdGF0dXMFDnN0YXR1c0FjY2VwdGVkCQBmAgURdm90ZXJSZXdhcmRBbW91bnQAAAcJAJQKAgURdm90ZXJSZXdhcmRBbW91bnQFCGNhbkNsYWltBwFpAQpzdWdnZXN0QWRkAwdhc3NldElkDHBlcmlvZExlbmd0aAphc3NldEltYWdlBAl3eFBheW1lbnQJAJEDAggFAWkIcGF5bWVudHMAAAQQd3hQYXltZW50QXNzZXRJZAkBBXZhbHVlAQgFCXd4UGF5bWVudAdhc3NldElkBA93eFBheW1lbnRBbW91bnQJAQV2YWx1ZQEIBQl3eFBheW1lbnQGYW1vdW50BA9taW5QZXJpb2RMZW5ndGgJARFAZXh0ck5hdGl2ZSgxMDU1KQEFEmtleU1pblBlcmlvZExlbmd0aAQPbWF4UGVyaW9kTGVuZ3RoCQERQGV4dHJOYXRpdmUoMTA1NSkBBRJrZXlNYXhQZXJpb2RMZW5ndGgED3Rva2VuSXNWZXJpZmllZAoAAUAJAPwHBAUTYXNzZXRzU3RvcmVDb250cmFjdAISaXNWZXJpZmllZFJFQURPTkxZCQDMCAIFB2Fzc2V0SWQFA25pbAUDbmlsAwkAAQIFAUACB0Jvb2xlYW4FAUAJAAIBCQCsAgIJAAMBBQFAAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAZjaGVja3MJAMwIAgMDCQBnAgUMcGVyaW9kTGVuZ3RoBQ9taW5QZXJpb2RMZW5ndGgJAGcCBQ9tYXhQZXJpb2RMZW5ndGgFDHBlcmlvZExlbmd0aAcGCQEIdGhyb3dFcnIBAhRpbnZhbGlkIHBlcmlvZExlbmd0aAkAzAgCAwkAAAIFD3Rva2VuSXNWZXJpZmllZAcGCQEIdGhyb3dFcnIBAhZ0b2tlbiBhbHJlYWR5IHZlcmlmaWVkCQDMCAIDCQAAAgUQd3hQYXltZW50QXNzZXRJZAUJd3hBc3NldElkBgkBCHRocm93RXJyAQIacGF5bWVudFswXSBzaG91bGQgYmUgaW4gd3gJAMwIAgMJAGcCBQ93eFBheW1lbnRBbW91bnQJAGgCBQxwZXJpb2RMZW5ndGgFC2ZlZVBlckJsb2NrBgkBCHRocm93RXJyAQIebm90IGVub3VnaCB3eCBmb3IgZ2l2ZW4gcGVyaW9kCQDMCAIDCQBnAgUPd3hQYXltZW50QW1vdW50CQERQGV4dHJOYXRpdmUoMTA1NSkBBSZrZXlNaW5XeE1pbkZvclN1Z2dlc3RBZGRBbW91bnRSZXF1aXJlZAYJAQh0aHJvd0VycgECIXBheW1lbnQgbGVzcyB0aGVuIG1pbiBmb3Igc3VnZ2VzdAUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBA9jdXJyZW50SW5kZXhLZXkJAQ9rZXlDdXJyZW50SW5kZXgBBQdhc3NldElkBAxjdXJyZW50SW5kZXgJAJ8IAQUPY3VycmVudEluZGV4S2V5BAhuZXdJbmRleAMJAQlpc0RlZmluZWQBBQxjdXJyZW50SW5kZXgJAGQCCQEFdmFsdWUBBQxjdXJyZW50SW5kZXgAAQAABAskdDA5MzMzOTk2NgMJAGYCCQCQAwEIBQFpCHBheW1lbnRzAAEEE3ZvdGluZ1Jld2FyZFBheW1lbnQJAJEDAggFAWkIcGF5bWVudHMAAQQadm90aW5nUmV3YXJkUGF5bWVudEFzc2V0SWQJAQ9hc3NldElkVG9TdHJpbmcBCAUTdm90aW5nUmV3YXJkUGF5bWVudAdhc3NldElkBBl2b3RpbmdSZXdhcmRQYXltZW50QW1vdW50CQEFdmFsdWUBCAUTdm90aW5nUmV3YXJkUGF5bWVudAZhbW91bnQJAJYKBAYFGnZvdGluZ1Jld2FyZFBheW1lbnRBc3NldElkBRl2b3RpbmdSZXdhcmRQYXltZW50QW1vdW50CQDMCAIJAQtTdHJpbmdFbnRyeQIJARZrZXlWb3RpbmdSZXdhcmRBc3NldElkAgUHYXNzZXRJZAUIbmV3SW5kZXgFGnZvdGluZ1Jld2FyZFBheW1lbnRBc3NldElkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEUa2V5VG90YWxWb3RpbmdSZXdhcmQCBQdhc3NldElkBQhuZXdJbmRleAUZdm90aW5nUmV3YXJkUGF5bWVudEFtb3VudAUDbmlsCQCWCgQHAgVFTVBUWQAABQNuaWwEDWlzUmV3YXJkRXhpc3QIBQskdDA5MzMzOTk2NgJfMQQNcmV3YXJkQXNzZXRJZAgFCyR0MDkzMzM5OTY2Al8yBAxyZXdhcmRBbW91bnQIBQskdDA5MzMzOTk2NgJfMwQTdm90aW5nUmV3YXJkQWN0aW9ucwgFCyR0MDkzMzM5OTY2Al80BAt2b3Rlc1F1b3J1bQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFFWtleVZvdGluZ1RocmVzaG9sZEFkZAkBB3dyYXBFcnIBAhp2b3RpbmdUaHJlc2hvbGRBZGQgbm90IHNldAQKdm90aW5nSW5mbwkBD3ZvdGluZ0luZm9WYWx1ZQoFDWlzUmV3YXJkRXhpc3QFDXJld2FyZEFzc2V0SWQFDHJld2FyZEFtb3VudAIMdmVyaWZpY2F0aW9uBRBzdGF0dXNJblByb2dyZXNzBQZoZWlnaHQJAGQCBQZoZWlnaHQFDHBlcmlvZExlbmd0aAULdm90ZXNRdW9ydW0AAAAABBhmaW5hbGl6ZUNhbGxSZXdhcmRBbW91bnQJARFAZXh0ck5hdGl2ZSgxMDU1KQEFG2tleUZpbmFsaXplQ2FsbFJld2FyZEFtb3VudAQMYnVybld4QW1vdW50CQBlAgUPd3hQYXltZW50QW1vdW50BRhmaW5hbGl6ZUNhbGxSZXdhcmRBbW91bnQJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUPY3VycmVudEluZGV4S2V5BQhuZXdJbmRleAkAzAgCCQELU3RyaW5nRW50cnkCCQEQa2V5U3VnZ2VzdElzc3VlcgIFB2Fzc2V0SWQFCG5ld0luZGV4CQClCAEIBQFpBmNhbGxlcgkAzAgCCQELU3RyaW5nRW50cnkCCQENa2V5Vm90aW5nSW5mbwIFB2Fzc2V0SWQFCG5ld0luZGV4BQp2b3RpbmdJbmZvCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ1rZXlBc3NldEltYWdlAQUHYXNzZXRJZAUKYXNzZXRJbWFnZQkAzAgCCQEEQnVybgIFEHd4UGF5bWVudEFzc2V0SWQFDGJ1cm5XeEFtb3VudAUDbmlsBRN2b3RpbmdSZXdhcmRBY3Rpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDXN1Z2dlc3RSZW1vdmUBB2Fzc2V0SWQEDmd3eEFtb3VudEF0Tm93CQEYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0AgkApQgBCAUBaQZjYWxsZXIFBmhlaWdodAQXbWluU3VnZ2VzdFJlbW92ZUJhbGFuY2UJARFAZXh0ck5hdGl2ZSgxMDU1KQEFGmtleU1pblN1Z2dlc3RSZW1vdmVCYWxhbmNlBAl3eFBheW1lbnQJAJEDAggFAWkIcGF5bWVudHMAAAQQd3hQYXltZW50QXNzZXRJZAkBBXZhbHVlAQgFCXd4UGF5bWVudAdhc3NldElkBA93eFBheW1lbnRBbW91bnQJAQV2YWx1ZQEIBQl3eFBheW1lbnQGYW1vdW50BA90b2tlbklzVmVyaWZpZWQKAAFACQD8BwQFE2Fzc2V0c1N0b3JlQ29udHJhY3QCEmlzVmVyaWZpZWRSRUFET05MWQkAzAgCBQdhc3NldElkBQNuaWwFA25pbAMJAAECBQFAAgdCb29sZWFuBQFACQACAQkArAICCQADAQUBQAIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQGY2hlY2tzCQDMCAIDBQ90b2tlbklzVmVyaWZpZWQGCQEIdGhyb3dFcnIBAhJ0b2tlbiBub3QgdmVyaWZpZWQJAMwIAgMJAGcCBQ5nd3hBbW91bnRBdE5vdwUXbWluU3VnZ2VzdFJlbW92ZUJhbGFuY2UGCQEIdGhyb3dFcnIBAhBub3QgZW5vdWdoIGdXWGVzCQDMCAIDCQAAAgUQd3hQYXltZW50QXNzZXRJZAUJd3hBc3NldElkBgkBCHRocm93RXJyAQIXcGF5bWVudCBzaG91bGQgYmUgaW4gd3gJAMwIAgMJAGcCBQ93eFBheW1lbnRBbW91bnQJARFAZXh0ck5hdGl2ZSgxMDU1KQEFI2tleVd4Rm9yU3VnZ2VzdFJlbW92ZUFtb3VudFJlcXVpcmVkBgkBCHRocm93RXJyAQIhcGF5bWVudCBsZXNzIHRoZW4gbWluIGZvciBzdWdnZXN0BQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MED2N1cnJlbnRJbmRleEtleQkBD2tleUN1cnJlbnRJbmRleAEFB2Fzc2V0SWQEDGN1cnJlbnRJbmRleAkAnwgBBQ9jdXJyZW50SW5kZXhLZXkECG5ld0luZGV4AwkBCWlzRGVmaW5lZAEFDGN1cnJlbnRJbmRleAkAZAIJAQV2YWx1ZQEFDGN1cnJlbnRJbmRleAABAAAEDHBlcmlvZExlbmd0aAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFFWtleVBlcmlvZExlbmd0aFJlbW92ZQkBB3dyYXBFcnIBAhpwZXJpb2RMZW5ndGhSZW1vdmUgbm90IHNldAQPdm90aW5nRW5kSGVpZ2h0CQBkAgUGaGVpZ2h0BQxwZXJpb2RMZW5ndGgEC3ZvdGVzUXVvcnVtCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUYa2V5Vm90aW5nVGhyZXNob2xkUmVtb3ZlCQEHd3JhcEVycgECHXZvdGluZ1RocmVzaG9sZFJlbW92ZSBub3Qgc2V0BAp2b3RpbmdJbmZvCQEPdm90aW5nSW5mb1ZhbHVlCgcCBUVNUFRZAAACDmRldmVyaWZpY2F0aW9uBRBzdGF0dXNJblByb2dyZXNzBQZoZWlnaHQJAGQCBQZoZWlnaHQFDHBlcmlvZExlbmd0aAULdm90ZXNRdW9ydW0AAAAABBNzZXRBc3NldEltYWdlQWN0aW9uBAckbWF0Y2gwCQCiCAEJAQ1rZXlBc3NldEltYWdlAQUHYXNzZXRJZAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAFA25pbAMJAAECBQckbWF0Y2gwAgRVbml0BBVhc3NldHNTdG9yZUFzc2V0SW1hZ2UKAAFACQD8BwQFE2Fzc2V0c1N0b3JlQ29udHJhY3QCFGdldEFzc2V0TG9nb1JFQURPTkxZCQDMCAIFB2Fzc2V0SWQFA25pbAUDbmlsAwkAAQIFAUACBlN0cmluZwUBQAkAAgEJAKwCAgkAAwEFAUACGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwkAzAgCCQELU3RyaW5nRW50cnkCCQENa2V5QXNzZXRJbWFnZQEFB2Fzc2V0SWQFFWFzc2V0c1N0b3JlQXNzZXRJbWFnZQUDbmlsCQACAQILTWF0Y2ggZXJyb3IJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUPY3VycmVudEluZGV4S2V5BQhuZXdJbmRleAkAzAgCCQELU3RyaW5nRW50cnkCCQEQa2V5U3VnZ2VzdElzc3VlcgIFB2Fzc2V0SWQFCG5ld0luZGV4CQClCAEIBQFpBmNhbGxlcgkAzAgCCQELU3RyaW5nRW50cnkCCQENa2V5Vm90aW5nSW5mbwIFB2Fzc2V0SWQFCG5ld0luZGV4BQp2b3RpbmdJbmZvBQNuaWwFE3NldEFzc2V0SW1hZ2VBY3Rpb24JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEEdm90ZQIHYXNzZXRJZAdpbkZhdm9yBA9jdXJyZW50SW5kZXhLZXkJAQ9rZXlDdXJyZW50SW5kZXgBBQdhc3NldElkBAxjdXJyZW50SW5kZXgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQ9jdXJyZW50SW5kZXhLZXkJAQd3cmFwRXJyAQIVdm90aW5nIGRvZXMgbm90IGV4aXN0BAp2b3RpbmdJbmZvCQERdm90aW5nRXhpc3RDaGVja3MCBQdhc3NldElkBQxjdXJyZW50SW5kZXgDCQAAAgUKdm90aW5nSW5mbwUKdm90aW5nSW5mbwQWY3VycmVudFZvdGluZ0VuZEhlaWdodAgFCnZvdGluZ0luZm8CXzIEDmd3eEFtb3VudEF0RW5kCQEYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0AgkApQgBCAUBaQZjYWxsZXIFFmN1cnJlbnRWb3RpbmdFbmRIZWlnaHQEB3ZvdGVLZXkJAQdrZXlWb3RlAwUHYXNzZXRJZAUMY3VycmVudEluZGV4CAUBaQZjYWxsZXIEBmNoZWNrcwkAzAgCAwkAAAIJAKIIAQUHdm90ZUtleQUEdW5pdAYJAQh0aHJvd0VycgECFllvdSBoYXZlIGFscmVhZHkgdm90ZWQJAMwIAgMJAGYCBQ5nd3hBbW91bnRBdEVuZAAABgkAAgECKFlvdSdsbCBub3QgaGF2ZSBnV1ggYXQgdGhlIGVuZCBvZiB2b3RpbmcFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwQNdm90aW5nSW5mb1N0cgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJAQ1rZXlWb3RpbmdJbmZvAgUHYXNzZXRJZAUMY3VycmVudEluZGV4CQEHd3JhcEVycgECFXZvdGluZyBpbmZvIG5vdCBmb3VuZAQPdm90aW5nSW5mb1BhcnRzCQESZ2V0Vm90aW5nSW5mb1BhcnRzAQUNdm90aW5nSW5mb1N0cgQIdm90ZXNGb3IIBQ92b3RpbmdJbmZvUGFydHMCXzkEDHZvdGVzQWdhaW5zdAgFD3ZvdGluZ0luZm9QYXJ0cwNfMTAEDSR0MDEzNzA1MTM4NjYDBQdpbkZhdm9yCQCUCgIJAGQCBQh2b3Rlc0ZvcgUOZ3d4QW1vdW50QXRFbmQFDHZvdGVzQWdhaW5zdAkAlAoCBQh2b3Rlc0ZvcgkAZAIFDHZvdGVzQWdhaW5zdAUOZ3d4QW1vdW50QXRFbmQEC25ld1ZvdGVzRm9yCAUNJHQwMTM3MDUxMzg2NgJfMQQPbmV3Vm90ZXNBZ2FpbnN0CAUNJHQwMTM3MDUxMzg2NgJfMgQSbmV3Vm90aW5nSW5mb1ZhbHVlCQEPdm90aW5nSW5mb1ZhbHVlCggFD3ZvdGluZ0luZm9QYXJ0cwJfMQgFD3ZvdGluZ0luZm9QYXJ0cwJfMggFD3ZvdGluZ0luZm9QYXJ0cwJfMwgFD3ZvdGluZ0luZm9QYXJ0cwJfNAgFD3ZvdGluZ0luZm9QYXJ0cwJfNQgFD3ZvdGluZ0luZm9QYXJ0cwJfNggFD3ZvdGluZ0luZm9QYXJ0cwJfNwgFD3ZvdGluZ0luZm9QYXJ0cwJfOAULbmV3Vm90ZXNGb3IFD25ld1ZvdGVzQWdhaW5zdAQSdm90aW5nUmV3YXJkQWN0aW9uBAckbWF0Y2gwCQCiCAEJARZrZXlWb3RpbmdSZXdhcmRBc3NldElkAgUHYXNzZXRJZAUMY3VycmVudEluZGV4AwkAAQIFByRtYXRjaDACBlN0cmluZwQCcGsFByRtYXRjaDAJAMwIAgkBC1N0cmluZ0VudHJ5AgkBD2tleVZvdGluZ1Jld2FyZAMIBQFpBmNhbGxlcgUHYXNzZXRJZAUMY3VycmVudEluZGV4CQEJdm90ZVZhbHVlAgUHaW5GYXZvcgUOZ3d4QW1vdW50QXRFbmQFA25pbAMJAAECBQckbWF0Y2gwAgRVbml0BQNuaWwJAAIBAgtNYXRjaCBlcnJvcgkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQIFB3ZvdGVLZXkJAQl2b3RlVmFsdWUCBQdpbkZhdm9yBQ5nd3hBbW91bnRBdEVuZAkAzAgCCQELU3RyaW5nRW50cnkCCQENa2V5Vm90aW5nSW5mbwIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAUSbmV3Vm90aW5nSW5mb1ZhbHVlBQNuaWwFEnZvdGluZ1Jld2FyZEFjdGlvbgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQpjYW5jZWxWb3RlAQdhc3NldElkBA9jdXJyZW50SW5kZXhLZXkJAQ9rZXlDdXJyZW50SW5kZXgBBQdhc3NldElkBAxjdXJyZW50SW5kZXgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQ9jdXJyZW50SW5kZXhLZXkJAQd3cmFwRXJyAQIVdm90aW5nIGRvZXMgbm90IGV4aXN0BAd2b3RlS2V5CQEHa2V5Vm90ZQMFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAgFAWkGY2FsbGVyBAhsYXN0Vm90ZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEFB3ZvdGVLZXkJAQd3cmFwRXJyAQISeW91IGhhdmUgbm90IHZvdGVkBA1sYXN0Vm90ZVBhcnRzCQC1CQIFCGxhc3RWb3RlBQlzZXBhcmF0b3IEB2luRmF2b3IJAJEDAgUNbGFzdFZvdGVQYXJ0cwABBAlnd3hBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ1sYXN0Vm90ZVBhcnRzAAIECnZvdGluZ0luZm8JARF2b3RpbmdFeGlzdENoZWNrcwIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAMJAAACBQp2b3RpbmdJbmZvBQp2b3RpbmdJbmZvBAZjaGVja3MJAMwIAgMDCQAAAgUHaW5GYXZvcgIEdHJ1ZQYJAAACBQdpbkZhdm9yAgVmYWxzZQYJAQh0aHJvd0VycgECDGludmFsaWQgdm90ZQUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBA12b3RpbmdJbmZvU3RyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkBDWtleVZvdGluZ0luZm8CBQdhc3NldElkBQxjdXJyZW50SW5kZXgJAQd3cmFwRXJyAQIVdm90aW5nIGluZm8gbm90IGZvdW5kBA92b3RpbmdJbmZvUGFydHMJARJnZXRWb3RpbmdJbmZvUGFydHMBBQ12b3RpbmdJbmZvU3RyBAh2b3Rlc0ZvcggFD3ZvdGluZ0luZm9QYXJ0cwJfOQQMdm90ZXNBZ2FpbnN0CAUPdm90aW5nSW5mb1BhcnRzA18xMAQNJHQwMTU0OTExNTY1MgMJAAACBQdpbkZhdm9yAgR0cnVlCQCUCgIJAGUCBQh2b3Rlc0ZvcgUJZ3d4QW1vdW50BQx2b3Rlc0FnYWluc3QJAJQKAgUIdm90ZXNGb3IJAGUCBQx2b3Rlc0FnYWluc3QFCWd3eEFtb3VudAQLbmV3Vm90ZXNGb3IIBQ0kdDAxNTQ5MTE1NjUyAl8xBA9uZXdWb3Rlc0FnYWluc3QIBQ0kdDAxNTQ5MTE1NjUyAl8yBBJuZXdWb3RpbmdJbmZvVmFsdWUJAQ92b3RpbmdJbmZvVmFsdWUKCAUPdm90aW5nSW5mb1BhcnRzAl8xCAUPdm90aW5nSW5mb1BhcnRzAl8yCAUPdm90aW5nSW5mb1BhcnRzAl8zCAUPdm90aW5nSW5mb1BhcnRzAl80CAUPdm90aW5nSW5mb1BhcnRzAl81CAUPdm90aW5nSW5mb1BhcnRzAl82CAUPdm90aW5nSW5mb1BhcnRzAl83CAUPdm90aW5nSW5mb1BhcnRzAl84BQtuZXdWb3Rlc0ZvcgUPbmV3Vm90ZXNBZ2FpbnN0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ1rZXlWb3RpbmdJbmZvAgUHYXNzZXRJZAUMY3VycmVudEluZGV4BRJuZXdWb3RpbmdJbmZvVmFsdWUJAMwIAgkBC0RlbGV0ZUVudHJ5AQUHdm90ZUtleQkAzAgCCQELRGVsZXRlRW50cnkBCQEPa2V5Vm90aW5nUmV3YXJkAwgFAWkGY2FsbGVyBQdhc3NldElkBQxjdXJyZW50SW5kZXgFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQhmaW5hbGl6ZQEHYXNzZXRJZAQPY3VycmVudEluZGV4S2V5CQEPa2V5Q3VycmVudEluZGV4AQUHYXNzZXRJZAQMY3VycmVudEluZGV4CQELdmFsdWVPckVsc2UCCQCfCAEFD2N1cnJlbnRJbmRleEtleQAABBJ2b3RpbmdUaHJlc2hvbGRBZGQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBRVrZXlWb3RpbmdUaHJlc2hvbGRBZGQJAQd3cmFwRXJyAQIadm90aW5nVGhyZXNob2xkQWRkIG5vdCBzZXQEFXZvdGluZ1RocmVzaG9sZFJlbW92ZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFGGtleVZvdGluZ1RocmVzaG9sZFJlbW92ZQkBB3dyYXBFcnIBAh12b3RpbmdUaHJlc2hvbGRSZW1vdmUgbm90IHNldAQNdm90aW5nSW5mb1N0cgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJAQ1rZXlWb3RpbmdJbmZvAgUHYXNzZXRJZAUMY3VycmVudEluZGV4CQEHd3JhcEVycgECFXZvdGluZyBpbmZvIG5vdCBmb3VuZAQPdm90aW5nSW5mb1BhcnRzCQESZ2V0Vm90aW5nSW5mb1BhcnRzAQUNdm90aW5nSW5mb1N0cgQKdm90aW5nVHlwZQgFD3ZvdGluZ0luZm9QYXJ0cwJfNAQGc3RhdHVzCAUPdm90aW5nSW5mb1BhcnRzAl81BA92b3RpbmdFbmRIZWlnaHQIBQ92b3RpbmdJbmZvUGFydHMCXzcEDHZvdGluZ1F1b3J1bQgFD3ZvdGluZ0luZm9QYXJ0cwJfOAQIdm90ZXNGb3IIBQ92b3RpbmdJbmZvUGFydHMCXzkEDHZvdGVzQWdhaW5zdAgFD3ZvdGluZ0luZm9QYXJ0cwNfMTAEBmNoZWNrcwkAzAgCAwkAAAIFBnN0YXR1cwUQc3RhdHVzSW5Qcm9ncmVzcwYJAQh0aHJvd0VycgECFnZvdGluZyBub3QgaW4gcHJvZ3Jlc3MJAMwIAgMJAGcCBQZoZWlnaHQFD3ZvdGluZ0VuZEhlaWdodAYJAQh0aHJvd0VycgECE3ZvdGluZyBub3QgZmluaXNoZWQJAMwIAgMJAQlpc0RlZmluZWQBCQCiCAEJAQ1rZXlBc3NldEltYWdlAQUHYXNzZXRJZAYJAQh0aHJvd0VycgECE2Fzc2V0IGltYWdlIG5vdCBzZXQFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwQOdm90aW5nQWNjZXB0ZWQDAwkAZwIJAGQCBQh2b3Rlc0ZvcgUMdm90ZXNBZ2FpbnN0BQx2b3RpbmdRdW9ydW0JAGYCBQh2b3Rlc0ZvcgUMdm90ZXNBZ2FpbnN0BwYHBAluZXdTdGF0dXMDBQ52b3RpbmdBY2NlcHRlZAUOc3RhdHVzQWNjZXB0ZWQFDnN0YXR1c1JlamVjdGVkBAphc3NldEltYWdlCQERQGV4dHJOYXRpdmUoMTA1OCkBCQENa2V5QXNzZXRJbWFnZQEFB2Fzc2V0SWQEEGlzVm90aW5nQWNjZXB0ZWQDBQ52b3RpbmdBY2NlcHRlZAQVdm90aW5nQWNjZXB0ZWRJbnZva2VzAwkAAAIFCnZvdGluZ1R5cGUCDHZlcmlmaWNhdGlvbgkA/AcEBRNhc3NldHNTdG9yZUNvbnRyYWN0Ag5jcmVhdGVPclVwZGF0ZQkAzAgCBQdhc3NldElkCQDMCAIFCmFzc2V0SW1hZ2UJAMwIAgYFA25pbAUDbmlsCQDMCAIJAPwHBAUTYXNzZXRzU3RvcmVDb250cmFjdAILc2V0VmVyaWZpZWQJAMwIAgUHYXNzZXRJZAkAzAgCBwUDbmlsBQNuaWwJAMwIAgkA/AcEBRNhc3NldHNTdG9yZUNvbnRyYWN0AgtvbkVsaW1pbmF0ZQkAzAgCBQdhc3NldElkBQNuaWwFA25pbAUDbmlsBRV2b3RpbmdBY2NlcHRlZEludm9rZXMFA25pbAMJAAACBRBpc1ZvdGluZ0FjY2VwdGVkBRBpc1ZvdGluZ0FjY2VwdGVkBBJuZXdWb3RpbmdJbmZvVmFsdWUJAQ92b3RpbmdJbmZvVmFsdWUKCAUPdm90aW5nSW5mb1BhcnRzAl8xCAUPdm90aW5nSW5mb1BhcnRzAl8yCAUPdm90aW5nSW5mb1BhcnRzAl8zCAUPdm90aW5nSW5mb1BhcnRzAl80BQluZXdTdGF0dXMIBQ92b3RpbmdJbmZvUGFydHMCXzYIBQ92b3RpbmdJbmZvUGFydHMCXzcIBQ92b3RpbmdJbmZvUGFydHMCXzgIBQ92b3RpbmdJbmZvUGFydHMCXzkIBQ92b3RpbmdJbmZvUGFydHMDXzEwBBhmaW5hbGl6ZUNhbGxSZXdhcmRBbW91bnQJARFAZXh0ck5hdGl2ZSgxMDU1KQEFG2tleUZpbmFsaXplQ2FsbFJld2FyZEFtb3VudAQUc3VnZ2VzdElzc3VlckFkZHJlc3MJARFAZXh0ck5hdGl2ZSgxMDYyKQEJARFAZXh0ck5hdGl2ZSgxMDU4KQEJARBrZXlTdWdnZXN0SXNzdWVyAgUHYXNzZXRJZAUMY3VycmVudEluZGV4BBl2b3RpbmdSZXdhcmRBc3NldElkT3B0aW9uCQCiCAEJARZrZXlWb3RpbmdSZXdhcmRBc3NldElkAgUHYXNzZXRJZAUMY3VycmVudEluZGV4BBd0b3RhbFZvdGluZ1Jld2FyZE9wdGlvbgkAnwgBCQEUa2V5VG90YWxWb3RpbmdSZXdhcmQCBQdhc3NldElkBQxjdXJyZW50SW5kZXgEE3JldHVyblJld2FyZEFjdGlvbnMDAwMFDnZvdGluZ0FjY2VwdGVkBgkAAAIFGXZvdGluZ1Jld2FyZEFzc2V0SWRPcHRpb24FBHVuaXQGCQAAAgUXdG90YWxWb3RpbmdSZXdhcmRPcHRpb24FBHVuaXQFA25pbAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBRRzdWdnZXN0SXNzdWVyQWRkcmVzcwkBBXZhbHVlAQUXdG90YWxWb3RpbmdSZXdhcmRPcHRpb24JAQxwYXJzZUFzc2V0SWQBCQEFdmFsdWUBBRl2b3RpbmdSZXdhcmRBc3NldElkT3B0aW9uBQNuaWwJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCCQENa2V5Vm90aW5nSW5mbwIFB2Fzc2V0SWQFDGN1cnJlbnRJbmRleAUSbmV3Vm90aW5nSW5mb1ZhbHVlCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUYZmluYWxpemVDYWxsUmV3YXJkQW1vdW50BQl3eEFzc2V0SWQFA25pbAUTcmV0dXJuUmV3YXJkQWN0aW9ucwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ1jbGFpbVJFQURPTkxZAwdhc3NldElkBWluZGV4DnVzZXJBZGRyZXNzU3RyBAt1c2VyQWRkcmVzcwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEFDnVzZXJBZGRyZXNzU3RyCQEHd3JhcEVycgECD2ludmFsaWQgYWRkcmVzcwQWdm90aW5nUmV3YXJkQXNzZXRJZFN0cgkAoggBCQEWa2V5Vm90aW5nUmV3YXJkQXNzZXRJZAIFB2Fzc2V0SWQFBWluZGV4BAxyZXdhcmRBbW91bnQDCQEJaXNEZWZpbmVkAQUWdm90aW5nUmV3YXJkQXNzZXRJZFN0cggJAQ9jYWxjdWxhdGVSZXdhcmQDBQt1c2VyQWRkcmVzcwUHYXNzZXRJZAUFaW5kZXgCXzEAAAkAlAoCBQNuaWwFDHJld2FyZEFtb3VudAFpAQVjbGFpbQIHYXNzZXRJZAVpbmRleAQNY2FsbGVyQWRkcmVzcwgFAWkGY2FsbGVyBA9jbGFpbUhpc3RvcnlLZXkJAQ9rZXlDbGFpbUhpc3RvcnkDBQ1jYWxsZXJBZGRyZXNzBQdhc3NldElkBQVpbmRleAQMY2xhaW1IaXN0b3J5CQCfCAEFD2NsYWltSGlzdG9yeUtleQQGY2hlY2tzCQDMCAIDCQAAAgUMY2xhaW1IaXN0b3J5BQR1bml0BgkBCHRocm93RXJyAQIPYWxyZWFkeSBjbGFpbWVkBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEDSR0MDE5NzQyMTk4MTkJAQ9jYWxjdWxhdGVSZXdhcmQDBQ1jYWxsZXJBZGRyZXNzBQdhc3NldElkBQVpbmRleAQMcmV3YXJkQW1vdW50CAUNJHQwMTk3NDIxOTgxOQJfMQQIY2FuQ2xhaW0IBQ0kdDAxOTc0MjE5ODE5Al8yAwkBASEBBQhjYW5DbGFpbQkBCHRocm93RXJyAQIQbm90aGluZyB0byBjbGFpbQQWdm90aW5nUmV3YXJkQXNzZXRJZFN0cgkAoggBCQEWa2V5Vm90aW5nUmV3YXJkQXNzZXRJZAIFB2Fzc2V0SWQFBWluZGV4BAxyZXdhcmRBY3Rpb24DCQEJaXNEZWZpbmVkAQUWdm90aW5nUmV3YXJkQXNzZXRJZFN0cgQTdm90aW5nUmV3YXJkQXNzZXRJZAkBDHBhcnNlQXNzZXRJZAEJAQV2YWx1ZQEFFnZvdGluZ1Jld2FyZEFzc2V0SWRTdHIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUNY2FsbGVyQWRkcmVzcwUMcmV3YXJkQW1vdW50BRN2b3RpbmdSZXdhcmRBc3NldElkCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ9jbGFpbUhpc3RvcnlLZXkFDHJld2FyZEFtb3VudAkAzAgCCQELRGVsZXRlRW50cnkBCQEPa2V5Vm90aW5nUmV3YXJkAwUNY2FsbGVyQWRkcmVzcwUHYXNzZXRJZAUFaW5kZXgFA25pbAkBCHRocm93RXJyAQIQbm90aGluZyB0byBjbGFpbQUMcmV3YXJkQWN0aW9uCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJ0eAEGdmVyaWZ5AAQPdGFyZ2V0UHVibGljS2V5BAckbWF0Y2gwCQEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAADCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCcGsFByRtYXRjaDAFAnBrAwkAAQIFByRtYXRjaDACBFVuaXQIBQJ0eA9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUPdGFyZ2V0UHVibGljS2V5DVDsWQ==", "height": 3245611, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: AD1yy84NgB3UNpyKryCJTDD6pqGyKCm22BovMbXr8F5j Next: none Diff:
OldNewDifferences
6565
6666 let wxAssetIdStr = split(getStringOrFail(emissionContract, keyEmissionConfig), separator)[1]
6767
68-let wxAssetId = fromBase58String(wxAssetIdStr)
68+let wxAssetId = parseAssetId(wxAssetIdStr)
6969
7070 let keyVotingThresholdAdd = makeString(["%s%s", "votingThreshold", "add"], separator)
7171
230230 then true
231231 else throwErr("invalid periodLength"), if ((tokenIsVerified == false))
232232 then true
233- else throwErr("token already verified"), if ((wxPaymentAmount >= (periodLength * feePerBlock)))
233+ else throwErr("token already verified"), if ((wxPaymentAssetId == wxAssetId))
234+ then true
235+ else throwErr("payment[0] should be in wx"), if ((wxPaymentAmount >= (periodLength * feePerBlock)))
234236 then true
235237 else throwErr("not enough wx for given period"), if ((wxPaymentAmount >= getIntegerValue(keyMinWxMinForSuggestAddAmountRequired)))
236238 then true
242244 let newIndex = if (isDefined(currentIndex))
243245 then (value(currentIndex) + 1)
244246 else 0
245- let $t092599899 = if ((size(i.payments) > 1))
247+ let $t093339966 = if ((size(i.payments) > 1))
246248 then {
247249 let votingRewardPayment = i.payments[1]
248- let votingRewardPaymentAssetId = toBase58String(value(votingRewardPayment.assetId))
250+ let votingRewardPaymentAssetId = assetIdToString(votingRewardPayment.assetId)
249251 let votingRewardPaymentAmount = value(votingRewardPayment.amount)
250252 $Tuple4(true, votingRewardPaymentAssetId, votingRewardPaymentAmount, [StringEntry(keyVotingRewardAssetId(assetId, newIndex), votingRewardPaymentAssetId), IntegerEntry(keyTotalVotingReward(assetId, newIndex), votingRewardPaymentAmount)])
251253 }
252254 else $Tuple4(false, "EMPTY", 0, nil)
253- let isRewardExist = $t092599899._1
254- let rewardAssetId = $t092599899._2
255- let rewardAmount = $t092599899._3
256- let votingRewardActions = $t092599899._4
255+ let isRewardExist = $t093339966._1
256+ let rewardAssetId = $t093339966._2
257+ let rewardAmount = $t093339966._3
258+ let votingRewardActions = $t093339966._4
257259 let votesQuorum = valueOrErrorMessage(getInteger(keyVotingThresholdAdd), wrapErr("votingThresholdAdd not set"))
258260 let votingInfo = votingInfoValue(isRewardExist, rewardAssetId, rewardAmount, "verification", statusInProgress, height, (height + periodLength), votesQuorum, 0, 0)
259261 let finalizeCallRewardAmount = getIntegerValue(keyFinalizeCallRewardAmount)
282284 then true
283285 else throwErr("token not verified"), if ((gwxAmountAtNow >= minSuggestRemoveBalance))
284286 then true
285- else throwErr("not enough gWXes"), if ((wxPaymentAmount >= getIntegerValue(keyWxForSuggestRemoveAmountRequired)))
287+ else throwErr("not enough gWXes"), if ((wxPaymentAssetId == wxAssetId))
288+ then true
289+ else throwErr("payment should be in wx"), if ((wxPaymentAmount >= getIntegerValue(keyWxForSuggestRemoveAmountRequired)))
286290 then true
287291 else throwErr("payment less then min for suggest")]
288292 if ((checks == checks))
338342 let votingInfoParts = getVotingInfoParts(votingInfoStr)
339343 let votesFor = votingInfoParts._9
340344 let votesAgainst = votingInfoParts._10
341- let $t01356313724 = if (inFavor)
345+ let $t01370513866 = if (inFavor)
342346 then $Tuple2((votesFor + gwxAmountAtEnd), votesAgainst)
343347 else $Tuple2(votesFor, (votesAgainst + gwxAmountAtEnd))
344- let newVotesFor = $t01356313724._1
345- let newVotesAgainst = $t01356313724._2
348+ let newVotesFor = $t01370513866._1
349+ let newVotesAgainst = $t01370513866._2
346350 let newVotingInfoValue = votingInfoValue(votingInfoParts._1, votingInfoParts._2, votingInfoParts._3, votingInfoParts._4, votingInfoParts._5, votingInfoParts._6, votingInfoParts._7, votingInfoParts._8, newVotesFor, newVotesAgainst)
347351 let votingRewardAction = match getString(keyVotingRewardAssetId(assetId, currentIndex)) {
348352 case pk: String =>
384388 let votingInfoParts = getVotingInfoParts(votingInfoStr)
385389 let votesFor = votingInfoParts._9
386390 let votesAgainst = votingInfoParts._10
387- let $t01534915510 = if ((inFavor == "true"))
391+ let $t01549115652 = if ((inFavor == "true"))
388392 then $Tuple2((votesFor - gwxAmount), votesAgainst)
389393 else $Tuple2(votesFor, (votesAgainst - gwxAmount))
390- let newVotesFor = $t01534915510._1
391- let newVotesAgainst = $t01534915510._2
394+ let newVotesFor = $t01549115652._1
395+ let newVotesAgainst = $t01549115652._2
392396 let newVotingInfoValue = votingInfoValue(votingInfoParts._1, votingInfoParts._2, votingInfoParts._3, votingInfoParts._4, votingInfoParts._5, votingInfoParts._6, votingInfoParts._7, votingInfoParts._8, newVotesFor, newVotesAgainst)
393397 [StringEntry(keyVotingInfo(assetId, currentIndex), newVotingInfoValue), DeleteEntry(voteKey), DeleteEntry(keyVotingReward(i.caller, assetId, currentIndex))]
394398 }
484488 else throwErr("already claimed")]
485489 if ((checks == checks))
486490 then {
487- let $t01960019677 = calculateReward(callerAddress, assetId, index)
488- let rewardAmount = $t01960019677._1
489- let canClaim = $t01960019677._2
491+ let $t01974219819 = calculateReward(callerAddress, assetId, index)
492+ let rewardAmount = $t01974219819._1
493+ let canClaim = $t01974219819._2
490494 if (!(canClaim))
491495 then throwErr("nothing to claim")
492496 else {
493497 let votingRewardAssetIdStr = getString(keyVotingRewardAssetId(assetId, index))
494498 let rewardAction = if (isDefined(votingRewardAssetIdStr))
495499 then {
496- let votingRewardAssetId = fromBase58String(value(votingRewardAssetIdStr))
500+ let votingRewardAssetId = parseAssetId(value(votingRewardAssetIdStr))
497501 [ScriptTransfer(callerAddress, rewardAmount, votingRewardAssetId), IntegerEntry(claimHistoryKey, rewardAmount), DeleteEntry(keyVotingReward(callerAddress, assetId, index))]
498502 }
499503 else throwErr("nothing to claim")
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let separator = "__"
55
66 let MULT8 = 100000000
77
88 let wavesString = "WAVES"
99
1010 let statusInProgress = "inProgress"
1111
1212 let statusAccepted = "accepted"
1313
1414 let statusRejected = "rejected"
1515
1616 func wrapErr (msg) = makeString(["voting_verified_v2.ride:", msg], " ")
1717
1818
1919 func throwErr (msg) = throw(wrapErr(msg))
2020
2121
2222 func asInt (val) = match val {
2323 case valInt: Int =>
2424 valInt
2525 case _ =>
2626 throw("Failed to cast into Integer")
2727 }
2828
2929
3030 func parseAssetId (input) = if ((input == wavesString))
3131 then unit
3232 else fromBase58String(input)
3333
3434
3535 func assetIdToString (input) = if ((input == unit))
3636 then wavesString
3737 else toBase58String(value(input))
3838
3939
4040 func getIntegerOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
4141
4242
4343 func getIntegerOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), wrapErr((key + " is not defined")))
4444
4545
4646 func getStringOrEmpty (address,key) = valueOrElse(getString(address, key), "")
4747
4848
4949 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), wrapErr((key + " is not defined")))
5050
5151
5252 let keyBoostingContract = makeString(["%s", "boostingContract"], separator)
5353
5454 let keyEmissionContract = makeString(["%s", "emissionContract"], separator)
5555
5656 let keyAssetsStoreContract = makeString(["%s", "assetsStoreContract"], separator)
5757
5858 let boostingContract = addressFromStringValue(getStringValue(keyBoostingContract))
5959
6060 let emissionContract = addressFromStringValue(getStringValue(keyEmissionContract))
6161
6262 let assetsStoreContract = addressFromStringValue(getStringValue(keyAssetsStoreContract))
6363
6464 let keyEmissionConfig = makeString(["%s", "config"], separator)
6565
6666 let wxAssetIdStr = split(getStringOrFail(emissionContract, keyEmissionConfig), separator)[1]
6767
68-let wxAssetId = fromBase58String(wxAssetIdStr)
68+let wxAssetId = parseAssetId(wxAssetIdStr)
6969
7070 let keyVotingThresholdAdd = makeString(["%s%s", "votingThreshold", "add"], separator)
7171
7272 let keyVotingThresholdRemove = makeString(["%s%s", "votingThreshold", "remove"], separator)
7373
7474 let keyPeriodLengthRemove = makeString(["%s", "periodLengthRemove"], separator)
7575
7676 let keyMaxPeriodLength = makeString(["%s", "maxPeriodLength"], separator)
7777
7878 let keyMinPeriodLength = makeString(["%s", "minPeriodLength"], separator)
7979
8080 func keyVotingRewardAssetId (assetId,index) = makeString(["%s%s%d", "votingRewardAssetId", assetId, toString(index)], separator)
8181
8282
8383 func keyVotingReward (userAddress,assetId,index) = makeString(["%s%s%s%d", "votingReward", toString(userAddress), assetId, toString(index)], separator)
8484
8585
8686 func keyTotalVotingReward (assetId,index) = makeString(["%s%s%d", "totalVotingReward", assetId, toString(index)], separator)
8787
8888
8989 let keyFinalizeCallRewardAmount = makeString(["%s", "finalizeCallRewardAmount"], separator)
9090
9191 let keyMinSuggestRemoveBalance = makeString(["%s", "minSuggestRemoveBalance"], separator)
9292
9393 func keyCurrentIndex (assetId) = makeString(["%s%s", "currentIndex", assetId], separator)
9494
9595
9696 func keyVote (assetId,index,caller) = makeString(["%s%s%d%s", "vote", assetId, toString(index), toString(caller)], separator)
9797
9898
9999 func voteValue (inFavor,gwxAmount) = makeString(["%s%d", toString(inFavor), toString(gwxAmount)], separator)
100100
101101
102102 func keySuggestIssuer (assetId,index) = makeString(["%s%s%d", "suggestIssuer", assetId, toString(index)], separator)
103103
104104
105105 func keyClaimHistory (userAddress,assetId,index) = makeString(["%s%s%s%d", "history", toString(userAddress), assetId, toString(index)], separator)
106106
107107
108108 let keyFeePerBlock = makeString(["%s", "feePerBlock"], separator)
109109
110110 let feePerBlock = getIntegerOrFail(this, keyFeePerBlock)
111111
112112 let keyMinWxMinForSuggestAddAmountRequired = makeString(["%s", "wxMinForSuggestAddAmountRequired"], separator)
113113
114114 let keyWxForSuggestRemoveAmountRequired = makeString(["%s", "wxForSuggestRemoveAmountRequired"], separator)
115115
116116 func keyVotingInfo (assetId,index) = makeString(["%s%s%d", "votingInfo", assetId, toString(index)], separator)
117117
118118
119119 func votingInfoValue (isRewardExist,rewardAssetId,rewardAmount,votingType,status,votingStartHeight,votingEndHeight,votesQuorum,votesFor,votesAgainst) = makeString(["%s%s%d%s%s%d%d%d%d%d", toString(isRewardExist), rewardAssetId, toString(rewardAmount), votingType, status, toString(votingStartHeight), toString(votingEndHeight), toString(votesQuorum), toString(votesFor), toString(votesAgainst)], separator)
120120
121121
122122 func keyAssetImage (assetId) = makeString(["%s%s", "assetImage", assetId], separator)
123123
124124
125125 func getUserGwxAmountAtHeight (userAddress,targetHeight) = {
126126 let gwxAmount = invoke(boostingContract, "getUserGwxAmountAtHeightREADONLY", [userAddress, targetHeight], nil)
127127 asInt(gwxAmount)
128128 }
129129
130130
131131 func keyManagerVaultAddress () = "%s__managerVaultAddress"
132132
133133
134134 func keyManagerPublicKey () = "%s__managerPublicKey"
135135
136136
137137 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
138138 case s: String =>
139139 addressFromStringValue(s)
140140 case _ =>
141141 this
142142 }
143143
144144
145145 func managerPublicKeyOrUnit () = {
146146 let managerVaultAddress = getManagerVaultAddressOrThis()
147147 match getString(managerVaultAddress, keyManagerPublicKey()) {
148148 case s: String =>
149149 fromBase58String(s)
150150 case _: Unit =>
151151 unit
152152 case _ =>
153153 throw("Match error")
154154 }
155155 }
156156
157157
158158 func getVotingInfoParts (votingInfo) = {
159159 let votingInfoParts = split(votingInfo, separator)
160160 let isRewardExistStr = votingInfoParts[1]
161161 let isRewardExist = if ((isRewardExistStr == "true"))
162162 then true
163163 else false
164164 let rewardAssetId = votingInfoParts[2]
165165 let rewardAmount = parseIntValue(votingInfoParts[3])
166166 let votingType = votingInfoParts[4]
167167 let status = votingInfoParts[5]
168168 let votingStartHeight = parseIntValue(votingInfoParts[6])
169169 let votingEndHeight = parseIntValue(votingInfoParts[7])
170170 let votesQuorum = parseIntValue(votingInfoParts[8])
171171 let votesFor = parseIntValue(votingInfoParts[9])
172172 let votesAgainst = parseIntValue(votingInfoParts[10])
173173 $Tuple10(isRewardExist, rewardAssetId, rewardAmount, votingType, status, votingStartHeight, votingEndHeight, votesQuorum, votesFor, votesAgainst)
174174 }
175175
176176
177177 func votingExistChecks (assetId,currentIndex) = {
178178 let votingInfo = valueOrErrorMessage(getString(keyVotingInfo(assetId, currentIndex)), wrapErr("voting info not found"))
179179 let votingInfoArray = split(votingInfo, separator)
180180 let status = votingInfoArray[5]
181181 let votingEndHeight = valueOrErrorMessage(parseIntValue(votingInfoArray[7]), wrapErr("voting start height not found"))
182182 let suggestIssuer = valueOrErrorMessage(getString(keySuggestIssuer(assetId, currentIndex)), wrapErr("voting issuer not found"))
183183 let checks = [if ((status == statusInProgress))
184184 then true
185185 else throwErr("no voting in progress"), if ((votingEndHeight > height))
186186 then true
187187 else throwErr("voting expired")]
188188 if ((checks == checks))
189189 then $Tuple3(status, votingEndHeight, suggestIssuer)
190190 else throw("Strict value is not equal to itself.")
191191 }
192192
193193
194194 func calculateReward (voter,assetId,index) = {
195195 let voteKey = keyVote(assetId, index, voter)
196196 let lastVote = valueOrErrorMessage(getString(voteKey), wrapErr("you have not voted"))
197197 let lastVoteParts = split(lastVote, separator)
198198 let gwxAmount = parseIntValue(lastVoteParts[2])
199199 let votingInfoStr = valueOrErrorMessage(getString(keyVotingInfo(assetId, index)), wrapErr("voting info not found"))
200200 let votingParts = getVotingInfoParts(votingInfoStr)
201201 let status = votingParts._5
202202 let votesFor = votingParts._9
203203 let votesAgainst = votingParts._10
204204 let partOfTheTotalVotesX8 = fraction(gwxAmount, MULT8, (votesFor + votesAgainst))
205205 let totalVotingReward = valueOrElse(getInteger(keyTotalVotingReward(assetId, index)), 0)
206206 let voterRewardAmount = fraction(partOfTheTotalVotesX8, totalVotingReward, MULT8, FLOOR)
207207 let canClaim = if ((status == statusAccepted))
208208 then (voterRewardAmount > 0)
209209 else false
210210 $Tuple2(voterRewardAmount, canClaim)
211211 }
212212
213213
214214 @Callable(i)
215215 func suggestAdd (assetId,periodLength,assetImage) = {
216216 let wxPayment = i.payments[0]
217217 let wxPaymentAssetId = value(wxPayment.assetId)
218218 let wxPaymentAmount = value(wxPayment.amount)
219219 let minPeriodLength = getIntegerValue(keyMinPeriodLength)
220220 let maxPeriodLength = getIntegerValue(keyMaxPeriodLength)
221221 let tokenIsVerified = {
222222 let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [assetId], nil)
223223 if ($isInstanceOf(@, "Boolean"))
224224 then @
225225 else throw(($getType(@) + " couldn't be cast to Boolean"))
226226 }
227227 let checks = [if (if ((periodLength >= minPeriodLength))
228228 then (maxPeriodLength >= periodLength)
229229 else false)
230230 then true
231231 else throwErr("invalid periodLength"), if ((tokenIsVerified == false))
232232 then true
233- else throwErr("token already verified"), if ((wxPaymentAmount >= (periodLength * feePerBlock)))
233+ else throwErr("token already verified"), if ((wxPaymentAssetId == wxAssetId))
234+ then true
235+ else throwErr("payment[0] should be in wx"), if ((wxPaymentAmount >= (periodLength * feePerBlock)))
234236 then true
235237 else throwErr("not enough wx for given period"), if ((wxPaymentAmount >= getIntegerValue(keyMinWxMinForSuggestAddAmountRequired)))
236238 then true
237239 else throwErr("payment less then min for suggest")]
238240 if ((checks == checks))
239241 then {
240242 let currentIndexKey = keyCurrentIndex(assetId)
241243 let currentIndex = getInteger(currentIndexKey)
242244 let newIndex = if (isDefined(currentIndex))
243245 then (value(currentIndex) + 1)
244246 else 0
245- let $t092599899 = if ((size(i.payments) > 1))
247+ let $t093339966 = if ((size(i.payments) > 1))
246248 then {
247249 let votingRewardPayment = i.payments[1]
248- let votingRewardPaymentAssetId = toBase58String(value(votingRewardPayment.assetId))
250+ let votingRewardPaymentAssetId = assetIdToString(votingRewardPayment.assetId)
249251 let votingRewardPaymentAmount = value(votingRewardPayment.amount)
250252 $Tuple4(true, votingRewardPaymentAssetId, votingRewardPaymentAmount, [StringEntry(keyVotingRewardAssetId(assetId, newIndex), votingRewardPaymentAssetId), IntegerEntry(keyTotalVotingReward(assetId, newIndex), votingRewardPaymentAmount)])
251253 }
252254 else $Tuple4(false, "EMPTY", 0, nil)
253- let isRewardExist = $t092599899._1
254- let rewardAssetId = $t092599899._2
255- let rewardAmount = $t092599899._3
256- let votingRewardActions = $t092599899._4
255+ let isRewardExist = $t093339966._1
256+ let rewardAssetId = $t093339966._2
257+ let rewardAmount = $t093339966._3
258+ let votingRewardActions = $t093339966._4
257259 let votesQuorum = valueOrErrorMessage(getInteger(keyVotingThresholdAdd), wrapErr("votingThresholdAdd not set"))
258260 let votingInfo = votingInfoValue(isRewardExist, rewardAssetId, rewardAmount, "verification", statusInProgress, height, (height + periodLength), votesQuorum, 0, 0)
259261 let finalizeCallRewardAmount = getIntegerValue(keyFinalizeCallRewardAmount)
260262 let burnWxAmount = (wxPaymentAmount - finalizeCallRewardAmount)
261263 ([IntegerEntry(currentIndexKey, newIndex), StringEntry(keySuggestIssuer(assetId, newIndex), toString(i.caller)), StringEntry(keyVotingInfo(assetId, newIndex), votingInfo), StringEntry(keyAssetImage(assetId), assetImage), Burn(wxPaymentAssetId, burnWxAmount)] ++ votingRewardActions)
262264 }
263265 else throw("Strict value is not equal to itself.")
264266 }
265267
266268
267269
268270 @Callable(i)
269271 func suggestRemove (assetId) = {
270272 let gwxAmountAtNow = getUserGwxAmountAtHeight(toString(i.caller), height)
271273 let minSuggestRemoveBalance = getIntegerValue(keyMinSuggestRemoveBalance)
272274 let wxPayment = i.payments[0]
273275 let wxPaymentAssetId = value(wxPayment.assetId)
274276 let wxPaymentAmount = value(wxPayment.amount)
275277 let tokenIsVerified = {
276278 let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [assetId], nil)
277279 if ($isInstanceOf(@, "Boolean"))
278280 then @
279281 else throw(($getType(@) + " couldn't be cast to Boolean"))
280282 }
281283 let checks = [if (tokenIsVerified)
282284 then true
283285 else throwErr("token not verified"), if ((gwxAmountAtNow >= minSuggestRemoveBalance))
284286 then true
285- else throwErr("not enough gWXes"), if ((wxPaymentAmount >= getIntegerValue(keyWxForSuggestRemoveAmountRequired)))
287+ else throwErr("not enough gWXes"), if ((wxPaymentAssetId == wxAssetId))
288+ then true
289+ else throwErr("payment should be in wx"), if ((wxPaymentAmount >= getIntegerValue(keyWxForSuggestRemoveAmountRequired)))
286290 then true
287291 else throwErr("payment less then min for suggest")]
288292 if ((checks == checks))
289293 then {
290294 let currentIndexKey = keyCurrentIndex(assetId)
291295 let currentIndex = getInteger(currentIndexKey)
292296 let newIndex = if (isDefined(currentIndex))
293297 then (value(currentIndex) + 1)
294298 else 0
295299 let periodLength = valueOrErrorMessage(getInteger(keyPeriodLengthRemove), wrapErr("periodLengthRemove not set"))
296300 let votingEndHeight = (height + periodLength)
297301 let votesQuorum = valueOrErrorMessage(getInteger(keyVotingThresholdRemove), wrapErr("votingThresholdRemove not set"))
298302 let votingInfo = votingInfoValue(false, "EMPTY", 0, "deverification", statusInProgress, height, (height + periodLength), votesQuorum, 0, 0)
299303 let setAssetImageAction = match getString(keyAssetImage(assetId)) {
300304 case s: String =>
301305 nil
302306 case _: Unit =>
303307 let assetsStoreAssetImage = {
304308 let @ = invoke(assetsStoreContract, "getAssetLogoREADONLY", [assetId], nil)
305309 if ($isInstanceOf(@, "String"))
306310 then @
307311 else throw(($getType(@) + " couldn't be cast to String"))
308312 }
309313 [StringEntry(keyAssetImage(assetId), assetsStoreAssetImage)]
310314 case _ =>
311315 throw("Match error")
312316 }
313317 ([IntegerEntry(currentIndexKey, newIndex), StringEntry(keySuggestIssuer(assetId, newIndex), toString(i.caller)), StringEntry(keyVotingInfo(assetId, newIndex), votingInfo)] ++ setAssetImageAction)
314318 }
315319 else throw("Strict value is not equal to itself.")
316320 }
317321
318322
319323
320324 @Callable(i)
321325 func vote (assetId,inFavor) = {
322326 let currentIndexKey = keyCurrentIndex(assetId)
323327 let currentIndex = valueOrErrorMessage(getInteger(currentIndexKey), wrapErr("voting does not exist"))
324328 let votingInfo = votingExistChecks(assetId, currentIndex)
325329 if ((votingInfo == votingInfo))
326330 then {
327331 let currentVotingEndHeight = votingInfo._2
328332 let gwxAmountAtEnd = getUserGwxAmountAtHeight(toString(i.caller), currentVotingEndHeight)
329333 let voteKey = keyVote(assetId, currentIndex, i.caller)
330334 let checks = [if ((getString(voteKey) == unit))
331335 then true
332336 else throwErr("You have already voted"), if ((gwxAmountAtEnd > 0))
333337 then true
334338 else throw("You'll not have gWX at the end of voting")]
335339 if ((checks == checks))
336340 then {
337341 let votingInfoStr = valueOrErrorMessage(getString(keyVotingInfo(assetId, currentIndex)), wrapErr("voting info not found"))
338342 let votingInfoParts = getVotingInfoParts(votingInfoStr)
339343 let votesFor = votingInfoParts._9
340344 let votesAgainst = votingInfoParts._10
341- let $t01356313724 = if (inFavor)
345+ let $t01370513866 = if (inFavor)
342346 then $Tuple2((votesFor + gwxAmountAtEnd), votesAgainst)
343347 else $Tuple2(votesFor, (votesAgainst + gwxAmountAtEnd))
344- let newVotesFor = $t01356313724._1
345- let newVotesAgainst = $t01356313724._2
348+ let newVotesFor = $t01370513866._1
349+ let newVotesAgainst = $t01370513866._2
346350 let newVotingInfoValue = votingInfoValue(votingInfoParts._1, votingInfoParts._2, votingInfoParts._3, votingInfoParts._4, votingInfoParts._5, votingInfoParts._6, votingInfoParts._7, votingInfoParts._8, newVotesFor, newVotesAgainst)
347351 let votingRewardAction = match getString(keyVotingRewardAssetId(assetId, currentIndex)) {
348352 case pk: String =>
349353 [StringEntry(keyVotingReward(i.caller, assetId, currentIndex), voteValue(inFavor, gwxAmountAtEnd))]
350354 case _: Unit =>
351355 nil
352356 case _ =>
353357 throw("Match error")
354358 }
355359 ([StringEntry(voteKey, voteValue(inFavor, gwxAmountAtEnd)), StringEntry(keyVotingInfo(assetId, currentIndex), newVotingInfoValue)] ++ votingRewardAction)
356360 }
357361 else throw("Strict value is not equal to itself.")
358362 }
359363 else throw("Strict value is not equal to itself.")
360364 }
361365
362366
363367
364368 @Callable(i)
365369 func cancelVote (assetId) = {
366370 let currentIndexKey = keyCurrentIndex(assetId)
367371 let currentIndex = valueOrErrorMessage(getInteger(currentIndexKey), wrapErr("voting does not exist"))
368372 let voteKey = keyVote(assetId, currentIndex, i.caller)
369373 let lastVote = valueOrErrorMessage(getString(voteKey), wrapErr("you have not voted"))
370374 let lastVoteParts = split(lastVote, separator)
371375 let inFavor = lastVoteParts[1]
372376 let gwxAmount = parseIntValue(lastVoteParts[2])
373377 let votingInfo = votingExistChecks(assetId, currentIndex)
374378 if ((votingInfo == votingInfo))
375379 then {
376380 let checks = [if (if ((inFavor == "true"))
377381 then true
378382 else (inFavor == "false"))
379383 then true
380384 else throwErr("invalid vote")]
381385 if ((checks == checks))
382386 then {
383387 let votingInfoStr = valueOrErrorMessage(getString(keyVotingInfo(assetId, currentIndex)), wrapErr("voting info not found"))
384388 let votingInfoParts = getVotingInfoParts(votingInfoStr)
385389 let votesFor = votingInfoParts._9
386390 let votesAgainst = votingInfoParts._10
387- let $t01534915510 = if ((inFavor == "true"))
391+ let $t01549115652 = if ((inFavor == "true"))
388392 then $Tuple2((votesFor - gwxAmount), votesAgainst)
389393 else $Tuple2(votesFor, (votesAgainst - gwxAmount))
390- let newVotesFor = $t01534915510._1
391- let newVotesAgainst = $t01534915510._2
394+ let newVotesFor = $t01549115652._1
395+ let newVotesAgainst = $t01549115652._2
392396 let newVotingInfoValue = votingInfoValue(votingInfoParts._1, votingInfoParts._2, votingInfoParts._3, votingInfoParts._4, votingInfoParts._5, votingInfoParts._6, votingInfoParts._7, votingInfoParts._8, newVotesFor, newVotesAgainst)
393397 [StringEntry(keyVotingInfo(assetId, currentIndex), newVotingInfoValue), DeleteEntry(voteKey), DeleteEntry(keyVotingReward(i.caller, assetId, currentIndex))]
394398 }
395399 else throw("Strict value is not equal to itself.")
396400 }
397401 else throw("Strict value is not equal to itself.")
398402 }
399403
400404
401405
402406 @Callable(i)
403407 func finalize (assetId) = {
404408 let currentIndexKey = keyCurrentIndex(assetId)
405409 let currentIndex = valueOrElse(getInteger(currentIndexKey), 0)
406410 let votingThresholdAdd = valueOrErrorMessage(getInteger(keyVotingThresholdAdd), wrapErr("votingThresholdAdd not set"))
407411 let votingThresholdRemove = valueOrErrorMessage(getInteger(keyVotingThresholdRemove), wrapErr("votingThresholdRemove not set"))
408412 let votingInfoStr = valueOrErrorMessage(getString(keyVotingInfo(assetId, currentIndex)), wrapErr("voting info not found"))
409413 let votingInfoParts = getVotingInfoParts(votingInfoStr)
410414 let votingType = votingInfoParts._4
411415 let status = votingInfoParts._5
412416 let votingEndHeight = votingInfoParts._7
413417 let votingQuorum = votingInfoParts._8
414418 let votesFor = votingInfoParts._9
415419 let votesAgainst = votingInfoParts._10
416420 let checks = [if ((status == statusInProgress))
417421 then true
418422 else throwErr("voting not in progress"), if ((height >= votingEndHeight))
419423 then true
420424 else throwErr("voting not finished"), if (isDefined(getString(keyAssetImage(assetId))))
421425 then true
422426 else throwErr("asset image not set")]
423427 if ((checks == checks))
424428 then {
425429 let votingAccepted = if (if (((votesFor + votesAgainst) >= votingQuorum))
426430 then (votesFor > votesAgainst)
427431 else false)
428432 then true
429433 else false
430434 let newStatus = if (votingAccepted)
431435 then statusAccepted
432436 else statusRejected
433437 let assetImage = getStringValue(keyAssetImage(assetId))
434438 let isVotingAccepted = if (votingAccepted)
435439 then {
436440 let votingAcceptedInvokes = if ((votingType == "verification"))
437441 then invoke(assetsStoreContract, "createOrUpdate", [assetId, assetImage, true], nil)
438442 else [invoke(assetsStoreContract, "setVerified", [assetId, false], nil), invoke(assetsStoreContract, "onEliminate", [assetId], nil)]
439443 votingAcceptedInvokes
440444 }
441445 else nil
442446 if ((isVotingAccepted == isVotingAccepted))
443447 then {
444448 let newVotingInfoValue = votingInfoValue(votingInfoParts._1, votingInfoParts._2, votingInfoParts._3, votingInfoParts._4, newStatus, votingInfoParts._6, votingInfoParts._7, votingInfoParts._8, votingInfoParts._9, votingInfoParts._10)
445449 let finalizeCallRewardAmount = getIntegerValue(keyFinalizeCallRewardAmount)
446450 let suggestIssuerAddress = addressFromStringValue(getStringValue(keySuggestIssuer(assetId, currentIndex)))
447451 let votingRewardAssetIdOption = getString(keyVotingRewardAssetId(assetId, currentIndex))
448452 let totalVotingRewardOption = getInteger(keyTotalVotingReward(assetId, currentIndex))
449453 let returnRewardActions = if (if (if (votingAccepted)
450454 then true
451455 else (votingRewardAssetIdOption == unit))
452456 then true
453457 else (totalVotingRewardOption == unit))
454458 then nil
455459 else [ScriptTransfer(suggestIssuerAddress, value(totalVotingRewardOption), parseAssetId(value(votingRewardAssetIdOption)))]
456460 ([StringEntry(keyVotingInfo(assetId, currentIndex), newVotingInfoValue), ScriptTransfer(i.caller, finalizeCallRewardAmount, wxAssetId)] ++ returnRewardActions)
457461 }
458462 else throw("Strict value is not equal to itself.")
459463 }
460464 else throw("Strict value is not equal to itself.")
461465 }
462466
463467
464468
465469 @Callable(i)
466470 func claimREADONLY (assetId,index,userAddressStr) = {
467471 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid address"))
468472 let votingRewardAssetIdStr = getString(keyVotingRewardAssetId(assetId, index))
469473 let rewardAmount = if (isDefined(votingRewardAssetIdStr))
470474 then calculateReward(userAddress, assetId, index)._1
471475 else 0
472476 $Tuple2(nil, rewardAmount)
473477 }
474478
475479
476480
477481 @Callable(i)
478482 func claim (assetId,index) = {
479483 let callerAddress = i.caller
480484 let claimHistoryKey = keyClaimHistory(callerAddress, assetId, index)
481485 let claimHistory = getInteger(claimHistoryKey)
482486 let checks = [if ((claimHistory == unit))
483487 then true
484488 else throwErr("already claimed")]
485489 if ((checks == checks))
486490 then {
487- let $t01960019677 = calculateReward(callerAddress, assetId, index)
488- let rewardAmount = $t01960019677._1
489- let canClaim = $t01960019677._2
491+ let $t01974219819 = calculateReward(callerAddress, assetId, index)
492+ let rewardAmount = $t01974219819._1
493+ let canClaim = $t01974219819._2
490494 if (!(canClaim))
491495 then throwErr("nothing to claim")
492496 else {
493497 let votingRewardAssetIdStr = getString(keyVotingRewardAssetId(assetId, index))
494498 let rewardAction = if (isDefined(votingRewardAssetIdStr))
495499 then {
496- let votingRewardAssetId = fromBase58String(value(votingRewardAssetIdStr))
500+ let votingRewardAssetId = parseAssetId(value(votingRewardAssetIdStr))
497501 [ScriptTransfer(callerAddress, rewardAmount, votingRewardAssetId), IntegerEntry(claimHistoryKey, rewardAmount), DeleteEntry(keyVotingReward(callerAddress, assetId, index))]
498502 }
499503 else throwErr("nothing to claim")
500504 rewardAction
501505 }
502506 }
503507 else throw("Strict value is not equal to itself.")
504508 }
505509
506510
507511 @Verifier(tx)
508512 func verify () = {
509513 let targetPublicKey = match managerPublicKeyOrUnit() {
510514 case pk: ByteVector =>
511515 pk
512516 case _: Unit =>
513517 tx.senderPublicKey
514518 case _ =>
515519 throw("Match error")
516520 }
517521 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
518522 }
519523

github/deemru/w8io/169f3d6 
84.89 ms