tx · 2Aizk9BvQhe4hE4fKr7ESsrye6nc7wiqJMWSHWinh8fb

3MsU936briqQ2XZMpkhWdrV8EsNwm5iCuRY:  -0.02100000 Waves

2023.05.11 12:59 [2573068] smart account 3MsU936briqQ2XZMpkhWdrV8EsNwm5iCuRY > SELF 0.00000000 Waves

{ "type": 13, "id": "2Aizk9BvQhe4hE4fKr7ESsrye6nc7wiqJMWSHWinh8fb", "fee": 2100000, "feeAssetId": null, "timestamp": 1683799210059, "version": 2, "chainId": 84, "sender": "3MsU936briqQ2XZMpkhWdrV8EsNwm5iCuRY", "senderPublicKey": "F471QhzucRgQCSkZK5opBNc55AoNgiibCabvTp6GZ9nq", "proofs": [ "5CuF1ASA512qJSUJ241ozu9msKtLpBihHxmq438j1vpQ2sfGDthHeC1MCoUKKnouibgxZQTtFSUQ2srKR6NPCqkN" ], "script": "base64:BgI6CAISBwoFAQgIAQESBQoDCAgIEgASAwoBCBIDCgEIEgYKBAgIAQESAwoBCBIGCgQBAQgIEgUKAwgICEoAA1NFUAICX18ABU1VTFQ2AMCEPQAFTVVMVDgAgMLXLwAKV0FWRVNJRFNUUgIFV0FWRVMAB1dBVkVTSUQJANkEAQUKV0FWRVNJRFNUUgEMZ2V0SW50T3JGYWlsAQNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQR0aGlzBQNrZXkJAKwCAgkArAICAg9NYW5kYXRvcnkgdGhpcy4FA2tleQIPIGlzIG5vdCBkZWZpbmVkAQxnZXRJbnRPckVsc2UCA2tleQN2YWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUDa2V5BQN2YWwBDGdldFN0ck9yRWxzZQMHYWRkcmVzcwNrZXkKZGVmYXVsdFZhbAkBC3ZhbHVlT3JFbHNlAgkAnQgCBQdhZGRyZXNzBQNrZXkFCmRlZmF1bHRWYWwBD2dldFN0cmluZ09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJAKwCAgkArAICAg9NYW5kYXRvcnkgdGhpcy4FA2tleQIPIGlzIG5vdCBkZWZpbmVkARBnZXRBZGRyZXNzT3JGYWlsAQNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQEPZ2V0U3RyaW5nT3JGYWlsAgUEdGhpcwUDa2V5CQCsAgIJAKwCAgIVRmFpbCB0byBjb252ZXJ0IHRoaXMuBQNrZXkCEyB2YWx1ZSBpbnRvIEFkZHJlc3MBCWFzQW55TGlzdAEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIJTGlzdFtBbnldBAp2YWxBbnlMaXN0BQckbWF0Y2gwBQp2YWxBbnlMaXN0CQACAQIbZmFpbCB0byBjYXN0IGludG8gTGlzdFtBbnldAQVhc0ludAEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAgNJbnQEAWkFByRtYXRjaDAFAWkJAAIBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBC2FzQnl0ZVZlY290AQF2BAckbWF0Y2gwBQF2AwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAWkFByRtYXRjaDAFAWkJAAIBAhxmYWlsIHRvIGNhc3QgaW50byBCeXRlVmVjdG9yARV2YWxpZGF0ZUFkZHJlc3NPckZhaWwBCmFkZHJlc3NTdHIEB2FkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQphZGRyZXNzU3RyCQCsAgICHWZhaWwgdG8gY29udmVydCBpbnRvIGFkZHJlc3MgBQphZGRyZXNzU3RyAwkAZgIAAAgJAO8HAQUHYWRkcmVzcwlhdmFpbGFibGUJAQV0aHJvdwAFCmFkZHJlc3NTdHIBD2tleU5vZGVSZWdpc3RyeQEHYWRkcmVzcwkArAICAgQlc19fBQdhZGRyZXNzARRrZXlOb2RlUmV3YXJkc1RvdGFscwEHYWRkcmVzcwkArAICAg4lcyVzX190b3RhbHNfXwUHYWRkcmVzcwETa2V5QXBwcm92ZWROb2RlTGlzdAACFCVzX19hcHByb3ZlZE5vZGVMaXN0ARBrZXlEZXBvc2l0QW1vdW50AAIYJXMlc19fY2ZnX19kZXBvc2l0QW1vdW50ARVrZXlOZXV0cmlub0FkZHJlc3NTdHIAAholcyVzX19jZmdfX25ldXRyaW5vQWRkcmVzcwEXa2V5TWFzdGVyTm9kZUFkZHJlc3NTdHIAAiIlcyVzX19jZmdfX21haW5OZXV0cmlub05vZGVBZGRyZXNzARFrZXlQcm90b2NvbFBhcnRYNgACGSVzJXNfX2NmZ19fcHJvdG9jb2xQYXJ0WDYBE2tleUJlbmlmaWNhcnlQYXJ0WDYAAhslcyVzX19jZmdfX2JlbmlmaWNhcnlQYXJ0WDYBFmtleU1pbkRpc3RyaWJ1dGVBbW91bnQAAh4lcyVzX19jZmdfX21pbkRpc3RyaWJ1dGVBbW91bnQBHGtleVN3b3BmaVVzZHRVc2RuUG9vbEFkZHJlc3MAAiQlcyVzX19jZmdfX3N3b3BmaVVzZHRVc2RuUG9vbEFkZHJlc3MBEGtleVd4U3dhcEFkZHJlc3MAAhglcyVzX19jZmdfX3d4U3dhcEFkZHJlc3MBEWtleVNhdmluZ3NBZGRyZXNzAAIZJXMlc19fY2ZnX19zYXZpbmdzQWRkcmVzcwEVa2V5QmVuZWZpY2lhcnlBZGRyZXNzAAIdJXMlc19fY2ZnX19iZW5lZmljaWFyeUFkZHJlc3MBFWtleU5vZGVzVm90aW5nTmV4dE51bQACIyVzJXNfX25vZGVzVm90aW5nQ2ZnX19uZXh0Vm90aW5nTnVtARdrZXlOb2Rlc1ZvdGluZ09wdGlvbktleQIJdm90aW5nTnVtCW9wdGlvbk51bQkAuQkCCQDMCAICFiVzJWQlc19fbm9kZXNWb3RpbmdDZmcJAMwIAgUJdm90aW5nTnVtCQDMCAIFCW9wdGlvbk51bQUDbmlsBQNTRVABEmtleU5vZGVzVm90aW5nRGVzYwEJdm90aW5nTnVtCQC5CQIJAMwIAgIWJXMlZCVzX19ub2Rlc1ZvdGluZ0NmZwkAzAgCBQl2b3RpbmdOdW0JAMwIAgILZGVzY3JpcHRpb24FA25pbAUDU0VQARlrZXlOb2Rlc1ZvdGluZ1N0YXJ0SGVpZ2h0AQl2b3RpbmdOdW0JALkJAgkAzAgCAhYlcyVkJXNfX25vZGVzVm90aW5nQ2ZnCQDMCAIFCXZvdGluZ051bQkAzAgCAhF2b3RpbmdTdGFydEhlaWdodAUDbmlsBQNTRVABF2tleU5vZGVzVm90aW5nRW5kSGVpZ2h0AQl2b3RpbmdOdW0JALkJAgkAzAgCAhYlcyVkJXNfX25vZGVzVm90aW5nQ2ZnCQDMCAIFCXZvdGluZ051bQkAzAgCAg92b3RpbmdFbmRIZWlnaHQFA25pbAUDU0VQAR5rZXlOb2Rlc1ZvdGluZ09wdGlvblRvdGFsVm90ZXMCCXZvdGluZ051bQlvcHRpb25OdW0JALkJAgkAzAgCAhklcyVkJXMlc19fbm9kZXNWb3RpbmdEYXRhCQDMCAIFCXZvdGluZ051bQkAzAgCAhBvcHRpb25Ub3RhbFZvdGVzCQDMCAIFCW9wdGlvbk51bQUDbmlsBQNTRVABGGtleU5vZGVzVm90aW5nTm9kZUNob2ljZQIJdm90aW5nTnVtDm5vZGVBZGRyZXNzU3RyCQC5CQIJAMwIAgIZJXMlZCVzJXNfX25vZGVzVm90aW5nRGF0YQkAzAgCBQl2b3RpbmdOdW0JAMwIAgIKbm9kZUNob2ljZQkAzAgCBQ5ub2RlQWRkcmVzc1N0cgUDbmlsBQNTRVAAGUlkeENvbnRyb2xDZmdOZXV0cmlub0RhcHAAAQAYSWR4Q29udHJvbENmZ0F1Y3Rpb25EYXBwAAIAFElkeENvbnRyb2xDZmdScGREYXBwAAMAFUlkeENvbnRyb2xDZmdNYXRoRGFwcAAEABxJZHhDb250cm9sQ2ZnTGlxdWlkYXRpb25EYXBwAAUAFUlkeENvbnRyb2xDZmdSZXN0RGFwcAAGAB1JZHhDb250cm9sQ2ZnTm9kZVJlZ2lzdHJ5RGFwcAAHABxJZHhDb250cm9sQ2ZnTnNidFN0YWtpbmdEYXBwAAgAGUlkeENvbnRyb2xDZmdNZWRpYXRvckRhcHAACQAcSWR4Q29udHJvbENmZ1N1cmZTdGFraW5nRGFwcAAKACBJZHhDb250cm9sQ2ZnR25zYnRDb250cm9sbGVyRGFwcAALABdJZHhDb250cm9sQ2ZnUmVzdFYyRGFwcAAMABtJZHhDb250cm9sQ2ZnR292ZXJuYW5jZURhcHAADQERa2V5Q29udHJvbEFkZHJlc3MAAhwlcyVzX19jb25maWdfX2NvbnRyb2xBZGRyZXNzAQ1rZXlDb250cm9sQ2ZnAAIRJXNfX2NvbnRyb2xDb25maWcBDmtleVVzZG5Bc3NldElkAAIRbmV1dHJpbm9fYXNzZXRfaWQBFHJlYWRDb250cm9sQ2ZnT3JGYWlsAQdjb250cm9sCQC8CQIJAQ9nZXRTdHJpbmdPckZhaWwCBQdjb250cm9sCQENa2V5Q29udHJvbENmZwAFA1NFUAEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgpjb250cm9sQ2ZnA2lkeAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUKY29udHJvbENmZwUDaWR4CQCsAgICLUNvbnRyb2wgY2ZnIGRvZXNuJ3QgY29udGFpbiBhZGRyZXNzIGF0IGluZGV4IAkApAMBBQNpZHgAD2NvbnRyb2xDb250cmFjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQERa2V5Q29udHJvbEFkZHJlc3MAAiMzTjROUzdkNEpvOWE2RjE0TGlGVUtLWVZkVWtrZjJlUDRaeAAKY29udHJvbENmZwkBFHJlYWRDb250cm9sQ2ZnT3JGYWlsAQUPY29udHJvbENvbnRyYWN0ABBuZXV0cmlub0NvbnRyYWN0CQEYZ2V0Q29udHJhY3RBZGRyZXNzT3JGYWlsAgUKY29udHJvbENmZwUZSWR4Q29udHJvbENmZ05ldXRyaW5vRGFwcAAOdXNkbkFzc2V0SWRTdHIJAQxnZXRTdHJPckVsc2UDBRBuZXV0cmlub0NvbnRyYWN0CQEOa2V5VXNkbkFzc2V0SWQAAixIZXpzZFF1UkR0emtzQVlVeTk3Z2ZoS3k3WjFOVzJ1WFlTSEEzYmdxZW5OWgALdXNkbkFzc2V0SWQJANkEAQUOdXNkbkFzc2V0SWRTdHIADG5SZWdJZHhUeEFkZAABABBuUmVnSWR4SGVpZ2h0QWRkAAIADm5SZWdJZHhUaW1lQWRkAAMADm5SZWdJZHhEZXBvQW10AAQAEm5SZWdJZHhEZXBvQW10TGVmdAAFAA1uUmVnSWR4U3RhdHVzAAYAGW5SZWdJZHhTdGF0dXNDaGFuZ2VIZWlnaHQABwAXblJlZ0lkeFN0YXR1c0NoYW5nZVRpbWUACAEQZm9ybWF0RGVwb3NpdEFkZAQHdHhJZFN0cg1kZXBvc2l0QW1vdW50FnJlbWFpbmluZ0RlcG9zaXRBbW91bnQGc3RhdHVzCQC5CQIJAMwIAgIQJXMlZCVkJWQlZCVzJWQlZAkAzAgCBQd0eElkU3RyCQDMCAIJAKQDAQgFCWxhc3RCbG9jawZoZWlnaHQJAMwIAgkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQCkAwEFDWRlcG9zaXRBbW91bnQJAMwIAgkApAMBBRZyZW1haW5pbmdEZXBvc2l0QW1vdW50CQDMCAIFBnN0YXR1cwkAzAgCAgEwCQDMCAICATAFA25pbAUDU0VQARlmb3JtYXREZXBvc2l0Q2hhbmdlU3RhdHVzAgVvcmlnUwluZXdTdGF0dXMEBG9yaWcJALUJAgUFb3JpZ1MFA1NFUAkAuQkCCQDMCAICECVzJWQlZCVkJWQlcyVkJWQJAMwIAgkAkQMCBQRvcmlnBQxuUmVnSWR4VHhBZGQJAMwIAgkAkQMCBQRvcmlnBRBuUmVnSWR4SGVpZ2h0QWRkCQDMCAIJAJEDAgUEb3JpZwUOblJlZ0lkeFRpbWVBZGQJAMwIAgkAkQMCBQRvcmlnBQ5uUmVnSWR4RGVwb0FtdAkAzAgCCQCRAwIFBG9yaWcFEm5SZWdJZHhEZXBvQW10TGVmdAkAzAgCBQluZXdTdGF0dXMJAMwIAgkApAMBCAUJbGFzdEJsb2NrBmhlaWdodAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQNuaWwFA1NFUAEQa2V5UmV3YXJkSGlzdG9yeQILbm9kZUFkZHJlc3MEdHhJZAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgdoaXN0b3J5CQDMCAIJAKUIAQULbm9kZUFkZHJlc3MJAMwIAgkA2AQBBQR0eElkBQNuaWwFA1NFUAERZGF0YVJld2FyZEhpc3RvcnkFEHdhdmVzQW1vdW50VG90YWwOYmVuZWZpY2lhcnlBbXQLcHJvdG9jb2xBbXQQcHJvdG9jb2xBbXRQYXJ0MRBwcm90b2NvbEFtdFBhcnQyCQC5CQIJAMwIAgIOJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBCAUJbGFzdEJsb2NrBmhlaWdodAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAKQDAQUQd2F2ZXNBbW91bnRUb3RhbAkAzAgCCQCkAwEFDmJlbmVmaWNpYXJ5QW10CQDMCAIJAKQDAQULcHJvdG9jb2xBbXQJAMwIAgkApAMBBRBwcm90b2NvbEFtdFBhcnQxCQDMCAIJAKQDAQUQcHJvdG9jb2xBbXRQYXJ0MgUDbmlsBQNTRVABElJld2FyZEhpc3RvcnlFbnRyeQcLbm9kZUFkZHJlc3MEdHhJZAhtaW5lZEFtdA5iZW5lZmljaWFyeUFtdAtwcm90b2NvbEFtdAxwcm90b2NvbEFtdDEMcHJvdG9jb2xBbXQyCQELU3RyaW5nRW50cnkCCQEQa2V5UmV3YXJkSGlzdG9yeQIFC25vZGVBZGRyZXNzBQR0eElkCQERZGF0YVJld2FyZEhpc3RvcnkFBQhtaW5lZEFtdAUOYmVuZWZpY2lhcnlBbXQFC3Byb3RvY29sQW10BQxwcm90b2NvbEFtdDEFDHByb3RvY29sQW10MgEQZGF0YVJld2FyZFRvdGFscwUIbWluZWRBbXQOYmVuZWZpY2lhcnlBbXQLcHJvdG9jb2xBbXQQcHJvdG9jb2xBbXRQYXJ0MRBwcm90b2NvbEFtdFBhcnQyCQC5CQIJAMwIAgIKJWQlZCVkJWQlZAkAzAgCCQCkAwEFCG1pbmVkQW10CQDMCAIJAKQDAQUOYmVuZWZpY2lhcnlBbXQJAMwIAgkApAMBBQtwcm90b2NvbEFtdAkAzAgCCQCkAwEFEHByb3RvY29sQW10UGFydDEJAMwIAgkApAMBBRBwcm90b2NvbEFtdFBhcnQyBQNuaWwFA1NFUAERUmV3YXJkVG90YWxzRW50cnkGBW1pbmVyCG1pbmVkQW10DmJlbmVmaWNpYXJ5QW10C3Byb3RvY29sQW10EHByb3RvY29sQW10UGFydDEQcHJvdG9jb2xBbXRQYXJ0MgQUbm9kZVJld2FyZHNUb3RhbHNLRVkJARRrZXlOb2RlUmV3YXJkc1RvdGFscwEJAKUIAQUFbWluZXIEEG5vZGVSZXdhcmRzQXJyYXkJALUJAgkBDGdldFN0ck9yRWxzZQMFBHRoaXMFFG5vZGVSZXdhcmRzVG90YWxzS0VZCQEQZGF0YVJld2FyZFRvdGFscwUAAAAAAAAAAAAABQNTRVAEC25ld01pbmVkQW10CQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFEG5vZGVSZXdhcmRzQXJyYXkAAQUIbWluZWRBbXQEEW5ld0JlbmVmaWNpYXJ5QW10CQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFEG5vZGVSZXdhcmRzQXJyYXkAAgUOYmVuZWZpY2lhcnlBbXQEDm5ld1Byb3RvY29sQW10CQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFEG5vZGVSZXdhcmRzQXJyYXkAAwULcHJvdG9jb2xBbXQEE25ld1Byb3RvY29sQW10UGFydDEJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUQbm9kZVJld2FyZHNBcnJheQAEBRBwcm90b2NvbEFtdFBhcnQxBBNuZXdQcm90b2NvbEFtdFBhcnQyCQBkAgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFEG5vZGVSZXdhcmRzQXJyYXkABQUQcHJvdG9jb2xBbXRQYXJ0MgkBC1N0cmluZ0VudHJ5AgUUbm9kZVJld2FyZHNUb3RhbHNLRVkJARBkYXRhUmV3YXJkVG90YWxzBQULbmV3TWluZWRBbXQFEW5ld0JlbmVmaWNpYXJ5QW10BQ5uZXdQcm90b2NvbEFtdAUTbmV3UHJvdG9jb2xBbXRQYXJ0MQUTbmV3UHJvdG9jb2xBbXRQYXJ0MgEUcmVzb2x2ZUJlbmVmaWNpYXJpZXMCDG1pbmVyQWRkcmVzcxRiZW5lZmljaWFyeUZyb21QYXJhbQQZYmVuZWZpY2lhcnlGcm9tTWluZXJTdGF0ZQkBEUBleHRyTmF0aXZlKDEwNjIpAQkBD2dldFN0cmluZ09yRmFpbAIFDG1pbmVyQWRkcmVzcwkBFWtleUJlbmVmaWNpYXJ5QWRkcmVzcwADCQAAAgkA8QcBBQxtaW5lckFkZHJlc3MFBHVuaXQFFGJlbmVmaWNpYXJ5RnJvbVBhcmFtBRliZW5lZmljaWFyeUZyb21NaW5lclN0YXRlAR1yZWFkTm9kZURhdGFBbmRWYWxpZGF0ZVN0YXR1cwIIbm9kZUFkZHIOZXhwZWN0ZWRTdGF0dXMEC25vZGVEYXRhT3B0CQCiCAEJAQ9rZXlOb2RlUmVnaXN0cnkBBQhub2RlQWRkcgMJAQEhAQkBCWlzRGVmaW5lZAEFC25vZGVEYXRhT3B0CQACAQkArAICAg1Vbmtub3duIE5vZGUgBQhub2RlQWRkcgQLbm9kZURhdGFTdHIJAQV2YWx1ZQEFC25vZGVEYXRhT3B0BAhub2RlRGF0YQkAtQkCBQtub2RlRGF0YVN0cgUDU0VQBApub2RlU3RhdHVzAwkAZwIJAJADAQUIbm9kZURhdGEACQkAkQMCBQhub2RlRGF0YQUNblJlZ0lkeFN0YXR1cwIHUEVORElORwMJAQIhPQIFCm5vZGVTdGF0dXMFDmV4cGVjdGVkU3RhdHVzCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICBU5vZGUgBQhub2RlQWRkcgISIHN0YXR1cyBzaG91bGQgYmUgBQ5leHBlY3RlZFN0YXR1cwIPLCBidXQgYWN0dWFsbHkgBQpub2RlU3RhdHVzBQtub2RlRGF0YVN0cgkBaQENY29uc3RydWN0b3JWMQUNZGVwb3NpdEFtb3VudBJuZXV0cmlub0FkZHJlc3NTdHIUbWFzdGVyTm9kZUFkZHJlc3NTdHIOcHJvdG9jb2xQYXJ0WDYQYmVuaWZpY2FyeVBhcnRYNgMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECEnBlcm1pc3Npb25zIGRlbmllZAMJAGYCAAAFDWRlcG9zaXRBbW91bnQJAAIBAhxkZXBvc2l0QW1vdW50IGxlc3MgdGhlbiB6ZXJvAwkAZgIAAAUOcHJvdG9jb2xQYXJ0WDYJAAIBAh1wcm90b2NvbFBhcnRYNiBsZXNzIHRoZW4gemVybwMJAGYCAAAFEGJlbmlmaWNhcnlQYXJ0WDYJAAIBAh9iZW5pZmljYXJ5UGFydFg2IGxlc3MgdGhlbiB6ZXJvAwkBAiE9AgkAZAIFDnByb3RvY29sUGFydFg2BRBiZW5pZmljYXJ5UGFydFg2BQVNVUxUNgkAAgECE3BhcnRzIHN1bSBtdXN0IGJlIDEJAMwIAgkBDEludGVnZXJFbnRyeQIJARBrZXlEZXBvc2l0QW1vdW50AAUNZGVwb3NpdEFtb3VudAkAzAgCCQELU3RyaW5nRW50cnkCCQEVa2V5TmV1dHJpbm9BZGRyZXNzU3RyAAkBFXZhbGlkYXRlQWRkcmVzc09yRmFpbAEFEm5ldXRyaW5vQWRkcmVzc1N0cgkAzAgCCQELU3RyaW5nRW50cnkCCQEXa2V5TWFzdGVyTm9kZUFkZHJlc3NTdHIACQEVdmFsaWRhdGVBZGRyZXNzT3JGYWlsAQUUbWFzdGVyTm9kZUFkZHJlc3NTdHIJAMwIAgkBDEludGVnZXJFbnRyeQIJARFrZXlQcm90b2NvbFBhcnRYNgAFDnByb3RvY29sUGFydFg2CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQETa2V5QmVuaWZpY2FyeVBhcnRYNgAFEGJlbmlmaWNhcnlQYXJ0WDYFA25pbAFpAQ1jb25zdHJ1Y3RvclYyAxBzd29wZmlBZGRyZXNzU3RyEWNvbnRyb2xBZGRyZXNzU3RyEXNhdmluZ3NBZGRyZXNzU3RyAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIScGVybWlzc2lvbnMgZGVuaWVkCQDMCAIJAQtTdHJpbmdFbnRyeQIJARxrZXlTd29wZmlVc2R0VXNkblBvb2xBZGRyZXNzAAkBFXZhbGlkYXRlQWRkcmVzc09yRmFpbAEFEHN3b3BmaUFkZHJlc3NTdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBEWtleUNvbnRyb2xBZGRyZXNzAAkBFXZhbGlkYXRlQWRkcmVzc09yRmFpbAEFEWNvbnRyb2xBZGRyZXNzU3RyCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlTYXZpbmdzQWRkcmVzcwAJARV2YWxpZGF0ZUFkZHJlc3NPckZhaWwBBRFzYXZpbmdzQWRkcmVzc1N0cgUDbmlsAWkBEXN1bWJpdEFwcGxpY2F0aW9uAAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECIGV4YWN0IDEgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkAwkBAiE9AggFAWkGY2FsbGVyCAUBaQxvcmlnaW5DYWxsZXIJAAIBAiJkYXBwIHRvIGRhcHAgY2FsbHMgYXJlIG5vdCBhbGxvd2VkBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAQHZGVwb3NpdAgFA3BtdAZhbW91bnQECnBtdEFzc2V0SWQJAQt2YWx1ZU9yRWxzZQIIBQNwbXQHYXNzZXRJZAUHV0FWRVNJRAQVZXhwZWN0ZWREZXBvc2l0QW1vdW50CQEMZ2V0SW50T3JGYWlsAQkBEGtleURlcG9zaXRBbW91bnQABAR0eElkCQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQEC25vZGVBZGRyZXNzCQClCAEIBQFpBmNhbGxlcgQPbm9kZVJlZ2lzdHJ5S0VZCQEPa2V5Tm9kZVJlZ2lzdHJ5AQULbm9kZUFkZHJlc3MDCQECIT0CBQpwbXRBc3NldElkBQdXQVZFU0lECQACAQIib25seSBXYXZlcyBjYW4gYmUgdXNlZCBmb3IgZGVwb3NpdAMJAQIhPQIFB2RlcG9zaXQFFWV4cGVjdGVkRGVwb3NpdEFtb3VudAkAAgEJAKwCAgkArAICAghleGFjdGx5IAkApAMBBRVleHBlY3RlZERlcG9zaXRBbW91bnQCFiBXYXZlbGV0cyBhcmUgZXhwZWN0ZWQDCQECIT0CCQEMZ2V0U3RyT3JFbHNlAwUEdGhpcwUPbm9kZVJlZ2lzdHJ5S0VZAgACAAkAAgECHHlvdXIgbm9kZSBhbHJlYWR5IHJlZ2lzdGVyZWQJAMwIAgkBC1N0cmluZ0VudHJ5AgUPbm9kZVJlZ2lzdHJ5S0VZCQEQZm9ybWF0RGVwb3NpdEFkZAQFBHR4SWQFB2RlcG9zaXQFB2RlcG9zaXQCB1BFTkRJTkcFA25pbAFpARVkaXN0cmlidXRlTWluZXJSZXdhcmQBFWJlbmVmaWNpYXJ5QWRkcmVzc1N0cgQTbWluRGlzdHJpYnV0ZUFtb3VudAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEWa2V5TWluRGlzdHJpYnV0ZUFtb3VudAAJAGgCABgFBU1VTFQ4AwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIgZXhhY3QgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQDCQECIT0CCAUBaQZjYWxsZXIIBQFpDG9yaWdpbkNhbGxlcgkAAgECImRhcHAgdG8gZGFwcCBjYWxscyBhcmUgbm90IGFsbG93ZWQEA3BtdAkAkQMCCAUBaQhwYXltZW50cwAABApwbXRBc3NldElkCQELdmFsdWVPckVsc2UCCAUDcG10B2Fzc2V0SWQFB1dBVkVTSUQEBmZlZUFtdAgFAWkDZmVlBApmZWVBc3NldElkCQELdmFsdWVPckVsc2UCCAUBaQpmZWVBc3NldElkBQdXQVZFU0lEBApjYWxsUmV3YXJkCQBoAgUGZmVlQW10AAMECG1pbmVkQW10CQBlAggFA3BtdAZhbW91bnQFCmNhbGxSZXdhcmQDCQECIT0CCAUDcG10BmFtb3VudAUTbWluRGlzdHJpYnV0ZUFtb3VudAkAAgEJAKwCAgkArAICAh9hdHRhY2hlZCBwYXltZW50IG11c3QgYmUgZXhhY3QgCQCkAwEFE21pbkRpc3RyaWJ1dGVBbW91bnQCCSBXYXZlbGV0cwMJAQIhPQIFCnBtdEFzc2V0SWQFB1dBVkVTSUQJAAIBAiFvbmx5IFdhdmVzIGNhbiBiZSB1c2VkIGluIHBheW1lbnQDCQECIT0CBQpmZWVBc3NldElkBQdXQVZFU0lECQACAQIeb25seSBXYXZlcyBjYW4gYmUgdXNlZCBpbiBmZWVzAwkBAiE9AgUGZmVlQW10CQBpAgkAaAIABQUFTVVMVDgA6AcJAAIBAiBmZWUgYW1vdW50IGNvdWxkbid0IGV4Y2VlZCAwLjAwNQQPbmV1dHJpbm9BZGRyZXNzCQEQZ2V0QWRkcmVzc09yRmFpbAEJARVrZXlOZXV0cmlub0FkZHJlc3NTdHIABBFtYXN0ZXJOb2RlQWRkcmVzcwkBEGdldEFkZHJlc3NPckZhaWwBCQEXa2V5TWFzdGVyTm9kZUFkZHJlc3NTdHIABAxtaW5lckFkZHJlc3MIBQFpBmNhbGxlcgQUYmVuZWZpY2lhcnlGcm9tUGFyYW0JARFAZXh0ck5hdGl2ZSgxMDYyKQEFFWJlbmVmaWNpYXJ5QWRkcmVzc1N0cgQSYmVuZWZpY2lhcnlBZGRyZXNzCQEUcmVzb2x2ZUJlbmVmaWNpYXJpZXMCBQxtaW5lckFkZHJlc3MFFGJlbmVmaWNpYXJ5RnJvbVBhcmFtBBB0eFJld2FyZFJlY2VpdmVyBRRiZW5lZmljaWFyeUZyb21QYXJhbQQMcHJvdG9jb2xQYXJ0CQEMZ2V0SW50T3JGYWlsAQkBEWtleVByb3RvY29sUGFydFg2AAQPYmVuZWZpY2lhcnlQYXJ0CQEMZ2V0SW50T3JGYWlsAQkBE2tleUJlbmlmaWNhcnlQYXJ0WDYABA5iZW5lZmljaWFyeUFtdAkAawMFCG1pbmVkQW10BQ9iZW5lZmljaWFyeVBhcnQFBU1VTFQ2BAtwcm90b2NvbEFtdAkAZQIFCG1pbmVkQW10BQ5iZW5lZmljaWFyeUFtdAQKYnV5QmFja0FtdAkAaAIAeAUFTVVMVDgEDnNhdmluZ3NBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBCQEMZ2V0U3RyT3JFbHNlAwUEdGhpcwkBEWtleVNhdmluZ3NBZGRyZXNzAAIjM1BDN0RCaW1hdXlLeXR4OHRYaEtvNXUyRUNiNkZzbmRZS0gECnNhdmluZ3NBbXQJAQVhc0ludAEJAPwHBAUOc2F2aW5nc0FkZHJlc3MCCHdpdGhkcmF3CQDMCAIFCmJ1eUJhY2tBbXQFA25pbAUDbmlsBAx3eEFzc2V0SWRTdHICLEF0cXY1OUVZempGR3VpdEtWbk1SazZIOEZ1a2pvVjNrdFBvcmJFeXMyNW9uBA13eFN3YXBBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBCQEMZ2V0U3RyT3JFbHNlAwUEdGhpcwkBEGtleVd4U3dhcEFkZHJlc3MAAiMzUDY4ek5pdWZzdTF2aVpwdTFhWTNjZGFoUlJLY3ZWNU45MwQKc3dhcFJlc3VsdAkA/AcEBQ13eFN3YXBBZGRyZXNzAgRzd2FwCQDMCAIAAQkAzAgCBQx3eEFzc2V0SWRTdHIJAMwIAgkApQgBBRBuZXV0cmlub0NvbnRyYWN0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFBHVuaXQFCnNhdmluZ3NBbXQFA25pbAMJAAACBQpzd2FwUmVzdWx0BQpzd2FwUmVzdWx0CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFEmJlbmVmaWNpYXJ5QWRkcmVzcwUOYmVuZWZpY2lhcnlBbXQFBHVuaXQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUQbmV1dHJpbm9Db250cmFjdAULcHJvdG9jb2xBbXQFBHVuaXQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUQdHhSZXdhcmRSZWNlaXZlcgUKY2FsbFJld2FyZAUEdW5pdAkAzAgCCQESUmV3YXJkSGlzdG9yeUVudHJ5BwUMbWluZXJBZGRyZXNzCAUBaQ10cmFuc2FjdGlvbklkBQhtaW5lZEFtdAUOYmVuZWZpY2lhcnlBbXQFC3Byb3RvY29sQW10BQtwcm90b2NvbEFtdAAACQDMCAIJARFSZXdhcmRUb3RhbHNFbnRyeQYFDG1pbmVyQWRkcmVzcwUIbWluZWRBbXQFDmJlbmVmaWNpYXJ5QW10BQtwcm90b2NvbEFtdAULcHJvdG9jb2xBbXQAAAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBGnZhbGlkYXRlQW5kQXBwcm92ZUxlYXNpbmdzAQZuTGlzdFMEBW5JZHhzCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFCQDMCAIABgkAzAgCAAcFA25pbAQFbkxpc3QJALUJAgUGbkxpc3RTBQNTRVAEDWV4cGVjdGVkQ291bnQJAJADAQUFbklkeHMED25ldXRyaW5vQWRkcmVzcwkBEGdldEFkZHJlc3NPckZhaWwBCQEVa2V5TmV1dHJpbm9BZGRyZXNzU3RyAAMJAQIhPQIIBQFpBmNhbGxlcgUPbmV1dHJpbm9BZGRyZXNzCQACAQIpdmFsaWRhdGVBbmRBcHByb3ZlTGVhc2luZ3Mgbm90IGF1dGhvcml6ZWQDCQECIT0CCQBqAgkAkAMBBQVuTGlzdAACAAAJAAIBAiRPbmx5IGV2ZW4gbnVtYmVyIG9mIG5vZGVzIGlzIGFsbG93ZWQDCQECIT0CCQCQAwEFBW5MaXN0BQ1leHBlY3RlZENvdW50CQACAQkArAICCQCsAgICBU9ubHkgCQCkAwEFDWV4cGVjdGVkQ291bnQCIiBvZiBub2RlcycgYWRkcmVzc2VzIGNhbiBiZSBwYXNzZWQKARdmb3JFYWNoTm9kZUNoYW5nZVN0YXR1cwIDYWNjAWkECG5vZGVBZGRyCQCRAwIFBW5MaXN0BQFpBAtub2RlRGF0YVN0cgkBHXJlYWROb2RlRGF0YUFuZFZhbGlkYXRlU3RhdHVzAgUIbm9kZUFkZHICB1BFTkRJTkcJAM0IAgUDYWNjCQELU3RyaW5nRW50cnkCCQEPa2V5Tm9kZVJlZ2lzdHJ5AQUIbm9kZUFkZHIJARlmb3JtYXREZXBvc2l0Q2hhbmdlU3RhdHVzAgULbm9kZURhdGFTdHICCEFQUFJPVkVEBBFhcHByb3ZlZE5vZGVzRGF0YQoAAiRsBQVuSWR4cwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEXZm9yRWFjaE5vZGVDaGFuZ2VTdGF0dXMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDgJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAICQCUCgIFEWFwcHJvdmVkTm9kZXNEYXRhBQNuaWwBaQETcmVwbGFjZUFwcHJvdmVkTm9kZQQOb2xkTm9kZUFkZHJTdHIObmV3Tm9kZUFkZHJTdHIIZ3JvdXBOdW0NcGVuYWx0eUFtb3VudAMJAQIhPQIIBQFpBmNhbGxlcgUQbmV1dHJpbm9Db250cmFjdAkAAgECEnBlcm1pc3Npb25zIGRlbmllZAQKb2xkRGF0YVN0cgkBHXJlYWROb2RlRGF0YUFuZFZhbGlkYXRlU3RhdHVzAgUOb2xkTm9kZUFkZHJTdHICCEFQUFJPVkVEBApuZXdEYXRhU3RyCQEdcmVhZE5vZGVEYXRhQW5kVmFsaWRhdGVTdGF0dXMCBQ5uZXdOb2RlQWRkclN0cgIHUEVORElORwQRYXBwcm92ZWROb2RlTGlzdFMJAQ9nZXRTdHJpbmdPckZhaWwCBQR0aGlzCQETa2V5QXBwcm92ZWROb2RlTGlzdAADCQEBIQEJAQhjb250YWlucwIFEWFwcHJvdmVkTm9kZUxpc3RTBQ5vbGROb2RlQWRkclN0cgkAAgEJAKwCAgIiYXBwcm92ZWROb2RlTGlzdCBkb2VzIG5vdCBjb250YWluIAUOb2xkTm9kZUFkZHJTdHIEEHVwZGF0ZWROb2RlTGlzdFMJALoJAgkAvAkCBRFhcHByb3ZlZE5vZGVMaXN0UwUOb2xkTm9kZUFkZHJTdHIFDm5ld05vZGVBZGRyU3RyBAtvbGROb2RlQWRkcgkBEUBleHRyTmF0aXZlKDEwNjIpAQUOb2xkTm9kZUFkZHJTdHIEEmJlbmVmaWNpYXJ5QWRkcmVzcwkBFHJlc29sdmVCZW5lZmljaWFyaWVzAgULb2xkTm9kZUFkZHIFC29sZE5vZGVBZGRyBApkZXBvQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgkAtQkCBQpvbGREYXRhU3RyBQNTRVAFDm5SZWdJZHhEZXBvQW10BAdhY3Rpb25zCQDMCAIJAQtTdHJpbmdFbnRyeQIJARNrZXlBcHByb3ZlZE5vZGVMaXN0AAUQdXBkYXRlZE5vZGVMaXN0UwkAzAgCCQELRGVsZXRlRW50cnkBCQEPa2V5Tm9kZVJlZ2lzdHJ5AQUOb2xkTm9kZUFkZHJTdHIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBD2tleU5vZGVSZWdpc3RyeQEFDm5ld05vZGVBZGRyU3RyCQEZZm9ybWF0RGVwb3NpdENoYW5nZVN0YXR1cwIFCm5ld0RhdGFTdHICCEFQUFJPVkVEBQNuaWwJAJQKAgMJAGYCBQpkZXBvQW1vdW50BQ1wZW5hbHR5QW1vdW50CQDNCAIFB2FjdGlvbnMJAQ5TY3JpcHRUcmFuc2ZlcgMFEmJlbmVmaWNpYXJ5QWRkcmVzcwkAZQIFCmRlcG9BbW91bnQFDXBlbmFsdHlBbW91bnQFBHVuaXQFB2FjdGlvbnMFBHVuaXQBaQENcmV0dXJuRGVwb3NpdAEObm9kZUFkZHJlc3NTdHIDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAhNObyBwYXltZW50cyBhbGxvd2VkBA1jYWxsZXJBZGRyZXNzCAUBaQZjYWxsZXIED25vZGVSZWdpc3RyeUtFWQkBD2tleU5vZGVSZWdpc3RyeQEFDm5vZGVBZGRyZXNzU3RyBAtub2RlRGF0YU9wdAkAnQgCBQR0aGlzBQ9ub2RlUmVnaXN0cnlLRVkDCQEBIQEJAQlpc0RlZmluZWQBBQtub2RlRGF0YU9wdAkAAgEJAKwCAgIpQWRkcmVzcyBpcyBub3QgYXBwbGllZCBhcyBuZXV0cmlubyBub2RlOiAFDm5vZGVBZGRyZXNzU3RyBBBhcHByb3ZlZE5vZGVMaXN0CQEPZ2V0U3RyaW5nT3JGYWlsAgUEdGhpcwkBE2tleUFwcHJvdmVkTm9kZUxpc3QAAwkBCGNvbnRhaW5zAgUQYXBwcm92ZWROb2RlTGlzdAUObm9kZUFkZHJlc3NTdHIJAAIBAkxJbXBvc3NpYmxlIHRvIHJldHVybiBkZXBvc2l0IGZyb20gYXBwcm92ZWQgTm9kZSwgcGxlYXNlIGNvbnRhY3Qgc3VwcG9ydCB0ZWFtBAhub2RlRGF0YQkAtQkCCQEFdmFsdWUBBQtub2RlRGF0YU9wdAUDU0VQBAZzdGF0dXMDCQBnAgkAkAMBBQhub2RlRGF0YQAJCQCRAwIFCG5vZGVEYXRhBQ1uUmVnSWR4U3RhdHVzAgdQRU5ESU5HAwkBAiE9AgUGc3RhdHVzAgdQRU5ESU5HCQACAQIiQXBwbGljYXRpb24gc3RhdHVzIGlzIG5vdCBQRU5ESU5HIQQKZGVwb0Ftb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCG5vZGVEYXRhBQ5uUmVnSWR4RGVwb0FtdAQLbm9kZUFkZHJlc3MJARFAZXh0ck5hdGl2ZSgxMDYyKQEFDm5vZGVBZGRyZXNzU3RyBBJiZW5lZmljaWFyeUFkZHJlc3MJARRyZXNvbHZlQmVuZWZpY2lhcmllcwIFC25vZGVBZGRyZXNzBQtub2RlQWRkcmVzcwMJAQEhAQMDCQAAAgUNY2FsbGVyQWRkcmVzcwUEdGhpcwYDCQECIT0CBRJiZW5lZmljaWFyeUFkZHJlc3MFC25vZGVBZGRyZXNzCQAAAgUNY2FsbGVyQWRkcmVzcwUSYmVuZWZpY2lhcnlBZGRyZXNzBwYDCQAAAgUSYmVuZWZpY2lhcnlBZGRyZXNzBQtub2RlQWRkcmVzcwkAAAIFDWNhbGxlckFkZHJlc3MFC25vZGVBZGRyZXNzBwkAAgECIHJldHVybkRlcG9zaXQgcGVybWlzc2lvbnMgZGVuaWVkCQDMCAIJAQtEZWxldGVFbnRyeQEFD25vZGVSZWdpc3RyeUtFWQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBRJiZW5lZmljaWFyeUFkZHJlc3MFCmRlcG9BbW91bnQFBHVuaXQFA25pbAFpAQ9pbml0Tm9kZXNWb3RpbmcEC3N0YXJ0SGVpZ2h0CWVuZEhlaWdodAdvcHRpb25zC2Rlc2NyaXB0aW9uAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIScGVybWlzc2lvbnMgZGVuaWVkBAxvcHRpb25zQXJyYXkJALUJAgUHb3B0aW9ucwICX18DCQECIT0CCQBqAgkAkAMBBQxvcHRpb25zQXJyYXkAAgAACQACAQIaTm90IGV2ZW4gbnVtYmVyIG9mIG9wdGlvbnMDCQBmAgkAaQIJAJADAQUMb3B0aW9uc0FycmF5AAIACgkAAgECH01heCAxMCBvcHRpb25zIGNhbiBiZSBzcGVjaWZpZWQEEW5vZGVzVm90aW5nTnVtS0VZCQEVa2V5Tm9kZXNWb3RpbmdOZXh0TnVtAAQJdm90aW5nTnVtCQEMZ2V0SW50T3JFbHNlAgURbm9kZXNWb3RpbmdOdW1LRVkAAAQMdm90aW5nTnVtU3RyCQCkAwEFCXZvdGluZ051bQoBEHRyYW5zZm9ybU9wdGlvbnMCBWFjY3VtB25leHRPcHQEB29wdERhdGEJALUJAgUHbmV4dE9wdAIBOgQDb3B0CQCRAwIFB29wdERhdGEAAAQGb3B0S0VZCQEXa2V5Tm9kZXNWb3RpbmdPcHRpb25LZXkCBQx2b3RpbmdOdW1TdHIFA29wdAQIb3B0RGVzY3IJAJEDAgUHb3B0RGF0YQABBBBvcHRUb3RhbFZvdGVzS0VZCQEea2V5Tm9kZXNWb3RpbmdPcHRpb25Ub3RhbFZvdGVzAgUMdm90aW5nTnVtU3RyBQNvcHQJAM0IAgkAzQgCBQVhY2N1bQkBC1N0cmluZ0VudHJ5AgUGb3B0S0VZBQhvcHREZXNjcgkBDEludGVnZXJFbnRyeQIFEG9wdFRvdGFsVm90ZXNLRVkAAAkAzQgCCQDNCAIJAM0IAgkAzQgCCgACJGwFDG9wdGlvbnNBcnJheQoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEQdHJhbnNmb3JtT3B0aW9ucwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgkBDEludGVnZXJFbnRyeQIFEW5vZGVzVm90aW5nTnVtS0VZCQBkAgUJdm90aW5nTnVtAAEJAQtTdHJpbmdFbnRyeQIJARJrZXlOb2Rlc1ZvdGluZ0Rlc2MBBQx2b3RpbmdOdW1TdHIFC2Rlc2NyaXB0aW9uCQEMSW50ZWdlckVudHJ5AgkBGWtleU5vZGVzVm90aW5nU3RhcnRIZWlnaHQBBQx2b3RpbmdOdW1TdHIFC3N0YXJ0SGVpZ2h0CQEMSW50ZWdlckVudHJ5AgkBF2tleU5vZGVzVm90aW5nRW5kSGVpZ2h0AQUMdm90aW5nTnVtU3RyBQllbmRIZWlnaHQBaQEKdm90ZUJ5Tm9kZQMObm9kZUFkZHJlc3NTdHIJdm90aW5nTnVtCW9wdGlvbk51bQQMdmFsaWRhdGVOb2RlCQEdcmVhZE5vZGVEYXRhQW5kVmFsaWRhdGVTdGF0dXMCBQ5ub2RlQWRkcmVzc1N0cgIIQVBQUk9WRUQDCQAAAgUMdmFsaWRhdGVOb2RlBQx2YWxpZGF0ZU5vZGUEC25vZGVBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBBQ5ub2RlQWRkcmVzc1N0cgQPbm9kZUJlbmVmaWNpYXJ5CQEPZ2V0U3RyaW5nT3JGYWlsAgULbm9kZUFkZHJlc3MJARVrZXlCZW5lZmljaWFyeUFkZHJlc3MABA92b3RlckFkZHJlc3NTdHIJAKUIAQgFAWkGY2FsbGVyAwkBAiE9AgUPdm90ZXJBZGRyZXNzU3RyBQ9ub2RlQmVuZWZpY2lhcnkJAAIBAiVPbmx5IE5vZGUncyBiZW5lZmljaWFyeSBjYW4gZG8gdm90aW5nBAtzdGFydEhlaWdodAkBDGdldEludE9yRmFpbAEJARlrZXlOb2Rlc1ZvdGluZ1N0YXJ0SGVpZ2h0AQUJdm90aW5nTnVtBAllbmRIZWlnaHQJAQxnZXRJbnRPckZhaWwBCQEXa2V5Tm9kZXNWb3RpbmdFbmRIZWlnaHQBBQl2b3RpbmdOdW0DCQBmAgULc3RhcnRIZWlnaHQFBmhlaWdodAkAAgECH1ZvdGluZyBoYXMgbm90IGJlZW4gc3RhcnRlZCB5ZXQDCQBmAgUGaGVpZ2h0BQllbmRIZWlnaHQJAAIBAg9Wb3RpbmcgZmluaXNoZWQEDW5vZGVDaG9pY2VLRVkJARhrZXlOb2Rlc1ZvdGluZ05vZGVDaG9pY2UCBQl2b3RpbmdOdW0FDm5vZGVBZGRyZXNzU3RyBApub2RlQ2hvaWNlCQEMZ2V0U3RyT3JFbHNlAwUEdGhpcwUNbm9kZUNob2ljZUtFWQIAAwkBAiE9AgUKbm9kZUNob2ljZQIACQACAQI3Tm9kZSBoYXMgYWxyZWFkeSB2b3RlZC4gSXQgaXMgYWxsb3dlZCB0byB2b3RlIG9ubHkgb25jZQQTb3B0aW9uVG90YWxWb3Rlc0tFWQkBHmtleU5vZGVzVm90aW5nT3B0aW9uVG90YWxWb3RlcwIFCXZvdGluZ051bQUJb3B0aW9uTnVtBBBvcHRpb25Ub3RhbFZvdGVzCQEMZ2V0SW50T3JGYWlsAQUTb3B0aW9uVG90YWxWb3Rlc0tFWQkAzAgCCQEMSW50ZWdlckVudHJ5AgUTb3B0aW9uVG90YWxWb3Rlc0tFWQkAZAIFEG9wdGlvblRvdGFsVm90ZXMAAQkAzAgCCQELU3RyaW5nRW50cnkCBQ1ub2RlQ2hvaWNlS0VZBQlvcHRpb25OdW0FA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgBabYzJ", "height": 2573068, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 3nbSEye8VP72T52daNthsvn6YuU9XHG9nss2faA4RAxE Next: 4wR9QRnwzw4fxLsSD92ah6jp8NKGNACNKtAd5Jnb2FfZ Diff:
OldNewDifferences
1212 let WAVESID = fromBase58String(WAVESIDSTR)
1313
1414 func getIntOrFail (key) = valueOrErrorMessage(getInteger(this, key), (("Mandatory this." + key) + " is not defined"))
15+
16+
17+func getIntOrElse (key,val) = valueOrElse(getInteger(this, key), val)
1518
1619
1720 func getStrOrElse (address,key,defaultVal) = valueOrElse(getString(address, key), defaultVal)
8588 func keySwopfiUsdtUsdnPoolAddress () = "%s%s__cfg__swopfiUsdtUsdnPoolAddress"
8689
8790
91+func keyWxSwapAddress () = "%s%s__cfg__wxSwapAddress"
92+
93+
8894 func keySavingsAddress () = "%s%s__cfg__savingsAddress"
8995
9096
9197 func keyBeneficiaryAddress () = "%s%s__cfg__beneficiaryAddress"
98+
99+
100+func keyNodesVotingNextNum () = "%s%s__nodesVotingCfg__nextVotingNum"
101+
102+
103+func keyNodesVotingOptionKey (votingNum,optionNum) = makeString(["%s%d%s__nodesVotingCfg", votingNum, optionNum], SEP)
104+
105+
106+func keyNodesVotingDesc (votingNum) = makeString(["%s%d%s__nodesVotingCfg", votingNum, "description"], SEP)
107+
108+
109+func keyNodesVotingStartHeight (votingNum) = makeString(["%s%d%s__nodesVotingCfg", votingNum, "votingStartHeight"], SEP)
110+
111+
112+func keyNodesVotingEndHeight (votingNum) = makeString(["%s%d%s__nodesVotingCfg", votingNum, "votingEndHeight"], SEP)
113+
114+
115+func keyNodesVotingOptionTotalVotes (votingNum,optionNum) = makeString(["%s%d%s%s__nodesVotingData", votingNum, "optionTotalVotes", optionNum], SEP)
116+
117+
118+func keyNodesVotingNodeChoice (votingNum,nodeAddressStr) = makeString(["%s%d%s%s__nodesVotingData", votingNum, "nodeChoice", nodeAddressStr], SEP)
92119
93120
94121 let IdxControlCfgNeutrinoDapp = 1
295322 let beneficiaryPart = getIntOrFail(keyBenificaryPartX6())
296323 let beneficiaryAmt = fraction(minedAmt, beneficiaryPart, MULT6)
297324 let protocolAmt = (minedAmt - beneficiaryAmt)
298-[ScriptTransfer(beneficiaryAddress, beneficiaryAmt, unit), ScriptTransfer(neutrinoContract, protocolAmt, unit), ScriptTransfer(txRewardReceiver, callReward, unit), RewardHistoryEntry(minerAddress, i.transactionId, minedAmt, beneficiaryAmt, protocolAmt, protocolAmt, 0), RewardTotalsEntry(minerAddress, minedAmt, beneficiaryAmt, protocolAmt, protocolAmt, 0)]
325+ let buyBackAmt = (120 * MULT8)
326+ let savingsAddress = addressFromStringValue(getStrOrElse(this, keySavingsAddress(), "3PC7DBimauyKytx8tXhKo5u2ECb6FsndYKH"))
327+ let savingsAmt = asInt(invoke(savingsAddress, "withdraw", [buyBackAmt], nil))
328+ let wxAssetIdStr = "Atqv59EYzjFGuitKVnMRk6H8FukjoV3ktPorbEys25on"
329+ let wxSwapAddress = addressFromStringValue(getStrOrElse(this, keyWxSwapAddress(), "3P68zNiufsu1viZpu1aY3cdahRRKcvV5N93"))
330+ let swapResult = invoke(wxSwapAddress, "swap", [1, wxAssetIdStr, toString(neutrinoContract)], [AttachedPayment(unit, savingsAmt)])
331+ if ((swapResult == swapResult))
332+ then [ScriptTransfer(beneficiaryAddress, beneficiaryAmt, unit), ScriptTransfer(neutrinoContract, protocolAmt, unit), ScriptTransfer(txRewardReceiver, callReward, unit), RewardHistoryEntry(minerAddress, i.transactionId, minedAmt, beneficiaryAmt, protocolAmt, protocolAmt, 0), RewardTotalsEntry(minerAddress, minedAmt, beneficiaryAmt, protocolAmt, protocolAmt, 0)]
333+ else throw("Strict value is not equal to itself.")
299334 }
300335 }
301336 }
405440 }
406441
407442
443+
444+@Callable(i)
445+func initNodesVoting (startHeight,endHeight,options,description) = if ((i.caller != this))
446+ then throw("permissions denied")
447+ else {
448+ let optionsArray = split(options, "__")
449+ if (((size(optionsArray) % 2) != 0))
450+ then throw("Not even number of options")
451+ else if (((size(optionsArray) / 2) > 10))
452+ then throw("Max 10 options can be specified")
453+ else {
454+ let nodesVotingNumKEY = keyNodesVotingNextNum()
455+ let votingNum = getIntOrElse(nodesVotingNumKEY, 0)
456+ let votingNumStr = toString(votingNum)
457+ func transformOptions (accum,nextOpt) = {
458+ let optData = split(nextOpt, ":")
459+ let opt = optData[0]
460+ let optKEY = keyNodesVotingOptionKey(votingNumStr, opt)
461+ let optDescr = optData[1]
462+ let optTotalVotesKEY = keyNodesVotingOptionTotalVotes(votingNumStr, opt)
463+ ((accum :+ StringEntry(optKEY, optDescr)) :+ IntegerEntry(optTotalVotesKEY, 0))
464+ }
465+
466+ (((({
467+ let $l = optionsArray
468+ let $s = size($l)
469+ let $acc0 = nil
470+ func $f0_1 ($a,$i) = if (($i >= $s))
471+ then $a
472+ else transformOptions($a, $l[$i])
473+
474+ func $f0_2 ($a,$i) = if (($i >= $s))
475+ then $a
476+ else throw("List size exceeds 10")
477+
478+ $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)
479+ } :+ IntegerEntry(nodesVotingNumKEY, (votingNum + 1))) :+ StringEntry(keyNodesVotingDesc(votingNumStr), description)) :+ IntegerEntry(keyNodesVotingStartHeight(votingNumStr), startHeight)) :+ IntegerEntry(keyNodesVotingEndHeight(votingNumStr), endHeight))
480+ }
481+ }
482+
483+
484+
485+@Callable(i)
486+func voteByNode (nodeAddressStr,votingNum,optionNum) = {
487+ let validateNode = readNodeDataAndValidateStatus(nodeAddressStr, "APPROVED")
488+ if ((validateNode == validateNode))
489+ then {
490+ let nodeAddress = addressFromStringValue(nodeAddressStr)
491+ let nodeBeneficiary = getStringOrFail(nodeAddress, keyBeneficiaryAddress())
492+ let voterAddressStr = toString(i.caller)
493+ if ((voterAddressStr != nodeBeneficiary))
494+ then throw("Only Node's beneficiary can do voting")
495+ else {
496+ let startHeight = getIntOrFail(keyNodesVotingStartHeight(votingNum))
497+ let endHeight = getIntOrFail(keyNodesVotingEndHeight(votingNum))
498+ if ((startHeight > height))
499+ then throw("Voting has not been started yet")
500+ else if ((height > endHeight))
501+ then throw("Voting finished")
502+ else {
503+ let nodeChoiceKEY = keyNodesVotingNodeChoice(votingNum, nodeAddressStr)
504+ let nodeChoice = getStrOrElse(this, nodeChoiceKEY, "")
505+ if ((nodeChoice != ""))
506+ then throw("Node has already voted. It is allowed to vote only once")
507+ else {
508+ let optionTotalVotesKEY = keyNodesVotingOptionTotalVotes(votingNum, optionNum)
509+ let optionTotalVotes = getIntOrFail(optionTotalVotesKEY)
510+[IntegerEntry(optionTotalVotesKEY, (optionTotalVotes + 1)), StringEntry(nodeChoiceKEY, optionNum)]
511+ }
512+ }
513+ }
514+ }
515+ else throw("Strict value is not equal to itself.")
516+ }
517+
518+
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SEP = "__"
55
66 let MULT6 = 1000000
77
88 let MULT8 = 100000000
99
1010 let WAVESIDSTR = "WAVES"
1111
1212 let WAVESID = fromBase58String(WAVESIDSTR)
1313
1414 func getIntOrFail (key) = valueOrErrorMessage(getInteger(this, key), (("Mandatory this." + key) + " is not defined"))
15+
16+
17+func getIntOrElse (key,val) = valueOrElse(getInteger(this, key), val)
1518
1619
1720 func getStrOrElse (address,key,defaultVal) = valueOrElse(getString(address, key), defaultVal)
1821
1922
2023 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (("Mandatory this." + key) + " is not defined"))
2124
2225
2326 func getAddressOrFail (key) = valueOrErrorMessage(addressFromString(getStringOrFail(this, key)), (("Fail to convert this." + key) + " value into Address"))
2427
2528
2629 func asAnyList (val) = match val {
2730 case valAnyList: List[Any] =>
2831 valAnyList
2932 case _ =>
3033 throw("fail to cast into List[Any]")
3134 }
3235
3336
3437 func asInt (v) = match v {
3538 case i: Int =>
3639 i
3740 case _ =>
3841 throw("fail to cast into Int")
3942 }
4043
4144
4245 func asByteVecot (v) = match v {
4346 case i: ByteVector =>
4447 i
4548 case _ =>
4649 throw("fail to cast into ByteVector")
4750 }
4851
4952
5053 func validateAddressOrFail (addressStr) = {
5154 let address = valueOrErrorMessage(addressFromString(addressStr), ("fail to convert into address " + addressStr))
5255 if ((0 > wavesBalance(address).available))
5356 then throw()
5457 else addressStr
5558 }
5659
5760
5861 func keyNodeRegistry (address) = ("%s__" + address)
5962
6063
6164 func keyNodeRewardsTotals (address) = ("%s%s__totals__" + address)
6265
6366
6467 func keyApprovedNodeList () = "%s__approvedNodeList"
6568
6669
6770 func keyDepositAmount () = "%s%s__cfg__depositAmount"
6871
6972
7073 func keyNeutrinoAddressStr () = "%s%s__cfg__neutrinoAddress"
7174
7275
7376 func keyMasterNodeAddressStr () = "%s%s__cfg__mainNeutrinoNodeAddress"
7477
7578
7679 func keyProtocolPartX6 () = "%s%s__cfg__protocolPartX6"
7780
7881
7982 func keyBenificaryPartX6 () = "%s%s__cfg__benificaryPartX6"
8083
8184
8285 func keyMinDistributeAmount () = "%s%s__cfg__minDistributeAmount"
8386
8487
8588 func keySwopfiUsdtUsdnPoolAddress () = "%s%s__cfg__swopfiUsdtUsdnPoolAddress"
8689
8790
91+func keyWxSwapAddress () = "%s%s__cfg__wxSwapAddress"
92+
93+
8894 func keySavingsAddress () = "%s%s__cfg__savingsAddress"
8995
9096
9197 func keyBeneficiaryAddress () = "%s%s__cfg__beneficiaryAddress"
98+
99+
100+func keyNodesVotingNextNum () = "%s%s__nodesVotingCfg__nextVotingNum"
101+
102+
103+func keyNodesVotingOptionKey (votingNum,optionNum) = makeString(["%s%d%s__nodesVotingCfg", votingNum, optionNum], SEP)
104+
105+
106+func keyNodesVotingDesc (votingNum) = makeString(["%s%d%s__nodesVotingCfg", votingNum, "description"], SEP)
107+
108+
109+func keyNodesVotingStartHeight (votingNum) = makeString(["%s%d%s__nodesVotingCfg", votingNum, "votingStartHeight"], SEP)
110+
111+
112+func keyNodesVotingEndHeight (votingNum) = makeString(["%s%d%s__nodesVotingCfg", votingNum, "votingEndHeight"], SEP)
113+
114+
115+func keyNodesVotingOptionTotalVotes (votingNum,optionNum) = makeString(["%s%d%s%s__nodesVotingData", votingNum, "optionTotalVotes", optionNum], SEP)
116+
117+
118+func keyNodesVotingNodeChoice (votingNum,nodeAddressStr) = makeString(["%s%d%s%s__nodesVotingData", votingNum, "nodeChoice", nodeAddressStr], SEP)
92119
93120
94121 let IdxControlCfgNeutrinoDapp = 1
95122
96123 let IdxControlCfgAuctionDapp = 2
97124
98125 let IdxControlCfgRpdDapp = 3
99126
100127 let IdxControlCfgMathDapp = 4
101128
102129 let IdxControlCfgLiquidationDapp = 5
103130
104131 let IdxControlCfgRestDapp = 6
105132
106133 let IdxControlCfgNodeRegistryDapp = 7
107134
108135 let IdxControlCfgNsbtStakingDapp = 8
109136
110137 let IdxControlCfgMediatorDapp = 9
111138
112139 let IdxControlCfgSurfStakingDapp = 10
113140
114141 let IdxControlCfgGnsbtControllerDapp = 11
115142
116143 let IdxControlCfgRestV2Dapp = 12
117144
118145 let IdxControlCfgGovernanceDapp = 13
119146
120147 func keyControlAddress () = "%s%s__config__controlAddress"
121148
122149
123150 func keyControlCfg () = "%s__controlConfig"
124151
125152
126153 func keyUsdnAssetId () = "neutrino_asset_id"
127154
128155
129156 func readControlCfgOrFail (control) = split_4C(getStringOrFail(control, keyControlCfg()), SEP)
130157
131158
132159 func getContractAddressOrFail (controlCfg,idx) = valueOrErrorMessage(addressFromString(controlCfg[idx]), ("Control cfg doesn't contain address at index " + toString(idx)))
133160
134161
135162 let controlContract = addressFromStringValue(valueOrElse(getString(this, keyControlAddress()), "3N4NS7d4Jo9a6F14LiFUKKYVdUkkf2eP4Zx"))
136163
137164 let controlCfg = readControlCfgOrFail(controlContract)
138165
139166 let neutrinoContract = getContractAddressOrFail(controlCfg, IdxControlCfgNeutrinoDapp)
140167
141168 let usdnAssetIdStr = getStrOrElse(neutrinoContract, keyUsdnAssetId(), "HezsdQuRDtzksAYUy97gfhKy7Z1NW2uXYSHA3bgqenNZ")
142169
143170 let usdnAssetId = fromBase58String(usdnAssetIdStr)
144171
145172 let nRegIdxTxAdd = 1
146173
147174 let nRegIdxHeightAdd = 2
148175
149176 let nRegIdxTimeAdd = 3
150177
151178 let nRegIdxDepoAmt = 4
152179
153180 let nRegIdxDepoAmtLeft = 5
154181
155182 let nRegIdxStatus = 6
156183
157184 let nRegIdxStatusChangeHeight = 7
158185
159186 let nRegIdxStatusChangeTime = 8
160187
161188 func formatDepositAdd (txIdStr,depositAmount,remainingDepositAmount,status) = makeString(["%s%d%d%d%d%s%d%d", txIdStr, toString(lastBlock.height), toString(lastBlock.timestamp), toString(depositAmount), toString(remainingDepositAmount), status, "0", "0"], SEP)
162189
163190
164191 func formatDepositChangeStatus (origS,newStatus) = {
165192 let orig = split(origS, SEP)
166193 makeString(["%s%d%d%d%d%s%d%d", orig[nRegIdxTxAdd], orig[nRegIdxHeightAdd], orig[nRegIdxTimeAdd], orig[nRegIdxDepoAmt], orig[nRegIdxDepoAmtLeft], newStatus, toString(lastBlock.height), toString(lastBlock.timestamp)], SEP)
167194 }
168195
169196
170197 func keyRewardHistory (nodeAddress,txId) = makeString(["%s%s%s", "history", toString(nodeAddress), toBase58String(txId)], SEP)
171198
172199
173200 func dataRewardHistory (wavesAmountTotal,beneficiaryAmt,protocolAmt,protocolAmtPart1,protocolAmtPart2) = makeString(["%d%d%d%d%d%d%d", toString(lastBlock.height), toString(lastBlock.timestamp), toString(wavesAmountTotal), toString(beneficiaryAmt), toString(protocolAmt), toString(protocolAmtPart1), toString(protocolAmtPart2)], SEP)
174201
175202
176203 func RewardHistoryEntry (nodeAddress,txId,minedAmt,beneficiaryAmt,protocolAmt,protocolAmt1,protocolAmt2) = StringEntry(keyRewardHistory(nodeAddress, txId), dataRewardHistory(minedAmt, beneficiaryAmt, protocolAmt, protocolAmt1, protocolAmt2))
177204
178205
179206 func dataRewardTotals (minedAmt,beneficiaryAmt,protocolAmt,protocolAmtPart1,protocolAmtPart2) = makeString(["%d%d%d%d%d", toString(minedAmt), toString(beneficiaryAmt), toString(protocolAmt), toString(protocolAmtPart1), toString(protocolAmtPart2)], SEP)
180207
181208
182209 func RewardTotalsEntry (miner,minedAmt,beneficiaryAmt,protocolAmt,protocolAmtPart1,protocolAmtPart2) = {
183210 let nodeRewardsTotalsKEY = keyNodeRewardsTotals(toString(miner))
184211 let nodeRewardsArray = split(getStrOrElse(this, nodeRewardsTotalsKEY, dataRewardTotals(0, 0, 0, 0, 0)), SEP)
185212 let newMinedAmt = (parseIntValue(nodeRewardsArray[1]) + minedAmt)
186213 let newBeneficiaryAmt = (parseIntValue(nodeRewardsArray[2]) + beneficiaryAmt)
187214 let newProtocolAmt = (parseIntValue(nodeRewardsArray[3]) + protocolAmt)
188215 let newProtocolAmtPart1 = (parseIntValue(nodeRewardsArray[4]) + protocolAmtPart1)
189216 let newProtocolAmtPart2 = (parseIntValue(nodeRewardsArray[5]) + protocolAmtPart2)
190217 StringEntry(nodeRewardsTotalsKEY, dataRewardTotals(newMinedAmt, newBeneficiaryAmt, newProtocolAmt, newProtocolAmtPart1, newProtocolAmtPart2))
191218 }
192219
193220
194221 func resolveBeneficiaries (minerAddress,beneficiaryFromParam) = {
195222 let beneficiaryFromMinerState = addressFromStringValue(getStringOrFail(minerAddress, keyBeneficiaryAddress()))
196223 if ((scriptHash(minerAddress) == unit))
197224 then beneficiaryFromParam
198225 else beneficiaryFromMinerState
199226 }
200227
201228
202229 func readNodeDataAndValidateStatus (nodeAddr,expectedStatus) = {
203230 let nodeDataOpt = getString(keyNodeRegistry(nodeAddr))
204231 if (!(isDefined(nodeDataOpt)))
205232 then throw(("Unknown Node " + nodeAddr))
206233 else {
207234 let nodeDataStr = value(nodeDataOpt)
208235 let nodeData = split(nodeDataStr, SEP)
209236 let nodeStatus = if ((size(nodeData) >= 9))
210237 then nodeData[nRegIdxStatus]
211238 else "PENDING"
212239 if ((nodeStatus != expectedStatus))
213240 then throw(((((("Node " + nodeAddr) + " status should be ") + expectedStatus) + ", but actually ") + nodeStatus))
214241 else nodeDataStr
215242 }
216243 }
217244
218245
219246 @Callable(i)
220247 func constructorV1 (depositAmount,neutrinoAddressStr,masterNodeAddressStr,protocolPartX6,benificaryPartX6) = if ((i.caller != this))
221248 then throw("permissions denied")
222249 else if ((0 > depositAmount))
223250 then throw("depositAmount less then zero")
224251 else if ((0 > protocolPartX6))
225252 then throw("protocolPartX6 less then zero")
226253 else if ((0 > benificaryPartX6))
227254 then throw("benificaryPartX6 less then zero")
228255 else if (((protocolPartX6 + benificaryPartX6) != MULT6))
229256 then throw("parts sum must be 1")
230257 else [IntegerEntry(keyDepositAmount(), depositAmount), StringEntry(keyNeutrinoAddressStr(), validateAddressOrFail(neutrinoAddressStr)), StringEntry(keyMasterNodeAddressStr(), validateAddressOrFail(masterNodeAddressStr)), IntegerEntry(keyProtocolPartX6(), protocolPartX6), IntegerEntry(keyBenificaryPartX6(), benificaryPartX6)]
231258
232259
233260
234261 @Callable(i)
235262 func constructorV2 (swopfiAddressStr,controlAddressStr,savingsAddressStr) = if ((i.caller != this))
236263 then throw("permissions denied")
237264 else [StringEntry(keySwopfiUsdtUsdnPoolAddress(), validateAddressOrFail(swopfiAddressStr)), StringEntry(keyControlAddress(), validateAddressOrFail(controlAddressStr)), StringEntry(keySavingsAddress(), validateAddressOrFail(savingsAddressStr))]
238265
239266
240267
241268 @Callable(i)
242269 func sumbitApplication () = if ((size(i.payments) != 1))
243270 then throw("exact 1 payment must be attached")
244271 else if ((i.caller != i.originCaller))
245272 then throw("dapp to dapp calls are not allowed")
246273 else {
247274 let pmt = i.payments[0]
248275 let deposit = pmt.amount
249276 let pmtAssetId = valueOrElse(pmt.assetId, WAVESID)
250277 let expectedDepositAmount = getIntOrFail(keyDepositAmount())
251278 let txId = toBase58String(i.transactionId)
252279 let nodeAddress = toString(i.caller)
253280 let nodeRegistryKEY = keyNodeRegistry(nodeAddress)
254281 if ((pmtAssetId != WAVESID))
255282 then throw("only Waves can be used for deposit")
256283 else if ((deposit != expectedDepositAmount))
257284 then throw((("exactly " + toString(expectedDepositAmount)) + " Wavelets are expected"))
258285 else if ((getStrOrElse(this, nodeRegistryKEY, "") != ""))
259286 then throw("your node already registered")
260287 else [StringEntry(nodeRegistryKEY, formatDepositAdd(txId, deposit, deposit, "PENDING"))]
261288 }
262289
263290
264291
265292 @Callable(i)
266293 func distributeMinerReward (beneficiaryAddressStr) = {
267294 let minDistributeAmount = valueOrElse(getInteger(this, keyMinDistributeAmount()), (24 * MULT8))
268295 if ((size(i.payments) != 1))
269296 then throw("exact 1 payment must be attached")
270297 else if ((i.caller != i.originCaller))
271298 then throw("dapp to dapp calls are not allowed")
272299 else {
273300 let pmt = i.payments[0]
274301 let pmtAssetId = valueOrElse(pmt.assetId, WAVESID)
275302 let feeAmt = i.fee
276303 let feeAssetId = valueOrElse(i.feeAssetId, WAVESID)
277304 let callReward = (feeAmt * 3)
278305 let minedAmt = (pmt.amount - callReward)
279306 if ((pmt.amount != minDistributeAmount))
280307 then throw((("attached payment must be exact " + toString(minDistributeAmount)) + " Wavelets"))
281308 else if ((pmtAssetId != WAVESID))
282309 then throw("only Waves can be used in payment")
283310 else if ((feeAssetId != WAVESID))
284311 then throw("only Waves can be used in fees")
285312 else if ((feeAmt != ((5 * MULT8) / 1000)))
286313 then throw("fee amount couldn't exceed 0.005")
287314 else {
288315 let neutrinoAddress = getAddressOrFail(keyNeutrinoAddressStr())
289316 let masterNodeAddress = getAddressOrFail(keyMasterNodeAddressStr())
290317 let minerAddress = i.caller
291318 let beneficiaryFromParam = addressFromStringValue(beneficiaryAddressStr)
292319 let beneficiaryAddress = resolveBeneficiaries(minerAddress, beneficiaryFromParam)
293320 let txRewardReceiver = beneficiaryFromParam
294321 let protocolPart = getIntOrFail(keyProtocolPartX6())
295322 let beneficiaryPart = getIntOrFail(keyBenificaryPartX6())
296323 let beneficiaryAmt = fraction(minedAmt, beneficiaryPart, MULT6)
297324 let protocolAmt = (minedAmt - beneficiaryAmt)
298-[ScriptTransfer(beneficiaryAddress, beneficiaryAmt, unit), ScriptTransfer(neutrinoContract, protocolAmt, unit), ScriptTransfer(txRewardReceiver, callReward, unit), RewardHistoryEntry(minerAddress, i.transactionId, minedAmt, beneficiaryAmt, protocolAmt, protocolAmt, 0), RewardTotalsEntry(minerAddress, minedAmt, beneficiaryAmt, protocolAmt, protocolAmt, 0)]
325+ let buyBackAmt = (120 * MULT8)
326+ let savingsAddress = addressFromStringValue(getStrOrElse(this, keySavingsAddress(), "3PC7DBimauyKytx8tXhKo5u2ECb6FsndYKH"))
327+ let savingsAmt = asInt(invoke(savingsAddress, "withdraw", [buyBackAmt], nil))
328+ let wxAssetIdStr = "Atqv59EYzjFGuitKVnMRk6H8FukjoV3ktPorbEys25on"
329+ let wxSwapAddress = addressFromStringValue(getStrOrElse(this, keyWxSwapAddress(), "3P68zNiufsu1viZpu1aY3cdahRRKcvV5N93"))
330+ let swapResult = invoke(wxSwapAddress, "swap", [1, wxAssetIdStr, toString(neutrinoContract)], [AttachedPayment(unit, savingsAmt)])
331+ if ((swapResult == swapResult))
332+ then [ScriptTransfer(beneficiaryAddress, beneficiaryAmt, unit), ScriptTransfer(neutrinoContract, protocolAmt, unit), ScriptTransfer(txRewardReceiver, callReward, unit), RewardHistoryEntry(minerAddress, i.transactionId, minedAmt, beneficiaryAmt, protocolAmt, protocolAmt, 0), RewardTotalsEntry(minerAddress, minedAmt, beneficiaryAmt, protocolAmt, protocolAmt, 0)]
333+ else throw("Strict value is not equal to itself.")
299334 }
300335 }
301336 }
302337
303338
304339
305340 @Callable(i)
306341 func validateAndApproveLeasings (nListS) = {
307342 let nIdxs = [0, 1, 2, 3, 4, 5, 6, 7]
308343 let nList = split(nListS, SEP)
309344 let expectedCount = size(nIdxs)
310345 let neutrinoAddress = getAddressOrFail(keyNeutrinoAddressStr())
311346 if ((i.caller != neutrinoAddress))
312347 then throw("validateAndApproveLeasings not authorized")
313348 else if (((size(nList) % 2) != 0))
314349 then throw("Only even number of nodes is allowed")
315350 else if ((size(nList) != expectedCount))
316351 then throw((("Only " + toString(expectedCount)) + " of nodes' addresses can be passed"))
317352 else {
318353 func forEachNodeChangeStatus (acc,i) = {
319354 let nodeAddr = nList[i]
320355 let nodeDataStr = readNodeDataAndValidateStatus(nodeAddr, "PENDING")
321356 (acc :+ StringEntry(keyNodeRegistry(nodeAddr), formatDepositChangeStatus(nodeDataStr, "APPROVED")))
322357 }
323358
324359 let approvedNodesData = {
325360 let $l = nIdxs
326361 let $s = size($l)
327362 let $acc0 = nil
328363 func $f0_1 ($a,$i) = if (($i >= $s))
329364 then $a
330365 else forEachNodeChangeStatus($a, $l[$i])
331366
332367 func $f0_2 ($a,$i) = if (($i >= $s))
333368 then $a
334369 else throw("List size exceeds 8")
335370
336371 $f0_2($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)
337372 }
338373 $Tuple2(approvedNodesData, nil)
339374 }
340375 }
341376
342377
343378
344379 @Callable(i)
345380 func replaceApprovedNode (oldNodeAddrStr,newNodeAddrStr,groupNum,penaltyAmount) = if ((i.caller != neutrinoContract))
346381 then throw("permissions denied")
347382 else {
348383 let oldDataStr = readNodeDataAndValidateStatus(oldNodeAddrStr, "APPROVED")
349384 let newDataStr = readNodeDataAndValidateStatus(newNodeAddrStr, "PENDING")
350385 let approvedNodeListS = getStringOrFail(this, keyApprovedNodeList())
351386 if (!(contains(approvedNodeListS, oldNodeAddrStr)))
352387 then throw(("approvedNodeList does not contain " + oldNodeAddrStr))
353388 else {
354389 let updatedNodeListS = makeString_2C(split_4C(approvedNodeListS, oldNodeAddrStr), newNodeAddrStr)
355390 let oldNodeAddr = addressFromStringValue(oldNodeAddrStr)
356391 let beneficiaryAddress = resolveBeneficiaries(oldNodeAddr, oldNodeAddr)
357392 let depoAmount = parseIntValue(split(oldDataStr, SEP)[nRegIdxDepoAmt])
358393 let actions = [StringEntry(keyApprovedNodeList(), updatedNodeListS), DeleteEntry(keyNodeRegistry(oldNodeAddrStr)), StringEntry(keyNodeRegistry(newNodeAddrStr), formatDepositChangeStatus(newDataStr, "APPROVED"))]
359394 $Tuple2(if ((depoAmount > penaltyAmount))
360395 then (actions :+ ScriptTransfer(beneficiaryAddress, (depoAmount - penaltyAmount), unit))
361396 else actions, unit)
362397 }
363398 }
364399
365400
366401
367402 @Callable(i)
368403 func returnDeposit (nodeAddressStr) = if ((size(i.payments) != 0))
369404 then throw("No payments allowed")
370405 else {
371406 let callerAddress = i.caller
372407 let nodeRegistryKEY = keyNodeRegistry(nodeAddressStr)
373408 let nodeDataOpt = getString(this, nodeRegistryKEY)
374409 if (!(isDefined(nodeDataOpt)))
375410 then throw(("Address is not applied as neutrino node: " + nodeAddressStr))
376411 else {
377412 let approvedNodeList = getStringOrFail(this, keyApprovedNodeList())
378413 if (contains(approvedNodeList, nodeAddressStr))
379414 then throw("Impossible to return deposit from approved Node, please contact support team")
380415 else {
381416 let nodeData = split(value(nodeDataOpt), SEP)
382417 let status = if ((size(nodeData) >= 9))
383418 then nodeData[nRegIdxStatus]
384419 else "PENDING"
385420 if ((status != "PENDING"))
386421 then throw("Application status is not PENDING!")
387422 else {
388423 let depoAmount = parseIntValue(nodeData[nRegIdxDepoAmt])
389424 let nodeAddress = addressFromStringValue(nodeAddressStr)
390425 let beneficiaryAddress = resolveBeneficiaries(nodeAddress, nodeAddress)
391426 if (!(if (if ((callerAddress == this))
392427 then true
393428 else if ((beneficiaryAddress != nodeAddress))
394429 then (callerAddress == beneficiaryAddress)
395430 else false)
396431 then true
397432 else if ((beneficiaryAddress == nodeAddress))
398433 then (callerAddress == nodeAddress)
399434 else false))
400435 then throw("returnDeposit permissions denied")
401436 else [DeleteEntry(nodeRegistryKEY), ScriptTransfer(beneficiaryAddress, depoAmount, unit)]
402437 }
403438 }
404439 }
405440 }
406441
407442
443+
444+@Callable(i)
445+func initNodesVoting (startHeight,endHeight,options,description) = if ((i.caller != this))
446+ then throw("permissions denied")
447+ else {
448+ let optionsArray = split(options, "__")
449+ if (((size(optionsArray) % 2) != 0))
450+ then throw("Not even number of options")
451+ else if (((size(optionsArray) / 2) > 10))
452+ then throw("Max 10 options can be specified")
453+ else {
454+ let nodesVotingNumKEY = keyNodesVotingNextNum()
455+ let votingNum = getIntOrElse(nodesVotingNumKEY, 0)
456+ let votingNumStr = toString(votingNum)
457+ func transformOptions (accum,nextOpt) = {
458+ let optData = split(nextOpt, ":")
459+ let opt = optData[0]
460+ let optKEY = keyNodesVotingOptionKey(votingNumStr, opt)
461+ let optDescr = optData[1]
462+ let optTotalVotesKEY = keyNodesVotingOptionTotalVotes(votingNumStr, opt)
463+ ((accum :+ StringEntry(optKEY, optDescr)) :+ IntegerEntry(optTotalVotesKEY, 0))
464+ }
465+
466+ (((({
467+ let $l = optionsArray
468+ let $s = size($l)
469+ let $acc0 = nil
470+ func $f0_1 ($a,$i) = if (($i >= $s))
471+ then $a
472+ else transformOptions($a, $l[$i])
473+
474+ func $f0_2 ($a,$i) = if (($i >= $s))
475+ then $a
476+ else throw("List size exceeds 10")
477+
478+ $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)
479+ } :+ IntegerEntry(nodesVotingNumKEY, (votingNum + 1))) :+ StringEntry(keyNodesVotingDesc(votingNumStr), description)) :+ IntegerEntry(keyNodesVotingStartHeight(votingNumStr), startHeight)) :+ IntegerEntry(keyNodesVotingEndHeight(votingNumStr), endHeight))
480+ }
481+ }
482+
483+
484+
485+@Callable(i)
486+func voteByNode (nodeAddressStr,votingNum,optionNum) = {
487+ let validateNode = readNodeDataAndValidateStatus(nodeAddressStr, "APPROVED")
488+ if ((validateNode == validateNode))
489+ then {
490+ let nodeAddress = addressFromStringValue(nodeAddressStr)
491+ let nodeBeneficiary = getStringOrFail(nodeAddress, keyBeneficiaryAddress())
492+ let voterAddressStr = toString(i.caller)
493+ if ((voterAddressStr != nodeBeneficiary))
494+ then throw("Only Node's beneficiary can do voting")
495+ else {
496+ let startHeight = getIntOrFail(keyNodesVotingStartHeight(votingNum))
497+ let endHeight = getIntOrFail(keyNodesVotingEndHeight(votingNum))
498+ if ((startHeight > height))
499+ then throw("Voting has not been started yet")
500+ else if ((height > endHeight))
501+ then throw("Voting finished")
502+ else {
503+ let nodeChoiceKEY = keyNodesVotingNodeChoice(votingNum, nodeAddressStr)
504+ let nodeChoice = getStrOrElse(this, nodeChoiceKEY, "")
505+ if ((nodeChoice != ""))
506+ then throw("Node has already voted. It is allowed to vote only once")
507+ else {
508+ let optionTotalVotesKEY = keyNodesVotingOptionTotalVotes(votingNum, optionNum)
509+ let optionTotalVotes = getIntOrFail(optionTotalVotesKEY)
510+[IntegerEntry(optionTotalVotesKEY, (optionTotalVotes + 1)), StringEntry(nodeChoiceKEY, optionNum)]
511+ }
512+ }
513+ }
514+ }
515+ else throw("Strict value is not equal to itself.")
516+ }
517+
518+

github/deemru/w8io/169f3d6 
119.43 ms