tx · 6tkdMir6rJdYVvKd7ihBV48aJBoMbXwbSsWabs5KHJsY 3Mz29fiz3zgY9JDbiHKANvHsFgQutdfu4Ua: -0.01400000 Waves 2021.03.27 10:09 [1455835] smart account 3Mz29fiz3zgY9JDbiHKANvHsFgQutdfu4Ua > SELF 0.00000000 Waves
{ "type": 13, "id": "6tkdMir6rJdYVvKd7ihBV48aJBoMbXwbSsWabs5KHJsY", "fee": 1400000, "feeAssetId": null, "timestamp": 1616828943244, "version": 2, "chainId": 84, "sender": "3Mz29fiz3zgY9JDbiHKANvHsFgQutdfu4Ua", "senderPublicKey": "CTyHhnVTxf16Z4CmGGneAK8WB5g2QyT4MB8kUn8vPPcu", "proofs": [ "2mTAZhycB6je2RdavTwLM8rPPozVKXCeNqKDmiRVPSevLSppmaHC3uzsTt3JCj4KmK8kVtTDjDXmiMofnquVB6oT" ], "script": "base64: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c3NldElkAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAApCeXRlVmVjdG9yBAAAAAxpc0J5dGVWZWN0b3IFAAAAByRtYXRjaDAFAAAADGlzQnl0ZVZlY3RvcgkAAAIAAAABAgAAABRFUlJPUjogQ29udHJhY3QgdHlwZQQAAAAMY29udHJhY3RJbmZvBAAAAAckbWF0Y2gwCQAD7AAAAAEFAAAADGNvbnRyYWN0SWRCVgMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAFQXNzZXQEAAAAB2lzQXNzZXQFAAAAByRtYXRjaDAFAAAAB2lzQXNzZXQJAAACAAAAAQIAAAAXRVJST1I6IFVua25vd24gQ29udHJhY3QDCQEAAAACIT0AAAACCAUAAAAMY29udHJhY3RJbmZvAAAABmlzc3VlcgUAAAAEdGhpcwkAAAIAAAABAgAAABZFUlJPUjogQ29udHJhY3QgSXNzdWVyAwkBAAAAAiE9AAAAAggFAAAADGNvbnRyYWN0SW5mbwAAAARuYW1lBQAAAAxjb250cmFjdE5hbWUJAAACAAAAAQIAAAAURVJST1I6IENvbnRyYWN0IG5hbWUDAwMDCQEAAAACIT0AAAACCAUAAAAMY29udHJhY3RJbmZvAAAACGRlY2ltYWxzAAAAAAAAAAAABgkBAAAAAiE9AAAAAggFAAAADGNvbnRyYWN0SW5mbwAAAAhxdWFudGl0eQAAAAAAAAAAAQYJAQAAAAIhPQAAAAIIBQAAAAxjb250cmFjdEluZm8AAAAKcmVpc3N1YWJsZQcGCQEAAAACIT0AAAACCAUAAAAMY29udHJhY3RJbmZvAAAACHNjcmlwdGVkBwkAAAIAAAABAgAAABdFUlJPUjogQ29udHJhY3Qgbm90IE5GVAQAAAAKY29udHJhY3RJZAkAAlgAAAABBQAAAAxjb250cmFjdElkQlYEAAAAE2NvbnRyYWN0RGVzY3JpcHRpb24JAAS1AAAAAggFAAAADGNvbnRyYWN0SW5mbwAAAAtkZXNjcmlwdGlvbgUAAAAJc2VwYXJhdG9yBAAAAA5jb250cmFjdEhlaWdodAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAE2NvbnRyYWN0RGVzY3JpcHRpb24AAAAAAAAAAAEEAAAAFWNvbnRyYWN0Q2FsbGVyQWRkcmVzcwkAAZEAAAACBQAAABNjb250cmFjdERlc2NyaXB0aW9uAAAAAAAAAAACBAAAAA9jb250cmFjdEFzc2V0SWQJAAGRAAAAAgUAAAATY29udHJhY3REZXNjcmlwdGlvbgAAAAAAAAAAAwQAAAAVY29udHJhY3RBc3NldFF1YW50aXR5CQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAATY29udHJhY3REZXNjcmlwdGlvbgAAAAAAAAAABAQAAAARY29udHJhY3RBc3NldEluZm8EAAAAByRtYXRjaDAJAAPsAAAAAQkAAlkAAAABBQAAAA9jb250cmFjdEFzc2V0SWQDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABUFzc2V0BAAAAAdpc0Fzc2V0BQAAAAckbWF0Y2gwBQAAAAdpc0Fzc2V0CQAAAgAAAAECAAAAFEVSUk9SOiBVbmtub3duIEFzc2V0AwkBAAAAAiE9AAAAAgkAAZAAAAABBQAAABNjb250cmFjdERlc2NyaXB0aW9uAAAAAAAAAAAFCQAAAgAAAAECAAAAG0VSUk9SOiBDb250cmFjdCBkZXNjcmlwdGlvbgMJAABnAAAAAgUAAAAOY29udHJhY3RIZWlnaHQFAAAABmhlaWdodAkAAAIAAAABAgAAABZFUlJPUjogU3RhcnRpbmcgaGVpZ2h0AwMJAABmAAAAAgAAAAAAAAAAAQUAAAAVY29udHJhY3RBc3NldFF1YW50aXR5BgkAAGYAAAACBQAAABVjb250cmFjdEFzc2V0UXVhbnRpdHkIBQAAABFjb250cmFjdEFzc2V0SW5mbwAAAAhxdWFudGl0eQkAAAIAAAABAgAAABVFUlJPUjogQXNzZXQgcXVhbnRpdHkDCQAAZgAAAAIFAAAAFWNvbnRyYWN0QXNzZXRRdWFudGl0eQkAA/AAAAACBQAAAAR0aGlzCAUAAAARY29udHJhY3RBc3NldEluZm8AAAACaWQJAAACAAAAAQIAAAAURVJST1I6IFZhdWx0IGJhbGFuY2UEAAAABW5vbmNlCQEAAAANZ2VuZXJhdGVOb25jZQAAAAAEAAAAEnJlY2VpcHREZXNjcmlwdGlvbgkABLkAAAACCQAETAAAAAIFAAAAC3JlY2VpcHRUZXh0CQAETAAAAAIJAAGkAAAAAQUAAAAOY29udHJhY3RIZWlnaHQJAARMAAAAAgkAAaQAAAABBQAAAAZoZWlnaHQJAARMAAAAAgUAAAAKY29udHJhY3RJZAkABEwAAAACBQAAABVjb250cmFjdENhbGxlckFkZHJlc3MJAARMAAAAAgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIJAARMAAAAAgUAAAAPY29udHJhY3RBc3NldElkCQAETAAAAAIJAAGkAAAAAQUAAAAVY29udHJhY3RBc3NldFF1YW50aXR5BQAAAANuaWwFAAAACXNlcGFyYXRvcgQAAAAMcmVjZWlwdElzc3VlCQAEQwAAAAcFAAAAC3JlY2VpcHROYW1lBQAAABJyZWNlaXB0RGVzY3JpcHRpb24AAAAAAAAAAAEAAAAAAAAAAAAHBQAAAAR1bml0CQABkQAAAAIFAAAABW5vbmNlAAAAAAAAAAAABAAAAAlyZWNlaXB0SWQJAAQ4AAAAAQUAAAAMcmVjZWlwdElzc3VlCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA1rZXlOb25jZUNvdW50CQABkQAAAAIFAAAABW5vbmNlAAAAAAAAAAABCQAETAAAAAIJAQAAAARCdXJuAAAAAgUAAAAMY29udHJhY3RJZEJWAAAAAAAAAAABCQAETAAAAAIFAAAADHJlY2VpcHRJc3N1ZQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIIBQAAAAxyZWNlaXB0SXNzdWUAAAAIcXVhbnRpdHkFAAAACXJlY2VpcHRJZAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAAFWNvbnRyYWN0QXNzZXRRdWFudGl0eQgFAAAAEWNvbnRyYWN0QXNzZXRJbmZvAAAAAmlkBQAAAANuaWwAAAABAAAAAnR4AQAAAAZ2ZXJpZnkAAAAACQAB9AAAAAMIBQAAAAJ0eAAAAAlib2R5Qnl0ZXMJAAGRAAAAAggFAAAAAnR4AAAABnByb29mcwAAAAAAAAAAAAgFAAAAAnR4AAAAD3NlbmRlclB1YmxpY0tlebjljG8=", "height": 1455835, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: DBizCVAQEPcn9iUentFkj6xoYhdbLsacen5ZwSBhR6m1 Next: HHuMk9ZdxSm1B6sEwmzjzrLqamNUzJotNMgtrGUm5AQZ Diff:
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 4 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | + | let self = toString(this) | |
5 | + | ||
6 | + | let separator = "___" | |
7 | + | ||
8 | + | let wavesAssetId = "WAVES" | |
9 | + | ||
10 | + | let maxInt = 9223372036854775805 | |
11 | + | ||
12 | + | let maxDescriptionBytes = 1000 | |
13 | + | ||
14 | + | let contractName = "VaultContract" | |
15 | + | ||
16 | + | let contractText = (("Don't trust, verify ! The NFT Issuer and dApp are the same address <" + self) + ">.") | |
17 | + | ||
18 | + | let receiptName = "VaultReceipt" | |
19 | + | ||
20 | + | let receiptText = "fuck off" | |
21 | + | ||
22 | + | let keyNonceCount = "NONCE_COUNT" | |
23 | + | ||
24 | + | func generateNonce () = { | |
25 | + | let newNonce = match getInteger(this, keyNonceCount) { | |
26 | + | case isInt: Int => | |
27 | + | if ((isInt >= maxInt)) | |
28 | + | then 1 | |
29 | + | else (isInt + 1) | |
30 | + | case _ => | |
31 | + | 1 | |
32 | + | } | |
33 | + | [parseIntValue((toString(newNonce) + toString(height))), newNonce] | |
34 | + | } | |
4 | 35 | ||
5 | 36 | ||
6 | 37 | @Callable(i) | |
7 | - | func call () = { | |
8 | - | let asset = Issue("Asset", "", 1, 0, true, unit, 0) | |
9 | - | let assetId = calculateAssetId(asset) | |
10 | - | [BinaryEntry("bin", base58''), BooleanEntry("bool", true), IntegerEntry("int", 1), StringEntry("str", ""), DeleteEntry("str"), asset, Reissue(assetId, 1, false), Burn(assetId, 1), ScriptTransfer(i.caller, 1, assetId)] | |
11 | - | } | |
38 | + | func deposit () = if ((this == i.caller)) | |
39 | + | then throw("ERROR: Self-invoke is forbidden") | |
40 | + | else if ((size(i.payments) != 1)) | |
41 | + | then throw("ERROR: Attached Payment != 1") | |
42 | + | else if (if ((1 > i.payments[0].amount)) | |
43 | + | then true | |
44 | + | else (i.payments[0].amount > maxInt)) | |
45 | + | then throw("ERROR: Payment amount") | |
46 | + | else { | |
47 | + | let contractAssetId = match i.payments[0].assetId { | |
48 | + | case isByteVector: ByteVector => | |
49 | + | match assetInfo(isByteVector) { | |
50 | + | case isAsset: Asset => | |
51 | + | toBase58String(isAsset.id) | |
52 | + | case _ => | |
53 | + | throw("ERROR: Unknown Asset") | |
54 | + | } | |
55 | + | case isWaves: Unit => | |
56 | + | wavesAssetId | |
57 | + | case _ => | |
58 | + | throw("ERROR: Unknown Asset type") | |
59 | + | } | |
60 | + | let nonce = generateNonce() | |
61 | + | let contractDescription = makeString([contractText, toString(height), toString(i.caller), contractAssetId, toString(i.payments[0].amount)], separator) | |
62 | + | if ((size(toBytes(contractDescription)) > maxDescriptionBytes)) | |
63 | + | then throw("ERROR: Too long contract") | |
64 | + | else { | |
65 | + | let contractIssue = Issue(contractName, contractDescription, 1, 0, false, unit, nonce[0]) | |
66 | + | let contractId = calculateAssetId(contractIssue) | |
67 | + | [IntegerEntry("sizetoBytescontractDescription", size(toBytes(contractDescription))), IntegerEntry(keyNonceCount, nonce[1]), contractIssue, ScriptTransfer(i.caller, contractIssue.quantity, contractId)] | |
68 | + | } | |
69 | + | } | |
70 | + | ||
71 | + | ||
72 | + | ||
73 | + | @Callable(i) | |
74 | + | func withdraw () = if ((this == i.caller)) | |
75 | + | then throw("ERROR: Self-invoke is forbidden") | |
76 | + | else if ((size(i.payments) != 1)) | |
77 | + | then throw("ERROR: Attached Payment != 1") | |
78 | + | else if ((i.payments[0].amount != 1)) | |
79 | + | then throw("ERROR: Payment amount != 1") | |
80 | + | else { | |
81 | + | let contractIdBV = match i.payments[0].assetId { | |
82 | + | case isByteVector: ByteVector => | |
83 | + | isByteVector | |
84 | + | case _ => | |
85 | + | throw("ERROR: Contract type") | |
86 | + | } | |
87 | + | let contractInfo = match assetInfo(contractIdBV) { | |
88 | + | case isAsset: Asset => | |
89 | + | isAsset | |
90 | + | case _ => | |
91 | + | throw("ERROR: Unknown Contract") | |
92 | + | } | |
93 | + | if ((contractInfo.issuer != this)) | |
94 | + | then throw("ERROR: Contract Issuer") | |
95 | + | else if ((contractInfo.name != contractName)) | |
96 | + | then throw("ERROR: Contract name") | |
97 | + | else if (if (if (if ((contractInfo.decimals != 0)) | |
98 | + | then true | |
99 | + | else (contractInfo.quantity != 1)) | |
100 | + | then true | |
101 | + | else (contractInfo.reissuable != false)) | |
102 | + | then true | |
103 | + | else (contractInfo.scripted != false)) | |
104 | + | then throw("ERROR: Contract not NFT") | |
105 | + | else { | |
106 | + | let contractId = toBase58String(contractIdBV) | |
107 | + | let contractDescription = split(contractInfo.description, separator) | |
108 | + | let contractHeight = parseIntValue(contractDescription[1]) | |
109 | + | let contractCallerAddress = contractDescription[2] | |
110 | + | let contractAssetId = contractDescription[3] | |
111 | + | let contractAssetQuantity = parseIntValue(contractDescription[4]) | |
112 | + | let contractAssetInfo = match assetInfo(fromBase58String(contractAssetId)) { | |
113 | + | case isAsset: Asset => | |
114 | + | isAsset | |
115 | + | case _ => | |
116 | + | throw("ERROR: Unknown Asset") | |
117 | + | } | |
118 | + | if ((size(contractDescription) != 5)) | |
119 | + | then throw("ERROR: Contract description") | |
120 | + | else if ((contractHeight >= height)) | |
121 | + | then throw("ERROR: Starting height") | |
122 | + | else if (if ((1 > contractAssetQuantity)) | |
123 | + | then true | |
124 | + | else (contractAssetQuantity > contractAssetInfo.quantity)) | |
125 | + | then throw("ERROR: Asset quantity") | |
126 | + | else if ((contractAssetQuantity > assetBalance(this, contractAssetInfo.id))) | |
127 | + | then throw("ERROR: Vault balance") | |
128 | + | else { | |
129 | + | let nonce = generateNonce() | |
130 | + | let receiptDescription = makeString([receiptText, toString(contractHeight), toString(height), contractId, contractCallerAddress, toString(i.caller), contractAssetId, toString(contractAssetQuantity)], separator) | |
131 | + | let receiptIssue = Issue(receiptName, receiptDescription, 1, 0, false, unit, nonce[0]) | |
132 | + | let receiptId = calculateAssetId(receiptIssue) | |
133 | + | [IntegerEntry(keyNonceCount, nonce[1]), Burn(contractIdBV, 1), receiptIssue, ScriptTransfer(i.caller, receiptIssue.quantity, receiptId), ScriptTransfer(i.caller, contractAssetQuantity, contractAssetInfo.id)] | |
134 | + | } | |
135 | + | } | |
136 | + | } | |
12 | 137 | ||
13 | 138 | ||
14 | 139 | @Verifier(tx) |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 4 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | + | let self = toString(this) | |
5 | + | ||
6 | + | let separator = "___" | |
7 | + | ||
8 | + | let wavesAssetId = "WAVES" | |
9 | + | ||
10 | + | let maxInt = 9223372036854775805 | |
11 | + | ||
12 | + | let maxDescriptionBytes = 1000 | |
13 | + | ||
14 | + | let contractName = "VaultContract" | |
15 | + | ||
16 | + | let contractText = (("Don't trust, verify ! The NFT Issuer and dApp are the same address <" + self) + ">.") | |
17 | + | ||
18 | + | let receiptName = "VaultReceipt" | |
19 | + | ||
20 | + | let receiptText = "fuck off" | |
21 | + | ||
22 | + | let keyNonceCount = "NONCE_COUNT" | |
23 | + | ||
24 | + | func generateNonce () = { | |
25 | + | let newNonce = match getInteger(this, keyNonceCount) { | |
26 | + | case isInt: Int => | |
27 | + | if ((isInt >= maxInt)) | |
28 | + | then 1 | |
29 | + | else (isInt + 1) | |
30 | + | case _ => | |
31 | + | 1 | |
32 | + | } | |
33 | + | [parseIntValue((toString(newNonce) + toString(height))), newNonce] | |
34 | + | } | |
4 | 35 | ||
5 | 36 | ||
6 | 37 | @Callable(i) | |
7 | - | func call () = { | |
8 | - | let asset = Issue("Asset", "", 1, 0, true, unit, 0) | |
9 | - | let assetId = calculateAssetId(asset) | |
10 | - | [BinaryEntry("bin", base58''), BooleanEntry("bool", true), IntegerEntry("int", 1), StringEntry("str", ""), DeleteEntry("str"), asset, Reissue(assetId, 1, false), Burn(assetId, 1), ScriptTransfer(i.caller, 1, assetId)] | |
11 | - | } | |
38 | + | func deposit () = if ((this == i.caller)) | |
39 | + | then throw("ERROR: Self-invoke is forbidden") | |
40 | + | else if ((size(i.payments) != 1)) | |
41 | + | then throw("ERROR: Attached Payment != 1") | |
42 | + | else if (if ((1 > i.payments[0].amount)) | |
43 | + | then true | |
44 | + | else (i.payments[0].amount > maxInt)) | |
45 | + | then throw("ERROR: Payment amount") | |
46 | + | else { | |
47 | + | let contractAssetId = match i.payments[0].assetId { | |
48 | + | case isByteVector: ByteVector => | |
49 | + | match assetInfo(isByteVector) { | |
50 | + | case isAsset: Asset => | |
51 | + | toBase58String(isAsset.id) | |
52 | + | case _ => | |
53 | + | throw("ERROR: Unknown Asset") | |
54 | + | } | |
55 | + | case isWaves: Unit => | |
56 | + | wavesAssetId | |
57 | + | case _ => | |
58 | + | throw("ERROR: Unknown Asset type") | |
59 | + | } | |
60 | + | let nonce = generateNonce() | |
61 | + | let contractDescription = makeString([contractText, toString(height), toString(i.caller), contractAssetId, toString(i.payments[0].amount)], separator) | |
62 | + | if ((size(toBytes(contractDescription)) > maxDescriptionBytes)) | |
63 | + | then throw("ERROR: Too long contract") | |
64 | + | else { | |
65 | + | let contractIssue = Issue(contractName, contractDescription, 1, 0, false, unit, nonce[0]) | |
66 | + | let contractId = calculateAssetId(contractIssue) | |
67 | + | [IntegerEntry("sizetoBytescontractDescription", size(toBytes(contractDescription))), IntegerEntry(keyNonceCount, nonce[1]), contractIssue, ScriptTransfer(i.caller, contractIssue.quantity, contractId)] | |
68 | + | } | |
69 | + | } | |
70 | + | ||
71 | + | ||
72 | + | ||
73 | + | @Callable(i) | |
74 | + | func withdraw () = if ((this == i.caller)) | |
75 | + | then throw("ERROR: Self-invoke is forbidden") | |
76 | + | else if ((size(i.payments) != 1)) | |
77 | + | then throw("ERROR: Attached Payment != 1") | |
78 | + | else if ((i.payments[0].amount != 1)) | |
79 | + | then throw("ERROR: Payment amount != 1") | |
80 | + | else { | |
81 | + | let contractIdBV = match i.payments[0].assetId { | |
82 | + | case isByteVector: ByteVector => | |
83 | + | isByteVector | |
84 | + | case _ => | |
85 | + | throw("ERROR: Contract type") | |
86 | + | } | |
87 | + | let contractInfo = match assetInfo(contractIdBV) { | |
88 | + | case isAsset: Asset => | |
89 | + | isAsset | |
90 | + | case _ => | |
91 | + | throw("ERROR: Unknown Contract") | |
92 | + | } | |
93 | + | if ((contractInfo.issuer != this)) | |
94 | + | then throw("ERROR: Contract Issuer") | |
95 | + | else if ((contractInfo.name != contractName)) | |
96 | + | then throw("ERROR: Contract name") | |
97 | + | else if (if (if (if ((contractInfo.decimals != 0)) | |
98 | + | then true | |
99 | + | else (contractInfo.quantity != 1)) | |
100 | + | then true | |
101 | + | else (contractInfo.reissuable != false)) | |
102 | + | then true | |
103 | + | else (contractInfo.scripted != false)) | |
104 | + | then throw("ERROR: Contract not NFT") | |
105 | + | else { | |
106 | + | let contractId = toBase58String(contractIdBV) | |
107 | + | let contractDescription = split(contractInfo.description, separator) | |
108 | + | let contractHeight = parseIntValue(contractDescription[1]) | |
109 | + | let contractCallerAddress = contractDescription[2] | |
110 | + | let contractAssetId = contractDescription[3] | |
111 | + | let contractAssetQuantity = parseIntValue(contractDescription[4]) | |
112 | + | let contractAssetInfo = match assetInfo(fromBase58String(contractAssetId)) { | |
113 | + | case isAsset: Asset => | |
114 | + | isAsset | |
115 | + | case _ => | |
116 | + | throw("ERROR: Unknown Asset") | |
117 | + | } | |
118 | + | if ((size(contractDescription) != 5)) | |
119 | + | then throw("ERROR: Contract description") | |
120 | + | else if ((contractHeight >= height)) | |
121 | + | then throw("ERROR: Starting height") | |
122 | + | else if (if ((1 > contractAssetQuantity)) | |
123 | + | then true | |
124 | + | else (contractAssetQuantity > contractAssetInfo.quantity)) | |
125 | + | then throw("ERROR: Asset quantity") | |
126 | + | else if ((contractAssetQuantity > assetBalance(this, contractAssetInfo.id))) | |
127 | + | then throw("ERROR: Vault balance") | |
128 | + | else { | |
129 | + | let nonce = generateNonce() | |
130 | + | let receiptDescription = makeString([receiptText, toString(contractHeight), toString(height), contractId, contractCallerAddress, toString(i.caller), contractAssetId, toString(contractAssetQuantity)], separator) | |
131 | + | let receiptIssue = Issue(receiptName, receiptDescription, 1, 0, false, unit, nonce[0]) | |
132 | + | let receiptId = calculateAssetId(receiptIssue) | |
133 | + | [IntegerEntry(keyNonceCount, nonce[1]), Burn(contractIdBV, 1), receiptIssue, ScriptTransfer(i.caller, receiptIssue.quantity, receiptId), ScriptTransfer(i.caller, contractAssetQuantity, contractAssetInfo.id)] | |
134 | + | } | |
135 | + | } | |
136 | + | } | |
12 | 137 | ||
13 | 138 | ||
14 | 139 | @Verifier(tx) | |
15 | 140 | func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) | |
16 | 141 |
github/deemru/w8io/169f3d6 30.47 ms ◑![]()