tx · DvRWsBBkbg81VB3jfEyeEnWjKAbFk3Jp2CUoN18RKDFd 3M8dFTdNMkyc4qzX2NRQbBBHAdbaiXgq4h2: -0.05500000 Waves 2025.10.06 03:36 [392010] smart account 3M8dFTdNMkyc4qzX2NRQbBBHAdbaiXgq4h2 > SELF 0.00000000 Waves
{ "type": 13, "id": "DvRWsBBkbg81VB3jfEyeEnWjKAbFk3Jp2CUoN18RKDFd", "fee": 5500000, "feeAssetId": null, "timestamp": 1759711014771, "version": 2, "chainId": 82, "sender": "3M8dFTdNMkyc4qzX2NRQbBBHAdbaiXgq4h2", "senderPublicKey": "BAxLripGQQdvNgtfpwr5UFPXytbou6jDxKVEPsk4bvS3", "proofs": [ "2ArBiqDKi8hQFadrco4Q3NQ8vUdnQ4rxwMrqXxwcb9FG7LU94abnZWAFid9pLGpKxfQJkgxMmMWTb6aqBBwdWRWM" ], "script": "base64:BgIcCAISAwoBGBIJCgcICAgBCAgIEgMKAQgSAwoBCAkAB1ZFUlNJT04CBTEuMC4wAAVMSU1JVAACAAhrX0FETUlOUwILQURNSU5TX1BCS1MACmtfTUFOQUdFUlMCDU1BTkFHRVJTX1BCS1MBDF92YWxpZGF0ZVBiawEDcGJrBAdhZGRyZXNzCQCnCAEJANkEAQUDcGJrBAphZGRyZXNzU3RyCQClCAEFB2FkZHJlc3MFCmFkZHJlc3NTdHIBCV9nZXRMaW1pdAAFBUxJTUlUAQhfaXNBZG1pbgEDcGJrBAlhZG1pbnNTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUIa19BRE1JTlMCAAQGYWRtaW5zCQC1CQIFCWFkbWluc1N0cgIBLAkBAiE9AgkAzwgCBQZhZG1pbnMFA3BiawUEdW5pdAEKX2lzTWFuYWdlcgEDcGJrBAttYW5hZ2Vyc1N0cgkBC3ZhbHVlT3JFbHNlAgkAoggBBQprX01BTkFHRVJTAgAECG1hbmFnZXJzCQC1CQIFC21hbmFnZXJzU3RyAgEsCQECIT0CCQDPCAIFCG1hbmFnZXJzBQNwYmsFBHVuaXQBEF9pc1ZhbGlkT3BlcmF0b3IBA3BiawQLbWFuYWdlcnNTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUKa19NQU5BR0VSUwIABAhtYW5hZ2VycwkAtQkCBQttYW5hZ2Vyc1N0cgIBLAQHaXNBZG1pbgkBCF9pc0FkbWluAQUDcGJrBAlpc01hbmFnZXIJAQpfaXNNYW5hZ2VyAQUDcGJrAwUHaXNBZG1pbgYFCWlzTWFuYWdlcgQBaQEEaW5pdAELYWRtaW5zX3Bia3MEDGNoZWNrX2FkbWlucwMJAQEhAQkBCWlzRGVmaW5lZAEFCGtfQURNSU5TBQR1bml0CQACAQIOQWxyZWFkeSBpbml0ZWQDCQAAAgUMY2hlY2tfYWRtaW5zBQxjaGVja19hZG1pbnMKAQh2YWxpZGF0ZQIFYWNjdW0EbmV4dAkBDF92YWxpZGF0ZVBiawEFBG5leHQECHZhbGlkUmVzCgACJGwFC2FkbWluc19wYmtzCgACJHMJAJADAQUCJGwKAAUkYWNjMAIACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQh2YWxpZGF0ZQIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgMJAAACBQh2YWxpZFJlcwUIdmFsaWRSZXMECWFkbWluc1N0cgkAuQkCBQthZG1pbnNfcGJrcwIBLAkAzAgCCQELU3RyaW5nRW50cnkCBQhrX0FETUlOUwUJYWRtaW5zU3RyBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEHYWRkVGFzawcEbmFtZQRkYXBwBHR4aWQJZXhlY3V0ZVRzBGRlc2MMaW5pdGlhdG9yQWRyBnR4ZGF0YQQJY2FsbGVyUGJrCQDYBAEIBQFpD2NhbGxlclB1YmxpY0tleQMJAQEhAQkBEF9pc1ZhbGlkT3BlcmF0b3IBBQljYWxsZXJQYmsJAAIBAgtOb3QgYWxsb3dlZAQGdGFza0lkCQCsAgIJAKwCAgUEZGFwcAIBXwUEdHhpZAkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIFBnRhc2tJZAIGX19uYW1lBQRuYW1lCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgUGdGFza0lkAgZfX2RhcHAFBGRhcHAJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICBQZ0YXNrSWQCBl9fdHhJZAUEdHhpZAkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIFBnRhc2tJZAIGX19kZXNjBQRkZXNjCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgUGdGFza0lkAghfX3R4ZGF0YQUGdHhkYXRhCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgUGdGFza0lkAgtfX2luaXRpYXRvcgUMaW5pdGlhdG9yQWRyCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBnRhc2tJZAIEX190cwUJZXhlY3V0ZVRzBQNuaWwBaQEPYWRkQ29uZmlybWF0aW9uAQZ0YXNrSWQECWNhbGxlclBiawkA2AQBCAUBaQ9jYWxsZXJQdWJsaWNLZXkEBWxpbWl0CQEJX2dldExpbWl0AAMJAQEhAQkBCF9pc0FkbWluAQUJY2FsbGVyUGJrCQACAQIXT25seSBhZG1pbnMgY2FuIGNvbmZpcm0EBHR4SWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQCsAgIFBnRhc2tJZAIGX190eElkAgtJdmFsaWQgdGFzawMJAAACBQR0eElkBQR0eElkBARkYXBwCQERQGV4dHJOYXRpdmUoMTA1OCkBCQCsAgIFBnRhc2tJZAIGX19kYXBwBBBjb25maXJtYXRpb25zU3RyCQELdmFsdWVPckVsc2UCCQCiCAEJAKwCAgUGdGFza0lkAg9fX2NvbmZpcm1hdGlvbnMCAAQNY29uZmlybWF0aW9ucwkAtQkCBRBjb25maXJtYXRpb25zU3RyAgEsAwkBAiE9AgkAzwgCBQ1jb25maXJtYXRpb25zBQljYWxsZXJQYmsFBHVuaXQJAAIBAhFBbHJlYWR5IGNvbmZpcm1lZAQHbmV3TGlzdAkAzQgCBQ1jb25maXJtYXRpb25zBQljYWxsZXJQYmsECm5ld0xpc3RTdHIJALkJAgUHbmV3TGlzdAIBLAQIYXBwcm92ZWQJAGcCCQCQAwEFB25ld0xpc3QFBWxpbWl0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgUGdGFza0lkAg9fX2NvbmZpcm1hdGlvbnMFCm5ld0xpc3RTdHIJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAKwCAgkArAICCQCsAgIFBGRhcHACAV8FBHR4SWQCCl9fYXBwcm92ZWQFCGFwcHJvdmVkBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEEdGVzdAEDcGJrBAF0CQEMX3ZhbGlkYXRlUGJrAQUDcGJrAwkAAAIFAXQFAXQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgDvhzH6", "height": 392010, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
| Old | New | Differences | |
|---|---|---|---|
| 1 | - | # no script | |
| 1 | + | {-# STDLIB_VERSION 6 #-} | |
| 2 | + | {-# SCRIPT_TYPE ACCOUNT #-} | |
| 3 | + | {-# CONTENT_TYPE DAPP #-} | |
| 4 | + | let VERSION = "1.0.0" | |
| 5 | + | ||
| 6 | + | let LIMIT = 2 | |
| 7 | + | ||
| 8 | + | let k_ADMINS = "ADMINS_PBKS" | |
| 9 | + | ||
| 10 | + | let k_MANAGERS = "MANAGERS_PBKS" | |
| 11 | + | ||
| 12 | + | func _validatePbk (pbk) = { | |
| 13 | + | let address = addressFromPublicKey(fromBase58String(pbk)) | |
| 14 | + | let addressStr = toString(address) | |
| 15 | + | addressStr | |
| 16 | + | } | |
| 17 | + | ||
| 18 | + | ||
| 19 | + | func _getLimit () = LIMIT | |
| 20 | + | ||
| 21 | + | ||
| 22 | + | func _isAdmin (pbk) = { | |
| 23 | + | let adminsStr = valueOrElse(getString(k_ADMINS), "") | |
| 24 | + | let admins = split(adminsStr, ",") | |
| 25 | + | (indexOf(admins, pbk) != unit) | |
| 26 | + | } | |
| 27 | + | ||
| 28 | + | ||
| 29 | + | func _isManager (pbk) = { | |
| 30 | + | let managersStr = valueOrElse(getString(k_MANAGERS), "") | |
| 31 | + | let managers = split(managersStr, ",") | |
| 32 | + | (indexOf(managers, pbk) != unit) | |
| 33 | + | } | |
| 34 | + | ||
| 35 | + | ||
| 36 | + | func _isValidOperator (pbk) = { | |
| 37 | + | let managersStr = valueOrElse(getString(k_MANAGERS), "") | |
| 38 | + | let managers = split(managersStr, ",") | |
| 39 | + | let isAdmin = _isAdmin(pbk) | |
| 40 | + | let isManager = _isManager(pbk) | |
| 41 | + | if (isAdmin) | |
| 42 | + | then true | |
| 43 | + | else isManager | |
| 44 | + | } | |
| 45 | + | ||
| 46 | + | ||
| 47 | + | @Callable(i) | |
| 48 | + | func init (admins_pbks) = { | |
| 49 | + | let check_admins = if (!(isDefined(k_ADMINS))) | |
| 50 | + | then unit | |
| 51 | + | else throw("Already inited") | |
| 52 | + | if ((check_admins == check_admins)) | |
| 53 | + | then { | |
| 54 | + | func validate (accum,next) = _validatePbk(next) | |
| 55 | + | ||
| 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]) | |
| 63 | + | ||
| 64 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
| 65 | + | then $a | |
| 66 | + | else throw("List size exceeds 10") | |
| 67 | + | ||
| 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)) | |
| 71 | + | then { | |
| 72 | + | let adminsStr = makeString(admins_pbks, ",") | |
| 73 | + | [StringEntry(k_ADMINS, adminsStr)] | |
| 74 | + | } | |
| 75 | + | else throw("Strict value is not equal to itself.") | |
| 76 | + | } | |
| 77 | + | else throw("Strict value is not equal to itself.") | |
| 78 | + | } | |
| 79 | + | ||
| 80 | + | ||
| 81 | + | ||
| 82 | + | @Callable(i) | |
| 83 | + | func addTask (name,dapp,txid,executeTs,desc,initiatorAdr,txdata) = { | |
| 84 | + | let callerPbk = toBase58String(i.callerPublicKey) | |
| 85 | + | if (!(_isValidOperator(callerPbk))) | |
| 86 | + | then throw("Not allowed") | |
| 87 | + | else { | |
| 88 | + | let taskId = ((dapp + "_") + txid) | |
| 89 | + | [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)] | |
| 90 | + | } | |
| 91 | + | } | |
| 92 | + | ||
| 93 | + | ||
| 94 | + | ||
| 95 | + | @Callable(i) | |
| 96 | + | func addConfirmation (taskId) = { | |
| 97 | + | let callerPbk = toBase58String(i.callerPublicKey) | |
| 98 | + | let limit = _getLimit() | |
| 99 | + | if (!(_isAdmin(callerPbk))) | |
| 100 | + | then throw("Only admins can confirm") | |
| 101 | + | else { | |
| 102 | + | let txId = valueOrErrorMessage(getString((taskId + "__txId")), "Ivalid task") | |
| 103 | + | if ((txId == txId)) | |
| 104 | + | then { | |
| 105 | + | let dapp = getStringValue((taskId + "__dapp")) | |
| 106 | + | let confirmationsStr = valueOrElse(getString((taskId + "__confirmations")), "") | |
| 107 | + | let confirmations = split(confirmationsStr, ",") | |
| 108 | + | if ((indexOf(confirmations, callerPbk) != unit)) | |
| 109 | + | then throw("Already confirmed") | |
| 110 | + | else { | |
| 111 | + | let newList = (confirmations :+ callerPbk) | |
| 112 | + | let newListStr = makeString(newList, ",") | |
| 113 | + | let approved = (size(newList) >= limit) | |
| 114 | + | [StringEntry((taskId + "__confirmations"), newListStr), BooleanEntry((((dapp + "_") + txId) + "__approved"), approved)] | |
| 115 | + | } | |
| 116 | + | } | |
| 117 | + | else throw("Strict value is not equal to itself.") | |
| 118 | + | } | |
| 119 | + | } | |
| 120 | + | ||
| 121 | + | ||
| 122 | + | ||
| 123 | + | @Callable(i) | |
| 124 | + | func test (pbk) = { | |
| 125 | + | let t = _validatePbk(pbk) | |
| 126 | + | if ((t == t)) | |
| 127 | + | then nil | |
| 128 | + | else throw("Strict value is not equal to itself.") | |
| 129 | + | } | |
| 130 | + | ||
| 131 | + |
github/deemru/w8io 40.03 ms ◑