tx · AwBdwbz8KPPNz3mDWC6WHGeG6X7mWQcYwek7FKa7dfuB

3M7uzD8rT54fKQcP4s417if1VKU8yromEP2:  -0.05500000 Waves

2025.10.17 03:06 [484709] smart account 3M7uzD8rT54fKQcP4s417if1VKU8yromEP2 > SELF 0.00000000 Waves

{ "type": 13, "id": "AwBdwbz8KPPNz3mDWC6WHGeG6X7mWQcYwek7FKa7dfuB", "fee": 5500000, "feeAssetId": null, "timestamp": 1760659591057, "version": 2, "chainId": 82, "sender": "3M7uzD8rT54fKQcP4s417if1VKU8yromEP2", "senderPublicKey": "2eFPamS5zez1159HEFEJaxs2XPq3AupPbNApNGffRjqf", "proofs": [ "5KQqYNUAAWr61dBF4iFvsVNg2y11ZLcahr6smFDob2oF7xuJ3w6sqcQqRHijELtmwYSkLrYVBSdi6fRgg3PiTUwg" ], "script": "base64:BgJTCAISBQoDGAEBEgMKAQgSAwoBCBIDCgEIEgMKAQgSBwoFCAgICAgSAwoBCBIDCgEIEgMKAQgSCQoHCAgIAQgICBIDCgEIEgMKAQgSAwoBARIAEgAZAAdWRVJTSU9OAgUxLjAuMAADU0VQAgFfAAZCSUdTRVACAl9fAAhrX0FETUlOUwILQURNSU5TX1BCS1MACmtfTUFOQUdFUlMCDU1BTkFHRVJTX1BCS1MAB2tfTElNSVQCDFZPVEVTX1FVT1JVTQAOa19TQ1JJUFRfVFlQRVMCDFNDUklQVF9UWVBFUwALa19JVEVSQVRJT04CCUlURVJBVElPTgAQa19BUFBST1ZFRF9DT1VOVAIOQVBQUk9WRURfQ09VTlQADGtfc2NyaXB0VHlwZQIKc2NyaXB0VHlwZQAMa19zY3JpcHRIYXNoAgpzY3JpcHRIYXNoABBrX3N0b3JhZ2VBZGRyZXNzAg5zdG9yYWdlQWRkcmVzcwAGa19kZXNjAgRkZXNjAAZrX2l0ZXICCWl0ZXJhdGlvbgALa19pbml0aWF0b3ICCWluaXRpYXRvcgAPa19jb25maXJtYXRpb25zAg1jb25maXJtYXRpb25zAQxfdmFsaWRhdGVQYmsBA3BiawQHYWRkcmVzcwkApwgBCQDZBAEFA3BiawMJAAACBQdhZGRyZXNzBQdhZGRyZXNzBAphZGRyZXNzU3RyCQClCAEFB2FkZHJlc3MDCQAAAgUKYWRkcmVzc1N0cgUKYWRkcmVzc1N0cgYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BEF92YWxpZGF0ZUFkZHJlc3MBB2FkZHJlc3MEBGFkZHIJARFAZXh0ck5hdGl2ZSgxMDYyKQEFB2FkZHJlc3MDCQAAAgUEYWRkcgUEYWRkcgYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BC192YWxpZGF0ZVRzAQJ0cwQGY3VyclRzBAckbWF0Y2gwCQDtBwEFBmhlaWdodAMJAAECBQckbWF0Y2gwAglCbG9ja0luZm8EBWJsb2NrBQckbWF0Y2gwCAUFYmxvY2sJdGltZXN0YW1wCQACAQIQQ2FuJ3QgZmluZCBibG9jawkAZgIFAnRzBQZjdXJyVHMBCV9nZXRMaW1pdAAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQdrX0xJTUlUAhhRdW9ydW0gbGltaXQgbm90IGRlZmluZWQBEV9nZXRBcHByb3ZlZENvdW50AAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFEGtfQVBQUk9WRURfQ09VTlQCNUFtb3VudCBvZiBzaW11bHRhbmVvdXNseSBhcHByb3ZlZCBzY3JpcHRzIG5vdCBkZWZpbmVkAQhfaXNBZG1pbgEDcGJrBAlhZG1pbnNTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUIa19BRE1JTlMCAAQGYWRtaW5zCQC1CQIFCWFkbWluc1N0cgIBLAkBAiE9AgkAzwgCBQZhZG1pbnMFA3BiawUEdW5pdAEKX2lzTWFuYWdlcgEDcGJrBAttYW5hZ2Vyc1N0cgkBC3ZhbHVlT3JFbHNlAgkAoggBBQprX01BTkFHRVJTAgAECG1hbmFnZXJzCQC1CQIFC21hbmFnZXJzU3RyAgEsCQECIT0CCQDPCAIFCG1hbmFnZXJzBQNwYmsFBHVuaXQBEF9pc1ZhbGlkT3BlcmF0b3IBA3BiawQLbWFuYWdlcnNTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUKa19NQU5BR0VSUwIABAhtYW5hZ2VycwkAtQkCBQttYW5hZ2Vyc1N0cgIBLAQHaXNBZG1pbgkBCF9pc0FkbWluAQUDcGJrBAlpc01hbmFnZXIJAQpfaXNNYW5hZ2VyAQUDcGJrAwUHaXNBZG1pbgYFCWlzTWFuYWdlcgEKc2F2ZVR4RGF0YQIGdGFza0lkBGRhdGEEB2luZGljZXMJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQkAzAgCAAYJAMwIAgAHCQDMCAIACAkAzAgCAAkJAMwIAgAKBQNuaWwECGRhdGFTaXplCQCxAgEFBGRhdGEECmlzTm90RW1wdHkDCQECIT0CBQhkYXRhU2l6ZQAABgkAAgECHXNhdmVUeERhdGE6IEVtcHR5IGRhdGEgcGFzc2VkAwkAAAIFCmlzTm90RW1wdHkFCmlzTm90RW1wdHkECWNodW5rU2l6ZQCw6gEEC2NodW5rc0NvdW50AwkAAAIJAGoCBQhkYXRhU2l6ZQUJY2h1bmtTaXplAAAJAGkCBQhkYXRhU2l6ZQUJY2h1bmtTaXplCQBkAgkAaQIFCGRhdGFTaXplBQljaHVua1NpemUAAQoBCm1ha2VDaHVua3MCBWFjY3VtBWluZGV4BAVjaHVuawkArwICCAUFYWNjdW0CXzEFCWNodW5rU2l6ZQMJAAACCQCxAgEFBWNodW5rAAAFBWFjY3VtBAhuZXh0RGF0YQkAsAICCAUFYWNjdW0CXzEFCWNodW5rU2l6ZQkAlAoCBQhuZXh0RGF0YQkAzQgCCAUFYWNjdW0CXzIJAQtTdHJpbmdFbnRyeQIJAKwCAgkArAICBQZ0YXNrSWQCCV9fdHhkYXRhXwkApAMBBQVpbmRleAUFY2h1bmsEB2VudHJpZXMKAAIkbAUHaW5kaWNlcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUEZGF0YQkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIFBnRhc2tJZAIPX190eGRhdGFfY2h1bmtzCQCkAwEFC2NodW5rc0NvdW50BQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCm1ha2VDaHVua3MCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoIBQdlbnRyaWVzAl8yCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuDwFpAQRpbml0AwthZG1pbnNfcGJrcwVsaW1pdA1hcHByb3ZlZENvdW50AwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIOU2VsZiBjYWxsIG9ubHkEC3NpemVfYWRtaW5zAwkBAiE9AgkAkAMBBQthZG1pbnNfcGJrcwAABgkAAgECJ0F0IGxlYXN0IG9uZSBhZG1pbiBwYmsgc2hvdWxkIGJlIHBhc3NlZAMJAAACBQtzaXplX2FkbWlucwULc2l6ZV9hZG1pbnMEDGNoZWNrX2FkbWlucwMJAQEhAQkBCWlzRGVmaW5lZAEJAKIIAQUIa19BRE1JTlMGCQACAQIOQWxyZWFkeSBpbml0ZWQDCQAAAgUMY2hlY2tfYWRtaW5zBQxjaGVja19hZG1pbnMECXplcm9MaW1pdAMJAGYCBQVsaW1pdAAABgkAAgECE0xpbWl0IHNob3VsZCBiZSA+IDADCQAAAgUJemVyb0xpbWl0BQl6ZXJvTGltaXQECGxpbWl0X29rAwkAZgIJAJADAQULYWRtaW5zX3Bia3MFBWxpbWl0BgkAAgEJAKwCAgkArAICCQCsAgICOUxpbWl0IHF1b3J1bSBzaG91bGQgYmUgPD0gc2l6ZSBvZiBsaXN0IG9mIGFkbWlucywgbGltaXQ6IAkApAMBBQVsaW1pdAIQLCBjdXJyZW50IHNpemU6IAkApAMBCQCQAwEFC2FkbWluc19wYmtzAwkAAAIFCGxpbWl0X29rBQhsaW1pdF9vawoBCHZhbGlkYXRlAgVhY2N1bQRuZXh0CQEMX3ZhbGlkYXRlUGJrAQUEbmV4dAQIdmFsaWRSZXMKAAIkbAULYWRtaW5zX3Bia3MKAAIkcwkAkAMBBQIkbAoABSRhY2MwAgAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCHZhbGlkYXRlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAwkAAAIFCHZhbGlkUmVzBQh2YWxpZFJlcwQJYWRtaW5zU3RyCQC5CQIFC2FkbWluc19wYmtzAgEsCQDMCAIJAQtTdHJpbmdFbnRyeQIFCGtfQURNSU5TBQlhZG1pbnNTdHIJAMwIAgkBDEludGVnZXJFbnRyeQIFB2tfTElNSVQFBWxpbWl0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRBrX0FQUFJPVkVEX0NPVU5UBQ1hcHByb3ZlZENvdW50BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEIYWRkQWRtaW4BA3BiawQJY2FsbGVyUGJrCQDYBAEIBQFpD2NhbGxlclB1YmxpY0tleQQHaXNBZG1pbgMJAQhfaXNBZG1pbgEFCWNhbGxlclBiawYJAAIBAhlPbmx5IGFkbWlucyBjYW4gYWRkIGFkbWluAwkAAAIFB2lzQWRtaW4FB2lzQWRtaW4EB2lzVmFsaWQDCQEMX3ZhbGlkYXRlUGJrAQUDcGJrBgkAAgECEUludmFsaWQgYWRtaW4gcGJrAwkAAAIFB2lzVmFsaWQFB2lzVmFsaWQEDG5ld0FkbWluc1N0cgkArAICCQCsAgIJARFAZXh0ck5hdGl2ZSgxMDU4KQEFCGtfQURNSU5TAgEsBQNwYmsJAMwIAgkBC1N0cmluZ0VudHJ5AgUIa19BRE1JTlMFDG5ld0FkbWluc1N0cgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBC3JlbW92ZUFkbWluAQNwYmsECWNhbGxlclBiawkA2AQBCAUBaQ9jYWxsZXJQdWJsaWNLZXkEB2lzQWRtaW4DCQEIX2lzQWRtaW4BBQljYWxsZXJQYmsGCQACAQIZT25seSBhZG1pbnMgY2FuIGFkZCBhZG1pbgMJAAACBQdpc0FkbWluBQdpc0FkbWluBAdpc1ZhbGlkAwkBDF92YWxpZGF0ZVBiawEFA3BiawYJAAIBAhFJbnZhbGlkIGFkbWluIHBiawMJAAACBQdpc1ZhbGlkBQdpc1ZhbGlkBAxvbGRBZG1pbnNTdHIJARFAZXh0ck5hdGl2ZSgxMDU4KQEFCGtfQURNSU5TBAlvbGRBZG1pbnMJALUJAgUMb2xkQWRtaW5zU3RyAgEsBApjaGVja0NvdW50AwkAZwIAAQkAkAMBBQlvbGRBZG1pbnMJAAIBAi9DYW5ub3QgcmVtb3ZlLCBhdCBsZWFzdCBvbmUgYWRtaW4gc2hvdWxkIHJlbWFpbgYDCQAAAgUKY2hlY2tDb3VudAUKY2hlY2tDb3VudAQFaW5kZXgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAzwgCBQlvbGRBZG1pbnMFA3BiawIYVGhpcyBwYmsgaXMgbm90IGFuIGFkbWluBAluZXdBZG1pbnMJANEIAgUJb2xkQWRtaW5zBQVpbmRleAQMbmV3QWRtaW5zU3RyCQC5CQIFCW5ld0FkbWlucwIBLAkAzAgCCQELU3RyaW5nRW50cnkCBQhrX0FETUlOUwUMbmV3QWRtaW5zU3RyBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQENYWRkU2NyaXB0VHlwZQEKc2NyaXB0VHlwZQQJY2FsbGVyUGJrCQDYBAEIBQFpD2NhbGxlclB1YmxpY0tleQMJAQEhAQkBCF9pc0FkbWluAQUJY2FsbGVyUGJrCQACAQILTm90IGFsbG93ZWQECmNoZWNrRW1wdHkDCQAAAgkAsQIBBQpzY3JpcHRUeXBlAAAJAAIBAhxTY3JpcHQgdHlwZSBjYW4gbm90IGJlIGVtcHR5BgMJAAACBQpjaGVja0VtcHR5BQpjaGVja0VtcHR5BA5zY3JpcHRUeXBlc1N0cgkBC3ZhbHVlT3JFbHNlAgkAoggBBQ5rX1NDUklQVF9UWVBFUwIABAtzY3JpcHRUeXBlcwkAvAkCBQ5zY3JpcHRUeXBlc1N0cgIBLAQLY2hlY2tFeGlzdHMDCQECIT0CCQDPCAIFC3NjcmlwdFR5cGVzBQpzY3JpcHRUeXBlBQR1bml0CQACAQkArAICCQCsAgICDVNjcmlwdCB0eXBlIDwFCnNjcmlwdFR5cGUCDz4gYWxyZWFkeSBhZGRlZAYDCQAAAgULY2hlY2tFeGlzdHMFC2NoZWNrRXhpc3RzBA5uZXdTY3JpcHRUeXBlcwMJAQIhPQIFDnNjcmlwdFR5cGVzU3RyAgAJAM0IAgULc2NyaXB0VHlwZXMFCnNjcmlwdFR5cGUJAMwIAgUKc2NyaXB0VHlwZQUDbmlsBBFuZXdTY3JpcHRUeXBlc1N0cgkAuQkCBQ5uZXdTY3JpcHRUeXBlcwIBLAkAzAgCCQELU3RyaW5nRW50cnkCBQ5rX1NDUklQVF9UWVBFUwURbmV3U2NyaXB0VHlwZXNTdHIFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARByZW1vdmVTY3JpcHRUeXBlAQpzY3JpcHRUeXBlBAljYWxsZXJQYmsJANgEAQgFAWkPY2FsbGVyUHVibGljS2V5AwkBASEBCQEIX2lzQWRtaW4BBQljYWxsZXJQYmsJAAIBAgtOb3QgYWxsb3dlZAQOc2NyaXB0VHlwZXNTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUOa19TQ1JJUFRfVFlQRVMCAAQLc2NyaXB0VHlwZXMJALwJAgUOc2NyaXB0VHlwZXNTdHICASwEBWluZGV4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAM8IAgULc2NyaXB0VHlwZXMFCnNjcmlwdFR5cGUJAKwCAgkArAICAg1TY3JpcHQgdHlwZSA8BQpzY3JpcHRUeXBlAhA+IGlzIG5vdCBwcmVzZW50BA5uZXdTY3JpcHRUeXBlcwkA0QgCBQtzY3JpcHRUeXBlcwUFaW5kZXgEEW5ld1NjcmlwdFR5cGVzU3RyCQC5CQIFDm5ld1NjcmlwdFR5cGVzAgEsCQDMCAIJAQtTdHJpbmdFbnRyeQIFDmtfU0NSSVBUX1RZUEVTBRFuZXdTY3JpcHRUeXBlc1N0cgUDbmlsAWkBCWFkZFNjcmlwdAUKc2NyaXB0VHlwZQ5zdG9yYWdlQWRkcmVzcwtfc2NyaXB0SGFzaARkZXNjDGluaXRpYXRvckFkcgQJY2FsbGVyUGJrCQDYBAEIBQFpD2NhbGxlclB1YmxpY0tleQMJAQEhAQkBEF9pc1ZhbGlkT3BlcmF0b3IBBQljYWxsZXJQYmsJAAIBAgtOb3QgYWxsb3dlZAQRc3RvcmFnZVNjcmlwdEhhc2gJANgEAQkBBXZhbHVlAQkA8QcBCQERQGV4dHJOYXRpdmUoMTA2MikBBQ5zdG9yYWdlQWRkcmVzcwQOc2NyaXB0VHlwZXNTdHIJARFAZXh0ck5hdGl2ZSgxMDU4KQEFDmtfU0NSSVBUX1RZUEVTBBFfY2hlY2tTY3JpcHRUeXBlcwMJAAACCQCzCQIFDnNjcmlwdFR5cGVzU3RyBQpzY3JpcHRUeXBlBQR1bml0CQACAQkArAICAjVpbnZhbGlkIHNjcmlwdCB0eXBlIG9yIGl0IGlzIG5vdCBwcmVzZW50IGluIHN0b3JhZ2U6IAUKc2NyaXB0VHlwZQYDCQAAAgURX2NoZWNrU2NyaXB0VHlwZXMFEV9jaGVja1NjcmlwdFR5cGVzBBBfc2NyaXB0VHlwZUNoZWNrAwkBAiE9AgURc3RvcmFnZVNjcmlwdEhhc2gFC19zY3JpcHRIYXNoCQACAQI0U3RvcmVkIGFuZCBwYXNzZWQgYXMgYXJndW1lbnQgc2NyaXB0SGFzaGVzIG5vdCBtYXRjaAYDCQAAAgUQX3NjcmlwdFR5cGVDaGVjawUQX3NjcmlwdFR5cGVDaGVjawQKX2Rlc2NDaGVjawMJAAACCQCxAgEFBGRlc2MAAAkAAgECGkRlc2NyaXB0aW9uIGNhbid0IGJlIGVtcHR5BgMJAAACBQpfZGVzY0NoZWNrBQpfZGVzY0NoZWNrBA9faW5pdGlhdG9yQ2hlY2sDCQECIT0CCQClCAEJAKcIAQgFAWkPY2FsbGVyUHVibGljS2V5BQxpbml0aWF0b3JBZHIJAAIBAiZJbml0aWF0b3IgYWRkcmVzcyBkb2Vzbid0IG1hdGNoIGNhbGxlcgYDCQAAAgUPX2luaXRpYXRvckNoZWNrBQ9faW5pdGlhdG9yQ2hlY2sECWl0ZXJhdGlvbgkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkArAICCQCsAgIFC2tfSVRFUkFUSU9OBQNTRVAFCnNjcmlwdFR5cGUAAAABBAhzY3JpcHRJZAkArAICCQCsAgIJAKwCAgIIc2NyaXB0JSUFCnNjcmlwdFR5cGUCAiUlBQtfc2NyaXB0SGFzaAkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgUIc2NyaXB0SWQFBkJJR1NFUAUMa19zY3JpcHRUeXBlBQpzY3JpcHRUeXBlCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgkArAICBQhzY3JpcHRJZAUGQklHU0VQBRBrX3N0b3JhZ2VBZGRyZXNzBQ5zdG9yYWdlQWRkcmVzcwkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgUIc2NyaXB0SWQFBkJJR1NFUAUMa19zY3JpcHRIYXNoBRFzdG9yYWdlU2NyaXB0SGFzaAkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgUIc2NyaXB0SWQFBkJJR1NFUAUGa19kZXNjBQRkZXNjCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgUIc2NyaXB0SWQFBkJJR1NFUAUGa19pdGVyBQlpdGVyYXRpb24JAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFCnNjcmlwdFR5cGUFBkJJR1NFUAUGa19pdGVyBQZCSUdTRVAJAKQDAQUJaXRlcmF0aW9uAgZfX2hhc2gFC19zY3JpcHRIYXNoCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgkArAICBQhzY3JpcHRJZAUGQklHU0VQBQtrX2luaXRpYXRvcgUMaW5pdGlhdG9yQWRyCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgULa19JVEVSQVRJT04FA1NFUAUKc2NyaXB0VHlwZQUJaXRlcmF0aW9uBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEMcmVtb3ZlU2NyaXB0AQhzY3JpcHRJZAQJY2FsbGVyUGJrCQDYBAEIBQFpD2NhbGxlclB1YmxpY0tleQMJAQEhAQkBEF9pc1ZhbGlkT3BlcmF0b3IBBQljYWxsZXJQYmsJAAIBAgtOb3QgYWxsb3dlZAQMaW5pdGlhdG9yQWRyCQERQGV4dHJOYXRpdmUoMTA1OCkBCQCsAgIFCHNjcmlwdElkAgtfX2luaXRpYXRvcgMJAQIhPQIFDGluaXRpYXRvckFkcgkApQgBCQCnCAEIBQFpD2NhbGxlclB1YmxpY0tleQkAAgECF09ubHkgY3JlYXRvciBjYW4gcmVtb3ZlBApzY3JpcHRUeXBlCQERQGV4dHJOYXRpdmUoMTA1OCkBCQCsAgIJAKwCAgUIc2NyaXB0SWQFBkJJR1NFUAUMa19zY3JpcHRUeXBlBAtfc2NyaXB0SGFzaAkBEUBleHRyTmF0aXZlKDEwNTgpAQkArAICCQCsAgIFCHNjcmlwdElkBQZCSUdTRVAFDGtfc2NyaXB0SGFzaAQEaXRlcgkBEUBleHRyTmF0aXZlKDEwNTUpAQkArAICCQCsAgIFCHNjcmlwdElkBQZCSUdTRVAFBmtfaXRlcgQOYXBwcm92ZWRIYXNoZXMJAQt2YWx1ZU9yRWxzZQIJAKIIAQkArAICCQCsAgICB3NjcmlwdF8FCnNjcmlwdFR5cGUCCl9fYXBwcm92ZWQCAAQOX2NoZWNrQXBwcm92ZWQDCQECIT0CCQCzCQIFDmFwcHJvdmVkSGFzaGVzBQtfc2NyaXB0SGFzaAUEdW5pdAkAAgECJ0NhbnQgcmVtb3ZlIGFwcHJvdmVkIHNjcmlwdCwgdXNlIHJldm9rZQYDCQAAAgUOX2NoZWNrQXBwcm92ZWQFDl9jaGVja0FwcHJvdmVkCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgkArAICBQhzY3JpcHRJZAUGQklHU0VQBQxrX3NjcmlwdFR5cGUJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgIFCHNjcmlwdElkBQZCSUdTRVAFEGtfc3RvcmFnZUFkZHJlc3MJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgIFCHNjcmlwdElkBQZCSUdTRVAFDGtfc2NyaXB0SGFzaAkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIJAKwCAgUIc2NyaXB0SWQFBkJJR1NFUAUGa19kZXNjCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgkArAICBQhzY3JpcHRJZAUGQklHU0VQBQZrX2l0ZXIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgIJAKwCAgUKc2NyaXB0VHlwZQINX19pdGVyYXRpb25fXwkApAMBBQRpdGVyAgZfX2hhc2gJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgIFCHNjcmlwdElkBQZCSUdTRVAFC2tfaW5pdGlhdG9yCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgkArAICBQhzY3JpcHRJZAUGQklHU0VQBQ9rX2NvbmZpcm1hdGlvbnMFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARVhZGRDb25maXJtYXRpb25TY3JpcHQBCHNjcmlwdElkBAljYWxsZXJQYmsJANgEAQgFAWkPY2FsbGVyUHVibGljS2V5BAVsaW1pdAkBCV9nZXRMaW1pdAADCQEBIQEJAQhfaXNBZG1pbgEFCWNhbGxlclBiawkAAgECF09ubHkgYWRtaW5zIGNhbiBjb25maXJtBAtfc2NyaXB0SGFzaAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJAKwCAgUIc2NyaXB0SWQCDF9fc2NyaXB0SGFzaAIPSXZhbGlkIHNjcmlwdElkAwkAAAIFC19zY3JpcHRIYXNoBQtfc2NyaXB0SGFzaAQKc2NyaXB0VHlwZQkBEUBleHRyTmF0aXZlKDEwNTgpAQkArAICBQhzY3JpcHRJZAIMX19zY3JpcHRUeXBlBBFhcHByb3ZlZEhhc2hlc1N0cgkBC3ZhbHVlT3JFbHNlAgkAoggBCQCsAgIJAKwCAgIHc2NyaXB0XwUKc2NyaXB0VHlwZQIKX19hcHByb3ZlZAIABA5fY2hlY2tBcHByb3ZlZAMJAQIhPQIJALMJAgURYXBwcm92ZWRIYXNoZXNTdHIFC19zY3JpcHRIYXNoBQR1bml0CQACAQIfVGhpcyBzY3JpcHQgaXMgYXBwcm92ZWQgYWxyZWFkeQYDCQAAAgUOX2NoZWNrQXBwcm92ZWQFDl9jaGVja0FwcHJvdmVkBA9nbG9iYWxJdGVyYXRpb24JAQt2YWx1ZU9yRWxzZQIJAJ8IAQkArAICCQCsAgIFC2tfSVRFUkFUSU9OBQNTRVAFCnNjcmlwdFR5cGUAAAQNdGhpc0l0ZXJhdGlvbgkBBXZhbHVlAQkAnwgBCQCsAgIFCHNjcmlwdElkAgtfX2l0ZXJhdGlvbgQQY29uZmlybWF0aW9uc1N0cgkBC3ZhbHVlT3JFbHNlAgkAoggBCQCsAgIFCHNjcmlwdElkAg9fX2NvbmZpcm1hdGlvbnMCAAQNY29uZmlybWF0aW9ucwkAtQkCBRBjb25maXJtYXRpb25zU3RyAgEsAwkBAiE9AgkAzwgCBQ1jb25maXJtYXRpb25zBQljYWxsZXJQYmsFBHVuaXQJAAIBAiFZb3UgYWxyZWFkeSBjb25maXJtZWQgdGhpcyBzY3JpcHQEB25ld0xpc3QDCQECIT0CBRBjb25maXJtYXRpb25zU3RyAgAJAM0IAgUNY29uZmlybWF0aW9ucwUJY2FsbGVyUGJrCQDMCAIFCWNhbGxlclBiawUDbmlsBApuZXdMaXN0U3RyCQC5CQIFB25ld0xpc3QCASwECGFwcHJvdmVkCQBnAgkAkAMBBQduZXdMaXN0BQVsaW1pdAQGcmVzdWx0AwUIYXBwcm92ZWQEDWFwcHJvdmVkQ291bnQJARFfZ2V0QXBwcm92ZWRDb3VudAAEDmFwcHJvdmVkSGFzaGVzCQC8CQIFEWFwcHJvdmVkSGFzaGVzU3RyAgEsBBFhcHByb3ZlZEhhc2hlc05ldwMJAQIhPQIFEWFwcHJvdmVkSGFzaGVzU3RyAgAJAM0IAgUOYXBwcm92ZWRIYXNoZXMFC19zY3JpcHRIYXNoCQDMCAIFC19zY3JpcHRIYXNoBQNuaWwDCQBmAgkAkAMBBRFhcHByb3ZlZEhhc2hlc05ldwUNYXBwcm92ZWRDb3VudAQMaGFzaFRvUmVtb3ZlCQCRAwIFEWFwcHJvdmVkSGFzaGVzTmV3AAAEEHNjcmlwdFRvUmVtb3ZlSWQJAKwCAgkArAICCQCsAgICCHNjcmlwdCUlBQpzY3JpcHRUeXBlAgIlJQULX3NjcmlwdEhhc2gEFmFwcHJvdmVkSGFzaGVzU3RyaXBwZWQJANEIAgURYXBwcm92ZWRIYXNoZXNOZXcAAAkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgIHc2NyaXB0XwUKc2NyaXB0VHlwZQIKX19hcHByb3ZlZAkAugkCBRZhcHByb3ZlZEhhc2hlc1N0cmlwcGVkAgEsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgkArAICBRBzY3JpcHRUb1JlbW92ZUlkBQZCSUdTRVAFD2tfY29uZmlybWF0aW9ucwIABQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgICB3NjcmlwdF8FCnNjcmlwdFR5cGUCCl9fYXBwcm92ZWQJALoJAgURYXBwcm92ZWRIYXNoZXNOZXcCASwFA25pbAUDbmlsCQDOCAIFBnJlc3VsdAkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIFCHNjcmlwdElkAg9fX2NvbmZpcm1hdGlvbnMFCm5ld0xpc3RTdHIFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARhyZXZva2VDb25maXJtYXRpb25TY3JpcHQBCHNjcmlwdElkBAljYWxsZXJQYmsJANgEAQgFAWkPY2FsbGVyUHVibGljS2V5BAVsaW1pdAkBCV9nZXRMaW1pdAADCQEBIQEJAQhfaXNBZG1pbgEFCWNhbGxlclBiawkAAgECFk9ubHkgYWRtaW5zIGNhbiByZXZva2UEC19zY3JpcHRIYXNoCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkArAICBQhzY3JpcHRJZAIMX19zY3JpcHRIYXNoAhBJbnZhbGlkIHNjcmlwdElkAwkAAAIFC19zY3JpcHRIYXNoBQtfc2NyaXB0SGFzaAQKc2NyaXB0VHlwZQkBEUBleHRyTmF0aXZlKDEwNTgpAQkArAICBQhzY3JpcHRJZAIMX19zY3JpcHRUeXBlBBFhcHByb3ZlZEhhc2hlc1N0cgkBC3ZhbHVlT3JFbHNlAgkAoggBCQCsAgIJAKwCAgIHc2NyaXB0XwUKc2NyaXB0VHlwZQIKX19hcHByb3ZlZAIABA5hcHByb3ZlZEhhc2hlcwkAvAkCBRFhcHByb3ZlZEhhc2hlc1N0cgIBLAQQY29uZmlybWF0aW9uc1N0cgkBC3ZhbHVlT3JFbHNlAgkAoggBCQCsAgIFCHNjcmlwdElkAg9fX2NvbmZpcm1hdGlvbnMCAAQNY29uZmlybWF0aW9ucwkAtQkCBRBjb25maXJtYXRpb25zU3RyAgEsBAxjb25maXJtSW5kZXgJAM8IAgUNY29uZmlybWF0aW9ucwUJY2FsbGVyUGJrAwkAAAIFDGNvbmZpcm1JbmRleAUEdW5pdAkAAgECMVlvdSBkaWRuJ3QgY29uZmlybSB0aGlzIHNjcmlwdCwgbm90aGluZyB0byByZXZva2UEEG5ld0NvbmZpcm1hdGlvbnMJANEIAgUNY29uZmlybWF0aW9ucwkBBXZhbHVlAQUMY29uZmlybUluZGV4BBNuZXdDb25maXJtYXRpb25zU3RyCQC5CQIFEG5ld0NvbmZpcm1hdGlvbnMCASwEC3dhc0FwcHJvdmVkCQECIT0CCQDPCAIFDmFwcHJvdmVkSGFzaGVzBQtfc2NyaXB0SGFzaAUEdW5pdAQNc3RpbGxBcHByb3ZlZAkAZwIJAJADAQUQbmV3Q29uZmlybWF0aW9ucwUFbGltaXQEDHN0YXRlQ2hhbmdlcwMDBQt3YXNBcHByb3ZlZAkBASEBBQ1zdGlsbEFwcHJvdmVkBwQPc2NyaXB0SGFzaEluZGV4CQEFdmFsdWUBCQDPCAIFDmFwcHJvdmVkSGFzaGVzBQtfc2NyaXB0SGFzaAQRbmV3QXBwcm92ZWRIYXNoZXMJANEIAgUOYXBwcm92ZWRIYXNoZXMFD3NjcmlwdEhhc2hJbmRleAQUbmV3QXBwcm92ZWRIYXNoZXNTdHIJALkJAgURbmV3QXBwcm92ZWRIYXNoZXMCASwJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgICB3NjcmlwdF8FCnNjcmlwdFR5cGUCCl9fYXBwcm92ZWQFFG5ld0FwcHJvdmVkSGFzaGVzU3RyBQNuaWwFA25pbAkAzggCBQxzdGF0ZUNoYW5nZXMJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICBQhzY3JpcHRJZAIPX19jb25maXJtYXRpb25zBRNuZXdDb25maXJtYXRpb25zU3RyBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEHYWRkVGFzawcEbmFtZQRkYXBwBHR4aWQJZXhlY3V0ZVRzBGRlc2MMaW5pdGlhdG9yQWRyBnR4ZGF0YQQJY2FsbGVyUGJrCQDYBAEIBQFpD2NhbGxlclB1YmxpY0tleQMJAQEhAQkBEF9pc1ZhbGlkT3BlcmF0b3IBBQljYWxsZXJQYmsJAAIBAgtOb3QgYWxsb3dlZAQKX25hbWVDaGVjawMJAAACCQCxAgEFBG5hbWUAAAkAAgECE05hbWUgY2FuJ3QgYmUgZW1wdHkGAwkAAAIFCl9uYW1lQ2hlY2sFCl9uYW1lQ2hlY2sECl9kYXBwQ2hlY2sDCQEBIQEJARBfdmFsaWRhdGVBZGRyZXNzAQUEZGFwcAkAAgECDkluY29ycmVjdCBkYXBwBgMJAAACBQpfZGFwcENoZWNrBQpfZGFwcENoZWNrBApfdHhpZENoZWNrAwkAAAIJALECAQUEdHhpZAAACQACAQITdHhpZCBjYW4ndCBiZSBlbXB0eQYDCQAAAgUKX3R4aWRDaGVjawUKX3R4aWRDaGVjawQPX3RpbWVzdGFtcENoZWNrAwkBASEBCQELX3ZhbGlkYXRlVHMBBQlleGVjdXRlVHMJAAIBAhN0eGlkIGNhbid0IGJlIGVtcHR5BgMJAAACBQ9fdGltZXN0YW1wQ2hlY2sFD190aW1lc3RhbXBDaGVjawQKX2Rlc2NDaGVjawMJAAACCQCxAgEFBGRlc2MAAAkAAgECGkRlc2NyaXB0aW9uIGNhbid0IGJlIGVtcHR5BgMJAAACBQpfZGVzY0NoZWNrBQpfZGVzY0NoZWNrBA9faW5pdGlhdG9yQ2hlY2sDCQECIT0CCQClCAEJAKcIAQgFAWkPY2FsbGVyUHVibGljS2V5BQxpbml0aWF0b3JBZHIJAAIBAiZJbml0aWF0b3IgYWRkcmVzcyBkb2Vzbid0IG1hdGNoIGNhbGxlcgYDCQAAAgUPX2luaXRpYXRvckNoZWNrBQ9faW5pdGlhdG9yQ2hlY2sEDF90eGRhdGFDaGVjawMJAAACCQCxAgEFBnR4ZGF0YQAACQACAQIWVHggZGF0YSBjYW4ndCBiZSBlbXB0eQYDCQAAAgUMX3R4ZGF0YUNoZWNrBQxfdHhkYXRhQ2hlY2sEBnRhc2tJZAkArAICCQCsAgIJAKwCAgIDdHhfBQRkYXBwBQNTRVAFBHR4aWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICBQZ0YXNrSWQCBl9fbmFtZQUEbmFtZQkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIFBnRhc2tJZAIGX19kYXBwBQRkYXBwCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgUGdGFza0lkAgZfX3R4SWQFBHR4aWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICBQZ0YXNrSWQCBl9fZGVzYwUEZGVzYwkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIFBnRhc2tJZAIIX190eGRhdGEFBnR4ZGF0YQkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIFBnRhc2tJZAILX19pbml0aWF0b3IFDGluaXRpYXRvckFkcgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQZ0YXNrSWQCBF9fdHMFCWV4ZWN1dGVUcwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCnJlbW92ZVRhc2sBBnRhc2tJZAQJY2FsbGVyUGJrCQDYBAEIBQFpD2NhbGxlclB1YmxpY0tleQMJAQEhAQkBEF9pc1ZhbGlkT3BlcmF0b3IBBQljYWxsZXJQYmsJAAIBAgtOb3QgYWxsb3dlZAQMaW5pdGlhdG9yQWRyCQERQGV4dHJOYXRpdmUoMTA1OCkBCQCsAgIFBnRhc2tJZAILX19pbml0aWF0b3IDCQECIT0CBQxpbml0aWF0b3JBZHIJAKUIAQkApwgBCAUBaQ9jYWxsZXJQdWJsaWNLZXkJAAIBAhdPbmx5IGNyZWF0b3IgY2FuIHJlbW92ZQkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIFBnRhc2tJZAIGX19uYW1lCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgUGdGFza0lkAgZfX2RhcHAJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICBQZ0YXNrSWQCBl9fdHhJZAkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIFBnRhc2tJZAIGX19kZXNjCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgUGdGFza0lkAghfX3R4ZGF0YQkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIFBnRhc2tJZAILX19pbml0aWF0b3IJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICBQZ0YXNrSWQCBF9fdHMJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICBQZ0YXNrSWQCD19fY29uZmlybWF0aW9ucwkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIFBnRhc2tJZAIKX19hcHByb3ZlZAUDbmlsAWkBD2FkZENvbmZpcm1hdGlvbgEGdGFza0lkBAljYWxsZXJQYmsJANgEAQgFAWkPY2FsbGVyUHVibGljS2V5BAVsaW1pdAkBCV9nZXRMaW1pdAADCQEBIQEJAQhfaXNBZG1pbgEFCWNhbGxlclBiawkAAgECF09ubHkgYWRtaW5zIGNhbiBjb25maXJtBAR0eElkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkArAICBQZ0YXNrSWQCBl9fdHhJZAILSXZhbGlkIHRhc2sDCQAAAgUEdHhJZAUEdHhJZAQEZGFwcAkBEUBleHRyTmF0aXZlKDEwNTgpAQkArAICBQZ0YXNrSWQCBl9fZGFwcAQQY29uZmlybWF0aW9uc1N0cgkBC3ZhbHVlT3JFbHNlAgkAoggBCQCsAgIFBnRhc2tJZAIPX19jb25maXJtYXRpb25zAgAEDWNvbmZpcm1hdGlvbnMJALUJAgUQY29uZmlybWF0aW9uc1N0cgIBLAMJAQIhPQIJAM8IAgUNY29uZmlybWF0aW9ucwUJY2FsbGVyUGJrBQR1bml0CQACAQIfWW91IGFscmVhZHkgY29uZmlybWVkIHRoaXMgdGFzawQHbmV3TGlzdAMJAQIhPQIFEGNvbmZpcm1hdGlvbnNTdHICAAkAzQgCBQ1jb25maXJtYXRpb25zBQljYWxsZXJQYmsJAMwIAgUJY2FsbGVyUGJrBQNuaWwECm5ld0xpc3RTdHIJALkJAgUHbmV3TGlzdAIBLAQIYXBwcm92ZWQJAGcCCQCQAwEFB25ld0xpc3QFBWxpbWl0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgUGdGFza0lkAg9fX2NvbmZpcm1hdGlvbnMFCm5ld0xpc3RTdHIJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAKwCAgkArAICCQCsAgIFBGRhcHAFA1NFUAUEdHhJZAIKX19hcHByb3ZlZAUIYXBwcm92ZWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQhzZXRMaW1pdAEFbGltaXQECWNhbGxlclBiawkA2AQBCAUBaQ9jYWxsZXJQdWJsaWNLZXkDCQEBIQEJAQhfaXNBZG1pbgEFCWNhbGxlclBiawkAAgECHk9ubHkgd2hpdGVsaXN0ZWQgY2FuIHNldCBsaW1pdAQJemVyb0xpbWl0AwkAZgIFBWxpbWl0AAAGCQACAQITTGltaXQgc2hvdWxkIGJlID4gMAMJAAACBQl6ZXJvTGltaXQFCXplcm9MaW1pdAQGYWRtaW5zCQERQGV4dHJOYXRpdmUoMTA1OCkBBQhrX0FETUlOUwMJAGYCBQVsaW1pdAkAsQIBBQZhZG1pbnMJAAIBCQCsAgIJAKwCAgkArAICAjlMaW1pdCBxdW9ydW0gc2hvdWxkIGJlIDw9IHNpemUgb2YgbGlzdCBvZiBhZG1pbnMsIGxpbWl0OiAJAKQDAQUFbGltaXQCECwgY3VycmVudCBzaXplOiAJAKQDAQkAsQIBBQZhZG1pbnMJAMwIAgkBDEludGVnZXJFbnRyeQIFB2tfTElNSVQFBWxpbWl0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEEdGVzdAAEAXgEByRtYXRjaDAJAO0HAQUGaGVpZ2h0AwkAAQIFByRtYXRjaDACCUJsb2NrSW5mbwQFYmxvY2sFByRtYXRjaDAJAAIBCQCkAwEIBQVibG9jawl0aW1lc3RhbXAJAAIBAhBDYW4ndCBmaW5kIGJsb2NrAwkAAAIFAXgFAXgFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQpjbGVhcl90ZXN0AAQHaW5kaWNlcwkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFCQDMCAIABgkAzAgCAAcJAMwIAgAICQDMCAIACQkAzAgCAAoFA25pbAoBDHJlbW92ZUNodW5rcwIFYWNjdW0FaW5kZXgJAM0IAgUFYWNjdW0JAQtEZWxldGVFbnRyeQEJAKwCAgkArAICAgh0ZXN0dGFzawIJX190eGRhdGFfCQCkAwEFBWluZGV4BAdlbnRyaWVzCgACJGwFB2luZGljZXMKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgIIdGVzdHRhc2sCD19fdHhkYXRhX2NodW5rcwUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQxyZW1vdmVDaHVua3MCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoFB2VudHJpZXMALsuB2Q==", "height": 484709, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: H1NA7FKQGfS3BJc5dDg5ZBNhYjxinDoDrWyuXeLacjxv Next: AVA7ohQFGuQZWif8dTvBQeCDuixHRGR83REdxJTfSt6n Diff:
OldNewDifferences
359359 let scriptType = getStringValue(((scriptId + BIGSEP) + k_scriptType))
360360 let _scriptHash = getStringValue(((scriptId + BIGSEP) + k_scriptHash))
361361 let iter = getIntegerValue(((scriptId + BIGSEP) + k_iter))
362- let approvedHashes = valueOrElse(getString((("script_" + scriptType) + "_approved")), "")
362+ let approvedHashes = valueOrElse(getString((("script_" + scriptType) + "__approved")), "")
363363 let _checkApproved = if ((indexOf(approvedHashes, _scriptHash) != unit))
364364 then throw("Cant remove approved script, use revoke")
365365 else true
383383 if ((_scriptHash == _scriptHash))
384384 then {
385385 let scriptType = getStringValue((scriptId + "__scriptType"))
386- let approvedHashesStr = valueOrElse(getString((("script_" + scriptType) + "_approved")), "")
386+ let approvedHashesStr = valueOrElse(getString((("script_" + scriptType) + "__approved")), "")
387387 let _checkApproved = if ((indexOf(approvedHashesStr, _scriptHash) != unit))
388388 then throw("This script is approved already")
389389 else true
440440 if ((_scriptHash == _scriptHash))
441441 then {
442442 let scriptType = getStringValue((scriptId + "__scriptType"))
443- let approvedHashesStr = valueOrElse(getString((("script_" + scriptType) + "_approved")), "")
443+ let approvedHashesStr = valueOrElse(getString((("script_" + scriptType) + "__approved")), "")
444444 let approvedHashes = split_4C(approvedHashesStr, ",")
445445 let confirmationsStr = valueOrElse(getString((scriptId + "__confirmations")), "")
446446 let confirmations = split(confirmationsStr, ",")
459459 let scriptHashIndex = value(indexOf(approvedHashes, _scriptHash))
460460 let newApprovedHashes = removeByIndex(approvedHashes, scriptHashIndex)
461461 let newApprovedHashesStr = makeString(newApprovedHashes, ",")
462-[StringEntry((("script_" + scriptType) + "_approved"), newApprovedHashesStr), DeleteEntry((((scriptType + SEP) + _scriptHash) + "__approved"))]
462+[StringEntry((("script_" + scriptType) + "__approved"), newApprovedHashesStr)]
463463 }
464464 else nil
465465 (stateChanges ++ [StringEntry((scriptId + "__confirmations"), newConfirmationsStr)])
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let VERSION = "1.0.0"
55
66 let SEP = "_"
77
88 let BIGSEP = "__"
99
1010 let k_ADMINS = "ADMINS_PBKS"
1111
1212 let k_MANAGERS = "MANAGERS_PBKS"
1313
1414 let k_LIMIT = "VOTES_QUORUM"
1515
1616 let k_SCRIPT_TYPES = "SCRIPT_TYPES"
1717
1818 let k_ITERATION = "ITERATION"
1919
2020 let k_APPROVED_COUNT = "APPROVED_COUNT"
2121
2222 let k_scriptType = "scriptType"
2323
2424 let k_scriptHash = "scriptHash"
2525
2626 let k_storageAddress = "storageAddress"
2727
2828 let k_desc = "desc"
2929
3030 let k_iter = "iteration"
3131
3232 let k_initiator = "initiator"
3333
3434 let k_confirmations = "confirmations"
3535
3636 func _validatePbk (pbk) = {
3737 let address = addressFromPublicKey(fromBase58String(pbk))
3838 if ((address == address))
3939 then {
4040 let addressStr = toString(address)
4141 if ((addressStr == addressStr))
4242 then true
4343 else throw("Strict value is not equal to itself.")
4444 }
4545 else throw("Strict value is not equal to itself.")
4646 }
4747
4848
4949 func _validateAddress (address) = {
5050 let addr = addressFromStringValue(address)
5151 if ((addr == addr))
5252 then true
5353 else throw("Strict value is not equal to itself.")
5454 }
5555
5656
5757 func _validateTs (ts) = {
5858 let currTs = match blockInfoByHeight(height) {
5959 case block: BlockInfo =>
6060 block.timestamp
6161 case _ =>
6262 throw("Can't find block")
6363 }
6464 (ts > currTs)
6565 }
6666
6767
6868 func _getLimit () = valueOrErrorMessage(getInteger(k_LIMIT), "Quorum limit not defined")
6969
7070
7171 func _getApprovedCount () = valueOrErrorMessage(getInteger(k_APPROVED_COUNT), "Amount of simultaneously approved scripts not defined")
7272
7373
7474 func _isAdmin (pbk) = {
7575 let adminsStr = valueOrElse(getString(k_ADMINS), "")
7676 let admins = split(adminsStr, ",")
7777 (indexOf(admins, pbk) != unit)
7878 }
7979
8080
8181 func _isManager (pbk) = {
8282 let managersStr = valueOrElse(getString(k_MANAGERS), "")
8383 let managers = split(managersStr, ",")
8484 (indexOf(managers, pbk) != unit)
8585 }
8686
8787
8888 func _isValidOperator (pbk) = {
8989 let managersStr = valueOrElse(getString(k_MANAGERS), "")
9090 let managers = split(managersStr, ",")
9191 let isAdmin = _isAdmin(pbk)
9292 let isManager = _isManager(pbk)
9393 if (isAdmin)
9494 then true
9595 else isManager
9696 }
9797
9898
9999 func saveTxData (taskId,data) = {
100100 let indices = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
101101 let dataSize = size(data)
102102 let isNotEmpty = if ((dataSize != 0))
103103 then true
104104 else throw("saveTxData: Empty data passed")
105105 if ((isNotEmpty == isNotEmpty))
106106 then {
107107 let chunkSize = 30000
108108 let chunksCount = if (((dataSize % chunkSize) == 0))
109109 then (dataSize / chunkSize)
110110 else ((dataSize / chunkSize) + 1)
111111 func makeChunks (accum,index) = {
112112 let chunk = take(accum._1, chunkSize)
113113 if ((size(chunk) == 0))
114114 then accum
115115 else {
116116 let nextData = drop(accum._1, chunkSize)
117117 $Tuple2(nextData, (accum._2 :+ StringEntry(((taskId + "__txdata_") + toString(index)), chunk)))
118118 }
119119 }
120120
121121 let entries = {
122122 let $l = indices
123123 let $s = size($l)
124124 let $acc0 = $Tuple2(data, [StringEntry((taskId + "__txdata_chunks"), toString(chunksCount))])
125125 func $f0_1 ($a,$i) = if (($i >= $s))
126126 then $a
127127 else makeChunks($a, $l[$i])
128128
129129 func $f0_2 ($a,$i) = if (($i >= $s))
130130 then $a
131131 else throw("List size exceeds 10")
132132
133133 $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)
134134 }
135135 entries._2
136136 }
137137 else throw("Strict value is not equal to itself.")
138138 }
139139
140140
141141 @Callable(i)
142142 func init (admins_pbks,limit,approvedCount) = if ((i.caller != this))
143143 then throw("Self call only")
144144 else {
145145 let size_admins = if ((size(admins_pbks) != 0))
146146 then true
147147 else throw("At least one admin pbk should be passed")
148148 if ((size_admins == size_admins))
149149 then {
150150 let check_admins = if (!(isDefined(getString(k_ADMINS))))
151151 then true
152152 else throw("Already inited")
153153 if ((check_admins == check_admins))
154154 then {
155155 let zeroLimit = if ((limit > 0))
156156 then true
157157 else throw("Limit should be > 0")
158158 if ((zeroLimit == zeroLimit))
159159 then {
160160 let limit_ok = if ((size(admins_pbks) > limit))
161161 then true
162162 else throw(((("Limit quorum should be <= size of list of admins, limit: " + toString(limit)) + ", current size: ") + toString(size(admins_pbks))))
163163 if ((limit_ok == limit_ok))
164164 then {
165165 func validate (accum,next) = _validatePbk(next)
166166
167167 let validRes = {
168168 let $l = admins_pbks
169169 let $s = size($l)
170170 let $acc0 = ""
171171 func $f0_1 ($a,$i) = if (($i >= $s))
172172 then $a
173173 else validate($a, $l[$i])
174174
175175 func $f0_2 ($a,$i) = if (($i >= $s))
176176 then $a
177177 else throw("List size exceeds 10")
178178
179179 $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)
180180 }
181181 if ((validRes == validRes))
182182 then {
183183 let adminsStr = makeString(admins_pbks, ",")
184184 [StringEntry(k_ADMINS, adminsStr), IntegerEntry(k_LIMIT, limit), IntegerEntry(k_APPROVED_COUNT, approvedCount)]
185185 }
186186 else throw("Strict value is not equal to itself.")
187187 }
188188 else throw("Strict value is not equal to itself.")
189189 }
190190 else throw("Strict value is not equal to itself.")
191191 }
192192 else throw("Strict value is not equal to itself.")
193193 }
194194 else throw("Strict value is not equal to itself.")
195195 }
196196
197197
198198
199199 @Callable(i)
200200 func addAdmin (pbk) = {
201201 let callerPbk = toBase58String(i.callerPublicKey)
202202 let isAdmin = if (_isAdmin(callerPbk))
203203 then true
204204 else throw("Only admins can add admin")
205205 if ((isAdmin == isAdmin))
206206 then {
207207 let isValid = if (_validatePbk(pbk))
208208 then true
209209 else throw("Invalid admin pbk")
210210 if ((isValid == isValid))
211211 then {
212212 let newAdminsStr = ((getStringValue(k_ADMINS) + ",") + pbk)
213213 [StringEntry(k_ADMINS, newAdminsStr)]
214214 }
215215 else throw("Strict value is not equal to itself.")
216216 }
217217 else throw("Strict value is not equal to itself.")
218218 }
219219
220220
221221
222222 @Callable(i)
223223 func removeAdmin (pbk) = {
224224 let callerPbk = toBase58String(i.callerPublicKey)
225225 let isAdmin = if (_isAdmin(callerPbk))
226226 then true
227227 else throw("Only admins can add admin")
228228 if ((isAdmin == isAdmin))
229229 then {
230230 let isValid = if (_validatePbk(pbk))
231231 then true
232232 else throw("Invalid admin pbk")
233233 if ((isValid == isValid))
234234 then {
235235 let oldAdminsStr = getStringValue(k_ADMINS)
236236 let oldAdmins = split(oldAdminsStr, ",")
237237 let checkCount = if ((1 >= size(oldAdmins)))
238238 then throw("Cannot remove, at least one admin should remain")
239239 else true
240240 if ((checkCount == checkCount))
241241 then {
242242 let index = valueOrErrorMessage(indexOf(oldAdmins, pbk), "This pbk is not an admin")
243243 let newAdmins = removeByIndex(oldAdmins, index)
244244 let newAdminsStr = makeString(newAdmins, ",")
245245 [StringEntry(k_ADMINS, newAdminsStr)]
246246 }
247247 else throw("Strict value is not equal to itself.")
248248 }
249249 else throw("Strict value is not equal to itself.")
250250 }
251251 else throw("Strict value is not equal to itself.")
252252 }
253253
254254
255255
256256 @Callable(i)
257257 func addScriptType (scriptType) = {
258258 let callerPbk = toBase58String(i.callerPublicKey)
259259 if (!(_isAdmin(callerPbk)))
260260 then throw("Not allowed")
261261 else {
262262 let checkEmpty = if ((size(scriptType) == 0))
263263 then throw("Script type can not be empty")
264264 else true
265265 if ((checkEmpty == checkEmpty))
266266 then {
267267 let scriptTypesStr = valueOrElse(getString(k_SCRIPT_TYPES), "")
268268 let scriptTypes = split_4C(scriptTypesStr, ",")
269269 let checkExists = if ((indexOf(scriptTypes, scriptType) != unit))
270270 then throw((("Script type <" + scriptType) + "> already added"))
271271 else true
272272 if ((checkExists == checkExists))
273273 then {
274274 let newScriptTypes = if ((scriptTypesStr != ""))
275275 then (scriptTypes :+ scriptType)
276276 else [scriptType]
277277 let newScriptTypesStr = makeString(newScriptTypes, ",")
278278 [StringEntry(k_SCRIPT_TYPES, newScriptTypesStr)]
279279 }
280280 else throw("Strict value is not equal to itself.")
281281 }
282282 else throw("Strict value is not equal to itself.")
283283 }
284284 }
285285
286286
287287
288288 @Callable(i)
289289 func removeScriptType (scriptType) = {
290290 let callerPbk = toBase58String(i.callerPublicKey)
291291 if (!(_isAdmin(callerPbk)))
292292 then throw("Not allowed")
293293 else {
294294 let scriptTypesStr = valueOrElse(getString(k_SCRIPT_TYPES), "")
295295 let scriptTypes = split_4C(scriptTypesStr, ",")
296296 let index = valueOrErrorMessage(indexOf(scriptTypes, scriptType), (("Script type <" + scriptType) + "> is not present"))
297297 let newScriptTypes = removeByIndex(scriptTypes, index)
298298 let newScriptTypesStr = makeString(newScriptTypes, ",")
299299 [StringEntry(k_SCRIPT_TYPES, newScriptTypesStr)]
300300 }
301301 }
302302
303303
304304
305305 @Callable(i)
306306 func addScript (scriptType,storageAddress,_scriptHash,desc,initiatorAdr) = {
307307 let callerPbk = toBase58String(i.callerPublicKey)
308308 if (!(_isValidOperator(callerPbk)))
309309 then throw("Not allowed")
310310 else {
311311 let storageScriptHash = toBase58String(value(scriptHash(addressFromStringValue(storageAddress))))
312312 let scriptTypesStr = getStringValue(k_SCRIPT_TYPES)
313313 let _checkScriptTypes = if ((indexOf(scriptTypesStr, scriptType) == unit))
314314 then throw(("invalid script type or it is not present in storage: " + scriptType))
315315 else true
316316 if ((_checkScriptTypes == _checkScriptTypes))
317317 then {
318318 let _scriptTypeCheck = if ((storageScriptHash != _scriptHash))
319319 then throw("Stored and passed as argument scriptHashes not match")
320320 else true
321321 if ((_scriptTypeCheck == _scriptTypeCheck))
322322 then {
323323 let _descCheck = if ((size(desc) == 0))
324324 then throw("Description can't be empty")
325325 else true
326326 if ((_descCheck == _descCheck))
327327 then {
328328 let _initiatorCheck = if ((toString(addressFromPublicKey(i.callerPublicKey)) != initiatorAdr))
329329 then throw("Initiator address doesn't match caller")
330330 else true
331331 if ((_initiatorCheck == _initiatorCheck))
332332 then {
333333 let iteration = (valueOrElse(getInteger(((k_ITERATION + SEP) + scriptType)), 0) + 1)
334334 let scriptId = ((("script%%" + scriptType) + "%%") + _scriptHash)
335335 [StringEntry(((scriptId + BIGSEP) + k_scriptType), scriptType), StringEntry(((scriptId + BIGSEP) + k_storageAddress), storageAddress), StringEntry(((scriptId + BIGSEP) + k_scriptHash), storageScriptHash), StringEntry(((scriptId + BIGSEP) + k_desc), desc), IntegerEntry(((scriptId + BIGSEP) + k_iter), iteration), StringEntry((((((scriptType + BIGSEP) + k_iter) + BIGSEP) + toString(iteration)) + "__hash"), _scriptHash), StringEntry(((scriptId + BIGSEP) + k_initiator), initiatorAdr), IntegerEntry(((k_ITERATION + SEP) + scriptType), iteration)]
336336 }
337337 else throw("Strict value is not equal to itself.")
338338 }
339339 else throw("Strict value is not equal to itself.")
340340 }
341341 else throw("Strict value is not equal to itself.")
342342 }
343343 else throw("Strict value is not equal to itself.")
344344 }
345345 }
346346
347347
348348
349349 @Callable(i)
350350 func removeScript (scriptId) = {
351351 let callerPbk = toBase58String(i.callerPublicKey)
352352 if (!(_isValidOperator(callerPbk)))
353353 then throw("Not allowed")
354354 else {
355355 let initiatorAdr = getStringValue((scriptId + "__initiator"))
356356 if ((initiatorAdr != toString(addressFromPublicKey(i.callerPublicKey))))
357357 then throw("Only creator can remove")
358358 else {
359359 let scriptType = getStringValue(((scriptId + BIGSEP) + k_scriptType))
360360 let _scriptHash = getStringValue(((scriptId + BIGSEP) + k_scriptHash))
361361 let iter = getIntegerValue(((scriptId + BIGSEP) + k_iter))
362- let approvedHashes = valueOrElse(getString((("script_" + scriptType) + "_approved")), "")
362+ let approvedHashes = valueOrElse(getString((("script_" + scriptType) + "__approved")), "")
363363 let _checkApproved = if ((indexOf(approvedHashes, _scriptHash) != unit))
364364 then throw("Cant remove approved script, use revoke")
365365 else true
366366 if ((_checkApproved == _checkApproved))
367367 then [DeleteEntry(((scriptId + BIGSEP) + k_scriptType)), DeleteEntry(((scriptId + BIGSEP) + k_storageAddress)), DeleteEntry(((scriptId + BIGSEP) + k_scriptHash)), DeleteEntry(((scriptId + BIGSEP) + k_desc)), DeleteEntry(((scriptId + BIGSEP) + k_iter)), DeleteEntry((((scriptType + "__iteration__") + toString(iter)) + "__hash")), DeleteEntry(((scriptId + BIGSEP) + k_initiator)), DeleteEntry(((scriptId + BIGSEP) + k_confirmations))]
368368 else throw("Strict value is not equal to itself.")
369369 }
370370 }
371371 }
372372
373373
374374
375375 @Callable(i)
376376 func addConfirmationScript (scriptId) = {
377377 let callerPbk = toBase58String(i.callerPublicKey)
378378 let limit = _getLimit()
379379 if (!(_isAdmin(callerPbk)))
380380 then throw("Only admins can confirm")
381381 else {
382382 let _scriptHash = valueOrErrorMessage(getString((scriptId + "__scriptHash")), "Ivalid scriptId")
383383 if ((_scriptHash == _scriptHash))
384384 then {
385385 let scriptType = getStringValue((scriptId + "__scriptType"))
386- let approvedHashesStr = valueOrElse(getString((("script_" + scriptType) + "_approved")), "")
386+ let approvedHashesStr = valueOrElse(getString((("script_" + scriptType) + "__approved")), "")
387387 let _checkApproved = if ((indexOf(approvedHashesStr, _scriptHash) != unit))
388388 then throw("This script is approved already")
389389 else true
390390 if ((_checkApproved == _checkApproved))
391391 then {
392392 let globalIteration = valueOrElse(getInteger(((k_ITERATION + SEP) + scriptType)), 0)
393393 let thisIteration = value(getInteger((scriptId + "__iteration")))
394394 let confirmationsStr = valueOrElse(getString((scriptId + "__confirmations")), "")
395395 let confirmations = split(confirmationsStr, ",")
396396 if ((indexOf(confirmations, callerPbk) != unit))
397397 then throw("You already confirmed this script")
398398 else {
399399 let newList = if ((confirmationsStr != ""))
400400 then (confirmations :+ callerPbk)
401401 else [callerPbk]
402402 let newListStr = makeString(newList, ",")
403403 let approved = (size(newList) >= limit)
404404 let result = if (approved)
405405 then {
406406 let approvedCount = _getApprovedCount()
407407 let approvedHashes = split_4C(approvedHashesStr, ",")
408408 let approvedHashesNew = if ((approvedHashesStr != ""))
409409 then (approvedHashes :+ _scriptHash)
410410 else [_scriptHash]
411411 if ((size(approvedHashesNew) > approvedCount))
412412 then {
413413 let hashToRemove = approvedHashesNew[0]
414414 let scriptToRemoveId = ((("script%%" + scriptType) + "%%") + _scriptHash)
415415 let approvedHashesStripped = removeByIndex(approvedHashesNew, 0)
416416 [StringEntry((("script_" + scriptType) + "__approved"), makeString_2C(approvedHashesStripped, ",")), StringEntry(((scriptToRemoveId + BIGSEP) + k_confirmations), "")]
417417 }
418418 else [StringEntry((("script_" + scriptType) + "__approved"), makeString_2C(approvedHashesNew, ","))]
419419 }
420420 else nil
421421 (result ++ [StringEntry((scriptId + "__confirmations"), newListStr)])
422422 }
423423 }
424424 else throw("Strict value is not equal to itself.")
425425 }
426426 else throw("Strict value is not equal to itself.")
427427 }
428428 }
429429
430430
431431
432432 @Callable(i)
433433 func revokeConfirmationScript (scriptId) = {
434434 let callerPbk = toBase58String(i.callerPublicKey)
435435 let limit = _getLimit()
436436 if (!(_isAdmin(callerPbk)))
437437 then throw("Only admins can revoke")
438438 else {
439439 let _scriptHash = valueOrErrorMessage(getString((scriptId + "__scriptHash")), "Invalid scriptId")
440440 if ((_scriptHash == _scriptHash))
441441 then {
442442 let scriptType = getStringValue((scriptId + "__scriptType"))
443- let approvedHashesStr = valueOrElse(getString((("script_" + scriptType) + "_approved")), "")
443+ let approvedHashesStr = valueOrElse(getString((("script_" + scriptType) + "__approved")), "")
444444 let approvedHashes = split_4C(approvedHashesStr, ",")
445445 let confirmationsStr = valueOrElse(getString((scriptId + "__confirmations")), "")
446446 let confirmations = split(confirmationsStr, ",")
447447 let confirmIndex = indexOf(confirmations, callerPbk)
448448 if ((confirmIndex == unit))
449449 then throw("You didn't confirm this script, nothing to revoke")
450450 else {
451451 let newConfirmations = removeByIndex(confirmations, value(confirmIndex))
452452 let newConfirmationsStr = makeString(newConfirmations, ",")
453453 let wasApproved = (indexOf(approvedHashes, _scriptHash) != unit)
454454 let stillApproved = (size(newConfirmations) >= limit)
455455 let stateChanges = if (if (wasApproved)
456456 then !(stillApproved)
457457 else false)
458458 then {
459459 let scriptHashIndex = value(indexOf(approvedHashes, _scriptHash))
460460 let newApprovedHashes = removeByIndex(approvedHashes, scriptHashIndex)
461461 let newApprovedHashesStr = makeString(newApprovedHashes, ",")
462-[StringEntry((("script_" + scriptType) + "_approved"), newApprovedHashesStr), DeleteEntry((((scriptType + SEP) + _scriptHash) + "__approved"))]
462+[StringEntry((("script_" + scriptType) + "__approved"), newApprovedHashesStr)]
463463 }
464464 else nil
465465 (stateChanges ++ [StringEntry((scriptId + "__confirmations"), newConfirmationsStr)])
466466 }
467467 }
468468 else throw("Strict value is not equal to itself.")
469469 }
470470 }
471471
472472
473473
474474 @Callable(i)
475475 func addTask (name,dapp,txid,executeTs,desc,initiatorAdr,txdata) = {
476476 let callerPbk = toBase58String(i.callerPublicKey)
477477 if (!(_isValidOperator(callerPbk)))
478478 then throw("Not allowed")
479479 else {
480480 let _nameCheck = if ((size(name) == 0))
481481 then throw("Name can't be empty")
482482 else true
483483 if ((_nameCheck == _nameCheck))
484484 then {
485485 let _dappCheck = if (!(_validateAddress(dapp)))
486486 then throw("Incorrect dapp")
487487 else true
488488 if ((_dappCheck == _dappCheck))
489489 then {
490490 let _txidCheck = if ((size(txid) == 0))
491491 then throw("txid can't be empty")
492492 else true
493493 if ((_txidCheck == _txidCheck))
494494 then {
495495 let _timestampCheck = if (!(_validateTs(executeTs)))
496496 then throw("txid can't be empty")
497497 else true
498498 if ((_timestampCheck == _timestampCheck))
499499 then {
500500 let _descCheck = if ((size(desc) == 0))
501501 then throw("Description can't be empty")
502502 else true
503503 if ((_descCheck == _descCheck))
504504 then {
505505 let _initiatorCheck = if ((toString(addressFromPublicKey(i.callerPublicKey)) != initiatorAdr))
506506 then throw("Initiator address doesn't match caller")
507507 else true
508508 if ((_initiatorCheck == _initiatorCheck))
509509 then {
510510 let _txdataCheck = if ((size(txdata) == 0))
511511 then throw("Tx data can't be empty")
512512 else true
513513 if ((_txdataCheck == _txdataCheck))
514514 then {
515515 let taskId = ((("tx_" + dapp) + SEP) + txid)
516516 [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)]
517517 }
518518 else throw("Strict value is not equal to itself.")
519519 }
520520 else throw("Strict value is not equal to itself.")
521521 }
522522 else throw("Strict value is not equal to itself.")
523523 }
524524 else throw("Strict value is not equal to itself.")
525525 }
526526 else throw("Strict value is not equal to itself.")
527527 }
528528 else throw("Strict value is not equal to itself.")
529529 }
530530 else throw("Strict value is not equal to itself.")
531531 }
532532 }
533533
534534
535535
536536 @Callable(i)
537537 func removeTask (taskId) = {
538538 let callerPbk = toBase58String(i.callerPublicKey)
539539 if (!(_isValidOperator(callerPbk)))
540540 then throw("Not allowed")
541541 else {
542542 let initiatorAdr = getStringValue((taskId + "__initiator"))
543543 if ((initiatorAdr != toString(addressFromPublicKey(i.callerPublicKey))))
544544 then throw("Only creator can remove")
545545 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"))]
546546 }
547547 }
548548
549549
550550
551551 @Callable(i)
552552 func addConfirmation (taskId) = {
553553 let callerPbk = toBase58String(i.callerPublicKey)
554554 let limit = _getLimit()
555555 if (!(_isAdmin(callerPbk)))
556556 then throw("Only admins can confirm")
557557 else {
558558 let txId = valueOrErrorMessage(getString((taskId + "__txId")), "Ivalid task")
559559 if ((txId == txId))
560560 then {
561561 let dapp = getStringValue((taskId + "__dapp"))
562562 let confirmationsStr = valueOrElse(getString((taskId + "__confirmations")), "")
563563 let confirmations = split(confirmationsStr, ",")
564564 if ((indexOf(confirmations, callerPbk) != unit))
565565 then throw("You already confirmed this task")
566566 else {
567567 let newList = if ((confirmationsStr != ""))
568568 then (confirmations :+ callerPbk)
569569 else [callerPbk]
570570 let newListStr = makeString(newList, ",")
571571 let approved = (size(newList) >= limit)
572572 [StringEntry((taskId + "__confirmations"), newListStr), BooleanEntry((((dapp + SEP) + txId) + "__approved"), approved)]
573573 }
574574 }
575575 else throw("Strict value is not equal to itself.")
576576 }
577577 }
578578
579579
580580
581581 @Callable(i)
582582 func setLimit (limit) = {
583583 let callerPbk = toBase58String(i.callerPublicKey)
584584 if (!(_isAdmin(callerPbk)))
585585 then throw("Only whitelisted can set limit")
586586 else {
587587 let zeroLimit = if ((limit > 0))
588588 then true
589589 else throw("Limit should be > 0")
590590 if ((zeroLimit == zeroLimit))
591591 then {
592592 let admins = getStringValue(k_ADMINS)
593593 if ((limit > size(admins)))
594594 then throw(((("Limit quorum should be <= size of list of admins, limit: " + toString(limit)) + ", current size: ") + toString(size(admins))))
595595 else [IntegerEntry(k_LIMIT, limit)]
596596 }
597597 else throw("Strict value is not equal to itself.")
598598 }
599599 }
600600
601601
602602
603603 @Callable(i)
604604 func test () = {
605605 let x = match blockInfoByHeight(height) {
606606 case block: BlockInfo =>
607607 throw(toString(block.timestamp))
608608 case _ =>
609609 throw("Can't find block")
610610 }
611611 if ((x == x))
612612 then nil
613613 else throw("Strict value is not equal to itself.")
614614 }
615615
616616
617617
618618 @Callable(i)
619619 func clear_test () = {
620620 let indices = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
621621 func removeChunks (accum,index) = (accum :+ DeleteEntry((("testtask" + "__txdata_") + toString(index))))
622622
623623 let entries = {
624624 let $l = indices
625625 let $s = size($l)
626626 let $acc0 = [DeleteEntry(("testtask" + "__txdata_chunks"))]
627627 func $f0_1 ($a,$i) = if (($i >= $s))
628628 then $a
629629 else removeChunks($a, $l[$i])
630630
631631 func $f0_2 ($a,$i) = if (($i >= $s))
632632 then $a
633633 else throw("List size exceeds 10")
634634
635635 $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)
636636 }
637637 entries
638638 }
639639
640640

github/deemru/w8io
60.21 ms