tx · H1NA7FKQGfS3BJc5dDg5ZBNhYjxinDoDrWyuXeLacjxv

3M7uzD8rT54fKQcP4s417if1VKU8yromEP2:  -0.05500000 Waves

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

{ "type": 13, "id": "H1NA7FKQGfS3BJc5dDg5ZBNhYjxinDoDrWyuXeLacjxv", "fee": 5500000, "feeAssetId": null, "timestamp": 1760659439128, "version": 2, "chainId": 82, "sender": "3M7uzD8rT54fKQcP4s417if1VKU8yromEP2", "senderPublicKey": "2eFPamS5zez1159HEFEJaxs2XPq3AupPbNApNGffRjqf", "proofs": [ "59P68rBFW5xg6m2YjVQeDUj7gDHgEBJgcPE8LNTizMckSpWcPRT51eS1fJnUHyKkLFh1iPpthyyXtuh7jTRjwKij" ], "script": "base64:BgJTCAISBQoDGAEBEgMKAQgSAwoBCBIDCgEIEgMKAQgSBwoFCAgICAgSAwoBCBIDCgEIEgMKAQgSCQoHCAgIAQgICBIDCgEIEgMKAQgSAwoBARIAEgAZAAdWRVJTSU9OAgUxLjAuMAADU0VQAgFfAAZCSUdTRVACAl9fAAhrX0FETUlOUwILQURNSU5TX1BCS1MACmtfTUFOQUdFUlMCDU1BTkFHRVJTX1BCS1MAB2tfTElNSVQCDFZPVEVTX1FVT1JVTQAOa19TQ1JJUFRfVFlQRVMCDFNDUklQVF9UWVBFUwALa19JVEVSQVRJT04CCUlURVJBVElPTgAQa19BUFBST1ZFRF9DT1VOVAIOQVBQUk9WRURfQ09VTlQADGtfc2NyaXB0VHlwZQIKc2NyaXB0VHlwZQAMa19zY3JpcHRIYXNoAgpzY3JpcHRIYXNoABBrX3N0b3JhZ2VBZGRyZXNzAg5zdG9yYWdlQWRkcmVzcwAGa19kZXNjAgRkZXNjAAZrX2l0ZXICCWl0ZXJhdGlvbgALa19pbml0aWF0b3ICCWluaXRpYXRvcgAPa19jb25maXJtYXRpb25zAg1jb25maXJtYXRpb25zAQxfdmFsaWRhdGVQYmsBA3BiawQHYWRkcmVzcwkApwgBCQDZBAEFA3BiawMJAAACBQdhZGRyZXNzBQdhZGRyZXNzBAphZGRyZXNzU3RyCQClCAEFB2FkZHJlc3MDCQAAAgUKYWRkcmVzc1N0cgUKYWRkcmVzc1N0cgYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BEF92YWxpZGF0ZUFkZHJlc3MBB2FkZHJlc3MEBGFkZHIJARFAZXh0ck5hdGl2ZSgxMDYyKQEFB2FkZHJlc3MDCQAAAgUEYWRkcgUEYWRkcgYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BC192YWxpZGF0ZVRzAQJ0cwQGY3VyclRzBAckbWF0Y2gwCQDtBwEFBmhlaWdodAMJAAECBQckbWF0Y2gwAglCbG9ja0luZm8EBWJsb2NrBQckbWF0Y2gwCAUFYmxvY2sJdGltZXN0YW1wCQACAQIQQ2FuJ3QgZmluZCBibG9jawkAZgIFAnRzBQZjdXJyVHMBCV9nZXRMaW1pdAAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQdrX0xJTUlUAhhRdW9ydW0gbGltaXQgbm90IGRlZmluZWQBEV9nZXRBcHByb3ZlZENvdW50AAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFEGtfQVBQUk9WRURfQ09VTlQCNUFtb3VudCBvZiBzaW11bHRhbmVvdXNseSBhcHByb3ZlZCBzY3JpcHRzIG5vdCBkZWZpbmVkAQhfaXNBZG1pbgEDcGJrBAlhZG1pbnNTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUIa19BRE1JTlMCAAQGYWRtaW5zCQC1CQIFCWFkbWluc1N0cgIBLAkBAiE9AgkAzwgCBQZhZG1pbnMFA3BiawUEdW5pdAEKX2lzTWFuYWdlcgEDcGJrBAttYW5hZ2Vyc1N0cgkBC3ZhbHVlT3JFbHNlAgkAoggBBQprX01BTkFHRVJTAgAECG1hbmFnZXJzCQC1CQIFC21hbmFnZXJzU3RyAgEsCQECIT0CCQDPCAIFCG1hbmFnZXJzBQNwYmsFBHVuaXQBEF9pc1ZhbGlkT3BlcmF0b3IBA3BiawQLbWFuYWdlcnNTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUKa19NQU5BR0VSUwIABAhtYW5hZ2VycwkAtQkCBQttYW5hZ2Vyc1N0cgIBLAQHaXNBZG1pbgkBCF9pc0FkbWluAQUDcGJrBAlpc01hbmFnZXIJAQpfaXNNYW5hZ2VyAQUDcGJrAwUHaXNBZG1pbgYFCWlzTWFuYWdlcgEKc2F2ZVR4RGF0YQIGdGFza0lkBGRhdGEEB2luZGljZXMJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQkAzAgCAAYJAMwIAgAHCQDMCAIACAkAzAgCAAkJAMwIAgAKBQNuaWwECGRhdGFTaXplCQCxAgEFBGRhdGEECmlzTm90RW1wdHkDCQECIT0CBQhkYXRhU2l6ZQAABgkAAgECHXNhdmVUeERhdGE6IEVtcHR5IGRhdGEgcGFzc2VkAwkAAAIFCmlzTm90RW1wdHkFCmlzTm90RW1wdHkECWNodW5rU2l6ZQCw6gEEC2NodW5rc0NvdW50AwkAAAIJAGoCBQhkYXRhU2l6ZQUJY2h1bmtTaXplAAAJAGkCBQhkYXRhU2l6ZQUJY2h1bmtTaXplCQBkAgkAaQIFCGRhdGFTaXplBQljaHVua1NpemUAAQoBCm1ha2VDaHVua3MCBWFjY3VtBWluZGV4BAVjaHVuawkArwICCAUFYWNjdW0CXzEFCWNodW5rU2l6ZQMJAAACCQCxAgEFBWNodW5rAAAFBWFjY3VtBAhuZXh0RGF0YQkAsAICCAUFYWNjdW0CXzEFCWNodW5rU2l6ZQkAlAoCBQhuZXh0RGF0YQkAzQgCCAUFYWNjdW0CXzIJAQtTdHJpbmdFbnRyeQIJAKwCAgkArAICBQZ0YXNrSWQCCV9fdHhkYXRhXwkApAMBBQVpbmRleAUFY2h1bmsEB2VudHJpZXMKAAIkbAUHaW5kaWNlcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUEZGF0YQkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIFBnRhc2tJZAIPX190eGRhdGFfY2h1bmtzCQCkAwEFC2NodW5rc0NvdW50BQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCm1ha2VDaHVua3MCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoIBQdlbnRyaWVzAl8yCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuDwFpAQRpbml0AwthZG1pbnNfcGJrcwVsaW1pdA1hcHByb3ZlZENvdW50AwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIOU2VsZiBjYWxsIG9ubHkEC3NpemVfYWRtaW5zAwkBAiE9AgkAkAMBBQthZG1pbnNfcGJrcwAABgkAAgECJ0F0IGxlYXN0IG9uZSBhZG1pbiBwYmsgc2hvdWxkIGJlIHBhc3NlZAMJAAACBQtzaXplX2FkbWlucwULc2l6ZV9hZG1pbnMEDGNoZWNrX2FkbWlucwMJAQEhAQkBCWlzRGVmaW5lZAEJAKIIAQUIa19BRE1JTlMGCQACAQIOQWxyZWFkeSBpbml0ZWQDCQAAAgUMY2hlY2tfYWRtaW5zBQxjaGVja19hZG1pbnMECXplcm9MaW1pdAMJAGYCBQVsaW1pdAAABgkAAgECE0xpbWl0IHNob3VsZCBiZSA+IDADCQAAAgUJemVyb0xpbWl0BQl6ZXJvTGltaXQECGxpbWl0X29rAwkAZgIJAJADAQULYWRtaW5zX3Bia3MFBWxpbWl0BgkAAgEJAKwCAgkArAICCQCsAgICOUxpbWl0IHF1b3J1bSBzaG91bGQgYmUgPD0gc2l6ZSBvZiBsaXN0IG9mIGFkbWlucywgbGltaXQ6IAkApAMBBQVsaW1pdAIQLCBjdXJyZW50IHNpemU6IAkApAMBCQCQAwEFC2FkbWluc19wYmtzAwkAAAIFCGxpbWl0X29rBQhsaW1pdF9vawoBCHZhbGlkYXRlAgVhY2N1bQRuZXh0CQEMX3ZhbGlkYXRlUGJrAQUEbmV4dAQIdmFsaWRSZXMKAAIkbAULYWRtaW5zX3Bia3MKAAIkcwkAkAMBBQIkbAoABSRhY2MwAgAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBCHZhbGlkYXRlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAwkAAAIFCHZhbGlkUmVzBQh2YWxpZFJlcwQJYWRtaW5zU3RyCQC5CQIFC2FkbWluc19wYmtzAgEsCQDMCAIJAQtTdHJpbmdFbnRyeQIFCGtfQURNSU5TBQlhZG1pbnNTdHIJAMwIAgkBDEludGVnZXJFbnRyeQIFB2tfTElNSVQFBWxpbWl0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRBrX0FQUFJPVkVEX0NPVU5UBQ1hcHByb3ZlZENvdW50BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEIYWRkQWRtaW4BA3BiawQJY2FsbGVyUGJrCQDYBAEIBQFpD2NhbGxlclB1YmxpY0tleQQHaXNBZG1pbgMJAQhfaXNBZG1pbgEFCWNhbGxlclBiawYJAAIBAhlPbmx5IGFkbWlucyBjYW4gYWRkIGFkbWluAwkAAAIFB2lzQWRtaW4FB2lzQWRtaW4EB2lzVmFsaWQDCQEMX3ZhbGlkYXRlUGJrAQUDcGJrBgkAAgECEUludmFsaWQgYWRtaW4gcGJrAwkAAAIFB2lzVmFsaWQFB2lzVmFsaWQEDG5ld0FkbWluc1N0cgkArAICCQCsAgIJARFAZXh0ck5hdGl2ZSgxMDU4KQEFCGtfQURNSU5TAgEsBQNwYmsJAMwIAgkBC1N0cmluZ0VudHJ5AgUIa19BRE1JTlMFDG5ld0FkbWluc1N0cgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBC3JlbW92ZUFkbWluAQNwYmsECWNhbGxlclBiawkA2AQBCAUBaQ9jYWxsZXJQdWJsaWNLZXkEB2lzQWRtaW4DCQEIX2lzQWRtaW4BBQljYWxsZXJQYmsGCQACAQIZT25seSBhZG1pbnMgY2FuIGFkZCBhZG1pbgMJAAACBQdpc0FkbWluBQdpc0FkbWluBAdpc1ZhbGlkAwkBDF92YWxpZGF0ZVBiawEFA3BiawYJAAIBAhFJbnZhbGlkIGFkbWluIHBiawMJAAACBQdpc1ZhbGlkBQdpc1ZhbGlkBAxvbGRBZG1pbnNTdHIJARFAZXh0ck5hdGl2ZSgxMDU4KQEFCGtfQURNSU5TBAlvbGRBZG1pbnMJALUJAgUMb2xkQWRtaW5zU3RyAgEsBApjaGVja0NvdW50AwkAZwIAAQkAkAMBBQlvbGRBZG1pbnMJAAIBAi9DYW5ub3QgcmVtb3ZlLCBhdCBsZWFzdCBvbmUgYWRtaW4gc2hvdWxkIHJlbWFpbgYDCQAAAgUKY2hlY2tDb3VudAUKY2hlY2tDb3VudAQFaW5kZXgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAzwgCBQlvbGRBZG1pbnMFA3BiawIYVGhpcyBwYmsgaXMgbm90IGFuIGFkbWluBAluZXdBZG1pbnMJANEIAgUJb2xkQWRtaW5zBQVpbmRleAQMbmV3QWRtaW5zU3RyCQC5CQIFCW5ld0FkbWlucwIBLAkAzAgCCQELU3RyaW5nRW50cnkCBQhrX0FETUlOUwUMbmV3QWRtaW5zU3RyBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQENYWRkU2NyaXB0VHlwZQEKc2NyaXB0VHlwZQQJY2FsbGVyUGJrCQDYBAEIBQFpD2NhbGxlclB1YmxpY0tleQMJAQEhAQkBCF9pc0FkbWluAQUJY2FsbGVyUGJrCQACAQILTm90IGFsbG93ZWQECmNoZWNrRW1wdHkDCQAAAgkAsQIBBQpzY3JpcHRUeXBlAAAJAAIBAhxTY3JpcHQgdHlwZSBjYW4gbm90IGJlIGVtcHR5BgMJAAACBQpjaGVja0VtcHR5BQpjaGVja0VtcHR5BA5zY3JpcHRUeXBlc1N0cgkBC3ZhbHVlT3JFbHNlAgkAoggBBQ5rX1NDUklQVF9UWVBFUwIABAtzY3JpcHRUeXBlcwkAvAkCBQ5zY3JpcHRUeXBlc1N0cgIBLAQLY2hlY2tFeGlzdHMDCQECIT0CCQDPCAIFC3NjcmlwdFR5cGVzBQpzY3JpcHRUeXBlBQR1bml0CQACAQkArAICCQCsAgICDVNjcmlwdCB0eXBlIDwFCnNjcmlwdFR5cGUCDz4gYWxyZWFkeSBhZGRlZAYDCQAAAgULY2hlY2tFeGlzdHMFC2NoZWNrRXhpc3RzBA5uZXdTY3JpcHRUeXBlcwMJAQIhPQIFDnNjcmlwdFR5cGVzU3RyAgAJAM0IAgULc2NyaXB0VHlwZXMFCnNjcmlwdFR5cGUJAMwIAgUKc2NyaXB0VHlwZQUDbmlsBBFuZXdTY3JpcHRUeXBlc1N0cgkAuQkCBQ5uZXdTY3JpcHRUeXBlcwIBLAkAzAgCCQELU3RyaW5nRW50cnkCBQ5rX1NDUklQVF9UWVBFUwURbmV3U2NyaXB0VHlwZXNTdHIFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARByZW1vdmVTY3JpcHRUeXBlAQpzY3JpcHRUeXBlBAljYWxsZXJQYmsJANgEAQgFAWkPY2FsbGVyUHVibGljS2V5AwkBASEBCQEIX2lzQWRtaW4BBQljYWxsZXJQYmsJAAIBAgtOb3QgYWxsb3dlZAQOc2NyaXB0VHlwZXNTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUOa19TQ1JJUFRfVFlQRVMCAAQLc2NyaXB0VHlwZXMJALwJAgUOc2NyaXB0VHlwZXNTdHICASwEBWluZGV4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAM8IAgULc2NyaXB0VHlwZXMFCnNjcmlwdFR5cGUJAKwCAgkArAICAg1TY3JpcHQgdHlwZSA8BQpzY3JpcHRUeXBlAhA+IGlzIG5vdCBwcmVzZW50BA5uZXdTY3JpcHRUeXBlcwkA0QgCBQtzY3JpcHRUeXBlcwUFaW5kZXgEEW5ld1NjcmlwdFR5cGVzU3RyCQC5CQIFDm5ld1NjcmlwdFR5cGVzAgEsCQDMCAIJAQtTdHJpbmdFbnRyeQIFDmtfU0NSSVBUX1RZUEVTBRFuZXdTY3JpcHRUeXBlc1N0cgUDbmlsAWkBCWFkZFNjcmlwdAUKc2NyaXB0VHlwZQ5zdG9yYWdlQWRkcmVzcwtfc2NyaXB0SGFzaARkZXNjDGluaXRpYXRvckFkcgQJY2FsbGVyUGJrCQDYBAEIBQFpD2NhbGxlclB1YmxpY0tleQMJAQEhAQkBEF9pc1ZhbGlkT3BlcmF0b3IBBQljYWxsZXJQYmsJAAIBAgtOb3QgYWxsb3dlZAQRc3RvcmFnZVNjcmlwdEhhc2gJANgEAQkBBXZhbHVlAQkA8QcBCQERQGV4dHJOYXRpdmUoMTA2MikBBQ5zdG9yYWdlQWRkcmVzcwQOc2NyaXB0VHlwZXNTdHIJARFAZXh0ck5hdGl2ZSgxMDU4KQEFDmtfU0NSSVBUX1RZUEVTBBFfY2hlY2tTY3JpcHRUeXBlcwMJAAACCQCzCQIFDnNjcmlwdFR5cGVzU3RyBQpzY3JpcHRUeXBlBQR1bml0CQACAQkArAICAjVpbnZhbGlkIHNjcmlwdCB0eXBlIG9yIGl0IGlzIG5vdCBwcmVzZW50IGluIHN0b3JhZ2U6IAUKc2NyaXB0VHlwZQYDCQAAAgURX2NoZWNrU2NyaXB0VHlwZXMFEV9jaGVja1NjcmlwdFR5cGVzBBBfc2NyaXB0VHlwZUNoZWNrAwkBAiE9AgURc3RvcmFnZVNjcmlwdEhhc2gFC19zY3JpcHRIYXNoCQACAQI0U3RvcmVkIGFuZCBwYXNzZWQgYXMgYXJndW1lbnQgc2NyaXB0SGFzaGVzIG5vdCBtYXRjaAYDCQAAAgUQX3NjcmlwdFR5cGVDaGVjawUQX3NjcmlwdFR5cGVDaGVjawQKX2Rlc2NDaGVjawMJAAACCQCxAgEFBGRlc2MAAAkAAgECGkRlc2NyaXB0aW9uIGNhbid0IGJlIGVtcHR5BgMJAAACBQpfZGVzY0NoZWNrBQpfZGVzY0NoZWNrBA9faW5pdGlhdG9yQ2hlY2sDCQECIT0CCQClCAEJAKcIAQgFAWkPY2FsbGVyUHVibGljS2V5BQxpbml0aWF0b3JBZHIJAAIBAiZJbml0aWF0b3IgYWRkcmVzcyBkb2Vzbid0IG1hdGNoIGNhbGxlcgYDCQAAAgUPX2luaXRpYXRvckNoZWNrBQ9faW5pdGlhdG9yQ2hlY2sECWl0ZXJhdGlvbgkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkArAICCQCsAgIFC2tfSVRFUkFUSU9OBQNTRVAFCnNjcmlwdFR5cGUAAAABBAhzY3JpcHRJZAkArAICCQCsAgIJAKwCAgIIc2NyaXB0JSUFCnNjcmlwdFR5cGUCAiUlBQtfc2NyaXB0SGFzaAkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgUIc2NyaXB0SWQFBkJJR1NFUAUMa19zY3JpcHRUeXBlBQpzY3JpcHRUeXBlCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgkArAICBQhzY3JpcHRJZAUGQklHU0VQBRBrX3N0b3JhZ2VBZGRyZXNzBQ5zdG9yYWdlQWRkcmVzcwkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgUIc2NyaXB0SWQFBkJJR1NFUAUMa19zY3JpcHRIYXNoBRFzdG9yYWdlU2NyaXB0SGFzaAkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgUIc2NyaXB0SWQFBkJJR1NFUAUGa19kZXNjBQRkZXNjCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgUIc2NyaXB0SWQFBkJJR1NFUAUGa19pdGVyBQlpdGVyYXRpb24JAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFCnNjcmlwdFR5cGUFBkJJR1NFUAUGa19pdGVyBQZCSUdTRVAJAKQDAQUJaXRlcmF0aW9uAgZfX2hhc2gFC19zY3JpcHRIYXNoCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgkArAICBQhzY3JpcHRJZAUGQklHU0VQBQtrX2luaXRpYXRvcgUMaW5pdGlhdG9yQWRyCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgULa19JVEVSQVRJT04FA1NFUAUKc2NyaXB0VHlwZQUJaXRlcmF0aW9uBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEMcmVtb3ZlU2NyaXB0AQhzY3JpcHRJZAQJY2FsbGVyUGJrCQDYBAEIBQFpD2NhbGxlclB1YmxpY0tleQMJAQEhAQkBEF9pc1ZhbGlkT3BlcmF0b3IBBQljYWxsZXJQYmsJAAIBAgtOb3QgYWxsb3dlZAQMaW5pdGlhdG9yQWRyCQERQGV4dHJOYXRpdmUoMTA1OCkBCQCsAgIFCHNjcmlwdElkAgtfX2luaXRpYXRvcgMJAQIhPQIFDGluaXRpYXRvckFkcgkApQgBCQCnCAEIBQFpD2NhbGxlclB1YmxpY0tleQkAAgECF09ubHkgY3JlYXRvciBjYW4gcmVtb3ZlBApzY3JpcHRUeXBlCQERQGV4dHJOYXRpdmUoMTA1OCkBCQCsAgIJAKwCAgUIc2NyaXB0SWQFBkJJR1NFUAUMa19zY3JpcHRUeXBlBAtfc2NyaXB0SGFzaAkBEUBleHRyTmF0aXZlKDEwNTgpAQkArAICCQCsAgIFCHNjcmlwdElkBQZCSUdTRVAFDGtfc2NyaXB0SGFzaAQEaXRlcgkBEUBleHRyTmF0aXZlKDEwNTUpAQkArAICCQCsAgIFCHNjcmlwdElkBQZCSUdTRVAFBmtfaXRlcgQOYXBwcm92ZWRIYXNoZXMJAQt2YWx1ZU9yRWxzZQIJAKIIAQkArAICCQCsAgICB3NjcmlwdF8FCnNjcmlwdFR5cGUCCV9hcHByb3ZlZAIABA5fY2hlY2tBcHByb3ZlZAMJAQIhPQIJALMJAgUOYXBwcm92ZWRIYXNoZXMFC19zY3JpcHRIYXNoBQR1bml0CQACAQInQ2FudCByZW1vdmUgYXBwcm92ZWQgc2NyaXB0LCB1c2UgcmV2b2tlBgMJAAACBQ5fY2hlY2tBcHByb3ZlZAUOX2NoZWNrQXBwcm92ZWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgIFCHNjcmlwdElkBQZCSUdTRVAFDGtfc2NyaXB0VHlwZQkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIJAKwCAgUIc2NyaXB0SWQFBkJJR1NFUAUQa19zdG9yYWdlQWRkcmVzcwkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIJAKwCAgUIc2NyaXB0SWQFBkJJR1NFUAUMa19zY3JpcHRIYXNoCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgkArAICBQhzY3JpcHRJZAUGQklHU0VQBQZrX2Rlc2MJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgIFCHNjcmlwdElkBQZCSUdTRVAFBmtfaXRlcgkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIJAKwCAgkArAICBQpzY3JpcHRUeXBlAg1fX2l0ZXJhdGlvbl9fCQCkAwEFBGl0ZXICBl9faGFzaAkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIJAKwCAgUIc2NyaXB0SWQFBkJJR1NFUAULa19pbml0aWF0b3IJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgIFCHNjcmlwdElkBQZCSUdTRVAFD2tfY29uZmlybWF0aW9ucwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBFWFkZENvbmZpcm1hdGlvblNjcmlwdAEIc2NyaXB0SWQECWNhbGxlclBiawkA2AQBCAUBaQ9jYWxsZXJQdWJsaWNLZXkEBWxpbWl0CQEJX2dldExpbWl0AAMJAQEhAQkBCF9pc0FkbWluAQUJY2FsbGVyUGJrCQACAQIXT25seSBhZG1pbnMgY2FuIGNvbmZpcm0EC19zY3JpcHRIYXNoCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkArAICBQhzY3JpcHRJZAIMX19zY3JpcHRIYXNoAg9JdmFsaWQgc2NyaXB0SWQDCQAAAgULX3NjcmlwdEhhc2gFC19zY3JpcHRIYXNoBApzY3JpcHRUeXBlCQERQGV4dHJOYXRpdmUoMTA1OCkBCQCsAgIFCHNjcmlwdElkAgxfX3NjcmlwdFR5cGUEEWFwcHJvdmVkSGFzaGVzU3RyCQELdmFsdWVPckVsc2UCCQCiCAEJAKwCAgkArAICAgdzY3JpcHRfBQpzY3JpcHRUeXBlAglfYXBwcm92ZWQCAAQOX2NoZWNrQXBwcm92ZWQDCQECIT0CCQCzCQIFEWFwcHJvdmVkSGFzaGVzU3RyBQtfc2NyaXB0SGFzaAUEdW5pdAkAAgECH1RoaXMgc2NyaXB0IGlzIGFwcHJvdmVkIGFscmVhZHkGAwkAAAIFDl9jaGVja0FwcHJvdmVkBQ5fY2hlY2tBcHByb3ZlZAQPZ2xvYmFsSXRlcmF0aW9uCQELdmFsdWVPckVsc2UCCQCfCAEJAKwCAgkArAICBQtrX0lURVJBVElPTgUDU0VQBQpzY3JpcHRUeXBlAAAEDXRoaXNJdGVyYXRpb24JAQV2YWx1ZQEJAJ8IAQkArAICBQhzY3JpcHRJZAILX19pdGVyYXRpb24EEGNvbmZpcm1hdGlvbnNTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQkArAICBQhzY3JpcHRJZAIPX19jb25maXJtYXRpb25zAgAEDWNvbmZpcm1hdGlvbnMJALUJAgUQY29uZmlybWF0aW9uc1N0cgIBLAMJAQIhPQIJAM8IAgUNY29uZmlybWF0aW9ucwUJY2FsbGVyUGJrBQR1bml0CQACAQIhWW91IGFscmVhZHkgY29uZmlybWVkIHRoaXMgc2NyaXB0BAduZXdMaXN0AwkBAiE9AgUQY29uZmlybWF0aW9uc1N0cgIACQDNCAIFDWNvbmZpcm1hdGlvbnMFCWNhbGxlclBiawkAzAgCBQljYWxsZXJQYmsFA25pbAQKbmV3TGlzdFN0cgkAuQkCBQduZXdMaXN0AgEsBAhhcHByb3ZlZAkAZwIJAJADAQUHbmV3TGlzdAUFbGltaXQEBnJlc3VsdAMFCGFwcHJvdmVkBA1hcHByb3ZlZENvdW50CQERX2dldEFwcHJvdmVkQ291bnQABA5hcHByb3ZlZEhhc2hlcwkAvAkCBRFhcHByb3ZlZEhhc2hlc1N0cgIBLAQRYXBwcm92ZWRIYXNoZXNOZXcDCQECIT0CBRFhcHByb3ZlZEhhc2hlc1N0cgIACQDNCAIFDmFwcHJvdmVkSGFzaGVzBQtfc2NyaXB0SGFzaAkAzAgCBQtfc2NyaXB0SGFzaAUDbmlsAwkAZgIJAJADAQURYXBwcm92ZWRIYXNoZXNOZXcFDWFwcHJvdmVkQ291bnQEDGhhc2hUb1JlbW92ZQkAkQMCBRFhcHByb3ZlZEhhc2hlc05ldwAABBBzY3JpcHRUb1JlbW92ZUlkCQCsAgIJAKwCAgkArAICAghzY3JpcHQlJQUKc2NyaXB0VHlwZQICJSUFC19zY3JpcHRIYXNoBBZhcHByb3ZlZEhhc2hlc1N0cmlwcGVkCQDRCAIFEWFwcHJvdmVkSGFzaGVzTmV3AAAJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgICB3NjcmlwdF8FCnNjcmlwdFR5cGUCCl9fYXBwcm92ZWQJALoJAgUWYXBwcm92ZWRIYXNoZXNTdHJpcHBlZAIBLAkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgUQc2NyaXB0VG9SZW1vdmVJZAUGQklHU0VQBQ9rX2NvbmZpcm1hdGlvbnMCAAUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgkArAICAgdzY3JpcHRfBQpzY3JpcHRUeXBlAgpfX2FwcHJvdmVkCQC6CQIFEWFwcHJvdmVkSGFzaGVzTmV3AgEsBQNuaWwFA25pbAkAzggCBQZyZXN1bHQJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICBQhzY3JpcHRJZAIPX19jb25maXJtYXRpb25zBQpuZXdMaXN0U3RyBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEYcmV2b2tlQ29uZmlybWF0aW9uU2NyaXB0AQhzY3JpcHRJZAQJY2FsbGVyUGJrCQDYBAEIBQFpD2NhbGxlclB1YmxpY0tleQQFbGltaXQJAQlfZ2V0TGltaXQAAwkBASEBCQEIX2lzQWRtaW4BBQljYWxsZXJQYmsJAAIBAhZPbmx5IGFkbWlucyBjYW4gcmV2b2tlBAtfc2NyaXB0SGFzaAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJAKwCAgUIc2NyaXB0SWQCDF9fc2NyaXB0SGFzaAIQSW52YWxpZCBzY3JpcHRJZAMJAAACBQtfc2NyaXB0SGFzaAULX3NjcmlwdEhhc2gECnNjcmlwdFR5cGUJARFAZXh0ck5hdGl2ZSgxMDU4KQEJAKwCAgUIc2NyaXB0SWQCDF9fc2NyaXB0VHlwZQQRYXBwcm92ZWRIYXNoZXNTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQkArAICCQCsAgICB3NjcmlwdF8FCnNjcmlwdFR5cGUCCV9hcHByb3ZlZAIABA5hcHByb3ZlZEhhc2hlcwkAvAkCBRFhcHByb3ZlZEhhc2hlc1N0cgIBLAQQY29uZmlybWF0aW9uc1N0cgkBC3ZhbHVlT3JFbHNlAgkAoggBCQCsAgIFCHNjcmlwdElkAg9fX2NvbmZpcm1hdGlvbnMCAAQNY29uZmlybWF0aW9ucwkAtQkCBRBjb25maXJtYXRpb25zU3RyAgEsBAxjb25maXJtSW5kZXgJAM8IAgUNY29uZmlybWF0aW9ucwUJY2FsbGVyUGJrAwkAAAIFDGNvbmZpcm1JbmRleAUEdW5pdAkAAgECMVlvdSBkaWRuJ3QgY29uZmlybSB0aGlzIHNjcmlwdCwgbm90aGluZyB0byByZXZva2UEEG5ld0NvbmZpcm1hdGlvbnMJANEIAgUNY29uZmlybWF0aW9ucwkBBXZhbHVlAQUMY29uZmlybUluZGV4BBNuZXdDb25maXJtYXRpb25zU3RyCQC5CQIFEG5ld0NvbmZpcm1hdGlvbnMCASwEC3dhc0FwcHJvdmVkCQECIT0CCQDPCAIFDmFwcHJvdmVkSGFzaGVzBQtfc2NyaXB0SGFzaAUEdW5pdAQNc3RpbGxBcHByb3ZlZAkAZwIJAJADAQUQbmV3Q29uZmlybWF0aW9ucwUFbGltaXQEDHN0YXRlQ2hhbmdlcwMDBQt3YXNBcHByb3ZlZAkBASEBBQ1zdGlsbEFwcHJvdmVkBwQPc2NyaXB0SGFzaEluZGV4CQEFdmFsdWUBCQDPCAIFDmFwcHJvdmVkSGFzaGVzBQtfc2NyaXB0SGFzaAQRbmV3QXBwcm92ZWRIYXNoZXMJANEIAgUOYXBwcm92ZWRIYXNoZXMFD3NjcmlwdEhhc2hJbmRleAQUbmV3QXBwcm92ZWRIYXNoZXNTdHIJALkJAgURbmV3QXBwcm92ZWRIYXNoZXMCASwJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgICB3NjcmlwdF8FCnNjcmlwdFR5cGUCCV9hcHByb3ZlZAUUbmV3QXBwcm92ZWRIYXNoZXNTdHIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgIJAKwCAgUKc2NyaXB0VHlwZQUDU0VQBQtfc2NyaXB0SGFzaAIKX19hcHByb3ZlZAUDbmlsBQNuaWwJAM4IAgUMc3RhdGVDaGFuZ2VzCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgUIc2NyaXB0SWQCD19fY29uZmlybWF0aW9ucwUTbmV3Q29uZmlybWF0aW9uc1N0cgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBB2FkZFRhc2sHBG5hbWUEZGFwcAR0eGlkCWV4ZWN1dGVUcwRkZXNjDGluaXRpYXRvckFkcgZ0eGRhdGEECWNhbGxlclBiawkA2AQBCAUBaQ9jYWxsZXJQdWJsaWNLZXkDCQEBIQEJARBfaXNWYWxpZE9wZXJhdG9yAQUJY2FsbGVyUGJrCQACAQILTm90IGFsbG93ZWQECl9uYW1lQ2hlY2sDCQAAAgkAsQIBBQRuYW1lAAAJAAIBAhNOYW1lIGNhbid0IGJlIGVtcHR5BgMJAAACBQpfbmFtZUNoZWNrBQpfbmFtZUNoZWNrBApfZGFwcENoZWNrAwkBASEBCQEQX3ZhbGlkYXRlQWRkcmVzcwEFBGRhcHAJAAIBAg5JbmNvcnJlY3QgZGFwcAYDCQAAAgUKX2RhcHBDaGVjawUKX2RhcHBDaGVjawQKX3R4aWRDaGVjawMJAAACCQCxAgEFBHR4aWQAAAkAAgECE3R4aWQgY2FuJ3QgYmUgZW1wdHkGAwkAAAIFCl90eGlkQ2hlY2sFCl90eGlkQ2hlY2sED190aW1lc3RhbXBDaGVjawMJAQEhAQkBC192YWxpZGF0ZVRzAQUJZXhlY3V0ZVRzCQACAQITdHhpZCBjYW4ndCBiZSBlbXB0eQYDCQAAAgUPX3RpbWVzdGFtcENoZWNrBQ9fdGltZXN0YW1wQ2hlY2sECl9kZXNjQ2hlY2sDCQAAAgkAsQIBBQRkZXNjAAAJAAIBAhpEZXNjcmlwdGlvbiBjYW4ndCBiZSBlbXB0eQYDCQAAAgUKX2Rlc2NDaGVjawUKX2Rlc2NDaGVjawQPX2luaXRpYXRvckNoZWNrAwkBAiE9AgkApQgBCQCnCAEIBQFpD2NhbGxlclB1YmxpY0tleQUMaW5pdGlhdG9yQWRyCQACAQImSW5pdGlhdG9yIGFkZHJlc3MgZG9lc24ndCBtYXRjaCBjYWxsZXIGAwkAAAIFD19pbml0aWF0b3JDaGVjawUPX2luaXRpYXRvckNoZWNrBAxfdHhkYXRhQ2hlY2sDCQAAAgkAsQIBBQZ0eGRhdGEAAAkAAgECFlR4IGRhdGEgY2FuJ3QgYmUgZW1wdHkGAwkAAAIFDF90eGRhdGFDaGVjawUMX3R4ZGF0YUNoZWNrBAZ0YXNrSWQJAKwCAgkArAICCQCsAgICA3R4XwUEZGFwcAUDU0VQBQR0eGlkCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgUGdGFza0lkAgZfX25hbWUFBG5hbWUJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICBQZ0YXNrSWQCBl9fZGFwcAUEZGFwcAkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIFBnRhc2tJZAIGX190eElkBQR0eGlkCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgUGdGFza0lkAgZfX2Rlc2MFBGRlc2MJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICBQZ0YXNrSWQCCF9fdHhkYXRhBQZ0eGRhdGEJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICBQZ0YXNrSWQCC19faW5pdGlhdG9yBQxpbml0aWF0b3JBZHIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUGdGFza0lkAgRfX3RzBQlleGVjdXRlVHMFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQpyZW1vdmVUYXNrAQZ0YXNrSWQECWNhbGxlclBiawkA2AQBCAUBaQ9jYWxsZXJQdWJsaWNLZXkDCQEBIQEJARBfaXNWYWxpZE9wZXJhdG9yAQUJY2FsbGVyUGJrCQACAQILTm90IGFsbG93ZWQEDGluaXRpYXRvckFkcgkBEUBleHRyTmF0aXZlKDEwNTgpAQkArAICBQZ0YXNrSWQCC19faW5pdGlhdG9yAwkBAiE9AgUMaW5pdGlhdG9yQWRyCQClCAEJAKcIAQgFAWkPY2FsbGVyUHVibGljS2V5CQACAQIXT25seSBjcmVhdG9yIGNhbiByZW1vdmUJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICBQZ0YXNrSWQCBl9fbmFtZQkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIFBnRhc2tJZAIGX19kYXBwCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgUGdGFza0lkAgZfX3R4SWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICBQZ0YXNrSWQCBl9fZGVzYwkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIFBnRhc2tJZAIIX190eGRhdGEJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICBQZ0YXNrSWQCC19faW5pdGlhdG9yCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgUGdGFza0lkAgRfX3RzCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgUGdGFza0lkAg9fX2NvbmZpcm1hdGlvbnMJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICBQZ0YXNrSWQCCl9fYXBwcm92ZWQFA25pbAFpAQ9hZGRDb25maXJtYXRpb24BBnRhc2tJZAQJY2FsbGVyUGJrCQDYBAEIBQFpD2NhbGxlclB1YmxpY0tleQQFbGltaXQJAQlfZ2V0TGltaXQAAwkBASEBCQEIX2lzQWRtaW4BBQljYWxsZXJQYmsJAAIBAhdPbmx5IGFkbWlucyBjYW4gY29uZmlybQQEdHhJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJAKwCAgUGdGFza0lkAgZfX3R4SWQCC0l2YWxpZCB0YXNrAwkAAAIFBHR4SWQFBHR4SWQEBGRhcHAJARFAZXh0ck5hdGl2ZSgxMDU4KQEJAKwCAgUGdGFza0lkAgZfX2RhcHAEEGNvbmZpcm1hdGlvbnNTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQkArAICBQZ0YXNrSWQCD19fY29uZmlybWF0aW9ucwIABA1jb25maXJtYXRpb25zCQC1CQIFEGNvbmZpcm1hdGlvbnNTdHICASwDCQECIT0CCQDPCAIFDWNvbmZpcm1hdGlvbnMFCWNhbGxlclBiawUEdW5pdAkAAgECH1lvdSBhbHJlYWR5IGNvbmZpcm1lZCB0aGlzIHRhc2sEB25ld0xpc3QDCQECIT0CBRBjb25maXJtYXRpb25zU3RyAgAJAM0IAgUNY29uZmlybWF0aW9ucwUJY2FsbGVyUGJrCQDMCAIFCWNhbGxlclBiawUDbmlsBApuZXdMaXN0U3RyCQC5CQIFB25ld0xpc3QCASwECGFwcHJvdmVkCQBnAgkAkAMBBQduZXdMaXN0BQVsaW1pdAkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIFBnRhc2tJZAIPX19jb25maXJtYXRpb25zBQpuZXdMaXN0U3RyCQDMCAIJAQxCb29sZWFuRW50cnkCCQCsAgIJAKwCAgkArAICBQRkYXBwBQNTRVAFBHR4SWQCCl9fYXBwcm92ZWQFCGFwcHJvdmVkBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEIc2V0TGltaXQBBWxpbWl0BAljYWxsZXJQYmsJANgEAQgFAWkPY2FsbGVyUHVibGljS2V5AwkBASEBCQEIX2lzQWRtaW4BBQljYWxsZXJQYmsJAAIBAh5Pbmx5IHdoaXRlbGlzdGVkIGNhbiBzZXQgbGltaXQECXplcm9MaW1pdAMJAGYCBQVsaW1pdAAABgkAAgECE0xpbWl0IHNob3VsZCBiZSA+IDADCQAAAgUJemVyb0xpbWl0BQl6ZXJvTGltaXQEBmFkbWlucwkBEUBleHRyTmF0aXZlKDEwNTgpAQUIa19BRE1JTlMDCQBmAgUFbGltaXQJALECAQUGYWRtaW5zCQACAQkArAICCQCsAgIJAKwCAgI5TGltaXQgcXVvcnVtIHNob3VsZCBiZSA8PSBzaXplIG9mIGxpc3Qgb2YgYWRtaW5zLCBsaW1pdDogCQCkAwEFBWxpbWl0AhAsIGN1cnJlbnQgc2l6ZTogCQCkAwEJALECAQUGYWRtaW5zCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQdrX0xJTUlUBQVsaW1pdAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBHRlc3QABAF4BAckbWF0Y2gwCQDtBwEFBmhlaWdodAMJAAECBQckbWF0Y2gwAglCbG9ja0luZm8EBWJsb2NrBQckbWF0Y2gwCQACAQkApAMBCAUFYmxvY2sJdGltZXN0YW1wCQACAQIQQ2FuJ3QgZmluZCBibG9jawMJAAACBQF4BQF4BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEKY2xlYXJfdGVzdAAEB2luZGljZXMJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQkAzAgCAAYJAMwIAgAHCQDMCAIACAkAzAgCAAkJAMwIAgAKBQNuaWwKAQxyZW1vdmVDaHVua3MCBWFjY3VtBWluZGV4CQDNCAIFBWFjY3VtCQELRGVsZXRlRW50cnkBCQCsAgIJAKwCAgIIdGVzdHRhc2sCCV9fdHhkYXRhXwkApAMBBQVpbmRleAQHZW50cmllcwoAAiRsBQdpbmRpY2VzCgACJHMJAJADAQUCJGwKAAUkYWNjMAkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgICCHRlc3R0YXNrAg9fX3R4ZGF0YV9jaHVua3MFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEMcmVtb3ZlQ2h1bmtzAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKBQdlbnRyaWVzAM+UxR8=", "height": 484699, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: Fkw4KF8c6GTRdcWHNRxzi8tJV18To7cHuUuj7DEq8iwb Next: AwBdwbz8KPPNz3mDWC6WHGeG6X7mWQcYwek7FKa7dfuB Diff:
OldNewDifferences
405405 then {
406406 let approvedCount = _getApprovedCount()
407407 let approvedHashes = split_4C(approvedHashesStr, ",")
408- let approvedHashesNew = (approvedHashes :+ _scriptHash)
408+ let approvedHashesNew = if ((approvedHashesStr != ""))
409+ then (approvedHashes :+ _scriptHash)
410+ else [_scriptHash]
409411 if ((size(approvedHashesNew) > approvedCount))
410412 then {
411413 let hashToRemove = approvedHashesNew[0]
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))
362362 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"))
386386 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, ",")
408- let approvedHashesNew = (approvedHashes :+ _scriptHash)
408+ let approvedHashesNew = if ((approvedHashesStr != ""))
409+ then (approvedHashes :+ _scriptHash)
410+ else [_scriptHash]
409411 if ((size(approvedHashesNew) > approvedCount))
410412 then {
411413 let hashToRemove = approvedHashesNew[0]
412414 let scriptToRemoveId = ((("script%%" + scriptType) + "%%") + _scriptHash)
413415 let approvedHashesStripped = removeByIndex(approvedHashesNew, 0)
414416 [StringEntry((("script_" + scriptType) + "__approved"), makeString_2C(approvedHashesStripped, ",")), StringEntry(((scriptToRemoveId + BIGSEP) + k_confirmations), "")]
415417 }
416418 else [StringEntry((("script_" + scriptType) + "__approved"), makeString_2C(approvedHashesNew, ","))]
417419 }
418420 else nil
419421 (result ++ [StringEntry((scriptId + "__confirmations"), newListStr)])
420422 }
421423 }
422424 else throw("Strict value is not equal to itself.")
423425 }
424426 else throw("Strict value is not equal to itself.")
425427 }
426428 }
427429
428430
429431
430432 @Callable(i)
431433 func revokeConfirmationScript (scriptId) = {
432434 let callerPbk = toBase58String(i.callerPublicKey)
433435 let limit = _getLimit()
434436 if (!(_isAdmin(callerPbk)))
435437 then throw("Only admins can revoke")
436438 else {
437439 let _scriptHash = valueOrErrorMessage(getString((scriptId + "__scriptHash")), "Invalid scriptId")
438440 if ((_scriptHash == _scriptHash))
439441 then {
440442 let scriptType = getStringValue((scriptId + "__scriptType"))
441443 let approvedHashesStr = valueOrElse(getString((("script_" + scriptType) + "_approved")), "")
442444 let approvedHashes = split_4C(approvedHashesStr, ",")
443445 let confirmationsStr = valueOrElse(getString((scriptId + "__confirmations")), "")
444446 let confirmations = split(confirmationsStr, ",")
445447 let confirmIndex = indexOf(confirmations, callerPbk)
446448 if ((confirmIndex == unit))
447449 then throw("You didn't confirm this script, nothing to revoke")
448450 else {
449451 let newConfirmations = removeByIndex(confirmations, value(confirmIndex))
450452 let newConfirmationsStr = makeString(newConfirmations, ",")
451453 let wasApproved = (indexOf(approvedHashes, _scriptHash) != unit)
452454 let stillApproved = (size(newConfirmations) >= limit)
453455 let stateChanges = if (if (wasApproved)
454456 then !(stillApproved)
455457 else false)
456458 then {
457459 let scriptHashIndex = value(indexOf(approvedHashes, _scriptHash))
458460 let newApprovedHashes = removeByIndex(approvedHashes, scriptHashIndex)
459461 let newApprovedHashesStr = makeString(newApprovedHashes, ",")
460462 [StringEntry((("script_" + scriptType) + "_approved"), newApprovedHashesStr), DeleteEntry((((scriptType + SEP) + _scriptHash) + "__approved"))]
461463 }
462464 else nil
463465 (stateChanges ++ [StringEntry((scriptId + "__confirmations"), newConfirmationsStr)])
464466 }
465467 }
466468 else throw("Strict value is not equal to itself.")
467469 }
468470 }
469471
470472
471473
472474 @Callable(i)
473475 func addTask (name,dapp,txid,executeTs,desc,initiatorAdr,txdata) = {
474476 let callerPbk = toBase58String(i.callerPublicKey)
475477 if (!(_isValidOperator(callerPbk)))
476478 then throw("Not allowed")
477479 else {
478480 let _nameCheck = if ((size(name) == 0))
479481 then throw("Name can't be empty")
480482 else true
481483 if ((_nameCheck == _nameCheck))
482484 then {
483485 let _dappCheck = if (!(_validateAddress(dapp)))
484486 then throw("Incorrect dapp")
485487 else true
486488 if ((_dappCheck == _dappCheck))
487489 then {
488490 let _txidCheck = if ((size(txid) == 0))
489491 then throw("txid can't be empty")
490492 else true
491493 if ((_txidCheck == _txidCheck))
492494 then {
493495 let _timestampCheck = if (!(_validateTs(executeTs)))
494496 then throw("txid can't be empty")
495497 else true
496498 if ((_timestampCheck == _timestampCheck))
497499 then {
498500 let _descCheck = if ((size(desc) == 0))
499501 then throw("Description can't be empty")
500502 else true
501503 if ((_descCheck == _descCheck))
502504 then {
503505 let _initiatorCheck = if ((toString(addressFromPublicKey(i.callerPublicKey)) != initiatorAdr))
504506 then throw("Initiator address doesn't match caller")
505507 else true
506508 if ((_initiatorCheck == _initiatorCheck))
507509 then {
508510 let _txdataCheck = if ((size(txdata) == 0))
509511 then throw("Tx data can't be empty")
510512 else true
511513 if ((_txdataCheck == _txdataCheck))
512514 then {
513515 let taskId = ((("tx_" + dapp) + SEP) + txid)
514516 [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)]
515517 }
516518 else throw("Strict value is not equal to itself.")
517519 }
518520 else throw("Strict value is not equal to itself.")
519521 }
520522 else throw("Strict value is not equal to itself.")
521523 }
522524 else throw("Strict value is not equal to itself.")
523525 }
524526 else throw("Strict value is not equal to itself.")
525527 }
526528 else throw("Strict value is not equal to itself.")
527529 }
528530 else throw("Strict value is not equal to itself.")
529531 }
530532 }
531533
532534
533535
534536 @Callable(i)
535537 func removeTask (taskId) = {
536538 let callerPbk = toBase58String(i.callerPublicKey)
537539 if (!(_isValidOperator(callerPbk)))
538540 then throw("Not allowed")
539541 else {
540542 let initiatorAdr = getStringValue((taskId + "__initiator"))
541543 if ((initiatorAdr != toString(addressFromPublicKey(i.callerPublicKey))))
542544 then throw("Only creator can remove")
543545 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"))]
544546 }
545547 }
546548
547549
548550
549551 @Callable(i)
550552 func addConfirmation (taskId) = {
551553 let callerPbk = toBase58String(i.callerPublicKey)
552554 let limit = _getLimit()
553555 if (!(_isAdmin(callerPbk)))
554556 then throw("Only admins can confirm")
555557 else {
556558 let txId = valueOrErrorMessage(getString((taskId + "__txId")), "Ivalid task")
557559 if ((txId == txId))
558560 then {
559561 let dapp = getStringValue((taskId + "__dapp"))
560562 let confirmationsStr = valueOrElse(getString((taskId + "__confirmations")), "")
561563 let confirmations = split(confirmationsStr, ",")
562564 if ((indexOf(confirmations, callerPbk) != unit))
563565 then throw("You already confirmed this task")
564566 else {
565567 let newList = if ((confirmationsStr != ""))
566568 then (confirmations :+ callerPbk)
567569 else [callerPbk]
568570 let newListStr = makeString(newList, ",")
569571 let approved = (size(newList) >= limit)
570572 [StringEntry((taskId + "__confirmations"), newListStr), BooleanEntry((((dapp + SEP) + txId) + "__approved"), approved)]
571573 }
572574 }
573575 else throw("Strict value is not equal to itself.")
574576 }
575577 }
576578
577579
578580
579581 @Callable(i)
580582 func setLimit (limit) = {
581583 let callerPbk = toBase58String(i.callerPublicKey)
582584 if (!(_isAdmin(callerPbk)))
583585 then throw("Only whitelisted can set limit")
584586 else {
585587 let zeroLimit = if ((limit > 0))
586588 then true
587589 else throw("Limit should be > 0")
588590 if ((zeroLimit == zeroLimit))
589591 then {
590592 let admins = getStringValue(k_ADMINS)
591593 if ((limit > size(admins)))
592594 then throw(((("Limit quorum should be <= size of list of admins, limit: " + toString(limit)) + ", current size: ") + toString(size(admins))))
593595 else [IntegerEntry(k_LIMIT, limit)]
594596 }
595597 else throw("Strict value is not equal to itself.")
596598 }
597599 }
598600
599601
600602
601603 @Callable(i)
602604 func test () = {
603605 let x = match blockInfoByHeight(height) {
604606 case block: BlockInfo =>
605607 throw(toString(block.timestamp))
606608 case _ =>
607609 throw("Can't find block")
608610 }
609611 if ((x == x))
610612 then nil
611613 else throw("Strict value is not equal to itself.")
612614 }
613615
614616
615617
616618 @Callable(i)
617619 func clear_test () = {
618620 let indices = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
619621 func removeChunks (accum,index) = (accum :+ DeleteEntry((("testtask" + "__txdata_") + toString(index))))
620622
621623 let entries = {
622624 let $l = indices
623625 let $s = size($l)
624626 let $acc0 = [DeleteEntry(("testtask" + "__txdata_chunks"))]
625627 func $f0_1 ($a,$i) = if (($i >= $s))
626628 then $a
627629 else removeChunks($a, $l[$i])
628630
629631 func $f0_2 ($a,$i) = if (($i >= $s))
630632 then $a
631633 else throw("List size exceeds 10")
632634
633635 $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)
634636 }
635637 entries
636638 }
637639
638640

github/deemru/w8io
48.32 ms