2023.01.08 15:20 [3461465] smart account 3P975LUuqc7uBPiSxp3nemf2FZh62zfirSh > SELF 0.00000000 Waves
{ "type": 13, "id": "5aJtkpBSeYF7oBXsbfvMQ8WU1uXNgWeCg5VPpA3ckE4u", "fee": 1000000, "feeAssetId": null, "timestamp": 1673180499445, "version": 2, "chainId": 87, "sender": "3P975LUuqc7uBPiSxp3nemf2FZh62zfirSh", "senderPublicKey": "6Dx2LuCqezyDYjt3zMEL6WRrs5oaor6aK3L6QouPMP1b", "proofs": [ "2mzFxqsjZXfgYej9sNTT6xVdJfV9hjSMHYtFpLJSbeuc6jNuspYY4hXMbeBQhcPMmAYuiJk7PvJ4z365dd2mmg6d" ], "script": "base64:BgIeCAISABIDCgEIEgMKAQgSAwoBCBIECgIICBIDCgEICAAPY3JlYXRpb25BZGRyZXNzCQEHQWRkcmVzcwEBGgFXk93E0hfnIAr99yESTvDwdmcmgwN41FxMAA50b3RhbFN0YWtlZEtleQIMdG90YWxfc3Rha2VkAA10b3RhbFBvd2VyS2V5Agt0b3RhbF9wb3dlcgALUE9XRVJfTElNSVQA6AcBCGNoZWNrTkZUAQVhc3NldAMDAwMJAAACCQERQGV4dHJOYXRpdmUoMTA1MykCBQ9jcmVhdGlvbkFkZHJlc3MJAKwCAgkArAICAgRuZnRfCQDYBAEIBQVhc3NldAJpZAIHX2lzc3VlcgkApQgBBQR0aGlzCQAAAggFBWFzc2V0Bmlzc3VlcgUPY3JlYXRpb25BZGRyZXNzBwkAAAIIBQVhc3NldAhkZWNpbWFscwAABwkAAAIIBQVhc3NldApyZWlzc3VhYmxlBwcJAAACCAUFYXNzZXQIcXVhbnRpdHkAAQcBC2dldFBvd2VyTkZUAQVhc3NldAQGcGFyYW1zCQERQGV4dHJOYXRpdmUoMTA1MykCBQ9jcmVhdGlvbkFkZHJlc3MJAKwCAgkArAICAgRuZnRfCQDYBAEIBQVhc3NldAJpZAIHX3BhcmFtcwMJAAACBQZwYXJhbXMCBGdvbGQAMgAKARNnZXRDb2xsZWN0aW9uSXNzdWVyAQxjb2xsZWN0aW9uSWQEB2Fzc2V0SWQJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUPY3JlYXRpb25BZGRyZXNzCQCsAgIJAKwCAgILY29sbGVjdGlvbl8FDGNvbGxlY3Rpb25JZAIIX2Fzc2V0SWQCAAkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ9jcmVhdGlvbkFkZHJlc3MJAKwCAgkArAICAgRuZnRfBQdhc3NldElkAgdfaXNzdWVyAgABDmlzVm90aW5nQ2xvc2VkAQZ2b3RlSWQEEHZvdGVDb25maXJtZWRLZXkJAKwCAgkArAICAgV2b3RlXwUGdm90ZUlkAgpfY29uZmlybWVkBA92b3RlUmVqZWN0ZWRLZXkJAKwCAgkArAICAgV2b3RlXwUGdm90ZUlkAglfcmVqZWN0ZWQEC2lzQ29uZmlybWVkCQELdmFsdWVPckVsc2UCCQCgCAEFEHZvdGVDb25maXJtZWRLZXkHBAppc1JlamVjdGVkCQELdmFsdWVPckVsc2UCCQCgCAEFD3ZvdGVSZWplY3RlZEtleQcDBQtpc0NvbmZpcm1lZAYFCmlzUmVqZWN0ZWQGAWkBBXN0YWtlAAQKYWRkcmVzc1N0cgkApQgBCAUBaQZjYWxsZXIEAXAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAkQMCCAUBaQhwYXltZW50cwAAAgtObyBwYXltZW50cwQFYXNzZXQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQETdmFsdWVPckVycm9yTWVzc2FnZQIIBQFwB2Fzc2V0SWQCD0ludmFsaWQgcGF5bWVudAIQSW52YWxpZCBhc3NldCBJZAMDCQBmAggFAXAGYW1vdW50AAAJAQhjaGVja05GVAEFBWFzc2V0BwQLdG90YWxTdGFrZWQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUOdG90YWxTdGFrZWRLZXkAAAQKdG90YWxQb3dlcgkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ10b3RhbFBvd2VyS2V5AAAEDGFkZHJlc3NQb3dlcgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQCsAgIJAKwCAgIIYWRkcmVzc18FCmFkZHJlc3NTdHICBl9wb3dlcgAABAhuZnRQb3dlcgkBC2dldFBvd2VyTkZUAQUFYXNzZXQECG5mdElkU3RyCQDYBAEIBQVhc3NldAJpZAkAzAgCCQEMSW50ZWdlckVudHJ5AgUOdG90YWxTdGFrZWRLZXkJAGQCBQt0b3RhbFN0YWtlZAABCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ10b3RhbFBvd2VyS2V5CQBkAgUKdG90YWxQb3dlcgUIbmZ0UG93ZXIJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgICBG5mdF8FCG5mdElkU3RyAgZfb3duZXIFCmFkZHJlc3NTdHIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAgRuZnRfBQhuZnRJZFN0cgIGX3Bvd2VyBQhuZnRQb3dlcgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICCGFkZHJlc3NfBQphZGRyZXNzU3RyAgZfcG93ZXIJAGQCBQxhZGRyZXNzUG93ZXIFCG5mdFBvd2VyBQNuaWwJAAIBAgtObyBwYXltZW50cwFpAQd1bnN0YWtlAQhuZnRJZFN0cgQKYWRkcmVzc1N0cgkApQgBCAUBaQZjYWxsZXIEBWFzc2V0CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQkA2QQBBQhuZnRJZFN0cgIOSW52YWxpZCBuZnQgSWQEDG93bmVyQWRkcmVzcwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJAKwCAgkArAICAgRuZnRfBQhuZnRJZFN0cgIGX293bmVyAhJPd25lciBkYXRhIGludmFsaWQDCQECIT0CBQxvd25lckFkZHJlc3MFCmFkZHJlc3NTdHIJAAIBAhVZb3UgYXJlIG5vdCB0aGUgb3duZXIDCQEIY2hlY2tORlQBBQVhc3NldAQLdG90YWxTdGFrZWQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUOdG90YWxTdGFrZWRLZXkAAAQKdG90YWxQb3dlcgkBC3ZhbHVlT3JFbHNlAgkAnwgBBQ10b3RhbFBvd2VyS2V5AAAEDGFkZHJlc3NQb3dlcgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQCsAgIJAKwCAgIIYWRkcmVzc18FCmFkZHJlc3NTdHICBl9wb3dlcgAABA1uZnRBc3NldElkU3RyCQDYBAEIBQVhc3NldAJpZAQIbmZ0UG93ZXIJARFAZXh0ck5hdGl2ZSgxMDU1KQEJAKwCAgkArAICAgRuZnRfBQ1uZnRBc3NldElkU3RyAgZfcG93ZXIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyAAEIBQVhc3NldAJpZAkAzAgCCQEMSW50ZWdlckVudHJ5AgUOdG90YWxTdGFrZWRLZXkJAGUCBQt0b3RhbFN0YWtlZAABCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ10b3RhbFBvd2VyS2V5CQBlAgUKdG90YWxQb3dlcgUIbmZ0UG93ZXIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgICBG5mdF8FDW5mdEFzc2V0SWRTdHICBl9vd25lcgkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIJAKwCAgIEbmZ0XwUNbmZ0QXNzZXRJZFN0cgIGX3Bvd2VyCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIIYWRkcmVzc18FCmFkZHJlc3NTdHICBl9wb3dlcgkAZQIFDGFkZHJlc3NQb3dlcgUIbmZ0UG93ZXIFA25pbAkAAgECDkludmFsaWQgbmZ0IElkAWkBCnNlbmRUb1ZvdGUBDGNvbGxlY3Rpb25JZAQGaXNzdWVyCQETZ2V0Q29sbGVjdGlvbklzc3VlcgEFDGNvbGxlY3Rpb25JZAMJAAACCQCxAgEFBmlzc3VlcgAACQACAQIbQ29sbGVjdGlvbiBpc3N1ZXIgbm90IGZvdW5kAwkBAiE9AgUGaXNzdWVyCQClCAEIBQFpBmNhbGxlcgkAAgECJk9ubHkgdGhlIGlzc3VlciBjYW4gc3VibWl0IHRvIHRoZSB2b3RlBAZ2b3RlSWQJANgEAQgFAWkNdHJhbnNhY3Rpb25JZAQKdG90YWxWb3RlcwkBC3ZhbHVlT3JFbHNlAgkAnwgBAgt0b3RhbF92b3RlcwAACQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgkArAICAgtjb2xsZWN0aW9uXwUMY29sbGVjdGlvbklkAgdfdm90ZUlkBQZ2b3RlSWQJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgICBXZvdGVfBQZ2b3RlSWQCDV9jb2xsZWN0aW9uSWQFDGNvbGxlY3Rpb25JZAkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKwCAgIFdm90ZV8FBnZvdGVJZAIGX293bmVyCQClCAEIBQFpBmNhbGxlcgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICBXZvdGVfBQZ2b3RlSWQCCl9jcmVhdGVkQXQFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgILdG90YWxfdm90ZXMJAGQCBQp0b3RhbFZvdGVzAAEFA25pbAFpAQ5yZW1vdmVGcm9tVm90ZQEGdm90ZUlkBAxjb2xsZWN0aW9uSWQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQCsAgIJAKwCAgIFdm90ZV8FBnZvdGVJZAINX2NvbGxlY3Rpb25JZAIXQ29sbGVjdGlvbiBJZCBub3QgZm91bmQEBW93bmVyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkArAICCQCsAgICBXZvdGVfBQZ2b3RlSWQCBl9vd25lcgIPT3duZXIgbm90IGZvdW5kAwkBAiE9AgUFb3duZXIJAKUIAQgFAWkGY2FsbGVyCQACAQIVWW91IGFyZSBub3QgdGhlIG93bmVyAwkBDmlzVm90aW5nQ2xvc2VkAQUGdm90ZUlkCQACAQIQVm90aW5nIGlzIGNsb3NlZAQKdG90YWxWb3RlcwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAECC3RvdGFsX3ZvdGVzAht0b3RhbCB2b3RlcyB2YWx1ZSBub3QgZm91bmQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgICC2NvbGxlY3Rpb25fBQxjb2xsZWN0aW9uSWQCB192b3RlSWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgICBXZvdGVfBQZ2b3RlSWQCDV9jb2xsZWN0aW9uSWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgICBXZvdGVfBQZ2b3RlSWQCBl9vd25lcgkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIJAKwCAgIFdm90ZV8FBnZvdGVJZAIKX2NyZWF0ZWRBdAkAzAgCCQEMSW50ZWdlckVudHJ5AgILdG90YWxfdm90ZXMJAGUCBQp0b3RhbFZvdGVzAAEFA25pbAFpAQR2b3RlAgZ2b3RlSWQEdHlwZQQKYWRkcmVzc1N0cgkApQgBCAUBaQZjYWxsZXIEBWV4aXN0BAckbWF0Y2gwCQCiCAEJAKwCAgkArAICAgV2b3RlXwUGdm90ZUlkAg1fY29sbGVjdGlvbklkAwkAAQIFByRtYXRjaDACBlN0cmluZwQBdAUHJG1hdGNoMAYHBAx2b3RlclZvdGVLZXkJAKwCAgkArAICCQCsAgIJAKwCAgIGdm90ZXJfBQphZGRyZXNzU3RyAgZfdm90ZV8FBnZvdGVJZAIIX2lzVm90ZWQEEHZvdGVyVm90ZVR5cGVLZXkJAKwCAgkArAICCQCsAgIJAKwCAgIGdm90ZXJfBQphZGRyZXNzU3RyAgZfdm90ZV8FBnZvdGVJZAIFX3R5cGUEEXZvdGVyVm90ZVBvd2VyS2V5CQCsAgIJAKwCAgkArAICCQCsAgICBnZvdGVyXwUKYWRkcmVzc1N0cgIGX3ZvdGVfBQZ2b3RlSWQCBl9wb3dlcgQTdm90ZXJWb3RlQ3JlYXRlZEtleQkArAICCQCsAgIJAKwCAgkArAICAgZ2b3Rlcl8FCmFkZHJlc3NTdHICBl92b3RlXwUGdm90ZUlkAghfY3JlYXRlZAQSdm90ZXJWb3Rlc0NvdW50S2V5CQCsAgIJAKwCAgIGdm90ZXJfBQphZGRyZXNzU3RyAgtfdm90ZXNDb3VudAQSdm90ZXJTcGVudFBvd2VyS2V5CQCsAgIJAKwCAgIGdm90ZXJfBQphZGRyZXNzU3RyAgtfc3BlbnRQb3dlcgQOdm90ZVVwQ291bnRLZXkJAKwCAgkArAICAgV2b3RlXwUGdm90ZUlkAghfdXBDb3VudAQQdm90ZURvd25Db3VudEtleQkArAICCQCsAgICBXZvdGVfBQZ2b3RlSWQCCl9kb3duQ291bnQEEXZvdGVUb3RhbENvdW50S2V5CQCsAgIJAKwCAgIFdm90ZV8FBnZvdGVJZAILX3RvdGFsQ291bnQEEHZvdGVDb25maXJtZWRLZXkJAKwCAgkArAICAgV2b3RlXwUGdm90ZUlkAgpfY29uZmlybWVkBA92b3RlUmVqZWN0ZWRLZXkJAKwCAgkArAICAgV2b3RlXwUGdm90ZUlkAglfcmVqZWN0ZWQEDGFkZHJlc3NQb3dlcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEJAKwCAgkArAICAghhZGRyZXNzXwUKYWRkcmVzc1N0cgIGX3Bvd2VyAh9UaGUgYWRkcmVzcyBoYXMgbm8gdm90aW5nIHBvd2VyBA50b3RhbFZvdGVDb3VudAkBC3ZhbHVlT3JFbHNlAgkAnwgBBRF2b3RlVG90YWxDb3VudEtleQAABA92b3RlclZvdGVzQ291bnQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUSdm90ZXJWb3Rlc0NvdW50S2V5AAAED3ZvdGVyU3BlbnRQb3dlcgkBC3ZhbHVlT3JFbHNlAgkAnwgBBRJ2b3RlclNwZW50UG93ZXJLZXkAAAQLdXBDb3VudERhcHAJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUOdm90ZVVwQ291bnRLZXkAAAQNZG93bkNvdW50RGFwcAkBC3ZhbHVlT3JFbHNlAgkAnwgBBRB2b3RlRG93bkNvdW50S2V5AAAEB3VwQ291bnQDCQAAAgUEdHlwZQICdXAJAGQCBQt1cENvdW50RGFwcAUMYWRkcmVzc1Bvd2VyBQt1cENvdW50RGFwcAQJZG93bkNvdW50AwkAAAIFBHR5cGUCBGRvd24JAGQCBQ1kb3duQ291bnREYXBwBQxhZGRyZXNzUG93ZXIFDWRvd25Db3VudERhcHAEDWlzQ2FsbGVyVm90ZWQJAQt2YWx1ZU9yRWxzZQIJAKAIAQUMdm90ZXJWb3RlS2V5BwMFDWlzQ2FsbGVyVm90ZWQJAAIBAhZZb3UgaGF2ZSBhbHJlYWR5IHZvdGVkAwkBDmlzVm90aW5nQ2xvc2VkAQUGdm90ZUlkCQACAQIQVm90aW5nIGlzIGNsb3NlZAMJAQEhAQUFZXhpc3QJAAIBAhRDb2xsZWN0aW9uIG5vdCBmb3VuZAMDCQECIT0CBQR0eXBlAgJ1cAkBAiE9AgUEdHlwZQIEZG93bgcJAAIBAhVJbnZhbGlkIHR5cGUgcGFyYW1ldHIEEHVwZGF0ZWRWb3RlQ291bnQJAGQCBQ50b3RhbFZvdGVDb3VudAUMYWRkcmVzc1Bvd2VyBA1lbmRWb3RlU3RhdGVzAwkAZwIFEHVwZGF0ZWRWb3RlQ291bnQFC1BPV0VSX0xJTUlUBAl1cFBlcmNlbnQJAGsDBQd1cENvdW50AGQFEHVwZGF0ZWRWb3RlQ291bnQEC2Rvd25QZXJjZW50CQBrAwUJZG93bkNvdW50AGQFEHVwZGF0ZWRWb3RlQ291bnQDCQBnAgUJdXBQZXJjZW50ADIJAMwIAgkBDEJvb2xlYW5FbnRyeQIFEHZvdGVDb25maXJtZWRLZXkGBQNuaWwJAMwIAgkBDEJvb2xlYW5FbnRyeQIFD3ZvdGVSZWplY3RlZEtleQYFA25pbAUDbmlsCQDOCAIJAMwIAgkBDEJvb2xlYW5FbnRyeQIFDHZvdGVyVm90ZUtleQYJAMwIAgkBC1N0cmluZ0VudHJ5AgUQdm90ZXJWb3RlVHlwZUtleQUEdHlwZQkAzAgCCQEMSW50ZWdlckVudHJ5AgUTdm90ZXJWb3RlQ3JlYXRlZEtleQUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRF2b3RlclZvdGVQb3dlcktleQUMYWRkcmVzc1Bvd2VyCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRJ2b3RlclZvdGVzQ291bnRLZXkJAGQCBQ92b3RlclZvdGVzQ291bnQAAQkAzAgCCQEMSW50ZWdlckVudHJ5AgUSdm90ZXJTcGVudFBvd2VyS2V5CQBkAgUPdm90ZXJTcGVudFBvd2VyBQxhZGRyZXNzUG93ZXIJAMwIAgkBDEludGVnZXJFbnRyeQIFDnZvdGVVcENvdW50S2V5BQd1cENvdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRB2b3RlRG93bkNvdW50S2V5BQlkb3duQ291bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFEXZvdGVUb3RhbENvdW50S2V5BRB1cGRhdGVkVm90ZUNvdW50BQNuaWwFDWVuZFZvdGVTdGF0ZXMBaQEGdW52b3RlAQZ2b3RlSWQECmFkZHJlc3NTdHIJAKUIAQgFAWkGY2FsbGVyBAx2b3RlclZvdGVLZXkJAKwCAgkArAICCQCsAgIJAKwCAgIGdm90ZXJfBQphZGRyZXNzU3RyAgZfdm90ZV8FBnZvdGVJZAIIX2lzVm90ZWQEEHZvdGVyVm90ZVR5cGVLZXkJAKwCAgkArAICCQCsAgIJAKwCAgIGdm90ZXJfBQphZGRyZXNzU3RyAgZfdm90ZV8FBnZvdGVJZAIFX3R5cGUEEXZvdGVyVm90ZVBvd2VyS2V5CQCsAgIJAKwCAgkArAICCQCsAgICBnZvdGVyXwUKYWRkcmVzc1N0cgIGX3ZvdGVfBQZ2b3RlSWQCBl9wb3dlcgQTdm90ZXJWb3RlQ3JlYXRlZEtleQkArAICCQCsAgIJAKwCAgkArAICAgZ2b3Rlcl8FCmFkZHJlc3NTdHICBl92b3RlXwUGdm90ZUlkAghfY3JlYXRlZAQSdm90ZXJWb3Rlc0NvdW50S2V5CQCsAgIJAKwCAgIGdm90ZXJfBQphZGRyZXNzU3RyAgtfdm90ZXNDb3VudAQSdm90ZXJTcGVudFBvd2VyS2V5CQCsAgIJAKwCAgIGdm90ZXJfBQphZGRyZXNzU3RyAgtfc3BlbnRQb3dlcgQOdm90ZVVwQ291bnRLZXkJAKwCAgkArAICAgV2b3RlXwUGdm90ZUlkAghfdXBDb3VudAQQdm90ZURvd25Db3VudEtleQkArAICCQCsAgICBXZvdGVfBQZ2b3RlSWQCCl9kb3duQ291bnQEEXZvdGVUb3RhbENvdW50S2V5CQCsAgIJAKwCAgIFdm90ZV8FBnZvdGVJZAILX3RvdGFsQ291bnQEEHZvdGVDb25maXJtZWRLZXkJAKwCAgkArAICAgV2b3RlXwUGdm90ZUlkAgpfY29uZmlybWVkBA92b3RlUmVqZWN0ZWRLZXkJAKwCAgkArAICAgV2b3RlXwUGdm90ZUlkAglfcmVqZWN0ZWQECnZvdGVJZFR5cGUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBBRB2b3RlclZvdGVUeXBlS2V5AhhWb3RlIElkIHR5cGUgbm90IGZvdW5kZWQEC3ZvdGVJZFBvd2VyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQURdm90ZXJWb3RlUG93ZXJLZXkCGVZvdGUgSWQgcG93ZXIgbm90IGZvdW5kZWQECnRvdGFsQ291bnQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBRF2b3RlVG90YWxDb3VudEtleQIfVm90ZSBJZCB0b3RhbCBjb3VudCBub3QgZm91bmRlZAQPdm90ZXJWb3Rlc0NvdW50CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUSdm90ZXJWb3Rlc0NvdW50S2V5AiNWb3RlciB2b3RlcyBjb3VudCB2YWx1ZSBub3QgZm91bmRlZAQPdm90ZXJTcGVudFBvd2VyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUSdm90ZXJTcGVudFBvd2VyS2V5AiNWb3RlciBzcGVudCBwb3dlciB2YWx1ZSBub3QgZm91bmRlZAQLdXBDb3VudERhcHAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBBQ52b3RlVXBDb3VudEtleQITVXAgY291bnQgbm90ZSBmb3VuZAQNZG93bkNvdW50RGFwcAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFEHZvdGVEb3duQ291bnRLZXkCFURvd24gY291bnQgbm90ZSBmb3VuZAQHdXBDb3VudAMJAAACBQp2b3RlSWRUeXBlAgJ1cAkAZQIFC3VwQ291bnREYXBwBQt2b3RlSWRQb3dlcgULdXBDb3VudERhcHAECWRvd25Db3VudAMJAAACBQp2b3RlSWRUeXBlAgRkb3duCQBlAgUNZG93bkNvdW50RGFwcAULdm90ZUlkUG93ZXIFDWRvd25Db3VudERhcHAEDWlzQ2FsbGVyVm90ZWQJAQt2YWx1ZU9yRWxzZQIJAKAIAQUMdm90ZXJWb3RlS2V5BwMJAQEhAQUNaXNDYWxsZXJWb3RlZAkAAgECFVlvdSBoYXZlbid0IHZvdGVkIHlldAMJAQ5pc1ZvdGluZ0Nsb3NlZAEFBnZvdGVJZAkAAgECEFZvdGluZyBpcyBjbG9zZWQDAwkBAiE9AgUKdm90ZUlkVHlwZQICdXAJAQIhPQIFCnZvdGVJZFR5cGUCBGRvd24HCQACAQIVSW52YWxpZCB0eXBlIHBhcmFtZXRyCQDMCAIJAQtEZWxldGVFbnRyeQEFDHZvdGVyVm90ZUtleQkAzAgCCQELRGVsZXRlRW50cnkBBRB2b3RlclZvdGVUeXBlS2V5CQDMCAIJAQtEZWxldGVFbnRyeQEFE3ZvdGVyVm90ZUNyZWF0ZWRLZXkJAMwIAgkBC0RlbGV0ZUVudHJ5AQURdm90ZXJWb3RlUG93ZXJLZXkJAMwIAgkBDEludGVnZXJFbnRyeQIFEnZvdGVyVm90ZXNDb3VudEtleQkAZQIFD3ZvdGVyVm90ZXNDb3VudAABCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRJ2b3RlclNwZW50UG93ZXJLZXkJAGUCBQ92b3RlclNwZW50UG93ZXIFC3ZvdGVJZFBvd2VyCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ52b3RlVXBDb3VudEtleQUHdXBDb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgUQdm90ZURvd25Db3VudEtleQUJZG93bkNvdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRF2b3RlVG90YWxDb3VudEtleQkAZQIFCnRvdGFsQ291bnQFC3ZvdGVJZFBvd2VyBQNuaWwBAnR4AQZ2ZXJpZnkACQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAACAUCdHgPc2VuZGVyUHVibGljS2V5aMSVFw==", "height": 3461465, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: H2bLPbiP4bVh3wqDqxwNnggsYEBoi2XXmtbJZxa7FbNJ Next: 37N4URn93rcaKfNuiPPDsqT6ht7frYWx5RJLH5en1Wk1 Diff:
Old | New | Differences | |
---|---|---|---|
6 | 6 | let totalStakedKey = "total_staked" | |
7 | 7 | ||
8 | 8 | let totalPowerKey = "total_power" | |
9 | + | ||
10 | + | let POWER_LIMIT = 1000 | |
9 | 11 | ||
10 | 12 | func checkNFT (asset) = if (if (if (if ((getStringValue(creationAddress, (("nft_" + toBase58String(asset.id)) + "_issuer")) == toString(this))) | |
11 | 13 | then (asset.issuer == creationAddress) | |
29 | 31 | func getCollectionIssuer (collectionId) = { | |
30 | 32 | let assetId = valueOrElse(getString(creationAddress, (("collection_" + collectionId) + "_assetId")), "") | |
31 | 33 | valueOrElse(getString(creationAddress, (("nft_" + assetId) + "_issuer")), "") | |
34 | + | } | |
35 | + | ||
36 | + | ||
37 | + | func isVotingClosed (voteId) = { | |
38 | + | let voteConfirmedKey = (("vote_" + voteId) + "_confirmed") | |
39 | + | let voteRejectedKey = (("vote_" + voteId) + "_rejected") | |
40 | + | let isConfirmed = valueOrElse(getBoolean(voteConfirmedKey), false) | |
41 | + | let isRejected = valueOrElse(getBoolean(voteRejectedKey), false) | |
42 | + | if (isConfirmed) | |
43 | + | then true | |
44 | + | else isRejected | |
32 | 45 | } | |
33 | 46 | ||
34 | 47 | ||
83 | 96 | then throw("Only the issuer can submit to the vote") | |
84 | 97 | else { | |
85 | 98 | let voteId = toBase58String(i.transactionId) | |
86 | - | [StringEntry((("collection_" + collectionId) + "_voteId"), voteId), StringEntry((("vote_" + voteId) + "_collectionId"), collectionId), StringEntry((("vote_" + voteId) + "_owner"), toString(i.caller)), IntegerEntry((("vote_" + voteId) + "_createdAt"), height)] | |
99 | + | let totalVotes = valueOrElse(getInteger("total_votes"), 0) | |
100 | + | [StringEntry((("collection_" + collectionId) + "_voteId"), voteId), StringEntry((("vote_" + voteId) + "_collectionId"), collectionId), StringEntry((("vote_" + voteId) + "_owner"), toString(i.caller)), IntegerEntry((("vote_" + voteId) + "_createdAt"), height), IntegerEntry("total_votes", (totalVotes + 1))] | |
87 | 101 | } | |
88 | 102 | } | |
89 | 103 | ||
95 | 109 | let owner = valueOrErrorMessage(getString((("vote_" + voteId) + "_owner")), "Owner not found") | |
96 | 110 | if ((owner != toString(i.caller))) | |
97 | 111 | then throw("You are not the owner") | |
98 | - | else [DeleteEntry((("collection_" + collectionId) + "_voteId")), DeleteEntry((("vote_" + voteId) + "_collectionId")), DeleteEntry((("vote_" + voteId) + "_owner")), DeleteEntry((("vote_" + voteId) + "_createdAt"))] | |
112 | + | else if (isVotingClosed(voteId)) | |
113 | + | then throw("Voting is closed") | |
114 | + | else { | |
115 | + | let totalVotes = valueOrErrorMessage(getInteger("total_votes"), "total votes value not found") | |
116 | + | [DeleteEntry((("collection_" + collectionId) + "_voteId")), DeleteEntry((("vote_" + voteId) + "_collectionId")), DeleteEntry((("vote_" + voteId) + "_owner")), DeleteEntry((("vote_" + voteId) + "_createdAt")), IntegerEntry("total_votes", (totalVotes - 1))] | |
117 | + | } | |
99 | 118 | } | |
100 | 119 | ||
101 | 120 | ||
118 | 137 | let voteUpCountKey = (("vote_" + voteId) + "_upCount") | |
119 | 138 | let voteDownCountKey = (("vote_" + voteId) + "_downCount") | |
120 | 139 | let voteTotalCountKey = (("vote_" + voteId) + "_totalCount") | |
140 | + | let voteConfirmedKey = (("vote_" + voteId) + "_confirmed") | |
141 | + | let voteRejectedKey = (("vote_" + voteId) + "_rejected") | |
121 | 142 | let addressPower = valueOrErrorMessage(getInteger((("address_" + addressStr) + "_power")), "The address has no voting power") | |
122 | - | let | |
143 | + | let totalVoteCount = valueOrElse(getInteger(voteTotalCountKey), 0) | |
123 | 144 | let voterVotesCount = valueOrElse(getInteger(voterVotesCountKey), 0) | |
124 | 145 | let voterSpentPower = valueOrElse(getInteger(voterSpentPowerKey), 0) | |
125 | - | let voteChangeStates = if ((type == "up")) | |
126 | - | then { | |
127 | - | let upCount = valueOrElse(getInteger(voteUpCountKey), 0) | |
128 | - | [IntegerEntry(voteUpCountKey, (upCount + addressPower))] | |
129 | - | } | |
130 | - | else if ((type == "down")) | |
131 | - | then { | |
132 | - | let downCount = valueOrElse(getInteger(voteDownCountKey), 0) | |
133 | - | [IntegerEntry(voteDownCountKey, (downCount + addressPower))] | |
134 | - | } | |
135 | - | else throw("Invalid type") | |
146 | + | let upCountDapp = valueOrElse(getInteger(voteUpCountKey), 0) | |
147 | + | let downCountDapp = valueOrElse(getInteger(voteDownCountKey), 0) | |
148 | + | let upCount = if ((type == "up")) | |
149 | + | then (upCountDapp + addressPower) | |
150 | + | else upCountDapp | |
151 | + | let downCount = if ((type == "down")) | |
152 | + | then (downCountDapp + addressPower) | |
153 | + | else downCountDapp | |
136 | 154 | let isCallerVoted = valueOrElse(getBoolean(voterVoteKey), false) | |
137 | 155 | if (isCallerVoted) | |
138 | 156 | then throw("You have already voted") | |
139 | - | else if (!(exist)) | |
140 | - | then throw("Collection not found") | |
141 | - | else ([BooleanEntry(voterVoteKey, true), StringEntry(voterVoteTypeKey, type), IntegerEntry(voterVoteCreatedKey, height), IntegerEntry(voterVotePowerKey, addressPower), IntegerEntry(voterVotesCountKey, (voterVotesCount + 1)), IntegerEntry(voterSpentPowerKey, (voterSpentPower + addressPower)), IntegerEntry(voteTotalCountKey, (totalCount + addressPower))] ++ voteChangeStates) | |
157 | + | else if (isVotingClosed(voteId)) | |
158 | + | then throw("Voting is closed") | |
159 | + | else if (!(exist)) | |
160 | + | then throw("Collection not found") | |
161 | + | else if (if ((type != "up")) | |
162 | + | then (type != "down") | |
163 | + | else false) | |
164 | + | then throw("Invalid type parametr") | |
165 | + | else { | |
166 | + | let updatedVoteCount = (totalVoteCount + addressPower) | |
167 | + | let endVoteStates = if ((updatedVoteCount >= POWER_LIMIT)) | |
168 | + | then { | |
169 | + | let upPercent = fraction(upCount, 100, updatedVoteCount) | |
170 | + | let downPercent = fraction(downCount, 100, updatedVoteCount) | |
171 | + | if ((upPercent >= 50)) | |
172 | + | then [BooleanEntry(voteConfirmedKey, true)] | |
173 | + | else [BooleanEntry(voteRejectedKey, true)] | |
174 | + | } | |
175 | + | else nil | |
176 | + | ([BooleanEntry(voterVoteKey, true), StringEntry(voterVoteTypeKey, type), IntegerEntry(voterVoteCreatedKey, height), IntegerEntry(voterVotePowerKey, addressPower), IntegerEntry(voterVotesCountKey, (voterVotesCount + 1)), IntegerEntry(voterSpentPowerKey, (voterSpentPower + addressPower)), IntegerEntry(voteUpCountKey, upCount), IntegerEntry(voteDownCountKey, downCount), IntegerEntry(voteTotalCountKey, updatedVoteCount)] ++ endVoteStates) | |
177 | + | } | |
142 | 178 | } | |
143 | 179 | ||
144 | 180 | ||
155 | 191 | let voteUpCountKey = (("vote_" + voteId) + "_upCount") | |
156 | 192 | let voteDownCountKey = (("vote_" + voteId) + "_downCount") | |
157 | 193 | let voteTotalCountKey = (("vote_" + voteId) + "_totalCount") | |
194 | + | let voteConfirmedKey = (("vote_" + voteId) + "_confirmed") | |
195 | + | let voteRejectedKey = (("vote_" + voteId) + "_rejected") | |
158 | 196 | let voteIdType = valueOrErrorMessage(getString(voterVoteTypeKey), "Vote Id type not founded") | |
159 | 197 | let voteIdPower = valueOrErrorMessage(getInteger(voterVotePowerKey), "Vote Id power not founded") | |
160 | 198 | let totalCount = valueOrErrorMessage(getInteger(voteTotalCountKey), "Vote Id total count not founded") | |
161 | 199 | let voterVotesCount = valueOrErrorMessage(getInteger(voterVotesCountKey), "Voter votes count value not founded") | |
162 | 200 | let voterSpentPower = valueOrErrorMessage(getInteger(voterSpentPowerKey), "Voter spent power value not founded") | |
163 | - | let voteChangeStates = if ((voteIdType == "up")) | |
164 | - | then { | |
165 | - | let upCount = valueOrElse(getInteger(voteUpCountKey), 0) | |
166 | - | [IntegerEntry(voteUpCountKey, (upCount - voteIdPower))] | |
167 | - | } | |
168 | - | else if ((voteIdType == "down")) | |
169 | - | then { | |
170 | - | let downCount = valueOrElse(getInteger(voteDownCountKey), 0) | |
171 | - | [IntegerEntry(voteDownCountKey, (downCount - voteIdPower))] | |
172 | - | } | |
173 | - | else throw("Invalid type") | |
201 | + | let upCountDapp = valueOrErrorMessage(getInteger(voteUpCountKey), "Up count note found") | |
202 | + | let downCountDapp = valueOrErrorMessage(getInteger(voteDownCountKey), "Down count note found") | |
203 | + | let upCount = if ((voteIdType == "up")) | |
204 | + | then (upCountDapp - voteIdPower) | |
205 | + | else upCountDapp | |
206 | + | let downCount = if ((voteIdType == "down")) | |
207 | + | then (downCountDapp - voteIdPower) | |
208 | + | else downCountDapp | |
174 | 209 | let isCallerVoted = valueOrElse(getBoolean(voterVoteKey), false) | |
175 | 210 | if (!(isCallerVoted)) | |
176 | 211 | then throw("You haven't voted yet") | |
177 | - | else ([DeleteEntry(voterVoteKey), DeleteEntry(voterVoteTypeKey), DeleteEntry(voterVoteCreatedKey), DeleteEntry(voterVotePowerKey), IntegerEntry(voterVotesCountKey, (voterVotesCount - 1)), IntegerEntry(voterSpentPowerKey, (voterSpentPower - voteIdPower)), IntegerEntry(voteTotalCountKey, (totalCount - voteIdPower))] ++ voteChangeStates) | |
212 | + | else if (isVotingClosed(voteId)) | |
213 | + | then throw("Voting is closed") | |
214 | + | else if (if ((voteIdType != "up")) | |
215 | + | then (voteIdType != "down") | |
216 | + | else false) | |
217 | + | then throw("Invalid type parametr") | |
218 | + | else [DeleteEntry(voterVoteKey), DeleteEntry(voterVoteTypeKey), DeleteEntry(voterVoteCreatedKey), DeleteEntry(voterVotePowerKey), IntegerEntry(voterVotesCountKey, (voterVotesCount - 1)), IntegerEntry(voterSpentPowerKey, (voterSpentPower - voteIdPower)), IntegerEntry(voteUpCountKey, upCount), IntegerEntry(voteDownCountKey, downCount), IntegerEntry(voteTotalCountKey, (totalCount - voteIdPower))] | |
178 | 219 | } | |
179 | 220 | ||
180 | 221 |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 6 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let creationAddress = Address(base58'3PFQjjDMiZKQZdu5JqTHD7HwgSXyp9Rw9By') | |
5 | 5 | ||
6 | 6 | let totalStakedKey = "total_staked" | |
7 | 7 | ||
8 | 8 | let totalPowerKey = "total_power" | |
9 | + | ||
10 | + | let POWER_LIMIT = 1000 | |
9 | 11 | ||
10 | 12 | func checkNFT (asset) = if (if (if (if ((getStringValue(creationAddress, (("nft_" + toBase58String(asset.id)) + "_issuer")) == toString(this))) | |
11 | 13 | then (asset.issuer == creationAddress) | |
12 | 14 | else false) | |
13 | 15 | then (asset.decimals == 0) | |
14 | 16 | else false) | |
15 | 17 | then (asset.reissuable == false) | |
16 | 18 | else false) | |
17 | 19 | then (asset.quantity == 1) | |
18 | 20 | else false | |
19 | 21 | ||
20 | 22 | ||
21 | 23 | func getPowerNFT (asset) = { | |
22 | 24 | let params = getStringValue(creationAddress, (("nft_" + toBase58String(asset.id)) + "_params")) | |
23 | 25 | if ((params == "gold")) | |
24 | 26 | then 50 | |
25 | 27 | else 10 | |
26 | 28 | } | |
27 | 29 | ||
28 | 30 | ||
29 | 31 | func getCollectionIssuer (collectionId) = { | |
30 | 32 | let assetId = valueOrElse(getString(creationAddress, (("collection_" + collectionId) + "_assetId")), "") | |
31 | 33 | valueOrElse(getString(creationAddress, (("nft_" + assetId) + "_issuer")), "") | |
34 | + | } | |
35 | + | ||
36 | + | ||
37 | + | func isVotingClosed (voteId) = { | |
38 | + | let voteConfirmedKey = (("vote_" + voteId) + "_confirmed") | |
39 | + | let voteRejectedKey = (("vote_" + voteId) + "_rejected") | |
40 | + | let isConfirmed = valueOrElse(getBoolean(voteConfirmedKey), false) | |
41 | + | let isRejected = valueOrElse(getBoolean(voteRejectedKey), false) | |
42 | + | if (isConfirmed) | |
43 | + | then true | |
44 | + | else isRejected | |
32 | 45 | } | |
33 | 46 | ||
34 | 47 | ||
35 | 48 | @Callable(i) | |
36 | 49 | func stake () = { | |
37 | 50 | let addressStr = toString(i.caller) | |
38 | 51 | let p = valueOrErrorMessage(i.payments[0], "No payments") | |
39 | 52 | let asset = valueOrErrorMessage(assetInfo(valueOrErrorMessage(p.assetId, "Invalid payment")), "Invalid asset Id") | |
40 | 53 | if (if ((p.amount > 0)) | |
41 | 54 | then checkNFT(asset) | |
42 | 55 | else false) | |
43 | 56 | then { | |
44 | 57 | let totalStaked = valueOrElse(getInteger(totalStakedKey), 0) | |
45 | 58 | let totalPower = valueOrElse(getInteger(totalPowerKey), 0) | |
46 | 59 | let addressPower = valueOrElse(getInteger((("address_" + addressStr) + "_power")), 0) | |
47 | 60 | let nftPower = getPowerNFT(asset) | |
48 | 61 | let nftIdStr = toBase58String(asset.id) | |
49 | 62 | [IntegerEntry(totalStakedKey, (totalStaked + 1)), IntegerEntry(totalPowerKey, (totalPower + nftPower)), StringEntry((("nft_" + nftIdStr) + "_owner"), addressStr), IntegerEntry((("nft_" + nftIdStr) + "_power"), nftPower), IntegerEntry((("address_" + addressStr) + "_power"), (addressPower + nftPower))] | |
50 | 63 | } | |
51 | 64 | else throw("No payments") | |
52 | 65 | } | |
53 | 66 | ||
54 | 67 | ||
55 | 68 | ||
56 | 69 | @Callable(i) | |
57 | 70 | func unstake (nftIdStr) = { | |
58 | 71 | let addressStr = toString(i.caller) | |
59 | 72 | let asset = valueOrErrorMessage(assetInfo(fromBase58String(nftIdStr)), "Invalid nft Id") | |
60 | 73 | let ownerAddress = valueOrErrorMessage(getString((("nft_" + nftIdStr) + "_owner")), "Owner data invalid") | |
61 | 74 | if ((ownerAddress != addressStr)) | |
62 | 75 | then throw("You are not the owner") | |
63 | 76 | else if (checkNFT(asset)) | |
64 | 77 | then { | |
65 | 78 | let totalStaked = valueOrElse(getInteger(totalStakedKey), 0) | |
66 | 79 | let totalPower = valueOrElse(getInteger(totalPowerKey), 0) | |
67 | 80 | let addressPower = valueOrElse(getInteger((("address_" + addressStr) + "_power")), 0) | |
68 | 81 | let nftAssetIdStr = toBase58String(asset.id) | |
69 | 82 | let nftPower = getIntegerValue((("nft_" + nftAssetIdStr) + "_power")) | |
70 | 83 | [ScriptTransfer(i.caller, 1, asset.id), IntegerEntry(totalStakedKey, (totalStaked - 1)), IntegerEntry(totalPowerKey, (totalPower - nftPower)), DeleteEntry((("nft_" + nftAssetIdStr) + "_owner")), DeleteEntry((("nft_" + nftAssetIdStr) + "_power")), IntegerEntry((("address_" + addressStr) + "_power"), (addressPower - nftPower))] | |
71 | 84 | } | |
72 | 85 | else throw("Invalid nft Id") | |
73 | 86 | } | |
74 | 87 | ||
75 | 88 | ||
76 | 89 | ||
77 | 90 | @Callable(i) | |
78 | 91 | func sendToVote (collectionId) = { | |
79 | 92 | let issuer = getCollectionIssuer(collectionId) | |
80 | 93 | if ((size(issuer) == 0)) | |
81 | 94 | then throw("Collection issuer not found") | |
82 | 95 | else if ((issuer != toString(i.caller))) | |
83 | 96 | then throw("Only the issuer can submit to the vote") | |
84 | 97 | else { | |
85 | 98 | let voteId = toBase58String(i.transactionId) | |
86 | - | [StringEntry((("collection_" + collectionId) + "_voteId"), voteId), StringEntry((("vote_" + voteId) + "_collectionId"), collectionId), StringEntry((("vote_" + voteId) + "_owner"), toString(i.caller)), IntegerEntry((("vote_" + voteId) + "_createdAt"), height)] | |
99 | + | let totalVotes = valueOrElse(getInteger("total_votes"), 0) | |
100 | + | [StringEntry((("collection_" + collectionId) + "_voteId"), voteId), StringEntry((("vote_" + voteId) + "_collectionId"), collectionId), StringEntry((("vote_" + voteId) + "_owner"), toString(i.caller)), IntegerEntry((("vote_" + voteId) + "_createdAt"), height), IntegerEntry("total_votes", (totalVotes + 1))] | |
87 | 101 | } | |
88 | 102 | } | |
89 | 103 | ||
90 | 104 | ||
91 | 105 | ||
92 | 106 | @Callable(i) | |
93 | 107 | func removeFromVote (voteId) = { | |
94 | 108 | let collectionId = valueOrErrorMessage(getString((("vote_" + voteId) + "_collectionId")), "Collection Id not found") | |
95 | 109 | let owner = valueOrErrorMessage(getString((("vote_" + voteId) + "_owner")), "Owner not found") | |
96 | 110 | if ((owner != toString(i.caller))) | |
97 | 111 | then throw("You are not the owner") | |
98 | - | else [DeleteEntry((("collection_" + collectionId) + "_voteId")), DeleteEntry((("vote_" + voteId) + "_collectionId")), DeleteEntry((("vote_" + voteId) + "_owner")), DeleteEntry((("vote_" + voteId) + "_createdAt"))] | |
112 | + | else if (isVotingClosed(voteId)) | |
113 | + | then throw("Voting is closed") | |
114 | + | else { | |
115 | + | let totalVotes = valueOrErrorMessage(getInteger("total_votes"), "total votes value not found") | |
116 | + | [DeleteEntry((("collection_" + collectionId) + "_voteId")), DeleteEntry((("vote_" + voteId) + "_collectionId")), DeleteEntry((("vote_" + voteId) + "_owner")), DeleteEntry((("vote_" + voteId) + "_createdAt")), IntegerEntry("total_votes", (totalVotes - 1))] | |
117 | + | } | |
99 | 118 | } | |
100 | 119 | ||
101 | 120 | ||
102 | 121 | ||
103 | 122 | @Callable(i) | |
104 | 123 | func vote (voteId,type) = { | |
105 | 124 | let addressStr = toString(i.caller) | |
106 | 125 | let exist = match getString((("vote_" + voteId) + "_collectionId")) { | |
107 | 126 | case t: String => | |
108 | 127 | true | |
109 | 128 | case _ => | |
110 | 129 | false | |
111 | 130 | } | |
112 | 131 | let voterVoteKey = (((("voter_" + addressStr) + "_vote_") + voteId) + "_isVoted") | |
113 | 132 | let voterVoteTypeKey = (((("voter_" + addressStr) + "_vote_") + voteId) + "_type") | |
114 | 133 | let voterVotePowerKey = (((("voter_" + addressStr) + "_vote_") + voteId) + "_power") | |
115 | 134 | let voterVoteCreatedKey = (((("voter_" + addressStr) + "_vote_") + voteId) + "_created") | |
116 | 135 | let voterVotesCountKey = (("voter_" + addressStr) + "_votesCount") | |
117 | 136 | let voterSpentPowerKey = (("voter_" + addressStr) + "_spentPower") | |
118 | 137 | let voteUpCountKey = (("vote_" + voteId) + "_upCount") | |
119 | 138 | let voteDownCountKey = (("vote_" + voteId) + "_downCount") | |
120 | 139 | let voteTotalCountKey = (("vote_" + voteId) + "_totalCount") | |
140 | + | let voteConfirmedKey = (("vote_" + voteId) + "_confirmed") | |
141 | + | let voteRejectedKey = (("vote_" + voteId) + "_rejected") | |
121 | 142 | let addressPower = valueOrErrorMessage(getInteger((("address_" + addressStr) + "_power")), "The address has no voting power") | |
122 | - | let | |
143 | + | let totalVoteCount = valueOrElse(getInteger(voteTotalCountKey), 0) | |
123 | 144 | let voterVotesCount = valueOrElse(getInteger(voterVotesCountKey), 0) | |
124 | 145 | let voterSpentPower = valueOrElse(getInteger(voterSpentPowerKey), 0) | |
125 | - | let voteChangeStates = if ((type == "up")) | |
126 | - | then { | |
127 | - | let upCount = valueOrElse(getInteger(voteUpCountKey), 0) | |
128 | - | [IntegerEntry(voteUpCountKey, (upCount + addressPower))] | |
129 | - | } | |
130 | - | else if ((type == "down")) | |
131 | - | then { | |
132 | - | let downCount = valueOrElse(getInteger(voteDownCountKey), 0) | |
133 | - | [IntegerEntry(voteDownCountKey, (downCount + addressPower))] | |
134 | - | } | |
135 | - | else throw("Invalid type") | |
146 | + | let upCountDapp = valueOrElse(getInteger(voteUpCountKey), 0) | |
147 | + | let downCountDapp = valueOrElse(getInteger(voteDownCountKey), 0) | |
148 | + | let upCount = if ((type == "up")) | |
149 | + | then (upCountDapp + addressPower) | |
150 | + | else upCountDapp | |
151 | + | let downCount = if ((type == "down")) | |
152 | + | then (downCountDapp + addressPower) | |
153 | + | else downCountDapp | |
136 | 154 | let isCallerVoted = valueOrElse(getBoolean(voterVoteKey), false) | |
137 | 155 | if (isCallerVoted) | |
138 | 156 | then throw("You have already voted") | |
139 | - | else if (!(exist)) | |
140 | - | then throw("Collection not found") | |
141 | - | else ([BooleanEntry(voterVoteKey, true), StringEntry(voterVoteTypeKey, type), IntegerEntry(voterVoteCreatedKey, height), IntegerEntry(voterVotePowerKey, addressPower), IntegerEntry(voterVotesCountKey, (voterVotesCount + 1)), IntegerEntry(voterSpentPowerKey, (voterSpentPower + addressPower)), IntegerEntry(voteTotalCountKey, (totalCount + addressPower))] ++ voteChangeStates) | |
157 | + | else if (isVotingClosed(voteId)) | |
158 | + | then throw("Voting is closed") | |
159 | + | else if (!(exist)) | |
160 | + | then throw("Collection not found") | |
161 | + | else if (if ((type != "up")) | |
162 | + | then (type != "down") | |
163 | + | else false) | |
164 | + | then throw("Invalid type parametr") | |
165 | + | else { | |
166 | + | let updatedVoteCount = (totalVoteCount + addressPower) | |
167 | + | let endVoteStates = if ((updatedVoteCount >= POWER_LIMIT)) | |
168 | + | then { | |
169 | + | let upPercent = fraction(upCount, 100, updatedVoteCount) | |
170 | + | let downPercent = fraction(downCount, 100, updatedVoteCount) | |
171 | + | if ((upPercent >= 50)) | |
172 | + | then [BooleanEntry(voteConfirmedKey, true)] | |
173 | + | else [BooleanEntry(voteRejectedKey, true)] | |
174 | + | } | |
175 | + | else nil | |
176 | + | ([BooleanEntry(voterVoteKey, true), StringEntry(voterVoteTypeKey, type), IntegerEntry(voterVoteCreatedKey, height), IntegerEntry(voterVotePowerKey, addressPower), IntegerEntry(voterVotesCountKey, (voterVotesCount + 1)), IntegerEntry(voterSpentPowerKey, (voterSpentPower + addressPower)), IntegerEntry(voteUpCountKey, upCount), IntegerEntry(voteDownCountKey, downCount), IntegerEntry(voteTotalCountKey, updatedVoteCount)] ++ endVoteStates) | |
177 | + | } | |
142 | 178 | } | |
143 | 179 | ||
144 | 180 | ||
145 | 181 | ||
146 | 182 | @Callable(i) | |
147 | 183 | func unvote (voteId) = { | |
148 | 184 | let addressStr = toString(i.caller) | |
149 | 185 | let voterVoteKey = (((("voter_" + addressStr) + "_vote_") + voteId) + "_isVoted") | |
150 | 186 | let voterVoteTypeKey = (((("voter_" + addressStr) + "_vote_") + voteId) + "_type") | |
151 | 187 | let voterVotePowerKey = (((("voter_" + addressStr) + "_vote_") + voteId) + "_power") | |
152 | 188 | let voterVoteCreatedKey = (((("voter_" + addressStr) + "_vote_") + voteId) + "_created") | |
153 | 189 | let voterVotesCountKey = (("voter_" + addressStr) + "_votesCount") | |
154 | 190 | let voterSpentPowerKey = (("voter_" + addressStr) + "_spentPower") | |
155 | 191 | let voteUpCountKey = (("vote_" + voteId) + "_upCount") | |
156 | 192 | let voteDownCountKey = (("vote_" + voteId) + "_downCount") | |
157 | 193 | let voteTotalCountKey = (("vote_" + voteId) + "_totalCount") | |
194 | + | let voteConfirmedKey = (("vote_" + voteId) + "_confirmed") | |
195 | + | let voteRejectedKey = (("vote_" + voteId) + "_rejected") | |
158 | 196 | let voteIdType = valueOrErrorMessage(getString(voterVoteTypeKey), "Vote Id type not founded") | |
159 | 197 | let voteIdPower = valueOrErrorMessage(getInteger(voterVotePowerKey), "Vote Id power not founded") | |
160 | 198 | let totalCount = valueOrErrorMessage(getInteger(voteTotalCountKey), "Vote Id total count not founded") | |
161 | 199 | let voterVotesCount = valueOrErrorMessage(getInteger(voterVotesCountKey), "Voter votes count value not founded") | |
162 | 200 | let voterSpentPower = valueOrErrorMessage(getInteger(voterSpentPowerKey), "Voter spent power value not founded") | |
163 | - | let voteChangeStates = if ((voteIdType == "up")) | |
164 | - | then { | |
165 | - | let upCount = valueOrElse(getInteger(voteUpCountKey), 0) | |
166 | - | [IntegerEntry(voteUpCountKey, (upCount - voteIdPower))] | |
167 | - | } | |
168 | - | else if ((voteIdType == "down")) | |
169 | - | then { | |
170 | - | let downCount = valueOrElse(getInteger(voteDownCountKey), 0) | |
171 | - | [IntegerEntry(voteDownCountKey, (downCount - voteIdPower))] | |
172 | - | } | |
173 | - | else throw("Invalid type") | |
201 | + | let upCountDapp = valueOrErrorMessage(getInteger(voteUpCountKey), "Up count note found") | |
202 | + | let downCountDapp = valueOrErrorMessage(getInteger(voteDownCountKey), "Down count note found") | |
203 | + | let upCount = if ((voteIdType == "up")) | |
204 | + | then (upCountDapp - voteIdPower) | |
205 | + | else upCountDapp | |
206 | + | let downCount = if ((voteIdType == "down")) | |
207 | + | then (downCountDapp - voteIdPower) | |
208 | + | else downCountDapp | |
174 | 209 | let isCallerVoted = valueOrElse(getBoolean(voterVoteKey), false) | |
175 | 210 | if (!(isCallerVoted)) | |
176 | 211 | then throw("You haven't voted yet") | |
177 | - | else ([DeleteEntry(voterVoteKey), DeleteEntry(voterVoteTypeKey), DeleteEntry(voterVoteCreatedKey), DeleteEntry(voterVotePowerKey), IntegerEntry(voterVotesCountKey, (voterVotesCount - 1)), IntegerEntry(voterSpentPowerKey, (voterSpentPower - voteIdPower)), IntegerEntry(voteTotalCountKey, (totalCount - voteIdPower))] ++ voteChangeStates) | |
212 | + | else if (isVotingClosed(voteId)) | |
213 | + | then throw("Voting is closed") | |
214 | + | else if (if ((voteIdType != "up")) | |
215 | + | then (voteIdType != "down") | |
216 | + | else false) | |
217 | + | then throw("Invalid type parametr") | |
218 | + | else [DeleteEntry(voterVoteKey), DeleteEntry(voterVoteTypeKey), DeleteEntry(voterVoteCreatedKey), DeleteEntry(voterVotePowerKey), IntegerEntry(voterVotesCountKey, (voterVotesCount - 1)), IntegerEntry(voterSpentPowerKey, (voterSpentPower - voteIdPower)), IntegerEntry(voteUpCountKey, upCount), IntegerEntry(voteDownCountKey, downCount), IntegerEntry(voteTotalCountKey, (totalCount - voteIdPower))] | |
178 | 219 | } | |
179 | 220 | ||
180 | 221 | ||
181 | 222 | @Verifier(tx) | |
182 | 223 | func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) | |
183 | 224 |
github/deemru/w8io/786bc32 47.05 ms ◑