2019.10.26 15:23 [1767308] smart account 3PC9BfRwJWWiw9AREE2B3eWzCks3CYtg4yo > SELF 0.00000000 Waves

{ "type": 13, "id": "4NaoQwY1ZoYuk1CYjT3FZ9LAmDswxugHhQsRfuEnBdRv", "fee": 1400000, "feeAssetId": null, "timestamp": 1572092664781, "version": 1, "sender": "3PC9BfRwJWWiw9AREE2B3eWzCks3CYtg4yo", "senderPublicKey": "BRnVwSVctnV8pge5vRpsJdWnkjWEJspFb6QvrmZvu3Ht", "proofs": [ "5g9bQASedAMGdPhp2EPayP7pSrR8cwdddCmZg2RV4a2c48d3wRJBZVZqz2CYR24VgbizXkeAoZkE6WN3HgUN1smV" ], "script": "base64:AAIDAAAAAAAAAC4IARIAEgASBAoCCAESABIAEgMKAQgSABIDCgEIEgASBgoECAEBARIGCgQICAEBAAAAdQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABAAAAA2tleQQAAAAHJG1hdGNoMAkABBoAAAACBQAAAAR0aGlzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAA0ludAQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQAAAAAAAAAAAAEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABAAAAA2tleQQAAAAHJG1hdGNoMAkABB0AAAACBQAAAAR0aGlzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQIAAAAAAQAAAAxnZXRCb29sQnlLZXkAAAABAAAAA2tleQQAAAAHJG1hdGNoMAkABBsAAAACBQAAAAR0aGlzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAB0Jvb2xlYW4EAAAAAWEFAAAAByRtYXRjaDAFAAAAAWEHAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACAAAAB2FkZHJlc3MAAAADa2V5BAAAAAckbWF0Y2gwCQAEGgAAAAIJAQAAABxAZXh0clVzZXIoYWRkcmVzc0Zyb21TdHJpbmcpAAAAAQUAAAAHYWRkcmVzcwUAAAADa2V5AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAANJbnQEAAAAAWEFAAAAByRtYXRjaDAFAAAAAWEAAAAAAAAAAAABAAAAGGdldFN0cmluZ0J5QWRkcmVzc0FuZEtleQAAAAIAAAAHYWRkcmVzcwAAAANrZXkEAAAAByRtYXRjaDAJAAQdAAAAAgkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABBQAAAAdhZGRyZXNzBQAAAANrZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQIAAAAAAQAAABZnZXRCb29sQnlBZGRyZXNzQW5kS2V5AAAAAgAAAAdhZGRyZXNzAAAAA2tleQQAAAAHJG1hdGNoMAkABBsAAAACCQEAAAAcQGV4dHJVc2VyKGFkZHJlc3NGcm9tU3RyaW5nKQAAAAEFAAAAB2FkZHJlc3MFAAAAA2tleQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAHQm9vbGVhbgQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQcAAAAAD0xJU1RTUExJVFNZTUJPTAIAAAABXwAAAAAOTElTVERBVEFTWU1CT0wCAAAAASsAAAAAB1dBVkVMRVQAAAAAAAX14QAAAAAABVBBVUxJAAAAAAAAAABkAAAAAA1DUllUSUNBTFNIQVJFAAAAAAAAAAAUAAAAAAxMRUFTSU5HU0hBUkUAAAAAAAAAADIAAAAACENBTkNFTEVEAgAAAAhjYW5jZWxlZAAAAAADTkVXAgAAAANuZXcAAAAABkZJTExFRAIAAAAGZmlsbGVkAAAAABJOZXV0cmlub0Fzc2V0SWRLZXkCAAAAEW5ldXRyaW5vX2Fzc2V0X2lkAAAAAA5Cb25kQXNzZXRJZEtleQIAAAANYm9uZF9hc3NldF9pZAAAAAASUmVzZXJ2ZUNvbnRyYWN0S2V5AgAAABByZXNlcnZlX2NvbnRyYWN0AAAAABJBdWN0aW9uQ29udHJhY3RLZXkCAAAAEGF1Y3Rpb25fY29udHJhY3QAAAAADlJQRENvbnRyYWN0S2V5AgAAAAxycGRfY29udHJhY3QAAAAAEUNvbnRvbENvbnRyYWN0S2V5AgAAABBjb250cm9sX2NvbnRyYWN0AAAAABZCYWxhbmNlTG9ja0ludGVydmFsS2V5AgAAABViYWxhbmNlX2xvY2tfaW50ZXJ2YWwAAAAAFU1pbldhdmVzU3dhcEFtb3VudEtleQIAAAAVbWluX3dhdmVzX3N3YXBfYW1vdW50AAAAABhNaW5OZXV0cmlub1N3YXBBbW91bnRLZXkCAAAAGG1pbl9uZXV0cmlub19zd2FwX2Ftb3VudAAAAAAOTm9kZUFkZHJlc3NLZXkCAAAADG5vZGVfYWRkcmVzcwAAAAASTGVhc2luZ0ludGVydmFsS2V5AgAAABBsZWFzaW5nX2ludGVydmFsAAAAAAhQcmljZUtleQIAAAAFcHJpY2UAAAAADVByaWNlSW5kZXhLZXkCAAAAC3ByaWNlX2luZGV4AAAAABdTY3JpcHRVcGRhdGVJbnRlcnZhbEtleQIAAAAWc2NyaXB0X3VwZGF0ZV9pbnRlcnZhbAAAAAASTmV1dHJpbm9CYWxhbmNlS2V5AgAAAAluZXV0cmlub18AAAAAD1dhdmVzQmFsYW5jZUtleQIAAAAGd2F2ZXNfAAAAABVCYWxhbmNlVW5sb2NrQmxvY2tLZXkCAAAADmJhbGFuY2VfYmxvY2tfAAAAAAxPcmRlcmJvb2tLZXkCAAAACW9yZGVyYm9vawAAAAANT3JkZXJUb3RhbEtleQIAAAAMb3JkZXJfdG90YWxfAAAAAA1PcmRlck93bmVyS2V5AgAAAAxvcmRlcl9vd25lcl8AAAAADk9yZGVySGVpZ2h0S2V5AgAAAA1vcmRlcl9oZWlnaHRfAAAAABNPcmRlckZpbGxlZFRvdGFsS2V5AgAAABNvcmRlcl9maWxsZWRfdG90YWxfAAAAAA5PcmRlclN0YXR1c0tleQIAAAANb3JkZXJfc3RhdHVzXwAAAAAPUlBEU3luY0luZGV4S2V5AgAAAA5ycGRfc3luY19pbmRleAAAAAAMUlBEUHJvZml0S2V5AgAAAApycGRfcHJvZml0AAAAAA1SUERCYWxhbmNlS2V5AgAAAAtycGRfYmFsYW5jZQAAAAAMSXNCbG9ja2VkS2V5AgAAAAppc19ibG9ja2VkAAAAABlJc0xlYXNpbmdQcm9maXRUeEV4aXN0S2V5AgAAABFpc19sZWFzaW5nX3Byb2ZpdAAAAAAUU2NyaXB0VXBkYXRlQmxvY2tLZXkCAAAAE3NjcmlwdF91cGRhdGVfYmxvY2sAAAAACkxlYXNlVHhLZXkCAAAACGxlYXNlX3R4AAAAAA5MZWFzZVR4SGFzaEtleQIAAAANbGVhc2VfdHhfaGFzaAAAAAAQTGVhc2luZ0Ftb3VudEtleQIAAAAObGVhc2luZ19hbW91bnQAAAAAGUxlYXNlVHhFeHBpcmVTZW5kQmxvY2tLZXkCAAAAE2xlYXNpbmdfZXhwaXJlX3NlbmQAAAAAFUxlYXNpbmdFeHBpcmVCbG9ja0tleQIAAAAUbGVhc2luZ19leHBpcmVfYmxvY2sAAAAADklzUmViYWxhbmNlS2V5AgAAAAxpc19yZWJhbGFuY2UAAAAAFFN3YXBMb2NrZWRCYWxhbmNlS2V5AgAAABNzd2FwX2xvY2tlZF9iYWxhbmNlAAAAABxTd2FwTmV1dHJpbm9Mb2NrZWRCYWxhbmNlS2V5AgAAABxzd2FwX25ldXRyaW5vX2xvY2tlZF9iYWxhbmNlAQAAACBnZXRSUERTbmFwc2hvdENvbnRyYWN0QmFsYW5jZUtleQAAAAIAAAAFY291bnQAAAAHYXNzZXRJZAkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACBQAAAA1SUERCYWxhbmNlS2V5AgAAAAFfCQACWAAAAAEFAAAAB2Fzc2V0SWQCAAAAAV8JAAGkAAAAAQUAAAAFY291bnQBAAAAGGdldFJQRENvbnRyYWN0QmFsYW5jZUtleQAAAAEAAAAHYXNzZXRJZAkAASwAAAACCQABLAAAAAIFAAAADVJQREJhbGFuY2VLZXkCAAAAAV8JAAJYAAAAAQUAAAAHYXNzZXRJZAEAAAAPZ2V0UlBEUHJvZml0S2V5AAAAAQAAAAVjb3VudAkAASwAAAACCQABLAAAAAIFAAAADFJQRFByb2ZpdEtleQIAAAABXwkAAaQAAAABBQAAAAVjb3VudAEAAAAVZ2V0TmV1dHJpbm9CYWxhbmNlS2V5AAAAAQAAAAVvd25lcgkAASwAAAACBQAAABJOZXV0cmlub0JhbGFuY2VLZXkFAAAABW93bmVyAQAAABJnZXRXYXZlc0JhbGFuY2VLZXkAAAABAAAABW93bmVyCQABLAAAAAIFAAAAD1dhdmVzQmFsYW5jZUtleQUAAAAFb3duZXIBAAAAGGdldEJhbGFuY2VVbmxvY2tCbG9ja0tleQAAAAEAAAAFb3duZXIJAAEsAAAAAgUAAAAVQmFsYW5jZVVubG9ja0Jsb2NrS2V5BQAAAAVvd25lcgEAAAAQZ2V0T3JkZXJUb3RhbEtleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACBQAAAA1PcmRlclRvdGFsS2V5BQAAAAdvcmRlcklkAQAAABBnZXRPcmRlck93bmVyS2V5AAAAAQAAAAdvcmRlcklkCQABLAAAAAIFAAAADU9yZGVyT3duZXJLZXkFAAAAB29yZGVySWQBAAAAEWdldE9yZGVySGVpZ2h0S2V5AAAAAQAAAAdvcmRlcklkCQABLAAAAAIFAAAADk9yZGVySGVpZ2h0S2V5BQAAAAdvcmRlcklkAQAAABFnZXRPcmRlclN0YXR1c0tleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACBQAAAA5PcmRlclN0YXR1c0tleQUAAAAHb3JkZXJJZAEAAAAWZ2V0T3JkZXJGaWxsZWRUb3RhbEtleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACBQAAABNPcmRlckZpbGxlZFRvdGFsS2V5BQAAAAdvcmRlcklkAQAAABJnZXRQcmljZUhpc3RvcnlLZXkAAAABAAAABWJsb2NrCQABLAAAAAIJAAEsAAAAAgUAAAAIUHJpY2VLZXkCAAAAAV8JAAGkAAAAAQUAAAAFYmxvY2sBAAAAGGdldEhlaWdodFByaWNlQnlJbmRleEtleQAAAAEAAAAFaW5kZXgJAAEsAAAAAgkAASwAAAACBQAAAA1QcmljZUluZGV4S2V5AgAAAAFfCQABpAAAAAEFAAAABWluZGV4AAAAAA9jb250cm9sQ29udHJhY3QJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEFAAAAEUNvbnRvbENvbnRyYWN0S2V5AAAAAAVwcmljZQkBAAAAGGdldE51bWJlckJ5QWRkcmVzc0FuZEtleQAAAAIFAAAAD2NvbnRyb2xDb250cmFjdAUAAAAIUHJpY2VLZXkAAAAACnByaWNlSW5kZXgJAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACBQAAAA9jb250cm9sQ29udHJhY3QFAAAADVByaWNlSW5kZXhLZXkBAAAAHWNvbnZlcnROZXV0cmlub1RvV2F2ZXNCeVByaWNlAAAAAgAAAAZhbW91bnQAAAAMY29udmVydFByaWNlCQAAaQAAAAIJAABoAAAAAgkAAGkAAAACCQAAaAAAAAIFAAAABmFtb3VudAAAAAAAAAAAZAUAAAAMY29udmVydFByaWNlBQAAAAdXQVZFTEVUBQAAAAVQQVVMSQEAAAAWY29udmVydE5ldXRyaW5vVG9XYXZlcwAAAAEAAAAGYW1vdW50CQAAaQAAAAIJAABoAAAAAgkAAGkAAAACCQAAaAAAAAIFAAAABmFtb3VudAAAAAAAAAAAZAUAAAAFcHJpY2UFAAAAB1dBVkVMRVQFAAAABVBBVUxJAQAAABZjb252ZXJ0V2F2ZXNUb05ldXRyaW5vAAAAAQAAAAZhbW91bnQJAABpAAAAAgkAAGgAAAACCQAAaQAAAAIJAABoAAAAAgUAAAAGYW1vdW50BQAAAAVwcmljZQAAAAAAAAAAZAUAAAAFUEFVTEkFAAAAB1dBVkVMRVQBAAAAFWNvbnZlcnROZXV0cmlub1RvQm9uZAAAAAEAAAAGYW1vdW50CQAAaQAAAAIFAAAABmFtb3VudAUAAAAFUEFVTEkBAAAAFWNvbnZlcnRCb25kVG9OZXV0cmlubwAAAAEAAAAGYW1vdW50CQAAaAAAAAIFAAAABmFtb3VudAUAAAAFUEFVTEkBAAAAEmNvbnZlcnRXYXZlc1RvQm9uZAAAAAEAAAAGYW1vdW50CQEAAAAVY29udmVydE5ldXRyaW5vVG9Cb25kAAAAAQkBAAAAFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8AAAABBQAAAAZhbW91bnQAAAAAC2lzUmViYWxhbmNlCQEAAAAMZ2V0Qm9vbEJ5S2V5AAAAAQUAAAAOSXNSZWJhbGFuY2VLZXkAAAAAD2xlYXNpbmdJbnRlcnZhbAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQUAAAASTGVhc2luZ0ludGVydmFsS2V5AAAAABZsZWFzZVR4RXhwaXJlU2VuZEJsb2NrCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABBQAAABlMZWFzZVR4RXhwaXJlU2VuZEJsb2NrS2V5AAAAABJsZWFzaW5nRXhwaXJlQmxvY2sJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEFAAAAFUxlYXNpbmdFeHBpcmVCbG9ja0tleQAAAAALbGVhc2VUeEhhc2gJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEFAAAADkxlYXNlVHhIYXNoS2V5AAAAAAxsZWFzZVR4Qnl0ZXMJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEFAAAACkxlYXNlVHhLZXkAAAAADWxlYXNpbmdBbW91bnQJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEFAAAAEExlYXNpbmdBbW91bnRLZXkAAAAAGXN3YXBOZXV0cmlub0xvY2tlZEJhbGFuY2UJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEFAAAAHFN3YXBOZXV0cmlub0xvY2tlZEJhbGFuY2VLZXkAAAAAFnN3YXBXYXZlc0xvY2tlZEJhbGFuY2UJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEFAAAAFFN3YXBMb2NrZWRCYWxhbmNlS2V5AAAAAAtub2RlQWRkcmVzcwkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAAOTm9kZUFkZHJlc3NLZXkAAAAAFHNjcmlwdFVwZGF0ZUludGVydmFsCQEAAAAYZ2V0TnVtYmVyQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAARQ29udG9sQ29udHJhY3RLZXkFAAAAF1NjcmlwdFVwZGF0ZUludGVydmFsS2V5AAAAABFzY3JpcHRVcGRhdGVCbG9jawkBAAAAGGdldE51bWJlckJ5QWRkcmVzc0FuZEtleQAAAAIFAAAAD2NvbnRyb2xDb250cmFjdAUAAAAUU2NyaXB0VXBkYXRlQmxvY2tLZXkAAAAADHJwZFN5bmNJbmRleAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQUAAAAPUlBEU3luY0luZGV4S2V5AAAAABNiYWxhbmNlTG9ja0ludGVydmFsCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABBQAAABZCYWxhbmNlTG9ja0ludGVydmFsS2V5AAAAAAlpc0Jsb2NrZWQJAQAAABZnZXRCb29sQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAAPY29udHJvbENvbnRyYWN0BQAAAAxJc0Jsb2NrZWRLZXkAAAAAEm1pbldhdmVzU3dhcEFtb3VudAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQUAAAAVTWluV2F2ZXNTd2FwQW1vdW50S2V5AAAAABVtaW5OZXV0cmlub1N3YXBBbW91bnQJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEFAAAAGE1pbk5ldXRyaW5vU3dhcEFtb3VudEtleQAAAAAPbmV1dHJpbm9Bc3NldElkCQACWQAAAAEJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEFAAAAEk5ldXRyaW5vQXNzZXRJZEtleQAAAAAPcmVzZXJ2ZUNvbnRyYWN0CQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAABJSZXNlcnZlQ29udHJhY3RLZXkAAAAAD2F1Y3Rpb25Db250cmFjdAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAASQXVjdGlvbkNvbnRyYWN0S2V5AAAAAAtycGRDb250cmFjdAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAAOUlBEQ29udHJhY3RLZXkAAAAAB3Jlc2VydmUJAABlAAAAAgkBAAAADHdhdmVzQmFsYW5jZQAAAAEFAAAABHRoaXMFAAAAFnN3YXBXYXZlc0xvY2tlZEJhbGFuY2UAAAAAFXJlc2VydmVXaXRob3V0TGVhc2luZwkAAGUAAAACBQAAAAdyZXNlcnZlCQAAaAAAAAIFAAAADWxlYXNpbmdBbW91bnQDCQEAAAAJaXNEZWZpbmVkAAAAAQkAA+kAAAABCQACWQAAAAEFAAAAC2xlYXNlVHhIYXNoAAAAAAAAAAABAAAAAAAAAAAAAAAAAAlvcmRlcmJvb2sJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEFAAAADE9yZGVyYm9va0tleQAAAAALYm9uZEFzc2V0SWQJAAJZAAAAAQkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAAOQm9uZEFzc2V0SWRLZXkAAAAACmJvbmRTdXBwbHkEAAAABGluZm8JAQAAAAdleHRyYWN0AAAAAQkAA+wAAAABBQAAAAtib25kQXNzZXRJZAkAAGUAAAACCAUAAAAEaW5mbwAAAAhxdWFudGl0eQkAA+sAAAACBQAAAAR0aGlzBQAAAAtib25kQXNzZXRJZAAAAAAObmV1dHJpbm9TdXBwbHkEAAAABGluZm8JAQAAAAdleHRyYWN0AAAAAQkAA+wAAAABBQAAAA9uZXV0cmlub0Fzc2V0SWQJAABkAAAAAgkAAGUAAAACCAUAAAAEaW5mbwAAAAhxdWFudGl0eQkAA+sAAAACBQAAAAR0aGlzBQAAAA9uZXV0cmlub0Fzc2V0SWQFAAAAGXN3YXBOZXV0cmlub0xvY2tlZEJhbGFuY2UAAAAAB3N1cnBsdXMJAABlAAAAAgkBAAAAFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8AAAABBQAAAAdyZXNlcnZlBQAAAA5uZXV0cmlub1N1cHBseQAAAAAHZGVmaWNpdAkAAGUAAAACBQAAAA5uZXV0cmlub1N1cHBseQkBAAAAFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8AAAABBQAAAAdyZXNlcnZlAQAAABVnZXRSUERDb250cmFjdEJhbGFuY2UAAAABAAAAB2Fzc2V0SWQJAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACBQAAAAtycGRDb250cmFjdAkBAAAAGGdldFJQRENvbnRyYWN0QmFsYW5jZUtleQAAAAEFAAAAB2Fzc2V0SWQBAAAAD2dldFdhdmVzQmFsYW5jZQAAAAEAAAAFb3duZXIJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABJnZXRXYXZlc0JhbGFuY2VLZXkAAAABBQAAAAVvd25lcgEAAAASZ2V0TmV1dHJpbm9CYWxhbmNlAAAAAQAAAAVvd25lcgkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAFWdldE5ldXRyaW5vQmFsYW5jZUtleQAAAAEFAAAABW93bmVyAQAAABVnZXRVbmxvY2tCYWxhbmNlQmxvY2sAAAABAAAABW93bmVyCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAYZ2V0QmFsYW5jZVVubG9ja0Jsb2NrS2V5AAAAAQUAAAAFb3duZXIBAAAADWdldE9yZGVyVG90YWwAAAABAAAAAmlkCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAAQZ2V0T3JkZXJUb3RhbEtleQAAAAEFAAAAAmlkAQAAAA1nZXRPcmRlck93bmVyAAAAAQAAAAJpZAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQkBAAAAEGdldE9yZGVyT3duZXJLZXkAAAABBQAAAAJpZAEAAAAOZ2V0T3JkZXJTdGF0dXMAAAABAAAAAmlkCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABCQEAAAARZ2V0T3JkZXJTdGF0dXNLZXkAAAABBQAAAAJpZAEAAAATZ2V0T3JkZXJGaWxsZWRUb3RhbAAAAAEAAAACaWQJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABZnZXRPcmRlckZpbGxlZFRvdGFsS2V5AAAAAQUAAAACaWQBAAAADGdldFJQRFByb2ZpdAAAAAEAAAAFY291bnQJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAAA9nZXRSUERQcm9maXRLZXkAAAABBQAAAAVjb3VudAEAAAAPZ2V0UHJpY2VIaXN0b3J5AAAAAQAAAAVibG9jawkBAAAAGGdldE51bWJlckJ5QWRkcmVzc0FuZEtleQAAAAIFAAAAD2NvbnRyb2xDb250cmFjdAkBAAAAEmdldFByaWNlSGlzdG9yeUtleQAAAAEFAAAABWJsb2NrAQAAABVnZXRIZWlnaHRQcmljZUJ5SW5kZXgAAAABAAAABWluZGV4CQEAAAAYZ2V0TnVtYmVyQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAAPY29udHJvbENvbnRyYWN0CQEAAAAYZ2V0SGVpZ2h0UHJpY2VCeUluZGV4S2V5AAAAAQUAAAAFaW5kZXgBAAAAE2dldE9yZGVyRWxlbWVudEJ5SWQAAAABAAAAAmlkCQABLAAAAAIFAAAAAmlkBQAAAA9MSVNUU1BMSVRTWU1CT0wBAAAACGFkZE9yZGVyAAAAAQAAAAdvcmRlcklkCQABLAAAAAIFAAAACW9yZGVyYm9vawkBAAAAE2dldE9yZGVyRWxlbWVudEJ5SWQAAAABBQAAAAdvcmRlcklkAQAAAAlkcm9wT3JkZXIAAAABAAAAB29yZGVySWQEAAAABXBhcnRzCQAEtQAAAAIFAAAACW9yZGVyYm9vawkBAAAAE2dldE9yZGVyRWxlbWVudEJ5SWQAAAABBQAAAAdvcmRlcklkCQABLAAAAAIJAAGRAAAAAgUAAAAFcGFydHMAAAAAAAAAAAAJAAGRAAAAAgUAAAAFcGFydHMAAAAAAAAAAAEAAAALAAAAAWkBAAAAE3N3YXBXYXZlc1RvTmV1dHJpbm8AAAAABAAAAANwbXQJAQAAAAdleHRyYWN0AAAAAQgFAAAAAWkAAAAHcGF5bWVudAMJAABmAAAAAgUAAAASbWluV2F2ZXNTd2FwQW1vdW50CAUAAAADcG10AAAABmFtb3VudAkAAAIAAAABAgAAAA9hbW91bnQgbGVzcyBtaW4DCQEAAAAJaXNEZWZpbmVkAAAAAQgFAAAAA3BtdAAAAAdhc3NldElkCQAAAgAAAAECAAAAEmNhbiB1c2Ugd2F2ZXMgb25seQMFAAAACWlzQmxvY2tlZAkAAAIAAAABAgAAABNjb250cmFjdCBpcyBibG9ja2VkBAAAAAZhbW91bnQJAQAAABZjb252ZXJ0V2F2ZXNUb05ldXRyaW5vAAAAAQgFAAAAA3BtdAAAAAZhbW91bnQJAQAAAAtUcmFuc2ZlclNldAAAAAEJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAZhbW91bnQFAAAAD25ldXRyaW5vQXNzZXRJZAUAAAADbmlsAAAAAWkBAAAAE3N3YXBOZXV0cmlub1RvV2F2ZXMAAAAABAAAAANwbXQJAQAAAAdleHRyYWN0AAAAAQgFAAAAAWkAAAAHcGF5bWVudAQAAAAHYWNjb3VudAkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIDCQAAZgAAAAIFAAAAFW1pbk5ldXRyaW5vU3dhcEFtb3VudAgFAAAAA3BtdAAAAAZhbW91bnQJAAACAAAAAQIAAAAPYW1vdW50IGxlc3MgbWluAwUAAAAJaXNCbG9ja2VkCQAAAgAAAAECAAAAE2NvbnRyYWN0IGlzIGJsb2NrZWQDCQEAAAACIT0AAAACCAUAAAADcG10AAAAB2Fzc2V0SWQFAAAAD25ldXRyaW5vQXNzZXRJZAkAAAIAAAABAgAAABVjYW4gdXNlIG5ldXRyaW5vIG9ubHkDCQAAZgAAAAIJAQAAABVnZXRVbmxvY2tCYWxhbmNlQmxvY2sAAAABBQAAAAdhY2NvdW50BQAAAAZoZWlnaHQJAAACAAAAAQkAASwAAAACCQABLAAAAAICAAAABmF3YWl0IAkAAaQAAAABCQAAZQAAAAIJAQAAABVnZXRVbmxvY2tCYWxhbmNlQmxvY2sAAAABBQAAAAdhY2NvdW50BQAAAAZoZWlnaHQCAAAAByBibG9ja3MDCQEAAAACIT0AAAACCQEAAAASZ2V0TmV1dHJpbm9CYWxhbmNlAAAAAQUAAAAHYWNjb3VudAAAAAAAAAAAAAkAAAIAAAABAgAAAAx1c2Ugd2l0aGRyYXcEAAAADm5ldXRyaW5vQW1vdW50CAUAAAADcG10AAAABmFtb3VudAQAAAAGYW1vdW50CQEAAAAWY29udmVydE5ldXRyaW5vVG9XYXZlcwAAAAEFAAAADm5ldXRyaW5vQW1vdW50CQEAAAAIV3JpdGVTZXQAAAABCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAVZ2V0TmV1dHJpbm9CYWxhbmNlS2V5AAAAAQUAAAAHYWNjb3VudAkAAGQAAAACCQEAAAASZ2V0TmV1dHJpbm9CYWxhbmNlAAAAAQUAAAAHYWNjb3VudAUAAAAObmV1dHJpbm9BbW91bnQJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAABhnZXRCYWxhbmNlVW5sb2NrQmxvY2tLZXkAAAABBQAAAAdhY2NvdW50CQAAZAAAAAIFAAAABmhlaWdodAUAAAATYmFsYW5jZUxvY2tJbnRlcnZhbAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgUAAAAOSXNSZWJhbGFuY2VLZXkJAABnAAAAAgkAAGkAAAACCQAAaAAAAAIFAAAAB3Jlc2VydmUFAAAADUNSWVRJQ0FMU0hBUkUAAAAAAAAAAGQJAABlAAAAAgUAAAAVcmVzZXJ2ZVdpdGhvdXRMZWFzaW5nBQAAAAZhbW91bnQJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIFAAAAHFN3YXBOZXV0cmlub0xvY2tlZEJhbGFuY2VLZXkJAABkAAAAAgUAAAAZc3dhcE5ldXRyaW5vTG9ja2VkQmFsYW5jZQUAAAAObmV1dHJpbm9BbW91bnQFAAAAA25pbAAAAAFpAQAAAAh3aXRoZHJhdwAAAAIAAAAHYWNjb3VudAAAAAVpbmRleAQAAAALaW5kZXhIZWlnaHQJAQAAABVnZXRIZWlnaHRQcmljZUJ5SW5kZXgAAAABBQAAAAVpbmRleAQAAAAPbmV4dEluZGV4SGVpZ2h0CQEAAAAVZ2V0SGVpZ2h0UHJpY2VCeUluZGV4AAAAAQkAAGQAAAACBQAAAAVpbmRleAAAAAAAAAAAAQQAAAAMdW5sb2NrSGVpZ2h0CQEAAAAVZ2V0VW5sb2NrQmFsYW5jZUJsb2NrAAAAAQUAAAAHYWNjb3VudAMFAAAACWlzQmxvY2tlZAkAAAIAAAABAgAAABNjb250cmFjdCBpcyBibG9ja2VkAwkAAGYAAAACBQAAAAx1bmxvY2tIZWlnaHQFAAAABmhlaWdodAkAAAIAAAABAgAAACR3YWl0IGEgY291cGxlIG9mIGJsb2NrcyBmb3Igd2l0aGRyYXcDAwMJAABmAAAAAgUAAAAFaW5kZXgFAAAACnByaWNlSW5kZXgGCQAAZgAAAAIFAAAAC2luZGV4SGVpZ2h0BQAAAAx1bmxvY2tIZWlnaHQGAwkBAAAAAiE9AAAAAgUAAAAPbmV4dEluZGV4SGVpZ2h0AAAAAAAAAAAACQAAZwAAAAIFAAAADHVubG9ja0hlaWdodAUAAAAPbmV4dEluZGV4SGVpZ2h0BwkAAAIAAAABAgAAAA1pbnZhbGlkIGluZGV4BAAAAAppbmRleFByaWNlCQEAAAAPZ2V0UHJpY2VIaXN0b3J5AAAAAQUAAAALaW5kZXhIZWlnaHQEAAAADm5ldXRyaW5vQW1vdW50CQEAAAASZ2V0TmV1dHJpbm9CYWxhbmNlAAAAAQUAAAAHYWNjb3VudAQAAAAGYW1vdW50CQEAAAAdY29udmVydE5ldXRyaW5vVG9XYXZlc0J5UHJpY2UAAAACBQAAAA5uZXV0cmlub0Ftb3VudAUAAAAKaW5kZXhQcmljZQkBAAAADFNjcmlwdFJlc3VsdAAAAAIJAQAAAAhXcml0ZVNldAAAAAEJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAABJnZXRXYXZlc0JhbGFuY2VLZXkAAAABBQAAAAdhY2NvdW50AAAAAAAAAAAACQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAVZ2V0TmV1dHJpbm9CYWxhbmNlS2V5AAAAAQUAAAAHYWNjb3VudAAAAAAAAAAAAAkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgUAAAAUU3dhcExvY2tlZEJhbGFuY2VLZXkJAABlAAAAAgUAAAAWc3dhcFdhdmVzTG9ja2VkQmFsYW5jZQkBAAAAD2dldFdhdmVzQmFsYW5jZQAAAAEFAAAAB2FjY291bnQJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIFAAAAHFN3YXBOZXV0cmlub0xvY2tlZEJhbGFuY2VLZXkJAABlAAAAAgUAAAAZc3dhcE5ldXRyaW5vTG9ja2VkQmFsYW5jZQUAAAAObmV1dHJpbm9BbW91bnQFAAAAA25pbAkBAAAAC1RyYW5zZmVyU2V0AAAAAQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCQEAAAAcQGV4dHJVc2VyKGFkZHJlc3NGcm9tU3RyaW5nKQAAAAEFAAAAB2FjY291bnQJAABkAAAAAgkBAAAAD2dldFdhdmVzQmFsYW5jZQAAAAEFAAAAB2FjY291bnQFAAAABmFtb3VudAUAAAAEdW5pdAUAAAADbmlsAAAAAWkB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AANuaWwJAQAAAAtUcmFuc2ZlclNldAAAAAEJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAZhbW91bnQFAAAAC2JvbmRBc3NldElkBQAAAANuaWwAAAABaQEAAAAMZXhlY3V0ZU9yZGVyAAAAAAQAAAAHb3JkZXJJZAkAAZEAAAACCQAEtQAAAAIFAAAACW9yZGVyYm9vawUAAAAPTElTVFNQTElUU1lNQk9MAAAAAAAAAAAABAAAAApvcmRlclRvdGFsCQEAAAANZ2V0T3JkZXJUb3RhbAAAAAEFAAAAB29yZGVySWQEAAAACm9yZGVyT3duZXIJAQAAAA1nZXRPcmRlck93bmVyAAAAAQUAAAAHb3JkZXJJZAQAAAALZmlsbGVkVG90YWwJAQAAABNnZXRPcmRlckZpbGxlZFRvdGFsAAAAAQUAAAAHb3JkZXJJZAQAAAALc3VycGx1c0JvbmQJAQAAABVjb252ZXJ0TmV1dHJpbm9Ub0JvbmQAAAABBQAAAAdzdXJwbHVzAwUAAAAJaXNCbG9ja2VkCQAAAgAAAAECAAAAE2NvbnRyYWN0IGlzIGJsb2NrZWQDCQAAZwAAAAIAAAAAAAAAAAAFAAAAC3N1cnBsdXNCb25kCQAAAgAAAAECAAAAGXN1cnBsdXMgaXMgbGVzcyB0aGFuIHplcm8DAwkAAAAAAAACBQAAAApvcmRlck93bmVyAgAAAAAJAABnAAAAAgUAAAALc3VycGx1c0JvbmQAAAAAAAAAAAoHBAAAAA9uZXdScGRTeW5jSW5kZXgJAABkAAAAAgUAAAAMcnBkU3luY0luZGV4AAAAAAAAAAABCQEAAAAMU2NyaXB0UmVzdWx0AAAAAgkBAAAACFdyaXRlU2V0AAAAAQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgUAAAAPUlBEU3luY0luZGV4S2V5BQAAAA9uZXdScGRTeW5jSW5kZXgJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAAA9nZXRSUERQcm9maXRLZXkAAAABBQAAAAxycGRTeW5jSW5kZXgFAAAAB3N1cnBsdXMJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAACBnZXRSUERTbmFwc2hvdENvbnRyYWN0QmFsYW5jZUtleQAAAAIFAAAADHJwZFN5bmNJbmRleAUAAAAPbmV1dHJpbm9Bc3NldElkCQEAAAAVZ2V0UlBEQ29udHJhY3RCYWxhbmNlAAAAAQUAAAAPbmV1dHJpbm9Bc3NldElkBQAAAANuaWwJAQAAAAtUcmFuc2ZlclNldAAAAAEJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwkBAAAAHEBleHRyVXNlcihhZGRyZXNzRnJvbVN0cmluZykAAAABBQAAAAtycGRDb250cmFjdAUAAAAHc3VycGx1cwUAAAAPbmV1dHJpbm9Bc3NldElkBQAAAANuaWwEAAAABmFtb3VudAkAAGUAAAACBQAAAApvcmRlclRvdGFsBQAAAAtmaWxsZWRUb3RhbAQAAAAGc3RhdHVzAwkAAGcAAAACBQAAAAtzdXJwbHVzQm9uZAUAAAAGYW1vdW50BQAAAAZGSUxMRUQFAAAAA05FVwQAAAAObmV3RmlsbGVkVG90YWwDCQAAZwAAAAIFAAAAC3N1cnBsdXNCb25kBQAAAAZhbW91bnQFAAAABmFtb3VudAUAAAALc3VycGx1c0JvbmQJAQAAAAxTY3JpcHRSZXN1bHQAAAACCQEAAAAIV3JpdGVTZXQAAAABCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACBQAAAAxPcmRlcmJvb2tLZXkDCQAAZwAAAAIFAAAAC3N1cnBsdXNCb25kBQAAAAZhbW91bnQJAQAAAAlkcm9wT3JkZXIAAAABBQAAAAdvcmRlcklkBQAAAAlvcmRlcmJvb2sJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAABZnZXRPcmRlckZpbGxlZFRvdGFsS2V5AAAAAQUAAAAHb3JkZXJJZAkAAGQAAAACBQAAAAtmaWxsZWRUb3RhbAUAAAAObmV3RmlsbGVkVG90YWwJAARMAAAAAgkBAAAACURhdGFFbnRyeQAAAAIJAQAAABFnZXRPcmRlclN0YXR1c0tleQAAAAEFAAAAB29yZGVySWQFAAAABnN0YXR1cwUAAAADbmlsCQEAAAALVHJhbnNmZXJTZXQAAAABCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMJAQAAABxAZXh0clVzZXIoYWRkcmVzc0Zy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", "chainId": 87, "height": 1767308, "spentComplexity": 0 } View: original | compacted Prev: 73j1bwzmZ2vHDzcx1DMbgX1FXJwyBAHFFSR52YuwB7md Next: GBUC3pfCBVG49gjDB4UeSzJLUps1UCucCGcyGNtfXSud Diff:
OldNewDifferences
4949 }
5050
5151
52-func isInt (val) = match val {
53- case a: Int =>
54- true
55- case _ =>
56- false
57-}
58-
59-
6052 let LISTSPLITSYMBOL = "_"
6153
6254 let LISTDATASYMBOL = "+"
7971
8072 let BondAssetIdKey = "bond_asset_id"
8173
74+let ReserveContractKey = "reserve_contract"
75+
8276 let AuctionContractKey = "auction_contract"
8377
8478 let RPDContractKey = "rpd_contract"
9690 let LeasingIntervalKey = "leasing_interval"
9791
9892 let PriceKey = "price"
93+
94+let PriceIndexKey = "price_index"
9995
10096 let ScriptUpdateIntervalKey = "script_update_interval"
10197
143139
144140 let SwapLockedBalanceKey = "swap_locked_balance"
145141
142+let SwapNeutrinoLockedBalanceKey = "swap_neutrino_locked_balance"
143+
146144 func getRPDSnapshotContractBalanceKey (count,assetId) = ((((RPDBalanceKey + "_") + toBase58String(assetId)) + "_") + toString(count))
147145
148146
176174 func getOrderFilledTotalKey (orderId) = (OrderFilledTotalKey + orderId)
177175
178176
177+func getPriceHistoryKey (block) = ((PriceKey + "_") + toString(block))
178+
179+
180+func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index))
181+
182+
179183 let controlContract = getStringByKey(ContolContractKey)
180184
181185 let price = getNumberByAddressAndKey(controlContract, PriceKey)
186+
187+let priceIndex = getNumberByAddressAndKey(controlContract, PriceIndexKey)
188+
189+func convertNeutrinoToWavesByPrice (amount,convertPrice) = ((((amount * 100) / convertPrice) * WAVELET) / PAULI)
190+
182191
183192 func convertNeutrinoToWaves (amount) = ((((amount * 100) / price) * WAVELET) / PAULI)
184193
209218
210219 let leasingAmount = getNumberByKey(LeasingAmountKey)
211220
212-let swapLockedBalance = getNumberByKey(SwapLockedBalanceKey)
221+let swapNeutrinoLockedBalance = getNumberByKey(SwapNeutrinoLockedBalanceKey)
222+
223+let swapWavesLockedBalance = getNumberByKey(SwapLockedBalanceKey)
213224
214225 let nodeAddress = getStringByKey(NodeAddressKey)
215226
229240
230241 let neutrinoAssetId = fromBase58String(getStringByKey(NeutrinoAssetIdKey))
231242
243+let reserveContract = getStringByKey(ReserveContractKey)
244+
232245 let auctionContract = getStringByKey(AuctionContractKey)
233246
234247 let rpdContract = getStringByKey(RPDContractKey)
235248
236-let reserve = (wavesBalance(this) - swapLockedBalance)
249+let reserve = (wavesBalance(this) - swapWavesLockedBalance)
237250
238-let reserveWithoutLeasing = ((wavesBalance(this) - (leasingAmount * (if (isInt(transactionHeightById(fromBase58String(leaseTxHash))))
251+let reserveWithoutLeasing = (reserve - (leasingAmount * (if (isDefined(transactionHeightById(fromBase58String(leaseTxHash))))
239252 then 1
240- else 0))) - swapLockedBalance)
253+ else 0)))
241254
242255 let orderbook = getStringByKey(OrderbookKey)
243256
250263
251264 let neutrinoSupply = {
252265 let info = extract(assetInfo(neutrinoAssetId))
253- (info.quantity - assetBalance(this, neutrinoAssetId))
266+ ((info.quantity - assetBalance(this, neutrinoAssetId)) + swapNeutrinoLockedBalance)
254267 }
255268
256269 let surplus = (convertWavesToNeutrino(reserve) - neutrinoSupply)
282295
283296
284297 func getRPDProfit (count) = getNumberByKey(getRPDProfitKey(count))
298+
299+
300+func getPriceHistory (block) = getNumberByAddressAndKey(controlContract, getPriceHistoryKey(block))
301+
302+
303+func getHeightPriceByIndex (index) = getNumberByAddressAndKey(controlContract, getHeightPriceByIndexKey(index))
285304
286305
287306 func getOrderElementById (id) = (id + LISTSPLITSYMBOL)
316335 @Callable(i)
317336 func swapNeutrinoToWaves () = {
318337 let pmt = extract(i.payment)
338+ let account = toString(i.caller)
319339 if ((minNeutrinoSwapAmount > pmt.amount))
320340 then throw("amount less min")
321341 else if (isBlocked)
322342 then throw("contract is blocked")
323343 else if ((pmt.assetId != neutrinoAssetId))
324344 then throw("can use neutrino only")
325- else {
326- let account = toBase58String(i.caller.bytes)
327- let amount = convertNeutrinoToWaves(pmt.amount)
328- WriteSet([DataEntry(getWavesBalanceKey(account), (getWavesBalance(account) + amount)), DataEntry(getBalanceUnlockBlockKey(account), (height + balanceLockInterval)), DataEntry(IsRebalanceKey, (((reserve * CRYTICALSHARE) / 100) >= (reserveWithoutLeasing - amount))), DataEntry(SwapLockedBalanceKey, (swapLockedBalance + amount))])
329- }
345+ else if ((getUnlockBalanceBlock(account) > height))
346+ then throw((("await " + toString((getUnlockBalanceBlock(account) - height))) + " blocks"))
347+ else if ((getNeutrinoBalance(account) != 0))
348+ then throw("use withdraw")
349+ else {
350+ let neutrinoAmount = pmt.amount
351+ let amount = convertNeutrinoToWaves(neutrinoAmount)
352+ WriteSet([DataEntry(getNeutrinoBalanceKey(account), (getNeutrinoBalance(account) + neutrinoAmount)), DataEntry(getBalanceUnlockBlockKey(account), (height + balanceLockInterval)), DataEntry(IsRebalanceKey, (((reserve * CRYTICALSHARE) / 100) >= (reserveWithoutLeasing - amount))), DataEntry(SwapNeutrinoLockedBalanceKey, (swapNeutrinoLockedBalance + neutrinoAmount))])
353+ }
330354 }
331355
332356
333357
334358 @Callable(i)
335-func withdraw (account) = if ((getUnlockBalanceBlock(account) > height))
336- then throw("wait a couple of blocks for withdraw")
337- 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)]))
359+func withdraw (account,index) = {
360+ let indexHeight = getHeightPriceByIndex(index)
361+ let nextIndexHeight = getHeightPriceByIndex((index + 1))
362+ let unlockHeight = getUnlockBalanceBlock(account)
363+ if (isBlocked)
364+ then throw("contract is blocked")
365+ else if ((unlockHeight > height))
366+ then throw("wait a couple of blocks for withdraw")
367+ else if (if (if ((index > priceIndex))
368+ then true
369+ else (indexHeight > unlockHeight))
370+ then true
371+ else if ((nextIndexHeight != 0))
372+ then (unlockHeight >= nextIndexHeight)
373+ else false)
374+ then throw("invalid index")
375+ else {
376+ let indexPrice = getPriceHistory(indexHeight)
377+ let neutrinoAmount = getNeutrinoBalance(account)
378+ let amount = convertNeutrinoToWavesByPrice(neutrinoAmount, indexPrice)
379+ ScriptResult(WriteSet([DataEntry(getWavesBalanceKey(account), 0), DataEntry(getNeutrinoBalanceKey(account), 0), DataEntry(SwapLockedBalanceKey, (swapWavesLockedBalance - getWavesBalance(account))), DataEntry(SwapNeutrinoLockedBalanceKey, (swapNeutrinoLockedBalance - neutrinoAmount))]), TransferSet([ScriptTransfer(addressFromStringValue(account), (getWavesBalance(account) + amount), unit)]))
380+ }
381+ }
338382
339383
340384
450494 else (timestamp > (lastBlock.timestamp + 5400000)))
451495 then throw((("invalid timestamp(lastBlock: " + toString(lastBlock.timestamp)) + ")"))
452496 else if (if ((leaseTxHash != ""))
453- then if (isInt(transactionHeightById(fromBase58String(leaseTxHash))))
497+ then if (isDefined(transactionHeightById(fromBase58String(leaseTxHash))))
454498 then true
455499 else (leaseTxExpireSendBlock >= height)
456500 else false)
474518 let txHash = blake2b256(txBytes)
475519 if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
476520 then throw("invalid pubKey")
477- else if (!(isInt(transactionHeightById(txHash))))
521+ else if (!(isDefined(transactionHeightById(txHash))))
478522 then throw("blockchain does not contain this transaction")
479523 else WriteSet([DataEntry(LeaseTxKey, ""), DataEntry(LeaseTxHashKey, ""), DataEntry(LeasingAmountKey, 0), DataEntry(LeaseTxExpireSendBlockKey, 0), DataEntry(LeasingExpireBlockKey, 0), DataEntry(IsRebalanceKey, false)])
480524 }
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-
59-
6052 let LISTSPLITSYMBOL = "_"
6153
6254 let LISTDATASYMBOL = "+"
6355
6456 let WAVELET = 100000000
6557
6658 let PAULI = 100
6759
6860 let CRYTICALSHARE = 20
6961
7062 let LEASINGSHARE = 50
7163
7264 let CANCELED = "canceled"
7365
7466 let NEW = "new"
7567
7668 let FILLED = "filled"
7769
7870 let NeutrinoAssetIdKey = "neutrino_asset_id"
7971
8072 let BondAssetIdKey = "bond_asset_id"
8173
74+let ReserveContractKey = "reserve_contract"
75+
8276 let AuctionContractKey = "auction_contract"
8377
8478 let RPDContractKey = "rpd_contract"
8579
8680 let ContolContractKey = "control_contract"
8781
8882 let BalanceLockIntervalKey = "balance_lock_interval"
8983
9084 let MinWavesSwapAmountKey = "min_waves_swap_amount"
9185
9286 let MinNeutrinoSwapAmountKey = "min_neutrino_swap_amount"
9387
9488 let NodeAddressKey = "node_address"
9589
9690 let LeasingIntervalKey = "leasing_interval"
9791
9892 let PriceKey = "price"
93+
94+let PriceIndexKey = "price_index"
9995
10096 let ScriptUpdateIntervalKey = "script_update_interval"
10197
10298 let NeutrinoBalanceKey = "neutrino_"
10399
104100 let WavesBalanceKey = "waves_"
105101
106102 let BalanceUnlockBlockKey = "balance_block_"
107103
108104 let OrderbookKey = "orderbook"
109105
110106 let OrderTotalKey = "order_total_"
111107
112108 let OrderOwnerKey = "order_owner_"
113109
114110 let OrderHeightKey = "order_height_"
115111
116112 let OrderFilledTotalKey = "order_filled_total_"
117113
118114 let OrderStatusKey = "order_status_"
119115
120116 let RPDSyncIndexKey = "rpd_sync_index"
121117
122118 let RPDProfitKey = "rpd_profit"
123119
124120 let RPDBalanceKey = "rpd_balance"
125121
126122 let IsBlockedKey = "is_blocked"
127123
128124 let IsLeasingProfitTxExistKey = "is_leasing_profit"
129125
130126 let ScriptUpdateBlockKey = "script_update_block"
131127
132128 let LeaseTxKey = "lease_tx"
133129
134130 let LeaseTxHashKey = "lease_tx_hash"
135131
136132 let LeasingAmountKey = "leasing_amount"
137133
138134 let LeaseTxExpireSendBlockKey = "leasing_expire_send"
139135
140136 let LeasingExpireBlockKey = "leasing_expire_block"
141137
142138 let IsRebalanceKey = "is_rebalance"
143139
144140 let SwapLockedBalanceKey = "swap_locked_balance"
145141
142+let SwapNeutrinoLockedBalanceKey = "swap_neutrino_locked_balance"
143+
146144 func getRPDSnapshotContractBalanceKey (count,assetId) = ((((RPDBalanceKey + "_") + toBase58String(assetId)) + "_") + toString(count))
147145
148146
149147 func getRPDContractBalanceKey (assetId) = ((RPDBalanceKey + "_") + toBase58String(assetId))
150148
151149
152150 func getRPDProfitKey (count) = ((RPDProfitKey + "_") + toString(count))
153151
154152
155153 func getNeutrinoBalanceKey (owner) = (NeutrinoBalanceKey + owner)
156154
157155
158156 func getWavesBalanceKey (owner) = (WavesBalanceKey + owner)
159157
160158
161159 func getBalanceUnlockBlockKey (owner) = (BalanceUnlockBlockKey + owner)
162160
163161
164162 func getOrderTotalKey (orderId) = (OrderTotalKey + orderId)
165163
166164
167165 func getOrderOwnerKey (orderId) = (OrderOwnerKey + orderId)
168166
169167
170168 func getOrderHeightKey (orderId) = (OrderHeightKey + orderId)
171169
172170
173171 func getOrderStatusKey (orderId) = (OrderStatusKey + orderId)
174172
175173
176174 func getOrderFilledTotalKey (orderId) = (OrderFilledTotalKey + orderId)
177175
178176
177+func getPriceHistoryKey (block) = ((PriceKey + "_") + toString(block))
178+
179+
180+func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index))
181+
182+
179183 let controlContract = getStringByKey(ContolContractKey)
180184
181185 let price = getNumberByAddressAndKey(controlContract, PriceKey)
186+
187+let priceIndex = getNumberByAddressAndKey(controlContract, PriceIndexKey)
188+
189+func convertNeutrinoToWavesByPrice (amount,convertPrice) = ((((amount * 100) / convertPrice) * WAVELET) / PAULI)
190+
182191
183192 func convertNeutrinoToWaves (amount) = ((((amount * 100) / price) * WAVELET) / PAULI)
184193
185194
186195 func convertWavesToNeutrino (amount) = ((((amount * price) / 100) * PAULI) / WAVELET)
187196
188197
189198 func convertNeutrinoToBond (amount) = (amount / PAULI)
190199
191200
192201 func convertBondToNeutrino (amount) = (amount * PAULI)
193202
194203
195204 func convertWavesToBond (amount) = convertNeutrinoToBond(convertWavesToNeutrino(amount))
196205
197206
198207 let isRebalance = getBoolByKey(IsRebalanceKey)
199208
200209 let leasingInterval = getNumberByKey(LeasingIntervalKey)
201210
202211 let leaseTxExpireSendBlock = getNumberByKey(LeaseTxExpireSendBlockKey)
203212
204213 let leasingExpireBlock = getNumberByKey(LeasingExpireBlockKey)
205214
206215 let leaseTxHash = getStringByKey(LeaseTxHashKey)
207216
208217 let leaseTxBytes = getStringByKey(LeaseTxKey)
209218
210219 let leasingAmount = getNumberByKey(LeasingAmountKey)
211220
212-let swapLockedBalance = getNumberByKey(SwapLockedBalanceKey)
221+let swapNeutrinoLockedBalance = getNumberByKey(SwapNeutrinoLockedBalanceKey)
222+
223+let swapWavesLockedBalance = getNumberByKey(SwapLockedBalanceKey)
213224
214225 let nodeAddress = getStringByKey(NodeAddressKey)
215226
216227 let scriptUpdateInterval = getNumberByAddressAndKey(ContolContractKey, ScriptUpdateIntervalKey)
217228
218229 let scriptUpdateBlock = getNumberByAddressAndKey(controlContract, ScriptUpdateBlockKey)
219230
220231 let rpdSyncIndex = getNumberByKey(RPDSyncIndexKey)
221232
222233 let balanceLockInterval = getNumberByKey(BalanceLockIntervalKey)
223234
224235 let isBlocked = getBoolByAddressAndKey(controlContract, IsBlockedKey)
225236
226237 let minWavesSwapAmount = getNumberByKey(MinWavesSwapAmountKey)
227238
228239 let minNeutrinoSwapAmount = getNumberByKey(MinNeutrinoSwapAmountKey)
229240
230241 let neutrinoAssetId = fromBase58String(getStringByKey(NeutrinoAssetIdKey))
231242
243+let reserveContract = getStringByKey(ReserveContractKey)
244+
232245 let auctionContract = getStringByKey(AuctionContractKey)
233246
234247 let rpdContract = getStringByKey(RPDContractKey)
235248
236-let reserve = (wavesBalance(this) - swapLockedBalance)
249+let reserve = (wavesBalance(this) - swapWavesLockedBalance)
237250
238-let reserveWithoutLeasing = ((wavesBalance(this) - (leasingAmount * (if (isInt(transactionHeightById(fromBase58String(leaseTxHash))))
251+let reserveWithoutLeasing = (reserve - (leasingAmount * (if (isDefined(transactionHeightById(fromBase58String(leaseTxHash))))
239252 then 1
240- else 0))) - swapLockedBalance)
253+ else 0)))
241254
242255 let orderbook = getStringByKey(OrderbookKey)
243256
244257 let bondAssetId = fromBase58String(getStringByKey(BondAssetIdKey))
245258
246259 let bondSupply = {
247260 let info = extract(assetInfo(bondAssetId))
248261 (info.quantity - assetBalance(this, bondAssetId))
249262 }
250263
251264 let neutrinoSupply = {
252265 let info = extract(assetInfo(neutrinoAssetId))
253- (info.quantity - assetBalance(this, neutrinoAssetId))
266+ ((info.quantity - assetBalance(this, neutrinoAssetId)) + swapNeutrinoLockedBalance)
254267 }
255268
256269 let surplus = (convertWavesToNeutrino(reserve) - neutrinoSupply)
257270
258271 let deficit = (neutrinoSupply - convertWavesToNeutrino(reserve))
259272
260273 func getRPDContractBalance (assetId) = getNumberByAddressAndKey(rpdContract, getRPDContractBalanceKey(assetId))
261274
262275
263276 func getWavesBalance (owner) = getNumberByKey(getWavesBalanceKey(owner))
264277
265278
266279 func getNeutrinoBalance (owner) = getNumberByKey(getNeutrinoBalanceKey(owner))
267280
268281
269282 func getUnlockBalanceBlock (owner) = getNumberByKey(getBalanceUnlockBlockKey(owner))
270283
271284
272285 func getOrderTotal (id) = getNumberByKey(getOrderTotalKey(id))
273286
274287
275288 func getOrderOwner (id) = getStringByKey(getOrderOwnerKey(id))
276289
277290
278291 func getOrderStatus (id) = getStringByKey(getOrderStatusKey(id))
279292
280293
281294 func getOrderFilledTotal (id) = getNumberByKey(getOrderFilledTotalKey(id))
282295
283296
284297 func getRPDProfit (count) = getNumberByKey(getRPDProfitKey(count))
298+
299+
300+func getPriceHistory (block) = getNumberByAddressAndKey(controlContract, getPriceHistoryKey(block))
301+
302+
303+func getHeightPriceByIndex (index) = getNumberByAddressAndKey(controlContract, getHeightPriceByIndexKey(index))
285304
286305
287306 func getOrderElementById (id) = (id + LISTSPLITSYMBOL)
288307
289308
290309 func addOrder (orderId) = (orderbook + getOrderElementById(orderId))
291310
292311
293312 func dropOrder (orderId) = {
294313 let parts = split(orderbook, getOrderElementById(orderId))
295314 (parts[0] + parts[1])
296315 }
297316
298317
299318 @Callable(i)
300319 func swapWavesToNeutrino () = {
301320 let pmt = extract(i.payment)
302321 if ((minWavesSwapAmount > pmt.amount))
303322 then throw("amount less min")
304323 else if (isDefined(pmt.assetId))
305324 then throw("can use waves only")
306325 else if (isBlocked)
307326 then throw("contract is blocked")
308327 else {
309328 let amount = convertWavesToNeutrino(pmt.amount)
310329 TransferSet([ScriptTransfer(i.caller, amount, neutrinoAssetId)])
311330 }
312331 }
313332
314333
315334
316335 @Callable(i)
317336 func swapNeutrinoToWaves () = {
318337 let pmt = extract(i.payment)
338+ let account = toString(i.caller)
319339 if ((minNeutrinoSwapAmount > pmt.amount))
320340 then throw("amount less min")
321341 else if (isBlocked)
322342 then throw("contract is blocked")
323343 else if ((pmt.assetId != neutrinoAssetId))
324344 then throw("can use neutrino only")
325- else {
326- let account = toBase58String(i.caller.bytes)
327- let amount = convertNeutrinoToWaves(pmt.amount)
328- WriteSet([DataEntry(getWavesBalanceKey(account), (getWavesBalance(account) + amount)), DataEntry(getBalanceUnlockBlockKey(account), (height + balanceLockInterval)), DataEntry(IsRebalanceKey, (((reserve * CRYTICALSHARE) / 100) >= (reserveWithoutLeasing - amount))), DataEntry(SwapLockedBalanceKey, (swapLockedBalance + amount))])
329- }
345+ else if ((getUnlockBalanceBlock(account) > height))
346+ then throw((("await " + toString((getUnlockBalanceBlock(account) - height))) + " blocks"))
347+ else if ((getNeutrinoBalance(account) != 0))
348+ then throw("use withdraw")
349+ else {
350+ let neutrinoAmount = pmt.amount
351+ let amount = convertNeutrinoToWaves(neutrinoAmount)
352+ WriteSet([DataEntry(getNeutrinoBalanceKey(account), (getNeutrinoBalance(account) + neutrinoAmount)), DataEntry(getBalanceUnlockBlockKey(account), (height + balanceLockInterval)), DataEntry(IsRebalanceKey, (((reserve * CRYTICALSHARE) / 100) >= (reserveWithoutLeasing - amount))), DataEntry(SwapNeutrinoLockedBalanceKey, (swapNeutrinoLockedBalance + neutrinoAmount))])
353+ }
330354 }
331355
332356
333357
334358 @Callable(i)
335-func withdraw (account) = if ((getUnlockBalanceBlock(account) > height))
336- then throw("wait a couple of blocks for withdraw")
337- 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)]))
359+func withdraw (account,index) = {
360+ let indexHeight = getHeightPriceByIndex(index)
361+ let nextIndexHeight = getHeightPriceByIndex((index + 1))
362+ let unlockHeight = getUnlockBalanceBlock(account)
363+ if (isBlocked)
364+ then throw("contract is blocked")
365+ else if ((unlockHeight > height))
366+ then throw("wait a couple of blocks for withdraw")
367+ else if (if (if ((index > priceIndex))
368+ then true
369+ else (indexHeight > unlockHeight))
370+ then true
371+ else if ((nextIndexHeight != 0))
372+ then (unlockHeight >= nextIndexHeight)
373+ else false)
374+ then throw("invalid index")
375+ else {
376+ let indexPrice = getPriceHistory(indexHeight)
377+ let neutrinoAmount = getNeutrinoBalance(account)
378+ let amount = convertNeutrinoToWavesByPrice(neutrinoAmount, indexPrice)
379+ ScriptResult(WriteSet([DataEntry(getWavesBalanceKey(account), 0), DataEntry(getNeutrinoBalanceKey(account), 0), DataEntry(SwapLockedBalanceKey, (swapWavesLockedBalance - getWavesBalance(account))), DataEntry(SwapNeutrinoLockedBalanceKey, (swapNeutrinoLockedBalance - neutrinoAmount))]), TransferSet([ScriptTransfer(addressFromStringValue(account), (getWavesBalance(account) + amount), unit)]))
380+ }
381+ }
338382
339383
340384
341385 @Callable(i)
342386 func generateBond () = {
343387 let balanceAuction = assetBalance(addressFromStringValue(auctionContract), bondAssetId)
344388 let amount = (convertNeutrinoToBond(deficit) - balanceAuction)
345389 if (isBlocked)
346390 then throw("contract is blocked")
347391 else if ((amount >= 10))
348392 then TransferSet([ScriptTransfer(addressFromStringValue(auctionContract), amount, bondAssetId)])
349393 else throw("bond were generated or do not need it")
350394 }
351395
352396
353397
354398 @Callable(i)
355399 func setOrder () = {
356400 let pmt = extract(i.payment)
357401 let newOrderId = toBase58String(keccak256(((toBytes(pmt.amount) + i.caller.bytes) + toBytes(height))))
358402 if ((pmt.assetId != bondAssetId))
359403 then throw("can use bond only")
360404 else if ((getOrderOwner(newOrderId) != ""))
361405 then throw("order exists")
362406 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)])
363407 }
364408
365409
366410
367411 @Callable(i)
368412 func cancelOrder (orderId) = {
369413 let owner = getOrderOwner(orderId)
370414 let amount = (getOrderTotal(orderId) - getOrderFilledTotal(orderId))
371415 if ((owner != toString(i.caller)))
372416 then throw("permission denied")
373417 else if ((getOrderStatus(orderId) != NEW))
374418 then throw("invalid order status")
375419 else ScriptResult(WriteSet([DataEntry(OrderbookKey, dropOrder(orderId)), DataEntry(getOrderStatusKey(orderId), CANCELED)]), TransferSet([ScriptTransfer(i.caller, amount, bondAssetId)]))
376420 }
377421
378422
379423
380424 @Callable(i)
381425 func executeOrder () = {
382426 let orderId = split(orderbook, LISTSPLITSYMBOL)[0]
383427 let orderTotal = getOrderTotal(orderId)
384428 let orderOwner = getOrderOwner(orderId)
385429 let filledTotal = getOrderFilledTotal(orderId)
386430 let surplusBond = convertNeutrinoToBond(surplus)
387431 if (isBlocked)
388432 then throw("contract is blocked")
389433 else if ((0 >= surplusBond))
390434 then throw("surplus is less than zero")
391435 else if (if ((orderOwner == ""))
392436 then (surplusBond >= 10)
393437 else false)
394438 then {
395439 let newRpdSyncIndex = (rpdSyncIndex + 1)
396440 ScriptResult(WriteSet([DataEntry(RPDSyncIndexKey, newRpdSyncIndex), DataEntry(getRPDProfitKey(rpdSyncIndex), surplus), DataEntry(getRPDSnapshotContractBalanceKey(rpdSyncIndex, neutrinoAssetId), getRPDContractBalance(neutrinoAssetId))]), TransferSet([ScriptTransfer(addressFromStringValue(rpdContract), surplus, neutrinoAssetId)]))
397441 }
398442 else {
399443 let amount = (orderTotal - filledTotal)
400444 let status = if ((surplusBond >= amount))
401445 then FILLED
402446 else NEW
403447 let newFilledTotal = if ((surplusBond >= amount))
404448 then amount
405449 else surplusBond
406450 ScriptResult(WriteSet([DataEntry(OrderbookKey, if ((surplusBond >= amount))
407451 then dropOrder(orderId)
408452 else orderbook), DataEntry(getOrderFilledTotalKey(orderId), (filledTotal + newFilledTotal)), DataEntry(getOrderStatusKey(orderId), status)]), TransferSet([ScriptTransfer(addressFromStringValue(orderOwner), convertBondToNeutrino(newFilledTotal), neutrinoAssetId)]))
409453 }
410454 }
411455
412456
413457
414458 @Callable(i)
415459 func transfer (account) = {
416460 let pmt = extract(i.payment)
417461 if (isDefined(pmt.assetId))
418462 then throw("can use waves only at the moment")
419463 else TransferSet([ScriptTransfer(addressFromStringValue(account), pmt.amount, unit)])
420464 }
421465
422466
423467
424468 @Callable(i)
425469 func nodeReward () = {
426470 let pmt = value(i.payment)
427471 if ((i.caller != addressFromStringValue(nodeAddress)))
428472 then throw("permission denied")
429473 else if (isDefined(pmt.assetId))
430474 then throw("waves only")
431475 else {
432476 let amount = convertWavesToNeutrino(pmt.amount)
433477 let newRpdSyncIndex = (rpdSyncIndex + 1)
434478 ScriptResult(WriteSet([DataEntry(RPDSyncIndexKey, newRpdSyncIndex), DataEntry(getRPDProfitKey(rpdSyncIndex), amount), DataEntry(getRPDSnapshotContractBalanceKey(rpdSyncIndex, neutrinoAssetId), getRPDContractBalance(neutrinoAssetId))]), TransferSet([ScriptTransfer(addressFromStringValue(rpdContract), amount, neutrinoAssetId)]))
435479 }
436480 }
437481
438482
439483
440484 @Callable(i)
441485 func registrationLeaseTx (senderPublicKey,amount,fee,timestamp) = {
442486 let txBytes = (((((base58'3h1H' + fromBase58String(senderPublicKey)) + fromBase58String(nodeAddress)) + toBytes(amount)) + toBytes(fee)) + toBytes(timestamp))
443487 let balance = ((reserve * LEASINGSHARE) / 100)
444488 let txHashBytes = blake2b256(txBytes)
445489 let txHash = toBase58String(txHashBytes)
446490 if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
447491 then throw("invalid pubKey")
448492 else if (if ((lastBlock.timestamp > timestamp))
449493 then true
450494 else (timestamp > (lastBlock.timestamp + 5400000)))
451495 then throw((("invalid timestamp(lastBlock: " + toString(lastBlock.timestamp)) + ")"))
452496 else if (if ((leaseTxHash != ""))
453- then if (isInt(transactionHeightById(fromBase58String(leaseTxHash))))
497+ then if (isDefined(transactionHeightById(fromBase58String(leaseTxHash))))
454498 then true
455499 else (leaseTxExpireSendBlock >= height)
456500 else false)
457501 then throw("leasing not canceled")
458502 else if (if ((fee > 1000000))
459503 then true
460504 else (500000 > fee))
461505 then throw("invalid fee")
462506 else if (if ((amount != balance))
463507 then true
464508 else (amount == 0))
465509 then throw((("invalid amount(leaseAmount:" + toString(balance)) + ")"))
466510 else WriteSet([DataEntry(LeaseTxKey, toBase64String(txBytes)), DataEntry(LeaseTxHashKey, txHash), DataEntry(LeasingAmountKey, balance), DataEntry(LeaseTxExpireSendBlockKey, (height + 30)), DataEntry(LeasingExpireBlockKey, (height + leasingInterval))])
467511 }
468512
469513
470514
471515 @Callable(i)
472516 func registrationUnleaseTx (chainIdString,senderPublicKey,fee,timestamp) = {
473517 let txBytes = (((((base58'gm' + toBytes(chainIdString)) + fromBase58String(senderPublicKey)) + toBytes(fee)) + toBytes(timestamp)) + fromBase58String(leaseTxHash))
474518 let txHash = blake2b256(txBytes)
475519 if ((this != addressFromPublicKey(fromBase58String(senderPublicKey))))
476520 then throw("invalid pubKey")
477- else if (!(isInt(transactionHeightById(txHash))))
521+ else if (!(isDefined(transactionHeightById(txHash))))
478522 then throw("blockchain does not contain this transaction")
479523 else WriteSet([DataEntry(LeaseTxKey, ""), DataEntry(LeaseTxHashKey, ""), DataEntry(LeasingAmountKey, 0), DataEntry(LeaseTxExpireSendBlockKey, 0), DataEntry(LeasingExpireBlockKey, 0), DataEntry(IsRebalanceKey, false)])
480524 }
481525
482526
483527 @Verifier(tx)
484528 func verify () = match tx {
485529 case leaseTx: LeaseTransaction =>
486530 if (if ((fromBase58String(leaseTxHash) == leaseTx.id))
487531 then (leasingExpireBlock >= height)
488532 else false)
489533 then (leaseTxExpireSendBlock >= height)
490534 else false
491535 case unleaseTx: LeaseCancelTransaction =>
492536 if (if ((fromBase58String(leaseTxHash) == unleaseTx.leaseId))
493537 then if ((height > leasingExpireBlock))
494538 then true
495539 else isRebalance
496540 else false)
497541 then if ((unleaseTx.fee >= 500000))
498542 then (1000000 >= unleaseTx.fee)
499543 else false
500544 else false
501545 case _ =>
502546 sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
503547 }
504548

github/deemru/w8io/786bc32 
115.17 ms