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