tx · FuX67qawXudjpChrkZ4wfvRgFRVTWYLorMv36b3DmuaD

3MyDtNTkCNyRCw3o2qv5BPPS7vvUosiQe6F:  -0.01400000 Waves

2019.11.01 22:31 [746218] smart account 3MyDtNTkCNyRCw3o2qv5BPPS7vvUosiQe6F > SELF 0.00000000 Waves

{ "type": 13, "id": "FuX67qawXudjpChrkZ4wfvRgFRVTWYLorMv36b3DmuaD", "fee": 1400000, "feeAssetId": null, "timestamp": 1572636748952, "version": 1, "sender": "3MyDtNTkCNyRCw3o2qv5BPPS7vvUosiQe6F", "senderPublicKey": "3z5txV1G5GKezwMRCHZDkLThqb1Yggepxvi2wq6iP6oz", "proofs": [ "4cCA7DRBKWsXA4itPzaEKcDRCrwJaPohs7csuL498qrSsAL6ey72XET4z5UsbpYbZinx1yUF3WoS8kboWZPv9GhL" ], "script": "base64:AAIDAAAAAAAAADQIARIAEgASBAoCCAESABIAEgMKAQgSABIDCgEIEgASBgoECAEBCBIDCgEIEgcKBQgIAQEIAAAAfwEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABAAAAA2tleQQAAAAHJG1hdGNoMAkABBoAAAACBQAAAAR0aGlzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAA0ludAQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQAAAAAAAAAAAAEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABAAAAA2tleQQAAAAHJG1hdGNoMAkABB0AAAACBQAAAAR0aGlzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQIAAAAAAQAAAAxnZXRCb29sQnlLZXkAAAABAAAAA2tleQQAAAAHJG1hdGNoMAkABBsAAAACBQAAAAR0aGlzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAB0Jvb2xlYW4EAAAAAWEFAAAAByRtYXRjaDAFAAAAAWEHAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACAAAAB2FkZHJlc3MAAAADa2V5BAAAAAckbWF0Y2gwCQAEGgAAAAIJAQAAABxAZXh0clVzZXIoYWRkcmVzc0Zyb21TdHJpbmcpAAAAAQUAAAAHYWRkcmVzcwUAAAADa2V5AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAANJbnQEAAAAAWEFAAAAByRtYXRjaDAFAAAAAWEAAAAAAAAAAAABAAAAGGdldFN0cmluZ0J5QWRkcmVzc0FuZEtleQAAAAIAAAAHYWRkcmVzcwAAAANrZXkEAAAAByRtYXRjaDAJAAQdAAAAAgkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABBQAAAAdhZGRyZXNzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQIAAAAAAQAAABZnZXRCb29sQnlBZGRyZXNzQW5kS2V5AAAAAgAAAAdhZGRyZXNzAAAAA2tleQQAAAAHJG1hdGNoMAkABBsAAAACCQEAAAAcQGV4dHJVc2VyKGFkZHJlc3NGcm9tU3RyaW5nKQAAAAEFAAAAB2FkZHJlc3MFAAAAA2tleQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAHQm9vbGVhbgQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQcAAAAADFNFTkRUWEVYUElSRQAAAAAAAAAAHgAAAAAPTElTVFNQTElUU1lNQk9MAgAAAAFfAAAAAA5MSVNUREFUQVNZTUJPTAIAAAABKwAAAAAHV0FWRUxFVAAAAAAABfXhAAAAAAAFUEFVTEkAAAAAAAAAAGQAAAAADUNSWVRJQ0FMU0hBUkUAAAAAAAAAABQAAAAADExFQVNJTkdTSEFSRQAAAAAAAAAAWgAAAAANTEVBU0lOVFhDT1VOVAAAAAAAAAAACgAAAAAIQ0FOQ0VMRUQCAAAACGNhbmNlbGVkAAAAAANORVcCAAAAA25ldwAAAAAGRklMTEVEAgAAAAZmaWxsZWQAAAAAEk5ldXRyaW5vQXNzZXRJZEtleQIAAAARbmV1dHJpbm9fYXNzZXRfaWQAAAAADkJvbmRBc3NldElkS2V5AgAAAA1ib25kX2Fzc2V0X2lkAAAAABJSZXNlcnZlQ29udHJhY3RLZXkCAAAAEHJlc2VydmVfY29udHJhY3QAAAAAEkF1Y3Rpb25Db250cmFjdEtleQIAAAAQYXVjdGlvbl9jb250cmFjdAAAAAAOUlBEQ29udHJhY3RLZXkCAAAADHJwZF9jb250cmFjdAAAAAARQ29udG9sQ29udHJhY3RLZXkCAAAAEGNvbnRyb2xfY29udHJhY3QAAAAAFkJhbGFuY2VMb2NrSW50ZXJ2YWxLZXkCAAAAFWJhbGFuY2VfbG9ja19pbnRlcnZhbAAAAAAVTWluV2F2ZXNTd2FwQW1vdW50S2V5AgAAABVtaW5fd2F2ZXNfc3dhcF9hbW91bnQAAAAAGE1pbk5ldXRyaW5vU3dhcEFtb3VudEtleQIAAAAYbWluX25ldXRyaW5vX3N3YXBfYW1vdW50AAAAAA5Ob2RlQWRkcmVzc0tleQIAAAAMbm9kZV9hZGRyZXNzAAAAABJMZWFzaW5nSW50ZXJ2YWxLZXkCAAAAEGxlYXNpbmdfaW50ZXJ2YWwAAAAACFByaWNlS2V5AgAAAAVwcmljZQAAAAANUHJpY2VJbmRleEtleQIAAAALcHJpY2VfaW5kZXgAAAAAF1NjcmlwdFVwZGF0ZUludGVydmFsS2V5AgAAABZzY3JpcHRfdXBkYXRlX2ludGVydmFsAAAAABJOZXV0cmlub0JhbGFuY2VLZXkCAAAACW5ldXRyaW5vXwAAAAAPV2F2ZXNCYWxhbmNlS2V5AgAAAAZ3YXZlc18AAAAAFUJhbGFuY2VVbmxvY2tCbG9ja0tleQIAAAAOYmFsYW5jZV9ibG9ja18AAAAADE9yZGVyYm9va0tleQIAAAAJb3JkZXJib29rAAAAAA1PcmRlclRvdGFsS2V5AgAAAAxvcmRlcl90b3RhbF8AAAAADU9yZGVyT3duZXJLZXkCAAAADG9yZGVyX293bmVyXwAAAAAOT3JkZXJIZWlnaHRLZXkCAAAADW9yZGVyX2hlaWdodF8AAAAAE09yZGVyRmlsbGVkVG90YWxLZXkCAAAAE29yZGVyX2ZpbGxlZF90b3RhbF8AAAAADk9yZGVyU3RhdHVzS2V5AgAAAA1vcmRlcl9zdGF0dXNfAAAAAA9SUERTeW5jSW5kZXhLZXkCAAAADnJwZF9zeW5jX2luZGV4AAAAAAxSUERQcm9maXRLZXkCAAAACnJwZF9wcm9maXQAAAAADVJQREJhbGFuY2VLZXkCAAAAC3JwZF9iYWxhbmNlAAAAAAxJc0Jsb2NrZWRLZXkCAAAACmlzX2Jsb2NrZWQAAAAAGUlzTGVhc2luZ1Byb2ZpdFR4RXhpc3RLZXkCAAAAEWlzX2xlYXNpbmdfcHJvZml0AAAAABRTY3JpcHRVcGRhdGVCbG9ja0tleQIAAAATc2NyaXB0X3VwZGF0ZV9ibG9jawAAAAAKTGVhc2VUeEtleQIAAAAIbGVhc2VfdHgAAAAAEExlYXNlVHhTdGF0dXNLZXkCAAAAD2xlYXNlX3R4X3N0YXR1cwAAAAAQTGVhc2luZ0Ftb3VudEtleQIAAAAObGVhc2luZ19hbW91bnQAAAAAGUxlYXNlVHhFeHBpcmVTZW5kQmxvY2tLZXkCAAAAE2xlYXNpbmdfZXhwaXJlX3NlbmQAAAAAFUxlYXNpbmdFeHBpcmVCbG9ja0tleQIAAAAUbGVhc2luZ19leHBpcmVfYmxvY2sAAAAADklzUmViYWxhbmNlS2V5AgAAAAxpc19yZWJhbGFuY2UAAAAAFFN3YXBMb2NrZWRCYWxhbmNlS2V5AgAAABNzd2FwX2xvY2tlZF9iYWxhbmNlAAAAABxTd2FwTmV1dHJpbm9Mb2NrZWRCYWxhbmNlS2V5AgAAABxzd2FwX25ldXRyaW5vX2xvY2tlZF9iYWxhbmNlAAAAABFMZWFzaW5nVHhDb3VudEtleQIAAAANbGVhc2luZ19pbmRleAEAAAAgZ2V0UlBEU25hcHNob3RDb250cmFjdEJhbGFuY2VLZXkAAAACAAAABWNvdW50AAAAB2Fzc2V0SWQJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgUAAAANUlBEQmFsYW5jZUtleQIAAAABXwkAAlgAAAABBQAAAAdhc3NldElkAgAAAAFfCQABpAAAAAEFAAAABWNvdW50AQAAABhnZXRSUERDb250cmFjdEJhbGFuY2VLZXkAAAABAAAAB2Fzc2V0SWQJAAEsAAAAAgkAASwAAAACBQAAAA1SUERCYWxhbmNlS2V5AgAAAAFfCQACWAAAAAEFAAAAB2Fzc2V0SWQBAAAAD2dldFJQRFByb2ZpdEtleQAAAAEAAAAFY291bnQJAAEsAAAAAgkAASwAAAACBQAAAAxSUERQcm9maXRLZXkCAAAAAV8JAAGkAAAAAQUAAAAFY291bnQBAAAAFWdldE5ldXRyaW5vQmFsYW5jZUtleQAAAAEAAAAFb3duZXIJAAEsAAAAAgUAAAASTmV1dHJpbm9CYWxhbmNlS2V5BQAAAAVvd25lcgEAAAASZ2V0V2F2ZXNCYWxhbmNlS2V5AAAAAQAAAAVvd25lcgkAASwAAAACBQAAAA9XYXZlc0JhbGFuY2VLZXkFAAAABW93bmVyAQAAABhnZXRCYWxhbmNlVW5sb2NrQmxvY2tLZXkAAAABAAAABW93bmVyCQABLAAAAAIFAAAAFUJhbGFuY2VVbmxvY2tCbG9ja0tleQUAAAAFb3duZXIBAAAAEGdldE9yZGVyVG90YWxLZXkAAAABAAAAB29yZGVySWQJAAEsAAAAAgUAAAANT3JkZXJUb3RhbEtleQUAAAAHb3JkZXJJZAEAAAAQZ2V0T3JkZXJPd25lcktleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACBQAAAA1PcmRlck93bmVyS2V5BQAAAAdvcmRlcklkAQAAABFnZXRPcmRlckhlaWdodEtleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACBQAAAA5PcmRlckhlaWdodEtleQUAAAAHb3JkZXJJZAEAAAARZ2V0T3JkZXJTdGF0dXNLZXkAAAABAAAAB29yZGVySWQJAAEsAAAAAgUAAAAOT3JkZXJTdGF0dXNLZXkFAAAAB29yZGVySWQBAAAAFmdldE9yZGVyRmlsbGVkVG90YWxLZXkAAAABAAAAB29yZGVySWQJAAEsAAAAAgUAAAATT3JkZXJGaWxsZWRUb3RhbEtleQUAAAAHb3JkZXJJZAEAAAASZ2V0UHJpY2VIaXN0b3J5S2V5AAAAAQAAAAVibG9jawkAASwAAAACCQABLAAAAAIFAAAACFByaWNlS2V5AgAAAAFfCQABpAAAAAEFAAAABWJsb2NrAQAAABhnZXRIZWlnaHRQcmljZUJ5SW5kZXhLZXkAAAABAAAABWluZGV4CQABLAAAAAIJAAEsAAAAAgUAAAANUHJpY2VJbmRleEtleQIAAAABXwkAAaQAAAABBQAAAAVpbmRleAEAAAATZ2V0TGVhc2VUeFN0YXR1c0tleQAAAAEAAAAEaGFzaAkAASwAAAACCQABLAAAAAIFAAAAEExlYXNlVHhTdGF0dXNLZXkCAAAAAV8FAAAABGhhc2gBAAAAGWdldExlYXNlVHhBbW91bnRCeUhhc2hLZXkAAAABAAAABGhhc2gJAAEsAAAAAgkAASwAAAACBQAAABBMZWFzaW5nQW1vdW50S2V5AgAAAAFfBQAAAARoYXNoAQAAABhnZXRMZWFzZVR4Qnl0ZXNCeUhhc2hLZXkAAAABAAAABGhhc2gJAAEsAAAAAgkAASwAAAACBQAAAApMZWFzZVR4S2V5AgAAAAFfBQAAAARoYXNoAQAAABxnZXRMZWFzZVR4RXhwaXJlU2VuZEJsb2NrS2V5AAAAAQAAAARoYXNoCQABLAAAAAIJAAEsAAAAAgUAAAAZTGVhc2VUeEV4cGlyZVNlbmRCbG9ja0tleQIAAAABXwUAAAAEaGFzaAEAAAAaZ2V0SXNSZWJhbGFuY2VCeUFkZHJlc3NLZXkAAAABAAAAB2FkZHJlc3MJAAEsAAAAAgkAASwAAAACBQAAAA5Jc1JlYmFsYW5jZUtleQIAAAABXwUAAAAHYWRkcmVzcwAAAAAPY29udHJvbENvbnRyYWN0CQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAABFDb250b2xDb250cmFjdEtleQAAAAAFcHJpY2UJAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACBQAAAA9jb250cm9sQ29udHJhY3QFAAAACFByaWNlS2V5AAAAAApwcmljZUluZGV4CQEAAAAYZ2V0TnVtYmVyQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAAPY29udHJvbENvbnRyYWN0BQAAAA1QcmljZUluZGV4S2V5AQAAAB1jb252ZXJ0TmV1dHJpbm9Ub1dhdmVzQnlQcmljZQAAAAIAAAAGYW1vdW50AAAADGNvbnZlcnRQcmljZQkAAGkAAAACCQAAaAAAAAIJAABpAAAAAgkAAGgAAAACBQAAAAZhbW91bnQAAAAAAAAAAGQFAAAADGNvbnZlcnRQcmljZQUAAAAHV0FWRUxFVAUAAAAFUEFVTEkBAAAAFmNvbnZlcnROZXV0cmlub1RvV2F2ZXMAAAABAAAABmFtb3VudAkAAGkAAAACCQAAaAAAAAIJAABpAAAAAgkAAGgAAAACBQAAAAZhbW91bnQAAAAAAAAAAGQFAAAABXByaWNlBQAAAAdXQVZFTEVUBQAAAAVQQVVMSQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAEAAAAGYW1vdW50CQAAaQAAAAIJAABoAAAAAgkAAGkAAAACCQAAaAAAAAIFAAAABmFtb3VudAUAAAAFcHJpY2UAAAAAAAAAAGQFAAAABVBBVUxJBQAAAAdXQVZFTEVUAQAAABVjb252ZXJ0TmV1dHJpbm9Ub0JvbmQAAAABAAAABmFtb3VudAkAAGkAAAACBQAAAAZhbW91bnQFAAAABVBBVUxJAQAAABVjb252ZXJ0Qm9uZFRvTmV1dHJpbm8AAAABAAAABmFtb3VudAkAAGgAAAACBQAAAAZhbW91bnQFAAAABVBBVUxJAQAAABJjb252ZXJ0V2F2ZXNUb0JvbmQAAAABAAAABmFtb3VudAkBAAAAFWNvbnZlcnROZXV0cmlub1RvQm9uZAAAAAEJAQAAABZjb252ZXJ0V2F2ZXNUb05ldXRyaW5vAAAAAQUAAAAGYW1vdW50AAAAAA5sZWFzaW5nVHhDb3VudAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQUAAAARTGVhc2luZ1R4Q291bnRLZXkAAAAAC2lzUmViYWxhbmNlCQEAAAAMZ2V0Qm9vbEJ5S2V5AAAAAQUAAAAOSXNSZWJhbGFuY2VLZXkAAAAAD2xlYXNpbmdJbnRlcnZhbAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQUAAAASTGVhc2luZ0ludGVydmFsS2V5AAAAABJsZWFzaW5nRXhwaXJlQmxvY2sJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEFAAAAFUxlYXNpbmdFeHBpcmVCbG9ja0tleQAAAAANbGVhc2luZ0Ftb3VudAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQUAAAAQTGVhc2luZ0Ftb3VudEtleQAAAAAZc3dhcE5ldXRyaW5vTG9ja2VkQmFsYW5jZQkBAAAADmdldE51bWJlckJ5S2V5AAAAAQUAAAAcU3dhcE5ldXRyaW5vTG9ja2VkQmFsYW5jZUtleQAAAAAWc3dhcFdhdmVzTG9ja2VkQmFsYW5jZQkBAAAADmdldE51bWJlckJ5S2V5AAAAAQUAAAAUU3dhcExvY2tlZEJhbGFuY2VLZXkAAAAAC25vZGVBZGRyZXNzCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAAA5Ob2RlQWRkcmVzc0tleQAAAAAUc2NyaXB0VXBkYXRlSW50ZXJ2YWwJAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACBQAAABFDb250b2xDb250cmFjdEtleQUAAAAXU2NyaXB0VXBkYXRlSW50ZXJ2YWxLZXkAAAAAEXNjcmlwdFVwZGF0ZUJsb2NrCQEAAAAYZ2V0TnVtYmVyQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAAPY29udHJvbENvbnRyYWN0BQAAABRTY3JpcHRVcGRhdGVCbG9ja0tleQAAAAAMcnBkU3luY0luZGV4CQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABBQAAAA9SUERTeW5jSW5kZXhLZXkAAAAAE2JhbGFuY2VMb2NrSW50ZXJ2YWwJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEFAAAAFkJhbGFuY2VMb2NrSW50ZXJ2YWxLZXkAAAAACWlzQmxvY2tlZAkBAAAAFmdldEJvb2xCeUFkZHJlc3NBbmRLZXkAAAACBQAAAA9jb250cm9sQ29udHJhY3QFAAAADElzQmxvY2tlZEtleQAAAAASbWluV2F2ZXNTd2FwQW1vdW50CQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABBQAAABVNaW5XYXZlc1N3YXBBbW91bnRLZXkAAAAAFW1pbk5ldXRyaW5vU3dhcEFtb3VudAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQUAAAAYTWluTmV1dHJpbm9Td2FwQW1vdW50S2V5AAAAAA9uZXV0cmlub0Fzc2V0SWQJAAJZAAAAAQkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAASTmV1dHJpbm9Bc3NldElkS2V5AAAAAA9yZXNlcnZlQ29udHJhY3QJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEFAAAAElJlc2VydmVDb250cmFjdEtleQAAAAAPYXVjdGlvbkNvbnRyYWN0CQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAABJBdWN0aW9uQ29udHJhY3RLZXkAAAAAC3JwZENvbnRyYWN0CQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAAA5SUERDb250cmFjdEtleQAAAAAHcmVzZXJ2ZQkAAGUAAAACCQEAAAAMd2F2ZXNCYWxhbmNlAAAAAQUAAAAEdGhpcwUAAAAWc3dhcFdhdmVzTG9ja2VkQmFsYW5jZQAAAAAVcmVzZXJ2ZVdpdGhvdXRMZWFzaW5nCQAAZQAAAAIFAAAAB3Jlc2VydmUFAAAADWxlYXNpbmdBbW91bnQAAAAACW9yZGVyYm9vawkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAAMT3JkZXJib29rS2V5AAAAAAtib25kQXNzZXRJZAkAAlkAAAABCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAAA5Cb25kQXNzZXRJZEtleQAAAAAKYm9uZFN1cHBseQQAAAAEaW5mbwkBAAAAB2V4dHJhY3QAAAABCQAD7AAAAAEFAAAAC2JvbmRBc3NldElkCQAAZQAAAAIIBQAAAARpbmZvAAAACHF1YW50aXR5CQAD6wAAAAIFAAAABHRoaXMFAAAAC2JvbmRBc3NldElkAAAAAA5uZXV0cmlub1N1cHBseQQAAAAEaW5mbwkBAAAAB2V4dHJhY3QAAAABCQAD7AAAAAEFAAAAD25ldXRyaW5vQXNzZXRJZAkAAGQAAAACCQAAZQAAAAIIBQAAAARpbmZvAAAACHF1YW50aXR5CQAD6wAAAAIFAAAABHRoaXMFAAAAD25ldXRyaW5vQXNzZXRJZAUAAAAZc3dhcE5ldXRyaW5vTG9ja2VkQmFsYW5jZQAAAAAHc3VycGx1cwkAAGUAAAACCQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAEFAAAAB3Jlc2VydmUFAAAADm5ldXRyaW5vU3VwcGx5AAAAAAdkZWZpY2l0CQAAZQAAAAIFAAAADm5ldXRyaW5vU3VwcGx5CQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAEFAAAAB3Jlc2VydmUBAAAAFWdldFJQRENvbnRyYWN0QmFsYW5jZQAAAAEAAAAHYXNzZXRJZAkBAAAAGGdldE51bWJlckJ5QWRkcmVzc0FuZEtleQAAAAIFAAAAC3JwZENvbnRyYWN0CQEAAAAYZ2V0UlBEQ29udHJhY3RCYWxhbmNlS2V5AAAAAQUAAAAHYXNzZXRJZAEAAAAPZ2V0V2F2ZXNCYWxhbmNlAAAAAQAAAAVvd25lcgkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAEmdldFdhdmVzQmFsYW5jZUtleQAAAAEFAAAABW93bmVyAQAAABJnZXROZXV0cmlub0JhbGFuY2UAAAABAAAABW93bmVyCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAVZ2V0TmV1dHJpbm9CYWxhbmNlS2V5AAAAAQUAAAAFb3duZXIBAAAAFWdldFVubG9ja0JhbGFuY2VCbG9jawAAAAEAAAAFb3duZXIJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABhnZXRCYWxhbmNlVW5sb2NrQmxvY2tLZXkAAAABBQAAAAVvd25lcgEAAAANZ2V0T3JkZXJUb3RhbAAAAAEAAAACaWQJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABBnZXRPcmRlclRvdGFsS2V5AAAAAQUAAAACaWQBAAAADWdldE9yZGVyT3duZXIAAAABAAAAAmlkCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABCQEAAAAQZ2V0T3JkZXJPd25lcktleQAAAAEFAAAAAmlkAQAAAA5nZXRPcmRlclN0YXR1cwAAAAEAAAACaWQJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEJAQAAABFnZXRPcmRlclN0YXR1c0tleQAAAAEFAAAAAmlkAQAAABNnZXRPcmRlckZpbGxlZFRvdGFsAAAAAQAAAAJpZAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAFmdldE9yZGVyRmlsbGVkVG90YWxLZXkAAAABBQAAAAJpZAEAAAAMZ2V0UlBEUHJvZml0AAAAAQAAAAVjb3VudAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAD2dldFJQRFByb2ZpdEtleQAAAAEFAAAABWNvdW50AQAAAA9nZXRQcmljZUhpc3RvcnkAAAABAAAABWJsb2NrCQEAAAAYZ2V0TnVtYmVyQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAAPY29udHJvbENvbnRyYWN0CQEAAAASZ2V0UHJpY2VIaXN0b3J5S2V5AAAAAQUAAAAFYmxvY2sBAAAAFWdldEhlaWdodFByaWNlQnlJbmRleAAAAAEAAAAFaW5kZXgJAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACBQAAAA9jb250cm9sQ29udHJhY3QJAQAAABhnZXRIZWlnaHRQcmljZUJ5SW5kZXhLZXkAAAABBQAAAAVpbmRleAEAAAAQZ2V0TGVhc2VUeFN0YXR1cwAAAAEAAAAEaGFzaAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQkBAAAAE2dldExlYXNlVHhTdGF0dXNLZXkAAAABBQAAAARoYXNoAQAAABZnZXRMZWFzZVR4QW1vdW50QnlIYXNoAAAAAQAAAARoYXNoCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAZZ2V0TGVhc2VUeEFtb3VudEJ5SGFzaEtleQAAAAEFAAAABGhhc2gBAAAAFWdldExlYXNlVHhCeXRlc0J5SGFzaAAAAAEAAAAEaGFzaAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQkBAAAAGGdldExlYXNlVHhCeXRlc0J5SGFzaEtleQAAAAEFAAAABGhhc2gBAAAAGWdldExlYXNlVHhFeHBpcmVTZW5kQmxvY2sA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Y2NvdW50CQAAZAAAAAIFAAAABmhlaWdodAUAAAATYmFsYW5jZUxvY2tJbnRlcnZhbAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgUAAAAcU3dhcE5ldXRyaW5vTG9ja2VkQmFsYW5jZUtleQUAAAAcbmV3U3dhcE5ldXRyaW5vTG9ja2VkQmFsYW5jZQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgUAAAAOSXNSZWJhbGFuY2VLZXkDCQAAZwAAAAIFAAAAFXJlc2VydmVXaXRob3V0TGVhc2luZwkBAAAAFmNvbnZlcnROZXV0cmlub1RvV2F2ZXMAAAABBQAAABxuZXdTd2FwTmV1dHJpbm9Mb2NrZWRCYWxhbmNlBwYFAAAAA25pbAAAAAFpAQAAAAh3aXRoZHJhdwAAAAIAAAAHYWNjb3VudAAAAAVpbmRleAQAAAALaW5kZXhIZWlnaHQJAQAAABVnZXRIZWlnaHRQcmljZUJ5SW5kZXgAAAABBQAAAAVpbmRleAQAAAAPbmV4dEluZGV4SGVpZ2h0CQEAAAAVZ2V0SGVpZ2h0UHJpY2VCeUluZGV4AAAAAQkAAGQAAAACBQAAAAVpbmRleAAAAAAAAAAAAQQAAAAMdW5sb2NrSGVpZ2h0CQEAAAAVZ2V0VW5sb2NrQmFsYW5jZUJsb2NrAAAAAQUAAAAHYWNjb3VudAQAAAAObmV1dHJpbm9BbW91bnQJAQAAABJnZXROZXV0cmlub0JhbGFuY2UAAAABBQAAAAdhY2NvdW50BAAAAAppbmRleFByaWNlCQEAAAAPZ2V0UHJpY2VIaXN0b3J5AAAAAQUAAAALaW5kZXhIZWlnaHQEAAAABmFtb3VudAkBAAAAHWNvbnZlcnROZXV0cmlub1RvV2F2ZXNCeVByaWNlAAAAAgUAAAAObmV1dHJpbm9BbW91bnQFAAAACmluZGV4UHJpY2UEAAAAEnRvdGFsV2F2ZXNXaXRoZHJhdwkAAGQAAAACCQEAAAAPZ2V0V2F2ZXNCYWxhbmNlAAAAAQUAAAAHYWNjb3VudAUAAAAGYW1vdW50AwUAAAAJaXNCbG9ja2VkCQAAAgAAAAECAAAAE2NvbnRyYWN0IGlzIGJsb2NrZWQDCQAAZgAAAAIFAAAADHVubG9ja0hlaWdodAUAAAAGaGVpZ2h0CQAAAgAAAAECAAAAJHdhaXQgYSBjb3VwbGUgb2YgYmxvY2tzIGZvciB3aXRoZHJhdwMDAwkAAGYAAAACBQAAAAVpbmRleAUAAAAKcHJpY2VJbmRleAYJAABmAAAAAgUAAAALaW5kZXhIZWlnaHQFAAAADHVubG9ja0hlaWdodAYDCQEAAAACIT0AAAACBQAAAA9uZXh0SW5kZXhIZWlnaHQAAAAAAAAAAAAJAABnAAAAAgUAAAAMdW5sb2NrSGVpZ2h0BQAAAA9uZXh0SW5kZXhIZWlnaHQHCQAAAgAAAAECAAAADWludmFsaWQgaW5kZXgJAQAAAAxTY3JpcHRSZXN1bHQAAAACCQEAAAAIV3JpdGVTZXQAAAABCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAASZ2V0V2F2ZXNCYWxhbmNlS2V5AAAAAQUAAAAHYWNjb3VudAAAAAAAAAAAAAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgkBAAAAFWdldE5ldXRyaW5vQmFsYW5jZUtleQAAAAEFAAAAB2FjY291bnQAAAAAAAAAAAAJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIFAAAAFFN3YXBMb2NrZWRCYWxhbmNlS2V5CQAAZQAAAAIFAAAAFnN3YXBXYXZlc0xvY2tlZEJhbGFuY2UJAQAAAA9nZXRXYXZlc0JhbGFuY2UAAAABBQAAAAdhY2NvdW50CQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACBQAAABxTd2FwTmV1dHJpbm9Mb2NrZWRCYWxhbmNlS2V5CQAAZQAAAAIFAAAAGXN3YXBOZXV0cmlub0xvY2tlZEJhbGFuY2UFAAAADm5ldXRyaW5vQW1vdW50BQAAAANuaWwJAQAAAAtUcmFuc2ZlclNldAAAAAEJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABBQAAAAdhY2NvdW50BQAAABJ0b3RhbFdhdmVzV2l0aGRyYXcFAAAABHVuaXQFAAAAA25pbAAAAAFpAQAAAAxnZW5lcmF0ZUJvbmQAAAAABAAAAA5iYWxhbmNlQXVjdGlvbgkAA+sAAAACCQEAAAAcQGV4dHJVc2VyKGFkZHJl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BmNhbGxlcgUAAAAGYW1vdW50BQAAAAtib25kQXNzZXRJZAUAAAADbmlsAAAAAWkBAAAADGV4ZWN1dGVPcmRlcgAAAAAEAAAAB29yZGVySWQJAAGRAAAAAgkABLUAAAACBQAAAAlvcmRlcmJvb2sFAAAAD0xJU1RTUExJVFNZTUJPTAAAAAAAAAAAAAQAAAAKb3JkZXJUb3RhbAkBAAAADWdldE9yZGVyVG90YWwAAAABBQAAAAdvcmRlcklkBAAAAApvcmRlck93bmVyCQEAAAANZ2V0T3JkZXJPd25lcgAAAAEFAAAAB29yZGVySWQEAAAAC2ZpbGxlZFRvdGFsCQEAAAATZ2V0T3JkZXJGaWxsZWRUb3RhbAAAAAEFAAAAB29yZGVySWQEAAAAC3N1cnBsdXNCb25kCQEAAAAVY29udmVydE5ldXRyaW5vVG9Cb25kAAAAAQUAAAAHc3VycGx1cwMFAAAACWlzQmxvY2tlZAkAAAIAAAABAgAAABNjb250cmFjdCBpcyBibG9ja2VkAwkAAGcAAAACAAAAAAAAAAAABQAAAAtzdXJwbHVzQm9uZAkAAAIAAAABAgAAABlzdXJwbHVzIGlzIGxlc3MgdGhhbiB6ZXJvAwMJAAAAAAAAAgUAAAAKb3JkZXJPd25lcgIAAAAACQAAZwAAAAIFAAAAC3N1cnBsdXNCb25kAAAAAAAAAAAKBwQAAAAPbmV3UnBkU3luY0luZGV4CQAAZAAAAAIFAAAADHJwZFN5bmNJbmRleAAAAAAAAAAAAQkBAAAADFNjcmlwdFJlc3VsdAAAAAIJAQAAAAhXcml0ZVNldAAAAAEJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIFAAAAD1JQRFN5bmNJbmRleEtleQUAAAAPbmV3UnBkU3luY0luZGV4CQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAPZ2V0UlBEUHJvZml0S2V5AAAAAQUAAAAMcnBkU3luY0luZGV4BQAAAAdzdXJwbHVzCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAgZ2V0UlBEU25hcHNob3RDb250cmFjdEJhbGFuY2VLZXkAAAACBQAAAAxycGRTeW5jSW5kZXgFAAAAD25ldXRyaW5vQXNzZXRJZAkBAAAAFWdldFJQRENvbnRyYWN0QmFsYW5jZQAAAAEFAAAAD25ldXRyaW5vQXNzZXRJZAUAAAADbmlsCQEAAAALVHJhbnNmZXJTZXQAAAABCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMJAQAAABxAZXh0clVzZXIoYWRkcmVzc0Zyb21TdHJpbmcpAAAAAQUAAAALcnBkQ29udHJhY3QFAAAAB3N1cnBsdXMFAAAAD25ldXRyaW5vQXNzZXRJZAUAAAADbmlsBAAAAAZhbW91bnQJAABlAAAAAgUAAAAKb3JkZXJUb3RhbAUAAAALZmlsbGVkVG90YWwEAAAABnN0YXR1cwMJAABnAAAAAgUAAAALc3VycGx1c0JvbmQFAAAABmFtb3VudAUAAAAGRklMTEVEBQAAAANORVcEAAAADm5ld0ZpbGxlZFRvdGFsAwkAAGcAAAACBQAAAAtzdXJwbHVzQm9uZAUAAAAGYW1vdW50BQAAAAZhbW91bnQFAAAAC3N1cnBsdXNCb25kCQEAAAAMU2NyaXB0UmVzdWx0AAAAAgkBAAAACFdyaXRlU2V0AAAAAQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgUAAAAMT3JkZXJib29rS2V5AwkAAGcAAAACBQAAAAtzdXJwbHVzQm9uZAUAAAAGYW1vdW50CQEAAAAJZHJvcE9yZGVyAAAAAQUAAAAHb3JkZXJJZAUAAAAJb3JkZXJib29rCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAWZ2V0T3JkZXJGaWxsZWRUb3RhbEtleQAAAAEFAAAAB29yZGVySWQJAABkAAAAAgUAAAALZmlsbGVkVG90YWwFAAAADm5ld0ZpbGxlZFRvdGFsCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAARZ2V0T3JkZXJTdGF0dXNLZXkAAAABBQAAAAdvcmRlcklkBQAAAAZzdGF0dXMFAAAAA25pbAkBAAAAC1RyYW5zZmVyU2V0AAAAAQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCQEAAAAcQGV4dHJVc2VyKGFkZHJlc3NGcm9tU3RyaW5nKQAAAAEFAAAACm9yZGVyT3duZXIJAQAAABVjb252ZXJ0Qm9uZFRvTmV1dHJpbm8AAAABBQAAAA5uZXdGaWxsZWRUb3RhbAUAAAAPbmV1dHJpbm9Bc3NldElkBQAAAANuaWwAAAABaQEAAAAIdHJhbnNmZXIAAAABAAAAB2FjY291bnQEAAAAA3BtdAkBAAAAB2V4dHJhY3QAAAABCAUAAAABaQAAAAdwYXltZW50CQEAAAALVHJhbnNmZXJTZXQAAAABCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMJAQAAABxAZXh0clVzZXIoYWRkcmVzc0Zyb21TdHJpbmcpAAAAAQUAAAAHYWNjb3VudAgFAAAAA3BtdAAAAAZhbW91bnQIBQAAAANwbXQAAAAHYXNzZXRJZAUAAAADbmlsAAAAAWkBAAAACm5vZGVSZXdhcmQAAAAABAAAAANwbXQJAQAAAAV2YWx1ZQAAAAEIBQAAAAFpAAAAB3BheW1lbnQDCQEAAAACIT0AAAACCAUAAAABaQAAAAZjYWxsZXIJAQAAABxAZXh0clVzZXIoYWRkcmVzc0Zyb21TdHJpbmcpAAAAAQUAAAALbm9kZUFkZHJlc3MJAAACAAAAAQIAAAARcGVybWlzc2lvbiBkZW5pZWQDCQEAAAAJaXNEZWZpbmVkAAAAAQgFAAAAA3BtdAAAAAdhc3NldElkCQAAAgAAAAECAAAACndhdmVzIG9ubHkEAAAABmFtb3VudAkBAAAAFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8AAAABCAUAAAADcG10AAAABmFtb3VudAQAAAAPbmV3UnBkU3luY0luZGV4CQAAZAAAAAIFAAAADHJwZFN5bmNJbmRleAAAAAAAAAAAAQkBAAAADFNjcmlwdFJlc3VsdAAAAAIJAQAAAAhXcml0ZVNldAAAAAEJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIFAAAAD1JQRFN5bmNJbmRleEtleQUAAAAPbmV3UnBkU3luY0luZGV4CQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAPZ2V0UlBEUHJvZml0S2V5AAAAAQUAAAAMcnBkU3luY0luZGV4BQAAAAZhbW91bnQJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAACBnZXRSUERTbmFwc2hvdENvbnRyYWN0QmFsYW5jZUtleQAAAAIFAAAADHJwZFN5bmNJbmRleAUAAAAPbmV1dHJpbm9Bc3NldElkCQEAAAAVZ2V0UlBEQ29udHJhY3RCYWxhbmNlAAAAAQUAAAAPbmV1dHJpbm9Bc3NldElkBQAAAANuaWwJAQAAAAtUcmFuc2ZlclNldAAAAAEJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABBQAAAAtycGRDb250cmFjdAUAAAAGYW1vdW50BQAAAA9uZXV0cmlub0Fzc2V0SWQFAAAAA25pbAAAAAFpAQAAABNyZWdpc3RyYXRpb25MZWFzZVR4AAAABAAAAA9zZW5kZXJQdWJsaWNLZXkAAAADZmVlAAAACXRpbWVzdGFtcAAAAAtsZWFzZVR4SGFzaAQAAAAQdG90YWxGcmVlUmVzZXJ2ZQkAAGUAAAACCQAAaQAAAAIJAABoAAAAAgUAAAAHcmVzZXJ2ZQUAAAAMTEVBU0lOR1NIQVJFAAAAAAAAAABkCQEAAAAWY29udmVydE5ldXRyaW5vVG9XYXZlcwAAAAEFAAAAGXN3YXBOZXV0cmlub0xvY2tlZEJhbGFuY2UEAAAABmFtb3VudAkAAGkAAAACBQAAABB0b3RhbEZyZWVSZXNlcnZlBQAAAA1MRUFTSU5UWENPVU5UBAAAAAd0eEJ5dGVzCQAAywAAAAIJAADLAAAAAgkAAMsAAAACCQAAywAAAAIJAADLAAAAAgEAAAADCAIACQACWQAAAAEFAAAAD3NlbmRlclB1YmxpY0tleQkAAlkAAAABBQAAAAtub2RlQWRkcmVzcwkAAZoAAAABBQAAAAZhbW91bnQJAAGaAAAAAQUAAAADZmVlCQABmgAAAAEFAAAACXRpbWVzdGFtcAQAAAALdHhIYXNoQnl0ZXMJAAH2AAAAAQUAAAAHdHhCeXRlcwQAAAAGdHhIYXNoCQACWAAAAAEFAAAAC3R4SGFzaEJ5dGVzAwkBAAAAAiE9AAAAAgUAAAALbGVhc2VUeEhhc2gFAAAABnR4SGFzaAkAAAIAAAABAgAAAA9pbnZhbGlkIHR4IGhhc2gDCQAAZwAAAAIFAAAADmxlYXNpbmdUeENvdW50BQAAAA1MRUFTSU5UWENPVU5UCQAAAgAAAAECAAAAOnRoZSBudW1iZXIgb2YgbGVhc2luZyB0cmFuc2FjdGlvbnMgaXMgZXF1YWwgdG8gdGhlIG1heGltdW0DCQEAAAACIT0AAAACBQAAAAR0aGlzCQEAAAAUYWRkcmVzc0Zyb21QdWJsaWNLZXkAAAABCQACWQAAAAEFAAAAD3NlbmRlclB1YmxpY0tleQkAAAIAAAABAgAAAA5pbnZhbGlkIHB1YktleQMDCQAAZgAAAAIIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wBQAAAAl0aW1lc3RhbXAGCQAAZgAAAAIFAAAACXRpbWVzdGFtcAkAAGQAAAACCAUAAAAJbGFzdEJsb2NrAAAACXRpbWVzdGFtcAAAAAAAAFJlwAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgIAAAAdaW52YWxpZCB0aW1lc3RhbXAobGFzdEJsb2NrOiAJAAGkAAAAAQgFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXACAAAAASkDCQAAAAAAAAIJAQAAABBnZXRMZWFzZVR4U3RhdHVzAAAAAQUAAAAGdHhIYXNoAgAAAAAJAAACAAAAAQIAAAALdHggaXMgZXhpc3QDAwkAAGYAAAACBQAAAANmZWUAAAAAAAAPQkAGCQAAZgAAAAIAAAAAAAAHoSAFAAAAA2ZlZQkAAAIAAAABAgAAAAtpbnZhbGlkIGZlZQMJAABmAAAAAgkAAGUAAAACBQAAABB0b3RhbEZyZWVSZXNlcnZlCQAAZAAAAAIFAAAADWxlYXNpbmdBbW91bnQFAAAABmFtb3VudAUAAAAVcmVzZXJ2ZVdpdGhvdXRMZWFzaW5nCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACAgAAABZpbnZhbGlkIGFtb3VudChyZXN1bHQ6CQABpQAAAAEJAABmAAAAAgkAAGUAAAACBQAAABB0b3RhbEZyZWVSZXNlcnZlCQAAZAAAAAIFAAAADWxlYXNpbmdBbW91bnQFAAAABmFtb3VudAUAAAAVcmVzZXJ2ZVdpdGhvdXRMZWFzaW5nAgAAAAEpCQEAAAAIV3JpdGVTZXQAAAABCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACBQAAABFMZWFzaW5nVHhDb3VudEtleQMJAAAAAAAAAgkBAAAAEGdldExlYXNlVHhTdGF0dXMAAAABBQAAAAZ0eEhhc2gCAAAAAAkAAGQAAAACBQAAAA5sZWFzaW5nVHhDb3VudAAAAAAAAAAAAQUAAAAObGVhc2luZ1R4Q291bnQJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIFAAAAEExlYXNpbmdBbW91bnRLZXkJAABkAAAAAgUAAAANbGVhc2luZ0Ftb3VudAUAAAAGYW1vdW50CQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACBQAAABVMZWFzaW5nRXhwaXJlQmxvY2tLZXkDCQAAZgAAAAIFAAAABmhlaWdodAUAAAASbGVhc2luZ0V4cGlyZUJsb2NrCQAAZAAAAAIFAAAABmhlaWdodAUAAAAPbGVhc2luZ0ludGVydmFsBQAAABJsZWFzaW5nRXhwaXJlQmxvY2sJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAABNnZXRMZWFzZVR4U3RhdHVzS2V5AAAAAQUAAAAGdHhIYXNoBQAAAANORVcJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAABxnZXRMZWFzZVR4RXhwaXJlU2VuZEJsb2NrS2V5AAAAAQUAAAAGdHhIYXNoCQAAZAAAAAIFAAAABmhlaWdodAUAAAAMU0VORFRYRVhQSVJFCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAZZ2V0TGVhc2VUeEFtb3VudEJ5SGFzaEtleQAAAAEFAAAABnR4SGFzaAUAAAAGYW1vdW50CQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAYZ2V0TGVhc2VUeEJ5dGVzQnlIYXNoS2V5AAAAAQUAAAAGdHhIYXNoCQACWgAAAAEFAAAAB3R4Qnl0ZXMFAAAAA25pbAAAAAFpAQAAABJjYW5jZWxTdHVja0xlYXNlVHgAAAABAAAABnR4SGFzaAMDAwkAAAAAAAACCQEAAAAQZ2V0TGVhc2VUeFN0YXR1cwAAAAEFAAAABnR4SGFzaAUAAAADTkVXCQEAAAABIQAAAAEJAQAAAAlpc0RlZmluZWQAAAABCQAD6QAAAAEJAAJZAAAAAQUAAAAGdHhIYXNoBwkAAGYAAAACBQAAAAZoZWlnaHQJAQAAABlnZXRMZWFzZVR4RXhwaXJlU2VuZEJsb2NrAAAAAQUAAAAGdHhIYXNoBwQAAAAGYW1vdW50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", "chainId": 84, "height": 746218, "spentComplexity": 0 } View: original | compacted Prev: HJTy146V4iWR1wXF8WsQqaqkZst2TRD1Hr9EvwHNZeXM Next: F2YAvX4T8eVU49N2upZfDBQBHfAg5TxAtJD3aoqAeNoD Diff:
OldNewDifferences
4949 }
5050
5151
52-func isInt (val) = match val {
53- case a: Int =>
54- true
55- case _ =>
56- false
57-}
58-
52+let SENDTXEXPIRE = 30
5953
6054 let LISTSPLITSYMBOL = "_"
6155
6761
6862 let CRYTICALSHARE = 20
6963
70-let LEASINGSHARE = 50
64+let LEASINGSHARE = 90
65+
66+let LEASINTXCOUNT = 10
7167
7268 let CANCELED = "canceled"
7369
7874 let NeutrinoAssetIdKey = "neutrino_asset_id"
7975
8076 let BondAssetIdKey = "bond_asset_id"
77+
78+let ReserveContractKey = "reserve_contract"
8179
8280 let AuctionContractKey = "auction_contract"
8381
9694 let LeasingIntervalKey = "leasing_interval"
9795
9896 let PriceKey = "price"
97+
98+let PriceIndexKey = "price_index"
9999
100100 let ScriptUpdateIntervalKey = "script_update_interval"
101101
131131
132132 let LeaseTxKey = "lease_tx"
133133
134-let LeaseTxHashKey = "lease_tx_hash"
134+let LeaseTxStatusKey = "lease_tx_status"
135135
136136 let LeasingAmountKey = "leasing_amount"
137137
142142 let IsRebalanceKey = "is_rebalance"
143143
144144 let SwapLockedBalanceKey = "swap_locked_balance"
145+
146+let SwapNeutrinoLockedBalanceKey = "swap_neutrino_locked_balance"
147+
148+let LeasingTxCountKey = "leasing_index"
145149
146150 func getRPDSnapshotContractBalanceKey (count,assetId) = ((((RPDBalanceKey + "_") + toBase58String(assetId)) + "_") + toString(count))
147151
176180 func getOrderFilledTotalKey (orderId) = (OrderFilledTotalKey + orderId)
177181
178182
183+func getPriceHistoryKey (block) = ((PriceKey + "_") + toString(block))
184+
185+
186+func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index))
187+
188+
189+func getLeaseTxStatusKey (hash) = ((LeaseTxStatusKey + "_") + hash)
190+
191+
192+func getLeaseTxAmountByHashKey (hash) = ((LeasingAmountKey + "_") + hash)
193+
194+
195+func getLeaseTxBytesByHashKey (hash) = ((LeaseTxKey + "_") + hash)
196+
197+
198+func getLeaseTxExpireSendBlockKey (hash) = ((LeaseTxExpireSendBlockKey + "_") + hash)
199+
200+
201+func getIsRebalanceByAddressKey (address) = ((IsRebalanceKey + "_") + address)
202+
203+
179204 let controlContract = getStringByKey(ContolContractKey)
180205
181206 let price = getNumberByAddressAndKey(controlContract, PriceKey)
207+
208+let priceIndex = getNumberByAddressAndKey(controlContract, PriceIndexKey)
209+
210+func convertNeutrinoToWavesByPrice (amount,convertPrice) = ((((amount * 100) / convertPrice) * WAVELET) / PAULI)
211+
182212
183213 func convertNeutrinoToWaves (amount) = ((((amount * 100) / price) * WAVELET) / PAULI)
184214
195225 func convertWavesToBond (amount) = convertNeutrinoToBond(convertWavesToNeutrino(amount))
196226
197227
228+let leasingTxCount = getNumberByKey(LeasingTxCountKey)
229+
198230 let isRebalance = getBoolByKey(IsRebalanceKey)
199231
200232 let leasingInterval = getNumberByKey(LeasingIntervalKey)
201233
202-let leaseTxExpireSendBlock = getNumberByKey(LeaseTxExpireSendBlockKey)
203-
204234 let leasingExpireBlock = getNumberByKey(LeasingExpireBlockKey)
205-
206-let leaseTxHash = getStringByKey(LeaseTxHashKey)
207-
208-let leaseTxBytes = getStringByKey(LeaseTxKey)
209235
210236 let leasingAmount = getNumberByKey(LeasingAmountKey)
211237
212-let swapLockedBalance = getNumberByKey(SwapLockedBalanceKey)
238+let swapNeutrinoLockedBalance = getNumberByKey(SwapNeutrinoLockedBalanceKey)
239+
240+let swapWavesLockedBalance = getNumberByKey(SwapLockedBalanceKey)
213241
214242 let nodeAddress = getStringByKey(NodeAddressKey)
215243
229257
230258 let neutrinoAssetId = fromBase58String(getStringByKey(NeutrinoAssetIdKey))
231259
260+let reserveContract = getStringByKey(ReserveContractKey)
261+
232262 let auctionContract = getStringByKey(AuctionContractKey)
233263
234264 let rpdContract = getStringByKey(RPDContractKey)
235265
236-let reserve = (wavesBalance(this) - swapLockedBalance)
266+let reserve = (wavesBalance(this) - swapWavesLockedBalance)
237267
238-let reserveWithoutLeasing = ((wavesBalance(this) - (leasingAmount * (if (isInt(transactionHeightById(fromBase58String(leaseTxHash))))
239- then 1
240- else 0))) - swapLockedBalance)
268+let reserveWithoutLeasing = (reserve - leasingAmount)
241269
242270 let orderbook = getStringByKey(OrderbookKey)
243271
250278
251279 let neutrinoSupply = {
252280 let info = extract(assetInfo(neutrinoAssetId))
253- (info.quantity - assetBalance(this, neutrinoAssetId))
281+ ((info.quantity - assetBalance(this, neutrinoAssetId)) + swapNeutrinoLockedBalance)
254282 }
255283
256284 let surplus = (convertWavesToNeutrino(reserve) - neutrinoSupply)
284312 func getRPDProfit (count) = getNumberByKey(getRPDProfitKey(count))
285313
286314
315+func getPriceHistory (block) = getNumberByAddressAndKey(controlContract, getPriceHistoryKey(block))
316+
317+
318+func getHeightPriceByIndex (index) = getNumberByAddressAndKey(controlContract, getHeightPriceByIndexKey(index))
319+
320+
321+func getLeaseTxStatus (hash) = getStringByKey(getLeaseTxStatusKey(hash))
322+
323+
324+func getLeaseTxAmountByHash (hash) = getNumberByKey(getLeaseTxAmountByHashKey(hash))
325+
326+
327+func getLeaseTxBytesByHash (hash) = getStringByKey(getLeaseTxBytesByHashKey(hash))
328+
329+
330+func getLeaseTxExpireSendBlock (hash) = getNumberByKey(getLeaseTxExpireSendBlockKey(hash))
331+
332+
287333 func getOrderElementById (id) = (id + LISTSPLITSYMBOL)
288334
289335
294340 let parts = split(orderbook, getOrderElementById(orderId))
295341 (parts[0] + parts[1])
296342 }
297-
298-
299-@Callable(i)
300-func setPrice () = WriteSet([DataEntry(PriceKey, price)])
301-
302343
303344
304345 @Callable(i)
321362 @Callable(i)
322363 func swapNeutrinoToWaves () = {
323364 let pmt = extract(i.payment)
365+ let account = toString(i.caller)
324366 if ((minNeutrinoSwapAmount > pmt.amount))
325367 then throw("amount less min")
326368 else if (isBlocked)
327369 then throw("contract is blocked")
328370 else if ((pmt.assetId != neutrinoAssetId))
329371 then throw("can use neutrino only")
330- else {
331- let account = toBase58String(i.caller.bytes)
332- let amount = convertNeutrinoToWaves(pmt.amount)
333- WriteSet([DataEntry(getWavesBalanceKey(account), (getWavesBalance(account) + amount)), DataEntry(getBalanceUnlockBlockKey(account), (height + balanceLockInterval)), DataEntry(IsRebalanceKey, (((reserve * CRYTICALSHARE) / 100) >= (reserveWithoutLeasing - amount))), DataEntry(SwapLockedBalanceKey, (swapLockedBalance + amount))])
334- }
372+ else if ((getUnlockBalanceBlock(account) > height))
373+ then throw((("await " + toString((getUnlockBalanceBlock(account) - height))) + " blocks"))
374+ else if ((getNeutrinoBalance(account) != 0))
375+ then throw("use withdraw")
376+ else {
377+ let neutrinoAmount = pmt.amount
378+ let newSwapNeutrinoLockedBalance = (swapNeutrinoLockedBalance + neutrinoAmount)
379+ WriteSet([DataEntry(getNeutrinoBalanceKey(account), (getNeutrinoBalance(account) + neutrinoAmount)), DataEntry(getBalanceUnlockBlockKey(account), (height + balanceLockInterval)), DataEntry(SwapNeutrinoLockedBalanceKey, newSwapNeutrinoLockedBalance), DataEntry(IsRebalanceKey, if ((reserveWithoutLeasing >= convertNeutrinoToWaves(newSwapNeutrinoLockedBalance)))
380+ then false
381+ else true)])
382+ }
335383 }
336384
337385
338386
339387 @Callable(i)
340-func withdraw (account) = if ((getUnlockBalanceBlock(account) > height))
341- then throw("wait a couple of blocks for withdraw")
342- else ScriptResult(WriteSet([DataEntry(getWavesBalanceKey(account), 0), DataEntry(getNeutrinoBalanceKey(account), 0), DataEntry(SwapLockedBalanceKey, (swapLockedBalance - getWavesBalance(account)))]), TransferSet([ScriptTransfer(addressFromStringValue(account), getNeutrinoBalance(account), neutrinoAssetId), ScriptTransfer(addressFromStringValue(account), getWavesBalance(account), unit)]))
388+func withdraw (account,index) = {
389+ let indexHeight = getHeightPriceByIndex(index)
390+ let nextIndexHeight = getHeightPriceByIndex((index + 1))
391+ let unlockHeight = getUnlockBalanceBlock(account)
392+ let neutrinoAmount = getNeutrinoBalance(account)
393+ let indexPrice = getPriceHistory(indexHeight)
394+ let amount = convertNeutrinoToWavesByPrice(neutrinoAmount, indexPrice)
395+ let totalWavesWithdraw = (getWavesBalance(account) + amount)
396+ if (isBlocked)
397+ then throw("contract is blocked")
398+ else if ((unlockHeight > height))
399+ then throw("wait a couple of blocks for withdraw")
400+ else if (if (if ((index > priceIndex))
401+ then true
402+ else (indexHeight > unlockHeight))
403+ then true
404+ else if ((nextIndexHeight != 0))
405+ then (unlockHeight >= nextIndexHeight)
406+ else false)
407+ then throw("invalid index")
408+ else ScriptResult(WriteSet([DataEntry(getWavesBalanceKey(account), 0), DataEntry(getNeutrinoBalanceKey(account), 0), DataEntry(SwapLockedBalanceKey, (swapWavesLockedBalance - getWavesBalance(account))), DataEntry(SwapNeutrinoLockedBalanceKey, (swapNeutrinoLockedBalance - neutrinoAmount))]), TransferSet([ScriptTransfer(addressFromStringValue(account), totalWavesWithdraw, unit)]))
409+ }
343410
344411
345412
406473 then FILLED
407474 else NEW
408475 let newFilledTotal = if ((surplusBond >= amount))
409- then orderTotal
476+ then amount
410477 else surplusBond
411478 ScriptResult(WriteSet([DataEntry(OrderbookKey, if ((surplusBond >= amount))
412479 then dropOrder(orderId)
419486 @Callable(i)
420487 func transfer (account) = {
421488 let pmt = extract(i.payment)
422- if (isDefined(pmt.assetId))
423- then throw("can use waves only at the moment")
424- else TransferSet([ScriptTransfer(addressFromStringValue(account), pmt.amount, unit)])
489+ TransferSet([ScriptTransfer(addressFromStringValue(account), pmt.amount, pmt.assetId)])
425490 }
426491
427492
443508
444509
445510 @Callable(i)
446-func registrationLeaseTx (senderPublicKey,amount,fee,timestamp) = {
511+func registrationLeaseTx (senderPublicKey,fee,timestamp,leaseTxHash) = {
512+ let totalFreeReserve = (((reserve * LEASINGSHARE) / 100) - convertNeutrinoToWaves(swapNeutrinoLockedBalance))
513+ let amount = (totalFreeReserve / LEASINTXCOUNT)
447514 let txBytes = (((((base58'3h1H' + fromBase58String(senderPublicKey)) + fromBase58String(nodeAddress)) + toBytes(amount)) + toBytes(fee)) + toBytes(timestamp))
448- let balance = ((reserve * LEASINGSHARE) / 100)
449515 let txHashBytes = blake2b256(txBytes)
450516 let txHash = toBase58String(txHashBytes)
451- if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
452- then throw("invalid pubKey")
453- else if (if ((lastBlock.timestamp > timestamp))
454- then true
455- else (timestamp > (lastBlock.timestamp + 5400000)))
456- then throw((("invalid timestamp(lastBlock: " + toString(lastBlock.timestamp)) + ")"))
457- else if (if ((leaseTxHash != ""))
458- then if (isInt(transactionHeightById(fromBase58String(leaseTxHash))))
517+ if ((leaseTxHash != txHash))
518+ then throw("invalid tx hash")
519+ else if ((leasingTxCount >= LEASINTXCOUNT))
520+ then throw("the number of leasing transactions is equal to the maximum")
521+ else if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
522+ then throw("invalid pubKey")
523+ else if (if ((lastBlock.timestamp > timestamp))
459524 then true
460- else (leaseTxExpireSendBlock >= height)
461- else false)
462- then throw("leasing not canceled")
463- else if (if ((fee > 1000000))
464- then true
465- else (500000 > fee))
466- then throw("invalid fee")
467- else if (if ((amount != balance))
468- then true
469- else (amount == 0))
470- then throw((("invalid amount(leaseAmount:" + toString(balance)) + ")"))
471- else WriteSet([DataEntry(LeaseTxKey, toBase64String(txBytes)), DataEntry(LeaseTxHashKey, txHash), DataEntry(LeasingAmountKey, balance), DataEntry(LeaseTxExpireSendBlockKey, (height + 30)), DataEntry(LeasingExpireBlockKey, (height + leasingInterval))])
525+ else (timestamp > (lastBlock.timestamp + 5400000)))
526+ then throw((("invalid timestamp(lastBlock: " + toString(lastBlock.timestamp)) + ")"))
527+ else if ((getLeaseTxStatus(txHash) == ""))
528+ then throw("tx is exist")
529+ else if (if ((fee > 1000000))
530+ then true
531+ else (500000 > fee))
532+ then throw("invalid fee")
533+ else if (((totalFreeReserve - (leasingAmount + amount)) > reserveWithoutLeasing))
534+ then throw((("invalid amount(result:" + toString(((totalFreeReserve - (leasingAmount + amount)) > reserveWithoutLeasing))) + ")"))
535+ else WriteSet([DataEntry(LeasingTxCountKey, if ((getLeaseTxStatus(txHash) == ""))
536+ then (leasingTxCount + 1)
537+ else leasingTxCount), DataEntry(LeasingAmountKey, (leasingAmount + amount)), DataEntry(LeasingExpireBlockKey, if ((height > leasingExpireBlock))
538+ then (height + leasingInterval)
539+ else leasingExpireBlock), DataEntry(getLeaseTxStatusKey(txHash), NEW), DataEntry(getLeaseTxExpireSendBlockKey(txHash), (height + SENDTXEXPIRE)), DataEntry(getLeaseTxAmountByHashKey(txHash), amount), DataEntry(getLeaseTxBytesByHashKey(txHash), toBase64String(txBytes))])
472540 }
473541
474542
475543
476544 @Callable(i)
477-func registrationUnleaseTx (chainIdString,senderPublicKey,fee,timestamp) = {
545+func cancelStuckLeaseTx (txHash) = if (if (if ((getLeaseTxStatus(txHash) == NEW))
546+ then !(isDefined(transactionHeightById(fromBase58String(txHash))))
547+ else false)
548+ then (height > getLeaseTxExpireSendBlock(txHash))
549+ else false)
550+ then {
551+ let amount = getLeaseTxAmountByHash(txHash)
552+ WriteSet([DataEntry(LeasingTxCountKey, (leasingTxCount - 1)), DataEntry(LeasingAmountKey, (leasingAmount - amount)), DataEntry(getLeaseTxStatusKey(txHash), CANCELED), DataEntry(IsRebalanceKey, if (((reserveWithoutLeasing - amount) >= convertNeutrinoToWaves(swapNeutrinoLockedBalance)))
553+ then false
554+ else true)])
555+ }
556+ else throw("invalid tx hash")
557+
558+
559+
560+@Callable(i)
561+func registrationUnleaseTx (chainIdString,senderPublicKey,fee,timestamp,leaseTxHash) = {
478562 let txBytes = (((((base58'gm' + toBytes(chainIdString)) + fromBase58String(senderPublicKey)) + toBytes(fee)) + toBytes(timestamp)) + fromBase58String(leaseTxHash))
479563 let txHash = blake2b256(txBytes)
480- if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
481- then throw("invalid pubKey")
482- else if (!(isInt(transactionHeightById(txHash))))
483- then throw("blockchain does not contain this transaction")
484- else WriteSet([DataEntry(LeaseTxKey, ""), DataEntry(LeaseTxHashKey, ""), DataEntry(LeasingAmountKey, 0), DataEntry(LeaseTxExpireSendBlockKey, 0), DataEntry(LeasingExpireBlockKey, 0), DataEntry(IsRebalanceKey, false)])
564+ if ((getLeaseTxStatus(leaseTxHash) != NEW))
565+ then throw("invalid tx status")
566+ else if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
567+ then throw("invalid pubKey")
568+ else if (!(isDefined(transactionHeightById(txHash))))
569+ then throw("blockchain does not contain this transaction")
570+ else {
571+ let amount = getLeaseTxAmountByHash(leaseTxHash)
572+ WriteSet([DataEntry(LeasingTxCountKey, (leasingTxCount - 1)), DataEntry(LeasingAmountKey, (leasingAmount - amount)), DataEntry(getLeaseTxStatusKey(leaseTxHash), CANCELED), DataEntry(IsRebalanceKey, if (((reserveWithoutLeasing - amount) >= convertNeutrinoToWaves(swapNeutrinoLockedBalance)))
573+ then false
574+ else true)])
575+ }
485576 }
486577
487578
488579 @Verifier(tx)
489-func verify () = match tx {
490- case leaseTx: LeaseTransaction =>
491- if (if ((fromBase58String(leaseTxHash) == leaseTx.id))
492- then (leasingExpireBlock >= height)
493- else false)
494- then (leaseTxExpireSendBlock >= height)
495- else false
496- case unleaseTx: LeaseCancelTransaction =>
497- if (if ((fromBase58String(leaseTxHash) == unleaseTx.leaseId))
498- then if ((height > leasingExpireBlock))
580+func verify () = {
581+ let id = toBase58String(tx.id)
582+ match tx {
583+ case leaseTx: LeaseTransaction =>
584+ if (if ((leasingExpireBlock >= height))
585+ then (getLeaseTxExpireSendBlock(id) >= height)
586+ else false)
587+ then (getLeaseTxStatusKey(id) == NEW)
588+ else false
589+ case unleaseTx: LeaseCancelTransaction =>
590+ if (if (if ((height > leasingExpireBlock))
499591 then true
500- else isRebalance
501- else false)
502- then if ((unleaseTx.fee >= 500000))
503- then (1000000 >= unleaseTx.fee)
592+ else isRebalance)
593+ then if ((unleaseTx.fee >= 500000))
594+ then (1000000 >= unleaseTx.fee)
595+ else false
596+ else false)
597+ then (getLeaseTxStatusKey(toBase58String(unleaseTx.leaseId)) == NEW)
504598 else false
505- else false
506- case _ =>
507- sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
508-}
599+ case _ =>
600+ sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
601+ }
602+ }
509603
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 3 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func getNumberByKey (key) = match getInteger(this, key) {
55 case a: Int =>
66 a
77 case _ =>
88 0
99 }
1010
1111
1212 func getStringByKey (key) = match getString(this, key) {
1313 case a: String =>
1414 a
1515 case _ =>
1616 ""
1717 }
1818
1919
2020 func getBoolByKey (key) = match getBoolean(this, key) {
2121 case a: Boolean =>
2222 a
2323 case _ =>
2424 false
2525 }
2626
2727
2828 func getNumberByAddressAndKey (address,key) = match getInteger(addressFromStringValue(address), key) {
2929 case a: Int =>
3030 a
3131 case _ =>
3232 0
3333 }
3434
3535
3636 func getStringByAddressAndKey (address,key) = match getString(addressFromStringValue(address), key) {
3737 case a: String =>
3838 a
3939 case _ =>
4040 ""
4141 }
4242
4343
4444 func getBoolByAddressAndKey (address,key) = match getBoolean(addressFromStringValue(address), key) {
4545 case a: Boolean =>
4646 a
4747 case _ =>
4848 false
4949 }
5050
5151
52-func isInt (val) = match val {
53- case a: Int =>
54- true
55- case _ =>
56- false
57-}
58-
52+let SENDTXEXPIRE = 30
5953
6054 let LISTSPLITSYMBOL = "_"
6155
6256 let LISTDATASYMBOL = "+"
6357
6458 let WAVELET = 100000000
6559
6660 let PAULI = 100
6761
6862 let CRYTICALSHARE = 20
6963
70-let LEASINGSHARE = 50
64+let LEASINGSHARE = 90
65+
66+let LEASINTXCOUNT = 10
7167
7268 let CANCELED = "canceled"
7369
7470 let NEW = "new"
7571
7672 let FILLED = "filled"
7773
7874 let NeutrinoAssetIdKey = "neutrino_asset_id"
7975
8076 let BondAssetIdKey = "bond_asset_id"
77+
78+let ReserveContractKey = "reserve_contract"
8179
8280 let AuctionContractKey = "auction_contract"
8381
8482 let RPDContractKey = "rpd_contract"
8583
8684 let ContolContractKey = "control_contract"
8785
8886 let BalanceLockIntervalKey = "balance_lock_interval"
8987
9088 let MinWavesSwapAmountKey = "min_waves_swap_amount"
9189
9290 let MinNeutrinoSwapAmountKey = "min_neutrino_swap_amount"
9391
9492 let NodeAddressKey = "node_address"
9593
9694 let LeasingIntervalKey = "leasing_interval"
9795
9896 let PriceKey = "price"
97+
98+let PriceIndexKey = "price_index"
9999
100100 let ScriptUpdateIntervalKey = "script_update_interval"
101101
102102 let NeutrinoBalanceKey = "neutrino_"
103103
104104 let WavesBalanceKey = "waves_"
105105
106106 let BalanceUnlockBlockKey = "balance_block_"
107107
108108 let OrderbookKey = "orderbook"
109109
110110 let OrderTotalKey = "order_total_"
111111
112112 let OrderOwnerKey = "order_owner_"
113113
114114 let OrderHeightKey = "order_height_"
115115
116116 let OrderFilledTotalKey = "order_filled_total_"
117117
118118 let OrderStatusKey = "order_status_"
119119
120120 let RPDSyncIndexKey = "rpd_sync_index"
121121
122122 let RPDProfitKey = "rpd_profit"
123123
124124 let RPDBalanceKey = "rpd_balance"
125125
126126 let IsBlockedKey = "is_blocked"
127127
128128 let IsLeasingProfitTxExistKey = "is_leasing_profit"
129129
130130 let ScriptUpdateBlockKey = "script_update_block"
131131
132132 let LeaseTxKey = "lease_tx"
133133
134-let LeaseTxHashKey = "lease_tx_hash"
134+let LeaseTxStatusKey = "lease_tx_status"
135135
136136 let LeasingAmountKey = "leasing_amount"
137137
138138 let LeaseTxExpireSendBlockKey = "leasing_expire_send"
139139
140140 let LeasingExpireBlockKey = "leasing_expire_block"
141141
142142 let IsRebalanceKey = "is_rebalance"
143143
144144 let SwapLockedBalanceKey = "swap_locked_balance"
145+
146+let SwapNeutrinoLockedBalanceKey = "swap_neutrino_locked_balance"
147+
148+let LeasingTxCountKey = "leasing_index"
145149
146150 func getRPDSnapshotContractBalanceKey (count,assetId) = ((((RPDBalanceKey + "_") + toBase58String(assetId)) + "_") + toString(count))
147151
148152
149153 func getRPDContractBalanceKey (assetId) = ((RPDBalanceKey + "_") + toBase58String(assetId))
150154
151155
152156 func getRPDProfitKey (count) = ((RPDProfitKey + "_") + toString(count))
153157
154158
155159 func getNeutrinoBalanceKey (owner) = (NeutrinoBalanceKey + owner)
156160
157161
158162 func getWavesBalanceKey (owner) = (WavesBalanceKey + owner)
159163
160164
161165 func getBalanceUnlockBlockKey (owner) = (BalanceUnlockBlockKey + owner)
162166
163167
164168 func getOrderTotalKey (orderId) = (OrderTotalKey + orderId)
165169
166170
167171 func getOrderOwnerKey (orderId) = (OrderOwnerKey + orderId)
168172
169173
170174 func getOrderHeightKey (orderId) = (OrderHeightKey + orderId)
171175
172176
173177 func getOrderStatusKey (orderId) = (OrderStatusKey + orderId)
174178
175179
176180 func getOrderFilledTotalKey (orderId) = (OrderFilledTotalKey + orderId)
177181
178182
183+func getPriceHistoryKey (block) = ((PriceKey + "_") + toString(block))
184+
185+
186+func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index))
187+
188+
189+func getLeaseTxStatusKey (hash) = ((LeaseTxStatusKey + "_") + hash)
190+
191+
192+func getLeaseTxAmountByHashKey (hash) = ((LeasingAmountKey + "_") + hash)
193+
194+
195+func getLeaseTxBytesByHashKey (hash) = ((LeaseTxKey + "_") + hash)
196+
197+
198+func getLeaseTxExpireSendBlockKey (hash) = ((LeaseTxExpireSendBlockKey + "_") + hash)
199+
200+
201+func getIsRebalanceByAddressKey (address) = ((IsRebalanceKey + "_") + address)
202+
203+
179204 let controlContract = getStringByKey(ContolContractKey)
180205
181206 let price = getNumberByAddressAndKey(controlContract, PriceKey)
207+
208+let priceIndex = getNumberByAddressAndKey(controlContract, PriceIndexKey)
209+
210+func convertNeutrinoToWavesByPrice (amount,convertPrice) = ((((amount * 100) / convertPrice) * WAVELET) / PAULI)
211+
182212
183213 func convertNeutrinoToWaves (amount) = ((((amount * 100) / price) * WAVELET) / PAULI)
184214
185215
186216 func convertWavesToNeutrino (amount) = ((((amount * price) / 100) * PAULI) / WAVELET)
187217
188218
189219 func convertNeutrinoToBond (amount) = (amount / PAULI)
190220
191221
192222 func convertBondToNeutrino (amount) = (amount * PAULI)
193223
194224
195225 func convertWavesToBond (amount) = convertNeutrinoToBond(convertWavesToNeutrino(amount))
196226
197227
228+let leasingTxCount = getNumberByKey(LeasingTxCountKey)
229+
198230 let isRebalance = getBoolByKey(IsRebalanceKey)
199231
200232 let leasingInterval = getNumberByKey(LeasingIntervalKey)
201233
202-let leaseTxExpireSendBlock = getNumberByKey(LeaseTxExpireSendBlockKey)
203-
204234 let leasingExpireBlock = getNumberByKey(LeasingExpireBlockKey)
205-
206-let leaseTxHash = getStringByKey(LeaseTxHashKey)
207-
208-let leaseTxBytes = getStringByKey(LeaseTxKey)
209235
210236 let leasingAmount = getNumberByKey(LeasingAmountKey)
211237
212-let swapLockedBalance = getNumberByKey(SwapLockedBalanceKey)
238+let swapNeutrinoLockedBalance = getNumberByKey(SwapNeutrinoLockedBalanceKey)
239+
240+let swapWavesLockedBalance = getNumberByKey(SwapLockedBalanceKey)
213241
214242 let nodeAddress = getStringByKey(NodeAddressKey)
215243
216244 let scriptUpdateInterval = getNumberByAddressAndKey(ContolContractKey, ScriptUpdateIntervalKey)
217245
218246 let scriptUpdateBlock = getNumberByAddressAndKey(controlContract, ScriptUpdateBlockKey)
219247
220248 let rpdSyncIndex = getNumberByKey(RPDSyncIndexKey)
221249
222250 let balanceLockInterval = getNumberByKey(BalanceLockIntervalKey)
223251
224252 let isBlocked = getBoolByAddressAndKey(controlContract, IsBlockedKey)
225253
226254 let minWavesSwapAmount = getNumberByKey(MinWavesSwapAmountKey)
227255
228256 let minNeutrinoSwapAmount = getNumberByKey(MinNeutrinoSwapAmountKey)
229257
230258 let neutrinoAssetId = fromBase58String(getStringByKey(NeutrinoAssetIdKey))
231259
260+let reserveContract = getStringByKey(ReserveContractKey)
261+
232262 let auctionContract = getStringByKey(AuctionContractKey)
233263
234264 let rpdContract = getStringByKey(RPDContractKey)
235265
236-let reserve = (wavesBalance(this) - swapLockedBalance)
266+let reserve = (wavesBalance(this) - swapWavesLockedBalance)
237267
238-let reserveWithoutLeasing = ((wavesBalance(this) - (leasingAmount * (if (isInt(transactionHeightById(fromBase58String(leaseTxHash))))
239- then 1
240- else 0))) - swapLockedBalance)
268+let reserveWithoutLeasing = (reserve - leasingAmount)
241269
242270 let orderbook = getStringByKey(OrderbookKey)
243271
244272 let bondAssetId = fromBase58String(getStringByKey(BondAssetIdKey))
245273
246274 let bondSupply = {
247275 let info = extract(assetInfo(bondAssetId))
248276 (info.quantity - assetBalance(this, bondAssetId))
249277 }
250278
251279 let neutrinoSupply = {
252280 let info = extract(assetInfo(neutrinoAssetId))
253- (info.quantity - assetBalance(this, neutrinoAssetId))
281+ ((info.quantity - assetBalance(this, neutrinoAssetId)) + swapNeutrinoLockedBalance)
254282 }
255283
256284 let surplus = (convertWavesToNeutrino(reserve) - neutrinoSupply)
257285
258286 let deficit = (neutrinoSupply - convertWavesToNeutrino(reserve))
259287
260288 func getRPDContractBalance (assetId) = getNumberByAddressAndKey(rpdContract, getRPDContractBalanceKey(assetId))
261289
262290
263291 func getWavesBalance (owner) = getNumberByKey(getWavesBalanceKey(owner))
264292
265293
266294 func getNeutrinoBalance (owner) = getNumberByKey(getNeutrinoBalanceKey(owner))
267295
268296
269297 func getUnlockBalanceBlock (owner) = getNumberByKey(getBalanceUnlockBlockKey(owner))
270298
271299
272300 func getOrderTotal (id) = getNumberByKey(getOrderTotalKey(id))
273301
274302
275303 func getOrderOwner (id) = getStringByKey(getOrderOwnerKey(id))
276304
277305
278306 func getOrderStatus (id) = getStringByKey(getOrderStatusKey(id))
279307
280308
281309 func getOrderFilledTotal (id) = getNumberByKey(getOrderFilledTotalKey(id))
282310
283311
284312 func getRPDProfit (count) = getNumberByKey(getRPDProfitKey(count))
285313
286314
315+func getPriceHistory (block) = getNumberByAddressAndKey(controlContract, getPriceHistoryKey(block))
316+
317+
318+func getHeightPriceByIndex (index) = getNumberByAddressAndKey(controlContract, getHeightPriceByIndexKey(index))
319+
320+
321+func getLeaseTxStatus (hash) = getStringByKey(getLeaseTxStatusKey(hash))
322+
323+
324+func getLeaseTxAmountByHash (hash) = getNumberByKey(getLeaseTxAmountByHashKey(hash))
325+
326+
327+func getLeaseTxBytesByHash (hash) = getStringByKey(getLeaseTxBytesByHashKey(hash))
328+
329+
330+func getLeaseTxExpireSendBlock (hash) = getNumberByKey(getLeaseTxExpireSendBlockKey(hash))
331+
332+
287333 func getOrderElementById (id) = (id + LISTSPLITSYMBOL)
288334
289335
290336 func addOrder (orderId) = (orderbook + getOrderElementById(orderId))
291337
292338
293339 func dropOrder (orderId) = {
294340 let parts = split(orderbook, getOrderElementById(orderId))
295341 (parts[0] + parts[1])
296342 }
297-
298-
299-@Callable(i)
300-func setPrice () = WriteSet([DataEntry(PriceKey, price)])
301-
302343
303344
304345 @Callable(i)
305346 func swapWavesToNeutrino () = {
306347 let pmt = extract(i.payment)
307348 if ((minWavesSwapAmount > pmt.amount))
308349 then throw("amount less min")
309350 else if (isDefined(pmt.assetId))
310351 then throw("can use waves only")
311352 else if (isBlocked)
312353 then throw("contract is blocked")
313354 else {
314355 let amount = convertWavesToNeutrino(pmt.amount)
315356 TransferSet([ScriptTransfer(i.caller, amount, neutrinoAssetId)])
316357 }
317358 }
318359
319360
320361
321362 @Callable(i)
322363 func swapNeutrinoToWaves () = {
323364 let pmt = extract(i.payment)
365+ let account = toString(i.caller)
324366 if ((minNeutrinoSwapAmount > pmt.amount))
325367 then throw("amount less min")
326368 else if (isBlocked)
327369 then throw("contract is blocked")
328370 else if ((pmt.assetId != neutrinoAssetId))
329371 then throw("can use neutrino only")
330- else {
331- let account = toBase58String(i.caller.bytes)
332- let amount = convertNeutrinoToWaves(pmt.amount)
333- WriteSet([DataEntry(getWavesBalanceKey(account), (getWavesBalance(account) + amount)), DataEntry(getBalanceUnlockBlockKey(account), (height + balanceLockInterval)), DataEntry(IsRebalanceKey, (((reserve * CRYTICALSHARE) / 100) >= (reserveWithoutLeasing - amount))), DataEntry(SwapLockedBalanceKey, (swapLockedBalance + amount))])
334- }
372+ else if ((getUnlockBalanceBlock(account) > height))
373+ then throw((("await " + toString((getUnlockBalanceBlock(account) - height))) + " blocks"))
374+ else if ((getNeutrinoBalance(account) != 0))
375+ then throw("use withdraw")
376+ else {
377+ let neutrinoAmount = pmt.amount
378+ let newSwapNeutrinoLockedBalance = (swapNeutrinoLockedBalance + neutrinoAmount)
379+ WriteSet([DataEntry(getNeutrinoBalanceKey(account), (getNeutrinoBalance(account) + neutrinoAmount)), DataEntry(getBalanceUnlockBlockKey(account), (height + balanceLockInterval)), DataEntry(SwapNeutrinoLockedBalanceKey, newSwapNeutrinoLockedBalance), DataEntry(IsRebalanceKey, if ((reserveWithoutLeasing >= convertNeutrinoToWaves(newSwapNeutrinoLockedBalance)))
380+ then false
381+ else true)])
382+ }
335383 }
336384
337385
338386
339387 @Callable(i)
340-func withdraw (account) = if ((getUnlockBalanceBlock(account) > height))
341- then throw("wait a couple of blocks for withdraw")
342- else ScriptResult(WriteSet([DataEntry(getWavesBalanceKey(account), 0), DataEntry(getNeutrinoBalanceKey(account), 0), DataEntry(SwapLockedBalanceKey, (swapLockedBalance - getWavesBalance(account)))]), TransferSet([ScriptTransfer(addressFromStringValue(account), getNeutrinoBalance(account), neutrinoAssetId), ScriptTransfer(addressFromStringValue(account), getWavesBalance(account), unit)]))
388+func withdraw (account,index) = {
389+ let indexHeight = getHeightPriceByIndex(index)
390+ let nextIndexHeight = getHeightPriceByIndex((index + 1))
391+ let unlockHeight = getUnlockBalanceBlock(account)
392+ let neutrinoAmount = getNeutrinoBalance(account)
393+ let indexPrice = getPriceHistory(indexHeight)
394+ let amount = convertNeutrinoToWavesByPrice(neutrinoAmount, indexPrice)
395+ let totalWavesWithdraw = (getWavesBalance(account) + amount)
396+ if (isBlocked)
397+ then throw("contract is blocked")
398+ else if ((unlockHeight > height))
399+ then throw("wait a couple of blocks for withdraw")
400+ else if (if (if ((index > priceIndex))
401+ then true
402+ else (indexHeight > unlockHeight))
403+ then true
404+ else if ((nextIndexHeight != 0))
405+ then (unlockHeight >= nextIndexHeight)
406+ else false)
407+ then throw("invalid index")
408+ else ScriptResult(WriteSet([DataEntry(getWavesBalanceKey(account), 0), DataEntry(getNeutrinoBalanceKey(account), 0), DataEntry(SwapLockedBalanceKey, (swapWavesLockedBalance - getWavesBalance(account))), DataEntry(SwapNeutrinoLockedBalanceKey, (swapNeutrinoLockedBalance - neutrinoAmount))]), TransferSet([ScriptTransfer(addressFromStringValue(account), totalWavesWithdraw, unit)]))
409+ }
343410
344411
345412
346413 @Callable(i)
347414 func generateBond () = {
348415 let balanceAuction = assetBalance(addressFromStringValue(auctionContract), bondAssetId)
349416 let amount = (convertNeutrinoToBond(deficit) - balanceAuction)
350417 if (isBlocked)
351418 then throw("contract is blocked")
352419 else if ((amount >= 10))
353420 then TransferSet([ScriptTransfer(addressFromStringValue(auctionContract), amount, bondAssetId)])
354421 else throw("bond were generated or do not need it")
355422 }
356423
357424
358425
359426 @Callable(i)
360427 func setOrder () = {
361428 let pmt = extract(i.payment)
362429 let newOrderId = toBase58String(keccak256(((toBytes(pmt.amount) + i.caller.bytes) + toBytes(height))))
363430 if ((pmt.assetId != bondAssetId))
364431 then throw("can use bond only")
365432 else if ((getOrderOwner(newOrderId) != ""))
366433 then throw("order exists")
367434 else WriteSet([DataEntry(OrderbookKey, addOrder(newOrderId)), DataEntry(getOrderTotalKey(newOrderId), pmt.amount), DataEntry(getOrderOwnerKey(newOrderId), toString(i.caller)), DataEntry(getOrderHeightKey(newOrderId), height), DataEntry(getOrderStatusKey(newOrderId), NEW)])
368435 }
369436
370437
371438
372439 @Callable(i)
373440 func cancelOrder (orderId) = {
374441 let owner = getOrderOwner(orderId)
375442 let amount = (getOrderTotal(orderId) - getOrderFilledTotal(orderId))
376443 if ((owner != toString(i.caller)))
377444 then throw("permission denied")
378445 else if ((getOrderStatus(orderId) != NEW))
379446 then throw("invalid order status")
380447 else ScriptResult(WriteSet([DataEntry(OrderbookKey, dropOrder(orderId)), DataEntry(getOrderStatusKey(orderId), CANCELED)]), TransferSet([ScriptTransfer(i.caller, amount, bondAssetId)]))
381448 }
382449
383450
384451
385452 @Callable(i)
386453 func executeOrder () = {
387454 let orderId = split(orderbook, LISTSPLITSYMBOL)[0]
388455 let orderTotal = getOrderTotal(orderId)
389456 let orderOwner = getOrderOwner(orderId)
390457 let filledTotal = getOrderFilledTotal(orderId)
391458 let surplusBond = convertNeutrinoToBond(surplus)
392459 if (isBlocked)
393460 then throw("contract is blocked")
394461 else if ((0 >= surplusBond))
395462 then throw("surplus is less than zero")
396463 else if (if ((orderOwner == ""))
397464 then (surplusBond >= 10)
398465 else false)
399466 then {
400467 let newRpdSyncIndex = (rpdSyncIndex + 1)
401468 ScriptResult(WriteSet([DataEntry(RPDSyncIndexKey, newRpdSyncIndex), DataEntry(getRPDProfitKey(rpdSyncIndex), surplus), DataEntry(getRPDSnapshotContractBalanceKey(rpdSyncIndex, neutrinoAssetId), getRPDContractBalance(neutrinoAssetId))]), TransferSet([ScriptTransfer(addressFromStringValue(rpdContract), surplus, neutrinoAssetId)]))
402469 }
403470 else {
404471 let amount = (orderTotal - filledTotal)
405472 let status = if ((surplusBond >= amount))
406473 then FILLED
407474 else NEW
408475 let newFilledTotal = if ((surplusBond >= amount))
409- then orderTotal
476+ then amount
410477 else surplusBond
411478 ScriptResult(WriteSet([DataEntry(OrderbookKey, if ((surplusBond >= amount))
412479 then dropOrder(orderId)
413480 else orderbook), DataEntry(getOrderFilledTotalKey(orderId), (filledTotal + newFilledTotal)), DataEntry(getOrderStatusKey(orderId), status)]), TransferSet([ScriptTransfer(addressFromStringValue(orderOwner), convertBondToNeutrino(newFilledTotal), neutrinoAssetId)]))
414481 }
415482 }
416483
417484
418485
419486 @Callable(i)
420487 func transfer (account) = {
421488 let pmt = extract(i.payment)
422- if (isDefined(pmt.assetId))
423- then throw("can use waves only at the moment")
424- else TransferSet([ScriptTransfer(addressFromStringValue(account), pmt.amount, unit)])
489+ TransferSet([ScriptTransfer(addressFromStringValue(account), pmt.amount, pmt.assetId)])
425490 }
426491
427492
428493
429494 @Callable(i)
430495 func nodeReward () = {
431496 let pmt = value(i.payment)
432497 if ((i.caller != addressFromStringValue(nodeAddress)))
433498 then throw("permission denied")
434499 else if (isDefined(pmt.assetId))
435500 then throw("waves only")
436501 else {
437502 let amount = convertWavesToNeutrino(pmt.amount)
438503 let newRpdSyncIndex = (rpdSyncIndex + 1)
439504 ScriptResult(WriteSet([DataEntry(RPDSyncIndexKey, newRpdSyncIndex), DataEntry(getRPDProfitKey(rpdSyncIndex), amount), DataEntry(getRPDSnapshotContractBalanceKey(rpdSyncIndex, neutrinoAssetId), getRPDContractBalance(neutrinoAssetId))]), TransferSet([ScriptTransfer(addressFromStringValue(rpdContract), amount, neutrinoAssetId)]))
440505 }
441506 }
442507
443508
444509
445510 @Callable(i)
446-func registrationLeaseTx (senderPublicKey,amount,fee,timestamp) = {
511+func registrationLeaseTx (senderPublicKey,fee,timestamp,leaseTxHash) = {
512+ let totalFreeReserve = (((reserve * LEASINGSHARE) / 100) - convertNeutrinoToWaves(swapNeutrinoLockedBalance))
513+ let amount = (totalFreeReserve / LEASINTXCOUNT)
447514 let txBytes = (((((base58'3h1H' + fromBase58String(senderPublicKey)) + fromBase58String(nodeAddress)) + toBytes(amount)) + toBytes(fee)) + toBytes(timestamp))
448- let balance = ((reserve * LEASINGSHARE) / 100)
449515 let txHashBytes = blake2b256(txBytes)
450516 let txHash = toBase58String(txHashBytes)
451- if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
452- then throw("invalid pubKey")
453- else if (if ((lastBlock.timestamp > timestamp))
454- then true
455- else (timestamp > (lastBlock.timestamp + 5400000)))
456- then throw((("invalid timestamp(lastBlock: " + toString(lastBlock.timestamp)) + ")"))
457- else if (if ((leaseTxHash != ""))
458- then if (isInt(transactionHeightById(fromBase58String(leaseTxHash))))
517+ if ((leaseTxHash != txHash))
518+ then throw("invalid tx hash")
519+ else if ((leasingTxCount >= LEASINTXCOUNT))
520+ then throw("the number of leasing transactions is equal to the maximum")
521+ else if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
522+ then throw("invalid pubKey")
523+ else if (if ((lastBlock.timestamp > timestamp))
459524 then true
460- else (leaseTxExpireSendBlock >= height)
461- else false)
462- then throw("leasing not canceled")
463- else if (if ((fee > 1000000))
464- then true
465- else (500000 > fee))
466- then throw("invalid fee")
467- else if (if ((amount != balance))
468- then true
469- else (amount == 0))
470- then throw((("invalid amount(leaseAmount:" + toString(balance)) + ")"))
471- else WriteSet([DataEntry(LeaseTxKey, toBase64String(txBytes)), DataEntry(LeaseTxHashKey, txHash), DataEntry(LeasingAmountKey, balance), DataEntry(LeaseTxExpireSendBlockKey, (height + 30)), DataEntry(LeasingExpireBlockKey, (height + leasingInterval))])
525+ else (timestamp > (lastBlock.timestamp + 5400000)))
526+ then throw((("invalid timestamp(lastBlock: " + toString(lastBlock.timestamp)) + ")"))
527+ else if ((getLeaseTxStatus(txHash) == ""))
528+ then throw("tx is exist")
529+ else if (if ((fee > 1000000))
530+ then true
531+ else (500000 > fee))
532+ then throw("invalid fee")
533+ else if (((totalFreeReserve - (leasingAmount + amount)) > reserveWithoutLeasing))
534+ then throw((("invalid amount(result:" + toString(((totalFreeReserve - (leasingAmount + amount)) > reserveWithoutLeasing))) + ")"))
535+ else WriteSet([DataEntry(LeasingTxCountKey, if ((getLeaseTxStatus(txHash) == ""))
536+ then (leasingTxCount + 1)
537+ else leasingTxCount), DataEntry(LeasingAmountKey, (leasingAmount + amount)), DataEntry(LeasingExpireBlockKey, if ((height > leasingExpireBlock))
538+ then (height + leasingInterval)
539+ else leasingExpireBlock), DataEntry(getLeaseTxStatusKey(txHash), NEW), DataEntry(getLeaseTxExpireSendBlockKey(txHash), (height + SENDTXEXPIRE)), DataEntry(getLeaseTxAmountByHashKey(txHash), amount), DataEntry(getLeaseTxBytesByHashKey(txHash), toBase64String(txBytes))])
472540 }
473541
474542
475543
476544 @Callable(i)
477-func registrationUnleaseTx (chainIdString,senderPublicKey,fee,timestamp) = {
545+func cancelStuckLeaseTx (txHash) = if (if (if ((getLeaseTxStatus(txHash) == NEW))
546+ then !(isDefined(transactionHeightById(fromBase58String(txHash))))
547+ else false)
548+ then (height > getLeaseTxExpireSendBlock(txHash))
549+ else false)
550+ then {
551+ let amount = getLeaseTxAmountByHash(txHash)
552+ WriteSet([DataEntry(LeasingTxCountKey, (leasingTxCount - 1)), DataEntry(LeasingAmountKey, (leasingAmount - amount)), DataEntry(getLeaseTxStatusKey(txHash), CANCELED), DataEntry(IsRebalanceKey, if (((reserveWithoutLeasing - amount) >= convertNeutrinoToWaves(swapNeutrinoLockedBalance)))
553+ then false
554+ else true)])
555+ }
556+ else throw("invalid tx hash")
557+
558+
559+
560+@Callable(i)
561+func registrationUnleaseTx (chainIdString,senderPublicKey,fee,timestamp,leaseTxHash) = {
478562 let txBytes = (((((base58'gm' + toBytes(chainIdString)) + fromBase58String(senderPublicKey)) + toBytes(fee)) + toBytes(timestamp)) + fromBase58String(leaseTxHash))
479563 let txHash = blake2b256(txBytes)
480- if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
481- then throw("invalid pubKey")
482- else if (!(isInt(transactionHeightById(txHash))))
483- then throw("blockchain does not contain this transaction")
484- else WriteSet([DataEntry(LeaseTxKey, ""), DataEntry(LeaseTxHashKey, ""), DataEntry(LeasingAmountKey, 0), DataEntry(LeaseTxExpireSendBlockKey, 0), DataEntry(LeasingExpireBlockKey, 0), DataEntry(IsRebalanceKey, false)])
564+ if ((getLeaseTxStatus(leaseTxHash) != NEW))
565+ then throw("invalid tx status")
566+ else if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
567+ then throw("invalid pubKey")
568+ else if (!(isDefined(transactionHeightById(txHash))))
569+ then throw("blockchain does not contain this transaction")
570+ else {
571+ let amount = getLeaseTxAmountByHash(leaseTxHash)
572+ WriteSet([DataEntry(LeasingTxCountKey, (leasingTxCount - 1)), DataEntry(LeasingAmountKey, (leasingAmount - amount)), DataEntry(getLeaseTxStatusKey(leaseTxHash), CANCELED), DataEntry(IsRebalanceKey, if (((reserveWithoutLeasing - amount) >= convertNeutrinoToWaves(swapNeutrinoLockedBalance)))
573+ then false
574+ else true)])
575+ }
485576 }
486577
487578
488579 @Verifier(tx)
489-func verify () = match tx {
490- case leaseTx: LeaseTransaction =>
491- if (if ((fromBase58String(leaseTxHash) == leaseTx.id))
492- then (leasingExpireBlock >= height)
493- else false)
494- then (leaseTxExpireSendBlock >= height)
495- else false
496- case unleaseTx: LeaseCancelTransaction =>
497- if (if ((fromBase58String(leaseTxHash) == unleaseTx.leaseId))
498- then if ((height > leasingExpireBlock))
580+func verify () = {
581+ let id = toBase58String(tx.id)
582+ match tx {
583+ case leaseTx: LeaseTransaction =>
584+ if (if ((leasingExpireBlock >= height))
585+ then (getLeaseTxExpireSendBlock(id) >= height)
586+ else false)
587+ then (getLeaseTxStatusKey(id) == NEW)
588+ else false
589+ case unleaseTx: LeaseCancelTransaction =>
590+ if (if (if ((height > leasingExpireBlock))
499591 then true
500- else isRebalance
501- else false)
502- then if ((unleaseTx.fee >= 500000))
503- then (1000000 >= unleaseTx.fee)
592+ else isRebalance)
593+ then if ((unleaseTx.fee >= 500000))
594+ then (1000000 >= unleaseTx.fee)
595+ else false
596+ else false)
597+ then (getLeaseTxStatusKey(toBase58String(unleaseTx.leaseId)) == NEW)
504598 else false
505- else false
506- case _ =>
507- sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
508-}
599+ case _ =>
600+ sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
601+ }
602+ }
509603

github/deemru/w8io/873ac7e 
133.95 ms