tx · H18J33EC1QZhnFNnMm748K2TwS8ujG58A5pEiwrVv7B4

3NA73oUXjqp7SpudXWV1yMFuKm9awPbqsVz:  -0.01200000 Waves

2022.10.27 18:11 [2290992] smart account 3NA73oUXjqp7SpudXWV1yMFuKm9awPbqsVz > SELF 0.00000000 Waves

{ "type": 13, "id": "H18J33EC1QZhnFNnMm748K2TwS8ujG58A5pEiwrVv7B4", "fee": 1200000, "feeAssetId": null, "timestamp": 1666883495265, "version": 2, "chainId": 84, "sender": "3NA73oUXjqp7SpudXWV1yMFuKm9awPbqsVz", "senderPublicKey": "2mHW72YTfnxJ1M8WsdUQjgpp3a2SUbt9mbAiePGiuJok", "proofs": [ "2YtBkFdz1zBAjxBpkbqnsbeV3MJX9MKX8JLGk1FZMpLGu5kWs5EBEXCDqHmbEWg25tyzmxA2ZTLpRmDQGRAETU24" ], "script": "base64:AAIFAAAAAAAAAEAIAhIDCgEBEgMKAQgSAwoBCBIDCgEIEgMKAQgSAwoBCBIDCgEIEgMKAQgSAwoBCBIDCgEIEgUKAwgIARIDCgEIAAAAKAEAAAAQZ2V0U3RyaW5nT3JUaHJvdwAAAAIAAAAHYWRkcmVzcwAAAANrZXkJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAAdhZGRyZXNzBQAAAANrZXkJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAADENhbid0IHJlYWQgJwUAAAADa2V5AgAAAA0nIGF0IGFkZHJlc3MgCQAEJQAAAAEFAAAAB2FkZHJlc3MBAAAAEWdldEludGVnZXJPclRocm93AAAAAgAAAAdhZGRyZXNzAAAAA2tleQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAAB2FkZHJlc3MFAAAAA2tleQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAMQ2FuJ3QgcmVhZCAnBQAAAANrZXkCAAAADScgYXQgYWRkcmVzcyAJAAQlAAAAAQUAAAAHYWRkcmVzcwEAAAATcGFyc2VBZGRyZXNzT3JUaHJvdwAAAAEAAAAMbWF5YmVBZGRyZXNzCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQmAAAAAQUAAAAMbWF5YmVBZGRyZXNzCQABLAAAAAIJAAEsAAAAAgIAAAAaQ2FuJ3QgcGFyc2UgYWRkcmVzcyBmcm9tICcFAAAADG1heWJlQWRkcmVzcwIAAAABJwEAAAAKa2V5X2VudGl0eQAAAAMAAAAEbmFtZQAAAAJwawAAAAhwcm9wZXJ0eQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACBQAAAARuYW1lAgAAAAFfBQAAAAJwawIAAAABXwUAAAAIcHJvcGVydHkBAAAADmtleV9Ub2tlbl9uYW1lAAAAAQAAAAd0b2tlbklkCQEAAAAKa2V5X2VudGl0eQAAAAMCAAAABVRva2VuBQAAAAd0b2tlbklkAgAAAARuYW1lAQAAAA5rZXlfTmFtZV90b2tlbgAAAAEAAAAEbmFtZQkBAAAACmtleV9lbnRpdHkAAAADAgAAAAROYW1lBQAAAARuYW1lAgAAAAV0b2tlbgEAAAAOa2V5X05hbWVfb3duZXIAAAABAAAABG5hbWUJAQAAAAprZXlfZW50aXR5AAAAAwIAAAAETmFtZQUAAAAEbmFtZQIAAAAFb3duZXIBAAAAEWtleV9OYW1lX3Jlc29sdmVyAAAAAQAAAARuYW1lCQEAAAAKa2V5X2VudGl0eQAAAAMCAAAABE5hbWUFAAAABG5hbWUCAAAACHJlc29sdmVyAQAAABJrZXlfTmFtZV9leHBpcmVzQXQAAAABAAAABG5hbWUJAQAAAAprZXlfZW50aXR5AAAAAwIAAAAETmFtZQUAAAAEbmFtZQIAAAAJZXhwaXJlc0F0AQAAABJrZXlfTmFtZV9jcmVhdGVkQXQAAAABAAAABG5hbWUJAQAAAAprZXlfZW50aXR5AAAAAwIAAAAETmFtZQUAAAAEbmFtZQIAAAAJY3JlYXRlZEF0AAAAAAtrZXlfbmFtZVRUTAIAAAAHbmFtZVRUTAAAAAAPa2V5X2NvbnRyb2xsZXJzAgAAAAtjb250cm9sbGVycwEAAAAJX3NldE93bmVyAAAAAgAAAARuYW1lAAAABW93bmVyCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAAA5rZXlfTmFtZV9vd25lcgAAAAEFAAAABG5hbWUFAAAABW93bmVyBQAAAANuaWwBAAAACV9nZXRPd25lcgAAAAEAAAAEbmFtZQkABB0AAAACBQAAAAR0aGlzCQEAAAAOa2V5X05hbWVfb3duZXIAAAABBQAAAARuYW1lAQAAAAxfZ2V0UmVzb2x2ZXIAAAABAAAABG5hbWUJAAQdAAAAAgUAAAAEdGhpcwkBAAAAEWtleV9OYW1lX3Jlc29sdmVyAAAAAQUAAAAEbmFtZQEAAAAJX2dldFRva2VuAAAAAQAAAARuYW1lCQAEHQAAAAIFAAAABHRoaXMJAQAAAA5rZXlfTmFtZV90b2tlbgAAAAEFAAAABG5hbWUBAAAADV9nZXRDcmVhdGVkQXQAAAABAAAABG5hbWUJAAQaAAAAAgUAAAAEdGhpcwkBAAAAEmtleV9OYW1lX2NyZWF0ZWRBdAAAAAEFAAAABG5hbWUBAAAADV9nZXRFeHBpcmVzQXQAAAABAAAABG5hbWUJAAQaAAAAAgUAAAAEdGhpcwkBAAAAEmtleV9OYW1lX2V4cGlyZXNBdAAAAAEFAAAABG5hbWUBAAAAD19nZXRDb250cm9sbGVycwAAAAAJAAQdAAAAAgUAAAAEdGhpcwUAAAAPa2V5X2NvbnRyb2xsZXJzAAAAAAtjb250cm9sbGVycwQAAAAHJG1hdGNoMAkBAAAAD19nZXRDb250cm9sbGVycwAAAAADCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAAEcmVwcgUAAAAHJG1hdGNoMAkABLUAAAACBQAAAARyZXByAgAAAAEsBQAAAANuaWwAAAAAB25hbWVUVEwJAQAAABFnZXRJbnRlZ2VyT3JUaHJvdwAAAAIFAAAABHRoaXMFAAAAC2tleV9uYW1lVFRMAQAAABBpc1JlZ2lzdGVyZWROYW1lAAAAAQAAAARuYW1lCQEAAAAJaXNEZWZpbmVkAAAAAQkABB0AAAACBQAAAAR0aGlzCQEAAAAOa2V5X05hbWVfdG9rZW4AAAABBQAAAARuYW1lAQAAAA1pc0NyZWF0ZWROYW1lAAAAAQAAAARuYW1lCQEAAAAJaXNEZWZpbmVkAAAAAQkBAAAADV9nZXRDcmVhdGVkQXQAAAABBQAAAARuYW1lAQAAAA1pc0V4cGlyZWROYW1lAAAAAQAAAARuYW1lBAAAAAckbWF0Y2gwCQEAAAANX2dldEV4cGlyZXNBdAAAAAEFAAAABG5hbWUDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAA0ludAQAAAAJZXhwaXJlc0F0BQAAAAckbWF0Y2gwCQAAZgAAAAIIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wBQAAAAlleHBpcmVzQXQHAQAAAAxpc0FjdGl2ZU5hbWUAAAABAAAABG5hbWUDAwkBAAAAEGlzUmVnaXN0ZXJlZE5hbWUAAAABBQAAAARuYW1lCQEAAAANaXNDcmVhdGVkTmFtZQAAAAEFAAAABG5hbWUHCQEAAAABIQAAAAEJAQAAAA1pc0V4cGlyZWROYW1lAAAAAQUAAAAEbmFtZQcBAAAAC2lzVmFsaWROYW1lAAAAAQAAAARuYW1lBAAAAAdzeW1ib2xzAgAAACVhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejEyMzQ1Njc4OTAtCgEAAAANdmFsaWRhdGVDaGFycwAAAAIAAAAHaXNWYWxpZAAAAARjaGFyAwUAAAAHaXNWYWxpZAkBAAAACGNvbnRhaW5zAAAAAgUAAAAHc3ltYm9scwUAAAAEY2hhcgcDAwMDAwkAAGYAAAACCQABMQAAAAEFAAAABG5hbWUAAAAAAAAAAAAJAABnAAAAAgAAAAAAAAAAPwkAATEAAAABBQAAAARuYW1lBwkBAAAAAiE9AAAAAgkABLMAAAACBQAAAARuYW1lAgAAAAItLQAAAAAAAAAAAgcJAQAAAAIhPQAAAAIJAASzAAAAAgUAAAAEbmFtZQIAAAABLQAAAAAAAAAAAAcJAQAAAAIhPQAAAAIJAAS3AAAAAgUAAAAEbmFtZQIAAAABLQkAAGUAAAACCQABMQAAAAEFAAAABG5hbWUAAAAAAAAAAAEHCgAAAAACJGwJAAS1AAAAAgUAAAAEbmFtZQIAAAAACgAAAAACJHMJAAGQAAAAAQUAAAACJGwKAAAAAAUkYWNjMAYKAQAAAAUkZjBfMQAAAAIAAAACJGEAAAACJGkDCQAAZwAAAAIFAAAAAiRpBQAAAAIkcwUAAAACJGEJAQAAAA12YWxpZGF0ZUNoYXJzAAAAAgUAAAACJGEJAAGRAAAAAgUAAAACJGwFAAAAAiRpCgEAAAAFJGYwXzIAAAACAAAAAiRhAAAAAiRpAwkAAGcAAAACBQAAAAIkaQUAAAACJHMFAAAAAiRhCQAAAgAAAAECAAAAFExpc3Qgc2l6ZSBleGNlZWRzIDYzCQEAAAAFJGYwXzIAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACCQEAAAAFJGYwXzEAAAACBQAAAAUkYWNjMAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAgAAAAAAAAAAAwAAAAAAAAAABAAAAAAAAAAABQAAAAAAAAAABgAAAAAAAAAABwAAAAAAAAAACAAAAAAAAAAACQAAAAAAAAAACgAAAAAAAAAACwAAAAAAAAAADAAAAAAAAAAADQAAAAAAAAAADgAAAAAAAAAADwAAAAAAAAAAEAAAAAAAAAAAEQAAAAAAAAAAEgAAAAAAAAAAEwAAAAAAAAAAFAAAAAAAAAAAFQAAAAAAAAAAFgAAAAAAAAAAFwAAAAAAAAAAGAAAAAAAAAAAGQAAAAAAAAAAGgAAAAAAAAAAGwAAAAAAAAAAHAAA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ZXdUb2tlbklkCQAEOAAAAAEJAAGRAAAAAgUAAAANaXNzdWVOZXdUb2tlbgAAAAAAAAAAAAQAAAALbmV3VG9rZW5TdHIJAAJYAAAAAQUAAAAKbmV3VG9rZW5JZAQAAAAXcmVzdG9yZU5hbWVXaXRoTmV3VG9rZW4JAQAAABVfcmVzdG9yZU5hbWVXaXRoVG9rZW4AAAACBQAAAARuYW1lBQAAAAtuZXdUb2tlblN0cgQAAAAXdHJhbnNmZXJOZXdUb2tlblRvT3duZXIJAQAAABVfdHJhbnNmZXJUb2tlblRvT3duZXIAAAACBQAAAAtuZXdUb2tlblN0cgUAAAAPbmV3T3duZXJBZGRyZXNzCQAETgAAAAIJAAROAAAAAgUAAAANaXNzdWVOZXdUb2tlbgUAAAAXcmVzdG9yZU5hbWVXaXRoTmV3VG9rZW4FAAAAF3RyYW5zZmVyTmV3VG9rZW5Ub093bmVyAwMFAAAADGlzVG9rZW5Pd25lcgUAAAAIaGFzVG9rZW4HCQAAAgAAAAECAAAAHFlvdSBhbHJlYWR5IG93biBhIG5hbWUgdG9rZW4DCQEAAAABIQAAAAEFAAAACGhhc1Rva2VuCQAAAgAAAAECAAAAG1lvdSBkb24ndCBoYXZlIGEgbmFtZSB0b2tlbgkBAAAACV9zZXRPd25lcgAAAAIFAAAABG5hbWUFAAAAD25ld093bmVyQWRkcmVzcwAAAAChR4yM", "height": 2290992, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 45RpUf1vCSNTpZvjdJzy3o3mS8KCJtDFbTF9xzx6PNjk Next: H1N1y8DoCe3tXvB7qR2nBbVTWMq2PYdP2kyR6f1c2kdZ Diff:
OldNewDifferences
1313 func key_entity (name,pk,property) = ((((name + "_") + pk) + "_") + property)
1414
1515
16+func key_Token_name (tokenId) = key_entity("Token", tokenId, "name")
17+
18+
1619 func key_Name_token (name) = key_entity("Name", name, "token")
1720
1821
19-let key_meedusAddress = "meedusAddress"
22+func key_Name_owner (name) = key_entity("Name", name, "owner")
2023
21-let key_registrarAddress = "registrarAddress"
2224
23-let key_meedusInitTimestamp = "meedusInitTimestamp"
25+func key_Name_resolver (name) = key_entity("Name", name, "resolver")
2426
25-let meedusAddress = getStringOrThrow(this, key_meedusAddress)
2627
27-let meedus = parseAddressOrThrow(meedusAddress)
28+func key_Name_expiresAt (name) = key_entity("Name", name, "expiresAt")
2829
29-let registrarAddress = getStringOrThrow(this, key_registrarAddress)
3030
31-let registrar = parseAddressOrThrow(registrarAddress)
31+func key_Name_createdAt (name) = key_entity("Name", name, "createdAt")
3232
33-let meedusInitTimestamp = getIntegerOrThrow(this, key_meedusInitTimestamp)
33+
34+let key_nameTTL = "nameTTL"
35+
36+let key_controllers = "controllers"
37+
38+func _setOwner (name,owner) = [StringEntry(key_Name_owner(name), owner)]
39+
40+
41+func _getOwner (name) = getString(this, key_Name_owner(name))
42+
43+
44+func _getResolver (name) = getString(this, key_Name_resolver(name))
45+
46+
47+func _getToken (name) = getString(this, key_Name_token(name))
48+
49+
50+func _getCreatedAt (name) = getInteger(this, key_Name_createdAt(name))
51+
52+
53+func _getExpiresAt (name) = getInteger(this, key_Name_expiresAt(name))
54+
55+
56+func _getControllers () = getString(this, key_controllers)
57+
58+
59+let controllers = match _getControllers() {
60+ case repr: String =>
61+ split(repr, ",")
62+ case _ =>
63+ nil
64+}
65+
66+let nameTTL = getIntegerOrThrow(this, key_nameTTL)
67+
68+func isRegisteredName (name) = isDefined(getString(this, key_Name_token(name)))
69+
70+
71+func isCreatedName (name) = isDefined(_getCreatedAt(name))
72+
73+
74+func isExpiredName (name) = match _getExpiresAt(name) {
75+ case expiresAt: Int =>
76+ (lastBlock.timestamp > expiresAt)
77+ case _ =>
78+ false
79+}
80+
81+
82+func isActiveName (name) = if (if (isRegisteredName(name))
83+ then isCreatedName(name)
84+ else false)
85+ then !(isExpiredName(name))
86+ else false
87+
88+
89+func isValidName (name) = {
90+ let symbols = "abcdefghijklmnopqrstuvwxyz1234567890-"
91+ func validateChars (isValid,char) = if (isValid)
92+ then contains(symbols, char)
93+ else false
94+
95+ if (if (if (if (if ((size(name) > 0))
96+ then (63 >= size(name))
97+ else false)
98+ then (indexOf(name, "--") != 2)
99+ else false)
100+ then (indexOf(name, "-") != 0)
101+ else false)
102+ then (lastIndexOf(name, "-") != (size(name) - 1))
103+ else false)
104+ then {
105+ let $l = split(name, "")
106+ let $s = size($l)
107+ let $acc0 = true
108+ func $f0_1 ($a,$i) = if (($i >= $s))
109+ then $a
110+ else validateChars($a, $l[$i])
111+
112+ func $f0_2 ($a,$i) = if (($i >= $s))
113+ then $a
114+ else throw("List size exceeds 63")
115+
116+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63)
117+ }
118+ else false
119+ }
120+
121+
122+func isAvailableName (name) = if (isValidName(name))
123+ then if (!(isRegisteredName(name)))
124+ then true
125+ else isExpiredName(name)
126+ else false
127+
128+
129+func isValidAddress (maybeAddress) = isDefined(addressFromString(maybeAddress))
130+
131+
132+func isAdmin (inv) = (inv.caller == this)
133+
134+
135+func isOwner (inv,name) = (toString(inv.originCaller) == valueOrElse(_getOwner(name), ""))
136+
137+
138+func isController (address) = containsElement(controllers, address)
139+
140+
141+func _splitLastLabel (name) = {
142+ let labels = split(name, ".")
143+ let lastIndex = (size(labels) - 1)
144+ let lastLabel = labels[lastIndex]
145+ let restLabels = makeString(removeByIndex(labels, lastIndex), ".")
146+ $Tuple2(lastLabel, restLabels)
147+ }
148+
149+
150+func _issueNameToken (name) = [Issue(if ((size(name) > 16))
151+ then (take(name, 15) + "~")
152+ else take(name, 16), (name + ".waves"), 1, 0, false)]
153+
154+
155+func _registerNameWithToken (name,tokenId,createdAt) = [StringEntry(key_Name_token(name), tokenId), StringEntry(key_Token_name(tokenId), name), IntegerEntry(key_Name_createdAt(name), createdAt), IntegerEntry(key_Name_expiresAt(name), (createdAt + nameTTL))]
156+
157+
158+func _restoreNameWithToken (name,tokenId) = [StringEntry(key_Name_token(name), tokenId), StringEntry(key_Token_name(tokenId), name)]
159+
160+
161+func _transferTokenToOwner (tokenId,owner) = [ScriptTransfer(parseAddressOrThrow(owner), 1, fromBase58String(tokenId))]
162+
163+
164+func modifiers (validations) = unit
165+
166+
167+func onlyAdmin (inv) = if (isAdmin(inv))
168+ then unit
169+ else throw("Permission denied")
170+
171+
172+func onlyController (inv) = if (if (isAdmin(inv))
173+ then true
174+ else isController(toString(inv.caller)))
175+ then unit
176+ else throw("Permission denied")
177+
178+
179+func onlyOwner (inv,name) = if (if (isAdmin(inv))
180+ then true
181+ else isOwner(inv, name))
182+ then unit
183+ else throw("Permission denied")
184+
34185
35186 @Callable(inv)
36-func init (meedusAddress,registrarAddress,meedusInitTimestamp) = [StringEntry(key_meedusAddress, meedusAddress), StringEntry(key_registrarAddress, registrarAddress), IntegerEntry(key_meedusInitTimestamp, meedusInitTimestamp)]
187+func init (nameTTL) = valueOrElse(modifiers([onlyAdmin(inv), if ((nameTTL > 0))
188+ then unit
189+ else throw("TTL cannot be negative")]), [IntegerEntry(key_nameTTL, nameTTL)])
37190
38191
39192
40193 @Callable(inv)
41-func transfer (addressStr,asset) = {
42- let address = parseAddressOrThrow(addressStr)
43-[ScriptTransfer(address, 1, asset)]
44- }
194+func supportsInterface (interfaceId) = $Tuple2(nil, containsElement(["getOwner", "getResolver", "getNameCreated", "getNameExpires"], interfaceId))
45195
46196
47197
48198 @Callable(inv)
49-func reserve (name) = {
50- let caller = inv.caller
51- let callerStr = toString(caller)
52- if ((this != caller))
53- then throw("Only self call are allowed")
54- else {
55- let reservation = invoke(registrar, "register", [name, callerStr, meedusInitTimestamp], nil)
56- if ((reservation == reservation))
57- then nil
58- else throw("Strict value is not equal to itself.")
59- }
60- }
199+func addController (address) = valueOrElse(modifiers([onlyAdmin(inv), if (isValidAddress(address))
200+ then unit
201+ else throw("Controller must be a valid address"), if (!(isController(address)))
202+ then unit
203+ else throw((("Controller `" + address) + "` is already registered"))]), [StringEntry(key_controllers, makeString((controllers :+ address), ","))])
61204
62205
63206
64207 @Callable(inv)
65-func exchange () = {
66- let caller = inv.originCaller
67- let callerStr = toString(caller)
68- let pmt = inv.payments[0]
69- let assetId = valueOrErrorMessage(pmt.assetId, "Asset cannot be WAVES")
70- let asset = valueOrErrorMessage(assetInfo(assetId), "Invalid asset")
71- let isMeedusNFT = if (if (if ((asset.issuer == meedus))
72- then (asset.quantity == 1)
208+func removeController (address) = valueOrElse(modifiers([onlyAdmin(inv), if (isController(address))
209+ then unit
210+ else throw((("Controller `" + address) + "` is not registered"))]), {
211+ let controllerIndex = value(indexOf(controllers, address))
212+[StringEntry(key_controllers, makeString(removeByIndex(controllers, controllerIndex), ","))]
213+ })
214+
215+
216+
217+@Callable(inv)
218+func isValid (name) = $Tuple2(nil, isValidName(name))
219+
220+
221+
222+@Callable(inv)
223+func isAvailable (name) = $Tuple2(nil, isAvailableName(name))
224+
225+
226+
227+@Callable(inv)
228+func getOwner (name) = $Tuple2(nil, _getOwner(_splitLastLabel(name)._1))
229+
230+
231+
232+@Callable(inv)
233+func getResolver (name) = $Tuple2(nil, _getResolver(_splitLastLabel(name)._1))
234+
235+
236+
237+@Callable(inv)
238+func getNameCreated (name) = $Tuple2(nil, _getCreatedAt(_splitLastLabel(name)._1))
239+
240+
241+
242+@Callable(inv)
243+func getNameExpires (name) = $Tuple2(nil, _getExpiresAt(_splitLastLabel(name)._1))
244+
245+
246+
247+@Callable(inv)
248+func register (name,owner,createdAt) = valueOrElse(modifiers([onlyController(inv), if (isAvailableName(name))
249+ then unit
250+ else throw((("`" + name) + "` cannot be registered")), if (isValidAddress(owner))
251+ then unit
252+ else throw("Owner must be a valid address"), if ((createdAt > 0))
253+ then unit
254+ else throw("CreatedAt cannot be negative"), if ((lastBlock.timestamp >= createdAt))
255+ then unit
256+ else throw("CreatedAt cannot be in the future")]), {
257+ let issueNameToken = _issueNameToken(name)
258+ let tokenId = calculateAssetId(issueNameToken[0])
259+ let tokenStr = toBase58String(tokenId)
260+ let registerNameWithToken = _registerNameWithToken(name, tokenStr, createdAt)
261+ let transferTokenToOwner = _transferTokenToOwner(tokenStr, owner)
262+ let setOwnership = _setOwner(name, owner)
263+ (((issueNameToken ++ registerNameWithToken) ++ transferTokenToOwner) ++ setOwnership)
264+ })
265+
266+
267+
268+@Callable(inv)
269+func reclaim (name) = valueOrElse(modifiers([if (isActiveName(name))
270+ then unit
271+ else throw((("`" + name) + "` is not active"))]), {
272+ let newOwner = inv.originCaller
273+ let newOwnerAddress = toString(newOwner)
274+ let tokenStr = valueOrErrorMessage(_getToken(name), (("No token is issued for `" + name) + "`"))
275+ let tokenId = fromBase58String(tokenStr)
276+ let hasToken = (assetBalance(newOwner, tokenId) == 1)
277+ let isTokenOwner = isOwner(inv, name)
278+ let isTokenExists = match assetInfo(tokenId) {
279+ case token: Asset =>
280+ (token.quantity == 1)
281+ case _ =>
282+ false
283+ }
284+ if (if (isTokenOwner)
285+ then !(isTokenExists)
73286 else false)
74- then (asset.decimals == 0)
75- else false)
76- then (asset.reissuable == false)
77- else false
78- if (if ((pmt.amount != 1))
79- then true
80- else !(isMeedusNFT))
81- then throw("Payment should contain Meedus NFT")
82- else {
83- let tokenStr = getStringOrThrow(registrar, key_Name_token(asset.name))
84- let token = toBytes(tokenStr)
85- let transfer = invoke(this, "transfer", [callerStr, assetId], nil)
86- if ((transfer == transfer))
87- then nil
88- else throw("Strict value is not equal to itself.")
287+ then {
288+ let issueNewToken = _issueNameToken(name)
289+ let newTokenId = calculateAssetId(issueNewToken[0])
290+ let newTokenStr = toBase58String(newTokenId)
291+ let restoreNameWithNewToken = _restoreNameWithToken(name, newTokenStr)
292+ let transferNewTokenToOwner = _transferTokenToOwner(newTokenStr, newOwnerAddress)
293+ ((issueNewToken ++ restoreNameWithNewToken) ++ transferNewTokenToOwner)
89294 }
90- }
295+ else if (if (isTokenOwner)
296+ then hasToken
297+ else false)
298+ then throw("You already own a name token")
299+ else if (!(hasToken))
300+ then throw("You don't have a name token")
301+ else _setOwner(name, newOwnerAddress)
302+ })
91303
92304
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func getStringOrThrow (address,key) = valueOrErrorMessage(getString(address, key), ((("Can't read '" + key) + "' at address ") + toString(address)))
55
66
77 func getIntegerOrThrow (address,key) = valueOrErrorMessage(getInteger(address, key), ((("Can't read '" + key) + "' at address ") + toString(address)))
88
99
1010 func parseAddressOrThrow (maybeAddress) = valueOrErrorMessage(addressFromString(maybeAddress), (("Can't parse address from '" + maybeAddress) + "'"))
1111
1212
1313 func key_entity (name,pk,property) = ((((name + "_") + pk) + "_") + property)
1414
1515
16+func key_Token_name (tokenId) = key_entity("Token", tokenId, "name")
17+
18+
1619 func key_Name_token (name) = key_entity("Name", name, "token")
1720
1821
19-let key_meedusAddress = "meedusAddress"
22+func key_Name_owner (name) = key_entity("Name", name, "owner")
2023
21-let key_registrarAddress = "registrarAddress"
2224
23-let key_meedusInitTimestamp = "meedusInitTimestamp"
25+func key_Name_resolver (name) = key_entity("Name", name, "resolver")
2426
25-let meedusAddress = getStringOrThrow(this, key_meedusAddress)
2627
27-let meedus = parseAddressOrThrow(meedusAddress)
28+func key_Name_expiresAt (name) = key_entity("Name", name, "expiresAt")
2829
29-let registrarAddress = getStringOrThrow(this, key_registrarAddress)
3030
31-let registrar = parseAddressOrThrow(registrarAddress)
31+func key_Name_createdAt (name) = key_entity("Name", name, "createdAt")
3232
33-let meedusInitTimestamp = getIntegerOrThrow(this, key_meedusInitTimestamp)
33+
34+let key_nameTTL = "nameTTL"
35+
36+let key_controllers = "controllers"
37+
38+func _setOwner (name,owner) = [StringEntry(key_Name_owner(name), owner)]
39+
40+
41+func _getOwner (name) = getString(this, key_Name_owner(name))
42+
43+
44+func _getResolver (name) = getString(this, key_Name_resolver(name))
45+
46+
47+func _getToken (name) = getString(this, key_Name_token(name))
48+
49+
50+func _getCreatedAt (name) = getInteger(this, key_Name_createdAt(name))
51+
52+
53+func _getExpiresAt (name) = getInteger(this, key_Name_expiresAt(name))
54+
55+
56+func _getControllers () = getString(this, key_controllers)
57+
58+
59+let controllers = match _getControllers() {
60+ case repr: String =>
61+ split(repr, ",")
62+ case _ =>
63+ nil
64+}
65+
66+let nameTTL = getIntegerOrThrow(this, key_nameTTL)
67+
68+func isRegisteredName (name) = isDefined(getString(this, key_Name_token(name)))
69+
70+
71+func isCreatedName (name) = isDefined(_getCreatedAt(name))
72+
73+
74+func isExpiredName (name) = match _getExpiresAt(name) {
75+ case expiresAt: Int =>
76+ (lastBlock.timestamp > expiresAt)
77+ case _ =>
78+ false
79+}
80+
81+
82+func isActiveName (name) = if (if (isRegisteredName(name))
83+ then isCreatedName(name)
84+ else false)
85+ then !(isExpiredName(name))
86+ else false
87+
88+
89+func isValidName (name) = {
90+ let symbols = "abcdefghijklmnopqrstuvwxyz1234567890-"
91+ func validateChars (isValid,char) = if (isValid)
92+ then contains(symbols, char)
93+ else false
94+
95+ if (if (if (if (if ((size(name) > 0))
96+ then (63 >= size(name))
97+ else false)
98+ then (indexOf(name, "--") != 2)
99+ else false)
100+ then (indexOf(name, "-") != 0)
101+ else false)
102+ then (lastIndexOf(name, "-") != (size(name) - 1))
103+ else false)
104+ then {
105+ let $l = split(name, "")
106+ let $s = size($l)
107+ let $acc0 = true
108+ func $f0_1 ($a,$i) = if (($i >= $s))
109+ then $a
110+ else validateChars($a, $l[$i])
111+
112+ func $f0_2 ($a,$i) = if (($i >= $s))
113+ then $a
114+ else throw("List size exceeds 63")
115+
116+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63)
117+ }
118+ else false
119+ }
120+
121+
122+func isAvailableName (name) = if (isValidName(name))
123+ then if (!(isRegisteredName(name)))
124+ then true
125+ else isExpiredName(name)
126+ else false
127+
128+
129+func isValidAddress (maybeAddress) = isDefined(addressFromString(maybeAddress))
130+
131+
132+func isAdmin (inv) = (inv.caller == this)
133+
134+
135+func isOwner (inv,name) = (toString(inv.originCaller) == valueOrElse(_getOwner(name), ""))
136+
137+
138+func isController (address) = containsElement(controllers, address)
139+
140+
141+func _splitLastLabel (name) = {
142+ let labels = split(name, ".")
143+ let lastIndex = (size(labels) - 1)
144+ let lastLabel = labels[lastIndex]
145+ let restLabels = makeString(removeByIndex(labels, lastIndex), ".")
146+ $Tuple2(lastLabel, restLabels)
147+ }
148+
149+
150+func _issueNameToken (name) = [Issue(if ((size(name) > 16))
151+ then (take(name, 15) + "~")
152+ else take(name, 16), (name + ".waves"), 1, 0, false)]
153+
154+
155+func _registerNameWithToken (name,tokenId,createdAt) = [StringEntry(key_Name_token(name), tokenId), StringEntry(key_Token_name(tokenId), name), IntegerEntry(key_Name_createdAt(name), createdAt), IntegerEntry(key_Name_expiresAt(name), (createdAt + nameTTL))]
156+
157+
158+func _restoreNameWithToken (name,tokenId) = [StringEntry(key_Name_token(name), tokenId), StringEntry(key_Token_name(tokenId), name)]
159+
160+
161+func _transferTokenToOwner (tokenId,owner) = [ScriptTransfer(parseAddressOrThrow(owner), 1, fromBase58String(tokenId))]
162+
163+
164+func modifiers (validations) = unit
165+
166+
167+func onlyAdmin (inv) = if (isAdmin(inv))
168+ then unit
169+ else throw("Permission denied")
170+
171+
172+func onlyController (inv) = if (if (isAdmin(inv))
173+ then true
174+ else isController(toString(inv.caller)))
175+ then unit
176+ else throw("Permission denied")
177+
178+
179+func onlyOwner (inv,name) = if (if (isAdmin(inv))
180+ then true
181+ else isOwner(inv, name))
182+ then unit
183+ else throw("Permission denied")
184+
34185
35186 @Callable(inv)
36-func init (meedusAddress,registrarAddress,meedusInitTimestamp) = [StringEntry(key_meedusAddress, meedusAddress), StringEntry(key_registrarAddress, registrarAddress), IntegerEntry(key_meedusInitTimestamp, meedusInitTimestamp)]
187+func init (nameTTL) = valueOrElse(modifiers([onlyAdmin(inv), if ((nameTTL > 0))
188+ then unit
189+ else throw("TTL cannot be negative")]), [IntegerEntry(key_nameTTL, nameTTL)])
37190
38191
39192
40193 @Callable(inv)
41-func transfer (addressStr,asset) = {
42- let address = parseAddressOrThrow(addressStr)
43-[ScriptTransfer(address, 1, asset)]
44- }
194+func supportsInterface (interfaceId) = $Tuple2(nil, containsElement(["getOwner", "getResolver", "getNameCreated", "getNameExpires"], interfaceId))
45195
46196
47197
48198 @Callable(inv)
49-func reserve (name) = {
50- let caller = inv.caller
51- let callerStr = toString(caller)
52- if ((this != caller))
53- then throw("Only self call are allowed")
54- else {
55- let reservation = invoke(registrar, "register", [name, callerStr, meedusInitTimestamp], nil)
56- if ((reservation == reservation))
57- then nil
58- else throw("Strict value is not equal to itself.")
59- }
60- }
199+func addController (address) = valueOrElse(modifiers([onlyAdmin(inv), if (isValidAddress(address))
200+ then unit
201+ else throw("Controller must be a valid address"), if (!(isController(address)))
202+ then unit
203+ else throw((("Controller `" + address) + "` is already registered"))]), [StringEntry(key_controllers, makeString((controllers :+ address), ","))])
61204
62205
63206
64207 @Callable(inv)
65-func exchange () = {
66- let caller = inv.originCaller
67- let callerStr = toString(caller)
68- let pmt = inv.payments[0]
69- let assetId = valueOrErrorMessage(pmt.assetId, "Asset cannot be WAVES")
70- let asset = valueOrErrorMessage(assetInfo(assetId), "Invalid asset")
71- let isMeedusNFT = if (if (if ((asset.issuer == meedus))
72- then (asset.quantity == 1)
208+func removeController (address) = valueOrElse(modifiers([onlyAdmin(inv), if (isController(address))
209+ then unit
210+ else throw((("Controller `" + address) + "` is not registered"))]), {
211+ let controllerIndex = value(indexOf(controllers, address))
212+[StringEntry(key_controllers, makeString(removeByIndex(controllers, controllerIndex), ","))]
213+ })
214+
215+
216+
217+@Callable(inv)
218+func isValid (name) = $Tuple2(nil, isValidName(name))
219+
220+
221+
222+@Callable(inv)
223+func isAvailable (name) = $Tuple2(nil, isAvailableName(name))
224+
225+
226+
227+@Callable(inv)
228+func getOwner (name) = $Tuple2(nil, _getOwner(_splitLastLabel(name)._1))
229+
230+
231+
232+@Callable(inv)
233+func getResolver (name) = $Tuple2(nil, _getResolver(_splitLastLabel(name)._1))
234+
235+
236+
237+@Callable(inv)
238+func getNameCreated (name) = $Tuple2(nil, _getCreatedAt(_splitLastLabel(name)._1))
239+
240+
241+
242+@Callable(inv)
243+func getNameExpires (name) = $Tuple2(nil, _getExpiresAt(_splitLastLabel(name)._1))
244+
245+
246+
247+@Callable(inv)
248+func register (name,owner,createdAt) = valueOrElse(modifiers([onlyController(inv), if (isAvailableName(name))
249+ then unit
250+ else throw((("`" + name) + "` cannot be registered")), if (isValidAddress(owner))
251+ then unit
252+ else throw("Owner must be a valid address"), if ((createdAt > 0))
253+ then unit
254+ else throw("CreatedAt cannot be negative"), if ((lastBlock.timestamp >= createdAt))
255+ then unit
256+ else throw("CreatedAt cannot be in the future")]), {
257+ let issueNameToken = _issueNameToken(name)
258+ let tokenId = calculateAssetId(issueNameToken[0])
259+ let tokenStr = toBase58String(tokenId)
260+ let registerNameWithToken = _registerNameWithToken(name, tokenStr, createdAt)
261+ let transferTokenToOwner = _transferTokenToOwner(tokenStr, owner)
262+ let setOwnership = _setOwner(name, owner)
263+ (((issueNameToken ++ registerNameWithToken) ++ transferTokenToOwner) ++ setOwnership)
264+ })
265+
266+
267+
268+@Callable(inv)
269+func reclaim (name) = valueOrElse(modifiers([if (isActiveName(name))
270+ then unit
271+ else throw((("`" + name) + "` is not active"))]), {
272+ let newOwner = inv.originCaller
273+ let newOwnerAddress = toString(newOwner)
274+ let tokenStr = valueOrErrorMessage(_getToken(name), (("No token is issued for `" + name) + "`"))
275+ let tokenId = fromBase58String(tokenStr)
276+ let hasToken = (assetBalance(newOwner, tokenId) == 1)
277+ let isTokenOwner = isOwner(inv, name)
278+ let isTokenExists = match assetInfo(tokenId) {
279+ case token: Asset =>
280+ (token.quantity == 1)
281+ case _ =>
282+ false
283+ }
284+ if (if (isTokenOwner)
285+ then !(isTokenExists)
73286 else false)
74- then (asset.decimals == 0)
75- else false)
76- then (asset.reissuable == false)
77- else false
78- if (if ((pmt.amount != 1))
79- then true
80- else !(isMeedusNFT))
81- then throw("Payment should contain Meedus NFT")
82- else {
83- let tokenStr = getStringOrThrow(registrar, key_Name_token(asset.name))
84- let token = toBytes(tokenStr)
85- let transfer = invoke(this, "transfer", [callerStr, assetId], nil)
86- if ((transfer == transfer))
87- then nil
88- else throw("Strict value is not equal to itself.")
287+ then {
288+ let issueNewToken = _issueNameToken(name)
289+ let newTokenId = calculateAssetId(issueNewToken[0])
290+ let newTokenStr = toBase58String(newTokenId)
291+ let restoreNameWithNewToken = _restoreNameWithToken(name, newTokenStr)
292+ let transferNewTokenToOwner = _transferTokenToOwner(newTokenStr, newOwnerAddress)
293+ ((issueNewToken ++ restoreNameWithNewToken) ++ transferNewTokenToOwner)
89294 }
90- }
295+ else if (if (isTokenOwner)
296+ then hasToken
297+ else false)
298+ then throw("You already own a name token")
299+ else if (!(hasToken))
300+ then throw("You don't have a name token")
301+ else _setOwner(name, newOwnerAddress)
302+ })
91303
92304

github/deemru/w8io/3ef1775 
52.21 ms