tx · 4ub2gGG3Y4MqpzHGAJBuGSaWCiNbH9Kzzeq8qCGwWYDo

3N2Gaubi51KGxUWyg36Q6sEon8nSKK3YmLK:  -0.01000000 Waves

2023.05.26 12:34 [2594773] smart account 3N2Gaubi51KGxUWyg36Q6sEon8nSKK3YmLK > SELF 0.00000000 Waves

{ "type": 13, "id": "4ub2gGG3Y4MqpzHGAJBuGSaWCiNbH9Kzzeq8qCGwWYDo", "fee": 1000000, "feeAssetId": null, "timestamp": 1685093681939, "version": 2, "chainId": 84, "sender": "3N2Gaubi51KGxUWyg36Q6sEon8nSKK3YmLK", "senderPublicKey": "GLYPQRdW58KJs72SRSnkiA5EswHHd3SpyBVb7exXreYE", "proofs": [ "NmCqBpdpx5Vumqmy2HPsrEizmJ4zJmbENCR9hxkLPgJDzi8MALDXPJK6dVje5nh7jCbaHoyHF2xydNhKyr4MMUq" ], "script": "base64:BgIHCAISAwoBCBwAA1NFUAICX18AEGNvbnRyYWN0RmlsZW5hbWUCDXRyZWFzdXJ5LnJpZGUAD0FETUlOX0xJU1RfU0laRQAFAAZRVU9SVU0AAwARVFhJRF9CWVRFU19MRU5HVEgAIAEHd3JhcEVycgEBcwkArAICCQCsAgIFEGNvbnRyYWN0RmlsZW5hbWUCAjogBQFzAQh0aHJvd0VycgEBcwkAAgEJAQd3cmFwRXJyAQUBcwEYa2V5QWxsb3dlZFR4SWRWb3RlUHJlZml4AQR0eElkCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICCWFsbG93VHhJZAkAzAgCBQR0eElkBQNuaWwFA1NFUAEQa2V5RnVsbEFkbWluVm90ZQIGcHJlZml4DGFkbWluQWRkcmVzcwkAuQkCCQDMCAIFBnByZWZpeAkAzAgCBQxhZG1pbkFkZHJlc3MFA25pbAUDU0VQARNrZXlBZG1pbkFkZHJlc3NMaXN0AAkAuQkCCQDMCAICAiVzCQDMCAICEGFkbWluQWRkcmVzc0xpc3QFA25pbAUDU0VQAQ5rZXlBbGxvd2VkVHhJZAAJALkJAgkAzAgCAgIlcwkAzAgCAgR0eElkBQNuaWwFA1NFUAEQa2V5Q29uZmlnQWRkcmVzcwACCiVzX19jb25maWcBFmtleVZvdGluZ1Jlc3VsdEFkZHJlc3MAAhZjb250cmFjdF92b3RpbmdfcmVzdWx0ARlrZXlQcm9wb3NhbEFsbG93QnJvYWRjYXN0AgdhZGRyZXNzBHR4SWQJAKwCAgkArAICCQCsAgICGXByb3Bvc2FsX2FsbG93X2Jyb2FkY2FzdF8JAKUIAQUHYWRkcmVzcwIBXwkA2AQBBQR0eElkABNjb25maWdBZGRyZXNzT3B0aW9uBAckbWF0Y2gwCQCdCAIFBHRoaXMJARBrZXlDb25maWdBZGRyZXNzAAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJAKYIAQUBcwMJAAECBQckbWF0Y2gwAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IADWNvbmZpZ0FkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgUTY29uZmlnQWRkcmVzc09wdGlvbgkBB3dyYXBFcnIBAhZpbnZhbGlkIGNvbmZpZyBhZGRyZXNzABp2b3RpbmdSZXN1bHRDb250cmFjdE9wdGlvbgQHJG1hdGNoMAUTY29uZmlnQWRkcmVzc09wdGlvbgMJAAECBQckbWF0Y2gwAgdBZGRyZXNzBAFhBQckbWF0Y2gwBAckbWF0Y2gxCQCdCAIFAWEJARZrZXlWb3RpbmdSZXN1bHRBZGRyZXNzAAMJAAECBQckbWF0Y2gxAgZTdHJpbmcEAXMFByRtYXRjaDEJAKYIAQUBcwMJAAECBQckbWF0Y2gxAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yABR2b3RpbmdSZXN1bHRDb250cmFjdAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBRp2b3RpbmdSZXN1bHRDb250cmFjdE9wdGlvbgkBB3dyYXBFcnIBAh1pbnZhbGlkIHZvdGluZyByZXN1bHQgYWRkcmVzcwEMZ2V0QWRtaW5Wb3RlAgZwcmVmaXgFYWRtaW4EB3ZvdGVLZXkJARBrZXlGdWxsQWRtaW5Wb3RlAgUGcHJlZml4BQVhZG1pbgkBC3ZhbHVlT3JFbHNlAgkAnwgBBQd2b3RlS2V5AAABDWdldEFkbWluc0xpc3QABAckbWF0Y2gwCQCdCAIFBHRoaXMJARNrZXlBZG1pbkFkZHJlc3NMaXN0AAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJALUJAgUBcwUDU0VQBQNuaWwBDWlzSW5BZG1pbkxpc3QBB2FkZHJlc3MJAQ9jb250YWluc0VsZW1lbnQCCQENZ2V0QWRtaW5zTGlzdAAFB2FkZHJlc3MBEmdlblZvdGVzS2V5c0hlbHBlcgIBYQxhZG1pbkFkZHJlc3MECyR0MDIwMjAyMDQ0BQFhBAZyZXN1bHQIBQskdDAyMDIwMjA0NAJfMQQGcHJlZml4CAULJHQwMjAyMDIwNDQCXzIJAJQKAgkAzQgCBQZyZXN1bHQJARBrZXlGdWxsQWRtaW5Wb3RlAgUGcHJlZml4BQxhZG1pbkFkZHJlc3MFBnByZWZpeAEMZ2VuVm90ZXNLZXlzAQlrZXlQcmVmaXgECWFkbWluTGlzdAkBE2tleUFkbWluQWRkcmVzc0xpc3QABAskdDAyMTkxMjI3NQoAAiRsCQENZ2V0QWRtaW5zTGlzdAAKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIFA25pbAUJa2V5UHJlZml4CgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARJnZW5Wb3Rlc0tleXNIZWxwZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDUJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFBAZyZXN1bHQIBQskdDAyMTkxMjI3NQJfMQQGcHJlZml4CAULJHQwMjE5MTIyNzUCXzIFBnJlc3VsdAEQY291bnRWb3Rlc0hlbHBlcgIGcmVzdWx0B3ZvdGVLZXkJAGQCBQZyZXN1bHQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUHdm90ZUtleQAAAQpjb3VudFZvdGVzAQZwcmVmaXgEBXZvdGVzCQEMZ2VuVm90ZXNLZXlzAQUGcHJlZml4CgACJGwFBXZvdGVzCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARBjb3VudFZvdGVzSGVscGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQEQY2xlYXJWb3Rlc0hlbHBlcgIGcmVzdWx0A2tleQkAzQgCBQZyZXN1bHQJAQtEZWxldGVFbnRyeQEFA2tleQETZ2V0Q2xlYXJWb3RlRW50cmllcwEGcHJlZml4BAV2b3RlcwkBDGdlblZvdGVzS2V5cwEFBnByZWZpeAoAAiRsBQV2b3RlcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEQY2xlYXJWb3Rlc0hlbHBlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUBDHZvdGVJTlRFUk5BTAQTY2FsbGVyQWRkcmVzc1N0cmluZwlrZXlQcmVmaXgIbWluVm90ZXMKdm90ZVJlc3VsdAQHdm90ZUtleQkBEGtleUZ1bGxBZG1pblZvdGUCBQlrZXlQcmVmaXgFE2NhbGxlckFkZHJlc3NTdHJpbmcEEGFkbWluQ3VycmVudFZvdGUJAQxnZXRBZG1pblZvdGUCBQlrZXlQcmVmaXgFE2NhbGxlckFkZHJlc3NTdHJpbmcEA2VycgMJAQEhAQkBDWlzSW5BZG1pbkxpc3QBBRNjYWxsZXJBZGRyZXNzU3RyaW5nCQEIdGhyb3dFcnIBCQCsAgIJAKwCAgIJQWRkcmVzczogBRNjYWxsZXJBZGRyZXNzU3RyaW5nAhIgbm90IGluIEFkbWluIGxpc3QDCQAAAgUQYWRtaW5DdXJyZW50Vm90ZQABCQEIdGhyb3dFcnIBCQCsAgIFB3ZvdGVLZXkCEiB5b3UgYWxyZWFkeSB2b3RlZAUEdW5pdAMJAAACBQNlcnIFA2VycgQFdm90ZXMJAQpjb3VudFZvdGVzAQUJa2V5UHJlZml4AwkAZwIJAGQCBQV2b3RlcwABBQhtaW5Wb3RlcwQQY2xlYXJWb3RlRW50cmllcwkBE2dldENsZWFyVm90ZUVudHJpZXMBBQlrZXlQcmVmaXgJAM4IAgUQY2xlYXJWb3RlRW50cmllcwUKdm90ZVJlc3VsdAkAzAgCCQEMSW50ZWdlckVudHJ5AgUHdm90ZUtleQABBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAWkBC3ZvdGVGb3JUeElkAQR0eElkBBNjYWxsZXJBZGRyZXNzU3RyaW5nCQDYBAEICAUBaQZjYWxsZXIFYnl0ZXMECWtleVByZWZpeAkBGGtleUFsbG93ZWRUeElkVm90ZVByZWZpeAEFBHR4SWQEBnJlc3VsdAkAzAgCCQELU3RyaW5nRW50cnkCCQEOa2V5QWxsb3dlZFR4SWQABQR0eElkBQNuaWwEEWFsbG93ZWRUeElkT3B0aW9uCQCdCAIFBHRoaXMJAQ5rZXlBbGxvd2VkVHhJZAAEA2VycgkAzAgCAwkAAAIJAMgBAQkA2QQBBQR0eElkBRFUWElEX0JZVEVTX0xFTkdUSAYJAQh0aHJvd0VycgEJAKwCAgUEdHhJZAISIGlzIG5vdCB2YWxpZCB0eElkCQDMCAIDAwkAAAIFEWFsbG93ZWRUeElkT3B0aW9uBQR1bml0BgkBAiE9AgkBBXZhbHVlAQURYWxsb3dlZFR4SWRPcHRpb24FBHR4SWQGCQEIdGhyb3dFcnIBCQCsAgIFBHR4SWQCEyBpcyBhbHJlYWR5IGFsbG93ZWQFA25pbAMJAAACBQNlcnIFA2VycgkBDHZvdGVJTlRFUk5BTAQFE2NhbGxlckFkZHJlc3NTdHJpbmcFCWtleVByZWZpeAUGUVVPUlVNBQZyZXN1bHQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAnR4AQZ2ZXJpZnkABBdhbGxvd2VkVHhJZFN0cmluZ09wdGlvbgkAoggBCQEOa2V5QWxsb3dlZFR4SWQABBBjdXJyZW50QWRtaW5MaXN0CQENZ2V0QWRtaW5zTGlzdAAECmJ5UHJvcG9zYWwJAQt2YWx1ZU9yRWxzZQIJAJsIAgUUdm90aW5nUmVzdWx0Q29udHJhY3QJARlrZXlQcm9wb3NhbEFsbG93QnJvYWRjYXN0AgUEdGhpcwgFAnR4AmlkBwQIYnlBZG1pbnMDCQECIT0CBRdhbGxvd2VkVHhJZFN0cmluZ09wdGlvbgUEdW5pdAkAAAIIBQJ0eAJpZAkA2QQBCQEFdmFsdWUBBRdhbGxvd2VkVHhJZFN0cmluZ09wdGlvbgcEB2J5T3duZXIJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAIBQJ0eA9zZW5kZXJQdWJsaWNLZXkDAwkBAiE9AgUTY29uZmlnQWRkcmVzc09wdGlvbgUEdW5pdAkAAAIJAJADAQUQY3VycmVudEFkbWluTGlzdAUPQURNSU5fTElTVF9TSVpFBwMDCQECIT0CBRp2b3RpbmdSZXN1bHRDb250cmFjdE9wdGlvbgUEdW5pdAUKYnlQcm9wb3NhbAcGBQhieUFkbWlucwUHYnlPd25lcu4IJF8=", "height": 2594773, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: 3p6xYjwdz1o5X9G1NN9EKwbAR4KDacjVsBugtYE2aMah Full:
OldNewDifferences
1-# no script
1+{-# STDLIB_VERSION 6 #-}
2+{-# SCRIPT_TYPE ACCOUNT #-}
3+{-# CONTENT_TYPE DAPP #-}
4+let SEP = "__"
5+
6+let contractFilename = "treasury.ride"
7+
8+let ADMIN_LIST_SIZE = 5
9+
10+let QUORUM = 3
11+
12+let TXID_BYTES_LENGTH = 32
13+
14+func wrapErr (s) = ((contractFilename + ": ") + s)
15+
16+
17+func throwErr (s) = throw(wrapErr(s))
18+
19+
20+func keyAllowedTxIdVotePrefix (txId) = makeString(["%s%s%s", "allowTxId", txId], SEP)
21+
22+
23+func keyFullAdminVote (prefix,adminAddress) = makeString([prefix, adminAddress], SEP)
24+
25+
26+func keyAdminAddressList () = makeString(["%s", "adminAddressList"], SEP)
27+
28+
29+func keyAllowedTxId () = makeString(["%s", "txId"], SEP)
30+
31+
32+func keyConfigAddress () = "%s__config"
33+
34+
35+func keyVotingResultAddress () = "contract_voting_result"
36+
37+
38+func keyProposalAllowBroadcast (address,txId) = ((("proposal_allow_broadcast_" + toString(address)) + "_") + toBase58String(txId))
39+
40+
41+let configAddressOption = match getString(this, keyConfigAddress()) {
42+ case s: String =>
43+ addressFromString(s)
44+ case _: Unit =>
45+ unit
46+ case _ =>
47+ throw("Match error")
48+}
49+
50+let configAddress = valueOrErrorMessage(configAddressOption, wrapErr("invalid config address"))
51+
52+let votingResultContractOption = match configAddressOption {
53+ case a: Address =>
54+ match getString(a, keyVotingResultAddress()) {
55+ case s: String =>
56+ addressFromString(s)
57+ case _: Unit =>
58+ unit
59+ case _ =>
60+ throw("Match error")
61+ }
62+ case _: Unit =>
63+ unit
64+ case _ =>
65+ throw("Match error")
66+}
67+
68+let votingResultContract = valueOrErrorMessage(votingResultContractOption, wrapErr("invalid voting result address"))
69+
70+func getAdminVote (prefix,admin) = {
71+ let voteKey = keyFullAdminVote(prefix, admin)
72+ valueOrElse(getInteger(voteKey), 0)
73+ }
74+
75+
76+func getAdminsList () = match getString(this, keyAdminAddressList()) {
77+ case s: String =>
78+ split(s, SEP)
79+ case _ =>
80+ nil
81+}
82+
83+
84+func isInAdminList (address) = containsElement(getAdminsList(), address)
85+
86+
87+func genVotesKeysHelper (a,adminAddress) = {
88+ let $t020202044 = a
89+ let result = $t020202044._1
90+ let prefix = $t020202044._2
91+ $Tuple2((result :+ keyFullAdminVote(prefix, adminAddress)), prefix)
92+ }
93+
94+
95+func genVotesKeys (keyPrefix) = {
96+ let adminList = keyAdminAddressList()
97+ let $t021912275 = {
98+ let $l = getAdminsList()
99+ let $s = size($l)
100+ let $acc0 = $Tuple2(nil, keyPrefix)
101+ func $f0_1 ($a,$i) = if (($i >= $s))
102+ then $a
103+ else genVotesKeysHelper($a, $l[$i])
104+
105+ func $f0_2 ($a,$i) = if (($i >= $s))
106+ then $a
107+ else throw("List size exceeds 5")
108+
109+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
110+ }
111+ let result = $t021912275._1
112+ let prefix = $t021912275._2
113+ result
114+ }
115+
116+
117+func countVotesHelper (result,voteKey) = (result + valueOrElse(getInteger(voteKey), 0))
118+
119+
120+func countVotes (prefix) = {
121+ let votes = genVotesKeys(prefix)
122+ let $l = votes
123+ let $s = size($l)
124+ let $acc0 = 0
125+ func $f0_1 ($a,$i) = if (($i >= $s))
126+ then $a
127+ else countVotesHelper($a, $l[$i])
128+
129+ func $f0_2 ($a,$i) = if (($i >= $s))
130+ then $a
131+ else throw("List size exceeds 5")
132+
133+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
134+ }
135+
136+
137+func clearVotesHelper (result,key) = (result :+ DeleteEntry(key))
138+
139+
140+func getClearVoteEntries (prefix) = {
141+ let votes = genVotesKeys(prefix)
142+ let $l = votes
143+ let $s = size($l)
144+ let $acc0 = nil
145+ func $f0_1 ($a,$i) = if (($i >= $s))
146+ then $a
147+ else clearVotesHelper($a, $l[$i])
148+
149+ func $f0_2 ($a,$i) = if (($i >= $s))
150+ then $a
151+ else throw("List size exceeds 5")
152+
153+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
154+ }
155+
156+
157+func voteINTERNAL (callerAddressString,keyPrefix,minVotes,voteResult) = {
158+ let voteKey = keyFullAdminVote(keyPrefix, callerAddressString)
159+ let adminCurrentVote = getAdminVote(keyPrefix, callerAddressString)
160+ let err = if (!(isInAdminList(callerAddressString)))
161+ then throwErr((("Address: " + callerAddressString) + " not in Admin list"))
162+ else if ((adminCurrentVote == 1))
163+ then throwErr((voteKey + " you already voted"))
164+ else unit
165+ if ((err == err))
166+ then {
167+ let votes = countVotes(keyPrefix)
168+ if (((votes + 1) >= minVotes))
169+ then {
170+ let clearVoteEntries = getClearVoteEntries(keyPrefix)
171+ (clearVoteEntries ++ voteResult)
172+ }
173+ else [IntegerEntry(voteKey, 1)]
174+ }
175+ else throw("Strict value is not equal to itself.")
176+ }
177+
178+
179+@Callable(i)
180+func voteForTxId (txId) = {
181+ let callerAddressString = toBase58String(i.caller.bytes)
182+ let keyPrefix = keyAllowedTxIdVotePrefix(txId)
183+ let result = [StringEntry(keyAllowedTxId(), txId)]
184+ let allowedTxIdOption = getString(this, keyAllowedTxId())
185+ let err = [if ((size(fromBase58String(txId)) == TXID_BYTES_LENGTH))
186+ then true
187+ else throwErr((txId + " is not valid txId")), if (if ((allowedTxIdOption == unit))
188+ then true
189+ else (value(allowedTxIdOption) != txId))
190+ then true
191+ else throwErr((txId + " is already allowed"))]
192+ if ((err == err))
193+ then voteINTERNAL(callerAddressString, keyPrefix, QUORUM, result)
194+ else throw("Strict value is not equal to itself.")
195+ }
196+
197+
198+@Verifier(tx)
199+func verify () = {
200+ let allowedTxIdStringOption = getString(keyAllowedTxId())
201+ let currentAdminList = getAdminsList()
202+ let byProposal = valueOrElse(getBoolean(votingResultContract, keyProposalAllowBroadcast(this, tx.id)), false)
203+ let byAdmins = if ((allowedTxIdStringOption != unit))
204+ then (tx.id == fromBase58String(value(allowedTxIdStringOption)))
205+ else false
206+ let byOwner = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
207+ if (if ((configAddressOption != unit))
208+ then (size(currentAdminList) == ADMIN_LIST_SIZE)
209+ else false)
210+ then if (if ((votingResultContractOption != unit))
211+ then byProposal
212+ else false)
213+ then true
214+ else byAdmins
215+ else byOwner
216+ }
217+

github/deemru/w8io/873ac7e 
19.01 ms