tx · ENQ2ao1hJpNA9UypZA39y8r1mRUPUnPzAXoom4iMoWro 3N4boZRUJ2LxY5jLyp6hmxGktqnawQidu6H: -0.11000000 Waves 2022.11.24 00:05 [2330261] smart account 3N4boZRUJ2LxY5jLyp6hmxGktqnawQidu6H > SELF 0.00000000 Waves
{ "type": 13, "id": "ENQ2ao1hJpNA9UypZA39y8r1mRUPUnPzAXoom4iMoWro", "fee": 11000000, "feeAssetId": null, "timestamp": 1669237535682, "version": 2, "chainId": 84, "sender": "3N4boZRUJ2LxY5jLyp6hmxGktqnawQidu6H", "senderPublicKey": "BDeCphaaC4MZvfmbJqQZ78EvuEBZTJ1VEW7fbxue8BUu", "proofs": [ "27cyQNr3K7SPppB4117Lh9iECht2x3yFCRvcDGwatfesRkm2ee8frSMfoVa5H4Wcx49fZJTv25opJfoXPWuzgcfX" ], "script": "base64:BgJKCAISCwoJCAgICAgBCAgIEgQKAggIEgMKAQgSAwoBARIDCgEBEg8KDQEBAQEICAgICAEICAgSAwoBCBIDCgEIEgMKAQgSBAoCCAEnAAlzZXBhcmF0b3ICAV8ACGtBdWN0aW9uAgdhdWN0aW9uAAVrU2VsbAIEc2VsbAAIa1RydXN0ZWQCB3RydXN0ZWQABmtQcmljZQIFcHJpY2UBCmdldFNsb3RLZXkCBnByZWZpeAVuZnRJZAkArAICCQCsAgIFBnByZWZpeAUJc2VwYXJhdG9yCQDYBAEFBW5mdElkAQtnZXRQcmljZUtleQEFbmZ0SWQJAKwCAgkArAICBQZrUHJpY2UFCXNlcGFyYXRvcgkA2AQBBQVuZnRJZAEKZ2V0U2VsbEtleQEFbmZ0SWQJAKwCAgkArAICBQVrU2VsbAUJc2VwYXJhdG9yCQDYBAEFBW5mdElkAQ1nZXRBdWN0aW9uS2V5AQVuZnRJZAkArAICCQCsAgIFCGtBdWN0aW9uBQlzZXBhcmF0b3IJANgEAQUFbmZ0SWQBDWdldFRydXN0ZWRLZXkBBmlzc3VlcgkArAICCQCsAgIFCGtUcnVzdGVkBQlzZXBhcmF0b3IJAKUIAQUGaXNzdWVyAQlhZGRUb0xpc3QCBWFjY3VtCW5leHRWYWx1ZQkAzggCBQVhY2N1bQkAzAgCBQluZXh0VmFsdWUFA25pbAEKam9pblN0cmluZwEGcGFyYW1zBAZsZW5ndGgJAJADAQUGcGFyYW1zAwkAAAIFBmxlbmd0aAAACQACAQINRW1wdHkgIHBhcmFtcwMJAAACBQZsZW5ndGgAAQkAuQkCCgACJGwFBnBhcmFtcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEJYWRkVG9MaXN0AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyAxCQEFJGYwXzICCQEFJGYwXzECBQUkYWNjMAAAAAEFCXNlcGFyYXRvcgMJAAACBQZsZW5ndGgAAgkAuQkCCgACJGwFBnBhcmFtcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEJYWRkVG9MaXN0AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyAyCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgUJc2VwYXJhdG9yAwkAAAIFBmxlbmd0aAADCQC5CQIKAAIkbAUGcGFyYW1zCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQlhZGRUb0xpc3QCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDMJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMFCXNlcGFyYXRvcgMJAAACBQZsZW5ndGgABAkAuQkCCgACJGwFBnBhcmFtcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEJYWRkVG9MaXN0AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA0CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQFCXNlcGFyYXRvcgMJAAACBQZsZW5ndGgABQkAuQkCCgACJGwFBnBhcmFtcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEJYWRkVG9MaXN0AgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQUJc2VwYXJhdG9yCQACAQIhTWF4IG51bWJlciBvZiBwYXJhbWV0ZXJzIGV4Y2VlZGVkAQ5wYXJzZUFzQXVjdGlvbgEHZGV0YWlscwQDcmVzCQC1CQIFB2RldGFpbHMFCXNlcGFyYXRvcgkAlwoFCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFA3JlcwAACQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDcmVzAAEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNyZXMAAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA3JlcwADCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDcmVzAAQBC3BhcnNlQXNTZWxsAQdkZXRhaWxzBANyZXMJALUJAgUHZGV0YWlscwUJc2VwYXJhdG9yCQCUCgIJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUDcmVzAAAJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNyZXMAAQEKam9pblN0cnVjdAEGcGFyYW1zBAckbWF0Y2gwBQZwYXJhbXMDCQABAgUHJG1hdGNoMAIdKEFkZHJlc3MsIEludCwgSW50LCBJbnQsIEludCkEB2F1Y3Rpb24FByRtYXRjaDAJAQpqb2luU3RyaW5nAQkAzAgCCQClCAEIBQdhdWN0aW9uAl8xCQDMCAIJAKQDAQgFB2F1Y3Rpb24CXzIJAMwIAgkApAMBCAUHYXVjdGlvbgJfMwkAzAgCCQCkAwEIBQdhdWN0aW9uAl80CQDMCAIJAKQDAQgFB2F1Y3Rpb24CXzUFA25pbAMJAAECBQckbWF0Y2gwAg4oQWRkcmVzcywgSW50KQQEc2VsbAUHJG1hdGNoMAkBCmpvaW5TdHJpbmcBCQDMCAIJAKUIAQgFBHNlbGwCXzEJAMwIAgkApAMBCAUEc2VsbAJfMgUDbmlsCQACAQITV3JvbmcgcGFyYW1zIHR1cHBsZQEKc2V0QXVjdGlvbgYGc2VsbGVyBW5mdElkCnN0YXJ0UHJpY2UIZW5kUHJpY2UFc3RhcnQDZW5kCQELU3RyaW5nRW50cnkCCQENZ2V0QXVjdGlvbktleQEFBW5mdElkCQEKam9pblN0cnVjdAEJAJcKBQUGc2VsbGVyBQpzdGFydFByaWNlBQhlbmRQcmljZQUFc3RhcnQFA2VuZAEHc2V0U2VsbAMFbmZ0SWQGY2VsbGVyBXByaWNlCQELU3RyaW5nRW50cnkCCQEKZ2V0U2VsbEtleQEFBW5mdElkCQEKam9pblN0cnVjdAEJAJQKAgUGY2VsbGVyBQVwcmljZQEKZ2V0QXVjdGlvbgEFbmZ0SWQJAQV2YWx1ZQEJAJ0IAgUEdGhpcwkBDWdldEF1Y3Rpb25LZXkBBQVuZnRJZAEHZ2V0U2VsbAEFbmZ0SWQJAQV2YWx1ZQEJAJ0IAgUEdGhpcwkBCmdldFNlbGxLZXkBBQVuZnRJZAEYY2FsY1ByaWNlQXRDdXJyZW50TW9tZW50Agdhc3NldElkBm1vbWVudAQHZGV0YWlscwkBCmdldEF1Y3Rpb24BBQdhc3NldElkBAskdDAyODE3MjkyMQkBDnBhcnNlQXNBdWN0aW9uAQUHZGV0YWlscwQGc2VsbGVyCAULJHQwMjgxNzI5MjECXzEED3N0YXJ0UHJpY2VWYWx1ZQgFCyR0MDI4MTcyOTIxAl8yBA1lbmRQcmljZVZhbHVlCAULJHQwMjgxNzI5MjECXzMEEHN0YXJ0UGVyaW9kVmFsdWUIBQskdDAyODE3MjkyMQJfNAQOZW5kUGVyaW9kVmFsdWUIBQskdDAyODE3MjkyMQJfNQMJAGcCBQZtb21lbnQFDmVuZFBlcmlvZFZhbHVlCQCUCgIFBnNlbGxlcgUNZW5kUHJpY2VWYWx1ZQQKZGVsdGFQcmljZQkAZQIFD3N0YXJ0UHJpY2VWYWx1ZQUNZW5kUHJpY2VWYWx1ZQQGcGVyaW9kCQBlAgUOZW5kUGVyaW9kVmFsdWUFEHN0YXJ0UGVyaW9kVmFsdWUEB3NwZW5kZWQJAGUCBQZtb21lbnQFEHN0YXJ0UGVyaW9kVmFsdWUJAJQKAgUGc2VsbGVyCQBlAgUPc3RhcnRQcmljZVZhbHVlCQBrAwUHc3BlbmRlZAUKZGVsdGFQcmljZQUGcGVyaW9kAQVpc05mdAEHYXNzZXRJZAQHJG1hdGNoMAkA7AcBBQdhc3NldElkAwkAAQIFByRtYXRjaDACBUFzc2V0BAV0b2tlbgUHJG1hdGNoMAMDCQAAAggFBXRva2VuCGRlY2ltYWxzAAAJAAACCAUFdG9rZW4IcXVhbnRpdHkAAQcJAAACCAUFdG9rZW4KcmVpc3N1YWJsZQcHBwEMaXNUcnVzdGVkTmZ0AQdhc3NldElkBAZpc3N1ZXIICQEFdmFsdWUBCQDsBwEFB2Fzc2V0SWQGaXNzdWVyCQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMJAQ1nZXRUcnVzdGVkS2V5AQUGaXNzdWVyBwELaXNTZWxsRXhpc3QBB2Fzc2V0SWQJAQlpc0RlZmluZWQBCQCdCAIFBHRoaXMJAQpnZXRTZWxsS2V5AQUHYXNzZXRJZAEOaXNBdWN0aW9uRXhpc3QBB2Fzc2V0SWQJAQlpc0RlZmluZWQBCQCdCAIFBHRoaXMJAQ1nZXRBdWN0aW9uS2V5AQUHYXNzZXRJZAESaXNDb3JyZWN0U2VsbFByaWNlAQVwcmljZQkAZgIFBXByaWNlAAABFmlzQ29ycmVjdEF1Y3Rpb25QZXJpb2QCBXN0YXJ0A2VuZAkAZgIFA2VuZAUFc3RhcnQBFmlzQ29ycmVjdEF1Y3Rpb25QcmljZXMCCnN0YXJ0UHJpY2UIZW5kUHJpY2UJAGYCBQpzdGFydFByaWNlBQhlbmRQcmljZQEHaXNBZG1pbgEGY2FsbGVyCQAAAgUGY2FsbGVyBQR0aGlzAQ1pc1ZhbGlkQ2FsbGVyAgZjYWxsZXIGc2VsbGVyAwkAAAIFBmNhbGxlcgUEdGhpcwYJAAACBQZjYWxsZXIFBnNlbGxlcgEOaXNBdWN0aW9uRW5kZWQCA25vdwNlbmQJAGYCBQNub3cFA2VuZAENaXNFbm91Z2hGdW5kcwIHcGF5bWVudBJjdXJyZW50TW9tZW50UHJpY2UJAGcCBQdwYXltZW50BRJjdXJyZW50TW9tZW50UHJpY2UBB2lzV2F3ZXMBB2Fzc2V0SWQJAAACBQdhc3NldElkBQR1bml0AQxpc0NvcnJlY3ROZnQBBW5mdElkAwkBASEBCQEFaXNOZnQBBQVuZnRJZAkAAgECEFRva2VuIGlzIG5vdCBOZnQDCQELaXNTZWxsRXhpc3QBBQVuZnRJZAkAAgECE1NlbGwgYWxyZWFkeSBleGlzdHMDCQEOaXNBdWN0aW9uRXhpc3QBBQVuZnRJZAkAAgECFkF1Y3Rpb24gYWxyZWFkeSBleGlzdHMFBHVuaXQBEWlzQ29ycmVjdFBheW1lbnRzAwxwYXltZW50QXNzZXQNcGF5bWVudEFtb3VudAVwcmljZQMJAQEhAQkBB2lzV2F3ZXMBBQxwYXltZW50QXNzZXQJAAIBAhhQYXltZW50IG11c3QgYmUgYXQgV0FWRVMDCQEBIQEJAQ1pc0Vub3VnaEZ1bmRzAgUNcGF5bWVudEFtb3VudAUFcHJpY2UJAAIBAhBOb3QgZW5vdWdoIGZ1bmRzBQR1bml0AQdjYWxjRmVlAAAAAQ5jYWxjVHJ1c3RlZEZlZQAAAAEScmVzdWx0RnVuZHNBbW91bnRzAwlpc1RydXN0ZWQNcGF5bWVudEFtb3VudAthY3R1YWxQcmljZQMFCWlzVHJ1c3RlZAkAlAoCCQBlAgULYWN0dWFsUHJpY2UJAQ5jYWxjVHJ1c3RlZEZlZQAJAGUCBQ1wYXltZW50QW1vdW50BQthY3R1YWxQcmljZQkAlAoCCQBlAgULYWN0dWFsUHJpY2UJAQdjYWxjRmVlAAkAZQIFDXBheW1lbnRBbW91bnQFC2FjdHVhbFByaWNlAQdnZXRTbG90AQVuZnRJZAMJAQtpc1NlbGxFeGlzdAEFBW5mdElkCQCUCgIFBWtTZWxsCQEHZ2V0U2VsbAEFBW5mdElkAwkBDmlzQXVjdGlvbkV4aXN0AQUFbmZ0SWQJAJQKAgUIa0F1Y3Rpb24JAQpnZXRBdWN0aW9uAQUFbmZ0SWQJAAIBAhJTbG90IGRvZXNuYHQgZXhpc3QABGtCdXkCA2J1eQoBaQEJY3JlYXRlTmZ0CQhuZnRfbmFtZQluZnRfb3duZXIPbmZ0X2RBcHBBZGRyZXNzCG5mdF90eXBlCG5mdF90YWdzEW5mdF9zZWxsaW5nX3ByaWNlD25mdF9kZXNjcmlwdGlvbgpuZnRfb25TZWxsCG5mdF9kYXRhBAhuZXdUb2tlbgkAwggFBQhuZnRfbmFtZQUPbmZ0X2Rlc2NyaXB0aW9uAAEAAAcEB2lzc3VlSWQJALgIAQUIbmV3VG9rZW4JAMwIAgUIbmV3VG9rZW4JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyAAEFB2lzc3VlSWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJANgEAQUHaXNzdWVJZAUJc2VwYXJhdG9yAgVPd25lcgkApQgBCAUBaQZjYWxsZXIJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJANgEAQUHaXNzdWVJZAUJc2VwYXJhdG9yAghuZnRfdHlwZQUIbmZ0X3R5cGUJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJANgEAQUHaXNzdWVJZAUJc2VwYXJhdG9yAghuZnRfdGFncwUIbmZ0X3RhZ3MJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJANgEAQUHaXNzdWVJZAUJc2VwYXJhdG9yAg9uZnRfZEFwcEFkZHJlc3MFD25mdF9kQXBwQWRkcmVzcwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJANgEAQUHaXNzdWVJZAUJc2VwYXJhdG9yAhFuZnRfc2VsbGluZ19wcmljZQURbmZ0X3NlbGxpbmdfcHJpY2UJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJANgEAQUHaXNzdWVJZAUJc2VwYXJhdG9yAgpuZnRfb25TZWxsBQpuZnRfb25TZWxsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgkArAICCQDYBAEFB2lzc3VlSWQFCXNlcGFyYXRvcgIIbmZ0X2RhdGEFCG5mdF9kYXRhBQNuaWwBaQEIaXNzdWVOZnQCBG5hbWUEbWV0YQQIbmV3VG9rZW4JAMIIBQUEbmFtZQUEbWV0YQABAAAHBAdpc3N1ZUlkCQC4CAEFCG5ld1Rva2VuCQDMCAIFCG5ld1Rva2VuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgABBQdpc3N1ZUlkCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgkArAICCQDYBAEFB2lzc3VlSWQFCXNlcGFyYXRvcgIFT3duZXIJAKUIAQgFAWkGY2FsbGVyBQNuaWwBaQEGYnV5TkZUAQVuZnRJRAQHYXNzZXRJZAkA2QQBBQVuZnRJRAQGYW1vdW50CQEFdmFsdWUBCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAQFcHJpY2UJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQCsAgIJAKwCAgUGa1ByaWNlBQlzZXBhcmF0b3IFBW5mdElEAh5UaGVyZSBpcyBubyBwcmljZSBmb3IgdGhpcyBORlQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJARFAZXh0ck5hdGl2ZSgxMDU4KQEJAKwCAgkArAICBQVuZnRJRAUJc2VwYXJhdG9yAgVPd25lcgIITm8gb3duZXIDCQECIT0CCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQFBHVuaXQJAAIBAgxQYXkgaW4gd2F2ZXMDCQBmAgkBDXBhcnNlSW50VmFsdWUBBQVwcmljZQUGYW1vdW50CQACAQIPSW52YWxpZCBwYXltZW50CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgABBQdhc3NldElkCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJAQV2YWx1ZQEJAKYIAQUFb3duZXIJAQ1wYXJzZUludFZhbHVlAQUFcHJpY2UFBHVuaXQJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJAKUIAQgFAWkGY2FsbGVyBQlzZXBhcmF0b3IFBGtCdXkJAKwCAgkArAICBQVuZnRJRAUJc2VwYXJhdG9yCQCkAwEFBmFtb3VudAUDbmlsAWkBB3NlbGxORlQBBXByaWNlBAskdDA3MzM5NzQyNAkAlAoCCQEFdmFsdWUBCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQJAQV2YWx1ZQEICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BAZ0b2tlbjAIBQskdDA3MzM5NzQyNAJfMQQHYW1vdW50MAgFCyR0MDczMzk3NDI0Al8yAwkBASEBCQEFaXNOZnQBBQZ0b2tlbjAJAAIBAhBUb2tlbiBpcyBub3QgTkZUCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgkArAICBQZrUHJpY2UFCXNlcGFyYXRvcgkA2AQBCQEFdmFsdWUBCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQJAKQDAQUFcHJpY2UJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJAKUIAQgFAWkGY2FsbGVyBQlzZXBhcmF0b3IFBWtTZWxsCQCsAgIJAKwCAgkA2AQBBQZ0b2tlbjAFCXNlcGFyYXRvcgkApAMBBQdhbW91bnQwBQNuaWwBaQEHYWRkU2VsbAEFcHJpY2UEBW5mdElkCQEFdmFsdWUBCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQJAQt2YWx1ZU9yRWxzZQIJAQxpc0NvcnJlY3ROZnQBBQVuZnRJZAMJAQEhAQkBEmlzQ29ycmVjdFNlbGxQcmljZQEFBXByaWNlCQACAQIRUHJpY2UgbXVzdCBiZSA+IDAJAMwIAgkBB3NldFNlbGwDBQVuZnRJZAgFAWkGY2FsbGVyBQVwcmljZQUDbmlsAWkBCmFkZEF1Y3Rpb24NCnN0YXJ0UHJpY2UIZW5kUHJpY2UFc3RhcnQDZW5kCG5mdF9uYW1lCW5mdF9vd25lcg9uZnRfZEFwcEFkZHJlc3MIbmZ0X3R5cGUIbmZ0X3RhZ3MRbmZ0X3NlbGxpbmdfcHJpY2UPbmZ0X2Rlc2NyaXB0aW9uCm5mdF9vblNlbGwIbmZ0X2RhdGEEBW5mdElkCQEFdmFsdWUBCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQJAQt2YWx1ZU9yRWxzZQIJAQxpc0NvcnJlY3ROZnQBBQVuZnRJZAMJAQEhAQkBFmlzQ29ycmVjdEF1Y3Rpb25QZXJpb2QCBQVzdGFydAUDZW5kCQACAQIVUGVyaW9kIGlzIG5vdCBjb3JyZWN0AwkBASEBCQEWaXNDb3JyZWN0QXVjdGlvblByaWNlcwIFCnN0YXJ0UHJpY2UFCGVuZFByaWNlCQACAQIeU3RhcnQgcHJpY2UgbXVzdCBiZSA+IGVuZFByaWNlCQDMCAIJAQpzZXRBdWN0aW9uBggFAWkGY2FsbGVyBQVuZnRJZAUKc3RhcnRQcmljZQUIZW5kUHJpY2UFBXN0YXJ0BQNlbmQJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJANgEAQUFbmZ0SWQFCXNlcGFyYXRvcgIJbmZ0X293bmVyCQClCAEIBQFpBmNhbGxlcgkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgkA2AQBBQVuZnRJZAUJc2VwYXJhdG9yAghuZnRfdHlwZQUIbmZ0X3R5cGUJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJANgEAQUFbmZ0SWQFCXNlcGFyYXRvcgIIbmZ0X3RhZ3MFCG5mdF90YWdzCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgkArAICCQDYBAEFBW5mdElkBQlzZXBhcmF0b3ICD25mdF9kQXBwQWRkcmVzcwUPbmZ0X2RBcHBBZGRyZXNzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkA2AQBBQVuZnRJZAUJc2VwYXJhdG9yAhFuZnRfc2VsbGluZ19wcmljZQURbmZ0X3NlbGxpbmdfcHJpY2UJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJANgEAQUFbmZ0SWQFCXNlcGFyYXRvcgIKbmZ0X29uU2VsbAUKbmZ0X29uU2VsbAkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgkA2AQBBQVuZnRJZAUJc2VwYXJhdG9yAghuZnRfZGF0YQUIbmZ0X2RhdGEFA25pbAFpAQtidXlGcm9tU2xvdAEFbmZ0SWQECyR0MDkyMjQ5MzEzCQCUCgIICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAkBBXZhbHVlAQgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQEDHBheW1lbnRBc3NldAgFCyR0MDkyMjQ5MzEzAl8xBA1wYXltZW50QW1vdW50CAULJHQwOTIyNDkzMTMCXzIEB2Fzc2V0SWQJANkEAQUFbmZ0SWQECyR0MDkzNTc5Mzk1CQEHZ2V0U2xvdAEFB2Fzc2V0SWQEBHR5cGUIBQskdDA5MzU3OTM5NQJfMQQHZGV0YWlscwgFCyR0MDkzNTc5Mzk1Al8yBAdiYXNlUmVzCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgABBQdhc3NldElkCQDMCAIJAQtEZWxldGVFbnRyeQEJAQpnZXRTbG90S2V5AgUEdHlwZQUHYXNzZXRJZAUDbmlsAwkAAAIFBHR5cGUFBWtTZWxsBAskdDA5NTM3OTU4NAkBC3BhcnNlQXNTZWxsAQUHZGV0YWlscwQGc2VsbGVyCAULJHQwOTUzNzk1ODQCXzEECnByaWNlVmFsdWUIBQskdDA5NTM3OTU4NAJfMgkBC3ZhbHVlT3JFbHNlAgkBEWlzQ29ycmVjdFBheW1lbnRzAwUMcGF5bWVudEFzc2V0BQ1wYXltZW50QW1vdW50BQpwcmljZVZhbHVlBAskdDA5NjY5OTc3MQkBEnJlc3VsdEZ1bmRzQW1vdW50cwMJAQxpc1RydXN0ZWROZnQBBQdhc3NldElkBQ1wYXltZW50QW1vdW50BQpwcmljZVZhbHVlBAxzZWxsZXJBbW91bnQIBQskdDA5NjY5OTc3MQJfMQQLYnV5ZXJBbW91bnQIBQskdDA5NjY5OTc3MQJfMgQKdXBkYXRlZFJlcwkAzggCBQdiYXNlUmVzCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFBnNlbGxlcgUMc2VsbGVyQW1vdW50BQR1bml0BQNuaWwDCQBmAgULYnV5ZXJBbW91bnQAAAkAzggCBQp1cGRhdGVkUmVzCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgULYnV5ZXJBbW91bnQFBHVuaXQFA25pbAUKdXBkYXRlZFJlcwQMJHQwOTk4ODEwMDU3CQEYY2FsY1ByaWNlQXRDdXJyZW50TW9tZW50AgUHYXNzZXRJZAUGaGVpZ2h0BAZzZWxsZXIIBQwkdDA5OTg4MTAwNTcCXzEEC2FjdHVhbFByaWNlCAUMJHQwOTk4ODEwMDU3Al8yCQELdmFsdWVPckVsc2UCCQERaXNDb3JyZWN0UGF5bWVudHMDBQxwYXltZW50QXNzZXQFDXBheW1lbnRBbW91bnQFC2FjdHVhbFByaWNlBA0kdDAxMDE0MzEwMjQ2CQEScmVzdWx0RnVuZHNBbW91bnRzAwkBDGlzVHJ1c3RlZE5mdAEFB2Fzc2V0SWQFDXBheW1lbnRBbW91bnQFC2FjdHVhbFByaWNlBAxzZWxsZXJBbW91bnQIBQ0kdDAxMDE0MzEwMjQ2Al8xBAtidXllckFtb3VudAgFDSR0MDEwMTQzMTAyNDYCXzIECnVwZGF0ZWRSZXMJAM4IAgUHYmFzZVJlcwkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQZzZWxsZXIFDHNlbGxlckFtb3VudAUEdW5pdAUDbmlsAwkAZgIFC2J1eWVyQW1vdW50AAAJAM4IAgUKdXBkYXRlZFJlcwkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFC2J1eWVyQW1vdW50BQR1bml0BQNuaWwFCnVwZGF0ZWRSZXMBaQELZGVjbGluZVNsb3QBBW5mdElkBAdhc3NldElkCQDZBAEFBW5mdElkBA0kdDAxMDU0NzEwNTg1CQEHZ2V0U2xvdAEFB2Fzc2V0SWQEBHR5cGUIBQ0kdDAxMDU0NzEwNTg1Al8xBAdkZXRhaWxzCAUNJHQwMTA1NDcxMDU4NQJfMgQHYmFzZVJlcwkAzAgCCQELRGVsZXRlRW50cnkBCQEKZ2V0U2xvdEtleQIFBHR5cGUFB2Fzc2V0SWQFA25pbAMJAAACBQR0eXBlBQVrU2VsbAQNJHQwMTA2NzcxMDcyNAkBC3BhcnNlQXNTZWxsAQUHZGV0YWlscwQGc2VsbGVyCAUNJHQwMTA2NzcxMDcyNAJfMQQKcHJpY2VWYWx1ZQgFDSR0MDEwNjc3MTA3MjQCXzIDCQEBIQEJAQ1pc1ZhbGlkQ2FsbGVyAggFAWkGY2FsbGVyBQZzZWxsZXIJAAIBAg5JbnZhbGlkIGNhbGxlcgkAzggCBQdiYXNlUmVzCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFBnNlbGxlcgABBQdhc3NldElkBQNuaWwEDSR0MDEwODY5MTA5NzMJAQ5wYXJzZUFzQXVjdGlvbgEFB2RldGFpbHMEBnNlbGxlcggFDSR0MDEwODY5MTA5NzMCXzEED3N0YXJ0UHJpY2VWYWx1ZQgFDSR0MDEwODY5MTA5NzMCXzIEDWVuZFByaWNlVmFsdWUIBQ0kdDAxMDg2OTEwOTczAl8zBBBzdGFydFBlcmlvZFZhbHVlCAUNJHQwMTA4NjkxMDk3MwJfNAQOZW5kUGVyaW9kVmFsdWUIBQ0kdDAxMDg2OTEwOTczAl81AwkBASEBCQENaXNWYWxpZENhbGxlcgIIBQFpBmNhbGxlcgUGc2VsbGVyCQACAQIOSW52YWxpZCBjYWxsZXIDCQEBIQEJAQ5pc0F1Y3Rpb25FbmRlZAIFBmhlaWdodAUOZW5kUGVyaW9kVmFsdWUJAAIBAhdXYWl0IGZvciBlbmQgb2YgYXVjdGlvbgkAzggCBQdiYXNlUmVzCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFBnNlbGxlcgABBQdhc3NldElkBQNuaWwBaQEQc2V0VHJ1c3RlZElzc3VlcgELdHJ1c3RlZEFkZHIDCQEBIQEJAQdpc0FkbWluAQgFAWkGY2FsbGVyCQACAQIKT25seSBhZG1pbgkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBDWdldFRydXN0ZWRLZXkBCQERQGV4dHJOYXRpdmUoMTA2MikBBQt0cnVzdGVkQWRkcgYFA25pbAFpARdnZXRQcmljZUF0Q3VycmVudE1vbWVudAIFbmZ0SWQGbW9tZW50BAdhc3NldElkCQDZBAEFBW5mdElkBA0kdDAxMTUxNDExNTc3CQEYY2FsY1ByaWNlQXRDdXJyZW50TW9tZW50AgUHYXNzZXRJZAUGbW9tZW50BAZzZWxsZXIIBQ0kdDAxMTUxNDExNTc3Al8xBAVwcmljZQgFDSR0MDExNTE0MTE1NzcCXzIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQtnZXRQcmljZUtleQEFB2Fzc2V0SWQFBXByaWNlBQNuaWwAGlPK6A==", "height": 2330261, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: C29sZqbiKokMsyK3hgu9fiTajxeVFcZe9xA2khe2pFih Next: GeUcjWtmgZrK1ehsDty2hQyQsh75yvQR5wXgM73MNewk Diff:
Old | New | Differences | |
---|---|---|---|
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let separator = "_" | |
5 | 5 | ||
6 | - | let | |
6 | + | let kAuction = "auction" | |
7 | 7 | ||
8 | - | let | |
8 | + | let kSell = "sell" | |
9 | 9 | ||
10 | - | let kStatus = "status" | |
11 | - | ||
12 | - | let kOwner = "owner" | |
10 | + | let kTrusted = "trusted" | |
13 | 11 | ||
14 | 12 | let kPrice = "price" | |
15 | 13 | ||
16 | - | let kRating = "rating" | |
17 | - | ||
18 | - | let CREATE_STATUS = "create" | |
19 | - | ||
20 | - | let COMPLETED_STATUS = "completed" | |
21 | - | ||
22 | - | let IN_WORK = "in_work" | |
23 | - | ||
24 | - | let WAITING_FOR_CONFIRMATION_STATUS = "waiting_for_Confirmation" | |
25 | - | ||
26 | - | let ANYS_SUGGESTION_STATUS = "any_suggestions" | |
27 | - | ||
28 | - | let WAVES = 100000000 | |
29 | - | ||
30 | - | func getPriceKey (incomingAddress,name) = makeString([toString(incomingAddress), name, kPrice], separator) | |
14 | + | func getSlotKey (prefix,nftId) = ((prefix + separator) + toBase58String(nftId)) | |
31 | 15 | ||
32 | 16 | ||
33 | - | func | |
17 | + | func getPriceKey (nftId) = ((kPrice + separator) + toBase58String(nftId)) | |
34 | 18 | ||
35 | 19 | ||
36 | - | func | |
20 | + | func getSellKey (nftId) = ((kSell + separator) + toBase58String(nftId)) | |
37 | 21 | ||
38 | 22 | ||
39 | - | func | |
23 | + | func getAuctionKey (nftId) = ((kAuction + separator) + toBase58String(nftId)) | |
40 | 24 | ||
41 | 25 | ||
42 | - | func | |
26 | + | func getTrustedKey (issuer) = ((kTrusted + separator) + toString(issuer)) | |
43 | 27 | ||
44 | 28 | ||
45 | - | func | |
29 | + | func addToList (accum,nextValue) = (accum ++ [nextValue]) | |
46 | 30 | ||
47 | 31 | ||
48 | - | func getExecutorRaitingKey (incomingAddress) = makeString([toString(incomingAddress), kExecutor, kRating], separator) | |
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 | + | } | |
49 | 113 | ||
50 | 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, Int, Int, Int) => | |
129 | + | joinString([toString(auction._1), toString(auction._2), toString(auction._3), toString(auction._4), toString(auction._5)]) | |
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,endPrice,start,end) = StringEntry(getAuctionKey(nftId), joinStruct($Tuple5(seller, startPrice, endPrice, 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 $t028172921 = parseAsAuction(details) | |
152 | + | let seller = $t028172921._1 | |
153 | + | let startPriceValue = $t028172921._2 | |
154 | + | let endPriceValue = $t028172921._3 | |
155 | + | let startPeriodValue = $t028172921._4 | |
156 | + | let endPeriodValue = $t028172921._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 | + | ||
167 | + | ||
168 | + | func isNft (assetId) = match assetInfo(assetId) { | |
169 | + | case token: Asset => | |
170 | + | if (if ((token.decimals == 0)) | |
171 | + | then (token.quantity == 1) | |
172 | + | else false) | |
173 | + | then (token.reissuable == false) | |
174 | + | else false | |
175 | + | case _ => | |
176 | + | false | |
177 | + | } | |
178 | + | ||
179 | + | ||
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 isCorrectAuctionPeriod (start,end) = (end > start) | |
196 | + | ||
197 | + | ||
198 | + | func isCorrectAuctionPrices (startPrice,endPrice) = (startPrice > endPrice) | |
199 | + | ||
200 | + | ||
201 | + | func isAdmin (caller) = (caller == this) | |
202 | + | ||
203 | + | ||
204 | + | func isValidCaller (caller,seller) = if ((caller == this)) | |
205 | + | then true | |
206 | + | else (caller == seller) | |
207 | + | ||
208 | + | ||
209 | + | func isAuctionEnded (now,end) = (now > end) | |
210 | + | ||
211 | + | ||
212 | + | func isEnoughFunds (payment,currentMomentPrice) = (payment >= currentMomentPrice) | |
213 | + | ||
214 | + | ||
215 | + | func isWawes (assetId) = (assetId == unit) | |
216 | + | ||
217 | + | ||
218 | + | func isCorrectNft (nftId) = if (!(isNft(nftId))) | |
219 | + | then throw("Token is not Nft") | |
220 | + | else if (isSellExist(nftId)) | |
221 | + | then throw("Sell already exists") | |
222 | + | else if (isAuctionExist(nftId)) | |
223 | + | then throw("Auction already exists") | |
224 | + | else unit | |
225 | + | ||
226 | + | ||
227 | + | func isCorrectPayments (paymentAsset,paymentAmount,price) = if (!(isWawes(paymentAsset))) | |
228 | + | then throw("Payment must be at WAVES") | |
229 | + | else if (!(isEnoughFunds(paymentAmount, price))) | |
230 | + | then throw("Not enough funds") | |
231 | + | else unit | |
232 | + | ||
233 | + | ||
234 | + | func calcFee () = 0 | |
235 | + | ||
236 | + | ||
237 | + | func calcTrustedFee () = 0 | |
238 | + | ||
239 | + | ||
240 | + | func resultFundsAmounts (isTrusted,paymentAmount,actualPrice) = if (isTrusted) | |
241 | + | then $Tuple2((actualPrice - calcTrustedFee()), (paymentAmount - actualPrice)) | |
242 | + | else $Tuple2((actualPrice - calcFee()), (paymentAmount - actualPrice)) | |
243 | + | ||
244 | + | ||
245 | + | func getSlot (nftId) = if (isSellExist(nftId)) | |
246 | + | then $Tuple2(kSell, getSell(nftId)) | |
247 | + | else if (isAuctionExist(nftId)) | |
248 | + | then $Tuple2(kAuction, getAuction(nftId)) | |
249 | + | else throw("Slot doesn`t exist") | |
250 | + | ||
251 | + | ||
252 | + | let kBuy = "buy" | |
253 | + | ||
51 | 254 | @Callable(i) | |
52 | - | func createOrder (price,desc,name) = { | |
53 | - | let $t015151591 = $Tuple2(i.payments[0].assetId, value(i.payments[0].amount)) | |
54 | - | let token = $t015151591._1 | |
55 | - | let amount0 = $t015151591._2 | |
56 | - | let descKey = getDescKey(i.caller, name) | |
57 | - | let priceKey = getPriceKey(i.caller, name) | |
58 | - | let statusKey = getStatusKey(i.caller, name, kCustomer) | |
59 | - | let ownerKey = getOwnerKey(i.caller, name) | |
60 | - | if ((token != unit)) | |
61 | - | then throw("Pay in waves") | |
62 | - | else if (((WAVES + price) > amount0)) | |
63 | - | then throw("The cost of placing an order 1 waves + amount") | |
64 | - | else [StringEntry(descKey, desc), StringEntry(ownerKey, toString(i.caller)), IntegerEntry(priceKey, price), StringEntry(statusKey, CREATE_STATUS)] | |
255 | + | func createNft (nft_name,nft_owner,nft_dAppAddress,nft_type,nft_tags,nft_selling_price,nft_description,nft_onSell,nft_data) = { | |
256 | + | let newToken = Issue(nft_name, nft_description, 1, 0, false) | |
257 | + | let issueId = calculateAssetId(newToken) | |
258 | + | [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)] | |
65 | 259 | } | |
66 | 260 | ||
67 | 261 | ||
68 | 262 | ||
69 | 263 | @Callable(i) | |
70 | - | func cancelOrder (name) = [DeleteEntry(getDescKey(i.caller, name)), DeleteEntry(getPriceKey(i.caller, name)), DeleteEntry(getStatusKey(i.caller, name, kCustomer)), DeleteEntry(getOwnerKey(i.caller, name))] | |
71 | - | ||
72 | - | ||
73 | - | ||
74 | - | @Callable(i) | |
75 | - | func confirmOffer (name,address,desc) = { | |
76 | - | let isExist = getString(this, getExecutorAddressKey(i.caller, name)) | |
77 | - | let owner = valueOrErrorMessage(getStringValue(this, getOwnerKey(i.caller, name)), "This order does not exist") | |
78 | - | if ((owner != toString(i.caller))) | |
79 | - | then throw("You are not the order owner") | |
80 | - | else if (isDefined(isExist)) | |
81 | - | then [StringEntry(getStatusKey(i.caller, name, kCustomer), IN_WORK), StringEntry(getStatusKey(value(addressFromString(address)), name, kExecutor), IN_WORK)] | |
82 | - | else throw("This offer does not exist") | |
264 | + | func issueNft (name,meta) = { | |
265 | + | let newToken = Issue(name, meta, 1, 0, false) | |
266 | + | let issueId = calculateAssetId(newToken) | |
267 | + | [newToken, ScriptTransfer(i.caller, 1, issueId), StringEntry(((toBase58String(issueId) + separator) + "Owner"), toString(i.caller))] | |
83 | 268 | } | |
84 | 269 | ||
85 | 270 | ||
86 | 271 | ||
87 | 272 | @Callable(i) | |
88 | - | func taskDoneCustomer (name,address) = { | |
89 | - | let customerRating = valueOrElse(getInteger(this, getCustomerRaitingKey(i.caller)), 0) | |
90 | - | let executorRating = valueOrElse(getInteger(this, getExecutorRaitingKey(value(addressFromString(address)))), 0) | |
91 | - | let amount = valueOrErrorMessage(getIntegerValue(this, getPriceKey(i.caller, name)), "No order price") | |
92 | - | let owner = valueOrErrorMessage(getStringValue(this, getOwnerKey(i.caller, name)), "This order does not exist") | |
93 | - | if ((owner != toString(i.caller))) | |
94 | - | then throw("You are not the order owner") | |
95 | - | else [StringEntry(getStatusKey(value(addressFromString(address)), name, kExecutor), COMPLETED_STATUS), StringEntry(getStatusKey(i.caller, name, kCustomer), COMPLETED_STATUS), ScriptTransfer(value(addressFromString(address)), amount, unit), IntegerEntry(getCustomerRaitingKey(i.caller), (customerRating + 1)), IntegerEntry(getExecutorRaitingKey(value(addressFromString(address))), (executorRating + 1))] | |
273 | + | func buyNFT (nftID) = { | |
274 | + | let assetId = fromBase58String(nftID) | |
275 | + | let amount = value(i.payments[0].amount) | |
276 | + | let price = valueOrErrorMessage(getString(((kPrice + separator) + nftID)), "There is no price for this NFT") | |
277 | + | let owner = valueOrErrorMessage(getStringValue(((nftID + separator) + "Owner")), "No owner") | |
278 | + | if ((i.payments[0].assetId != unit)) | |
279 | + | then throw("Pay in waves") | |
280 | + | else if ((parseIntValue(price) > amount)) | |
281 | + | then throw("Invalid payment") | |
282 | + | else [ScriptTransfer(i.caller, 1, assetId), ScriptTransfer(value(addressFromString(owner)), parseIntValue(price), unit), StringEntry(((toString(i.caller) + separator) + kBuy), ((nftID + separator) + toString(amount)))] | |
96 | 283 | } | |
97 | 284 | ||
98 | 285 | ||
99 | 286 | ||
100 | 287 | @Callable(i) | |
101 | - | func offer (name,address,desc) = { | |
102 | - | let isExist = valueOrErrorMessage(getString(this, getDescKey(value(addressFromString(address)), name)), "This order does not exist") | |
103 | - | if ((isExist == isExist)) | |
104 | - | then [StringEntry(getExecutorAddressKey(value(addressFromString(address)), name), toString(i.caller)), StringEntry(getDescKey(i.caller, name), desc), StringEntry(getStatusKey(value(addressFromString(address)), name, kCustomer), ANYS_SUGGESTION_STATUS), StringEntry(getStatusKey(i.caller, name, kExecutor), CREATE_STATUS)] | |
105 | - | else throw("Strict value is not equal to itself.") | |
288 | + | func sellNFT (price) = { | |
289 | + | let $t073397424 = $Tuple2(value(i.payments[0].assetId), value(i.payments[0].amount)) | |
290 | + | let token0 = $t073397424._1 | |
291 | + | let amount0 = $t073397424._2 | |
292 | + | if (!(isNft(token0))) | |
293 | + | then throw("Token is not NFT") | |
294 | + | else [StringEntry(((kPrice + separator) + toBase58String(value(i.payments[0].assetId))), toString(price)), StringEntry(((toString(i.caller) + separator) + kSell), ((toBase58String(token0) + separator) + toString(amount0)))] | |
106 | 295 | } | |
107 | 296 | ||
108 | 297 | ||
109 | 298 | ||
110 | 299 | @Callable(i) | |
111 | - | func taskDone (name,address) = { | |
112 | - | let desc = getString(this, getDescKey(value(addressFromString(address)), name)) | |
113 | - | let customerTask = valueOrElse(getStringValue(this, getExecutorAddressKey(value(addressFromString(address)), name)), "null") | |
114 | - | if ((toString(i.caller) != customerTask)) | |
115 | - | then throw("You are not the performer of this task") | |
116 | - | else if (isDefined(desc)) | |
117 | - | then [StringEntry(getStatusKey(value(addressFromString(address)), name, kCustomer), WAITING_FOR_CONFIRMATION_STATUS)] | |
118 | - | else throw("This order does not exist") | |
300 | + | func addSell (price) = { | |
301 | + | let nftId = value(i.payments[0].assetId) | |
302 | + | valueOrElse(isCorrectNft(nftId), if (!(isCorrectSellPrice(price))) | |
303 | + | then throw("Price must be > 0") | |
304 | + | else [setSell(nftId, i.caller, price)]) | |
305 | + | } | |
306 | + | ||
307 | + | ||
308 | + | ||
309 | + | @Callable(i) | |
310 | + | func addAuction (startPrice,endPrice,start,end,nft_name,nft_owner,nft_dAppAddress,nft_type,nft_tags,nft_selling_price,nft_description,nft_onSell,nft_data) = { | |
311 | + | let nftId = value(i.payments[0].assetId) | |
312 | + | valueOrElse(isCorrectNft(nftId), if (!(isCorrectAuctionPeriod(start, end))) | |
313 | + | then throw("Period is not correct") | |
314 | + | else if (!(isCorrectAuctionPrices(startPrice, endPrice))) | |
315 | + | then throw("Start price must be > endPrice") | |
316 | + | else [setAuction(i.caller, nftId, startPrice, endPrice, start, end), StringEntry(((toBase58String(nftId) + separator) + "nft_owner"), toString(i.caller)), StringEntry(((toBase58String(nftId) + separator) + "nft_type"), nft_type), StringEntry(((toBase58String(nftId) + separator) + "nft_tags"), nft_tags), StringEntry(((toBase58String(nftId) + separator) + "nft_dAppAddress"), nft_dAppAddress), IntegerEntry(((toBase58String(nftId) + separator) + "nft_selling_price"), nft_selling_price), StringEntry(((toBase58String(nftId) + separator) + "nft_onSell"), nft_onSell), StringEntry(((toBase58String(nftId) + separator) + "nft_data"), nft_data)]) | |
317 | + | } | |
318 | + | ||
319 | + | ||
320 | + | ||
321 | + | @Callable(i) | |
322 | + | func buyFromSlot (nftId) = { | |
323 | + | let $t092249313 = $Tuple2(i.payments[0].assetId, value(i.payments[0].amount)) | |
324 | + | let paymentAsset = $t092249313._1 | |
325 | + | let paymentAmount = $t092249313._2 | |
326 | + | let assetId = fromBase58String(nftId) | |
327 | + | let $t093579395 = getSlot(assetId) | |
328 | + | let type = $t093579395._1 | |
329 | + | let details = $t093579395._2 | |
330 | + | let baseRes = [ScriptTransfer(i.caller, 1, assetId), DeleteEntry(getSlotKey(type, assetId))] | |
331 | + | if ((type == kSell)) | |
332 | + | then { | |
333 | + | let $t095379584 = parseAsSell(details) | |
334 | + | let seller = $t095379584._1 | |
335 | + | let priceValue = $t095379584._2 | |
336 | + | valueOrElse(isCorrectPayments(paymentAsset, paymentAmount, priceValue), { | |
337 | + | let $t096699771 = resultFundsAmounts(isTrustedNft(assetId), paymentAmount, priceValue) | |
338 | + | let sellerAmount = $t096699771._1 | |
339 | + | let buyerAmount = $t096699771._2 | |
340 | + | let updatedRes = (baseRes ++ [ScriptTransfer(seller, sellerAmount, unit)]) | |
341 | + | if ((buyerAmount > 0)) | |
342 | + | then (updatedRes ++ [ScriptTransfer(i.caller, buyerAmount, unit)]) | |
343 | + | else updatedRes | |
344 | + | }) | |
345 | + | } | |
346 | + | else { | |
347 | + | let $t0998810057 = calcPriceAtCurrentMoment(assetId, height) | |
348 | + | let seller = $t0998810057._1 | |
349 | + | let actualPrice = $t0998810057._2 | |
350 | + | valueOrElse(isCorrectPayments(paymentAsset, paymentAmount, actualPrice), { | |
351 | + | let $t01014310246 = resultFundsAmounts(isTrustedNft(assetId), paymentAmount, actualPrice) | |
352 | + | let sellerAmount = $t01014310246._1 | |
353 | + | let buyerAmount = $t01014310246._2 | |
354 | + | let updatedRes = (baseRes ++ [ScriptTransfer(seller, sellerAmount, unit)]) | |
355 | + | if ((buyerAmount > 0)) | |
356 | + | then (updatedRes ++ [ScriptTransfer(i.caller, buyerAmount, unit)]) | |
357 | + | else updatedRes | |
358 | + | }) | |
359 | + | } | |
360 | + | } | |
361 | + | ||
362 | + | ||
363 | + | ||
364 | + | @Callable(i) | |
365 | + | func declineSlot (nftId) = { | |
366 | + | let assetId = fromBase58String(nftId) | |
367 | + | let $t01054710585 = getSlot(assetId) | |
368 | + | let type = $t01054710585._1 | |
369 | + | let details = $t01054710585._2 | |
370 | + | let baseRes = [DeleteEntry(getSlotKey(type, assetId))] | |
371 | + | if ((type == kSell)) | |
372 | + | then { | |
373 | + | let $t01067710724 = parseAsSell(details) | |
374 | + | let seller = $t01067710724._1 | |
375 | + | let priceValue = $t01067710724._2 | |
376 | + | if (!(isValidCaller(i.caller, seller))) | |
377 | + | then throw("Invalid caller") | |
378 | + | else (baseRes ++ [ScriptTransfer(seller, 1, assetId)]) | |
379 | + | } | |
380 | + | else { | |
381 | + | let $t01086910973 = parseAsAuction(details) | |
382 | + | let seller = $t01086910973._1 | |
383 | + | let startPriceValue = $t01086910973._2 | |
384 | + | let endPriceValue = $t01086910973._3 | |
385 | + | let startPeriodValue = $t01086910973._4 | |
386 | + | let endPeriodValue = $t01086910973._5 | |
387 | + | if (!(isValidCaller(i.caller, seller))) | |
388 | + | then throw("Invalid caller") | |
389 | + | else if (!(isAuctionEnded(height, endPeriodValue))) | |
390 | + | then throw("Wait for end of auction") | |
391 | + | else (baseRes ++ [ScriptTransfer(seller, 1, assetId)]) | |
392 | + | } | |
393 | + | } | |
394 | + | ||
395 | + | ||
396 | + | ||
397 | + | @Callable(i) | |
398 | + | func setTrustedIssuer (trustedAddr) = if (!(isAdmin(i.caller))) | |
399 | + | then throw("Only admin") | |
400 | + | else [BooleanEntry(getTrustedKey(addressFromStringValue(trustedAddr)), true)] | |
401 | + | ||
402 | + | ||
403 | + | ||
404 | + | @Callable(i) | |
405 | + | func getPriceAtCurrentMoment (nftId,moment) = { | |
406 | + | let assetId = fromBase58String(nftId) | |
407 | + | let $t01151411577 = calcPriceAtCurrentMoment(assetId, moment) | |
408 | + | let seller = $t01151411577._1 | |
409 | + | let price = $t01151411577._2 | |
410 | + | [IntegerEntry(getPriceKey(assetId), price)] | |
119 | 411 | } | |
120 | 412 | ||
121 | 413 |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 6 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let separator = "_" | |
5 | 5 | ||
6 | - | let | |
6 | + | let kAuction = "auction" | |
7 | 7 | ||
8 | - | let | |
8 | + | let kSell = "sell" | |
9 | 9 | ||
10 | - | let kStatus = "status" | |
11 | - | ||
12 | - | let kOwner = "owner" | |
10 | + | let kTrusted = "trusted" | |
13 | 11 | ||
14 | 12 | let kPrice = "price" | |
15 | 13 | ||
16 | - | let kRating = "rating" | |
17 | - | ||
18 | - | let CREATE_STATUS = "create" | |
19 | - | ||
20 | - | let COMPLETED_STATUS = "completed" | |
21 | - | ||
22 | - | let IN_WORK = "in_work" | |
23 | - | ||
24 | - | let WAITING_FOR_CONFIRMATION_STATUS = "waiting_for_Confirmation" | |
25 | - | ||
26 | - | let ANYS_SUGGESTION_STATUS = "any_suggestions" | |
27 | - | ||
28 | - | let WAVES = 100000000 | |
29 | - | ||
30 | - | func getPriceKey (incomingAddress,name) = makeString([toString(incomingAddress), name, kPrice], separator) | |
14 | + | func getSlotKey (prefix,nftId) = ((prefix + separator) + toBase58String(nftId)) | |
31 | 15 | ||
32 | 16 | ||
33 | - | func | |
17 | + | func getPriceKey (nftId) = ((kPrice + separator) + toBase58String(nftId)) | |
34 | 18 | ||
35 | 19 | ||
36 | - | func | |
20 | + | func getSellKey (nftId) = ((kSell + separator) + toBase58String(nftId)) | |
37 | 21 | ||
38 | 22 | ||
39 | - | func | |
23 | + | func getAuctionKey (nftId) = ((kAuction + separator) + toBase58String(nftId)) | |
40 | 24 | ||
41 | 25 | ||
42 | - | func | |
26 | + | func getTrustedKey (issuer) = ((kTrusted + separator) + toString(issuer)) | |
43 | 27 | ||
44 | 28 | ||
45 | - | func | |
29 | + | func addToList (accum,nextValue) = (accum ++ [nextValue]) | |
46 | 30 | ||
47 | 31 | ||
48 | - | func getExecutorRaitingKey (incomingAddress) = makeString([toString(incomingAddress), kExecutor, kRating], separator) | |
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 | + | } | |
49 | 113 | ||
50 | 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, Int, Int, Int) => | |
129 | + | joinString([toString(auction._1), toString(auction._2), toString(auction._3), toString(auction._4), toString(auction._5)]) | |
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,endPrice,start,end) = StringEntry(getAuctionKey(nftId), joinStruct($Tuple5(seller, startPrice, endPrice, 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 $t028172921 = parseAsAuction(details) | |
152 | + | let seller = $t028172921._1 | |
153 | + | let startPriceValue = $t028172921._2 | |
154 | + | let endPriceValue = $t028172921._3 | |
155 | + | let startPeriodValue = $t028172921._4 | |
156 | + | let endPeriodValue = $t028172921._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 | + | ||
167 | + | ||
168 | + | func isNft (assetId) = match assetInfo(assetId) { | |
169 | + | case token: Asset => | |
170 | + | if (if ((token.decimals == 0)) | |
171 | + | then (token.quantity == 1) | |
172 | + | else false) | |
173 | + | then (token.reissuable == false) | |
174 | + | else false | |
175 | + | case _ => | |
176 | + | false | |
177 | + | } | |
178 | + | ||
179 | + | ||
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 isCorrectAuctionPeriod (start,end) = (end > start) | |
196 | + | ||
197 | + | ||
198 | + | func isCorrectAuctionPrices (startPrice,endPrice) = (startPrice > endPrice) | |
199 | + | ||
200 | + | ||
201 | + | func isAdmin (caller) = (caller == this) | |
202 | + | ||
203 | + | ||
204 | + | func isValidCaller (caller,seller) = if ((caller == this)) | |
205 | + | then true | |
206 | + | else (caller == seller) | |
207 | + | ||
208 | + | ||
209 | + | func isAuctionEnded (now,end) = (now > end) | |
210 | + | ||
211 | + | ||
212 | + | func isEnoughFunds (payment,currentMomentPrice) = (payment >= currentMomentPrice) | |
213 | + | ||
214 | + | ||
215 | + | func isWawes (assetId) = (assetId == unit) | |
216 | + | ||
217 | + | ||
218 | + | func isCorrectNft (nftId) = if (!(isNft(nftId))) | |
219 | + | then throw("Token is not Nft") | |
220 | + | else if (isSellExist(nftId)) | |
221 | + | then throw("Sell already exists") | |
222 | + | else if (isAuctionExist(nftId)) | |
223 | + | then throw("Auction already exists") | |
224 | + | else unit | |
225 | + | ||
226 | + | ||
227 | + | func isCorrectPayments (paymentAsset,paymentAmount,price) = if (!(isWawes(paymentAsset))) | |
228 | + | then throw("Payment must be at WAVES") | |
229 | + | else if (!(isEnoughFunds(paymentAmount, price))) | |
230 | + | then throw("Not enough funds") | |
231 | + | else unit | |
232 | + | ||
233 | + | ||
234 | + | func calcFee () = 0 | |
235 | + | ||
236 | + | ||
237 | + | func calcTrustedFee () = 0 | |
238 | + | ||
239 | + | ||
240 | + | func resultFundsAmounts (isTrusted,paymentAmount,actualPrice) = if (isTrusted) | |
241 | + | then $Tuple2((actualPrice - calcTrustedFee()), (paymentAmount - actualPrice)) | |
242 | + | else $Tuple2((actualPrice - calcFee()), (paymentAmount - actualPrice)) | |
243 | + | ||
244 | + | ||
245 | + | func getSlot (nftId) = if (isSellExist(nftId)) | |
246 | + | then $Tuple2(kSell, getSell(nftId)) | |
247 | + | else if (isAuctionExist(nftId)) | |
248 | + | then $Tuple2(kAuction, getAuction(nftId)) | |
249 | + | else throw("Slot doesn`t exist") | |
250 | + | ||
251 | + | ||
252 | + | let kBuy = "buy" | |
253 | + | ||
51 | 254 | @Callable(i) | |
52 | - | func createOrder (price,desc,name) = { | |
53 | - | let $t015151591 = $Tuple2(i.payments[0].assetId, value(i.payments[0].amount)) | |
54 | - | let token = $t015151591._1 | |
55 | - | let amount0 = $t015151591._2 | |
56 | - | let descKey = getDescKey(i.caller, name) | |
57 | - | let priceKey = getPriceKey(i.caller, name) | |
58 | - | let statusKey = getStatusKey(i.caller, name, kCustomer) | |
59 | - | let ownerKey = getOwnerKey(i.caller, name) | |
60 | - | if ((token != unit)) | |
61 | - | then throw("Pay in waves") | |
62 | - | else if (((WAVES + price) > amount0)) | |
63 | - | then throw("The cost of placing an order 1 waves + amount") | |
64 | - | else [StringEntry(descKey, desc), StringEntry(ownerKey, toString(i.caller)), IntegerEntry(priceKey, price), StringEntry(statusKey, CREATE_STATUS)] | |
255 | + | func createNft (nft_name,nft_owner,nft_dAppAddress,nft_type,nft_tags,nft_selling_price,nft_description,nft_onSell,nft_data) = { | |
256 | + | let newToken = Issue(nft_name, nft_description, 1, 0, false) | |
257 | + | let issueId = calculateAssetId(newToken) | |
258 | + | [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)] | |
65 | 259 | } | |
66 | 260 | ||
67 | 261 | ||
68 | 262 | ||
69 | 263 | @Callable(i) | |
70 | - | func cancelOrder (name) = [DeleteEntry(getDescKey(i.caller, name)), DeleteEntry(getPriceKey(i.caller, name)), DeleteEntry(getStatusKey(i.caller, name, kCustomer)), DeleteEntry(getOwnerKey(i.caller, name))] | |
71 | - | ||
72 | - | ||
73 | - | ||
74 | - | @Callable(i) | |
75 | - | func confirmOffer (name,address,desc) = { | |
76 | - | let isExist = getString(this, getExecutorAddressKey(i.caller, name)) | |
77 | - | let owner = valueOrErrorMessage(getStringValue(this, getOwnerKey(i.caller, name)), "This order does not exist") | |
78 | - | if ((owner != toString(i.caller))) | |
79 | - | then throw("You are not the order owner") | |
80 | - | else if (isDefined(isExist)) | |
81 | - | then [StringEntry(getStatusKey(i.caller, name, kCustomer), IN_WORK), StringEntry(getStatusKey(value(addressFromString(address)), name, kExecutor), IN_WORK)] | |
82 | - | else throw("This offer does not exist") | |
264 | + | func issueNft (name,meta) = { | |
265 | + | let newToken = Issue(name, meta, 1, 0, false) | |
266 | + | let issueId = calculateAssetId(newToken) | |
267 | + | [newToken, ScriptTransfer(i.caller, 1, issueId), StringEntry(((toBase58String(issueId) + separator) + "Owner"), toString(i.caller))] | |
83 | 268 | } | |
84 | 269 | ||
85 | 270 | ||
86 | 271 | ||
87 | 272 | @Callable(i) | |
88 | - | func taskDoneCustomer (name,address) = { | |
89 | - | let customerRating = valueOrElse(getInteger(this, getCustomerRaitingKey(i.caller)), 0) | |
90 | - | let executorRating = valueOrElse(getInteger(this, getExecutorRaitingKey(value(addressFromString(address)))), 0) | |
91 | - | let amount = valueOrErrorMessage(getIntegerValue(this, getPriceKey(i.caller, name)), "No order price") | |
92 | - | let owner = valueOrErrorMessage(getStringValue(this, getOwnerKey(i.caller, name)), "This order does not exist") | |
93 | - | if ((owner != toString(i.caller))) | |
94 | - | then throw("You are not the order owner") | |
95 | - | else [StringEntry(getStatusKey(value(addressFromString(address)), name, kExecutor), COMPLETED_STATUS), StringEntry(getStatusKey(i.caller, name, kCustomer), COMPLETED_STATUS), ScriptTransfer(value(addressFromString(address)), amount, unit), IntegerEntry(getCustomerRaitingKey(i.caller), (customerRating + 1)), IntegerEntry(getExecutorRaitingKey(value(addressFromString(address))), (executorRating + 1))] | |
273 | + | func buyNFT (nftID) = { | |
274 | + | let assetId = fromBase58String(nftID) | |
275 | + | let amount = value(i.payments[0].amount) | |
276 | + | let price = valueOrErrorMessage(getString(((kPrice + separator) + nftID)), "There is no price for this NFT") | |
277 | + | let owner = valueOrErrorMessage(getStringValue(((nftID + separator) + "Owner")), "No owner") | |
278 | + | if ((i.payments[0].assetId != unit)) | |
279 | + | then throw("Pay in waves") | |
280 | + | else if ((parseIntValue(price) > amount)) | |
281 | + | then throw("Invalid payment") | |
282 | + | else [ScriptTransfer(i.caller, 1, assetId), ScriptTransfer(value(addressFromString(owner)), parseIntValue(price), unit), StringEntry(((toString(i.caller) + separator) + kBuy), ((nftID + separator) + toString(amount)))] | |
96 | 283 | } | |
97 | 284 | ||
98 | 285 | ||
99 | 286 | ||
100 | 287 | @Callable(i) | |
101 | - | func offer (name,address,desc) = { | |
102 | - | let isExist = valueOrErrorMessage(getString(this, getDescKey(value(addressFromString(address)), name)), "This order does not exist") | |
103 | - | if ((isExist == isExist)) | |
104 | - | then [StringEntry(getExecutorAddressKey(value(addressFromString(address)), name), toString(i.caller)), StringEntry(getDescKey(i.caller, name), desc), StringEntry(getStatusKey(value(addressFromString(address)), name, kCustomer), ANYS_SUGGESTION_STATUS), StringEntry(getStatusKey(i.caller, name, kExecutor), CREATE_STATUS)] | |
105 | - | else throw("Strict value is not equal to itself.") | |
288 | + | func sellNFT (price) = { | |
289 | + | let $t073397424 = $Tuple2(value(i.payments[0].assetId), value(i.payments[0].amount)) | |
290 | + | let token0 = $t073397424._1 | |
291 | + | let amount0 = $t073397424._2 | |
292 | + | if (!(isNft(token0))) | |
293 | + | then throw("Token is not NFT") | |
294 | + | else [StringEntry(((kPrice + separator) + toBase58String(value(i.payments[0].assetId))), toString(price)), StringEntry(((toString(i.caller) + separator) + kSell), ((toBase58String(token0) + separator) + toString(amount0)))] | |
106 | 295 | } | |
107 | 296 | ||
108 | 297 | ||
109 | 298 | ||
110 | 299 | @Callable(i) | |
111 | - | func taskDone (name,address) = { | |
112 | - | let desc = getString(this, getDescKey(value(addressFromString(address)), name)) | |
113 | - | let customerTask = valueOrElse(getStringValue(this, getExecutorAddressKey(value(addressFromString(address)), name)), "null") | |
114 | - | if ((toString(i.caller) != customerTask)) | |
115 | - | then throw("You are not the performer of this task") | |
116 | - | else if (isDefined(desc)) | |
117 | - | then [StringEntry(getStatusKey(value(addressFromString(address)), name, kCustomer), WAITING_FOR_CONFIRMATION_STATUS)] | |
118 | - | else throw("This order does not exist") | |
300 | + | func addSell (price) = { | |
301 | + | let nftId = value(i.payments[0].assetId) | |
302 | + | valueOrElse(isCorrectNft(nftId), if (!(isCorrectSellPrice(price))) | |
303 | + | then throw("Price must be > 0") | |
304 | + | else [setSell(nftId, i.caller, price)]) | |
305 | + | } | |
306 | + | ||
307 | + | ||
308 | + | ||
309 | + | @Callable(i) | |
310 | + | func addAuction (startPrice,endPrice,start,end,nft_name,nft_owner,nft_dAppAddress,nft_type,nft_tags,nft_selling_price,nft_description,nft_onSell,nft_data) = { | |
311 | + | let nftId = value(i.payments[0].assetId) | |
312 | + | valueOrElse(isCorrectNft(nftId), if (!(isCorrectAuctionPeriod(start, end))) | |
313 | + | then throw("Period is not correct") | |
314 | + | else if (!(isCorrectAuctionPrices(startPrice, endPrice))) | |
315 | + | then throw("Start price must be > endPrice") | |
316 | + | else [setAuction(i.caller, nftId, startPrice, endPrice, start, end), StringEntry(((toBase58String(nftId) + separator) + "nft_owner"), toString(i.caller)), StringEntry(((toBase58String(nftId) + separator) + "nft_type"), nft_type), StringEntry(((toBase58String(nftId) + separator) + "nft_tags"), nft_tags), StringEntry(((toBase58String(nftId) + separator) + "nft_dAppAddress"), nft_dAppAddress), IntegerEntry(((toBase58String(nftId) + separator) + "nft_selling_price"), nft_selling_price), StringEntry(((toBase58String(nftId) + separator) + "nft_onSell"), nft_onSell), StringEntry(((toBase58String(nftId) + separator) + "nft_data"), nft_data)]) | |
317 | + | } | |
318 | + | ||
319 | + | ||
320 | + | ||
321 | + | @Callable(i) | |
322 | + | func buyFromSlot (nftId) = { | |
323 | + | let $t092249313 = $Tuple2(i.payments[0].assetId, value(i.payments[0].amount)) | |
324 | + | let paymentAsset = $t092249313._1 | |
325 | + | let paymentAmount = $t092249313._2 | |
326 | + | let assetId = fromBase58String(nftId) | |
327 | + | let $t093579395 = getSlot(assetId) | |
328 | + | let type = $t093579395._1 | |
329 | + | let details = $t093579395._2 | |
330 | + | let baseRes = [ScriptTransfer(i.caller, 1, assetId), DeleteEntry(getSlotKey(type, assetId))] | |
331 | + | if ((type == kSell)) | |
332 | + | then { | |
333 | + | let $t095379584 = parseAsSell(details) | |
334 | + | let seller = $t095379584._1 | |
335 | + | let priceValue = $t095379584._2 | |
336 | + | valueOrElse(isCorrectPayments(paymentAsset, paymentAmount, priceValue), { | |
337 | + | let $t096699771 = resultFundsAmounts(isTrustedNft(assetId), paymentAmount, priceValue) | |
338 | + | let sellerAmount = $t096699771._1 | |
339 | + | let buyerAmount = $t096699771._2 | |
340 | + | let updatedRes = (baseRes ++ [ScriptTransfer(seller, sellerAmount, unit)]) | |
341 | + | if ((buyerAmount > 0)) | |
342 | + | then (updatedRes ++ [ScriptTransfer(i.caller, buyerAmount, unit)]) | |
343 | + | else updatedRes | |
344 | + | }) | |
345 | + | } | |
346 | + | else { | |
347 | + | let $t0998810057 = calcPriceAtCurrentMoment(assetId, height) | |
348 | + | let seller = $t0998810057._1 | |
349 | + | let actualPrice = $t0998810057._2 | |
350 | + | valueOrElse(isCorrectPayments(paymentAsset, paymentAmount, actualPrice), { | |
351 | + | let $t01014310246 = resultFundsAmounts(isTrustedNft(assetId), paymentAmount, actualPrice) | |
352 | + | let sellerAmount = $t01014310246._1 | |
353 | + | let buyerAmount = $t01014310246._2 | |
354 | + | let updatedRes = (baseRes ++ [ScriptTransfer(seller, sellerAmount, unit)]) | |
355 | + | if ((buyerAmount > 0)) | |
356 | + | then (updatedRes ++ [ScriptTransfer(i.caller, buyerAmount, unit)]) | |
357 | + | else updatedRes | |
358 | + | }) | |
359 | + | } | |
360 | + | } | |
361 | + | ||
362 | + | ||
363 | + | ||
364 | + | @Callable(i) | |
365 | + | func declineSlot (nftId) = { | |
366 | + | let assetId = fromBase58String(nftId) | |
367 | + | let $t01054710585 = getSlot(assetId) | |
368 | + | let type = $t01054710585._1 | |
369 | + | let details = $t01054710585._2 | |
370 | + | let baseRes = [DeleteEntry(getSlotKey(type, assetId))] | |
371 | + | if ((type == kSell)) | |
372 | + | then { | |
373 | + | let $t01067710724 = parseAsSell(details) | |
374 | + | let seller = $t01067710724._1 | |
375 | + | let priceValue = $t01067710724._2 | |
376 | + | if (!(isValidCaller(i.caller, seller))) | |
377 | + | then throw("Invalid caller") | |
378 | + | else (baseRes ++ [ScriptTransfer(seller, 1, assetId)]) | |
379 | + | } | |
380 | + | else { | |
381 | + | let $t01086910973 = parseAsAuction(details) | |
382 | + | let seller = $t01086910973._1 | |
383 | + | let startPriceValue = $t01086910973._2 | |
384 | + | let endPriceValue = $t01086910973._3 | |
385 | + | let startPeriodValue = $t01086910973._4 | |
386 | + | let endPeriodValue = $t01086910973._5 | |
387 | + | if (!(isValidCaller(i.caller, seller))) | |
388 | + | then throw("Invalid caller") | |
389 | + | else if (!(isAuctionEnded(height, endPeriodValue))) | |
390 | + | then throw("Wait for end of auction") | |
391 | + | else (baseRes ++ [ScriptTransfer(seller, 1, assetId)]) | |
392 | + | } | |
393 | + | } | |
394 | + | ||
395 | + | ||
396 | + | ||
397 | + | @Callable(i) | |
398 | + | func setTrustedIssuer (trustedAddr) = if (!(isAdmin(i.caller))) | |
399 | + | then throw("Only admin") | |
400 | + | else [BooleanEntry(getTrustedKey(addressFromStringValue(trustedAddr)), true)] | |
401 | + | ||
402 | + | ||
403 | + | ||
404 | + | @Callable(i) | |
405 | + | func getPriceAtCurrentMoment (nftId,moment) = { | |
406 | + | let assetId = fromBase58String(nftId) | |
407 | + | let $t01151411577 = calcPriceAtCurrentMoment(assetId, moment) | |
408 | + | let seller = $t01151411577._1 | |
409 | + | let price = $t01151411577._2 | |
410 | + | [IntegerEntry(getPriceKey(assetId), price)] | |
119 | 411 | } | |
120 | 412 | ||
121 | 413 |
github/deemru/w8io/169f3d6 61.61 ms ◑![]()