tx · 9r99Ene4wVXKwqx7LzhD33Vbr7Ein3qwuLVVS7SdkS2h

3M7uzD8rT54fKQcP4s417if1VKU8yromEP2:  -0.05500000 Waves

2025.10.10 03:29 [425575] smart account 3M7uzD8rT54fKQcP4s417if1VKU8yromEP2 > SELF 0.00000000 Waves

{ "type": 13, "id": "9r99Ene4wVXKwqx7LzhD33Vbr7Ein3qwuLVVS7SdkS2h", "fee": 5500000, "feeAssetId": null, "timestamp": 1760056169770, "version": 2, "chainId": 82, "sender": "3M7uzD8rT54fKQcP4s417if1VKU8yromEP2", "senderPublicKey": "2eFPamS5zez1159HEFEJaxs2XPq3AupPbNApNGffRjqf", "proofs": [ "en232uZLHXB1YLDiuP3wfUuFVBFUU6hL7WHiD2BpyBa1f9XM7HQBCn6r6qiNmLYQeR9VW9KhDpNn9Ru9Ze1ovfg" ], "script": "base64:BgIxCAISBAoCGAESAwoBCBIDCgEIEgkKBwgICAEICAgSAwoBCBIDCgEIEgMKAQESAwoBCAsAB1ZFUlNJT04CBTEuMC4wAAVMSU1JVAACAAhrX0FETUlOUwILQURNSU5TX1BCS1MACmtfTUFOQUdFUlMCDU1BTkFHRVJTX1BCS1MAB2tfTElNSVQCDFZPVEVTX1FVT1JVTQEMX3ZhbGlkYXRlUGJrAQNwYmsEB2FkZHJlc3MJAKcIAQkA2QQBBQNwYmsECmFkZHJlc3NTdHIJAKUIAQUHYWRkcmVzcwYBCV9nZXRMaW1pdAAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQdrX0xJTUlUAhhRdW9ydW0gbGltaXQgbm90IGRlZmluZWQBCF9pc0FkbWluAQNwYmsECWFkbWluc1N0cgkBC3ZhbHVlT3JFbHNlAgkAoggBBQhrX0FETUlOUwIABAZhZG1pbnMJALUJAgUJYWRtaW5zU3RyAgEsCQECIT0CCQDPCAIFBmFkbWlucwUDcGJrBQR1bml0AQpfaXNNYW5hZ2VyAQNwYmsEC21hbmFnZXJzU3RyCQELdmFsdWVPckVsc2UCCQCiCAEFCmtfTUFOQUdFUlMCAAQIbWFuYWdlcnMJALUJAgULbWFuYWdlcnNTdHICASwJAQIhPQIJAM8IAgUIbWFuYWdlcnMFA3BiawUEdW5pdAEQX2lzVmFsaWRPcGVyYXRvcgEDcGJrBAttYW5hZ2Vyc1N0cgkBC3ZhbHVlT3JFbHNlAgkAoggBBQprX01BTkFHRVJTAgAECG1hbmFnZXJzCQC1CQIFC21hbmFnZXJzU3RyAgEsBAdpc0FkbWluCQEIX2lzQWRtaW4BBQNwYmsECWlzTWFuYWdlcgkBCl9pc01hbmFnZXIBBQNwYmsDBQdpc0FkbWluBgUJaXNNYW5hZ2VyAQpzYXZlVHhEYXRhAQRkYXRhCQACAQkApAMBCQCxAgEFBGRhdGEIAWkBBGluaXQCC2FkbWluc19wYmtzBWxpbWl0AwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIOU2VsZiBjYWxsIG9ubHkEC3NpemVfYWRtaW5zAwkBAiE9AgkAkAMBBQthZG1pbnNfcGJrcwAABgkAAgECJ0F0IGxlYXN0IG9uZSBhZG1pbiBwYmsgc2hvdWxkIGJlIHBhc3NlZAMJAAACBQtzaXplX2FkbWlucwULc2l6ZV9hZG1pbnMEDGNoZWNrX2FkbWlucwMJAQEhAQkBCWlzRGVmaW5lZAEJAKIIAQUIa19BRE1JTlMGCQACAQIOQWxyZWFkeSBpbml0ZWQDCQAAAgUMY2hlY2tfYWRtaW5zBQxjaGVja19hZG1pbnMECXplcm9MaW1pdAMJAGYCBQVsaW1pdAAABgkAAgECE0xpbWl0IHNob3VsZCBiZSA+IDADCQAAAgUJemVyb0xpbWl0BQl6ZXJvTGltaXQECGxpbWl0X29rAwkAZwIFBWxpbWl0CQCQAwEFC2FkbWluc19wYmtzBgkAAgEJAKwCAgkArAICCQCsAgICOUxpbWl0IHF1b3J1bSBzaG91bGQgYmUgPD0gc2l6ZSBvZiBsaXN0IG9mIGFkbWlucywgbGltaXQ6IAkApAMBBQVsaW1pdAIQLCBjdXJyZW50IHNpemU6IAkApAMBCQCQAwEFC2FkbWluc19wYmtzAwkAAAIFCGxpbWl0X29rBQhsaW1pdF9vawoBCHZhbGlkYXRlAgVhY2N1bQRuZXh0CQEMX3ZhbGlkYXRlUGJrAQUEbmV4dAQIdmFsaWRSZXMKAAIkbAULYWRtaW5zX3Bia3MKAAIkcwkAkAMBBQIkbAoABSRhY2MwAgAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCHZhbGlkYXRlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAwkAAAIFCHZhbGlkUmVzBQh2YWxpZFJlcwQJYWRtaW5zU3RyCQC5CQIFC2FkbWluc19wYmtzAgEsCQDMCAIJAQtTdHJpbmdFbnRyeQIFCGtfQURNSU5TBQlhZG1pbnNTdHIJAMwIAgkBDEludGVnZXJFbnRyeQIFB2tfTElNSVQFBWxpbWl0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEIYWRkQWRtaW4BA3BiawQJY2FsbGVyUGJrCQDYBAEIBQFpD2NhbGxlclB1YmxpY0tleQQHaXNBZG1pbgMJAQhfaXNBZG1pbgEFCWNhbGxlclBiawYJAAIBAhlPbmx5IGFkbWlucyBjYW4gYWRkIGFkbWluAwkAAAIFB2lzQWRtaW4FB2lzQWRtaW4EB2lzVmFsaWQDCQEMX3ZhbGlkYXRlUGJrAQUDcGJrBgkAAgECEUludmFsaWQgYWRtaW4gcGJrAwkAAAIFB2lzVmFsaWQFB2lzVmFsaWQEDG5ld0FkbWluc1N0cgkArAICCQCsAgIJARFAZXh0ck5hdGl2ZSgxMDU4KQEFCGtfQURNSU5TAgEsBQNwYmsJAMwIAgkBC1N0cmluZ0VudHJ5AgUIa19BRE1JTlMFDG5ld0FkbWluc1N0cgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBC3JlbW92ZUFkbWluAQNwYmsECWNhbGxlclBiawkA2AQBCAUBaQ9jYWxsZXJQdWJsaWNLZXkEB2lzQWRtaW4DCQEIX2lzQWRtaW4BBQljYWxsZXJQYmsGCQACAQIZT25seSBhZG1pbnMgY2FuIGFkZCBhZG1pbgMJAAACBQdpc0FkbWluBQdpc0FkbWluBAdpc1ZhbGlkAwkBDF92YWxpZGF0ZVBiawEFA3BiawYJAAIBAhFJbnZhbGlkIGFkbWluIHBiawMJAAACBQdpc1ZhbGlkBQdpc1ZhbGlkBAxvbGRBZG1pbnNTdHIJARFAZXh0ck5hdGl2ZSgxMDU4KQEFCGtfQURNSU5TBAlvbGRBZG1pbnMJALUJAgUMb2xkQWRtaW5zU3RyAgEsBAVpbmRleAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDPCAIFCW9sZEFkbWlucwUDcGJrAhhUaGlzIHBiayBpcyBub3QgYW4gYWRtaW4ECW5ld0FkbWlucwkA0QgCBQlvbGRBZG1pbnMFBWluZGV4BAxuZXdBZG1pbnNTdHIJALkJAgUJbmV3QWRtaW5zAgEsCQDMCAIJAQtTdHJpbmdFbnRyeQIFCGtfQURNSU5TBQxuZXdBZG1pbnNTdHIFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQdhZGRUYXNrBwRuYW1lBGRhcHAEdHhpZAlleGVjdXRlVHMEZGVzYwxpbml0aWF0b3JBZHIGdHhkYXRhBAljYWxsZXJQYmsJANgEAQgFAWkPY2FsbGVyUHVibGljS2V5AwkBASEBCQEQX2lzVmFsaWRPcGVyYXRvcgEFCWNhbGxlclBiawkAAgECC05vdCBhbGxvd2VkBAZ0YXNrSWQJAKwCAgkArAICBQRkYXBwAgFfBQR0eGlkCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgUGdGFza0lkAgZfX25hbWUFBG5hbWUJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICBQZ0YXNrSWQCBl9fZGFwcAUEZGFwcAkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIFBnRhc2tJZAIGX190eElkBQR0eGlkCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgUGdGFza0lkAgZfX2Rlc2MFBGRlc2MJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICBQZ0YXNrSWQCCF9fdHhkYXRhBQZ0eGRhdGEJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICBQZ0YXNrSWQCC19faW5pdGlhdG9yBQxpbml0aWF0b3JBZHIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUGdGFza0lkAgRfX3RzBQlleGVjdXRlVHMFA25pbAFpAQpyZW1vdmVUYXNrAQZ0YXNrSWQECWNhbGxlclBiawkA2AQBCAUBaQ9jYWxsZXJQdWJsaWNLZXkDCQEBIQEJARBfaXNWYWxpZE9wZXJhdG9yAQUJY2FsbGVyUGJrCQACAQILTm90IGFsbG93ZWQEDGluaXRpYXRvckFkcgkBEUBleHRyTmF0aXZlKDEwNTgpAQkArAICBQZ0YXNrSWQCC19faW5pdGlhdG9yAwkBAiE9AgUMaW5pdGlhdG9yQWRyCQClCAEJAKcIAQgFAWkPY2FsbGVyUHVibGljS2V5CQACAQIXT25seSBjcmVhdG9yIGNhbiByZW1vdmUJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICBQZ0YXNrSWQCBl9fbmFtZQkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIFBnRhc2tJZAIGX19kYXBwCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgUGdGFza0lkAgZfX3R4SWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICBQZ0YXNrSWQCBl9fZGVzYwkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIFBnRhc2tJZAIIX190eGRhdGEJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICBQZ0YXNrSWQCC19faW5pdGlhdG9yCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgUGdGFza0lkAgRfX3RzCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgUGdGFza0lkAg9fX2NvbmZpcm1hdGlvbnMJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICBQZ0YXNrSWQCCl9fYXBwcm92ZWQFA25pbAFpAQ9hZGRDb25maXJtYXRpb24BBnRhc2tJZAQJY2FsbGVyUGJrCQDYBAEIBQFpD2NhbGxlclB1YmxpY0tleQQFbGltaXQJAQlfZ2V0TGltaXQAAwkBASEBCQEIX2lzQWRtaW4BBQljYWxsZXJQYmsJAAIBAhdPbmx5IGFkbWlucyBjYW4gY29uZmlybQQEdHhJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJAKwCAgUGdGFza0lkAgZfX3R4SWQCC0l2YWxpZCB0YXNrAwkAAAIFBHR4SWQFBHR4SWQEBGRhcHAJARFAZXh0ck5hdGl2ZSgxMDU4KQEJAKwCAgUGdGFza0lkAgZfX2RhcHAEEGNvbmZpcm1hdGlvbnNTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQkArAICBQZ0YXNrSWQCD19fY29uZmlybWF0aW9ucwIABA1jb25maXJtYXRpb25zCQC1CQIFEGNvbmZpcm1hdGlvbnNTdHICASwDCQECIT0CCQDPCAIFDWNvbmZpcm1hdGlvbnMFCWNhbGxlclBiawUEdW5pdAkAAgECEUFscmVhZHkgY29uZmlybWVkBAduZXdMaXN0AwkBAiE9AgUQY29uZmlybWF0aW9uc1N0cgIACQDNCAIFDWNvbmZpcm1hdGlvbnMFCWNhbGxlclBiawkAzAgCBQljYWxsZXJQYmsFA25pbAQKbmV3TGlzdFN0cgkAuQkCBQduZXdMaXN0AgEsBAhhcHByb3ZlZAkAZwIJAJADAQUHbmV3TGlzdAUFbGltaXQJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICBQZ0YXNrSWQCD19fY29uZmlybWF0aW9ucwUKbmV3TGlzdFN0cgkAzAgCCQEMQm9vbGVhbkVudHJ5AgkArAICCQCsAgIJAKwCAgUEZGFwcAIBXwUEdHhJZAIKX19hcHByb3ZlZAUIYXBwcm92ZWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQhzZXRMaW1pdAEFbGltaXQECWNhbGxlclBiawkA2AQBCAUBaQ9jYWxsZXJQdWJsaWNLZXkDCQEBIQEJAQhfaXNBZG1pbgEFCWNhbGxlclBiawkAAgECHk9ubHkgd2hpdGVsaXN0ZWQgY2FuIHNldCBsaW1pdAQJemVyb0xpbWl0AwkAZgIFBWxpbWl0AAAGCQACAQITTGltaXQgc2hvdWxkIGJlID4gMAMJAAACBQl6ZXJvTGltaXQFCXplcm9MaW1pdAQGYWRtaW5zCQERQGV4dHJOYXRpdmUoMTA1OCkBBQhrX0FETUlOUwMJAGYCBQVsaW1pdAkAsQIBBQZhZG1pbnMJAAIBCQCsAgIJAKwCAgkArAICAjlMaW1pdCBxdW9ydW0gc2hvdWxkIGJlIDw9IHNpemUgb2YgbGlzdCBvZiBhZG1pbnMsIGxpbWl0OiAJAKQDAQUFbGltaXQCECwgY3VycmVudCBzaXplOiAJAKQDAQkAsQIBBQZhZG1pbnMJAMwIAgkBDEludGVnZXJFbnRyeQIFB2tfTElNSVQFBWxpbWl0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEEdGVzdAEDcGJrCQEKc2F2ZVR4RGF0YQEFA3BiawAwBvdz", "height": 425575, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 376dYWa9ovhJnHtZcgNvSus9sGoUvXpytE4smZ96ne94 Next: FvRCpvxFVPkUS1qEde7n1wBYyenqEG6JutZTF7gPxi9n Diff:
OldNewDifferences
99
1010 let k_MANAGERS = "MANAGERS_PBKS"
1111
12+let k_LIMIT = "VOTES_QUORUM"
13+
1214 func _validatePbk (pbk) = {
1315 let address = addressFromPublicKey(fromBase58String(pbk))
1416 let addressStr = toString(address)
15- addressStr
17+ true
1618 }
1719
1820
19-func _getLimit () = LIMIT
21+func _getLimit () = valueOrErrorMessage(getInteger(k_LIMIT), "Quorum limit not defined")
2022
2123
2224 func _isAdmin (pbk) = {
4446 }
4547
4648
49+func saveTxData (data) = throw(toString(size(data)))
50+
51+
4752 @Callable(i)
48-func init (admins_pbks) = {
49- let check_admins = if (!(isDefined(getString(k_ADMINS))))
50- then unit
51- else throw("Already inited")
52- if ((check_admins == check_admins))
53+func init (admins_pbks,limit) = if ((i.caller != this))
54+ then throw("Self call only")
55+ else {
56+ let size_admins = if ((size(admins_pbks) != 0))
57+ then true
58+ else throw("At least one admin pbk should be passed")
59+ if ((size_admins == size_admins))
60+ then {
61+ let check_admins = if (!(isDefined(getString(k_ADMINS))))
62+ then true
63+ else throw("Already inited")
64+ if ((check_admins == check_admins))
65+ then {
66+ let zeroLimit = if ((limit > 0))
67+ then true
68+ else throw("Limit should be > 0")
69+ if ((zeroLimit == zeroLimit))
70+ then {
71+ let limit_ok = if ((limit >= size(admins_pbks)))
72+ then true
73+ else throw(((("Limit quorum should be <= size of list of admins, limit: " + toString(limit)) + ", current size: ") + toString(size(admins_pbks))))
74+ if ((limit_ok == limit_ok))
75+ then {
76+ func validate (accum,next) = _validatePbk(next)
77+
78+ let validRes = {
79+ let $l = admins_pbks
80+ let $s = size($l)
81+ let $acc0 = ""
82+ func $f0_1 ($a,$i) = if (($i >= $s))
83+ then $a
84+ else validate($a, $l[$i])
85+
86+ func $f0_2 ($a,$i) = if (($i >= $s))
87+ then $a
88+ else throw("List size exceeds 10")
89+
90+ $f0_2($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)
91+ }
92+ if ((validRes == validRes))
93+ then {
94+ let adminsStr = makeString(admins_pbks, ",")
95+[StringEntry(k_ADMINS, adminsStr), IntegerEntry(k_LIMIT, limit)]
96+ }
97+ else throw("Strict value is not equal to itself.")
98+ }
99+ else throw("Strict value is not equal to itself.")
100+ }
101+ else throw("Strict value is not equal to itself.")
102+ }
103+ else throw("Strict value is not equal to itself.")
104+ }
105+ else throw("Strict value is not equal to itself.")
106+ }
107+
108+
109+
110+@Callable(i)
111+func addAdmin (pbk) = {
112+ let callerPbk = toBase58String(i.callerPublicKey)
113+ let isAdmin = if (_isAdmin(callerPbk))
114+ then true
115+ else throw("Only admins can add admin")
116+ if ((isAdmin == isAdmin))
53117 then {
54- func validate (accum,next) = _validatePbk(next)
118+ let isValid = if (_validatePbk(pbk))
119+ then true
120+ else throw("Invalid admin pbk")
121+ if ((isValid == isValid))
122+ then {
123+ let newAdminsStr = ((getStringValue(k_ADMINS) + ",") + pbk)
124+[StringEntry(k_ADMINS, newAdminsStr)]
125+ }
126+ else throw("Strict value is not equal to itself.")
127+ }
128+ else throw("Strict value is not equal to itself.")
129+ }
55130
56- let validRes = {
57- let $l = admins_pbks
58- let $s = size($l)
59- let $acc0 = ""
60- func $f0_1 ($a,$i) = if (($i >= $s))
61- then $a
62- else validate($a, $l[$i])
63131
64- func $f0_2 ($a,$i) = if (($i >= $s))
65- then $a
66- else throw("List size exceeds 10")
67132
68- $f0_2($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)
69- }
70- if ((validRes == validRes))
133+@Callable(i)
134+func removeAdmin (pbk) = {
135+ let callerPbk = toBase58String(i.callerPublicKey)
136+ let isAdmin = if (_isAdmin(callerPbk))
137+ then true
138+ else throw("Only admins can add admin")
139+ if ((isAdmin == isAdmin))
140+ then {
141+ let isValid = if (_validatePbk(pbk))
142+ then true
143+ else throw("Invalid admin pbk")
144+ if ((isValid == isValid))
71145 then {
72- let adminsStr = makeString(admins_pbks, ",")
73-[StringEntry(k_ADMINS, adminsStr)]
146+ let oldAdminsStr = getStringValue(k_ADMINS)
147+ let oldAdmins = split(oldAdminsStr, ",")
148+ let index = valueOrErrorMessage(indexOf(oldAdmins, pbk), "This pbk is not an admin")
149+ let newAdmins = removeByIndex(oldAdmins, index)
150+ let newAdminsStr = makeString(newAdmins, ",")
151+[StringEntry(k_ADMINS, newAdminsStr)]
74152 }
75153 else throw("Strict value is not equal to itself.")
76154 }
138216
139217
140218 @Callable(i)
141-func test (pbk) = {
142- let t = _validatePbk(pbk)
143- if ((t == t))
144- then nil
145- else throw("Strict value is not equal to itself.")
219+func setLimit (limit) = {
220+ let callerPbk = toBase58String(i.callerPublicKey)
221+ if (!(_isAdmin(callerPbk)))
222+ then throw("Only whitelisted can set limit")
223+ else {
224+ let zeroLimit = if ((limit > 0))
225+ then true
226+ else throw("Limit should be > 0")
227+ if ((zeroLimit == zeroLimit))
228+ then {
229+ let admins = getStringValue(k_ADMINS)
230+ if ((limit > size(admins)))
231+ then throw(((("Limit quorum should be <= size of list of admins, limit: " + toString(limit)) + ", current size: ") + toString(size(admins))))
232+ else [IntegerEntry(k_LIMIT, limit)]
233+ }
234+ else throw("Strict value is not equal to itself.")
235+ }
146236 }
237+
238+
239+
240+@Callable(i)
241+func test (pbk) = saveTxData(pbk)
147242
148243
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let VERSION = "1.0.0"
55
66 let LIMIT = 2
77
88 let k_ADMINS = "ADMINS_PBKS"
99
1010 let k_MANAGERS = "MANAGERS_PBKS"
1111
12+let k_LIMIT = "VOTES_QUORUM"
13+
1214 func _validatePbk (pbk) = {
1315 let address = addressFromPublicKey(fromBase58String(pbk))
1416 let addressStr = toString(address)
15- addressStr
17+ true
1618 }
1719
1820
19-func _getLimit () = LIMIT
21+func _getLimit () = valueOrErrorMessage(getInteger(k_LIMIT), "Quorum limit not defined")
2022
2123
2224 func _isAdmin (pbk) = {
2325 let adminsStr = valueOrElse(getString(k_ADMINS), "")
2426 let admins = split(adminsStr, ",")
2527 (indexOf(admins, pbk) != unit)
2628 }
2729
2830
2931 func _isManager (pbk) = {
3032 let managersStr = valueOrElse(getString(k_MANAGERS), "")
3133 let managers = split(managersStr, ",")
3234 (indexOf(managers, pbk) != unit)
3335 }
3436
3537
3638 func _isValidOperator (pbk) = {
3739 let managersStr = valueOrElse(getString(k_MANAGERS), "")
3840 let managers = split(managersStr, ",")
3941 let isAdmin = _isAdmin(pbk)
4042 let isManager = _isManager(pbk)
4143 if (isAdmin)
4244 then true
4345 else isManager
4446 }
4547
4648
49+func saveTxData (data) = throw(toString(size(data)))
50+
51+
4752 @Callable(i)
48-func init (admins_pbks) = {
49- let check_admins = if (!(isDefined(getString(k_ADMINS))))
50- then unit
51- else throw("Already inited")
52- if ((check_admins == check_admins))
53+func init (admins_pbks,limit) = if ((i.caller != this))
54+ then throw("Self call only")
55+ else {
56+ let size_admins = if ((size(admins_pbks) != 0))
57+ then true
58+ else throw("At least one admin pbk should be passed")
59+ if ((size_admins == size_admins))
60+ then {
61+ let check_admins = if (!(isDefined(getString(k_ADMINS))))
62+ then true
63+ else throw("Already inited")
64+ if ((check_admins == check_admins))
65+ then {
66+ let zeroLimit = if ((limit > 0))
67+ then true
68+ else throw("Limit should be > 0")
69+ if ((zeroLimit == zeroLimit))
70+ then {
71+ let limit_ok = if ((limit >= size(admins_pbks)))
72+ then true
73+ else throw(((("Limit quorum should be <= size of list of admins, limit: " + toString(limit)) + ", current size: ") + toString(size(admins_pbks))))
74+ if ((limit_ok == limit_ok))
75+ then {
76+ func validate (accum,next) = _validatePbk(next)
77+
78+ let validRes = {
79+ let $l = admins_pbks
80+ let $s = size($l)
81+ let $acc0 = ""
82+ func $f0_1 ($a,$i) = if (($i >= $s))
83+ then $a
84+ else validate($a, $l[$i])
85+
86+ func $f0_2 ($a,$i) = if (($i >= $s))
87+ then $a
88+ else throw("List size exceeds 10")
89+
90+ $f0_2($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)
91+ }
92+ if ((validRes == validRes))
93+ then {
94+ let adminsStr = makeString(admins_pbks, ",")
95+[StringEntry(k_ADMINS, adminsStr), IntegerEntry(k_LIMIT, limit)]
96+ }
97+ else throw("Strict value is not equal to itself.")
98+ }
99+ else throw("Strict value is not equal to itself.")
100+ }
101+ else throw("Strict value is not equal to itself.")
102+ }
103+ else throw("Strict value is not equal to itself.")
104+ }
105+ else throw("Strict value is not equal to itself.")
106+ }
107+
108+
109+
110+@Callable(i)
111+func addAdmin (pbk) = {
112+ let callerPbk = toBase58String(i.callerPublicKey)
113+ let isAdmin = if (_isAdmin(callerPbk))
114+ then true
115+ else throw("Only admins can add admin")
116+ if ((isAdmin == isAdmin))
53117 then {
54- func validate (accum,next) = _validatePbk(next)
118+ let isValid = if (_validatePbk(pbk))
119+ then true
120+ else throw("Invalid admin pbk")
121+ if ((isValid == isValid))
122+ then {
123+ let newAdminsStr = ((getStringValue(k_ADMINS) + ",") + pbk)
124+[StringEntry(k_ADMINS, newAdminsStr)]
125+ }
126+ else throw("Strict value is not equal to itself.")
127+ }
128+ else throw("Strict value is not equal to itself.")
129+ }
55130
56- let validRes = {
57- let $l = admins_pbks
58- let $s = size($l)
59- let $acc0 = ""
60- func $f0_1 ($a,$i) = if (($i >= $s))
61- then $a
62- else validate($a, $l[$i])
63131
64- func $f0_2 ($a,$i) = if (($i >= $s))
65- then $a
66- else throw("List size exceeds 10")
67132
68- $f0_2($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)
69- }
70- if ((validRes == validRes))
133+@Callable(i)
134+func removeAdmin (pbk) = {
135+ let callerPbk = toBase58String(i.callerPublicKey)
136+ let isAdmin = if (_isAdmin(callerPbk))
137+ then true
138+ else throw("Only admins can add admin")
139+ if ((isAdmin == isAdmin))
140+ then {
141+ let isValid = if (_validatePbk(pbk))
142+ then true
143+ else throw("Invalid admin pbk")
144+ if ((isValid == isValid))
71145 then {
72- let adminsStr = makeString(admins_pbks, ",")
73-[StringEntry(k_ADMINS, adminsStr)]
146+ let oldAdminsStr = getStringValue(k_ADMINS)
147+ let oldAdmins = split(oldAdminsStr, ",")
148+ let index = valueOrErrorMessage(indexOf(oldAdmins, pbk), "This pbk is not an admin")
149+ let newAdmins = removeByIndex(oldAdmins, index)
150+ let newAdminsStr = makeString(newAdmins, ",")
151+[StringEntry(k_ADMINS, newAdminsStr)]
74152 }
75153 else throw("Strict value is not equal to itself.")
76154 }
77155 else throw("Strict value is not equal to itself.")
78156 }
79157
80158
81159
82160 @Callable(i)
83161 func addTask (name,dapp,txid,executeTs,desc,initiatorAdr,txdata) = {
84162 let callerPbk = toBase58String(i.callerPublicKey)
85163 if (!(_isValidOperator(callerPbk)))
86164 then throw("Not allowed")
87165 else {
88166 let taskId = ((dapp + "_") + txid)
89167 [StringEntry((taskId + "__name"), name), StringEntry((taskId + "__dapp"), dapp), StringEntry((taskId + "__txId"), txid), StringEntry((taskId + "__desc"), desc), StringEntry((taskId + "__txdata"), txdata), StringEntry((taskId + "__initiator"), initiatorAdr), IntegerEntry((taskId + "__ts"), executeTs)]
90168 }
91169 }
92170
93171
94172
95173 @Callable(i)
96174 func removeTask (taskId) = {
97175 let callerPbk = toBase58String(i.callerPublicKey)
98176 if (!(_isValidOperator(callerPbk)))
99177 then throw("Not allowed")
100178 else {
101179 let initiatorAdr = getStringValue((taskId + "__initiator"))
102180 if ((initiatorAdr != toString(addressFromPublicKey(i.callerPublicKey))))
103181 then throw("Only creator can remove")
104182 else [DeleteEntry((taskId + "__name")), DeleteEntry((taskId + "__dapp")), DeleteEntry((taskId + "__txId")), DeleteEntry((taskId + "__desc")), DeleteEntry((taskId + "__txdata")), DeleteEntry((taskId + "__initiator")), DeleteEntry((taskId + "__ts")), DeleteEntry((taskId + "__confirmations")), DeleteEntry((taskId + "__approved"))]
105183 }
106184 }
107185
108186
109187
110188 @Callable(i)
111189 func addConfirmation (taskId) = {
112190 let callerPbk = toBase58String(i.callerPublicKey)
113191 let limit = _getLimit()
114192 if (!(_isAdmin(callerPbk)))
115193 then throw("Only admins can confirm")
116194 else {
117195 let txId = valueOrErrorMessage(getString((taskId + "__txId")), "Ivalid task")
118196 if ((txId == txId))
119197 then {
120198 let dapp = getStringValue((taskId + "__dapp"))
121199 let confirmationsStr = valueOrElse(getString((taskId + "__confirmations")), "")
122200 let confirmations = split(confirmationsStr, ",")
123201 if ((indexOf(confirmations, callerPbk) != unit))
124202 then throw("Already confirmed")
125203 else {
126204 let newList = if ((confirmationsStr != ""))
127205 then (confirmations :+ callerPbk)
128206 else [callerPbk]
129207 let newListStr = makeString(newList, ",")
130208 let approved = (size(newList) >= limit)
131209 [StringEntry((taskId + "__confirmations"), newListStr), BooleanEntry((((dapp + "_") + txId) + "__approved"), approved)]
132210 }
133211 }
134212 else throw("Strict value is not equal to itself.")
135213 }
136214 }
137215
138216
139217
140218 @Callable(i)
141-func test (pbk) = {
142- let t = _validatePbk(pbk)
143- if ((t == t))
144- then nil
145- else throw("Strict value is not equal to itself.")
219+func setLimit (limit) = {
220+ let callerPbk = toBase58String(i.callerPublicKey)
221+ if (!(_isAdmin(callerPbk)))
222+ then throw("Only whitelisted can set limit")
223+ else {
224+ let zeroLimit = if ((limit > 0))
225+ then true
226+ else throw("Limit should be > 0")
227+ if ((zeroLimit == zeroLimit))
228+ then {
229+ let admins = getStringValue(k_ADMINS)
230+ if ((limit > size(admins)))
231+ then throw(((("Limit quorum should be <= size of list of admins, limit: " + toString(limit)) + ", current size: ") + toString(size(admins))))
232+ else [IntegerEntry(k_LIMIT, limit)]
233+ }
234+ else throw("Strict value is not equal to itself.")
235+ }
146236 }
237+
238+
239+
240+@Callable(i)
241+func test (pbk) = saveTxData(pbk)
147242
148243

github/deemru/w8io
27.46 ms