tx · FoDgahN94S9LP76DLx2JtwEovakdu2j9T8RJbqA5BtK7

3NCWFHDzdPHZC6636ZkMLNDup9mjpbTLs7h:  -0.02200000 Waves

2024.10.09 15:52 [3319324] smart account 3NCWFHDzdPHZC6636ZkMLNDup9mjpbTLs7h > SELF 0.00000000 Waves

{ "type": 13, "id": "FoDgahN94S9LP76DLx2JtwEovakdu2j9T8RJbqA5BtK7", "fee": 2200000, "feeAssetId": null, "timestamp": 1728478350109, "version": 1, "sender": "3NCWFHDzdPHZC6636ZkMLNDup9mjpbTLs7h", "senderPublicKey": "3z8Q6Zu3KppVmn6fJJvrLc1Wo3krVHSvfaNcerm82md2", "proofs": [ "2aWix6AfFpHHdTBhjg6srLRLM5JCFVnAzvn3H9T9XPU7XLG5zariJEyuLkyswTAPFzKBvGwz9S35ui7XyjnDWBn7" ], "script": "base64:BgJJCAISAwoBARIDCgEEEgMKAQQSAwoBCBIECgIICBIDCgEIEgQKAggIEgMKAQgSBAoCCAESBAoCCAESAwoBARIAEgMKAQgSAwoBCDkADGNvbnRyYWN0RmlsZQIRbDJtcF9sZWFzaW5nLnJpZGUAA1NFUAICX18BCHRocm93RXJyAQNtc2cJAAIBCQCsAgIJAKwCAgUMY29udHJhY3RGaWxlAgI6IAUDbXNnAAprZXlBc3NldElkCQC5CQIJAMwIAgICJXMJAMwIAgIHYXNzZXRJZAUDbmlsBQNTRVAADGtleUZvcmNlU3RvcAkAuQkCCQDMCAICAiVzCQDMCAICCWZvcmNlU3RvcAUDbmlsBQNTRVAAD2tleUZvcmNlT3V0U3RvcAkAuQkCCQDMCAICAiVzCQDMCAICDGZvcmNlT3V0U3RvcAUDbmlsBQNTRVAAEWtleVBlcmlvZE9mZnNldElkCQC5CQIJAMwIAgICJXMJAMwIAgIIb2Zmc2V0SWQFA25pbAUDU0VQABVrZXlQZXJpb2RPZmZzZXRIZWlnaHQJALkJAgkAzAgCAgIlcwkAzAgCAgxvZmZzZXRIZWlnaHQFA25pbAUDU0VQAA9rZXlQZXJpb2RMZW5ndGgJALkJAgkAzAgCAgIlcwkAzAgCAgxwZXJpb2RMZW5ndGgFA25pbAUDU0VQAA5wZXJpb2RPZmZzZXRJZAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBRFrZXlQZXJpb2RPZmZzZXRJZAAAAAxwZXJpb2RMZW5ndGgJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUPa2V5UGVyaW9kTGVuZ3RoAJBOABJwZXJpb2RPZmZzZXRIZWlnaHQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUVa2V5UGVyaW9kT2Zmc2V0SGVpZ2h0AP///////////wEAD2N1cnJlbnRQZXJpb2RJZAMDCQBmAgUGaGVpZ2h0BRJwZXJpb2RPZmZzZXRIZWlnaHQJAQIhPQIFEnBlcmlvZE9mZnNldEhlaWdodAD///////////8BBwkAZAIJAGkCCQBlAgUGaGVpZ2h0BRJwZXJpb2RPZmZzZXRIZWlnaHQFDHBlcmlvZExlbmd0aAUOcGVyaW9kT2Zmc2V0SWQJAJYDAQkAzAgCAAAJAMwIAgkAZQIFDnBlcmlvZE9mZnNldElkAAEFA25pbAATY3VycmVudFBlcmlvZEhlaWdodAMDCQAAAgUScGVyaW9kT2Zmc2V0SGVpZ2h0AP///////////wEGAwkAAAIFD2N1cnJlbnRQZXJpb2RJZAAACQBmAgUScGVyaW9kT2Zmc2V0SGVpZ2h0BQZoZWlnaHQHAAAJAGQCBRJwZXJpb2RPZmZzZXRIZWlnaHQJAGgCCQBlAgUPY3VycmVudFBlcmlvZElkBQ5wZXJpb2RPZmZzZXRJZAUMcGVyaW9kTGVuZ3RoABBuZXh0UGVyaW9kSGVpZ2h0AwMJAAACBRJwZXJpb2RPZmZzZXRIZWlnaHQA////////////AQYDCQAAAgUPY3VycmVudFBlcmlvZElkAAAJAGYCBRJwZXJpb2RPZmZzZXRIZWlnaHQFBmhlaWdodAcAAAkAZAIFE2N1cnJlbnRQZXJpb2RIZWlnaHQFDHBlcmlvZExlbmd0aAESa2V5TGVhc2luZ05vZGVEYXRhAQtub2RlQWRkcmVzcwkAuQkCCQDMCAICAiVzCQDMCAIFC25vZGVBZGRyZXNzBQNuaWwFA1NFUAEWa2V5VXNlckxlYXNpbmdOb2RlRGF0YQILdXNlckFkZHJlc3MLbm9kZUFkZHJlc3MJALkJAgkAzAgCAgQlcyVzCQDMCAIFC25vZGVBZGRyZXNzCQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAEOa2V5VXNlclRvQ2xhaW0BC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIEJXMlcwkAzAgCAgd0b0NsYWltCQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAESa2V5VXNlclRvdGFsTG9ja2VkAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIPdXNlclRvdGFsTG9ja2VkCQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAEWa2V5Tm9kZUxlYXNpbmdCeUhlaWdodAELbm9kZUFkZHJlc3MEAWgDCQAAAgUScGVyaW9kT2Zmc2V0SGVpZ2h0AP///////////wEAAAUGaGVpZ2h0CQC5CQIJAMwIAgIEJXMlZAkAzAgCBQtub2RlQWRkcmVzcwkAzAgCCQCkAwEFAWgFA25pbAUDU0VQARZrZXlVc2VyTGVhc2luZ0J5SGVpZ2h0Agtub2RlQWRkcmVzcwt1c2VyQWRkcmVzcwQBaAMJAAACBRJwZXJpb2RPZmZzZXRIZWlnaHQA////////////AQAABQZoZWlnaHQJALkJAgkAzAgCAgYlcyVzJWQJAMwIAgULbm9kZUFkZHJlc3MJAMwIAgULdXNlckFkZHJlc3MJAMwIAgkApAMBBQFoBQNuaWwFA1NFUAANYXNzZXRJZFN0cmluZwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQprZXlBc3NldElkAgVXQVZFUwAMYXNzZXRJZEJ5dGVzAwkAAAIFDWFzc2V0SWRTdHJpbmcCBVdBVkVTBQR1bml0CQDZBAEFDWFzc2V0SWRTdHJpbmcAC2lzRm9yY2VTdG9wCQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMFDGtleUZvcmNlU3RvcAcADmlzRm9yY2VPdXRTdG9wCQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMFD2tleUZvcmNlT3V0U3RvcAcBDmlzVmFsaWRBZGRyZXNzAQdhZGRyZXNzBAckbWF0Y2gwCQCmCAEFB2FkZHJlc3MDCQABAgUHJG1hdGNoMAIHQWRkcmVzcwQBYQUHJG1hdGNoMAYHAA9BRE1JTl9MSVNUX1NJWkUABQAGUVVPUlVNAAMAEVRYSURfQllURVNfTEVOR1RIACABGGtleUFsbG93ZWRUeElkVm90ZVByZWZpeAEEdHhJZAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAglhbGxvd1R4SWQJAMwIAgUEdHhJZAUDbmlsBQNTRVABEGtleUZ1bGxBZG1pblZvdGUCBnByZWZpeAxhZG1pbkFkZHJlc3MJALkJAgkAzAgCBQZwcmVmaXgJAMwIAgUMYWRtaW5BZGRyZXNzBQNuaWwFA1NFUAETa2V5QWRtaW5BZGRyZXNzTGlzdAAJALkJAgkAzAgCAgIlcwkAzAgCAhBhZG1pbkFkZHJlc3NMaXN0BQNuaWwFA1NFUAEOa2V5QWxsb3dlZFR4SWQACQC5CQIJAMwIAgICJXMJAMwIAgIEdHhJZAUDbmlsBQNTRVABDGdldEFkbWluVm90ZQIGcHJlZml4BWFkbWluBAd2b3RlS2V5CQEQa2V5RnVsbEFkbWluVm90ZQIFBnByZWZpeAUFYWRtaW4JAQt2YWx1ZU9yRWxzZQIJAJ8IAQUHdm90ZUtleQAAAQ1nZXRBZG1pbnNMaXN0AAQHJG1hdGNoMAkAnQgCBQR0aGlzCQETa2V5QWRtaW5BZGRyZXNzTGlzdAADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQC1CQIFAXMFA1NFUAUDbmlsAQ1pc0luQWRtaW5MaXN0AQdhZGRyZXNzCQEPY29udGFpbnNFbGVtZW50AgkBDWdldEFkbWluc0xpc3QABQdhZGRyZXNzARJnZW5Wb3Rlc0tleXNIZWxwZXICAWEMYWRtaW5BZGRyZXNzBAskdDAzNjk2MzcyMAUBYQQGcmVzdWx0CAULJHQwMzY5NjM3MjACXzEEBnByZWZpeAgFCyR0MDM2OTYzNzIwAl8yCQCUCgIJAM0IAgUGcmVzdWx0CQEQa2V5RnVsbEFkbWluVm90ZQIFBnByZWZpeAUMYWRtaW5BZGRyZXNzBQZwcmVmaXgBDGdlblZvdGVzS2V5cwEJa2V5UHJlZml4BAlhZG1pbkxpc3QJARNrZXlBZG1pbkFkZHJlc3NMaXN0AAQLJHQwMzg2NzM5NTEKAAIkbAkBDWdldEFkbWluc0xpc3QACgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlAoCBQNuaWwFCWtleVByZWZpeAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQESZ2VuVm90ZXNLZXlzSGVscGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQQGcmVzdWx0CAULJHQwMzg2NzM5NTECXzEEBnByZWZpeAgFCyR0MDM4NjczOTUxAl8yBQZyZXN1bHQBEGNvdW50Vm90ZXNIZWxwZXICBnJlc3VsdAd2b3RlS2V5CQBkAgUGcmVzdWx0CQELdmFsdWVPckVsc2UCCQCfCAEFB3ZvdGVLZXkAAAEKY291bnRWb3RlcwEGcHJlZml4BAV2b3RlcwkBDGdlblZvdGVzS2V5cwEFBnByZWZpeAoAAiRsBQV2b3RlcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEQY291bnRWb3Rlc0hlbHBlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUBEGNsZWFyVm90ZXNIZWxwZXICBnJlc3VsdANrZXkJAM0IAgUGcmVzdWx0CQELRGVsZXRlRW50cnkBBQNrZXkBE2dldENsZWFyVm90ZUVudHJpZXMBBnByZWZpeAQFdm90ZXMJAQxnZW5Wb3Rlc0tleXMBBQZwcmVmaXgKAAIkbAUFdm90ZXMKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEGNsZWFyVm90ZXNIZWxwZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDUJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAQx2b3RlSU5URVJOQUwEE2NhbGxlckFkZHJlc3NTdHJpbmcJa2V5UHJlZml4CG1pblZvdGVzCnZvdGVSZXN1bHQEB3ZvdGVLZXkJARBrZXlGdWxsQWRtaW5Wb3RlAgUJa2V5UHJlZml4BRNjYWxsZXJBZGRyZXNzU3RyaW5nBBBhZG1pbkN1cnJlbnRWb3RlCQEMZ2V0QWRtaW5Wb3RlAgUJa2V5UHJlZml4BRNjYWxsZXJBZGRyZXNzU3RyaW5nBANlcnIDCQEBIQEJAQ1pc0luQWRtaW5MaXN0AQUTY2FsbGVyQWRkcmVzc1N0cmluZwkBCHRocm93RXJyAQkArAICCQCsAgICCUFkZHJlc3M6IAUTY2FsbGVyQWRkcmVzc1N0cmluZwISIG5vdCBpbiBBZG1pbiBsaXN0AwkAAAIFEGFkbWluQ3VycmVudFZvdGUAAQkBCHRocm93RXJyAQkArAICBQd2b3RlS2V5AhIgeW91IGFscmVhZHkgdm90ZWQFBHVuaXQDCQAAAgUDZXJyBQNlcnIEBXZvdGVzCQEKY291bnRWb3RlcwEFCWtleVByZWZpeAMJAGcCCQBkAgUFdm90ZXMAAQUIbWluVm90ZXMEEGNsZWFyVm90ZUVudHJpZXMJARNnZXRDbGVhclZvdGVFbnRyaWVzAQUJa2V5UHJlZml4CQDOCAIFEGNsZWFyVm90ZUVudHJpZXMFCnZvdGVSZXN1bHQJAMwIAgkBDEludGVnZXJFbnRyeQIFB3ZvdGVLZXkAAQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuARNnZXRMZWFzaW5nTm9kZUVudHJ5Awtub2RlQWRkcmVzcw1jdXJyZW50TGVhc2VkCm5leHRMZWFzZWQEC3ZhbHVlU3RyaW5nCQC5CQIJAMwIAgIIJWQlZCVkJWQJAMwIAgkApAMBBRNjdXJyZW50UGVyaW9kSGVpZ2h0CQDMCAIJAKQDAQUNY3VycmVudExlYXNlZAkAzAgCCQCkAwEFEG5leHRQZXJpb2RIZWlnaHQJAMwIAgkApAMBBQpuZXh0TGVhc2VkBQNuaWwFA1NFUAkBC1N0cmluZ0VudHJ5AgkBEmtleUxlYXNpbmdOb2RlRGF0YQEFC25vZGVBZGRyZXNzBQt2YWx1ZVN0cmluZwESZ2V0TGVhc2luZ05vZGVEYXRhAQtub2RlQWRkcmVzcwQYbGVhc2luZ05vZGVEYXRhU3RyaW5nUmF3CQCdCAIFBHRoaXMJARJrZXlMZWFzaW5nTm9kZURhdGEBBQtub2RlQWRkcmVzcwQHJG1hdGNoMAUYbGVhc2luZ05vZGVEYXRhU3RyaW5nUmF3AwkAAQIFByRtYXRjaDACBlN0cmluZwQCZHMFByRtYXRjaDAECGRhdGFMaXN0CQC1CQIFAmRzBQNTRVAEEW5vZGVDdXJyZW50UGVyaW9kCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIZGF0YUxpc3QAAQQRbm9kZUN1cnJlbnRMZWFzZWQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhkYXRhTGlzdAACBA5ub2RlTmV4dFBlcmlvZAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGRhdGFMaXN0AAMEDm5vZGVOZXh0TGVhc2VkCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIZGF0YUxpc3QABAMDCQBmAgUObm9kZU5leHRQZXJpb2QFBmhlaWdodAYJAAACBRJwZXJpb2RPZmZzZXRIZWlnaHQA////////////AQkAlAoCBRFub2RlQ3VycmVudExlYXNlZAUObm9kZU5leHRMZWFzZWQJAJQKAgUObm9kZU5leHRMZWFzZWQFDm5vZGVOZXh0TGVhc2VkCQCUCgIAAAAAARNnZXRVc2VyTGVhc2luZ0VudHJ5BAtub2RlQWRkcmVzcwt1c2VyQWRkcmVzcxF1c2VyQ3VycmVudExlYXNlZA51c2VyTmV4dExlYXNlZAQLdmFsdWVTdHJpbmcJALkJAgkAzAgCAgglZCVkJWQlZAkAzAgCCQCkAwEFE2N1cnJlbnRQZXJpb2RIZWlnaHQJAMwIAgkApAMBBRF1c2VyQ3VycmVudExlYXNlZAkAzAgCCQCkAwEFEG5leHRQZXJpb2RIZWlnaHQJAMwIAgkApAMBBQ51c2VyTmV4dExlYXNlZAUDbmlsBQNTRVAJAQtTdHJpbmdFbnRyeQIJARZrZXlVc2VyTGVhc2luZ05vZGVEYXRhAgULdXNlckFkZHJlc3MFC25vZGVBZGRyZXNzBQt2YWx1ZVN0cmluZwESZ2V0VXNlckxlYXNpbmdEYXRhAgtub2RlQWRkcmVzcwt1c2VyQWRkcmVzcwQYbGVhc2luZ1VzZXJEYXRhU3RyaW5nUmF3CQCdCAIFBHRoaXMJARZrZXlVc2VyTGVhc2luZ05vZGVEYXRhAgULdXNlckFkZHJlc3MFC25vZGVBZGRyZXNzBAckbWF0Y2gwBRhsZWFzaW5nVXNlckRhdGFTdHJpbmdSYXcDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAJkcwUHJG1hdGNoMAQIZGF0YUxpc3QJALUJAgUCZHMFA1NFUAQRdXNlckN1cnJlbnRQZXJpb2QJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhkYXRhTGlzdAABBBF1c2VyQ3VycmVudExlYXNlZAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGRhdGFMaXN0AAIEDnVzZXJOZXh0UGVyaW9kCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIZGF0YUxpc3QAAwQOdXNlck5leHRMZWFzZWQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhkYXRhTGlzdAAEAwMJAGYCBQ51c2VyTmV4dFBlcmlvZAUGaGVpZ2h0BgkAAAIFEnBlcmlvZE9mZnNldEhlaWdodAD///////////8BCQCUCgIFEXVzZXJDdXJyZW50TGVhc2VkBQ51c2VyTmV4dExlYXNlZAkAlAoCBQ51c2VyTmV4dExlYXNlZAUOdXNlck5leHRMZWFzZWQJAJQKAgAAAAABE2dldFVzZXJUb0NsYWltRW50cnkDC3VzZXJBZGRyZXNzB3RvQ2xhaW0IdG9VbmxvY2sEC3ZhbHVlU3RyaW5nCQC5CQIJAMwIAgIIJWQlZCVkJWQJAMwIAgkApAMBBRNjdXJyZW50UGVyaW9kSGVpZ2h0CQDMCAIJAKQDAQUHdG9DbGFpbQkAzAgCCQCkAwEFEG5leHRQZXJpb2RIZWlnaHQJAMwIAgkApAMBBQh0b1VubG9jawUDbmlsBQNTRVAJAQtTdHJpbmdFbnRyeQIJAQ5rZXlVc2VyVG9DbGFpbQEFC3VzZXJBZGRyZXNzBQt2YWx1ZVN0cmluZwEVZ2V0VXNlclRvQ2xhaW1CYWxhbmNlAQt1c2VyQWRkcmVzcwQYdXNlclRvQ2xhaW1EYXRhU3RyaW5nUmF3CQCdCAIFBHRoaXMJAQ5rZXlVc2VyVG9DbGFpbQEFC3VzZXJBZGRyZXNzBAckbWF0Y2gwBRh1c2VyVG9DbGFpbURhdGFTdHJpbmdSYXcDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAJkcwUHJG1hdGNoMAQIZGF0YUxpc3QJALUJAgUCZHMFA1NFUAQNY3VycmVudFBlcmlvZAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGRhdGFMaXN0AAEEB3RvQ2xhaW0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhkYXRhTGlzdAACBApuZXh0UGVyaW9kCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIZGF0YUxpc3QAAwQIdG9VbmxvY2sJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhkYXRhTGlzdAAEAwMJAGYCBQpuZXh0UGVyaW9kBQZoZWlnaHQGCQAAAgUPY3VycmVudFBlcmlvZElkAAAJAJQKAgUHdG9DbGFpbQUIdG9VbmxvY2sJAJQKAgkAZAIFB3RvQ2xhaW0FCHRvVW5sb2NrAAAJAJQKAgAAAAABF2dldFVzZXJUb3RhbExvY2tlZEVudHJ5Agt1c2VyQWRkcmVzcw91c2VyVG90YWxMb2NrZWQJAQxJbnRlZ2VyRW50cnkCCQESa2V5VXNlclRvdGFsTG9ja2VkAQULdXNlckFkZHJlc3MFD3VzZXJUb3RhbExvY2tlZAESZ2V0VXNlclRvdGFsTG9ja2VkAQt1c2VyQWRkcmVzcwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQESa2V5VXNlclRvdGFsTG9ja2VkAQULdXNlckFkZHJlc3MAAAERZ2V0VW5zdGFrZUFjdGlvbnMDC25vZGVBZGRyZXNzC3VzZXJBZGRyZXNzDXVuc3Rha2VBbW91bnQECyR0MDg5OTE5MDY0CQESZ2V0TGVhc2luZ05vZGVEYXRhAQULbm9kZUFkZHJlc3MEEW5vZGVDdXJyZW50TGVhc2VkCAULJHQwODk5MTkwNjQCXzEEDm5vZGVOZXh0TGVhc2VkCAULJHQwODk5MTkwNjQCXzIECyR0MDkwNjk5MTU1CQESZ2V0VXNlckxlYXNpbmdEYXRhAgULbm9kZUFkZHJlc3MFC3VzZXJBZGRyZXNzBBF1c2VyQ3VycmVudExlYXNlZAgFCyR0MDkwNjk5MTU1Al8xBA51c2VyTmV4dExlYXNlZAgFCyR0MDkwNjk5MTU1Al8yBAZjaGVja3MJAMwIAgMJAQEhAQULaXNGb3JjZVN0b3AGCQEIdGhyb3dFcnIBAh1jb250cmFjdCBpcyB0ZW1wb3Jhcnkgc3RvcHBlZAkAzAgCAwkBASEBBQ5pc0ZvcmNlT3V0U3RvcAYJAQh0aHJvd0VycgECHXVuc3Rha2UgaXMgdGVtcG9yYXJ5IGRpc2FibGVkCQDMCAIDCQBmAgUNdW5zdGFrZUFtb3VudAAABgkBCHRocm93RXJyAQIndW5zdGFrZSBhbW91bnQgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiAwCQDMCAIDCQBnAgUOdXNlck5leHRMZWFzZWQFDXVuc3Rha2VBbW91bnQGCQEIdGhyb3dFcnIBAjl1bnN0YWtlIGFtb3VudCBzaG91bGQgYmUgbGVzcyBvciBlcXVhbCB1c2VyIHN0YWtlZCBhbW91bnQJAMwIAgMJAGcCBQ5ub2RlTmV4dExlYXNlZAUNdW5zdGFrZUFtb3VudAYJAQh0aHJvd0VycgECOXVuc3Rha2UgYW1vdW50IHNob3VsZCBiZSBsZXNzIG9yIGVxdWFsIG5vZGUgc3Rha2VkIGFtb3VudAkAzAgCAwkBDmlzVmFsaWRBZGRyZXNzAQULbm9kZUFkZHJlc3MGCQEIdGhyb3dFcnIBCQC5CQIJAMwIAgIabm9kZSBhZGRyZXNzIGlzIG5vdCB2YWxpZDoJAMwIAgULbm9kZUFkZHJlc3MFA25pbAIBIAkAzAgCAwkBDmlzVmFsaWRBZGRyZXNzAQULdXNlckFkZHJlc3MGCQEIdGhyb3dFcnIBCQC5CQIJAMwIAgIadXNlciBhZGRyZXNzIGlzIG5vdCB2YWxpZDoJAMwIAgULdXNlckFkZHJlc3MFA25pbAIBIAUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBBBuZXdOb2RlTmV4dExlYXNlCQBlAgUObm9kZU5leHRMZWFzZWQFDXVuc3Rha2VBbW91bnQEEW5ld1VzZXJOZXh0TGVhc2VkCQBlAgUOdXNlck5leHRMZWFzZWQFDXVuc3Rha2VBbW91bnQEDSR0MDEwMDM5MTAwOTkJARVnZXRVc2VyVG9DbGFpbUJhbGFuY2UBBQt1c2VyQWRkcmVzcwQHdG9DbGFpbQgFDSR0MDEwMDM5MTAwOTkCXzEECHRvVW5sb2NrCAUNJHQwMTAwMzkxMDA5OQJfMgQLbmV3VG9VbmxvY2sJAGQCBQh0b1VubG9jawUNdW5zdGFrZUFtb3VudAQPdXNlclRvdGFsTG9ja2VkCQESZ2V0VXNlclRvdGFsTG9ja2VkAQULdXNlckFkZHJlc3MEEm5ld1VzZXJUb3RhbExvY2tlZAkAZQIFD3VzZXJUb3RhbExvY2tlZAUNdW5zdGFrZUFtb3VudAkAzAgCCQETZ2V0TGVhc2luZ05vZGVFbnRyeQMFC25vZGVBZGRyZXNzBRFub2RlQ3VycmVudExlYXNlZAUQbmV3Tm9kZU5leHRMZWFzZQkAzAgCCQETZ2V0VXNlckxlYXNpbmdFbnRyeQQFC25vZGVBZGRyZXNzBQt1c2VyQWRkcmVzcwURdXNlckN1cnJlbnRMZWFzZWQFEW5ld1VzZXJOZXh0TGVhc2VkCQDMCAIJARNnZXRVc2VyVG9DbGFpbUVudHJ5AwULdXNlckFkZHJlc3MFB3RvQ2xhaW0FC25ld1RvVW5sb2NrCQDMCAIJARdnZXRVc2VyVG90YWxMb2NrZWRFbnRyeQIFC3VzZXJBZGRyZXNzBRJuZXdVc2VyVG90YWxMb2NrZWQJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlOb2RlTGVhc2luZ0J5SGVpZ2h0AQULbm9kZUFkZHJlc3MFEG5ld05vZGVOZXh0TGVhc2UJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlVc2VyTGVhc2luZ0J5SGVpZ2h0AgULbm9kZUFkZHJlc3MFC3VzZXJBZGRyZXNzBRFuZXdVc2VyTmV4dExlYXNlZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuARdnZXRDbGFpbVVubG9ja2VkQWN0aW9ucwILdXNlckFkZHJlc3MLY2xhaW1BbW91bnQEDSR0MDEwODI4MTA4ODgJARVnZXRVc2VyVG9DbGFpbUJhbGFuY2UBBQt1c2VyQWRkcmVzcwQHdG9DbGFpbQgFDSR0MDEwODI4MTA4ODgCXzEECHRvVW5sb2NrCAUNJHQwMTA4MjgxMDg4OAJfMgQGY2hlY2tzCQDMCAIDCQEBIQEFC2lzRm9yY2VTdG9wBgkBCHRocm93RXJyAQIdY29udHJhY3QgaXMgdGVtcG9yYXJ5IHN0b3BwZWQJAMwIAgMJAQEhAQUOaXNGb3JjZU91dFN0b3AGCQEIdGhyb3dFcnIBAhtjbGFpbSBpcyB0ZW1wb3JhcnkgZGlzYWJsZWQJAMwIAgMJAGYCBQtjbGFpbUFtb3VudAAABgkBCHRocm93RXJyAQIlY2xhaW0gYW1vdW50IHNob3VsZCBiZSBncmVhdGVyIHRoYW4gMAkAzAgCAwkAZwIFB3RvQ2xhaW0FC2NsYWltQW1vdW50BgkBCHRocm93RXJyAQI0Y2xhaW0gYW1vdW50IHNob3VsZCBiZSBsZXNzIG9yIGVxdWFsIHVubG9ja2VkIGFtb3VudAkAzAgCAwkBDmlzVmFsaWRBZGRyZXNzAQULdXNlckFkZHJlc3MGCQEIdGhyb3dFcnIBCQC5CQIJAMwIAgIadXNlciBhZGRyZXNzIGlzIG5vdCB2YWxpZDoJAMwIAgULdXNlckFkZHJlc3MFA25pbAIBIAUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBApuZXdUb0NsYWltCQBlAgUHdG9DbGFpbQULY2xhaW1BbW91bnQJAMwIAgkBE2dldFVzZXJUb0NsYWltRW50cnkDBQt1c2VyQWRkcmVzcwUKbmV3VG9DbGFpbQUIdG9VbmxvY2sJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQULdXNlckFkZHJlc3MFC2NsYWltQW1vdW50BQxhc3NldElkQnl0ZXMFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgESZ2V0U3Rha2VGb3JBY3Rpb25zAgt1c2VyQWRkcmVzcwFpBA0kdDAxMTY1MjExNzEyCQEVZ2V0VXNlclRvQ2xhaW1CYWxhbmNlAQULdXNlckFkZHJlc3MEB3RvQ2xhaW0IBQ0kdDAxMTY1MjExNzEyAl8xBAh0b1VubG9jawgFDSR0MDExNjUyMTE3MTICXzIEBmNoZWNrcwkAzAgCAwkBASEBBQtpc0ZvcmNlU3RvcAYJAQh0aHJvd0VycgECHWNvbnRyYWN0IGlzIHRlbXBvcmFyeSBzdG9wcGVkCQDMCAIDCQBnAgABCQCQAwEIBQFpCHBheW1lbnRzBgkBCHRocm93RXJyAQIRbWF4aW11bSAxIHBheW1lbnQJAMwIAgMDCQAAAgkAkAMBCAUBaQhwYXltZW50cwAABgkAAAIICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAUMYXNzZXRJZEJ5dGVzBgkBCHRocm93RXJyAQkAuQkCCQDMCAICGnBheW1lbnQgYXNzZXRJZCBzaG91bGQgYmU6CQDMCAIFDWFzc2V0SWRTdHJpbmcFA25pbAIBIAkAzAgCAwkBDmlzVmFsaWRBZGRyZXNzAQULdXNlckFkZHJlc3MGCQEIdGhyb3dFcnIBCQC5CQIJAMwIAgIadXNlciBhZGRyZXNzIGlzIG5vdCB2YWxpZDoJAMwIAgULdXNlckFkZHJlc3MFA25pbAIBIAUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzBApuZXdUb0NsYWltCQBkAgUHdG9DbGFpbQgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQJAMwIAgkBE2dldFVzZXJUb0NsYWltRW50cnkDBQt1c2VyQWRkcmVzcwUKbmV3VG9DbGFpbQUIdG9VbmxvY2sFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEPZ2V0U3Rha2VBY3Rpb25zBAtub2RlQWRkcmVzcwt1c2VyQWRkcmVzcxF1c2VyTGVhc2luZ0Ftb3VudAFpBA0kdDAxMjQ0MDEyNTAwCQEVZ2V0VXNlclRvQ2xhaW1CYWxhbmNlAQULdXNlckFkZHJlc3MEB3RvQ2xhaW0IBQ0kdDAxMjQ0MDEyNTAwAl8xBAh0b1VubG9jawgFDSR0MDEyNDQwMTI1MDACXzIEDXBheW1lbnRBbW91bnQDCQAAAgkAkAMBCAUBaQhwYXltZW50cwAAAAAICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BAlhdmFpbGFibGUJAGQCCQBkAgUIdG9VbmxvY2sFB3RvQ2xhaW0FDXBheW1lbnRBbW91bnQEBmNoZWNrcwkAzAgCAwkBASEBBQtpc0ZvcmNlU3RvcAYJAQh0aHJvd0VycgECHWNvbnRyYWN0IGlzIHRlbXBvcmFyeSBzdG9wcGVkCQDMCAIDCQBnAgABCQCQAwEIBQFpCHBheW1lbnRzBgkBCHRocm93RXJyAQIRbWF4aW11bSAxIHBheW1lbnQJAMwIAgMDCQAAAgkAkAMBCAUBaQhwYXltZW50cwAABgkAAAIICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAUMYXNzZXRJZEJ5dGVzBgkBCHRocm93RXJyAQkAuQkCCQDMCAICGnBheW1lbnQgYXNzZXRJZCBzaG91bGQgYmU6CQDMCAIFDWFzc2V0SWRTdHJpbmcFA25pbAIBIAkAzAgCAwkAZgIFEXVzZXJMZWFzaW5nQW1vdW50AAAGCQEIdGhyb3dFcnIBAh9hbW91bnQgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiAwCQDMCAIDCQBnAgUJYXZhaWxhYmxlBRF1c2VyTGVhc2luZ0Ftb3VudAYJAQh0aHJvd0VycgECO2Ftb3VudCBzaG91bGQgYmUgbGVzcyBvciBlcXVhbCAocGF5bWVudCArIGF2YWlsYWJsZSkgYW1vdW50CQDMCAIDCQBnAgURdXNlckxlYXNpbmdBbW91bnQFDXBheW1lbnRBbW91bnQGCQACAQIwYW1vdW50IHNob3VsZCBiZSBncmVhdGVyIG9yIGVxdWFsIHBheW1lbnQgYW1vdW50CQDMCAIDCQEOaXNWYWxpZEFkZHJlc3MBBQtub2RlQWRkcmVzcwYJAQh0aHJvd0VycgEJALkJAgkAzAgCAhpub2RlIGFkZHJlc3MgaXMgbm90IHZhbGlkOgkAzAgCBQtub2RlQWRkcmVzcwUDbmlsAgEgCQDMCAIDCQEOaXNWYWxpZEFkZHJlc3MBBQt1c2VyQWRkcmVzcwYJAQh0aHJvd0VycgEJALkJAgkAzAgCAhp1c2VyIGFkZHJlc3MgaXMgbm90IHZhbGlkOgkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsAgEgBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEDSR0MDEzNTcxMTM2NDQJARJnZXRMZWFzaW5nTm9kZURhdGEBBQtub2RlQWRkcmVzcwQRbm9kZUN1cnJlbnRMZWFzZWQIBQ0kdDAxMzU3MTEzNjQ0Al8xBA5ub2RlTmV4dExlYXNlZAgFDSR0MDEzNTcxMTM2NDQCXzIEEG5ld05vZGVOZXh0TGVhc2UJAGQCBQ5ub2RlTmV4dExlYXNlZAURdXNlckxlYXNpbmdBbW91bnQEDSR0MDEzNzEyMTM3OTgJARJnZXRVc2VyTGVhc2luZ0RhdGECBQtub2RlQWRkcmVzcwULdXNlckFkZHJlc3MEEXVzZXJDdXJyZW50TGVhc2VkCAUNJHQwMTM3MTIxMzc5OAJfMQQOdXNlck5leHRMZWFzZWQIBQ0kdDAxMzcxMjEzNzk4Al8yBBFuZXdVc2VyTmV4dExlYXNlZAkAZAIFDnVzZXJOZXh0TGVhc2VkBRF1c2VyTGVhc2luZ0Ftb3VudAQSZnJvbVVubG9ja2VkQW1vdW50CQBlAgURdXNlckxlYXNpbmdBbW91bnQFDXBheW1lbnRBbW91bnQEC25ld1RvVW5sb2NrCQCWAwEJAMwIAgAACQDMCAIJAGUCBQh0b1VubG9jawUSZnJvbVVubG9ja2VkQW1vdW50BQNuaWwECm5ld1RvQ2xhaW0JAJcDAQkAzAgCBQd0b0NsYWltCQDMCAIJAGQCBQd0b0NsYWltCQBlAgUIdG9VbmxvY2sFEmZyb21VbmxvY2tlZEFtb3VudAUDbmlsBA91c2VyVG90YWxMb2NrZWQJARJnZXRVc2VyVG90YWxMb2NrZWQBBQt1c2VyQWRkcmVzcwQSbmV3VXNlclRvdGFsTG9ja2VkCQBkAgUPdXNlclRvdGFsTG9ja2VkBRF1c2VyTGVhc2luZ0Ftb3VudAkAzAgCCQETZ2V0TGVhc2luZ05vZGVFbnRyeQMFC25vZGVBZGRyZXNzBRFub2RlQ3VycmVudExlYXNlZAUQbmV3Tm9kZU5leHRMZWFzZQkAzAgCCQETZ2V0VXNlckxlYXNpbmdFbnRyeQQFC25vZGVBZGRyZXNzBQt1c2VyQWRkcmVzcwURdXNlckN1cnJlbnRMZWFzZWQFEW5ld1VzZXJOZXh0TGVhc2VkCQDMCAIJARNnZXRVc2VyVG9DbGFpbUVudHJ5AwULdXNlckFkZHJlc3MFCm5ld1RvQ2xhaW0FC25ld1RvVW5sb2NrCQDMCAIJARdnZXRVc2VyVG90YWxMb2NrZWRFbnRyeQIFC3VzZXJBZGRyZXNzBRJuZXdVc2VyVG90YWxMb2NrZWQJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlOb2RlTGVhc2luZ0J5SGVpZ2h0AQULbm9kZUFkZHJlc3MFEG5ld05vZGVOZXh0TGVhc2UJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlVc2VyTGVhc2luZ0J5SGVpZ2h0AgULbm9kZUFkZHJlc3MFC3VzZXJBZGRyZXNzBRFuZXdVc2VyTmV4dExlYXNlZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuARpnZXRTdGFrZUZyb21QYXltZW50QWN0aW9ucwMLbm9kZUFkZHJlc3MLdXNlckFkZHJlc3MBaQQGY2hlY2tzCQDMCAIDCQAAAgkAkAMBCAUBaQhwYXltZW50cwABBgkBCHRocm93RXJyAQIgcGF5bWVudCBzaXplIHNob3VsZCBiZSBleGFjdGx5IDEFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwkBD2dldFN0YWtlQWN0aW9ucwQFC25vZGVBZGRyZXNzBQt1c2VyQWRkcmVzcwgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQFAWkJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BHGdldFNldE5ld1BlcmlvZExlbmd0aEFjdGlvbnMBD25ld1BlcmlvZExlbmd0aAQFY2hlY2sJAMwIAgMJAGYCBQ9uZXdQZXJpb2RMZW5ndGgAAAYJAQh0aHJvd0VycgECJnBlcmlvZCBsZW5ndGggc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiAwBQNuaWwDCQAAAgUFY2hlY2sFBWNoZWNrAwkAAAIFEnBlcmlvZE9mZnNldEhlaWdodAD///////////8BCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ9rZXlQZXJpb2RMZW5ndGgFD25ld1BlcmlvZExlbmd0aAkAzAgCCQEMSW50ZWdlckVudHJ5AgUVa2V5UGVyaW9kT2Zmc2V0SGVpZ2h0BQZoZWlnaHQFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgURa2V5UGVyaW9kT2Zmc2V0SWQJAGQCBQ9jdXJyZW50UGVyaW9kSWQAAQkAzAgCCQEMSW50ZWdlckVudHJ5AgUVa2V5UGVyaW9kT2Zmc2V0SGVpZ2h0BRBuZXh0UGVyaW9kSGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ9rZXlQZXJpb2RMZW5ndGgFD25ld1BlcmlvZExlbmd0aAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuDgFpARJzZXROZXdQZXJpb2RMZW5ndGgBD25ld1BlcmlvZExlbmd0aAQGY2hlY2tzCQDMCAIDCQENaXNJbkFkbWluTGlzdAEJAKUIAQgFAWkGY2FsbGVyBgkBCHRocm93RXJyAQIaY2FsbGVyIGlzIG5vdCBpbiBhZG1pbkxpc3QFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwkBHGdldFNldE5ld1BlcmlvZExlbmd0aEFjdGlvbnMBBQ9uZXdQZXJpb2RMZW5ndGgJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEQc2V0Rm9yY2VTdG9wRmxhZwEEc3RvcAQFY2hlY2sJAMwIAgMJAQ1pc0luQWRtaW5MaXN0AQkApQgBCAUBaQZjYWxsZXIGCQEIdGhyb3dFcnIBAhpjYWxsZXIgaXMgbm90IGluIGFkbWluTGlzdAUDbmlsAwkAAAIFBWNoZWNrBQVjaGVjawkAzAgCCQEMQm9vbGVhbkVudHJ5AgUMa2V5Rm9yY2VTdG9wBQRzdG9wBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQETc2V0Rm9yY2VPdXRTdG9wRmxhZwEEc3RvcAQFY2hlY2sJAMwIAgMJAQ1pc0luQWRtaW5MaXN0AQkApQgBCAUBaQZjYWxsZXIGCQEIdGhyb3dFcnIBAhpjYWxsZXIgaXMgbm90IGluIGFkbWluTGlzdAUDbmlsAwkAAAIFBWNoZWNrBQVjaGVjawkAzAgCCQEMQm9vbGVhbkVudHJ5AgUPa2V5Rm9yY2VPdXRTdG9wBQRzdG9wBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQETZ2V0Tm9kZURhdGFSRUFET05MWQELbm9kZUFkZHJlc3MEDSR0MDE2NDcxMTY1MzUJARJnZXRMZWFzaW5nTm9kZURhdGEBBQtub2RlQWRkcmVzcwQMY3VycmVudExlYXNlCAUNJHQwMTY0NzExNjUzNQJfMQQKbmV4dExlYXNlZAgFDSR0MDE2NDcxMTY1MzUCXzIJAJQKAgUDbmlsCQCXCgUFE2N1cnJlbnRQZXJpb2RIZWlnaHQFDGN1cnJlbnRMZWFzZQUQbmV4dFBlcmlvZEhlaWdodAUKbmV4dExlYXNlZAUGaGVpZ2h0AWkBGmdldFVzZXJMZWFzaW5nRGF0YVJFQURPTkxZAgtub2RlQWRkcmVzcwt1c2VyQWRkcmVzcwQNJHQwMTY5MDUxNjk4MgkBEmdldFVzZXJMZWFzaW5nRGF0YQIFC25vZGVBZGRyZXNzBQt1c2VyQWRkcmVzcwQMY3VycmVudExlYXNlCAUNJHQwMTY5MDUxNjk4MgJfMQQKbmV4dExlYXNlZAgFDSR0MDE2OTA1MTY5ODICXzIJAJQKAgUDbmlsCQCXCgUFE2N1cnJlbnRQZXJpb2RIZWlnaHQFDGN1cnJlbnRMZWFzZQUQbmV4dFBlcmlvZEhlaWdodAUKbmV4dExlYXNlZAUGaGVpZ2h0AWkBE2dldFVzZXJEYXRhUkVBRE9OTFkBC3VzZXJBZGRyZXNzBA0kdDAxNzM0NTE3NDA1CQEVZ2V0VXNlclRvQ2xhaW1CYWxhbmNlAQULdXNlckFkZHJlc3MEB3RvQ2xhaW0IBQ0kdDAxNzM0NTE3NDA1Al8xBAh0b1VubG9jawgFDSR0MDE3MzQ1MTc0MDUCXzIED3VzZXJUb3RhbExvY2tlZAkBEmdldFVzZXJUb3RhbExvY2tlZAEFC3VzZXJBZGRyZXNzCQCUCgIFA25pbAkAmAoGBRNjdXJyZW50UGVyaW9kSGVpZ2h0BQd0b0NsYWltBRBuZXh0UGVyaW9kSGVpZ2h0BQh0b1VubG9jawUPdXNlclRvdGFsTG9ja2VkBQZoZWlnaHQBaQEObGVhc2VCeUFkZHJlc3MCC25vZGVBZGRyZXNzC3VzZXJBZGRyZXNzCQEaZ2V0U3Rha2VGcm9tUGF5bWVudEFjdGlvbnMDBQtub2RlQWRkcmVzcwULdXNlckFkZHJlc3MFAWkBaQEFbGVhc2UBC25vZGVBZGRyZXNzBAt1c2VyQWRkcmVzcwkApQgBCAUBaQZjYWxsZXIJARpnZXRTdGFrZUZyb21QYXltZW50QWN0aW9ucwMFC25vZGVBZGRyZXNzBQt1c2VyQWRkcmVzcwUBaQFpAQ9sZWFzZUZyb21Mb2NrZWQCC25vZGVBZGRyZXNzBmFtb3VudAQLdXNlckFkZHJlc3MJAKUIAQgFAWkGY2FsbGVyCQEPZ2V0U3Rha2VBY3Rpb25zBAULbm9kZUFkZHJlc3MFC3VzZXJBZGRyZXNzBQZhbW91bnQFAWkBaQELY2FuY2VsTGVhc2UCC25vZGVBZGRyZXNzBmFtb3VudAQLdXNlckFkZHJlc3MJAKUIAQgFAWkGY2FsbGVyCQERZ2V0VW5zdGFrZUFjdGlvbnMDBQtub2RlQWRkcmVzcwULdXNlckFkZHJlc3MFBmFtb3VudAFpAQVjbGFpbQEGYW1vdW50BAt1c2VyQWRkcmVzcwkApQgBCAUBaQZjYWxsZXIJARdnZXRDbGFpbVVubG9ja2VkQWN0aW9ucwIFC3VzZXJBZGRyZXNzBQZhbW91bnQBaQEIY2xhaW1BbGwABAt1c2VyQWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEDSR0MDE4NDE5MTg0NzkJARVnZXRVc2VyVG9DbGFpbUJhbGFuY2UBBQt1c2VyQWRkcmVzcwQHdG9DbGFpbQgFDSR0MDE4NDE5MTg0NzkCXzEECHRvVW5sb2NrCAUNJHQwMTg0MTkxODQ3OQJfMgQGY2hlY2tzCQDMCAIDCQBmAgUHdG9DbGFpbQAABgkBCHRocm93RXJyAQIQbm90aGluZyB0byBjbGFpbQUDbmlsAwkAAAIFBmNoZWNrcwUGY2hlY2tzCQEXZ2V0Q2xhaW1VbmxvY2tlZEFjdGlvbnMCBQt1c2VyQWRkcmVzcwUHdG9DbGFpbQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQhzdGFrZUZvcgELdXNlckFkZHJlc3MJARJnZXRTdGFrZUZvckFjdGlvbnMCBQt1c2VyQWRkcmVzcwUBaQFpAQt2b3RlRm9yVHhJZAEEdHhJZAQTY2FsbGVyQWRkcmVzc1N0cmluZwkA2AQBCAgFAWkGY2FsbGVyBWJ5dGVzBAlrZXlQcmVmaXgJARhrZXlBbGxvd2VkVHhJZFZvdGVQcmVmaXgBBQR0eElkBAZyZXN1bHQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBDmtleUFsbG93ZWRUeElkAAUEdHhJZAUDbmlsBBFhbGxvd2VkVHhJZE9wdGlvbgkAnQgCBQR0aGlzCQEOa2V5QWxsb3dlZFR4SWQABANlcnIJAMwIAgMJAAACCQDIAQEJANkEAQUEdHhJZAURVFhJRF9CWVRFU19MRU5HVEgGCQEIdGhyb3dFcnIBCQCsAgIFBHR4SWQCEiBpcyBub3QgdmFsaWQgdHhJZAkAzAgCAwMJAAACBRFhbGxvd2VkVHhJZE9wdGlvbgUEdW5pdAYJAQIhPQIJAQV2YWx1ZQEFEWFsbG93ZWRUeElkT3B0aW9uBQR0eElkBgkBCHRocm93RXJyAQkArAICBQR0eElkAhMgaXMgYWxyZWFkeSBhbGxvd2VkBQNuaWwDCQAAAgUDZXJyBQNlcnIJAQx2b3RlSU5URVJOQUwEBRNjYWxsZXJBZGRyZXNzU3RyaW5nBQlrZXlQcmVmaXgFBlFVT1JVTQUGcmVzdWx0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJ0eAEGdmVyaWZ5AAQIYnlBZG1pbnMJAAACCAUCdHgCaWQJANkEAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQEOa2V5QWxsb3dlZFR4SWQAAgAEB2J5T3duZXIDCQBnAgkAkAMBCQENZ2V0QWRtaW5zTGlzdAAFBlFVT1JVTQcJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAIBQJ0eA9zZW5kZXJQdWJsaWNLZXkDBQhieUFkbWlucwYFB2J5T3duZXLY8Lxb", "chainId": 84, "height": 3319324, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 2aHiTM93eoXBAJnpwC9aJS21Cd9ADmT53cs6neZdKAT7 Next: 24A1mSKMLAyoGHWK9aRJsRp8HChXJF9GBtsXyxM61QGr Diff:
OldNewDifferences
1111 let keyAssetId = makeString(["%s", "assetId"], SEP)
1212
1313 let keyForceStop = makeString(["%s", "forceStop"], SEP)
14+
15+let keyForceOutStop = makeString(["%s", "forceOutStop"], SEP)
1416
1517 let keyPeriodOffsetId = makeString(["%s", "offsetId"], SEP)
1618
8284
8385 let isForceStop = valueOrElse(getBoolean(this, keyForceStop), false)
8486
87+let isForceOutStop = valueOrElse(getBoolean(this, keyForceOutStop), false)
88+
8589 func isValidAddress (address) = match addressFromString(address) {
8690 case a: Address =>
8791 true
126130
127131
128132 func genVotesKeysHelper (a,adminAddress) = {
129- let $t035623586 = a
130- let result = $t035623586._1
131- let prefix = $t035623586._2
133+ let $t036963720 = a
134+ let result = $t036963720._1
135+ let prefix = $t036963720._2
132136 $Tuple2((result :+ keyFullAdminVote(prefix, adminAddress)), prefix)
133137 }
134138
135139
136140 func genVotesKeys (keyPrefix) = {
137141 let adminList = keyAdminAddressList()
138- let $t037333817 = {
142+ let $t038673951 = {
139143 let $l = getAdminsList()
140144 let $s = size($l)
141145 let $acc0 = $Tuple2(nil, keyPrefix)
149153
150154 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
151155 }
152- let result = $t037333817._1
153- let prefix = $t037333817._2
156+ let result = $t038673951._1
157+ let prefix = $t038673951._2
154158 result
155159 }
156160
302306
303307
304308 func getUnstakeActions (nodeAddress,userAddress,unstakeAmount) = {
305- let $t088578930 = getLeasingNodeData(nodeAddress)
306- let nodeCurrentLeased = $t088578930._1
307- let nodeNextLeased = $t088578930._2
308- let $t089359021 = getUserLeasingData(nodeAddress, userAddress)
309- let userCurrentLeased = $t089359021._1
310- let userNextLeased = $t089359021._2
309+ let $t089919064 = getLeasingNodeData(nodeAddress)
310+ let nodeCurrentLeased = $t089919064._1
311+ let nodeNextLeased = $t089919064._2
312+ let $t090699155 = getUserLeasingData(nodeAddress, userAddress)
313+ let userCurrentLeased = $t090699155._1
314+ let userNextLeased = $t090699155._2
311315 let checks = [if (!(isForceStop))
312316 then true
313- else throwErr("contract is temporary stopped"), if ((unstakeAmount > 0))
317+ else throwErr("contract is temporary stopped"), if (!(isForceOutStop))
318+ then true
319+ else throwErr("unstake is temporary disabled"), if ((unstakeAmount > 0))
314320 then true
315321 else throwErr("unstake amount should be greater than 0"), if ((userNextLeased >= unstakeAmount))
316322 then true
325331 then {
326332 let newNodeNextLease = (nodeNextLeased - unstakeAmount)
327333 let newUserNextLeased = (userNextLeased - unstakeAmount)
328- let $t098349894 = getUserToClaimBalance(userAddress)
329- let toClaim = $t098349894._1
330- let toUnlock = $t098349894._2
334+ let $t01003910099 = getUserToClaimBalance(userAddress)
335+ let toClaim = $t01003910099._1
336+ let toUnlock = $t01003910099._2
331337 let newToUnlock = (toUnlock + unstakeAmount)
332338 let userTotalLocked = getUserTotalLocked(userAddress)
333339 let newUserTotalLocked = (userTotalLocked - unstakeAmount)
338344
339345
340346 func getClaimUnlockedActions (userAddress,claimAmount) = {
341- let $t01062310683 = getUserToClaimBalance(userAddress)
342- let toClaim = $t01062310683._1
343- let toUnlock = $t01062310683._2
347+ let $t01082810888 = getUserToClaimBalance(userAddress)
348+ let toClaim = $t01082810888._1
349+ let toUnlock = $t01082810888._2
344350 let checks = [if (!(isForceStop))
345351 then true
346- else throwErr("contract is temporary stopped"), if ((claimAmount > 0))
352+ else throwErr("contract is temporary stopped"), if (!(isForceOutStop))
353+ then true
354+ else throwErr("claim is temporary disabled"), if ((claimAmount > 0))
347355 then true
348356 else throwErr("claim amount should be greater than 0"), if ((toClaim >= claimAmount))
349357 then true
359367 }
360368
361369
370+func getStakeForActions (userAddress,i) = {
371+ let $t01165211712 = getUserToClaimBalance(userAddress)
372+ let toClaim = $t01165211712._1
373+ let toUnlock = $t01165211712._2
374+ let checks = [if (!(isForceStop))
375+ then true
376+ else throwErr("contract is temporary stopped"), if ((1 >= size(i.payments)))
377+ then true
378+ else throwErr("maximum 1 payment"), if (if ((size(i.payments) == 0))
379+ then true
380+ else (i.payments[0].assetId == assetIdBytes))
381+ then true
382+ else throwErr(makeString(["payment assetId should be:", assetIdString], " ")), if (isValidAddress(userAddress))
383+ then true
384+ else throwErr(makeString(["user address is not valid:", userAddress], " "))]
385+ if ((checks == checks))
386+ then {
387+ let newToClaim = (toClaim + i.payments[0].amount)
388+[getUserToClaimEntry(userAddress, newToClaim, toUnlock)]
389+ }
390+ else throw("Strict value is not equal to itself.")
391+ }
392+
393+
362394 func getStakeActions (nodeAddress,userAddress,userLeasingAmount,i) = {
363- let $t01144411504 = getUserToClaimBalance(userAddress)
364- let toClaim = $t01144411504._1
365- let toUnlock = $t01144411504._2
395+ let $t01244012500 = getUserToClaimBalance(userAddress)
396+ let toClaim = $t01244012500._1
397+ let toUnlock = $t01244012500._2
366398 let paymentAmount = if ((size(i.payments) == 0))
367399 then 0
368400 else i.payments[0].amount
388420 else throwErr(makeString(["user address is not valid:", userAddress], " "))]
389421 if ((checks == checks))
390422 then {
391- let $t01257512648 = getLeasingNodeData(nodeAddress)
392- let nodeCurrentLeased = $t01257512648._1
393- let nodeNextLeased = $t01257512648._2
423+ let $t01357113644 = getLeasingNodeData(nodeAddress)
424+ let nodeCurrentLeased = $t01357113644._1
425+ let nodeNextLeased = $t01357113644._2
394426 let newNodeNextLease = (nodeNextLeased + userLeasingAmount)
395- let $t01271612802 = getUserLeasingData(nodeAddress, userAddress)
396- let userCurrentLeased = $t01271612802._1
397- let userNextLeased = $t01271612802._2
427+ let $t01371213798 = getUserLeasingData(nodeAddress, userAddress)
428+ let userCurrentLeased = $t01371213798._1
429+ let userNextLeased = $t01371213798._2
398430 let newUserNextLeased = (userNextLeased + userLeasingAmount)
399431 let fromUnlockedAmount = (userLeasingAmount - paymentAmount)
400432 let newToUnlock = max([0, (toUnlock - fromUnlockedAmount)])
454486
455487
456488 @Callable(i)
489+func setForceOutStopFlag (stop) = {
490+ let check = [if (isInAdminList(toString(i.caller)))
491+ then true
492+ else throwErr("caller is not in adminList")]
493+ if ((check == check))
494+ then [BooleanEntry(keyForceOutStop, stop)]
495+ else throw("Strict value is not equal to itself.")
496+ }
497+
498+
499+
500+@Callable(i)
457501 func getNodeDataREADONLY (nodeAddress) = {
458- let $t01524515309 = getLeasingNodeData(nodeAddress)
459- let currentLease = $t01524515309._1
460- let nextLeased = $t01524515309._2
502+ let $t01647116535 = getLeasingNodeData(nodeAddress)
503+ let currentLease = $t01647116535._1
504+ let nextLeased = $t01647116535._2
461505 $Tuple2(nil, $Tuple5(currentPeriodHeight, currentLease, nextPeriodHeight, nextLeased, height))
462506 }
463507
465509
466510 @Callable(i)
467511 func getUserLeasingDataREADONLY (nodeAddress,userAddress) = {
468- let $t01567915756 = getUserLeasingData(nodeAddress, userAddress)
469- let currentLease = $t01567915756._1
470- let nextLeased = $t01567915756._2
512+ let $t01690516982 = getUserLeasingData(nodeAddress, userAddress)
513+ let currentLease = $t01690516982._1
514+ let nextLeased = $t01690516982._2
471515 $Tuple2(nil, $Tuple5(currentPeriodHeight, currentLease, nextPeriodHeight, nextLeased, height))
472516 }
473517
475519
476520 @Callable(i)
477521 func getUserDataREADONLY (userAddress) = {
478- let $t01611916179 = getUserToClaimBalance(userAddress)
479- let toClaim = $t01611916179._1
480- let toUnlock = $t01611916179._2
522+ let $t01734517405 = getUserToClaimBalance(userAddress)
523+ let toClaim = $t01734517405._1
524+ let toUnlock = $t01734517405._2
481525 let userTotalLocked = getUserTotalLocked(userAddress)
482526 $Tuple2(nil, $Tuple6(currentPeriodHeight, toClaim, nextPeriodHeight, toUnlock, userTotalLocked, height))
483527 }
524568 @Callable(i)
525569 func claimAll () = {
526570 let userAddress = toString(i.caller)
527- let $t01719317253 = getUserToClaimBalance(userAddress)
528- let toClaim = $t01719317253._1
529- let toUnlock = $t01719317253._2
571+ let $t01841918479 = getUserToClaimBalance(userAddress)
572+ let toClaim = $t01841918479._1
573+ let toUnlock = $t01841918479._2
530574 let checks = [if ((toClaim > 0))
531575 then true
532576 else throwErr("nothing to claim")]
534578 then getClaimUnlockedActions(userAddress, toClaim)
535579 else throw("Strict value is not equal to itself.")
536580 }
581+
582+
583+
584+@Callable(i)
585+func stakeFor (userAddress) = getStakeForActions(userAddress, i)
537586
538587
539588
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let contractFile = "l2mp_leasing.ride"
55
66 let SEP = "__"
77
88 func throwErr (msg) = throw(((contractFile + ": ") + msg))
99
1010
1111 let keyAssetId = makeString(["%s", "assetId"], SEP)
1212
1313 let keyForceStop = makeString(["%s", "forceStop"], SEP)
14+
15+let keyForceOutStop = makeString(["%s", "forceOutStop"], SEP)
1416
1517 let keyPeriodOffsetId = makeString(["%s", "offsetId"], SEP)
1618
1719 let keyPeriodOffsetHeight = makeString(["%s", "offsetHeight"], SEP)
1820
1921 let keyPeriodLength = makeString(["%s", "periodLength"], SEP)
2022
2123 let periodOffsetId = valueOrElse(getInteger(this, keyPeriodOffsetId), 0)
2224
2325 let periodLength = valueOrElse(getInteger(this, keyPeriodLength), 10000)
2426
2527 let periodOffsetHeight = valueOrElse(getInteger(this, keyPeriodOffsetHeight), -1)
2628
2729 let currentPeriodId = if (if ((height > periodOffsetHeight))
2830 then (periodOffsetHeight != -1)
2931 else false)
3032 then (((height - periodOffsetHeight) / periodLength) + periodOffsetId)
3133 else max([0, (periodOffsetId - 1)])
3234
3335 let currentPeriodHeight = if (if ((periodOffsetHeight == -1))
3436 then true
3537 else if ((currentPeriodId == 0))
3638 then (periodOffsetHeight > height)
3739 else false)
3840 then 0
3941 else (periodOffsetHeight + ((currentPeriodId - periodOffsetId) * periodLength))
4042
4143 let nextPeriodHeight = if (if ((periodOffsetHeight == -1))
4244 then true
4345 else if ((currentPeriodId == 0))
4446 then (periodOffsetHeight > height)
4547 else false)
4648 then 0
4749 else (currentPeriodHeight + periodLength)
4850
4951 func keyLeasingNodeData (nodeAddress) = makeString(["%s", nodeAddress], SEP)
5052
5153
5254 func keyUserLeasingNodeData (userAddress,nodeAddress) = makeString(["%s%s", nodeAddress, userAddress], SEP)
5355
5456
5557 func keyUserToClaim (userAddress) = makeString(["%s%s", "toClaim", userAddress], SEP)
5658
5759
5860 func keyUserTotalLocked (userAddress) = makeString(["%s%s", "userTotalLocked", userAddress], SEP)
5961
6062
6163 func keyNodeLeasingByHeight (nodeAddress) = {
6264 let h = if ((periodOffsetHeight == -1))
6365 then 0
6466 else height
6567 makeString(["%s%d", nodeAddress, toString(h)], SEP)
6668 }
6769
6870
6971 func keyUserLeasingByHeight (nodeAddress,userAddress) = {
7072 let h = if ((periodOffsetHeight == -1))
7173 then 0
7274 else height
7375 makeString(["%s%s%d", nodeAddress, userAddress, toString(h)], SEP)
7476 }
7577
7678
7779 let assetIdString = valueOrElse(getString(this, keyAssetId), "WAVES")
7880
7981 let assetIdBytes = if ((assetIdString == "WAVES"))
8082 then unit
8183 else fromBase58String(assetIdString)
8284
8385 let isForceStop = valueOrElse(getBoolean(this, keyForceStop), false)
8486
87+let isForceOutStop = valueOrElse(getBoolean(this, keyForceOutStop), false)
88+
8589 func isValidAddress (address) = match addressFromString(address) {
8690 case a: Address =>
8791 true
8892 case _ =>
8993 false
9094 }
9195
9296
9397 let ADMIN_LIST_SIZE = 5
9498
9599 let QUORUM = 3
96100
97101 let TXID_BYTES_LENGTH = 32
98102
99103 func keyAllowedTxIdVotePrefix (txId) = makeString(["%s%s%s", "allowTxId", txId], SEP)
100104
101105
102106 func keyFullAdminVote (prefix,adminAddress) = makeString([prefix, adminAddress], SEP)
103107
104108
105109 func keyAdminAddressList () = makeString(["%s", "adminAddressList"], SEP)
106110
107111
108112 func keyAllowedTxId () = makeString(["%s", "txId"], SEP)
109113
110114
111115 func getAdminVote (prefix,admin) = {
112116 let voteKey = keyFullAdminVote(prefix, admin)
113117 valueOrElse(getInteger(voteKey), 0)
114118 }
115119
116120
117121 func getAdminsList () = match getString(this, keyAdminAddressList()) {
118122 case s: String =>
119123 split(s, SEP)
120124 case _ =>
121125 nil
122126 }
123127
124128
125129 func isInAdminList (address) = containsElement(getAdminsList(), address)
126130
127131
128132 func genVotesKeysHelper (a,adminAddress) = {
129- let $t035623586 = a
130- let result = $t035623586._1
131- let prefix = $t035623586._2
133+ let $t036963720 = a
134+ let result = $t036963720._1
135+ let prefix = $t036963720._2
132136 $Tuple2((result :+ keyFullAdminVote(prefix, adminAddress)), prefix)
133137 }
134138
135139
136140 func genVotesKeys (keyPrefix) = {
137141 let adminList = keyAdminAddressList()
138- let $t037333817 = {
142+ let $t038673951 = {
139143 let $l = getAdminsList()
140144 let $s = size($l)
141145 let $acc0 = $Tuple2(nil, keyPrefix)
142146 func $f0_1 ($a,$i) = if (($i >= $s))
143147 then $a
144148 else genVotesKeysHelper($a, $l[$i])
145149
146150 func $f0_2 ($a,$i) = if (($i >= $s))
147151 then $a
148152 else throw("List size exceeds 5")
149153
150154 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
151155 }
152- let result = $t037333817._1
153- let prefix = $t037333817._2
156+ let result = $t038673951._1
157+ let prefix = $t038673951._2
154158 result
155159 }
156160
157161
158162 func countVotesHelper (result,voteKey) = (result + valueOrElse(getInteger(voteKey), 0))
159163
160164
161165 func countVotes (prefix) = {
162166 let votes = genVotesKeys(prefix)
163167 let $l = votes
164168 let $s = size($l)
165169 let $acc0 = 0
166170 func $f0_1 ($a,$i) = if (($i >= $s))
167171 then $a
168172 else countVotesHelper($a, $l[$i])
169173
170174 func $f0_2 ($a,$i) = if (($i >= $s))
171175 then $a
172176 else throw("List size exceeds 5")
173177
174178 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
175179 }
176180
177181
178182 func clearVotesHelper (result,key) = (result :+ DeleteEntry(key))
179183
180184
181185 func getClearVoteEntries (prefix) = {
182186 let votes = genVotesKeys(prefix)
183187 let $l = votes
184188 let $s = size($l)
185189 let $acc0 = nil
186190 func $f0_1 ($a,$i) = if (($i >= $s))
187191 then $a
188192 else clearVotesHelper($a, $l[$i])
189193
190194 func $f0_2 ($a,$i) = if (($i >= $s))
191195 then $a
192196 else throw("List size exceeds 5")
193197
194198 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
195199 }
196200
197201
198202 func voteINTERNAL (callerAddressString,keyPrefix,minVotes,voteResult) = {
199203 let voteKey = keyFullAdminVote(keyPrefix, callerAddressString)
200204 let adminCurrentVote = getAdminVote(keyPrefix, callerAddressString)
201205 let err = if (!(isInAdminList(callerAddressString)))
202206 then throwErr((("Address: " + callerAddressString) + " not in Admin list"))
203207 else if ((adminCurrentVote == 1))
204208 then throwErr((voteKey + " you already voted"))
205209 else unit
206210 if ((err == err))
207211 then {
208212 let votes = countVotes(keyPrefix)
209213 if (((votes + 1) >= minVotes))
210214 then {
211215 let clearVoteEntries = getClearVoteEntries(keyPrefix)
212216 (clearVoteEntries ++ voteResult)
213217 }
214218 else [IntegerEntry(voteKey, 1)]
215219 }
216220 else throw("Strict value is not equal to itself.")
217221 }
218222
219223
220224 func getLeasingNodeEntry (nodeAddress,currentLeased,nextLeased) = {
221225 let valueString = makeString(["%d%d%d%d", toString(currentPeriodHeight), toString(currentLeased), toString(nextPeriodHeight), toString(nextLeased)], SEP)
222226 StringEntry(keyLeasingNodeData(nodeAddress), valueString)
223227 }
224228
225229
226230 func getLeasingNodeData (nodeAddress) = {
227231 let leasingNodeDataStringRaw = getString(this, keyLeasingNodeData(nodeAddress))
228232 match leasingNodeDataStringRaw {
229233 case ds: String =>
230234 let dataList = split(ds, SEP)
231235 let nodeCurrentPeriod = parseIntValue(dataList[1])
232236 let nodeCurrentLeased = parseIntValue(dataList[2])
233237 let nodeNextPeriod = parseIntValue(dataList[3])
234238 let nodeNextLeased = parseIntValue(dataList[4])
235239 if (if ((nodeNextPeriod > height))
236240 then true
237241 else (periodOffsetHeight == -1))
238242 then $Tuple2(nodeCurrentLeased, nodeNextLeased)
239243 else $Tuple2(nodeNextLeased, nodeNextLeased)
240244 case _ =>
241245 $Tuple2(0, 0)
242246 }
243247 }
244248
245249
246250 func getUserLeasingEntry (nodeAddress,userAddress,userCurrentLeased,userNextLeased) = {
247251 let valueString = makeString(["%d%d%d%d", toString(currentPeriodHeight), toString(userCurrentLeased), toString(nextPeriodHeight), toString(userNextLeased)], SEP)
248252 StringEntry(keyUserLeasingNodeData(userAddress, nodeAddress), valueString)
249253 }
250254
251255
252256 func getUserLeasingData (nodeAddress,userAddress) = {
253257 let leasingUserDataStringRaw = getString(this, keyUserLeasingNodeData(userAddress, nodeAddress))
254258 match leasingUserDataStringRaw {
255259 case ds: String =>
256260 let dataList = split(ds, SEP)
257261 let userCurrentPeriod = parseIntValue(dataList[1])
258262 let userCurrentLeased = parseIntValue(dataList[2])
259263 let userNextPeriod = parseIntValue(dataList[3])
260264 let userNextLeased = parseIntValue(dataList[4])
261265 if (if ((userNextPeriod > height))
262266 then true
263267 else (periodOffsetHeight == -1))
264268 then $Tuple2(userCurrentLeased, userNextLeased)
265269 else $Tuple2(userNextLeased, userNextLeased)
266270 case _ =>
267271 $Tuple2(0, 0)
268272 }
269273 }
270274
271275
272276 func getUserToClaimEntry (userAddress,toClaim,toUnlock) = {
273277 let valueString = makeString(["%d%d%d%d", toString(currentPeriodHeight), toString(toClaim), toString(nextPeriodHeight), toString(toUnlock)], SEP)
274278 StringEntry(keyUserToClaim(userAddress), valueString)
275279 }
276280
277281
278282 func getUserToClaimBalance (userAddress) = {
279283 let userToClaimDataStringRaw = getString(this, keyUserToClaim(userAddress))
280284 match userToClaimDataStringRaw {
281285 case ds: String =>
282286 let dataList = split(ds, SEP)
283287 let currentPeriod = parseIntValue(dataList[1])
284288 let toClaim = parseIntValue(dataList[2])
285289 let nextPeriod = parseIntValue(dataList[3])
286290 let toUnlock = parseIntValue(dataList[4])
287291 if (if ((nextPeriod > height))
288292 then true
289293 else (currentPeriodId == 0))
290294 then $Tuple2(toClaim, toUnlock)
291295 else $Tuple2((toClaim + toUnlock), 0)
292296 case _ =>
293297 $Tuple2(0, 0)
294298 }
295299 }
296300
297301
298302 func getUserTotalLockedEntry (userAddress,userTotalLocked) = IntegerEntry(keyUserTotalLocked(userAddress), userTotalLocked)
299303
300304
301305 func getUserTotalLocked (userAddress) = valueOrElse(getInteger(this, keyUserTotalLocked(userAddress)), 0)
302306
303307
304308 func getUnstakeActions (nodeAddress,userAddress,unstakeAmount) = {
305- let $t088578930 = getLeasingNodeData(nodeAddress)
306- let nodeCurrentLeased = $t088578930._1
307- let nodeNextLeased = $t088578930._2
308- let $t089359021 = getUserLeasingData(nodeAddress, userAddress)
309- let userCurrentLeased = $t089359021._1
310- let userNextLeased = $t089359021._2
309+ let $t089919064 = getLeasingNodeData(nodeAddress)
310+ let nodeCurrentLeased = $t089919064._1
311+ let nodeNextLeased = $t089919064._2
312+ let $t090699155 = getUserLeasingData(nodeAddress, userAddress)
313+ let userCurrentLeased = $t090699155._1
314+ let userNextLeased = $t090699155._2
311315 let checks = [if (!(isForceStop))
312316 then true
313- else throwErr("contract is temporary stopped"), if ((unstakeAmount > 0))
317+ else throwErr("contract is temporary stopped"), if (!(isForceOutStop))
318+ then true
319+ else throwErr("unstake is temporary disabled"), if ((unstakeAmount > 0))
314320 then true
315321 else throwErr("unstake amount should be greater than 0"), if ((userNextLeased >= unstakeAmount))
316322 then true
317323 else throwErr("unstake amount should be less or equal user staked amount"), if ((nodeNextLeased >= unstakeAmount))
318324 then true
319325 else throwErr("unstake amount should be less or equal node staked amount"), if (isValidAddress(nodeAddress))
320326 then true
321327 else throwErr(makeString(["node address is not valid:", nodeAddress], " ")), if (isValidAddress(userAddress))
322328 then true
323329 else throwErr(makeString(["user address is not valid:", userAddress], " "))]
324330 if ((checks == checks))
325331 then {
326332 let newNodeNextLease = (nodeNextLeased - unstakeAmount)
327333 let newUserNextLeased = (userNextLeased - unstakeAmount)
328- let $t098349894 = getUserToClaimBalance(userAddress)
329- let toClaim = $t098349894._1
330- let toUnlock = $t098349894._2
334+ let $t01003910099 = getUserToClaimBalance(userAddress)
335+ let toClaim = $t01003910099._1
336+ let toUnlock = $t01003910099._2
331337 let newToUnlock = (toUnlock + unstakeAmount)
332338 let userTotalLocked = getUserTotalLocked(userAddress)
333339 let newUserTotalLocked = (userTotalLocked - unstakeAmount)
334340 [getLeasingNodeEntry(nodeAddress, nodeCurrentLeased, newNodeNextLease), getUserLeasingEntry(nodeAddress, userAddress, userCurrentLeased, newUserNextLeased), getUserToClaimEntry(userAddress, toClaim, newToUnlock), getUserTotalLockedEntry(userAddress, newUserTotalLocked), IntegerEntry(keyNodeLeasingByHeight(nodeAddress), newNodeNextLease), IntegerEntry(keyUserLeasingByHeight(nodeAddress, userAddress), newUserNextLeased)]
335341 }
336342 else throw("Strict value is not equal to itself.")
337343 }
338344
339345
340346 func getClaimUnlockedActions (userAddress,claimAmount) = {
341- let $t01062310683 = getUserToClaimBalance(userAddress)
342- let toClaim = $t01062310683._1
343- let toUnlock = $t01062310683._2
347+ let $t01082810888 = getUserToClaimBalance(userAddress)
348+ let toClaim = $t01082810888._1
349+ let toUnlock = $t01082810888._2
344350 let checks = [if (!(isForceStop))
345351 then true
346- else throwErr("contract is temporary stopped"), if ((claimAmount > 0))
352+ else throwErr("contract is temporary stopped"), if (!(isForceOutStop))
353+ then true
354+ else throwErr("claim is temporary disabled"), if ((claimAmount > 0))
347355 then true
348356 else throwErr("claim amount should be greater than 0"), if ((toClaim >= claimAmount))
349357 then true
350358 else throwErr("claim amount should be less or equal unlocked amount"), if (isValidAddress(userAddress))
351359 then true
352360 else throwErr(makeString(["user address is not valid:", userAddress], " "))]
353361 if ((checks == checks))
354362 then {
355363 let newToClaim = (toClaim - claimAmount)
356364 [getUserToClaimEntry(userAddress, newToClaim, toUnlock), ScriptTransfer(addressFromStringValue(userAddress), claimAmount, assetIdBytes)]
357365 }
358366 else throw("Strict value is not equal to itself.")
359367 }
360368
361369
370+func getStakeForActions (userAddress,i) = {
371+ let $t01165211712 = getUserToClaimBalance(userAddress)
372+ let toClaim = $t01165211712._1
373+ let toUnlock = $t01165211712._2
374+ let checks = [if (!(isForceStop))
375+ then true
376+ else throwErr("contract is temporary stopped"), if ((1 >= size(i.payments)))
377+ then true
378+ else throwErr("maximum 1 payment"), if (if ((size(i.payments) == 0))
379+ then true
380+ else (i.payments[0].assetId == assetIdBytes))
381+ then true
382+ else throwErr(makeString(["payment assetId should be:", assetIdString], " ")), if (isValidAddress(userAddress))
383+ then true
384+ else throwErr(makeString(["user address is not valid:", userAddress], " "))]
385+ if ((checks == checks))
386+ then {
387+ let newToClaim = (toClaim + i.payments[0].amount)
388+[getUserToClaimEntry(userAddress, newToClaim, toUnlock)]
389+ }
390+ else throw("Strict value is not equal to itself.")
391+ }
392+
393+
362394 func getStakeActions (nodeAddress,userAddress,userLeasingAmount,i) = {
363- let $t01144411504 = getUserToClaimBalance(userAddress)
364- let toClaim = $t01144411504._1
365- let toUnlock = $t01144411504._2
395+ let $t01244012500 = getUserToClaimBalance(userAddress)
396+ let toClaim = $t01244012500._1
397+ let toUnlock = $t01244012500._2
366398 let paymentAmount = if ((size(i.payments) == 0))
367399 then 0
368400 else i.payments[0].amount
369401 let available = ((toUnlock + toClaim) + paymentAmount)
370402 let checks = [if (!(isForceStop))
371403 then true
372404 else throwErr("contract is temporary stopped"), if ((1 >= size(i.payments)))
373405 then true
374406 else throwErr("maximum 1 payment"), if (if ((size(i.payments) == 0))
375407 then true
376408 else (i.payments[0].assetId == assetIdBytes))
377409 then true
378410 else throwErr(makeString(["payment assetId should be:", assetIdString], " ")), if ((userLeasingAmount > 0))
379411 then true
380412 else throwErr("amount should be greater than 0"), if ((available >= userLeasingAmount))
381413 then true
382414 else throwErr("amount should be less or equal (payment + available) amount"), if ((userLeasingAmount >= paymentAmount))
383415 then true
384416 else throw("amount should be greater or equal payment amount"), if (isValidAddress(nodeAddress))
385417 then true
386418 else throwErr(makeString(["node address is not valid:", nodeAddress], " ")), if (isValidAddress(userAddress))
387419 then true
388420 else throwErr(makeString(["user address is not valid:", userAddress], " "))]
389421 if ((checks == checks))
390422 then {
391- let $t01257512648 = getLeasingNodeData(nodeAddress)
392- let nodeCurrentLeased = $t01257512648._1
393- let nodeNextLeased = $t01257512648._2
423+ let $t01357113644 = getLeasingNodeData(nodeAddress)
424+ let nodeCurrentLeased = $t01357113644._1
425+ let nodeNextLeased = $t01357113644._2
394426 let newNodeNextLease = (nodeNextLeased + userLeasingAmount)
395- let $t01271612802 = getUserLeasingData(nodeAddress, userAddress)
396- let userCurrentLeased = $t01271612802._1
397- let userNextLeased = $t01271612802._2
427+ let $t01371213798 = getUserLeasingData(nodeAddress, userAddress)
428+ let userCurrentLeased = $t01371213798._1
429+ let userNextLeased = $t01371213798._2
398430 let newUserNextLeased = (userNextLeased + userLeasingAmount)
399431 let fromUnlockedAmount = (userLeasingAmount - paymentAmount)
400432 let newToUnlock = max([0, (toUnlock - fromUnlockedAmount)])
401433 let newToClaim = min([toClaim, (toClaim + (toUnlock - fromUnlockedAmount))])
402434 let userTotalLocked = getUserTotalLocked(userAddress)
403435 let newUserTotalLocked = (userTotalLocked + userLeasingAmount)
404436 [getLeasingNodeEntry(nodeAddress, nodeCurrentLeased, newNodeNextLease), getUserLeasingEntry(nodeAddress, userAddress, userCurrentLeased, newUserNextLeased), getUserToClaimEntry(userAddress, newToClaim, newToUnlock), getUserTotalLockedEntry(userAddress, newUserTotalLocked), IntegerEntry(keyNodeLeasingByHeight(nodeAddress), newNodeNextLease), IntegerEntry(keyUserLeasingByHeight(nodeAddress, userAddress), newUserNextLeased)]
405437 }
406438 else throw("Strict value is not equal to itself.")
407439 }
408440
409441
410442 func getStakeFromPaymentActions (nodeAddress,userAddress,i) = {
411443 let checks = [if ((size(i.payments) == 1))
412444 then true
413445 else throwErr("payment size should be exactly 1")]
414446 if ((checks == checks))
415447 then getStakeActions(nodeAddress, userAddress, i.payments[0].amount, i)
416448 else throw("Strict value is not equal to itself.")
417449 }
418450
419451
420452 func getSetNewPeriodLengthActions (newPeriodLength) = {
421453 let check = [if ((newPeriodLength > 0))
422454 then true
423455 else throwErr("period length should be greater than 0")]
424456 if ((check == check))
425457 then if ((periodOffsetHeight == -1))
426458 then [IntegerEntry(keyPeriodLength, newPeriodLength), IntegerEntry(keyPeriodOffsetHeight, height)]
427459 else [IntegerEntry(keyPeriodOffsetId, (currentPeriodId + 1)), IntegerEntry(keyPeriodOffsetHeight, nextPeriodHeight), IntegerEntry(keyPeriodLength, newPeriodLength)]
428460 else throw("Strict value is not equal to itself.")
429461 }
430462
431463
432464 @Callable(i)
433465 func setNewPeriodLength (newPeriodLength) = {
434466 let checks = [if (isInAdminList(toString(i.caller)))
435467 then true
436468 else throwErr("caller is not in adminList")]
437469 if ((checks == checks))
438470 then getSetNewPeriodLengthActions(newPeriodLength)
439471 else throw("Strict value is not equal to itself.")
440472 }
441473
442474
443475
444476 @Callable(i)
445477 func setForceStopFlag (stop) = {
446478 let check = [if (isInAdminList(toString(i.caller)))
447479 then true
448480 else throwErr("caller is not in adminList")]
449481 if ((check == check))
450482 then [BooleanEntry(keyForceStop, stop)]
451483 else throw("Strict value is not equal to itself.")
452484 }
453485
454486
455487
456488 @Callable(i)
489+func setForceOutStopFlag (stop) = {
490+ let check = [if (isInAdminList(toString(i.caller)))
491+ then true
492+ else throwErr("caller is not in adminList")]
493+ if ((check == check))
494+ then [BooleanEntry(keyForceOutStop, stop)]
495+ else throw("Strict value is not equal to itself.")
496+ }
497+
498+
499+
500+@Callable(i)
457501 func getNodeDataREADONLY (nodeAddress) = {
458- let $t01524515309 = getLeasingNodeData(nodeAddress)
459- let currentLease = $t01524515309._1
460- let nextLeased = $t01524515309._2
502+ let $t01647116535 = getLeasingNodeData(nodeAddress)
503+ let currentLease = $t01647116535._1
504+ let nextLeased = $t01647116535._2
461505 $Tuple2(nil, $Tuple5(currentPeriodHeight, currentLease, nextPeriodHeight, nextLeased, height))
462506 }
463507
464508
465509
466510 @Callable(i)
467511 func getUserLeasingDataREADONLY (nodeAddress,userAddress) = {
468- let $t01567915756 = getUserLeasingData(nodeAddress, userAddress)
469- let currentLease = $t01567915756._1
470- let nextLeased = $t01567915756._2
512+ let $t01690516982 = getUserLeasingData(nodeAddress, userAddress)
513+ let currentLease = $t01690516982._1
514+ let nextLeased = $t01690516982._2
471515 $Tuple2(nil, $Tuple5(currentPeriodHeight, currentLease, nextPeriodHeight, nextLeased, height))
472516 }
473517
474518
475519
476520 @Callable(i)
477521 func getUserDataREADONLY (userAddress) = {
478- let $t01611916179 = getUserToClaimBalance(userAddress)
479- let toClaim = $t01611916179._1
480- let toUnlock = $t01611916179._2
522+ let $t01734517405 = getUserToClaimBalance(userAddress)
523+ let toClaim = $t01734517405._1
524+ let toUnlock = $t01734517405._2
481525 let userTotalLocked = getUserTotalLocked(userAddress)
482526 $Tuple2(nil, $Tuple6(currentPeriodHeight, toClaim, nextPeriodHeight, toUnlock, userTotalLocked, height))
483527 }
484528
485529
486530
487531 @Callable(i)
488532 func leaseByAddress (nodeAddress,userAddress) = getStakeFromPaymentActions(nodeAddress, userAddress, i)
489533
490534
491535
492536 @Callable(i)
493537 func lease (nodeAddress) = {
494538 let userAddress = toString(i.caller)
495539 getStakeFromPaymentActions(nodeAddress, userAddress, i)
496540 }
497541
498542
499543
500544 @Callable(i)
501545 func leaseFromLocked (nodeAddress,amount) = {
502546 let userAddress = toString(i.caller)
503547 getStakeActions(nodeAddress, userAddress, amount, i)
504548 }
505549
506550
507551
508552 @Callable(i)
509553 func cancelLease (nodeAddress,amount) = {
510554 let userAddress = toString(i.caller)
511555 getUnstakeActions(nodeAddress, userAddress, amount)
512556 }
513557
514558
515559
516560 @Callable(i)
517561 func claim (amount) = {
518562 let userAddress = toString(i.caller)
519563 getClaimUnlockedActions(userAddress, amount)
520564 }
521565
522566
523567
524568 @Callable(i)
525569 func claimAll () = {
526570 let userAddress = toString(i.caller)
527- let $t01719317253 = getUserToClaimBalance(userAddress)
528- let toClaim = $t01719317253._1
529- let toUnlock = $t01719317253._2
571+ let $t01841918479 = getUserToClaimBalance(userAddress)
572+ let toClaim = $t01841918479._1
573+ let toUnlock = $t01841918479._2
530574 let checks = [if ((toClaim > 0))
531575 then true
532576 else throwErr("nothing to claim")]
533577 if ((checks == checks))
534578 then getClaimUnlockedActions(userAddress, toClaim)
535579 else throw("Strict value is not equal to itself.")
536580 }
581+
582+
583+
584+@Callable(i)
585+func stakeFor (userAddress) = getStakeForActions(userAddress, i)
537586
538587
539588
540589 @Callable(i)
541590 func voteForTxId (txId) = {
542591 let callerAddressString = toBase58String(i.caller.bytes)
543592 let keyPrefix = keyAllowedTxIdVotePrefix(txId)
544593 let result = [StringEntry(keyAllowedTxId(), txId)]
545594 let allowedTxIdOption = getString(this, keyAllowedTxId())
546595 let err = [if ((size(fromBase58String(txId)) == TXID_BYTES_LENGTH))
547596 then true
548597 else throwErr((txId + " is not valid txId")), if (if ((allowedTxIdOption == unit))
549598 then true
550599 else (value(allowedTxIdOption) != txId))
551600 then true
552601 else throwErr((txId + " is already allowed"))]
553602 if ((err == err))
554603 then voteINTERNAL(callerAddressString, keyPrefix, QUORUM, result)
555604 else throw("Strict value is not equal to itself.")
556605 }
557606
558607
559608 @Verifier(tx)
560609 func verify () = {
561610 let byAdmins = (tx.id == fromBase58String(valueOrElse(getString(this, keyAllowedTxId()), "")))
562611 let byOwner = if ((size(getAdminsList()) >= QUORUM))
563612 then false
564613 else sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
565614 if (byAdmins)
566615 then true
567616 else byOwner
568617 }
569618

github/deemru/w8io/169f3d6 
68.11 ms