tx · 5UFuuoyDANnumqRwF9KQXxQgkb3b1jJrPfsbF7XZm4TY

3N1Dhq5ZZyoojQisuTLusYjnGisqrxDwGLy:  -0.01000000 Waves

2022.04.11 18:27 [2004109] smart account 3N1Dhq5ZZyoojQisuTLusYjnGisqrxDwGLy > SELF 0.00000000 Waves

{ "type": 13, "id": "5UFuuoyDANnumqRwF9KQXxQgkb3b1jJrPfsbF7XZm4TY", "fee": 1000000, "feeAssetId": null, "timestamp": 1649690982732, "version": 2, "chainId": 84, "sender": "3N1Dhq5ZZyoojQisuTLusYjnGisqrxDwGLy", "senderPublicKey": "4ogfEQE7KGDWQR7Vd5VThqBebZ47NxrMLmAApR3sFuXW", "proofs": [ "24HNQoyd43tpY7ey1cmdB1KAU51ykhDBZss3bGc3BiSkPo8owvM4hnE52ZTMEsbiJP36WJqcirvzAMVteFScuGzH" ], "script": "base64:AAIFAAAAAAAAAFgIAhIDCgEIEgMKAQgSBQoDAQgIEgwKCggICAgICAgICAgSDgoMCAEBCAgBCAgIAQEBEgQKAggIEgUKAwgICBIDCgEIEgQKAggIEgYKBAgICAgSBQoDCAgIAAAAUwAAAAAIdW5pdFRlc3QHAAAAAAlvcmFjbGVLZXkCAAAACW9yYWNsZUtleQEAAAAGZ2V0U3RyAAAAAQAAAANrZXkEAAAAByRtYXRjaDAJAAQdAAAAAgUAAAAEdGhpcwUAAAADa2V5AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAAZTdHJpbmcEAAAAAWIFAAAAByRtYXRjaDAFAAAAAWICAAAAAAAAAAAGb3JhY2xlCQEAAAAGZ2V0U3RyAAAAAQUAAAAJb3JhY2xlS2V5AAAAAAlvcmFjbGVGZWUJAQAAAAV2YWx1ZQAAAAEJAAQmAAAAAQUAAAAGb3JhY2xlAAAAAAZvd25lcnMJAARMAAAAAgkABB0AAAACBQAAAAlvcmFjbGVGZWUCAAAABm93bmVyMQkABEwAAAACCQAEHQAAAAIFAAAACW9yYWNsZUZlZQIAAAAGb3duZXIyBQAAAANuaWwAAAAAD2NvbGxlY3Rpb25zRGFwcAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAACW9yYWNsZUZlZQIAAAAPY29sbGVjdGlvbnNEYXBwAgAAABhjb2xsZWN0aW9uRGFwcCBub3QgZm91bmQAAAAAC2ZlZVJlY2VpdmVyCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAJb3JhY2xlRmVlAgAAAAtmZWVSZWNlaXZlcgIAAAAVZmVlUmVjZWl2ZXIgbm90IGZvdW5kAAAAAAhjZXJ0RGFwcAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAACW9yYWNsZUZlZQIAAAAIY2VydERhcHACAAAAEmNlcnREYXBwIG5vdCBmb3VuZAAAAAAHZmVlRGFwcAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAACW9yYWNsZUZlZQIAAAAHZmVlRGFwcAIAAAARZmVlRGFwcCBub3QgZm91bmQAAAAACHVzZXJEYXBwCQEAAAAFdmFsdWUAAAABCQAEJgAAAAEJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAAlvcmFjbGVGZWUCAAAACHVzZXJEYXBwAgAAABJ1c2VyZGFwcCBub3QgZm91bmQAAAAAC1VTRE5Bc3NldElkCQACWQAAAAEJAQAAABFAZXh0ck5hdGl2ZSgxMDUzKQAAAAIFAAAACW9yYWNsZUZlZQIAAAALVVNETkFzc2V0SWQAAAAADVNjb25leEFzc2V0SWQJAAJZAAAAAQkBAAAAEUBleHRyTmF0aXZlKDEwNTMpAAAAAgUAAAAJb3JhY2xlRmVlAgAAAA1TY29uZXhBc3NldElkAAAAAAV0eXBlcwkABEwAAAACAgAAAAVJTUFHRQkABEwAAAACAgAAAANQREYJAARMAAAAAgIAAAAFVklERU8FAAAAA25pbAAAAAAMUHJldmlld3R5cGVzCQAETAAAAAICAAAAA1BERgUAAAADbmlsAAAAAAtkYXBwUnVubmluZwkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBsAAAACBQAAAAh1c2VyRGFwcAIAAAAUY29uZl9kYXBwX2lzX3J1bm5pbmcGAAAAAA5tYWludGVuYW5jZU1TRwkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABB0AAAACBQAAAAh1c2VyRGFwcAIAAAAUY29uZl9tYWludGVuYW5jZV9tc2cCAAAAAAAAAAANdXNlclN1c3BlbmRlZAIAAAAJU1VTUEVOREVEAAAAAAt1c2VyUmVtb3ZlZAIAAAAHUkVNT1ZFRAAAAAAQdXNlclVucmVnaXN0ZXJlZAIAAAAMVU5SRUdJU1RFUkVEAAAAAAxhdWN0aW9uVHlwZTECAAAAB0JJRFRZUEUAAAAADGF1Y3Rpb25UeXBlMgIAAAALVFJBRElUSU9OQUwAAAAADGF1Y3Rpb25UeXBlMwIAAAAGRElSRUNUAQAAABdnZXRTdHJpbmdCeUtleUZyb21Vc2VycwAAAAEAAAADa2V5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAACHVzZXJEYXBwBQAAAANrZXkCAAAAAAEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABAAAAA2tleQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABB0AAAACBQAA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dW50CQAAAgAAAAECAAAADFdyb25nIGFtb3VudAkABRQAAAACBQAAAAliaWRBbW91bnQFAAAACmJpZEFzc2V0SWQBAAAADGlkQ2FsbGVyRGF0ZQAAAAEAAAABaQMJAQAAAAEhAAAAAQUAAAALZGFwcFJ1bm5pbmcJAAACAAAAAQUAAAAObWFpbnRlbmFuY2VNU0cJAAUVAAAAAwkAAlgAAAABCAUAAAABaQAAAA10cmFuc2FjdGlvbklkCQACWAAAAAEICAUAAAABaQAAAAZjYWxsZXIAAAAFYnl0ZXMIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wAQAAAApnZXRBcnREYXRhAAAABAAAAAFpAAAABmlzc3VlcgAAAAVhcnRJZAAAAAVpc0JpZAQAAAAOY2FsbGVySXNJc3N1ZXIJAAAAAAAAAgkAAlgAAAABCAgFAAAAAWkAAAAGY2FsbGVyAAAABWJ5dGVzBQAAAAZpc3N1ZXIEAAAACHRvdGFsTkZUCQEAAAAPZ2V0SW50ZWdlckJ5S2V5AAAAAQIAAAAQdG90YWxfbmZ0X2lzc3VlZAQAAAALYXJ0d29ya05hbWUJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEJAQAAAAdrZXlOYW1lAAAAAgUAAAAGaXNzdWVyBQAAAAVhcnRJZAMJAAAAAAAAAgUAAAALYXJ0d29ya05hbWUCAAAAAAkAAAIAAAABAgAAABFBcnQgZG9lc24ndCBleGlzdAQAAAAIaXNPblNhbGUJAQAAAA9nZXRCb29sZWFuQnlLZXkAAAABCQEAAAAJa2V5T25TYWxlAAAAAgUAAAAGaXNzdWVyBQAAAAVhcnRJZAQAAAAKYW1vdW50U29sZAkBAAAAD2dldEludGVnZXJCeUtleQAAAAEJAQAAAAlrZXlJc3N1ZWQAAAACBQAAAAZpc3N1ZXIFAAAABWFydElkBAAAAAxhcnR3b3JrUHJpY2UJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAQAAAA9nZXRJbnRlZ2VyQnlLZXkAAAABCQEAAAAIa2V5UHJpY2UAAAACBQAAAAZpc3N1ZXIFAAAABWFydElkBQAAAAxtaW5VU0ROUHJpY2UEAAAADHByaWNlQXNzZXRJZAMFAAAADmNhbGxlcklzSXNzdWVyCQACWAAAAAEFAAAAC1VT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aHQJAQAAAA9nZXRJbnRlZ2VyQnlLZXkAAAABCQEAAAAMa2V5RW5kSGVpZ2h0AAAAAgUAAAAGaXNzdWVyBQAAAAVhcnRJZAQAAAAKaGlnaGVzdEJpZAkBAAAAGmdldEFtb3VudEhpZ2hlc3RCaWRCeUFydElkAAAAAQUAAAAFYXJ0SWQDCQAAZgAAAAIFAAAABmhlaWdodAUAAAAJZW5kSGVpZ2h0CQAAAgAAAAECAAAAIVRoaXMgYXVjdGlvbiBpcyBmaW5pc2hlZCBhbHJlYWR5IQQAAAALY2FsbGRlckRhdGEJAQAAAAxpZENhbGxlckRhdGUAAAABBQAAAAFpBAAAAAJpZAgFAAAAC2NhbGxkZXJEYXRhAAAAAl8xBAAAAAZjYWxsZXIIBQAAAAtjYWxsZGVyRGF0YQAAAAJfMgQAAAAEZGF0ZQgFAAAAC2NhbGxkZXJEYXRhAAAAAl8zBAAAAAxpc1BheW1lbnRWYXIJAQAAAAlpc1BheW1lbnQAAAABBQAAAAFpBAAAAAdwYXltZW50CAUAAAAMaXNQYXltZW50VmFyAAAAAl8xBAAAAAZhbW91bnQIBQAAAAxpc1BheW1lbnRWYXIAAAACXzIDCQAAZwAAAAIFAAAACmhpZ2hlc3RCaWQFAAAABmFtb3VudAkAAAIAAAABCQABLAAAAAICAAAAIFBsZWFzZSBwbGFjZSBhIGJpZCBoaWdoZXIgdGhhbjogCQABpAAAAAEFAAAACmhpZ2hlc3RCaWQEAAAAB2Fzc2V0SWQDCQEAAAABIQAAAAEJAQAAAAlpc0RlZmluZWQAAAABCAUAAAAHcGF5bWVudAAAAAdhc3NldElkCQAAAgAAAAECAAAAFk9ubHkgVVNETiBpcyBhY2NlcHRlZCEJAAJYAAAAAQkBAAAABXZhbHVlAAAAAQgFAAAAB3BheW1lbnQAAAAHYXNzZXRJZAQAAAAGYmlkTmJyCQEAAAAPZ2V0SW50ZWdlckJ5S2V5AAAAAQkAASwAAAACAgAAABJjdXJyZW50X2JpZGFtb3VudF8FAAAABWFydElkBAAAAA9taW5BcnR3b3JrUHJpY2UJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAQAAAA9nZXRJbnRlZ2VyQnlLZXkAAAABCQEAAAAIa2V5UHJpY2UAAAACBQAAAAZpc3N1ZXIFAAAABWFydElkBQAAAAxtaW5VU0ROUHJpY2UDCQEAAAABIQAAAAEJAQAAABBhY2NlcHRlZEFzc2V0SWRzAAAAAQUAAAAHYXNzZXRJZAkAAAIAAAABAgAAABJhc3NldCBub3QgYWNjZXB0ZWQDCQAAZgAAAAIFAAAAD21pbkFydHdvcmtQcmljZQUAAAAGYW1vdW50CQAAAgAAAAECAAAAF0JpZCBpcyBiZWxvdyBtaW4gcHJpY2UhBAAAAAphbW91bnRTb2xkCQEAAAAPZ2V0SW50ZWdlckJ5S2V5AAAAAQkBAAAACWtleUlzc3VlZAAAAAIFAAAABmlzc3VlcgUAAAAFYXJ0SWQEAAAACm1heENhblNlbGwJAQAAAA9nZXRJbnRlZ2VyQnlLZXkAAAABCQEAAAAKa2V5TWF4TWludAAAAAIFAAAABmlzc3VlcgUAAAAFYXJ0SWQDCQAAZwAAAAIAAAAAAAAAAAAFAAAACm1heENhblNlbGwJAAACAAAAAQIAAAAjTm8gbWF4IGVkaXRpb24gc2V0IGZvciB0aGlzIGFydHdvcmsDCQAAZwAAAAIFAAAACmFtb3VudFNvbGQFAAAACm1heENhblNlbGwJAAACAAAAAQIAAAAYU29sZCBvdXQsIHlvdSBjYW5ub3QgYmlkCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAARiaWRfBQAAAAVhcnRJZAIAAAABXwUAAAAGaXNzdWVyAgAAAAFfBQAAAAZjYWxsZXICAAAAAV8FAAAAAmlkAgAAAAVfT1BFTgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACBQAAAAdhc3NldElkAgAAAAFfCQABpAAAAAEFAAAABmFtb3VudAIAAAABXwkAAaQAAAABBQAAAARkYXRlCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQABLAAAAAICAAAAEmN1cnJlbnRfYmlkYW1vdW50XwUAAAAFYXJ0SWQJAABkAAAAAgUAAAAGYmlkTmJyAAAAAAAAAAABCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAABJrZXlIaWdoZXN0QmlkQmlkSWQAAAABBQAAAAVhcnRJZAkAAlgAAAABCAUAAAABaQAAAA10cmFuc2FjdGlvbklkCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAIa2V5QmlkSWQAAAABCQACWAAAAAEIBQAAAAFpAAAADXRyYW5zYWN0aW9uSWQFAAAABmFtb3VudAUAAAADbmlsAQAAABdhY2NlcHRCaWROb25UcmFkaXRpb25hbAAAAAUAAAABaQAAAAVhcnRJZAAAAAZpc3N1ZXIAAAAFYmlkSWQAAAAIYmlkT3duZXIEAAAABmNhbGxlcgkAAlgAAAABCAgFAAAAAWkAAAAGY2FsbGVyAAAABWJ5dGVzAwkBAAAAAiE9AAAAAgUAAAAGY2FsbGVyBQAAAAZpc3N1ZXIJAAACAAAAAQIAAAAZWW91IGNhbm5vdCBkbyB0aGlzIGFjdGlvbgkBAAAAB2J1eU1pbnQAAAAGBQAAAAFpBQAAAAVhcnRJZAUAAAAGaXNzdWVyBQAAAAViaWRJZAUAAAAIYmlkT3duZXIGAQAAAA5yZXN0YXJ0QXVjdGlvbgAAAAIAAAAFYXJ0SWQAAAAGaXNzdWVyBAAAAAphbW91bnRTb2xkCQEAAAAPZ2V0SW50ZWdlckJ5S2V5AAAAAQkBAAAACWtleUlzc3VlZAAAAAIFAAAABmlzc3VlcgUAAAAFYXJ0SWQEAAAACm1heENhblNlbGwJAQAAAA9nZXRJbnRlZ2VyQnlLZXkAAAABCQEAAAAKa2V5TWF4TWludAAAAAIFAAAABmlzc3VlcgUAAAAFYXJ0SWQEAAAADG9sZEVuZEhlaWdodAkBAAAAD2dldEludGVnZXJCeUtleQAAAAEJAQAAAAxrZXlFbmRIZWlnaHQAAAACBQAAAAZpc3N1ZXIFAAAABWFydElkBAAAAAhkdXJhdGlvbgkBAAAAD2dldEludGVnZXJCeUtleQAAAAEJAQAAAAtrZXlEdXJhdGlvbgAAAAIFAAAABmlzc3VlcgUAAAAFYXJ0SWQEAAAACWVuZEhlaWdodAkAAGQAAAACBQAAAAhkdXJhdGlvbgUAAAAGaGVpZ2h0AwkAAGYAAAACBQAAAAZoZWlnaHQFAAAADG9sZEVuZEhlaWdodAMJAAAAAAAAAgUAAAAKYW1vdW50U29sZAUAAAAKbWF4Q2FuU2VsbAkAAAIAAAABAgAAACZDYW4ndCByZXN0YXJ0IGF1Y3Rpb24sIG1heCBhbW91bnQgc29sZAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAADGtleUVuZEhlaWdodAAAAAIFAAAABmlzc3VlcgUAAAAFYXJ0SWQFAAAACWVuZEhlaWdodAkABEwAAAACCQEAAAALRGVsZXRlRW50cnkAAAABCQEAAAASa2V5SGlnaGVzdEJpZEJpZElkAAAAAQUAAAAFYXJ0SWQFAAAAA25pbAkAAAIAAAABAgAAACRQcmV2aW91cyBhdWN0aW9uIGlzbid0IGNvbXBsZXRlZCB5ZXQBAAAAFGFjY2VwdEJpZFRyYWRpdGlvbmFsAAAABQAAAAFpAAAABWFydElkAAAABmlzc3VlcgAAAAViaWRJZAAAAAhiaWRPd25lcgQAAAAJZW5kSGVpZ2h0CQEAAAAPZ2V0SW50ZWdlckJ5S2V5AAAAAQkBAAAADGtleUVuZEhlaWdodAAAAAIFAAAABmlzc3VlcgUAAAAFYXJ0SWQEAAAADGhpZ2hlc3RCaWRJZAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQkBAAAAEmtleUhpZ2hlc3RCaWRCaWRJZAAAAAEFAAAABWFydElkAwkAAGYAAAACBQAAAAZoZWlnaHQFAAAACWVuZEhlaWdodAMJAAAAAAAAAgUAAAAFYmlkSWQFAAAADGhpZ2hlc3RCaWRJZAQAAAALYnV5TWludERhdGEJAQAAAAdidXlNaW50AAAABgUAAAABaQUAAAAFYXJ0SWQFAAAABmlzc3VlcgUAAAAFYmlkSWQFAAAACGJpZE93bmVyBgQAAAAScmVzdGFydEF1Y3Rpb25EYXRhCQEAAAAOcmVzdGFydEF1Y3Rpb24AAAACBQAAAAVhcnRJZAUAAAAGaXNzdWVyCQAETgAAAAIFAAAAEnJlc3RhcnRBdWN0aW9uRGF0YQUAAAALYnV5TWludERhdGEJAAACAAAAAQIAAAAcVGhpcyBpcyBub3QgdGhlIHdpbm5pbmcgYmlkIQkAAAIAAAABAgAAACFUaGlzIGF1Y3Rpb24gaXMgbm90IHlldCBmaW5pc2hlZCEBAAAADWNhbmNlbEJpZEltcGwAAAAEAAAAAWkAAAAFYXJ0SWQA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AAAEdHlwZQQAAAAPdmFsaWRhdGVBcnR3b3JrCQEAAAATdmFsaWRhdGVBcnR3b3JrRGF0YQAAAAUFAAAABmNhbGxlcgUAAAAKY2lkRGlzcGxheQUAAAAEbmFtZQUAAAALZGVzY3JpcHRpb24FAAAABHRhZ3MDCQEAAAACIT0AAAACBQAAAA92YWxpZGF0ZUFydHdvcmsCAAAAAAkAAAIAAAABAgAAABVTb21ldGhpbmcgd2VudCB3cm9uZyEEAAAADHQwMTgxNzAxODIxMgkBAAAAD3ZhbGlkYXRlUGF5bWVudAAAAAEFAAAAAWkEAAAABmFtb3VudAgFAAAADHQwMTgxNzAxODIxMgAAAAJfMQQAAAAHYXNzZXRJZAgFAAAADHQwMTgxNzAxODIxMgAAAAJfMgMJAQAAAAEhAAAAAQkBAAAACWlzRGVmaW5lZAAAAAEFAAAABmFtb3VudAkAAAIAAAABAgAAABRTb21ldGhpbmcgd2VudCB3cm9uZwQAAAALcHJldmlld0RhdGEDCQEAAAAPY29udGFpbnNFbGVtZW50AAAAAgUAAAAMUHJldmlld3R5cGVzBQAAAAR0eXBlCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAAA1rZXlQcmV2aWV3Q2lkAAAAAgUAAAAGY2FsbGVyBQAAAAVhcnRJZAUAAAAHcHJldmlldwUAAAADbmlsBQAAAANuaWwEAAAAFmludm9rZUNvbGxlY3Rpb25DcmVhdGUJAAP8AAAABAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEJgAAAAEFAAAAD2NvbGxlY3Rpb25zRGFwcAkAASwAAAACBQAAAA9jb2xsZWN0aW9uc0RhcHACAAAACiBub3QgZm91bmQCAAAAEWNvbGxlY3Rpb25Qcm9jZXNzCQAETAAAAAIFAAAACmNvbGxlY3Rpb24JAARMAAAAAgUAAAANc3ViY29sbGVjdGlvbgkABEwAAAACBQAAAAZjYWxsZXIFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAABZpbnZva2VDb2xsZWN0aW9uQ3JlYXRlBQAAABZpbnZva2VDb2xsZWN0aW9uQ3JlYXRlBAAAAAxpZENvbGxlY3Rpb24EAAAAByRtYXRjaDAFAAAAFmludm9rZUNvbGxl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AAAADmtleUF1Y3Rpb25UeXBlAAAAAgUAAAAGaXNzdWVyBQAAAAVhcnRJZAMJAAAAAAAAAgUAAAALYXVjdGlvblR5cGUFAAAADGF1Y3Rpb25UeXBlMQkBAAAAF2FjY2VwdEJpZE5vblRyYWRpdGlvbmFsAAAABQUAAAABaQUAAAAFYXJ0SWQFAAAABmlzc3VlcgUAAAAFYmlkSWQFAAAACGJpZE93bmVyAwkAAAAAAAACBQAAAAthdWN0aW9uVHlwZQUAAAAMYXVjdGlvblR5cGUyCQEAAAAUYWNjZXB0QmlkVHJhZGl0aW9uYWwAAAAFBQAAAAFpBQAAAAVhcnRJZAUAAAAGaXNzdWVyBQAAAAViaWRJZAUAAAAIYmlkT3duZXIJAAACAAAAAQkAASwAAAACCQABLAAAAAICAAAAFlVua25vd24gYXVjdGlvbiB0eXBlIDoFAAAAC2F1Y3Rpb25UeXBlAgAAABssIHBsZWFzZSBjb250YWN0IHRoZSBhZG1pbnMAAAABaQEAAAAJY2FuY2VsQmlkAAAAAwAAAAVhcnRJZAAAAAZpc3N1ZXIAAAAFYmlkSWQEAAAAC2F1Y3Rpb25UeXBlCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABCQEAAAAOa2V5QXVjdGlvblR5cGUAAAACBQAAAAZpc3N1ZXIFAAAABWFydElkAwkAAAAAAAACBQAAAAthdWN0aW9uVHlwZQUAAAAMYXVjdGlvblR5cGUxCQEAAAANY2FuY2VsQmlkSW1wbAAAAAQFAAAAAWkFAAAABWFydElkBQAAAAZpc3N1ZXIFAAAABWJpZElkCQEAAAAYY2FuY2VsQmlkSW1wbFRyYWRpdGlvbmFsAAAABAUAAAABaQUAAAAFYXJ0SWQFAAAABmlzc3VlcgUAAAAFYmlkSWQAAAAAzTO8Ng==", "height": 2004109, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 53Njw8bL7LMBub98BbvBsxTY116cyktHfjBtqbbCo9a2 Next: 38PrUFiT1pKYmiPUM2zVKa2YKxdz69eJorT8BmCzEXLw Diff:
OldNewDifferences
33 {-# CONTENT_TYPE DAPP #-}
44 let unitTest = false
55
6-let oracleFee = value(addressFromString("3MpZQjzGogmifcEKe8mDd6ribL7nxT9ACye"))
6+let oracleKey = "oracleKey"
77
8-let feeReceiver = "3N65xLq8JcCeaEiR1TJQ7dBqXBvEy6E48Wz"
8+func getStr (key) = match getString(this, key) {
9+ case b: String =>
10+ b
11+ case _ =>
12+ ""
13+}
914
10-let certDapp = "3MxcXrNbMZKYaSrhcfeMm2hZnBeCu3yRWsw"
1115
12-let userDapp = value(addressFromString("3N9cQgZFPHHVu8wqsn2DkQFehg3h8CNiooA"))
16+let oracle = getStr(oracleKey)
1317
14-let whitelistDapp = value(addressFromString("3N9xZYGpzMFDXvXuctmU6zV8qSzm2ZfF31f"))
15-
16-let USDNAssetId = base58'132maRL3uF35tc2bpRih9D6MYq5DR6H28zkop786dKyu'
18+let oracleFee = value(addressFromString(oracle))
1719
1820 let owners = [getString(oracleFee, "owner1"), getString(oracleFee, "owner2")]
1921
20-let USDNFirstSellCut = 150
22+let collectionsDapp = valueOrErrorMessage(getString(oracleFee, "collectionsDapp"), "collectionDapp not found")
2123
22-let USDNSecondSellCut = 30
24+let feeReceiver = valueOrErrorMessage(getString(oracleFee, "feeReceiver"), "feeReceiver not found")
2325
24-let originalCreatorCut = 70
26+let certDapp = valueOrErrorMessage(getString(oracleFee, "certDapp"), "certDapp not found")
27+
28+let feeDapp = valueOrErrorMessage(getString(oracleFee, "feeDapp"), "feeDapp not found")
29+
30+let userDapp = value(addressFromString(valueOrErrorMessage(getString(oracleFee, "userDapp"), "userdapp not found")))
31+
32+let USDNAssetId = fromBase58String(getStringValue(oracleFee, "USDNAssetId"))
33+
34+let SconexAssetId = fromBase58String(getStringValue(oracleFee, "SconexAssetId"))
35+
36+let types = ["IMAGE", "PDF", "VIDEO"]
37+
38+let Previewtypes = ["PDF"]
2539
2640 let dappRunning = valueOrElse(getBoolean(userDapp, "conf_dapp_is_running"), true)
2741
3347
3448 let userUnregistered = "UNREGISTERED"
3549
36-let userAllowed = "ALLOWED"
37-
3850 let auctionType1 = "BIDTYPE"
3951
4052 let auctionType2 = "TRADITIONAL"
53+
54+let auctionType3 = "DIRECT"
4155
4256 func getStringByKeyFromUsers (key) = valueOrElse(getString(userDapp, key), "")
4357
5266
5367
5468 func getIntegerByKey (key) = valueOrElse(getInteger(this, key), 0)
55-
56-
57-func checkWhitelist (key) = valueOrElse(getInteger(whitelistDapp, key), 0)
5869
5970
6071 func getBooleanByKey (key) = valueOrElse(getBoolean(this, key), false)
7889 func keyDisplayCid (caller,artId) = ((("art_display_cid_" + artId) + "_") + caller)
7990
8091
81-func keyMaxMint (caller,artId) = ((("art_maxmint_" + artId) + "_") + caller)
92+func keyPreviewCid (caller,artId) = ((("art_preview_cid_" + artId) + "_") + caller)
8293
8394
84-func keyMinPrice (caller,artId) = ((("art_minprice_" + artId) + "_") + caller)
95+func keyMaxMint (caller,artId) = ((("art_maxmint_" + artId) + "_") + caller)
8596
8697
8798 func keyHighestBidBidId (artId) = ("art_highestBidBidId_" + artId)
103114
104115
105116 func KeyNftIssuer (nftId) = ("nft_issued_" + nftId)
117+
118+
119+func KeyNftArtId (nftId) = ("nft_artId_" + nftId)
106120
107121
108122 func keyOnSale (caller,artId) = ((("art_onsale_" + artId) + "_") + caller)
132146 func keyTxidByHashOwner (sha256Hash,caller) = ("get_txid_by_hash_owner_" + toBase58String(sha256_16Kb(toBytes((sha256Hash + caller)))))
133147
134148
135-let currentCertificationPrice = getIntegerByKeyFromOracle(("certification_fee_" + toBase58String(USDNAssetId)))
149+func keyCollection (caller,artId) = ((("collection_" + artId) + "_") + caller)
150+
151+
152+let minUSDNPrice = getIntegerByKeyFromOracle(("min_" + toBase58String(USDNAssetId)))
153+
154+let currentFeeSconex = getIntegerByKeyFromOracle(("fee_" + toBase58String(SconexAssetId)))
136155
137156 func getAmountByBidId (bidId) = valueOrElse(getIntegerByKey(keyBidId(bidId)), 0)
138157
154173
155174 func validateUser (caller) = {
156175 let userStatus = valueOrElse(getString(userDapp, keyUserStatus(caller)), userUnregistered)
157- if (if ((userStatus == userUnregistered))
158- then true
159- else (userStatus == userAllowed))
176+ if ((userStatus == userUnregistered))
160177 then "Register this account first with 'Account' tab"
161178 else if ((userStatus == userSuspended))
162179 then "Account suspended"
198215 let payment = t089829018._1
199216 let amount = t089829018._2
200217 let assetId = if (if (isDefined(payment.assetId))
201- then (payment.assetId == USDNAssetId)
218+ then (payment.assetId == SconexAssetId)
202219 else false)
203220 then payment.assetId
204- else throw("Only USDN token accepted as transaction fee")
205- if ((amount != currentCertificationPrice))
206- then throw(((("Payment amount should be " + toString(currentCertificationPrice)) + " but is: ") + toString(amount)))
221+ else throw((("Only " + toBase58String(SconexAssetId)) + " token accepted as transaction fee"))
222+ if ((amount != currentFeeSconex))
223+ then throw(((("Payment amount should be " + toString(currentFeeSconex)) + " but is: ") + toString(amount)))
207224 else $Tuple2(amount, assetId)
208225 }
209226
245262
246263
247264 func validateMinSell (assetId,price) = {
248- let minSellSconex = if (unitTest)
249- then 1
250- else (currentCertificationPrice * 2)
251- if (if (if ((assetId == toBase58String(USDNAssetId)))
252- then (minSellSconex > price)
253- else false)
254- then (price != 0)
255- else false)
265+ let minSellSconex = minUSDNPrice
266+ if (if ((minSellSconex > price))
267+ then true
268+ else (assetId != toBase58String(USDNAssetId)))
256269 then throw(("Wrong minimum sell price " + toString(minSellSconex)))
257270 else true
258271 }
283296 else $Tuple3(toBase58String(i.transactionId), toBase58String(i.caller.bytes), lastBlock.timestamp)
284297
285298
286-func isBidCheck (i,issuer,bidOwner,bidId) = if (if (if ((toBase58String(i.caller.bytes) == issuer))
287- then (bidOwner != "")
288- else false)
289- then (bidId != "")
290- else false)
291- then true
292- else false
293-
294-
295299 func getArtData (i,issuer,artId,isBid) = {
296300 let callerIsIssuer = (toBase58String(i.caller.bytes) == issuer)
297301 let totalNFT = getIntegerByKey("total_nft_issued")
301305 else {
302306 let isOnSale = getBooleanByKey(keyOnSale(issuer, artId))
303307 let amountSold = getIntegerByKey(keyIssued(issuer, artId))
304- let artworkPrice = valueOrElse(getIntegerByKey(keyPrice(issuer, artId)), (currentCertificationPrice * 2))
308+ let artworkPrice = valueOrElse(getIntegerByKey(keyPrice(issuer, artId)), minUSDNPrice)
305309 let priceAssetId = if (callerIsIssuer)
306310 then toBase58String(USDNAssetId)
307311 else getStringByKey(keyAssetIdAccepted(issuer, artId))
345349 }
346350
347351
348-func getCommissionData (issuer,assetId,amount,amountSold,maxCanSell) = {
349- let isWhitelisted = checkWhitelist(issuer)
350- let cut = if ((isWhitelisted > height))
351- then 0
352- else if ((assetId == USDNAssetId))
353- then USDNFirstSellCut
354- else throw("Only USDN is accepted!")
355- let amountForSconex = fraction(amount, cut, 1000)
356- let amountForCreator = (amount - amountForSconex)
357- if ((amountSold == maxCanSell))
358- then throw("Art sold out")
359- else {
360- let newAmountSold = (amountSold + 1)
361- $Tuple3(amountForSconex, amountForCreator, newAmountSold)
362- }
363- }
364-
365-
366352 func getIssueData (issuer,artId,artworkName,newAmountSold,maxCanSell,totalNFT,caller,bidOwner,bidId,i,isOnSale) = {
367353 let issueMeta = ((((((((("Creator: " + issuer) + ",ArtID: ") + artId) + ",Artwork name: ") + artworkName) + ",Issue: ") + toString(newAmountSold)) + "/") + toString(maxCanSell))
368354 let sellStatus = if (if ((newAmountSold == maxCanSell))
375361 else i.caller
376362 $Tuple3(sellStatus, receiveNFT, issueMeta)
377363 }
378-
379-
380-func calculateRarity (mintIndex) = if ((4 > mintIndex))
381- then "SSR"
382- else if ((11 > mintIndex))
383- then "SR"
384- else if ((101 > mintIndex))
385- then "R"
386- else "N"
387364
388365
389366 func getBidKeyVal (assetId,bidDataKey,date) = {
414391 let bidDataKey = bidData._1
415392 let amount = bidData._2
416393 let assetId = bidData._3
417- let commisionData = getCommissionData(issuer, value(assetId), amount, amountSold, maxCanSell)
418- let amountForSconex = commisionData._1
419- let amountForCreator = commisionData._2
420- let newAmountSold = commisionData._3
394+ let newAmountSold = if ((amountSold == maxCanSell))
395+ then throw("Max items sold")
396+ else (amountSold + 1)
421397 let issuerData = getIssueData(issuer, artId, artworkName, newAmountSold, maxCanSell, totalNFT, caller, bidOwner, bidId, i, isOnSale)
422398 let sellStatus = issuerData._1
423399 let receiveNFT = issuerData._2
436412 let bidDelOld = bidKeyValue._2
437413 let bidUpdate = bidKeyValue._3
438414 let soldKey = ((((((("art_sold_" + toString(newAmountSold)) + "_of_") + toString(maxCanSell)) + "_") + artId) + "_") + issuer)
439- let rarity = calculateRarity(newAmountSold)
440415 let soldValue = if (!(isBid))
441416 then ((((((((((caller + "_") + toString(date)) + "_") + id) + "_") + toString(artworkPrice)) + "_") + priceAssetId) + "_") + idNFT)
442417 else ((((((((((toString(receiveNFT) + "_") + toString(date)) + "_") + id) + "_") + toString(amount)) + "_") + assetIdBid) + "_") + idNFT)
443- let soldData = StringEntry(soldKey, soldValue)
444- let buyRes = [IntegerEntry(keyIssued(issuer, artId), newAmountSold), StringEntry(("nft_" + idNFT), soldKey), StringEntry(("nft_rarity_" + idNFT), rarity), IntegerEntry("total_nft_issued", (totalNFT + 1)), BooleanEntry(keyOnSale(issuer, artId), sellStatus), ScriptTransfer(Address(fromBase58String(issuer)), amountForCreator, assetId), ScriptTransfer(Address(fromBase58String(feeReceiver)), amountForSconex, assetId), StringEntry(KeyNftIssuer(idNFT), issuer)]
445- let res = invoke(addressFromStringValue(certDapp), "createCert", [toString(receiveNFT), idNFT, issuer], nil)
446- if ((res == res))
447- then if (isBid)
448- then (((buyRes :+ soldData) :+ bidUpdate) :+ bidDelOld)
449- else soldData :: buyRes
418+ let invokeTeamFeeSplit = invoke(valueOrErrorMessage(addressFromString(feeDapp), (feeDapp + " not found")), "payFee", [artId, issuer], [AttachedPayment(assetId, amount)])
419+ if ((invokeTeamFeeSplit == invokeTeamFeeSplit))
420+ then {
421+ let soldData = StringEntry(soldKey, soldValue)
422+ let buyRes = [IntegerEntry(keyIssued(issuer, artId), newAmountSold), StringEntry(("nft_" + idNFT), soldKey), IntegerEntry("total_nft_issued", (totalNFT + 1)), BooleanEntry(keyOnSale(issuer, artId), sellStatus), StringEntry(KeyNftIssuer(idNFT), issuer), StringEntry(KeyNftArtId(idNFT), artId)]
423+ let res = invoke(addressFromStringValue(certDapp), "createCert", [toString(receiveNFT), idNFT, issuer], nil)
424+ if ((res == res))
425+ then if (isBid)
426+ then (((buyRes :+ soldData) :+ bidUpdate) :+ bidDelOld)
427+ else soldData :: buyRes
428+ else throw("Strict value is not equal to itself.")
429+ }
450430 else throw("Strict value is not equal to itself.")
451431 }
452432 else throw("Strict value is not equal to itself.")
467447 let bidNbr = getIntegerByKey(("current_bidamount_" + artId))
468448 if (!(acceptedAssetIds(assetId)))
469449 then throw("asset not accepted")
470- else if (!(validateMinSell(assetId, amount)))
471- then throw("Wrong min sell")
472- else {
473- let amountSold = getIntegerByKey(keyIssued(issuer, artId))
474- let maxCanSell = getIntegerByKey(keyMaxMint(issuer, artId))
475- if ((0 >= maxCanSell))
476- then throw("No max edition set for this artwork")
477- else if ((amountSold >= maxCanSell))
478- then throw("Sold out, you cannot bid")
479- else [StringEntry((((((((("bid_" + artId) + "_") + issuer) + "_") + caller) + "_") + id) + "_OPEN"), ((((assetId + "_") + toString(amount)) + "_") + toString(date))), IntegerEntry(("current_bidamount_" + artId), (bidNbr + 1))]
480- }
450+ else {
451+ let amountSold = getIntegerByKey(keyIssued(issuer, artId))
452+ let maxCanSell = getIntegerByKey(keyMaxMint(issuer, artId))
453+ if ((0 >= maxCanSell))
454+ then throw("No max edition set for this artwork")
455+ else if ((amountSold >= maxCanSell))
456+ then throw("Sold out, you cannot bid")
457+ else [StringEntry((((((((("bid_" + artId) + "_") + issuer) + "_") + caller) + "_") + id) + "_OPEN"), ((((assetId + "_") + toString(amount)) + "_") + toString(date))), IntegerEntry(("current_bidamount_" + artId), (bidNbr + 1))]
458+ }
481459 }
482460
483461
501479 then throw("Only USDN is accepted!")
502480 else toBase58String(value(payment.assetId))
503481 let bidNbr = getIntegerByKey(("current_bidamount_" + artId))
482+ let minArtworkPrice = valueOrElse(getIntegerByKey(keyPrice(issuer, artId)), minUSDNPrice)
504483 if (!(acceptedAssetIds(assetId)))
505484 then throw("asset not accepted")
506- else if (!(validateMinSell(assetId, amount)))
507- then throw("Wrong min sell")
485+ else if ((minArtworkPrice > amount))
486+ then throw("Bid is below min price!")
508487 else {
509488 let amountSold = getIntegerByKey(keyIssued(issuer, artId))
510489 let maxCanSell = getIntegerByKey(keyMaxMint(issuer, artId))
591570
592571
593572 @Callable(i)
573+func initDapp (dappKey) = if ((i.caller != this))
574+ then throw("You cannot do this action")
575+ else if ((oracle != ""))
576+ then throw("oracle already set, you can't override!")
577+ else [StringEntry(oracleKey, dappKey)]
578+
579+
580+
581+@Callable(i)
582+func restartAuctionManual (artId) = if ((getAmountHighestBidByArtId(artId) != 0))
583+ then throw("Please accept the highest bid!")
584+ else restartAuction(artId, toBase58String(i.caller.bytes))
585+
586+
587+
588+@Callable(i)
594589 func mintNft (totalNFT,issueMeta,receiveNFT) = if ((i.caller == this))
595590 then {
596591 let receiveNFTAddy = Address(fromBase58String(receiveNFT))
603598
604599
605600 @Callable(i)
606-func addArtwork (sha256Hash,name,description,tags,type,cidDisplay,entitlement) = {
601+func addArtwork (sha256Hash,name,description,tags,type,cidDisplay,entitlement,preview,collection,subcollection) = {
607602 let t01774017781 = idCallerDate(i)
608603 let artId = t01774017781._1
609604 let caller = t01774017781._2
610605 let date = t01774017781._3
611- let validateArtwork = validateArtworkData(caller, cidDisplay, name, description, tags)
612- if ((validateArtwork != ""))
613- then throw("Something went wrong!")
614- else {
615- let t01817018212 = validatePayment(i)
616- let amount = t01817018212._1
617- let assetId = t01817018212._2
618- if (!(isDefined(amount)))
619- then throw("Something went wrong")
606+ if (containsElement(types, type))
607+ then {
608+ let validateArtwork = validateArtworkData(caller, cidDisplay, name, description, tags)
609+ if ((validateArtwork != ""))
610+ then throw("Something went wrong!")
620611 else {
621- let entryExist = getStringByKey(keyTxidByHashOwner(sha256Hash, caller))
622- if ((entryExist != ""))
623- then throw("You already added it")
612+ let t01817018212 = validatePayment(i)
613+ let amount = t01817018212._1
614+ let assetId = t01817018212._2
615+ if (!(isDefined(amount)))
616+ then throw("Something went wrong")
624617 else {
625- let hashExist = getStringByKey(keyOwnerByHash(sha256Hash))
626- if ((hashExist != ""))
627- then throw("This hash is already registered")
628- else [StringEntry(keyOwnerByHash(sha256Hash), caller), StringEntry(keyTxidByHashOwner(sha256Hash, caller), artId), IntegerEntry(keyDate(caller, artId), date), StringEntry(keyName(caller, artId), name), StringEntry(keyDesc(caller, artId), description), StringEntry(keyDisplayCid(caller, artId), cidDisplay), StringEntry(keyType(caller, artId), type), StringEntry(keyTags(caller, artId), tags), IntegerEntry(keyMaxMint(caller, artId), 0), IntegerEntry(keyIssued(caller, artId), 0), BooleanEntry(keyOnSale(caller, artId), false), StringEntry(keyHashByTxidAddr(caller, artId), sha256Hash), StringEntry(keyEntitlement(caller, artId), entitlement), ScriptTransfer(Address(fromBase58String(feeReceiver)), amount, assetId)]
618+ let previewData = if (containsElement(Previewtypes, type))
619+ then [StringEntry(keyPreviewCid(caller, artId), preview)]
620+ else nil
621+ let invokeCollectionCreate = invoke(valueOrErrorMessage(addressFromString(collectionsDapp), (collectionsDapp + " not found")), "collectionProcess", [collection, subcollection, caller], nil)
622+ if ((invokeCollectionCreate == invokeCollectionCreate))
623+ then {
624+ let idCollection = match invokeCollectionCreate {
625+ case r: String =>
626+ r
627+ case _ =>
628+ throw("Incorrect invoke result")
629+ }
630+ let entryExist = getStringByKey(keyTxidByHashOwner(sha256Hash, caller))
631+ if ((entryExist != ""))
632+ then throw("You already added it")
633+ else {
634+ let hashExist = getStringByKey(keyOwnerByHash(sha256Hash))
635+ if ((hashExist != ""))
636+ then throw("This hash is already registered")
637+ else (previewData ++ [StringEntry(keyOwnerByHash(sha256Hash), caller), StringEntry(keyTxidByHashOwner(sha256Hash, caller), artId), IntegerEntry(keyDate(caller, artId), date), StringEntry(keyName(caller, artId), name), StringEntry(keyDesc(caller, artId), description), StringEntry(keyDisplayCid(caller, artId), cidDisplay), StringEntry(keyType(caller, artId), type), StringEntry(keyTags(caller, artId), tags), IntegerEntry(keyMaxMint(caller, artId), 0), IntegerEntry(keyIssued(caller, artId), 0), BooleanEntry(keyOnSale(caller, artId), false), StringEntry(keyHashByTxidAddr(caller, artId), sha256Hash), StringEntry(keyEntitlement(caller, artId), entitlement), ScriptTransfer(Address(fromBase58String(feeReceiver)), amount, assetId)])
638+ }
639+ }
640+ else throw("Strict value is not equal to itself.")
629641 }
630642 }
631643 }
644+ else throw("Unknown type")
632645 }
633646
634647
635648
636649 @Callable(i)
637-func sellArtwork (artId,price,maxMint,assetId,auctionType,minBid,duration) = {
638- let t02571425747 = idCallerDate(i)
639- let id = t02571425747._1
640- let caller = t02571425747._2
641- let artworkName = getStringByKey(keyName(caller, artId))
642- if (!(containsElement([auctionType1, auctionType2], auctionType)))
643- then throw("We don't know this auction type")
644- else if ((artworkName == ""))
645- then throw("This art doesn't match your account")
646- else {
647- let bidNbr = getIntegerByKey(("current_bidamount_" + artId))
648- if (!(acceptedAssetIds(assetId)))
649- then throw("Something went wrong!")
650- else if (!(validateMinSell(assetId, price)))
651- then throw("Something went wrong!")
652- else {
653- let checkUser = validateUser(caller)
654- if ((checkUser != ""))
655- then throw(checkUser)
656- else {
657- let amountSold = getIntegerByKey(keyIssued(caller, artId))
658- let maxCanSell = getIntegerByKey(keyMaxMint(caller, artId))
659- if ((maxMint > 5000))
660- then throw("5000 editions max per artwork")
661- else if (if ((amountSold != 0))
662- then (amountSold == maxCanSell)
663- else false)
664- then throw("Max edition reached.")
665- else if (if ((amountSold > 0))
666- then (maxCanSell != maxMint)
667- else false)
668- then throw("Cannot change maximum issuable anymore")
669- else if (if ((bidNbr > 0))
670- then (maxCanSell != maxMint)
671- else false)
672- then throw("Cannot change maximum issuable with active orders")
673- else {
674- let sellStatus = if (if ((price > 0))
675- then (maxMint > 0)
650+func sellArtwork (artId,price,maxMint,assetId,auctionType,duration,add1,add2,add3,add1Sh,add2Sh,add3Sh) = {
651+ let invokeTeamFeeSplit = invoke(valueOrErrorMessage(addressFromString(feeDapp), (feeDapp + " not found")), "teamSplitFee", [artId, feeReceiver, "", "", 15, 0, 0], nil)
652+ if ((invokeTeamFeeSplit == invokeTeamFeeSplit))
653+ then {
654+ let invokeCreatorFeeSplit = invoke(valueOrErrorMessage(addressFromString(feeDapp), (feeDapp + " not found")), "creatorSplitFee", [artId, add1, add2, add3, add1Sh, add2Sh, add3Sh], nil)
655+ if ((invokeCreatorFeeSplit == invokeCreatorFeeSplit))
656+ then {
657+ let t02571425747 = idCallerDate(i)
658+ let id = t02571425747._1
659+ let caller = t02571425747._2
660+ let artworkName = getStringByKey(keyName(caller, artId))
661+ if (!(containsElement([auctionType1, auctionType2, auctionType3], auctionType)))
662+ then throw("We don't know this auction type")
663+ else if ((artworkName == ""))
664+ then throw("This art doesn't match your account")
665+ else {
666+ let bidNbr = getIntegerByKey(("current_bidamount_" + artId))
667+ if (!(acceptedAssetIds(assetId)))
668+ then throw("Something went wrong!")
669+ else if (!(validateMinSell(assetId, price)))
670+ then throw("Something went wrong!")
671+ else {
672+ let checkUser = validateUser(caller)
673+ if ((checkUser != ""))
674+ then throw(checkUser)
675+ else {
676+ let amountSold = getIntegerByKey(keyIssued(caller, artId))
677+ let maxCanSell = getIntegerByKey(keyMaxMint(caller, artId))
678+ if ((maxMint > 10000))
679+ then throw("10000 editions max per artwork")
680+ else if (if ((amountSold != 0))
681+ then (amountSold == maxCanSell)
676682 else false)
677- then true
678- else false
679- let endHeight = (duration + height)
680-[BooleanEntry(keyOnSale(caller, artId), sellStatus), IntegerEntry(keyPrice(caller, artId), price), IntegerEntry(keyMaxMint(caller, artId), maxMint), IntegerEntry(keyMinPrice(caller, artId), minBid), IntegerEntry(keyDuration(caller, artId), duration), IntegerEntry(keyEndHeight(caller, artId), endHeight), StringEntry(keyAssetIdAccepted(caller, artId), assetId), StringEntry(keyAuctionType(caller, artId), auctionType)]
681- }
682- }
683- }
684- }
683+ then throw("Max edition reached.")
684+ else if (if ((amountSold > 0))
685+ then (maxCanSell != maxMint)
686+ else false)
687+ then throw("Cannot change maximum issuable anymore")
688+ else if (if ((bidNbr > 0))
689+ then (maxCanSell != maxMint)
690+ else false)
691+ then throw("Cannot change maximum issuable with active orders")
692+ else {
693+ let sellStatus = if (if ((price > 0))
694+ then (maxMint > 0)
695+ else false)
696+ then true
697+ else false
698+ let endHeight = (duration + height)
699+[BooleanEntry(keyOnSale(caller, artId), sellStatus), IntegerEntry(keyPrice(caller, artId), price), IntegerEntry(keyMaxMint(caller, artId), maxMint), IntegerEntry(keyDuration(caller, artId), duration), IntegerEntry(keyEndHeight(caller, artId), endHeight), StringEntry(keyAssetIdAccepted(caller, artId), assetId), StringEntry(keyAuctionType(caller, artId), auctionType)]
700+ }
701+ }
702+ }
703+ }
704+ }
705+ else throw("Strict value is not equal to itself.")
706+ }
707+ else throw("Strict value is not equal to itself.")
685708 }
686709
687710
688711
689712 @Callable(i)
690-func buyArtwork (artId,issuer) = buyMint(i, artId, issuer, "", "", false)
713+func buyArtwork (artId,issuer) = {
714+ let auctionType = getStringByKey(keyAuctionType(issuer, artId))
715+ if ((auctionType == auctionType3))
716+ then buyMint(i, artId, issuer, "", "", false)
717+ else throw("Direct buy only allowed when no auction type is set!")
718+ }
719+
720+
721+
722+@Callable(i)
723+func updateTags (artist,artId,tags) = {
724+ let caller = toString(addressFromPublicKey(i.callerPublicKey))
725+ if (containsElement(owners, caller))
726+ then if ((size(split(tags, ",")) > 5))
727+ then throw("5 tags max.")
728+ else {
729+ let tagsOld = getStringByKeyOrError(keyTags(artist, artId), "No tags created with this key, so can't update!")
730+ if ((tags == tagsOld))
731+ then throw("Tags are the same as old tags!")
732+ else [StringEntry(keyTags(artist, artId), tags)]
733+ }
734+ else throw("no")
735+ }
691736
692737
693738
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let unitTest = false
55
6-let oracleFee = value(addressFromString("3MpZQjzGogmifcEKe8mDd6ribL7nxT9ACye"))
6+let oracleKey = "oracleKey"
77
8-let feeReceiver = "3N65xLq8JcCeaEiR1TJQ7dBqXBvEy6E48Wz"
8+func getStr (key) = match getString(this, key) {
9+ case b: String =>
10+ b
11+ case _ =>
12+ ""
13+}
914
10-let certDapp = "3MxcXrNbMZKYaSrhcfeMm2hZnBeCu3yRWsw"
1115
12-let userDapp = value(addressFromString("3N9cQgZFPHHVu8wqsn2DkQFehg3h8CNiooA"))
16+let oracle = getStr(oracleKey)
1317
14-let whitelistDapp = value(addressFromString("3N9xZYGpzMFDXvXuctmU6zV8qSzm2ZfF31f"))
15-
16-let USDNAssetId = base58'132maRL3uF35tc2bpRih9D6MYq5DR6H28zkop786dKyu'
18+let oracleFee = value(addressFromString(oracle))
1719
1820 let owners = [getString(oracleFee, "owner1"), getString(oracleFee, "owner2")]
1921
20-let USDNFirstSellCut = 150
22+let collectionsDapp = valueOrErrorMessage(getString(oracleFee, "collectionsDapp"), "collectionDapp not found")
2123
22-let USDNSecondSellCut = 30
24+let feeReceiver = valueOrErrorMessage(getString(oracleFee, "feeReceiver"), "feeReceiver not found")
2325
24-let originalCreatorCut = 70
26+let certDapp = valueOrErrorMessage(getString(oracleFee, "certDapp"), "certDapp not found")
27+
28+let feeDapp = valueOrErrorMessage(getString(oracleFee, "feeDapp"), "feeDapp not found")
29+
30+let userDapp = value(addressFromString(valueOrErrorMessage(getString(oracleFee, "userDapp"), "userdapp not found")))
31+
32+let USDNAssetId = fromBase58String(getStringValue(oracleFee, "USDNAssetId"))
33+
34+let SconexAssetId = fromBase58String(getStringValue(oracleFee, "SconexAssetId"))
35+
36+let types = ["IMAGE", "PDF", "VIDEO"]
37+
38+let Previewtypes = ["PDF"]
2539
2640 let dappRunning = valueOrElse(getBoolean(userDapp, "conf_dapp_is_running"), true)
2741
2842 let maintenanceMSG = valueOrElse(getString(userDapp, "conf_maintenance_msg"), "")
2943
3044 let userSuspended = "SUSPENDED"
3145
3246 let userRemoved = "REMOVED"
3347
3448 let userUnregistered = "UNREGISTERED"
3549
36-let userAllowed = "ALLOWED"
37-
3850 let auctionType1 = "BIDTYPE"
3951
4052 let auctionType2 = "TRADITIONAL"
53+
54+let auctionType3 = "DIRECT"
4155
4256 func getStringByKeyFromUsers (key) = valueOrElse(getString(userDapp, key), "")
4357
4458
4559 func getStringByKey (key) = valueOrElse(getString(this, key), "")
4660
4761
4862 func getStringByKeyOrError (key,error) = valueOrErrorMessage(getString(this, key), error)
4963
5064
5165 func getIntegerByKeyFromOracle (key) = valueOrErrorMessage(getInteger(oracleFee, key), "Integer undefine or 0 in oracle")
5266
5367
5468 func getIntegerByKey (key) = valueOrElse(getInteger(this, key), 0)
55-
56-
57-func checkWhitelist (key) = valueOrElse(getInteger(whitelistDapp, key), 0)
5869
5970
6071 func getBooleanByKey (key) = valueOrElse(getBoolean(this, key), false)
6172
6273
6374 func validateHash (hash) = (size(hash) == 64)
6475
6576
6677 func keyUserStatus (caller) = ("user_status_" + caller)
6778
6879
6980 func keyDate (caller,artId) = ((("art_date_" + artId) + "_") + caller)
7081
7182
7283 func keyName (caller,artId) = ((("art_name_" + artId) + "_") + caller)
7384
7485
7586 func keyDesc (caller,artId) = ((("art_desc_" + artId) + "_") + caller)
7687
7788
7889 func keyDisplayCid (caller,artId) = ((("art_display_cid_" + artId) + "_") + caller)
7990
8091
81-func keyMaxMint (caller,artId) = ((("art_maxmint_" + artId) + "_") + caller)
92+func keyPreviewCid (caller,artId) = ((("art_preview_cid_" + artId) + "_") + caller)
8293
8394
84-func keyMinPrice (caller,artId) = ((("art_minprice_" + artId) + "_") + caller)
95+func keyMaxMint (caller,artId) = ((("art_maxmint_" + artId) + "_") + caller)
8596
8697
8798 func keyHighestBidBidId (artId) = ("art_highestBidBidId_" + artId)
8899
89100
90101 func keyBidId (bidId) = ("bid_" + bidId)
91102
92103
93104 func keyDuration (caller,artId) = ((("art_duration_" + artId) + "_") + caller)
94105
95106
96107 func keyEndHeight (caller,artId) = ((("art_endheight_" + artId) + "_") + caller)
97108
98109
99110 func keyAuctionType (caller,artId) = ((("art_auctiontype_" + artId) + "_") + caller)
100111
101112
102113 func keyIssued (caller,artId) = ((("art_issued_" + artId) + "_") + caller)
103114
104115
105116 func KeyNftIssuer (nftId) = ("nft_issued_" + nftId)
117+
118+
119+func KeyNftArtId (nftId) = ("nft_artId_" + nftId)
106120
107121
108122 func keyOnSale (caller,artId) = ((("art_onsale_" + artId) + "_") + caller)
109123
110124
111125 func keyEntitlement (caller,artId) = ((("art_entitlement_" + artId) + "_") + caller)
112126
113127
114128 func keyTags (caller,artId) = ((("art_tags_" + artId) + "_") + caller)
115129
116130
117131 func keyType (caller,artId) = ((("art_type_" + artId) + "_") + caller)
118132
119133
120134 func keyPrice (caller,artId) = ((("art_price_" + artId) + "_") + caller)
121135
122136
123137 func keyAssetIdAccepted (caller,artId) = ((("art_assetAccepted_" + artId) + "_") + caller)
124138
125139
126140 func keyHashByTxidAddr (caller,txid) = ((("get_hashbytxidaddr_" + txid) + "_") + caller)
127141
128142
129143 func keyOwnerByHash (sha256Hash) = ("get_owner_by_hash_" + sha256Hash)
130144
131145
132146 func keyTxidByHashOwner (sha256Hash,caller) = ("get_txid_by_hash_owner_" + toBase58String(sha256_16Kb(toBytes((sha256Hash + caller)))))
133147
134148
135-let currentCertificationPrice = getIntegerByKeyFromOracle(("certification_fee_" + toBase58String(USDNAssetId)))
149+func keyCollection (caller,artId) = ((("collection_" + artId) + "_") + caller)
150+
151+
152+let minUSDNPrice = getIntegerByKeyFromOracle(("min_" + toBase58String(USDNAssetId)))
153+
154+let currentFeeSconex = getIntegerByKeyFromOracle(("fee_" + toBase58String(SconexAssetId)))
136155
137156 func getAmountByBidId (bidId) = valueOrElse(getIntegerByKey(keyBidId(bidId)), 0)
138157
139158
140159 func getAmountHighestBidByArtId (artId) = {
141160 let bidId = getStringByKey(keyHighestBidBidId(artId))
142161 if ((bidId == ""))
143162 then 0
144163 else getAmountByBidId(bidId)
145164 }
146165
147166
148167 func validateString (str,max) = if ((size(str) == 0))
149168 then throw("Field cannot be is empty")
150169 else if ((size(str) > max))
151170 then throw((str + " is too long"))
152171 else true
153172
154173
155174 func validateUser (caller) = {
156175 let userStatus = valueOrElse(getString(userDapp, keyUserStatus(caller)), userUnregistered)
157- if (if ((userStatus == userUnregistered))
158- then true
159- else (userStatus == userAllowed))
176+ if ((userStatus == userUnregistered))
160177 then "Register this account first with 'Account' tab"
161178 else if ((userStatus == userSuspended))
162179 then "Account suspended"
163180 else if ((userStatus == userRemoved))
164181 then "Account removed"
165182 else ""
166183 }
167184
168185
169186 func validateArtworkData (caller,cidDisplay,name,description,tags) = {
170187 let checkUser = validateUser(caller)
171188 if ((checkUser != ""))
172189 then throw(checkUser)
173190 else if ((size(cidDisplay) == 0))
174191 then throw("Display CID cannot be empty")
175192 else if ((size(cidDisplay) != 46))
176193 then throw("This doesn't seem a valid CID!")
177194 else if (!(validateString(name, 100)))
178195 then throw("100 Char. max name")
179196 else if (!(validateString(description, 1000)))
180197 then throw("1000 Char. max description")
181198 else if ((size(split(tags, ",")) > 5))
182199 then throw("5 tags max.")
183200 else ""
184201 }
185202
186203
187204 func isPayment (i) = if ((size(i.payments) == 0))
188205 then throw("No payment attached")
189206 else {
190207 let payment = value(i.payments[0])
191208 let amount = value(payment.amount)
192209 $Tuple2(payment, amount)
193210 }
194211
195212
196213 func validatePayment (i) = {
197214 let t089829018 = isPayment(i)
198215 let payment = t089829018._1
199216 let amount = t089829018._2
200217 let assetId = if (if (isDefined(payment.assetId))
201- then (payment.assetId == USDNAssetId)
218+ then (payment.assetId == SconexAssetId)
202219 else false)
203220 then payment.assetId
204- else throw("Only USDN token accepted as transaction fee")
205- if ((amount != currentCertificationPrice))
206- then throw(((("Payment amount should be " + toString(currentCertificationPrice)) + " but is: ") + toString(amount)))
221+ else throw((("Only " + toBase58String(SconexAssetId)) + " token accepted as transaction fee"))
222+ if ((amount != currentFeeSconex))
223+ then throw(((("Payment amount should be " + toString(currentFeeSconex)) + " but is: ") + toString(amount)))
207224 else $Tuple2(amount, assetId)
208225 }
209226
210227
211228 func isArtMinted (addrToUse,artId) = match getInteger(this, keyIssued(addrToUse, artId)) {
212229 case b: Int =>
213230 if ((b != 0))
214231 then true
215232 else false
216233 case _ =>
217234 false
218235 }
219236
220237
221238 func validatePriceAssetId (i,priceAssetId,artworkPrice) = {
222239 let t096119647 = isPayment(i)
223240 let payment = t096119647._1
224241 let amount = t096119647._2
225242 let assetId = if (!(isDefined(payment.assetId)))
226243 then throw("Wrong asset id")
227244 else if (if ((size(priceAssetId) > 0))
228245 then (toBase58String(value(payment.assetId)) == priceAssetId)
229246 else false)
230247 then payment.assetId
231248 else throw("Wrong asset id")
232249 if (if ((assetId == unit))
233250 then (priceAssetId != "")
234251 else false)
235252 then throw("Wrong asset id")
236253 else if ((artworkPrice != amount))
237254 then throw(((("Payment don't match " + toString(artworkPrice)) + " ") + toString(amount)))
238255 else $Tuple2(amount, assetId)
239256 }
240257
241258
242259 func acceptedAssetIds (assetId) = if ((assetId != toBase58String(USDNAssetId)))
243260 then throw("Only USDN accepted")
244261 else true
245262
246263
247264 func validateMinSell (assetId,price) = {
248- let minSellSconex = if (unitTest)
249- then 1
250- else (currentCertificationPrice * 2)
251- if (if (if ((assetId == toBase58String(USDNAssetId)))
252- then (minSellSconex > price)
253- else false)
254- then (price != 0)
255- else false)
265+ let minSellSconex = minUSDNPrice
266+ if (if ((minSellSconex > price))
267+ then true
268+ else (assetId != toBase58String(USDNAssetId)))
256269 then throw(("Wrong minimum sell price " + toString(minSellSconex)))
257270 else true
258271 }
259272
260273
261274 func getBidAssetId (assetId) = if ((assetId == "WAVES"))
262275 then throw("Only USDN is accepted!")
263276 else fromBase58String(assetId)
264277
265278
266279 func getPriceAssetIdFromBid (bidDataKey) = {
267280 let bidData = getStringByKey((bidDataKey + "_OPEN"))
268281 if ((bidData == ""))
269282 then throw("Bid not found")
270283 else {
271284 let bidDataArr = split(bidData, "_")
272285 let bidAmount = parseIntValue(bidDataArr[1])
273286 let bidAssetId = getBidAssetId(bidDataArr[0])
274287 if ((0 >= bidAmount))
275288 then throw("Wrong amount")
276289 else $Tuple2(bidAmount, bidAssetId)
277290 }
278291 }
279292
280293
281294 func idCallerDate (i) = if (!(dappRunning))
282295 then throw(maintenanceMSG)
283296 else $Tuple3(toBase58String(i.transactionId), toBase58String(i.caller.bytes), lastBlock.timestamp)
284297
285298
286-func isBidCheck (i,issuer,bidOwner,bidId) = if (if (if ((toBase58String(i.caller.bytes) == issuer))
287- then (bidOwner != "")
288- else false)
289- then (bidId != "")
290- else false)
291- then true
292- else false
293-
294-
295299 func getArtData (i,issuer,artId,isBid) = {
296300 let callerIsIssuer = (toBase58String(i.caller.bytes) == issuer)
297301 let totalNFT = getIntegerByKey("total_nft_issued")
298302 let artworkName = getStringByKey(keyName(issuer, artId))
299303 if ((artworkName == ""))
300304 then throw("Art doesn't exist")
301305 else {
302306 let isOnSale = getBooleanByKey(keyOnSale(issuer, artId))
303307 let amountSold = getIntegerByKey(keyIssued(issuer, artId))
304- let artworkPrice = valueOrElse(getIntegerByKey(keyPrice(issuer, artId)), (currentCertificationPrice * 2))
308+ let artworkPrice = valueOrElse(getIntegerByKey(keyPrice(issuer, artId)), minUSDNPrice)
305309 let priceAssetId = if (callerIsIssuer)
306310 then toBase58String(USDNAssetId)
307311 else getStringByKey(keyAssetIdAccepted(issuer, artId))
308312 let maxCanSell = getIntegerByKey(keyMaxMint(issuer, artId))
309313 if (if (if (!(isBid))
310314 then !(callerIsIssuer)
311315 else false)
312316 then if (if ((0 >= artworkPrice))
313317 then true
314318 else !(isOnSale))
315319 then true
316320 else (0 >= maxCanSell)
317321 else false)
318322 then throw("Art not for sale")
319323 else if (if (if (!(isBid))
320324 then callerIsIssuer
321325 else false)
322326 then (0 >= maxCanSell)
323327 else false)
324328 then throw("Max issuable not set")
325329 else $Tuple7(totalNFT, artworkName, amountSold, artworkPrice, priceAssetId, maxCanSell, isOnSale)
326330 }
327331 }
328332
329333
330334 func getBidData (i,caller,issuer,artId,bidOwner,bidId,priceAssetId,artworkPrice,isBid) = {
331335 let checkUser = validateUser(issuer)
332336 if (if (isBid)
333337 then (checkUser != "")
334338 else false)
335339 then throw(checkUser)
336340 else {
337341 let bidDataKey = ((((((("bid_" + artId) + "_") + issuer) + "_") + bidOwner) + "_") + bidId)
338342 let t01351913648 = if (isBid)
339343 then getPriceAssetIdFromBid(bidDataKey)
340344 else validatePriceAssetId(i, priceAssetId, artworkPrice)
341345 let amount = t01351913648._1
342346 let assetId = t01351913648._2
343347 $Tuple3(bidDataKey, amount, assetId)
344348 }
345349 }
346350
347351
348-func getCommissionData (issuer,assetId,amount,amountSold,maxCanSell) = {
349- let isWhitelisted = checkWhitelist(issuer)
350- let cut = if ((isWhitelisted > height))
351- then 0
352- else if ((assetId == USDNAssetId))
353- then USDNFirstSellCut
354- else throw("Only USDN is accepted!")
355- let amountForSconex = fraction(amount, cut, 1000)
356- let amountForCreator = (amount - amountForSconex)
357- if ((amountSold == maxCanSell))
358- then throw("Art sold out")
359- else {
360- let newAmountSold = (amountSold + 1)
361- $Tuple3(amountForSconex, amountForCreator, newAmountSold)
362- }
363- }
364-
365-
366352 func getIssueData (issuer,artId,artworkName,newAmountSold,maxCanSell,totalNFT,caller,bidOwner,bidId,i,isOnSale) = {
367353 let issueMeta = ((((((((("Creator: " + issuer) + ",ArtID: ") + artId) + ",Artwork name: ") + artworkName) + ",Issue: ") + toString(newAmountSold)) + "/") + toString(maxCanSell))
368354 let sellStatus = if (if ((newAmountSold == maxCanSell))
369355 then true
370356 else !(isOnSale))
371357 then false
372358 else true
373359 let receiveNFT = if ((bidOwner != ""))
374360 then addressFromStringValue(bidOwner)
375361 else i.caller
376362 $Tuple3(sellStatus, receiveNFT, issueMeta)
377363 }
378-
379-
380-func calculateRarity (mintIndex) = if ((4 > mintIndex))
381- then "SSR"
382- else if ((11 > mintIndex))
383- then "SR"
384- else if ((101 > mintIndex))
385- then "R"
386- else "N"
387364
388365
389366 func getBidKeyVal (assetId,bidDataKey,date) = {
390367 let assetIdBid = if (!(isDefined(assetId)))
391368 then throw("Only USDN is accepted")
392369 else toBase58String(value(assetId))
393370 let bidData = getStringByKey((bidDataKey + "_OPEN"))
394371 let bidDelOld = DeleteEntry((bidDataKey + "_OPEN"))
395372 let bidUpdate = StringEntry((bidDataKey + "_CLOSED"), ((bidData + "_") + toString(date)))
396373 $Tuple3(assetIdBid, bidDelOld, bidUpdate)
397374 }
398375
399376
400377 func buyMint (i,artId,issuer,bidId,bidOwner,isBid) = {
401378 let callerData = idCallerDate(i)
402379 let id = callerData._1
403380 let caller = callerData._2
404381 let date = callerData._3
405382 let artData = getArtData(i, issuer, artId, isBid)
406383 let totalNFT = artData._1
407384 let artworkName = artData._2
408385 let amountSold = artData._3
409386 let artworkPrice = artData._4
410387 let priceAssetId = artData._5
411388 let maxCanSell = artData._6
412389 let isOnSale = artData._7
413390 let bidData = getBidData(i, caller, issuer, artId, bidOwner, bidId, priceAssetId, artworkPrice, isBid)
414391 let bidDataKey = bidData._1
415392 let amount = bidData._2
416393 let assetId = bidData._3
417- let commisionData = getCommissionData(issuer, value(assetId), amount, amountSold, maxCanSell)
418- let amountForSconex = commisionData._1
419- let amountForCreator = commisionData._2
420- let newAmountSold = commisionData._3
394+ let newAmountSold = if ((amountSold == maxCanSell))
395+ then throw("Max items sold")
396+ else (amountSold + 1)
421397 let issuerData = getIssueData(issuer, artId, artworkName, newAmountSold, maxCanSell, totalNFT, caller, bidOwner, bidId, i, isOnSale)
422398 let sellStatus = issuerData._1
423399 let receiveNFT = issuerData._2
424400 let issueMeta = issuerData._3
425401 let idNFTInvoke = invoke(this, "mintNft", [totalNFT, issueMeta, toString(receiveNFT)], nil)
426402 if ((idNFTInvoke == idNFTInvoke))
427403 then {
428404 let idNFT = match idNFTInvoke {
429405 case r: String =>
430406 r
431407 case _ =>
432408 throw("Incorrect invoke result")
433409 }
434410 let bidKeyValue = getBidKeyVal(assetId, bidDataKey, date)
435411 let assetIdBid = bidKeyValue._1
436412 let bidDelOld = bidKeyValue._2
437413 let bidUpdate = bidKeyValue._3
438414 let soldKey = ((((((("art_sold_" + toString(newAmountSold)) + "_of_") + toString(maxCanSell)) + "_") + artId) + "_") + issuer)
439- let rarity = calculateRarity(newAmountSold)
440415 let soldValue = if (!(isBid))
441416 then ((((((((((caller + "_") + toString(date)) + "_") + id) + "_") + toString(artworkPrice)) + "_") + priceAssetId) + "_") + idNFT)
442417 else ((((((((((toString(receiveNFT) + "_") + toString(date)) + "_") + id) + "_") + toString(amount)) + "_") + assetIdBid) + "_") + idNFT)
443- let soldData = StringEntry(soldKey, soldValue)
444- let buyRes = [IntegerEntry(keyIssued(issuer, artId), newAmountSold), StringEntry(("nft_" + idNFT), soldKey), StringEntry(("nft_rarity_" + idNFT), rarity), IntegerEntry("total_nft_issued", (totalNFT + 1)), BooleanEntry(keyOnSale(issuer, artId), sellStatus), ScriptTransfer(Address(fromBase58String(issuer)), amountForCreator, assetId), ScriptTransfer(Address(fromBase58String(feeReceiver)), amountForSconex, assetId), StringEntry(KeyNftIssuer(idNFT), issuer)]
445- let res = invoke(addressFromStringValue(certDapp), "createCert", [toString(receiveNFT), idNFT, issuer], nil)
446- if ((res == res))
447- then if (isBid)
448- then (((buyRes :+ soldData) :+ bidUpdate) :+ bidDelOld)
449- else soldData :: buyRes
418+ let invokeTeamFeeSplit = invoke(valueOrErrorMessage(addressFromString(feeDapp), (feeDapp + " not found")), "payFee", [artId, issuer], [AttachedPayment(assetId, amount)])
419+ if ((invokeTeamFeeSplit == invokeTeamFeeSplit))
420+ then {
421+ let soldData = StringEntry(soldKey, soldValue)
422+ let buyRes = [IntegerEntry(keyIssued(issuer, artId), newAmountSold), StringEntry(("nft_" + idNFT), soldKey), IntegerEntry("total_nft_issued", (totalNFT + 1)), BooleanEntry(keyOnSale(issuer, artId), sellStatus), StringEntry(KeyNftIssuer(idNFT), issuer), StringEntry(KeyNftArtId(idNFT), artId)]
423+ let res = invoke(addressFromStringValue(certDapp), "createCert", [toString(receiveNFT), idNFT, issuer], nil)
424+ if ((res == res))
425+ then if (isBid)
426+ then (((buyRes :+ soldData) :+ bidUpdate) :+ bidDelOld)
427+ else soldData :: buyRes
428+ else throw("Strict value is not equal to itself.")
429+ }
450430 else throw("Strict value is not equal to itself.")
451431 }
452432 else throw("Strict value is not equal to itself.")
453433 }
454434
455435
456436 func setBidNonTraditional (i,artId,issuer) = {
457437 let t02770927747 = idCallerDate(i)
458438 let id = t02770927747._1
459439 let caller = t02770927747._2
460440 let date = t02770927747._3
461441 let t02775227788 = isPayment(i)
462442 let payment = t02775227788._1
463443 let amount = t02775227788._2
464444 let assetId = if (!(isDefined(payment.assetId)))
465445 then throw("Only USDN is accepted!")
466446 else toBase58String(value(payment.assetId))
467447 let bidNbr = getIntegerByKey(("current_bidamount_" + artId))
468448 if (!(acceptedAssetIds(assetId)))
469449 then throw("asset not accepted")
470- else if (!(validateMinSell(assetId, amount)))
471- then throw("Wrong min sell")
472- else {
473- let amountSold = getIntegerByKey(keyIssued(issuer, artId))
474- let maxCanSell = getIntegerByKey(keyMaxMint(issuer, artId))
475- if ((0 >= maxCanSell))
476- then throw("No max edition set for this artwork")
477- else if ((amountSold >= maxCanSell))
478- then throw("Sold out, you cannot bid")
479- else [StringEntry((((((((("bid_" + artId) + "_") + issuer) + "_") + caller) + "_") + id) + "_OPEN"), ((((assetId + "_") + toString(amount)) + "_") + toString(date))), IntegerEntry(("current_bidamount_" + artId), (bidNbr + 1))]
480- }
450+ else {
451+ let amountSold = getIntegerByKey(keyIssued(issuer, artId))
452+ let maxCanSell = getIntegerByKey(keyMaxMint(issuer, artId))
453+ if ((0 >= maxCanSell))
454+ then throw("No max edition set for this artwork")
455+ else if ((amountSold >= maxCanSell))
456+ then throw("Sold out, you cannot bid")
457+ else [StringEntry((((((((("bid_" + artId) + "_") + issuer) + "_") + caller) + "_") + id) + "_OPEN"), ((((assetId + "_") + toString(amount)) + "_") + toString(date))), IntegerEntry(("current_bidamount_" + artId), (bidNbr + 1))]
458+ }
481459 }
482460
483461
484462 func setBidTraditional (i,artId,issuer) = {
485463 let endHeight = getIntegerByKey(keyEndHeight(issuer, artId))
486464 let highestBid = getAmountHighestBidByArtId(artId)
487465 if ((height > endHeight))
488466 then throw("This auction is finished already!")
489467 else {
490468 let callderData = idCallerDate(i)
491469 let id = callderData._1
492470 let caller = callderData._2
493471 let date = callderData._3
494472 let isPaymentVar = isPayment(i)
495473 let payment = isPaymentVar._1
496474 let amount = isPaymentVar._2
497475 if ((highestBid >= amount))
498476 then throw(("Please place a bid higher than: " + toString(highestBid)))
499477 else {
500478 let assetId = if (!(isDefined(payment.assetId)))
501479 then throw("Only USDN is accepted!")
502480 else toBase58String(value(payment.assetId))
503481 let bidNbr = getIntegerByKey(("current_bidamount_" + artId))
482+ let minArtworkPrice = valueOrElse(getIntegerByKey(keyPrice(issuer, artId)), minUSDNPrice)
504483 if (!(acceptedAssetIds(assetId)))
505484 then throw("asset not accepted")
506- else if (!(validateMinSell(assetId, amount)))
507- then throw("Wrong min sell")
485+ else if ((minArtworkPrice > amount))
486+ then throw("Bid is below min price!")
508487 else {
509488 let amountSold = getIntegerByKey(keyIssued(issuer, artId))
510489 let maxCanSell = getIntegerByKey(keyMaxMint(issuer, artId))
511490 if ((0 >= maxCanSell))
512491 then throw("No max edition set for this artwork")
513492 else if ((amountSold >= maxCanSell))
514493 then throw("Sold out, you cannot bid")
515494 else [StringEntry((((((((("bid_" + artId) + "_") + issuer) + "_") + caller) + "_") + id) + "_OPEN"), ((((assetId + "_") + toString(amount)) + "_") + toString(date))), IntegerEntry(("current_bidamount_" + artId), (bidNbr + 1)), StringEntry(keyHighestBidBidId(artId), toBase58String(i.transactionId)), IntegerEntry(keyBidId(toBase58String(i.transactionId)), amount)]
516495 }
517496 }
518497 }
519498 }
520499
521500
522501 func acceptBidNonTraditional (i,artId,issuer,bidId,bidOwner) = {
523502 let caller = toBase58String(i.caller.bytes)
524503 if ((caller != issuer))
525504 then throw("You cannot do this action")
526505 else buyMint(i, artId, issuer, bidId, bidOwner, true)
527506 }
528507
529508
530509 func restartAuction (artId,issuer) = {
531510 let amountSold = getIntegerByKey(keyIssued(issuer, artId))
532511 let maxCanSell = getIntegerByKey(keyMaxMint(issuer, artId))
533512 let oldEndHeight = getIntegerByKey(keyEndHeight(issuer, artId))
534513 let duration = getIntegerByKey(keyDuration(issuer, artId))
535514 let endHeight = (duration + height)
536515 if ((height > oldEndHeight))
537516 then if ((amountSold == maxCanSell))
538517 then throw("Can't restart auction, max amount sold")
539518 else [IntegerEntry(keyEndHeight(issuer, artId), endHeight), DeleteEntry(keyHighestBidBidId(artId))]
540519 else throw("Previous auction isn't completed yet")
541520 }
542521
543522
544523 func acceptBidTraditional (i,artId,issuer,bidId,bidOwner) = {
545524 let endHeight = getIntegerByKey(keyEndHeight(issuer, artId))
546525 let highestBidId = getStringByKey(keyHighestBidBidId(artId))
547526 if ((height > endHeight))
548527 then if ((bidId == highestBidId))
549528 then {
550529 let buyMintData = buyMint(i, artId, issuer, bidId, bidOwner, true)
551530 let restartAuctionData = restartAuction(artId, issuer)
552531 (restartAuctionData ++ buyMintData)
553532 }
554533 else throw("This is not the winning bid!")
555534 else throw("This auction is not yet finished!")
556535 }
557536
558537
559538 func cancelBidImpl (i,artId,issuer,bidId) = {
560539 let t02894229094 = idCallerDate(i)
561540 let id = t02894229094._1
562541 let caller = t02894229094._2
563542 let date = t02894229094._3
564543 let bidNbr = getIntegerByKey(("current_bidamount_" + artId))
565544 let bidDataKey = ((((((("bid_" + artId) + "_") + issuer) + "_") + caller) + "_") + bidId)
566545 let bidData = getStringByKeyOrError((bidDataKey + "_OPEN"), "Bid not found")
567546 let bidDataArr = split(bidData, "_")
568547 let assetId = getBidAssetId(bidDataArr[0])
569548 let bidStatus = "CANCELED"
570549 [DeleteEntry((bidDataKey + "_OPEN")), StringEntry(((bidDataKey + "_") + bidStatus), ((bidData + "_") + toString(date))), IntegerEntry(("current_bidamount_" + artId), (bidNbr - 1)), ScriptTransfer(Address(fromBase58String(caller)), parseIntValue(bidDataArr[1]), assetId)]
571550 }
572551
573552
574553 func cancelBidImplTraditional (i,artId,issuer,bidId) = {
575554 let t02894229094 = idCallerDate(i)
576555 let id = t02894229094._1
577556 let caller = t02894229094._2
578557 let date = t02894229094._3
579558 let bidNbr = getIntegerByKey(("current_bidamount_" + artId))
580559 let bidDataKey = ((((((("bid_" + artId) + "_") + issuer) + "_") + caller) + "_") + bidId)
581560 let bidData = getStringByKeyOrError((bidDataKey + "_OPEN"), "Bid not found")
582561 let bidDataArr = split(bidData, "_")
583562 let assetId = getBidAssetId(bidDataArr[0])
584563 let bidStatus = "CANCELED"
585564 let bidAmount = parseIntValue(bidDataArr[1])
586565 let highestBidId = getStringByKey(keyHighestBidBidId(artId))
587566 if ((bidId == highestBidId))
588567 then throw("You can't cancel the highest bid!")
589568 else [DeleteEntry((bidDataKey + "_OPEN")), StringEntry(((bidDataKey + "_") + bidStatus), ((bidData + "_") + toString(date))), IntegerEntry(("current_bidamount_" + artId), (bidNbr - 1)), ScriptTransfer(Address(fromBase58String(caller)), bidAmount, assetId)]
590569 }
591570
592571
593572 @Callable(i)
573+func initDapp (dappKey) = if ((i.caller != this))
574+ then throw("You cannot do this action")
575+ else if ((oracle != ""))
576+ then throw("oracle already set, you can't override!")
577+ else [StringEntry(oracleKey, dappKey)]
578+
579+
580+
581+@Callable(i)
582+func restartAuctionManual (artId) = if ((getAmountHighestBidByArtId(artId) != 0))
583+ then throw("Please accept the highest bid!")
584+ else restartAuction(artId, toBase58String(i.caller.bytes))
585+
586+
587+
588+@Callable(i)
594589 func mintNft (totalNFT,issueMeta,receiveNFT) = if ((i.caller == this))
595590 then {
596591 let receiveNFTAddy = Address(fromBase58String(receiveNFT))
597592 let issueNFT = Issue(("SCONEX_" + toString((totalNFT + 1))), issueMeta, 1, 0, false)
598593 let idNFT = calculateAssetId(issueNFT)
599594 $Tuple2([issueNFT, ScriptTransfer(receiveNFTAddy, 1, idNFT)], toBase58String(idNFT))
600595 }
601596 else throw("Only the dApp can mint NFT's")
602597
603598
604599
605600 @Callable(i)
606-func addArtwork (sha256Hash,name,description,tags,type,cidDisplay,entitlement) = {
601+func addArtwork (sha256Hash,name,description,tags,type,cidDisplay,entitlement,preview,collection,subcollection) = {
607602 let t01774017781 = idCallerDate(i)
608603 let artId = t01774017781._1
609604 let caller = t01774017781._2
610605 let date = t01774017781._3
611- let validateArtwork = validateArtworkData(caller, cidDisplay, name, description, tags)
612- if ((validateArtwork != ""))
613- then throw("Something went wrong!")
614- else {
615- let t01817018212 = validatePayment(i)
616- let amount = t01817018212._1
617- let assetId = t01817018212._2
618- if (!(isDefined(amount)))
619- then throw("Something went wrong")
606+ if (containsElement(types, type))
607+ then {
608+ let validateArtwork = validateArtworkData(caller, cidDisplay, name, description, tags)
609+ if ((validateArtwork != ""))
610+ then throw("Something went wrong!")
620611 else {
621- let entryExist = getStringByKey(keyTxidByHashOwner(sha256Hash, caller))
622- if ((entryExist != ""))
623- then throw("You already added it")
612+ let t01817018212 = validatePayment(i)
613+ let amount = t01817018212._1
614+ let assetId = t01817018212._2
615+ if (!(isDefined(amount)))
616+ then throw("Something went wrong")
624617 else {
625- let hashExist = getStringByKey(keyOwnerByHash(sha256Hash))
626- if ((hashExist != ""))
627- then throw("This hash is already registered")
628- else [StringEntry(keyOwnerByHash(sha256Hash), caller), StringEntry(keyTxidByHashOwner(sha256Hash, caller), artId), IntegerEntry(keyDate(caller, artId), date), StringEntry(keyName(caller, artId), name), StringEntry(keyDesc(caller, artId), description), StringEntry(keyDisplayCid(caller, artId), cidDisplay), StringEntry(keyType(caller, artId), type), StringEntry(keyTags(caller, artId), tags), IntegerEntry(keyMaxMint(caller, artId), 0), IntegerEntry(keyIssued(caller, artId), 0), BooleanEntry(keyOnSale(caller, artId), false), StringEntry(keyHashByTxidAddr(caller, artId), sha256Hash), StringEntry(keyEntitlement(caller, artId), entitlement), ScriptTransfer(Address(fromBase58String(feeReceiver)), amount, assetId)]
618+ let previewData = if (containsElement(Previewtypes, type))
619+ then [StringEntry(keyPreviewCid(caller, artId), preview)]
620+ else nil
621+ let invokeCollectionCreate = invoke(valueOrErrorMessage(addressFromString(collectionsDapp), (collectionsDapp + " not found")), "collectionProcess", [collection, subcollection, caller], nil)
622+ if ((invokeCollectionCreate == invokeCollectionCreate))
623+ then {
624+ let idCollection = match invokeCollectionCreate {
625+ case r: String =>
626+ r
627+ case _ =>
628+ throw("Incorrect invoke result")
629+ }
630+ let entryExist = getStringByKey(keyTxidByHashOwner(sha256Hash, caller))
631+ if ((entryExist != ""))
632+ then throw("You already added it")
633+ else {
634+ let hashExist = getStringByKey(keyOwnerByHash(sha256Hash))
635+ if ((hashExist != ""))
636+ then throw("This hash is already registered")
637+ else (previewData ++ [StringEntry(keyOwnerByHash(sha256Hash), caller), StringEntry(keyTxidByHashOwner(sha256Hash, caller), artId), IntegerEntry(keyDate(caller, artId), date), StringEntry(keyName(caller, artId), name), StringEntry(keyDesc(caller, artId), description), StringEntry(keyDisplayCid(caller, artId), cidDisplay), StringEntry(keyType(caller, artId), type), StringEntry(keyTags(caller, artId), tags), IntegerEntry(keyMaxMint(caller, artId), 0), IntegerEntry(keyIssued(caller, artId), 0), BooleanEntry(keyOnSale(caller, artId), false), StringEntry(keyHashByTxidAddr(caller, artId), sha256Hash), StringEntry(keyEntitlement(caller, artId), entitlement), ScriptTransfer(Address(fromBase58String(feeReceiver)), amount, assetId)])
638+ }
639+ }
640+ else throw("Strict value is not equal to itself.")
629641 }
630642 }
631643 }
644+ else throw("Unknown type")
632645 }
633646
634647
635648
636649 @Callable(i)
637-func sellArtwork (artId,price,maxMint,assetId,auctionType,minBid,duration) = {
638- let t02571425747 = idCallerDate(i)
639- let id = t02571425747._1
640- let caller = t02571425747._2
641- let artworkName = getStringByKey(keyName(caller, artId))
642- if (!(containsElement([auctionType1, auctionType2], auctionType)))
643- then throw("We don't know this auction type")
644- else if ((artworkName == ""))
645- then throw("This art doesn't match your account")
646- else {
647- let bidNbr = getIntegerByKey(("current_bidamount_" + artId))
648- if (!(acceptedAssetIds(assetId)))
649- then throw("Something went wrong!")
650- else if (!(validateMinSell(assetId, price)))
651- then throw("Something went wrong!")
652- else {
653- let checkUser = validateUser(caller)
654- if ((checkUser != ""))
655- then throw(checkUser)
656- else {
657- let amountSold = getIntegerByKey(keyIssued(caller, artId))
658- let maxCanSell = getIntegerByKey(keyMaxMint(caller, artId))
659- if ((maxMint > 5000))
660- then throw("5000 editions max per artwork")
661- else if (if ((amountSold != 0))
662- then (amountSold == maxCanSell)
663- else false)
664- then throw("Max edition reached.")
665- else if (if ((amountSold > 0))
666- then (maxCanSell != maxMint)
667- else false)
668- then throw("Cannot change maximum issuable anymore")
669- else if (if ((bidNbr > 0))
670- then (maxCanSell != maxMint)
671- else false)
672- then throw("Cannot change maximum issuable with active orders")
673- else {
674- let sellStatus = if (if ((price > 0))
675- then (maxMint > 0)
650+func sellArtwork (artId,price,maxMint,assetId,auctionType,duration,add1,add2,add3,add1Sh,add2Sh,add3Sh) = {
651+ let invokeTeamFeeSplit = invoke(valueOrErrorMessage(addressFromString(feeDapp), (feeDapp + " not found")), "teamSplitFee", [artId, feeReceiver, "", "", 15, 0, 0], nil)
652+ if ((invokeTeamFeeSplit == invokeTeamFeeSplit))
653+ then {
654+ let invokeCreatorFeeSplit = invoke(valueOrErrorMessage(addressFromString(feeDapp), (feeDapp + " not found")), "creatorSplitFee", [artId, add1, add2, add3, add1Sh, add2Sh, add3Sh], nil)
655+ if ((invokeCreatorFeeSplit == invokeCreatorFeeSplit))
656+ then {
657+ let t02571425747 = idCallerDate(i)
658+ let id = t02571425747._1
659+ let caller = t02571425747._2
660+ let artworkName = getStringByKey(keyName(caller, artId))
661+ if (!(containsElement([auctionType1, auctionType2, auctionType3], auctionType)))
662+ then throw("We don't know this auction type")
663+ else if ((artworkName == ""))
664+ then throw("This art doesn't match your account")
665+ else {
666+ let bidNbr = getIntegerByKey(("current_bidamount_" + artId))
667+ if (!(acceptedAssetIds(assetId)))
668+ then throw("Something went wrong!")
669+ else if (!(validateMinSell(assetId, price)))
670+ then throw("Something went wrong!")
671+ else {
672+ let checkUser = validateUser(caller)
673+ if ((checkUser != ""))
674+ then throw(checkUser)
675+ else {
676+ let amountSold = getIntegerByKey(keyIssued(caller, artId))
677+ let maxCanSell = getIntegerByKey(keyMaxMint(caller, artId))
678+ if ((maxMint > 10000))
679+ then throw("10000 editions max per artwork")
680+ else if (if ((amountSold != 0))
681+ then (amountSold == maxCanSell)
676682 else false)
677- then true
678- else false
679- let endHeight = (duration + height)
680-[BooleanEntry(keyOnSale(caller, artId), sellStatus), IntegerEntry(keyPrice(caller, artId), price), IntegerEntry(keyMaxMint(caller, artId), maxMint), IntegerEntry(keyMinPrice(caller, artId), minBid), IntegerEntry(keyDuration(caller, artId), duration), IntegerEntry(keyEndHeight(caller, artId), endHeight), StringEntry(keyAssetIdAccepted(caller, artId), assetId), StringEntry(keyAuctionType(caller, artId), auctionType)]
681- }
682- }
683- }
684- }
683+ then throw("Max edition reached.")
684+ else if (if ((amountSold > 0))
685+ then (maxCanSell != maxMint)
686+ else false)
687+ then throw("Cannot change maximum issuable anymore")
688+ else if (if ((bidNbr > 0))
689+ then (maxCanSell != maxMint)
690+ else false)
691+ then throw("Cannot change maximum issuable with active orders")
692+ else {
693+ let sellStatus = if (if ((price > 0))
694+ then (maxMint > 0)
695+ else false)
696+ then true
697+ else false
698+ let endHeight = (duration + height)
699+[BooleanEntry(keyOnSale(caller, artId), sellStatus), IntegerEntry(keyPrice(caller, artId), price), IntegerEntry(keyMaxMint(caller, artId), maxMint), IntegerEntry(keyDuration(caller, artId), duration), IntegerEntry(keyEndHeight(caller, artId), endHeight), StringEntry(keyAssetIdAccepted(caller, artId), assetId), StringEntry(keyAuctionType(caller, artId), auctionType)]
700+ }
701+ }
702+ }
703+ }
704+ }
705+ else throw("Strict value is not equal to itself.")
706+ }
707+ else throw("Strict value is not equal to itself.")
685708 }
686709
687710
688711
689712 @Callable(i)
690-func buyArtwork (artId,issuer) = buyMint(i, artId, issuer, "", "", false)
713+func buyArtwork (artId,issuer) = {
714+ let auctionType = getStringByKey(keyAuctionType(issuer, artId))
715+ if ((auctionType == auctionType3))
716+ then buyMint(i, artId, issuer, "", "", false)
717+ else throw("Direct buy only allowed when no auction type is set!")
718+ }
719+
720+
721+
722+@Callable(i)
723+func updateTags (artist,artId,tags) = {
724+ let caller = toString(addressFromPublicKey(i.callerPublicKey))
725+ if (containsElement(owners, caller))
726+ then if ((size(split(tags, ",")) > 5))
727+ then throw("5 tags max.")
728+ else {
729+ let tagsOld = getStringByKeyOrError(keyTags(artist, artId), "No tags created with this key, so can't update!")
730+ if ((tags == tagsOld))
731+ then throw("Tags are the same as old tags!")
732+ else [StringEntry(keyTags(artist, artId), tags)]
733+ }
734+ else throw("no")
735+ }
691736
692737
693738
694739 @Callable(i)
695740 func deleteEntry (entry) = {
696741 let caller = toString(addressFromPublicKey(i.callerPublicKey))
697742 if (containsElement(owners, caller))
698743 then [DeleteEntry(entry)]
699744 else throw("no")
700745 }
701746
702747
703748
704749 @Callable(i)
705750 func setBid (artId,issuer) = {
706751 let auctionType = getStringByKey(keyAuctionType(issuer, artId))
707752 if ((auctionType == auctionType1))
708753 then setBidNonTraditional(i, artId, issuer)
709754 else if ((auctionType == auctionType2))
710755 then setBidTraditional(i, artId, issuer)
711756 else throw((("Unknown auction type :" + auctionType) + ", please contact the admins"))
712757 }
713758
714759
715760
716761 @Callable(i)
717762 func acceptBid (artId,issuer,bidId,bidOwner) = {
718763 let auctionType = getStringByKey(keyAuctionType(issuer, artId))
719764 if ((auctionType == auctionType1))
720765 then acceptBidNonTraditional(i, artId, issuer, bidId, bidOwner)
721766 else if ((auctionType == auctionType2))
722767 then acceptBidTraditional(i, artId, issuer, bidId, bidOwner)
723768 else throw((("Unknown auction type :" + auctionType) + ", please contact the admins"))
724769 }
725770
726771
727772
728773 @Callable(i)
729774 func cancelBid (artId,issuer,bidId) = {
730775 let auctionType = getStringByKey(keyAuctionType(issuer, artId))
731776 if ((auctionType == auctionType1))
732777 then cancelBidImpl(i, artId, issuer, bidId)
733778 else cancelBidImplTraditional(i, artId, issuer, bidId)
734779 }
735780
736781

github/deemru/w8io/169f3d6 
146.54 ms