tx · 7eCD58kwqKzy6gSvUTpNBtTXN7LZCcQWcuytDT3H7LqX

3MvjAaDYHpS4A5K4CV3kZMMEH9m9JdBSvbq:  -0.01000000 Waves

2022.11.29 07:49 [2337935] smart account 3MvjAaDYHpS4A5K4CV3kZMMEH9m9JdBSvbq > SELF 0.00000000 Waves

{ "type": 13, "id": "7eCD58kwqKzy6gSvUTpNBtTXN7LZCcQWcuytDT3H7LqX", "fee": 1000000, "feeAssetId": null, "timestamp": 1669697397153, "version": 2, "chainId": 84, "sender": "3MvjAaDYHpS4A5K4CV3kZMMEH9m9JdBSvbq", "senderPublicKey": "H6UqxUDcJamDRg1uykVcWMn4zhAMTV7i1nfPq1moLWmJ", "proofs": [ "W5RejTmdDxu7L7UkG5hPgAxWpEPMvjDH2zK9ykMmtiiMr5mp8HtogugjJtBKHRD9w1cd5UYVXxh6bDky3oRD2D6" ], "script": "base64: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ZXBhcmF0b3IJAAIBAiFNYXggbnVtYmVyIG9mIHBhcmFtZXRlcnMgZXhjZWVkZWQBDnBhcnNlQXNBdWN0aW9uAQdkZXRhaWxzBANyZXMJALUJAgUHZGV0YWlscwUJc2VwYXJhdG9yCQCXCgUJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUDcmVzAAAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNyZXMAAQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA3JlcwACCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDcmVzAAMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNyZXMABAELcGFyc2VBc1NlbGwBB2RldGFpbHMEA3JlcwkAtQkCBQdkZXRhaWxzBQlzZXBhcmF0b3IJAJQKAgkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQNyZXMAAAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA3JlcwABAQpqb2luU3RydWN0AQZwYXJhbXMEByRtYXRjaDAFBnBhcmFtcwMJAAECBQckbWF0Y2gwAh4oQWRkcmVzcywgSW50LCBTdHJpbmcsIFN0cmluZykEB2F1Y3Rpb24FByRtYXRjaDAJAQpqb2luU3RyaW5nAQkAzAgCCQClCAEIBQdhdWN0aW9uAl8xCQDMCAIJAKQDAQgFB2F1Y3Rpb24CXzIJAMwIAggFB2F1Y3Rpb24CXzMJAMwIAggFB2F1Y3Rpb24CXzQFA25pbAMJAAECBQckbWF0Y2gwAg4oQWRkcmVzcywgSW50KQQEc2VsbAUHJG1hdGNoMAkBCmpvaW5TdHJpbmcBCQDMCAIJAKUIAQgFBHNlbGwCXzEJAMwIAgkApAMBCAUEc2VsbAJfMgUDbmlsCQACAQITV3JvbmcgcGFyYW1zIHR1cHBsZQEKc2V0QXVjdGlvbgUGc2VsbGVyBW5mdElkCnN0YXJ0UHJpY2UFc3RhcnQDZW5kCQELU3RyaW5nRW50cnkCCQENZ2V0QXVjdGlvbktleQEFBW5mdElkCQEKam9pblN0cnVjdAEJAJYKBAUGc2VsbGVyBQpzdGFydFByaWNlBQVzdGFydAUDZW5kAQdzZXRTZWxsAwVuZnRJZAZjZWxsZXIFcHJpY2UJAQtTdHJpbmdFbnRyeQIJAQpnZXRTZWxsS2V5AQUFbmZ0SWQJAQpqb2luU3RydWN0AQkAlAoCBQZjZWxsZXIFBXByaWNlAQpnZXRBdWN0aW9uAQVuZnRJZAkBBXZhbHVlAQkAnQgCBQR0aGlzCQENZ2V0QXVjdGlvbktleQEFBW5mdElkAQdnZXRTZWxsAQVuZnRJZAkBBXZhbHVlAQkAnQgCBQR0aGlzCQEKZ2V0U2VsbEtleQEFBW5mdElkARhjYWxjUHJpY2VBdEN1cnJlbnRNb21lbnQCB2Fzc2V0SWQGbW9tZW50BAdkZXRhaWxzCQEKZ2V0QXVjdGlvbgEFB2Fzc2V0SWQECyR0MDI3NTUyODU5CQEOcGFyc2VBc0F1Y3Rpb24BBQdkZXRhaWxzBAZzZWxsZXIIBQskdDAyNzU1Mjg1OQJfMQQPc3RhcnRQcmljZVZhbHVlCAULJHQwMjc1NTI4NTkCXzIEDWVuZFByaWNlVmFsdWUIBQskdDAyNzU1Mjg1OQJfMwQQc3RhcnRQZXJpb2RWYWx1ZQgFCyR0MDI3NTUyODU5Al80BA5lbmRQZXJpb2RWYWx1ZQgFCyR0MDI3NTUyODU5Al81AwkAZwIFBm1vbWVudAUOZW5kUGVyaW9kVmFsdWUJAJQKAgUGc2VsbGVyBQ1lbmRQcmljZVZhbHVlBApkZWx0YVByaWNlCQBlAgUPc3RhcnRQcmljZVZhbHVlBQ1lbmRQcmljZVZhbHVlBAZwZXJpb2QJAGUCBQ5lbmRQZXJpb2RWYWx1ZQUQc3RhcnRQZXJpb2RWYWx1ZQQHc3BlbmRlZAkAZQIFBm1vbWVudAUQc3RhcnRQZXJpb2RWYWx1ZQkAlAoCBQZzZWxsZXIJAGUCBQ9zdGFydFByaWNlVmFsdWUJAGsDBQdzcGVuZGVkBQpkZWx0YVByaWNlBQZwZXJpb2QBBWlzTmZ0AQdhc3NldElkBAckbWF0Y2gwCQDsBwEFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIFQXNzZXQEBXRva2VuBQckbWF0Y2gwAwMJAAACCAUFdG9rZW4IZGVjaW1hbHMAAAkAAAIIBQV0b2tlbghxdWFudGl0eQABBwkAAAIIBQV0b2tlbgpyZWlzc3VhYmxlBwcHAQxpc1RydXN0ZWROZnQBB2Fzc2V0SWQEBmlzc3VlcggJAQV2YWx1ZQEJAOwHAQUHYXNzZXRJZAZpc3N1ZXIJAQt2YWx1ZU9yRWxzZQIJAJsIAgUEdGhpcwkBDWdldFRydXN0ZWRLZXkBBQZpc3N1ZXIHAQtpc1NlbGxFeGlzdAEHYXNzZXRJZAkBCWlzRGVmaW5lZAEJAJ0IAgUEdGhpcwkBCmdldFNlbGxLZXkBBQdhc3NldElkAQ5pc0F1Y3Rpb25FeGlzdAEHYXNzZXRJZAkBCWlzRGVmaW5lZAEJAJ0IAgUEdGhpcwkBDWdldEF1Y3Rpb25LZXkBBQdhc3NldElkARJpc0NvcnJlY3RTZWxsUHJpY2UBBXByaWNlCQBmAgUFcHJpY2UAAAEWaXNDb3JyZWN0QXVjdGlvblByaWNlcwIKc3RhcnRQcmljZQhlbmRQcmljZQkAZgIFCnN0YXJ0UHJpY2UFCGVuZFByaWNlAQdpc0FkbWluAQZjYWxsZXIJAAACBQZjYWxsZXIFBHRoaXMBDWlzVmFsaWRDYWxsZXICBmNhbGxlcgZzZWxsZXIDCQAAAgUGY2FsbGVyBQR0aGlzBgkAAAIFBmNhbGxlcgUGc2VsbGVyAQ5pc0F1Y3Rpb25FbmRlZAIDbm93A2VuZAkAZgIFA25vdwUDZW5kAQ1pc0Vub3VnaEZ1bmRzAgdwYXltZW50EmN1cnJlbnRNb21lbnRQcmljZQkAZwIFB3BheW1lbnQFEmN1cnJlbnRNb21lbnRQcmljZQEHaXNXYXdlcwEHYXNzZXRJZAkAAAIFB2Fzc2V0SWQFBHVuaXQBDGlzQ29ycmVjdE5mdAEFbmZ0SWQDCQEBIQEJAQVpc05mdAEFBW5mdElkCQACAQIQVG9rZW4gaXMgbm90IE5mdAMJAQtpc1NlbGxFeGlzdAEFBW5mdElkCQACAQITU2VsbCBhbHJlYWR5IGV4aXN0cwMJAQ5pc0F1Y3Rpb25FeGlzdAEFBW5mdElkCQACAQIWQXVjdGlvbiBhbHJlYWR5IGV4aXN0cwUEdW5pdAERaXNDb3JyZWN0UGF5bWVudHMDDHBheW1lbnRBc3NldA1wYXltZW50QW1vdW50BXByaWNlAwkBASEBCQEHaXNXYXdlcwEFDHBheW1lbnRBc3NldAkAAgECGFBheW1lbnQgbXVzdCBiZSBhdCBXQVZFUwMJAQEhAQkBDWlzRW5vdWdoRnVuZHMCBQ1wYXltZW50QW1vdW50BQVwcmljZQkAAgECEE5vdCBlbm91Z2ggZnVuZHMFBHVuaXQBB2NhbGNGZWUAAAABDmNhbGNUcnVzdGVkRmVlAAAAARJyZXN1bHRGdW5kc0Ftb3VudHMDCWlzVHJ1c3RlZA1wYXltZW50QW1vdW50C2FjdHVhbFByaWNlAwUJaXNUcnVzdGVkCQCUCgIJAGUCBQthY3R1YWxQcmljZQkBDmNhbGNUcnVzdGVkRmVlAAkAZQIFDXBheW1lbnRBbW91bnQFC2FjdHVhbFByaWNlCQCUCgIJAGUCBQthY3R1YWxQcmljZQkBB2NhbGNGZWUACQBlAgUNcGF5bWVudEFtb3VudAULYWN0dWFsUHJpY2UBB2dldFNsb3QBBW5mdElkAwkBC2lzU2VsbEV4aXN0AQUFbmZ0SWQJAJQKAgUFa1NlbGwJAQdnZXRTZWxsAQUFbmZ0SWQDCQEOaXNBdWN0aW9uRXhpc3QBBQVuZnRJZAkAlAoCBQhrQXVjdGlvbgkBCmdldEF1Y3Rpb24BBQVuZnRJZAkAAgECElNsb3QgZG9lc25gdCBleGlzdAAEa0J1eQIDYnV5CgFpAQljcmVhdGVOZnQJCG5mdF9uYW1lCW5mdF9vd25lcg9uZnRfZEFwcEFkZHJlc3MIbmZ0X3R5cGUIbmZ0X3RhZ3MRbmZ0X3NlbGxpbmdfcHJpY2UPbmZ0X2Rlc2NyaXB0aW9uCm5mdF9vblNlbGwIbmZ0X2RhdGEECG5ld1Rva2VuCQDCCAUFCG5mdF9uYW1lBQ9uZnRfZGVzY3JpcHRpb24AAQAABwQHaXNzdWVJZAkAuAgBBQhuZXdUb2tlbgkAzAgCBQhuZXdUb2tlbgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIAAQUHaXNzdWVJZAkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgkA2AQBBQdpc3N1ZUlkBQlzZXBhcmF0b3ICBU93bmVyCQClCAEIBQFpBmNhbGxlcgkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgkA2AQBBQdpc3N1ZUlkBQlzZXBhcmF0b3ICCG5mdF90eXBlBQhuZnRfdHlwZQkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgkA2AQBBQdpc3N1ZUlkBQlzZXBhcmF0b3ICCG5mdF90YWdzBQhuZnRfdGFncwkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgkA2AQBBQdpc3N1ZUlkBQlzZXBhcmF0b3ICD25mdF9kQXBwQWRkcmVzcwUPbmZ0X2RBcHBBZGRyZXNzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkA2AQBBQdpc3N1ZUlkBQlzZXBhcmF0b3ICEW5mdF9zZWxsaW5nX3ByaWNlBRFuZnRfc2VsbGluZ19wcmljZQkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgkA2AQBBQdpc3N1ZUlkBQlzZXBhcmF0b3ICCm5mdF9vblNlbGwFCm5mdF9vblNlbGwJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJANgEAQUHaXNzdWVJZAUJc2VwYXJhdG9yAghuZnRfZGF0YQUIbmZ0X2RhdGEFA25pbAFpAQhpc3N1ZU5mdAIEbmFtZQRtZXRhBAhuZXdUb2tlbgkAwggFBQRuYW1lBQRtZXRhAAEAAAcEB2lzc3VlSWQJALgIAQUIbmV3VG9rZW4JAMwIAgUIbmV3VG9rZW4JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyAAEFB2lzc3VlSWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJANgEAQUHaXNzdWVJZAUJc2VwYXJhdG9yAgVPd25lcgkApQgBCAUBaQZjYWxsZXIFA25pbAFpAQZidXlORlQBBW5mdElEBAdhc3NldElkCQDZBAEFBW5mdElEBAZhbW91bnQJAQV2YWx1ZQEICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BAVwcmljZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJAKwCAgkArAICBQZrUHJpY2UFCXNlcGFyYXRvcgUFbmZ0SUQCHlRoZXJlIGlzIG5vIHByaWNlIGZvciB0aGlzIE5GVAQFb3duZXIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkBEUBleHRyTmF0aXZlKDEwNTgpAQkArAICCQCsAgIFBW5mdElEBQlzZXBhcmF0b3ICBU93bmVyAghObyBvd25lcgMJAQIhPQIICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAUEdW5pdAkAAgECDFBheSBpbiB3YXZlcwMJAGYCCQENcGFyc2VJbnRWYWx1ZQEFBXByaWNlBQZhbW91bnQJAAIBAg9JbnZhbGlkIHBheW1lbnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyAAEFB2Fzc2V0SWQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwkBBXZhbHVlAQkApggBBQVvd25lcgkBDXBhcnNlSW50VmFsdWUBBQVwcmljZQUEdW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgkApQgBCAUBaQZjYWxsZXIFCXNlcGFyYXRvcgUEa0J1eQkArAICCQCsAgIFBW5mdElEBQlzZXBhcmF0b3IJAKQDAQUGYW1vdW50BQNuaWwBaQEHc2VsbE5GVAEFcHJpY2UECyR0MDcyMTQ3Mjk5CQCUCgIJAQV2YWx1ZQEICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAkBBXZhbHVlAQgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQEBnRva2VuMAgFCyR0MDcyMTQ3Mjk5Al8xBAdhbW91bnQwCAULJHQwNzIxNDcyOTkCXzIDCQEBIQEJAQVpc05mdAEFBnRva2VuMAkAAgECEFRva2VuIGlzIG5vdCBORlQJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIFBmtQcmljZQUJc2VwYXJhdG9yCQDYBAEJAQV2YWx1ZQEICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAkApAMBBQVwcmljZQkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgkApQgBCAUBaQZjYWxsZXIFCXNlcGFyYXRvcgUFa1NlbGwJAKwCAgkArAICCQDYBAEFBnRva2VuMAUJc2VwYXJhdG9yCQCkAwEFB2Ftb3VudDAFA25pbAFpAQdhZGRTZWxsAQVwcmljZQQFbmZ0SWQJAQV2YWx1ZQEICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAkBC3ZhbHVlT3JFbHNlAgkBDGlzQ29ycmVjdE5mdAEFBW5mdElkAwkBASEBCQESaXNDb3JyZWN0U2VsbFByaWNlAQUFcHJpY2UJAAIBAhFQcmljZSBtdXN0IGJlID4gMAkAzAgCCQEHc2V0U2VsbAMFBW5mdElkCAUBaQZjYWxsZXIFBXByaWNlBQNuaWwBaQEKYWRkQXVjdGlvbgMKc3RhcnRQcmljZQVzdGFydANlbmQEBW5mdElkCQEFdmFsdWUBCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQJAQt2YWx1ZU9yRWxzZQIJAQxpc0NvcnJlY3ROZnQBBQVuZnRJZAkAzAgCCQEKc2V0QXVjdGlvbgUIBQFpBmNhbGxlcgUFbmZ0SWQFCnN0YXJ0UHJpY2UFBXN0YXJ0BQNlbmQJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJANgEAQUFbmZ0SWQFCXNlcGFyYXRvcgIJbmZ0X293bmVyCQClCAEIBQFpBmNhbGxlcgUDbmlsAWkBC2J1eUZyb21TbG90AQVuZnRJZAQLJHQwODIxOTgzMDgJAJQKAggJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkCQEFdmFsdWUBCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAQMcGF5bWVudEFzc2V0CAULJHQwODIxOTgzMDgCXzEEDXBheW1lbnRBbW91bnQIBQskdDA4MjE5ODMwOAJfMgQHYXNzZXRJZAkA2QQBBQVuZnRJZAQLJHQwODM1MjgzOTAJAQdnZXRTbG90AQUHYXNzZXRJZAQEdHlwZQgFCyR0MDgzNTI4MzkwAl8xBAdkZXRhaWxzCAULJHQwODM1MjgzOTACXzIEB2Jhc2VSZXMJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyAAEFB2Fzc2V0SWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBCmdldFNsb3RLZXkCBQR0eXBlBQdhc3NldElkBQNuaWwDCQAAAgUEdHlwZQUFa1NlbGwECyR0MDg1MzI4NTc5CQELcGFyc2VBc1NlbGwBBQdkZXRhaWxzBAZzZWxsZXIIBQskdDA4NTMyODU3OQJfMQQKcHJpY2VWYWx1ZQgFCyR0MDg1MzI4NTc5Al8yCQELdmFsdWVPckVsc2UCCQERaXNDb3JyZWN0UGF5bWVudHMDBQxwYXltZW50QXNzZXQFDXBheW1lbnRBbW91bnQFCnByaWNlVmFsdWUECyR0MDg2NjQ4NzY2CQEScmVzdWx0RnVuZHNBbW91bnRzAwkBDGlzVHJ1c3RlZE5mdAEFB2Fzc2V0SWQFDXBheW1lbnRBbW91bnQFCnByaWNlVmFsdWUEDHNlbGxlckFtb3VudAgFCyR0MDg2NjQ4NzY2Al8xBAtidXllckFtb3VudAgFCyR0MDg2NjQ4NzY2Al8yBAp1cGRhdGVkUmVzCQDOCAIFB2Jhc2VSZXMJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUGc2VsbGVyBQxzZWxsZXJBbW91bnQFBHVuaXQFA25pbAMJAGYCBQtidXllckFtb3VudAAACQDOCAIFCnVwZGF0ZWRSZXMJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQtidXllckFtb3VudAUEdW5pdAUDbmlsBQp1cGRhdGVkUmVzBAskdDA4OTgzOTA1MgkBGGNhbGNQcmljZUF0Q3VycmVudE1vbWVudAIFB2Fzc2V0SWQFBmhlaWdodAQGc2VsbGVyCAULJHQwODk4MzkwNTICXzEEC2FjdHVhbFByaWNlCAULJHQwODk4MzkwNTICXzIJAQt2YWx1ZU9yRWxzZQIJARFpc0NvcnJlY3RQYXltZW50cwMFDHBheW1lbnRBc3NldAUNcGF5bWVudEFtb3VudAULYWN0dWFsUHJpY2UECyR0MDkxMzg5MjQxCQEScmVzdWx0RnVuZHNBbW91bnRzAwkBDGlzVHJ1c3RlZE5mdAEFB2Fzc2V0SWQFDXBheW1lbnRBbW91bnQFC2FjdHVhbFByaWNlBAxzZWxsZXJBbW91bnQIBQskdDA5MTM4OTI0MQJfMQQLYnV5ZXJBbW91bnQIBQskdDA5MTM4OTI0MQJfMgQKdXBkYXRlZFJlcwkAzggCBQdiYXNlUmVzCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFBnNlbGxlcgUMc2VsbGVyQW1vdW50BQR1bml0BQNuaWwDCQBmAgULYnV5ZXJBbW91bnQAAAkAzggCBQp1cGRhdGVkUmVzCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgULYnV5ZXJBbW91bnQFBHVuaXQFA25pbAUKdXBkYXRlZFJlcwFpAQtkZWNsaW5lU2xvdAEFbmZ0SWQEB2Fzc2V0SWQJANkEAQUFbmZ0SWQECyR0MDk1NDI5NTgwCQEHZ2V0U2xvdAEFB2Fzc2V0SWQEBHR5cGUIBQskdDA5NTQyOTU4MAJfMQQHZGV0YWlscwgFCyR0MDk1NDI5NTgwAl8yBAdiYXNlUmVzCQDMCAIJAQtEZWxldGVFbnRyeQEJAQpnZXRTbG90S2V5AgUEdHlwZQUHYXNzZXRJZAUDbmlsAwkAAAIFBHR5cGUFBWtTZWxsBAskdDA5NjcyOTcxOQkBC3BhcnNlQXNTZWxsAQUHZGV0YWlscwQGc2VsbGVyCAULJHQwOTY3Mjk3MTkCXzEECnByaWNlVmFsdWUIBQskdDA5NjcyOTcxOQJfMgMJAQEhAQkBDWlzVmFsaWRDYWxsZXICCAUBaQZjYWxsZXIFBnNlbGxlcgkAAgECDkludmFsaWQgY2FsbGVyCQDOCAIFB2Jhc2VSZXMJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUGc2VsbGVyAAEFB2Fzc2V0SWQFA25pbAQLJHQwOTg2NDk5NjgJAQ5wYXJzZUFzQXVjdGlvbgEFB2RldGFpbHMEBnNlbGxlcggFCyR0MDk4NjQ5OTY4Al8xBA9zdGFydFByaWNlVmFsdWUIBQskdDA5ODY0OTk2OAJfMgQNZW5kUHJpY2VWYWx1ZQgFCyR0MDk4NjQ5OTY4Al8zBBBzdGFydFBlcmlvZFZhbHVlCAULJHQwOTg2NDk5NjgCXzQEDmVuZFBlcmlvZFZhbHVlCAULJHQwOTg2NDk5NjgCXzUDCQEBIQEJAQ1pc1ZhbGlkQ2FsbGVyAggFAWkGY2FsbGVyBQZzZWxsZXIJAAIBAg5JbnZhbGlkIGNhbGxlcgMJAQEhAQkBDmlzQXVjdGlvbkVuZGVkAgUGaGVpZ2h0BQ5lbmRQZXJpb2RWYWx1ZQkAAgECF1dhaXQgZm9yIGVuZCBvZiBhdWN0aW9uCQDOCAIFB2Jhc2VSZXMJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUGc2VsbGVyAAEFB2Fzc2V0SWQFA25pbAFpARBzZXRUcnVzdGVkSXNzdWVyAQt0cnVzdGVkQWRkcgMJAQEhAQkBB2lzQWRtaW4BCAUBaQZjYWxsZXIJAAIBAgpPbmx5IGFkbWluCQDMCAIJAQxCb29sZWFuRW50cnkCCQENZ2V0VHJ1c3RlZEtleQEJARFAZXh0ck5hdGl2ZSgxMDYyKQEFC3RydXN0ZWRBZGRyBgUDbmlsAWkBF2dldFByaWNlQXRDdXJyZW50TW9tZW50AgVuZnRJZAZtb21lbnQEB2Fzc2V0SWQJANkEAQUFbmZ0SWQEDSR0MDEwNTA5MTA1NzIJARhjYWxjUHJpY2VBdEN1cnJlbnRNb21lbnQCBQdhc3NldElkBQZtb21lbnQEBnNlbGxlcggFDSR0MDEwNTA5MTA1NzICXzEEBXByaWNlCAUNJHQwMTA1MDkxMDU3MgJfMgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBC2dldFByaWNlS2V5AQUHYXNzZXRJZAUFcHJpY2UFA25pbAAw0k2G", "height": 2337935, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: ERF1sLvsJ76NijdJw7hbdWw7drbvMxX8NLzhddCfdzDR Next: 3DJYfYXjGaYEaChEXLTRiJvFQ4eTvJD62CecqGsHstXk Diff:
OldNewDifferences
33 {-# CONTENT_TYPE DAPP #-}
44 let separator = "_"
55
6-let kBuy = "buy"
6+let kAuction = "auction"
77
88 let kSell = "sell"
99
10+let kTrusted = "trusted"
11+
1012 let kPrice = "price"
13+
14+func getSlotKey (prefix,nftId) = ((prefix + separator) + toBase58String(nftId))
15+
16+
17+func getPriceKey (nftId) = ((kPrice + separator) + toBase58String(nftId))
18+
19+
20+func getSellKey (nftId) = ((kSell + separator) + toBase58String(nftId))
21+
22+
23+func getAuctionKey (nftId) = ((kAuction + separator) + toBase58String(nftId))
24+
25+
26+func getTrustedKey (issuer) = ((kTrusted + separator) + toString(issuer))
27+
28+
29+func addToList (accum,nextValue) = (accum ++ [nextValue])
30+
31+
32+func joinString (params) = {
33+ let length = size(params)
34+ if ((length == 0))
35+ then throw("Empty params")
36+ else if ((length == 1))
37+ then makeString({
38+ let $l = params
39+ let $s = size($l)
40+ let $acc0 = nil
41+ func $f0_1 ($a,$i) = if (($i >= $s))
42+ then $a
43+ else addToList($a, $l[$i])
44+
45+ func $f0_2 ($a,$i) = if (($i >= $s))
46+ then $a
47+ else throw("List size exceeds 1")
48+
49+ $f0_2($f0_1($acc0, 0), 1)
50+ }, separator)
51+ else if ((length == 2))
52+ then makeString({
53+ let $l = params
54+ let $s = size($l)
55+ let $acc0 = nil
56+ func $f0_1 ($a,$i) = if (($i >= $s))
57+ then $a
58+ else addToList($a, $l[$i])
59+
60+ func $f0_2 ($a,$i) = if (($i >= $s))
61+ then $a
62+ else throw("List size exceeds 2")
63+
64+ $f0_2($f0_1($f0_1($acc0, 0), 1), 2)
65+ }, separator)
66+ else if ((length == 3))
67+ then makeString({
68+ let $l = params
69+ let $s = size($l)
70+ let $acc0 = nil
71+ func $f0_1 ($a,$i) = if (($i >= $s))
72+ then $a
73+ else addToList($a, $l[$i])
74+
75+ func $f0_2 ($a,$i) = if (($i >= $s))
76+ then $a
77+ else throw("List size exceeds 3")
78+
79+ $f0_2($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3)
80+ }, separator)
81+ else if ((length == 4))
82+ then makeString({
83+ let $l = params
84+ let $s = size($l)
85+ let $acc0 = nil
86+ func $f0_1 ($a,$i) = if (($i >= $s))
87+ then $a
88+ else addToList($a, $l[$i])
89+
90+ func $f0_2 ($a,$i) = if (($i >= $s))
91+ then $a
92+ else throw("List size exceeds 4")
93+
94+ $f0_2($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4)
95+ }, separator)
96+ else if ((length == 5))
97+ then makeString({
98+ let $l = params
99+ let $s = size($l)
100+ let $acc0 = nil
101+ func $f0_1 ($a,$i) = if (($i >= $s))
102+ then $a
103+ else addToList($a, $l[$i])
104+
105+ func $f0_2 ($a,$i) = if (($i >= $s))
106+ then $a
107+ else throw("List size exceeds 5")
108+
109+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
110+ }, separator)
111+ else throw("Max number of parameters exceeded")
112+ }
113+
114+
115+func parseAsAuction (details) = {
116+ let res = split(details, separator)
117+ $Tuple5(addressFromStringValue(res[0]), parseIntValue(res[1]), parseIntValue(res[2]), parseIntValue(res[3]), parseIntValue(res[4]))
118+ }
119+
120+
121+func parseAsSell (details) = {
122+ let res = split(details, separator)
123+ $Tuple2(addressFromStringValue(res[0]), parseIntValue(res[1]))
124+ }
125+
126+
127+func joinStruct (params) = match params {
128+ case auction: (Address, Int, String, String) =>
129+ joinString([toString(auction._1), toString(auction._2), auction._3, auction._4])
130+ case sell: (Address, Int) =>
131+ joinString([toString(sell._1), toString(sell._2)])
132+ case _ =>
133+ throw("Wrong params tupple")
134+}
135+
136+
137+func setAuction (seller,nftId,startPrice,start,end) = StringEntry(getAuctionKey(nftId), joinStruct($Tuple4(seller, startPrice, start, end)))
138+
139+
140+func setSell (nftId,celler,price) = StringEntry(getSellKey(nftId), joinStruct($Tuple2(celler, price)))
141+
142+
143+func getAuction (nftId) = value(getString(this, getAuctionKey(nftId)))
144+
145+
146+func getSell (nftId) = value(getString(this, getSellKey(nftId)))
147+
148+
149+func calcPriceAtCurrentMoment (assetId,moment) = {
150+ let details = getAuction(assetId)
151+ let $t027552859 = parseAsAuction(details)
152+ let seller = $t027552859._1
153+ let startPriceValue = $t027552859._2
154+ let endPriceValue = $t027552859._3
155+ let startPeriodValue = $t027552859._4
156+ let endPeriodValue = $t027552859._5
157+ if ((moment >= endPeriodValue))
158+ then $Tuple2(seller, endPriceValue)
159+ else {
160+ let deltaPrice = (startPriceValue - endPriceValue)
161+ let period = (endPeriodValue - startPeriodValue)
162+ let spended = (moment - startPeriodValue)
163+ $Tuple2(seller, (startPriceValue - fraction(spended, deltaPrice, period)))
164+ }
165+ }
166+
11167
12168 func isNft (assetId) = match assetInfo(assetId) {
13169 case token: Asset =>
21177 }
22178
23179
180+func isTrustedNft (assetId) = {
181+ let issuer = value(assetInfo(assetId)).issuer
182+ valueOrElse(getBoolean(this, getTrustedKey(issuer)), false)
183+ }
184+
185+
186+func isSellExist (assetId) = isDefined(getString(this, getSellKey(assetId)))
187+
188+
189+func isAuctionExist (assetId) = isDefined(getString(this, getAuctionKey(assetId)))
190+
191+
192+func isCorrectSellPrice (price) = (price > 0)
193+
194+
195+func isCorrectAuctionPrices (startPrice,endPrice) = (startPrice > endPrice)
196+
197+
198+func isAdmin (caller) = (caller == this)
199+
200+
201+func isValidCaller (caller,seller) = if ((caller == this))
202+ then true
203+ else (caller == seller)
204+
205+
206+func isAuctionEnded (now,end) = (now > end)
207+
208+
209+func isEnoughFunds (payment,currentMomentPrice) = (payment >= currentMomentPrice)
210+
211+
212+func isWawes (assetId) = (assetId == unit)
213+
214+
215+func isCorrectNft (nftId) = if (!(isNft(nftId)))
216+ then throw("Token is not Nft")
217+ else if (isSellExist(nftId))
218+ then throw("Sell already exists")
219+ else if (isAuctionExist(nftId))
220+ then throw("Auction already exists")
221+ else unit
222+
223+
224+func isCorrectPayments (paymentAsset,paymentAmount,price) = if (!(isWawes(paymentAsset)))
225+ then throw("Payment must be at WAVES")
226+ else if (!(isEnoughFunds(paymentAmount, price)))
227+ then throw("Not enough funds")
228+ else unit
229+
230+
231+func calcFee () = 0
232+
233+
234+func calcTrustedFee () = 0
235+
236+
237+func resultFundsAmounts (isTrusted,paymentAmount,actualPrice) = if (isTrusted)
238+ then $Tuple2((actualPrice - calcTrustedFee()), (paymentAmount - actualPrice))
239+ else $Tuple2((actualPrice - calcFee()), (paymentAmount - actualPrice))
240+
241+
242+func getSlot (nftId) = if (isSellExist(nftId))
243+ then $Tuple2(kSell, getSell(nftId))
244+ else if (isAuctionExist(nftId))
245+ then $Tuple2(kAuction, getAuction(nftId))
246+ else throw("Slot doesn`t exist")
247+
248+
249+let kBuy = "buy"
250+
24251 @Callable(i)
25-func issueNft (nft_name,nft_owner,nft_dAppAddress,nft_type,nft_tags,nft_selling_price,nft_description,nft_onSell,nft_data) = {
252+func createNft (nft_name,nft_owner,nft_dAppAddress,nft_type,nft_tags,nft_selling_price,nft_description,nft_onSell,nft_data) = {
26253 let newToken = Issue(nft_name, nft_description, 1, 0, false)
27- let txId = i.transactionId
28254 let issueId = calculateAssetId(newToken)
29-[newToken, ScriptTransfer(i.caller, 1, issueId), StringEntry(((toBase58String(issueId) + separator) + "Owner"), toString(i.caller)), StringEntry(((toBase58String(issueId) + separator) + "nft_type"), nft_type), StringEntry(((toBase58String(issueId) + separator) + "nft_tags"), nft_tags), StringEntry(((toBase58String(issueId) + separator) + "nft_dAppAddress"), nft_dAppAddress), IntegerEntry(((toBase58String(issueId) + separator) + "nft_selling_price"), nft_selling_price), StringEntry(((toBase58String(issueId) + separator) + "nft_onSell"), nft_onSell), StringEntry(((toBase58String(issueId) + separator) + "nft_data"), nft_data), StringEntry(((toBase58String(txId) + separator) + "issue_nft"), toBase58String(issueId))]
255+[newToken, ScriptTransfer(i.caller, 1, issueId), StringEntry(((toBase58String(issueId) + separator) + "Owner"), toString(i.caller)), StringEntry(((toBase58String(issueId) + separator) + "nft_type"), nft_type), StringEntry(((toBase58String(issueId) + separator) + "nft_tags"), nft_tags), StringEntry(((toBase58String(issueId) + separator) + "nft_dAppAddress"), nft_dAppAddress), IntegerEntry(((toBase58String(issueId) + separator) + "nft_selling_price"), nft_selling_price), StringEntry(((toBase58String(issueId) + separator) + "nft_onSell"), nft_onSell), StringEntry(((toBase58String(issueId) + separator) + "nft_data"), nft_data)]
30256 }
31257
32258
33259
34260 @Callable(i)
35-func createNFT (name,meta) = {
261+func issueNft (name,meta) = {
36262 let newToken = Issue(name, meta, 1, 0, false)
37263 let issueId = calculateAssetId(newToken)
38264 [newToken, ScriptTransfer(i.caller, 1, issueId), StringEntry(((toBase58String(issueId) + separator) + "Owner"), toString(i.caller))]
44270 func buyNFT (nftID) = {
45271 let assetId = fromBase58String(nftID)
46272 let amount = value(i.payments[0].amount)
47- let price = valueOrErrorMessage(getInteger(((kPrice + separator) + nftID)), "There is no price for this NFT")
273+ let price = valueOrErrorMessage(getString(((kPrice + separator) + nftID)), "There is no price for this NFT")
48274 let owner = valueOrErrorMessage(getStringValue(((nftID + separator) + "Owner")), "No owner")
49275 if ((i.payments[0].assetId != unit))
50276 then throw("Pay in waves")
51- else if ((price > amount))
277+ else if ((parseIntValue(price) > amount))
52278 then throw("Invalid payment")
53- else [ScriptTransfer(i.caller, 1, assetId), ScriptTransfer(value(addressFromString(owner)), price, unit), StringEntry(((toString(i.caller) + separator) + kBuy), ((nftID + separator) + toString(amount)))]
279+ else [ScriptTransfer(i.caller, 1, assetId), ScriptTransfer(value(addressFromString(owner)), parseIntValue(price), unit), StringEntry(((toString(i.caller) + separator) + kBuy), ((nftID + separator) + toString(amount)))]
54280 }
55281
56282
57283
58284 @Callable(i)
59285 func sellNFT (price) = {
60- let $t024642549 = $Tuple2(value(i.payments[0].assetId), value(i.payments[0].amount))
61- let token0 = $t024642549._1
62- let amount0 = $t024642549._2
63- let assetid = value(i.payments[0].assetId)
286+ let $t072147299 = $Tuple2(value(i.payments[0].assetId), value(i.payments[0].amount))
287+ let token0 = $t072147299._1
288+ let amount0 = $t072147299._2
64289 if (!(isNft(token0)))
65290 then throw("Token is not NFT")
66- else [StringEntry((toBase58String(assetid) + "_owner"), toString(i.caller)), IntegerEntry((toBase58String(assetid) + "_nft_selling_price"), price), StringEntry((toBase58String(assetid) + "_onsell"), "true"), IntegerEntry(((kPrice + separator) + toBase58String(value(i.payments[0].assetId))), price), StringEntry(((toString(i.caller) + separator) + kSell), ((toBase58String(token0) + separator) + toString(amount0)))]
291+ else [StringEntry(((kPrice + separator) + toBase58String(value(i.payments[0].assetId))), toString(price)), StringEntry(((toString(i.caller) + separator) + kSell), ((toBase58String(token0) + separator) + toString(amount0)))]
292+ }
293+
294+
295+
296+@Callable(i)
297+func addSell (price) = {
298+ let nftId = value(i.payments[0].assetId)
299+ valueOrElse(isCorrectNft(nftId), if (!(isCorrectSellPrice(price)))
300+ then throw("Price must be > 0")
301+ else [setSell(nftId, i.caller, price)])
302+ }
303+
304+
305+
306+@Callable(i)
307+func addAuction (startPrice,start,end) = {
308+ let nftId = value(i.payments[0].assetId)
309+ valueOrElse(isCorrectNft(nftId), [setAuction(i.caller, nftId, startPrice, start, end), StringEntry(((toBase58String(nftId) + separator) + "nft_owner"), toString(i.caller))])
310+ }
311+
312+
313+
314+@Callable(i)
315+func buyFromSlot (nftId) = {
316+ let $t082198308 = $Tuple2(i.payments[0].assetId, value(i.payments[0].amount))
317+ let paymentAsset = $t082198308._1
318+ let paymentAmount = $t082198308._2
319+ let assetId = fromBase58String(nftId)
320+ let $t083528390 = getSlot(assetId)
321+ let type = $t083528390._1
322+ let details = $t083528390._2
323+ let baseRes = [ScriptTransfer(i.caller, 1, assetId), DeleteEntry(getSlotKey(type, assetId))]
324+ if ((type == kSell))
325+ then {
326+ let $t085328579 = parseAsSell(details)
327+ let seller = $t085328579._1
328+ let priceValue = $t085328579._2
329+ valueOrElse(isCorrectPayments(paymentAsset, paymentAmount, priceValue), {
330+ let $t086648766 = resultFundsAmounts(isTrustedNft(assetId), paymentAmount, priceValue)
331+ let sellerAmount = $t086648766._1
332+ let buyerAmount = $t086648766._2
333+ let updatedRes = (baseRes ++ [ScriptTransfer(seller, sellerAmount, unit)])
334+ if ((buyerAmount > 0))
335+ then (updatedRes ++ [ScriptTransfer(i.caller, buyerAmount, unit)])
336+ else updatedRes
337+ })
338+ }
339+ else {
340+ let $t089839052 = calcPriceAtCurrentMoment(assetId, height)
341+ let seller = $t089839052._1
342+ let actualPrice = $t089839052._2
343+ valueOrElse(isCorrectPayments(paymentAsset, paymentAmount, actualPrice), {
344+ let $t091389241 = resultFundsAmounts(isTrustedNft(assetId), paymentAmount, actualPrice)
345+ let sellerAmount = $t091389241._1
346+ let buyerAmount = $t091389241._2
347+ let updatedRes = (baseRes ++ [ScriptTransfer(seller, sellerAmount, unit)])
348+ if ((buyerAmount > 0))
349+ then (updatedRes ++ [ScriptTransfer(i.caller, buyerAmount, unit)])
350+ else updatedRes
351+ })
352+ }
353+ }
354+
355+
356+
357+@Callable(i)
358+func declineSlot (nftId) = {
359+ let assetId = fromBase58String(nftId)
360+ let $t095429580 = getSlot(assetId)
361+ let type = $t095429580._1
362+ let details = $t095429580._2
363+ let baseRes = [DeleteEntry(getSlotKey(type, assetId))]
364+ if ((type == kSell))
365+ then {
366+ let $t096729719 = parseAsSell(details)
367+ let seller = $t096729719._1
368+ let priceValue = $t096729719._2
369+ if (!(isValidCaller(i.caller, seller)))
370+ then throw("Invalid caller")
371+ else (baseRes ++ [ScriptTransfer(seller, 1, assetId)])
372+ }
373+ else {
374+ let $t098649968 = parseAsAuction(details)
375+ let seller = $t098649968._1
376+ let startPriceValue = $t098649968._2
377+ let endPriceValue = $t098649968._3
378+ let startPeriodValue = $t098649968._4
379+ let endPeriodValue = $t098649968._5
380+ if (!(isValidCaller(i.caller, seller)))
381+ then throw("Invalid caller")
382+ else if (!(isAuctionEnded(height, endPeriodValue)))
383+ then throw("Wait for end of auction")
384+ else (baseRes ++ [ScriptTransfer(seller, 1, assetId)])
385+ }
386+ }
387+
388+
389+
390+@Callable(i)
391+func setTrustedIssuer (trustedAddr) = if (!(isAdmin(i.caller)))
392+ then throw("Only admin")
393+ else [BooleanEntry(getTrustedKey(addressFromStringValue(trustedAddr)), true)]
394+
395+
396+
397+@Callable(i)
398+func getPriceAtCurrentMoment (nftId,moment) = {
399+ let assetId = fromBase58String(nftId)
400+ let $t01050910572 = calcPriceAtCurrentMoment(assetId, moment)
401+ let seller = $t01050910572._1
402+ let price = $t01050910572._2
403+[IntegerEntry(getPriceKey(assetId), price)]
67404 }
68405
69406
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let separator = "_"
55
6-let kBuy = "buy"
6+let kAuction = "auction"
77
88 let kSell = "sell"
99
10+let kTrusted = "trusted"
11+
1012 let kPrice = "price"
13+
14+func getSlotKey (prefix,nftId) = ((prefix + separator) + toBase58String(nftId))
15+
16+
17+func getPriceKey (nftId) = ((kPrice + separator) + toBase58String(nftId))
18+
19+
20+func getSellKey (nftId) = ((kSell + separator) + toBase58String(nftId))
21+
22+
23+func getAuctionKey (nftId) = ((kAuction + separator) + toBase58String(nftId))
24+
25+
26+func getTrustedKey (issuer) = ((kTrusted + separator) + toString(issuer))
27+
28+
29+func addToList (accum,nextValue) = (accum ++ [nextValue])
30+
31+
32+func joinString (params) = {
33+ let length = size(params)
34+ if ((length == 0))
35+ then throw("Empty params")
36+ else if ((length == 1))
37+ then makeString({
38+ let $l = params
39+ let $s = size($l)
40+ let $acc0 = nil
41+ func $f0_1 ($a,$i) = if (($i >= $s))
42+ then $a
43+ else addToList($a, $l[$i])
44+
45+ func $f0_2 ($a,$i) = if (($i >= $s))
46+ then $a
47+ else throw("List size exceeds 1")
48+
49+ $f0_2($f0_1($acc0, 0), 1)
50+ }, separator)
51+ else if ((length == 2))
52+ then makeString({
53+ let $l = params
54+ let $s = size($l)
55+ let $acc0 = nil
56+ func $f0_1 ($a,$i) = if (($i >= $s))
57+ then $a
58+ else addToList($a, $l[$i])
59+
60+ func $f0_2 ($a,$i) = if (($i >= $s))
61+ then $a
62+ else throw("List size exceeds 2")
63+
64+ $f0_2($f0_1($f0_1($acc0, 0), 1), 2)
65+ }, separator)
66+ else if ((length == 3))
67+ then makeString({
68+ let $l = params
69+ let $s = size($l)
70+ let $acc0 = nil
71+ func $f0_1 ($a,$i) = if (($i >= $s))
72+ then $a
73+ else addToList($a, $l[$i])
74+
75+ func $f0_2 ($a,$i) = if (($i >= $s))
76+ then $a
77+ else throw("List size exceeds 3")
78+
79+ $f0_2($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3)
80+ }, separator)
81+ else if ((length == 4))
82+ then makeString({
83+ let $l = params
84+ let $s = size($l)
85+ let $acc0 = nil
86+ func $f0_1 ($a,$i) = if (($i >= $s))
87+ then $a
88+ else addToList($a, $l[$i])
89+
90+ func $f0_2 ($a,$i) = if (($i >= $s))
91+ then $a
92+ else throw("List size exceeds 4")
93+
94+ $f0_2($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4)
95+ }, separator)
96+ else if ((length == 5))
97+ then makeString({
98+ let $l = params
99+ let $s = size($l)
100+ let $acc0 = nil
101+ func $f0_1 ($a,$i) = if (($i >= $s))
102+ then $a
103+ else addToList($a, $l[$i])
104+
105+ func $f0_2 ($a,$i) = if (($i >= $s))
106+ then $a
107+ else throw("List size exceeds 5")
108+
109+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
110+ }, separator)
111+ else throw("Max number of parameters exceeded")
112+ }
113+
114+
115+func parseAsAuction (details) = {
116+ let res = split(details, separator)
117+ $Tuple5(addressFromStringValue(res[0]), parseIntValue(res[1]), parseIntValue(res[2]), parseIntValue(res[3]), parseIntValue(res[4]))
118+ }
119+
120+
121+func parseAsSell (details) = {
122+ let res = split(details, separator)
123+ $Tuple2(addressFromStringValue(res[0]), parseIntValue(res[1]))
124+ }
125+
126+
127+func joinStruct (params) = match params {
128+ case auction: (Address, Int, String, String) =>
129+ joinString([toString(auction._1), toString(auction._2), auction._3, auction._4])
130+ case sell: (Address, Int) =>
131+ joinString([toString(sell._1), toString(sell._2)])
132+ case _ =>
133+ throw("Wrong params tupple")
134+}
135+
136+
137+func setAuction (seller,nftId,startPrice,start,end) = StringEntry(getAuctionKey(nftId), joinStruct($Tuple4(seller, startPrice, start, end)))
138+
139+
140+func setSell (nftId,celler,price) = StringEntry(getSellKey(nftId), joinStruct($Tuple2(celler, price)))
141+
142+
143+func getAuction (nftId) = value(getString(this, getAuctionKey(nftId)))
144+
145+
146+func getSell (nftId) = value(getString(this, getSellKey(nftId)))
147+
148+
149+func calcPriceAtCurrentMoment (assetId,moment) = {
150+ let details = getAuction(assetId)
151+ let $t027552859 = parseAsAuction(details)
152+ let seller = $t027552859._1
153+ let startPriceValue = $t027552859._2
154+ let endPriceValue = $t027552859._3
155+ let startPeriodValue = $t027552859._4
156+ let endPeriodValue = $t027552859._5
157+ if ((moment >= endPeriodValue))
158+ then $Tuple2(seller, endPriceValue)
159+ else {
160+ let deltaPrice = (startPriceValue - endPriceValue)
161+ let period = (endPeriodValue - startPeriodValue)
162+ let spended = (moment - startPeriodValue)
163+ $Tuple2(seller, (startPriceValue - fraction(spended, deltaPrice, period)))
164+ }
165+ }
166+
11167
12168 func isNft (assetId) = match assetInfo(assetId) {
13169 case token: Asset =>
14170 if (if ((token.decimals == 0))
15171 then (token.quantity == 1)
16172 else false)
17173 then (token.reissuable == false)
18174 else false
19175 case _ =>
20176 false
21177 }
22178
23179
180+func isTrustedNft (assetId) = {
181+ let issuer = value(assetInfo(assetId)).issuer
182+ valueOrElse(getBoolean(this, getTrustedKey(issuer)), false)
183+ }
184+
185+
186+func isSellExist (assetId) = isDefined(getString(this, getSellKey(assetId)))
187+
188+
189+func isAuctionExist (assetId) = isDefined(getString(this, getAuctionKey(assetId)))
190+
191+
192+func isCorrectSellPrice (price) = (price > 0)
193+
194+
195+func isCorrectAuctionPrices (startPrice,endPrice) = (startPrice > endPrice)
196+
197+
198+func isAdmin (caller) = (caller == this)
199+
200+
201+func isValidCaller (caller,seller) = if ((caller == this))
202+ then true
203+ else (caller == seller)
204+
205+
206+func isAuctionEnded (now,end) = (now > end)
207+
208+
209+func isEnoughFunds (payment,currentMomentPrice) = (payment >= currentMomentPrice)
210+
211+
212+func isWawes (assetId) = (assetId == unit)
213+
214+
215+func isCorrectNft (nftId) = if (!(isNft(nftId)))
216+ then throw("Token is not Nft")
217+ else if (isSellExist(nftId))
218+ then throw("Sell already exists")
219+ else if (isAuctionExist(nftId))
220+ then throw("Auction already exists")
221+ else unit
222+
223+
224+func isCorrectPayments (paymentAsset,paymentAmount,price) = if (!(isWawes(paymentAsset)))
225+ then throw("Payment must be at WAVES")
226+ else if (!(isEnoughFunds(paymentAmount, price)))
227+ then throw("Not enough funds")
228+ else unit
229+
230+
231+func calcFee () = 0
232+
233+
234+func calcTrustedFee () = 0
235+
236+
237+func resultFundsAmounts (isTrusted,paymentAmount,actualPrice) = if (isTrusted)
238+ then $Tuple2((actualPrice - calcTrustedFee()), (paymentAmount - actualPrice))
239+ else $Tuple2((actualPrice - calcFee()), (paymentAmount - actualPrice))
240+
241+
242+func getSlot (nftId) = if (isSellExist(nftId))
243+ then $Tuple2(kSell, getSell(nftId))
244+ else if (isAuctionExist(nftId))
245+ then $Tuple2(kAuction, getAuction(nftId))
246+ else throw("Slot doesn`t exist")
247+
248+
249+let kBuy = "buy"
250+
24251 @Callable(i)
25-func issueNft (nft_name,nft_owner,nft_dAppAddress,nft_type,nft_tags,nft_selling_price,nft_description,nft_onSell,nft_data) = {
252+func createNft (nft_name,nft_owner,nft_dAppAddress,nft_type,nft_tags,nft_selling_price,nft_description,nft_onSell,nft_data) = {
26253 let newToken = Issue(nft_name, nft_description, 1, 0, false)
27- let txId = i.transactionId
28254 let issueId = calculateAssetId(newToken)
29-[newToken, ScriptTransfer(i.caller, 1, issueId), StringEntry(((toBase58String(issueId) + separator) + "Owner"), toString(i.caller)), StringEntry(((toBase58String(issueId) + separator) + "nft_type"), nft_type), StringEntry(((toBase58String(issueId) + separator) + "nft_tags"), nft_tags), StringEntry(((toBase58String(issueId) + separator) + "nft_dAppAddress"), nft_dAppAddress), IntegerEntry(((toBase58String(issueId) + separator) + "nft_selling_price"), nft_selling_price), StringEntry(((toBase58String(issueId) + separator) + "nft_onSell"), nft_onSell), StringEntry(((toBase58String(issueId) + separator) + "nft_data"), nft_data), StringEntry(((toBase58String(txId) + separator) + "issue_nft"), toBase58String(issueId))]
255+[newToken, ScriptTransfer(i.caller, 1, issueId), StringEntry(((toBase58String(issueId) + separator) + "Owner"), toString(i.caller)), StringEntry(((toBase58String(issueId) + separator) + "nft_type"), nft_type), StringEntry(((toBase58String(issueId) + separator) + "nft_tags"), nft_tags), StringEntry(((toBase58String(issueId) + separator) + "nft_dAppAddress"), nft_dAppAddress), IntegerEntry(((toBase58String(issueId) + separator) + "nft_selling_price"), nft_selling_price), StringEntry(((toBase58String(issueId) + separator) + "nft_onSell"), nft_onSell), StringEntry(((toBase58String(issueId) + separator) + "nft_data"), nft_data)]
30256 }
31257
32258
33259
34260 @Callable(i)
35-func createNFT (name,meta) = {
261+func issueNft (name,meta) = {
36262 let newToken = Issue(name, meta, 1, 0, false)
37263 let issueId = calculateAssetId(newToken)
38264 [newToken, ScriptTransfer(i.caller, 1, issueId), StringEntry(((toBase58String(issueId) + separator) + "Owner"), toString(i.caller))]
39265 }
40266
41267
42268
43269 @Callable(i)
44270 func buyNFT (nftID) = {
45271 let assetId = fromBase58String(nftID)
46272 let amount = value(i.payments[0].amount)
47- let price = valueOrErrorMessage(getInteger(((kPrice + separator) + nftID)), "There is no price for this NFT")
273+ let price = valueOrErrorMessage(getString(((kPrice + separator) + nftID)), "There is no price for this NFT")
48274 let owner = valueOrErrorMessage(getStringValue(((nftID + separator) + "Owner")), "No owner")
49275 if ((i.payments[0].assetId != unit))
50276 then throw("Pay in waves")
51- else if ((price > amount))
277+ else if ((parseIntValue(price) > amount))
52278 then throw("Invalid payment")
53- else [ScriptTransfer(i.caller, 1, assetId), ScriptTransfer(value(addressFromString(owner)), price, unit), StringEntry(((toString(i.caller) + separator) + kBuy), ((nftID + separator) + toString(amount)))]
279+ else [ScriptTransfer(i.caller, 1, assetId), ScriptTransfer(value(addressFromString(owner)), parseIntValue(price), unit), StringEntry(((toString(i.caller) + separator) + kBuy), ((nftID + separator) + toString(amount)))]
54280 }
55281
56282
57283
58284 @Callable(i)
59285 func sellNFT (price) = {
60- let $t024642549 = $Tuple2(value(i.payments[0].assetId), value(i.payments[0].amount))
61- let token0 = $t024642549._1
62- let amount0 = $t024642549._2
63- let assetid = value(i.payments[0].assetId)
286+ let $t072147299 = $Tuple2(value(i.payments[0].assetId), value(i.payments[0].amount))
287+ let token0 = $t072147299._1
288+ let amount0 = $t072147299._2
64289 if (!(isNft(token0)))
65290 then throw("Token is not NFT")
66- else [StringEntry((toBase58String(assetid) + "_owner"), toString(i.caller)), IntegerEntry((toBase58String(assetid) + "_nft_selling_price"), price), StringEntry((toBase58String(assetid) + "_onsell"), "true"), IntegerEntry(((kPrice + separator) + toBase58String(value(i.payments[0].assetId))), price), StringEntry(((toString(i.caller) + separator) + kSell), ((toBase58String(token0) + separator) + toString(amount0)))]
291+ else [StringEntry(((kPrice + separator) + toBase58String(value(i.payments[0].assetId))), toString(price)), StringEntry(((toString(i.caller) + separator) + kSell), ((toBase58String(token0) + separator) + toString(amount0)))]
292+ }
293+
294+
295+
296+@Callable(i)
297+func addSell (price) = {
298+ let nftId = value(i.payments[0].assetId)
299+ valueOrElse(isCorrectNft(nftId), if (!(isCorrectSellPrice(price)))
300+ then throw("Price must be > 0")
301+ else [setSell(nftId, i.caller, price)])
302+ }
303+
304+
305+
306+@Callable(i)
307+func addAuction (startPrice,start,end) = {
308+ let nftId = value(i.payments[0].assetId)
309+ valueOrElse(isCorrectNft(nftId), [setAuction(i.caller, nftId, startPrice, start, end), StringEntry(((toBase58String(nftId) + separator) + "nft_owner"), toString(i.caller))])
310+ }
311+
312+
313+
314+@Callable(i)
315+func buyFromSlot (nftId) = {
316+ let $t082198308 = $Tuple2(i.payments[0].assetId, value(i.payments[0].amount))
317+ let paymentAsset = $t082198308._1
318+ let paymentAmount = $t082198308._2
319+ let assetId = fromBase58String(nftId)
320+ let $t083528390 = getSlot(assetId)
321+ let type = $t083528390._1
322+ let details = $t083528390._2
323+ let baseRes = [ScriptTransfer(i.caller, 1, assetId), DeleteEntry(getSlotKey(type, assetId))]
324+ if ((type == kSell))
325+ then {
326+ let $t085328579 = parseAsSell(details)
327+ let seller = $t085328579._1
328+ let priceValue = $t085328579._2
329+ valueOrElse(isCorrectPayments(paymentAsset, paymentAmount, priceValue), {
330+ let $t086648766 = resultFundsAmounts(isTrustedNft(assetId), paymentAmount, priceValue)
331+ let sellerAmount = $t086648766._1
332+ let buyerAmount = $t086648766._2
333+ let updatedRes = (baseRes ++ [ScriptTransfer(seller, sellerAmount, unit)])
334+ if ((buyerAmount > 0))
335+ then (updatedRes ++ [ScriptTransfer(i.caller, buyerAmount, unit)])
336+ else updatedRes
337+ })
338+ }
339+ else {
340+ let $t089839052 = calcPriceAtCurrentMoment(assetId, height)
341+ let seller = $t089839052._1
342+ let actualPrice = $t089839052._2
343+ valueOrElse(isCorrectPayments(paymentAsset, paymentAmount, actualPrice), {
344+ let $t091389241 = resultFundsAmounts(isTrustedNft(assetId), paymentAmount, actualPrice)
345+ let sellerAmount = $t091389241._1
346+ let buyerAmount = $t091389241._2
347+ let updatedRes = (baseRes ++ [ScriptTransfer(seller, sellerAmount, unit)])
348+ if ((buyerAmount > 0))
349+ then (updatedRes ++ [ScriptTransfer(i.caller, buyerAmount, unit)])
350+ else updatedRes
351+ })
352+ }
353+ }
354+
355+
356+
357+@Callable(i)
358+func declineSlot (nftId) = {
359+ let assetId = fromBase58String(nftId)
360+ let $t095429580 = getSlot(assetId)
361+ let type = $t095429580._1
362+ let details = $t095429580._2
363+ let baseRes = [DeleteEntry(getSlotKey(type, assetId))]
364+ if ((type == kSell))
365+ then {
366+ let $t096729719 = parseAsSell(details)
367+ let seller = $t096729719._1
368+ let priceValue = $t096729719._2
369+ if (!(isValidCaller(i.caller, seller)))
370+ then throw("Invalid caller")
371+ else (baseRes ++ [ScriptTransfer(seller, 1, assetId)])
372+ }
373+ else {
374+ let $t098649968 = parseAsAuction(details)
375+ let seller = $t098649968._1
376+ let startPriceValue = $t098649968._2
377+ let endPriceValue = $t098649968._3
378+ let startPeriodValue = $t098649968._4
379+ let endPeriodValue = $t098649968._5
380+ if (!(isValidCaller(i.caller, seller)))
381+ then throw("Invalid caller")
382+ else if (!(isAuctionEnded(height, endPeriodValue)))
383+ then throw("Wait for end of auction")
384+ else (baseRes ++ [ScriptTransfer(seller, 1, assetId)])
385+ }
386+ }
387+
388+
389+
390+@Callable(i)
391+func setTrustedIssuer (trustedAddr) = if (!(isAdmin(i.caller)))
392+ then throw("Only admin")
393+ else [BooleanEntry(getTrustedKey(addressFromStringValue(trustedAddr)), true)]
394+
395+
396+
397+@Callable(i)
398+func getPriceAtCurrentMoment (nftId,moment) = {
399+ let assetId = fromBase58String(nftId)
400+ let $t01050910572 = calcPriceAtCurrentMoment(assetId, moment)
401+ let seller = $t01050910572._1
402+ let price = $t01050910572._2
403+[IntegerEntry(getPriceKey(assetId), price)]
67404 }
68405
69406

github/deemru/w8io/169f3d6 
56.56 ms