tx · F4pAAvH83rQBNzq6Zpq9dPz6biTGyoXjEL3bdAdKvN6W

3N9yMmmL5cJ7LJxr8o6GFbKFUbGz4XcAjeg:  -0.01000000 Waves

2022.03.28 10:23 [1983460] smart account 3N9yMmmL5cJ7LJxr8o6GFbKFUbGz4XcAjeg > SELF 0.00000000 Waves

{ "type": 13, "id": "F4pAAvH83rQBNzq6Zpq9dPz6biTGyoXjEL3bdAdKvN6W", "fee": 1000000, "feeAssetId": null, "timestamp": 1648452216898, "version": 2, "chainId": 84, "sender": "3N9yMmmL5cJ7LJxr8o6GFbKFUbGz4XcAjeg", "senderPublicKey": "C2aAS9D6FqfbrkCuCQCtPWAiopjyagvitFLjRuLcRPYt", "proofs": [ "5HxtnEaLJrsbCArUFUhAABWUQrYV51HoTxvZwTU6iwbbuV6cQ13JitT6zfC1G7VpzCXKsQhBs18tmYPnWtgD6sdq" ], "script": "base64:AAIFAAAAAAAAAEgIAhIMCgoICAgBCAEBAQEBEgQKAggIEgQKAggEEgMKAQgSBAoCCAESABIDCgEBEgASABIDCgEBEgASAwoBARIDCgEBEgMKAQgAAAA6AAAAAAlzZXBhcmF0b3ICAAAAAl9fAAAAAA9tYXhEZXB0aERlZmF1bHQAAAAAAAAAAAoBAAAABWFzSW50AAAAAQAAAAN2YWwEAAAAByRtYXRjaDAFAAAAA3ZhbAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAADSW50BAAAAAZ2YWxJbnQFAAAAByRtYXRjaDAFAAAABnZhbEludAkAAAIAAAABAgAAABtGYWlsZWQgdG8gY2FzdCBpbnRvIEludGVnZXIBAAAABmFzQm9vbAAAAAEAAAADdmFsBAAAAAckbWF0Y2gwBQAAAAN2YWwDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAB0Jvb2xlYW4EAAAAB3ZhbEJvb2wFAAAAByRtYXRjaDAFAAAAB3ZhbEJvb2wJAAACAAAAAQIAAAAbRmFpbGVkIHRvIGNhc3QgaW50byBCb29sZWFuAAAAAAxrZXlGZWVBbW91bnQJAAS5AAAAAgkABEwAAAACAgAAAAIlcwkABEwAAAACAgAAAANmZWUFAAAAA25pbAUAAAAJc2VwYXJhdG9yAAAAAAxrZXlXeEFzc2V0SWQJAAS5AAAAAgkABEwAAAACAgAAAAIlcwkABEwAAAACAgAAAAl3eEFzc2V0SWQFAAAAA25pbAUAAAAJc2VwYXJhdG9yAAAAABJrZXlWb3RpbmdUaHJlc2hvbGQJAAS5AAAAAgkABEwAAAACAgAAAAIlcwkABEwAAAACAgAAAA92b3RpbmdUaHJlc2hvbGQFAAAAA25pbAUAAAAJc2VwYXJhdG9yAAAAABFrZXlWb3RpbmdEdXJhdGlvbgkABLkAAAACCQAETAAAAAICAAAAAiVzCQAETAAAAAICAAAAC2Vwb2NoTGVuZ3RoBQAAAANuaWwFAAAACXNlcGFyYXRvcgAAAAAYa2V5Vm90ZUJlZm9yZUVsaW1pbmF0aW9uCQAEuQAAAAIJAARMAAAAAgIAAAACJXMJAARMAAAAAgIAAAAVdm90ZUJlZm9yZUVsaW1pbmF0aW9uBQAAAANuaWwFAAAACXNlcGFyYXRvcgAAAAAOa2V5U3RhcnRIZWlnaHQJAAS5AAAAAgkABEwAAAACAgAAAAIlcwkABEwAAAACAgAAABhjdXJyZW50Vm90aW5nSGVpZ2h0U3RhcnQFAAAAA25pbAUAAAAJc2VwYXJhdG9yAAAAABBrZXlDdXJyZW50UGVyaW9kCQAEuQAAAAIJAARMAAAAAgIAAAACJXMJAARMAAAAAgIAAAAMY3VycmVudEVwb2NoBQAAAANuaWwFAAAACXNlcGFyYXRvcgAAAAATa2V5Qm9vc3RpbmdDb250cmFjdAkABLkAAAACCQAETAAAAAICAAAAAiVzCQAETAAAAAICAAAAEGJvb3N0aW5nQ29udHJhY3QFAAAAA25pbAUAAAAJc2VwYXJhdG9yAAAAABNrZXlFbWlzc2lvbkNvbnRyYWN0CQAEuQAAAAIJAARMAAAAAgIAAAACJXMJAARMAAAAAgIAAAAQZW1pc3Npb25Db250cmFjdAUAAAADbmlsBQAAAAlzZXBhcmF0b3IAAAAAFmtleUFzc2V0c1N0b3JlQ29udHJhY3QJAAS5AAAAAgkABEwAAAACAgAAAAIlcwkABEwAAAACAgAAABNhc3NldHNTdG9yZUNvbnRyYWN0BQAAAANuaWwFAAAACXNlcGFyYXRvcgAAAAAXa2V5TGF0ZXN0UHJvY2Vzc2VkQXNzZXQJAAS5AAAAAgkABEwAAAACAgAAAAIlcwkABEwAAAACAgAAABRsYXRlc3RQcm9jZXNzZWRBc3NldAUAAAADbmlsBQAAAAlzZXBhcmF0b3IAAAAAFmtleUxhdGVzdFByb2Nlc3NlZFVzZXIJAAS5AAAAAgkABEwAAAACAgAAAAIlcwkABEwAAAACAgAAABNsYXRlc3RQcm9jZXNzZWRVc2VyBQAAAANuaWwFAAAACXNlcGFyYXRvcgAAAAAfa2V5TGF0ZXN0UHJvY2Vzc2VkQXNzZXRUcmFuc2ZlcgkABLkAAAACCQAETAAAAAICAAAAAiVzCQAETAAAAAICAAAAHGxhdGVzdFByb2Nlc3NlZEFzc2V0VHJhbnNmZXIFAAAAA25pbAUAAAAJc2VwYXJhdG9yAAAAAB5rZXlMYXRlc3RQcm9jZXNzZWRVc2VyVHJhbnNmZXIJAAS5AAAAAgkABEwAAAACAgAAAAIlcwkABEwAAAACAgAAABtsYXRlc3RQcm9jZXNzZWRVc2VyVHJhbnNmZXIFAAAAA25pbAUAAAAJc2VwYXJhdG9yAAAAAAtrZXlNYXhEZXB0aAkABLkAAAACCQAETAAAAAICAAAAAiVzCQAETAAAAAICAAAACG1heERlcHRoBQAAAANuaWwFAAAACXNlcGFyYXRvcgEAAAAga2V5Vm90ZXNUcmFuc2ZlckZpbmlzaGVkQnlQZXJpb2QAAAABAAAABnBlcmlvZAkABLkAAAACCQAETAAAAAICAAAAAiVzCQAETAAAAAICAAAAFXZvdGVzVHJhbnNmZXJGaW5pc2hlZAkABEwAAAACCQABpAAAAAEFAAAABnBlcmlvZAUAAAADbmlsBQAAAAlzZXBhcmF0b3IAAAAADmFzc2V0c0xpc3ROYW1lAgAAAAhfX2Fzc2V0cwEAAAAQZ2V0Vm90ZXNMaXN0TmFtZQAAAAEAAAAHYXNzZXRJZAkAASwAAAACAgAAAAslc19fdm90ZXNfXwUAAAAHYXNzZXRJZAEAAAALa2V5TGlzdEhlYWQAAAABAAAACGxpc3ROYW1lCQAEuQAAAAIJAARMAAAAAgkAASwAAAACAgAAAAQlcyVzBQAAAAhsaXN0TmFtZQkABEwAAAACAgAAAARoZWFkBQAAAANuaWwFAAAACXNlcGFyYXRvcgEAAAALa2V5TGlzdFNpemUAAAABAAAACGxpc3ROYW1lCQAEuQAAAAIJAARMAAAAAgkAASwAAAACAgAAAAQlcyVzBQAAAAhsaXN0TmFtZQkABEwAAAACAgAAAARzaXplBQAAAANuaWwFAAAACXNlcGFyYXRvcgEAAAALa2V5TGlzdFByZXYAAAACAAAACGxpc3ROYW1lAAAAAmlkCQAEuQAAAAIJAARMAAAAAgkAASwAAAACAgAAAAYlcyVzJXMFAAAACGxpc3ROYW1lCQAETAAAAAIFAAAAAmlkCQAETAAAAAICAAAABHByZXYFAAAAA25pbAUAAAAJc2VwYXJhdG9yAQAAAAtrZXlMaXN0TmV4dAAAAAIAAAAIbGlzdE5hbWUAAAACaWQJAAS5AAAAAgkABEwAAAACCQABLAAAAAICAAAABiVzJXMlcwUAAAAIbGlzdE5hbWUJAARMAAAAAgUAAAACaWQJAARMAAAAAgIAAAAEbmV4dAUAAAADbmlsBQAAAAlzZXBhcmF0b3IBAAAAGGtleUFzc2V0VmVyaWZpZWRCeVBlcmlvZAAAAAIAAAAHYXNzZXRJZAAAAAZwZXJpb2QJAAS5AAAAAgkABEwAAAACAgAAAAYlcyVkJXMJAARMAAAAAgIAAAAKdmVyaWZpZWRBdAkABEwAAAACCQABpAAAAAEFAAAABnBlcmlvZAkABEwAAAACBQAAAAdhc3NldElkBQAAAANuaWwFAAAACXNlcGFyYXRvcgEAAAAVa2V5Vm90ZVJlc3VsdEJ5UGVyaW9kAAAAAgAAAAdhc3NldElkAAAABnBlcmlvZAkABLkAAAACCQAETAAAAAICAAAABiVzJWQlcwkABEwAAAACAgAAABN2b3RpbmdSZXN1bHRBdEFzc2V0CQAETAAAAAIJAAGkAAAAAQUAAAAGcGVyaW9kCQAETAAAAAIFAAAAB2Fzc2V0SWQFAAAAA25pbAUAAAAJc2VwYXJhdG9yAQAAABBmb3JtYXRWb3RlUmVzdWx0AAAAAwAAAAh0b3RhbFllcwAAAAd0b3RhbE5vAAAACHZlcmlmaWVkCQAEuQAAAAIJAARMAAAAAgIAAAAGJWQlZCVzCQAETAAAAAIJAAGkAAAAAQUAAAAIdG90YWxZZXMJAARMAAAAAgkAAaQAAAABBQAAAAd0b3RhbE5vCQAETAAAAAIJAAGlAAAAAQUAAAAIdmVyaWZpZWQFAAAAA25pbAUAAAAJc2VwYXJhdG9yAQAAAA9wYXJzZVZvdGVSZXN1bHQAAAABAAAABWlucHV0BAAAAAVwYXJ0cwkABLUAAAACBQAAAAVpbnB1dAUAAAAJc2VwYXJhdG9yBAAAAAt0b3RhbFllc0lkeAAAAAAAAAAAAQQAAAAKdG90YWxOb0lkeAAAAAAAAAAAAgQAAAALdmVyaWZpZWRJZHgAAAAAAAAAAAMEAAAACHRvdGFsWWVzCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAFcGFydHMFAAAAC3RvdGFsWWVzSWR4BAAAAAd0b3RhbE5vCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAFcGFydHMFAAAACnRvdGFsTm9JZHgEAAAACHZlcmlmaWVkAwkAAAAAAAACCQABkAAAAAEFAAAABXBhcnRzAAAAAAAAAAADCQAAAAAAAAIJAAGRAAAAAgUAAAAFcGFydHMFAAAAC3ZlcmlmaWVkSWR4AgAAAAR0cnVlBwkABRUAAAADBQAAAAh0b3RhbFllcwUAAAAHdG90YWxObwUAAAAIdmVyaWZpZWQBAAAAE2tleVVzZXJWb3RlQnlQZXJpb2QAAAADAAAAC3VzZXJBZGRyZXNzAAAAB2Fzc2V0SWQAAAAGcGVyaW9kCQAEuQAAAAIJAARMAAAAAgIAAAAIJXMlZCVzJXMJAARMAAAAAgIAAAADdnJ1CQAETAAAAAIJAAGkAAAAAQUAAAAGcGVyaW9kCQAETAAAAAIFAAAAB2Fzc2V0SWQJAARMAAAAAgUAAAALdXNlckFkZHJlc3MFAAAAA25pbAUAAAAJc2VwYXJhdG9yAQAAAA5mb3JtYXRVc2VyVm90ZQAAAAIAAAAFdG90YWwAAAAHaW5GYXZvcgQAAAAIdG90YWxZZXMDBQAAAAdpbkZhdm9yBQAAAAV0b3RhbAAAAAAAAAAAAAQAAAAHdG90YWxObwMFAAAAB2luRmF2b3IAAAAAAAAAAAAFAAAABXRvdGFsCQAEuQAAAAIJAARMAAAAAgIAAAAEJWQlZAkABEwAAAACCQABpAAAAAEFAAAACHRvdGFsWWVzCQAETAAAAAIJAAGkAAAAAQUAAAAHdG90YWxObwUAAAADbmlsBQAAAAlzZXBhcmF0b3IBAAAADXBhcnNlVXNlclZvdGUAAAABAAAABWlucHV0BAAAAAVwYXJ0cwkABLUAAAACBQAAAAVpbnB1dAUAAAAJc2VwYXJhdG9yBAAAAAt0b3RhbFllc0lkeAAAAAAAAAAAAQQAAAAKdG90YWxOb0lkeAAAAAAAAAAAAgQAAAAIdG90YWxZZXMJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAVwYXJ0cwUAAAALdG90YWxZZXNJZHgEAAAAB3RvdGFsTm8JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAVwYXJ0cwUAAAAKdG90YWxOb0lkeAQAAAAHaW5GYXZvcgMJAABmAAAAAgUAAAAIdG90YWxZZXMAAAAAAAAAAAAJAAAAAAAAAgUAAAAHdG90YWxObwAAAAAAAAAAAAcEAAAAB2FnYWluc3QDCQAAAAAAAAIFAAAACHRvdGFsWWVzAAAAAAAAAAAACQAAZgAAAAIFAAAAB3RvdGFsTm8AAAAAAAAAAAAHBAAAAAtjaGVja1RvdGFscwMDBQAAAAdpbkZhdm9yBgUAAAAHYWdhaW5zdAYJAAACAAAAAQIAAAAXSW52YWxpZCB1c2VyIHZvdGUgdmFsdWUDCQAAAAAAAAIFAAAAC2NoZWNrVG90YWxzBQAAAAtjaGVja1RvdGFscwQAAAAFdG90YWwDBQAAAAdpbkZhdm9yBQAAAAh0b3RhbFllcwUAAAAHdG90YWxObwkABRQAAAACBQAAAAV0b3RhbAUAAAAHaW5GYXZvcgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAAAAEmtleVVzZXJWb3RlSGlzdG9yeQAAAAUAAAAEdHlwZQAAAAt1c2VyQWRkcmVzcwAAAAdhc3NldElkAAAABHR4SWQAAAAGcGVyaW9kCQAEuQAAAAIJAARMAAAAAgIAAAAMJXMlcyVzJXMlcyVkCQAETAAAAAICAAAAB2hpc3RvcnkJAARMAAAAAgUAAAAEdHlwZQkABEwAAAACBQAAAAdhc3NldElkCQAETAAAAAIFAAAAC3VzZXJBZGRyZXNzCQAETAAAAAIFAAAABHR4SWQJAARMAAAAAgkAAaQAAAABBQAAAAZwZXJpb2QFAAAAA25pbAUAAAAJc2VwYXJhdG9yAQAAAAh0aGlzT25seQAAAAEAAAABaQMJAAAAAAAAAggFAAAAAWkAAAAGY2FsbGVyBQAAAAR0aGlzBgkAAAIAAAABAgAAABFQZXJtaXNzaW9uIGRlbmllZAEAAAAQZ2V0SW50ZWdlck9yWmVybwAAAAEAAAADa2V5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAA2tleQAAAAAAAAAAAAEAAAAQZ2V0SW50ZWdlck9yRmFpbAAAAAEAAAADa2V5CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAADa2V5CQABLAAAAAIFAAAAA2tleQIAAAAPIGlzIG5vdCBkZWZpbmVkAQAAABBnZXRTdHJpbmdPckVtcHR5AAAAAQAAAANrZXkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAADa2V5AgAAAAABAAAAD2dldFN0cmluZ09yRmFpbAAAAAEAAAADa2V5CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAADa2V5CQABLAAAAAIFAAAAA2tleQIAAAAPIGlzIG5vdCBkZWZpbmVkAAAAAAlmZWVBbW91bnQJAQAAABBnZXRJbnRlZ2VyT3JGYWlsAAAAAQUAAAAMa2V5RmVlQW1vdW50AAAAAAl3eEFzc2V0SWQJAAJZAAAAAQkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAEFAAAADGtleVd4QXNzZXRJZAAAAAAPdm90aW5nVGhyZXNob2xkCQEAAAAQZ2V0SW50ZWdlck9yRmFpbAAAAAEFAAAAEmtleVZvdGluZ1RocmVzaG9sZAAAAAAOdm90aW5nRHVyYXRpb24JAQAAABBnZXRJbnRlZ2VyT3JGYWlsAAAAAQUAAAARa2V5Vm90aW5nRHVyYXRpb24AAAAAFXZvdGVCZWZvcmVFbGltaW5hdGlvbgkBAAAAEGdldEludGVnZXJPckZhaWwAAAABBQAAABhrZXlWb3RlQmVmb3JlRWxpbWluYXRpb24AAAAAC3N0YXJ0SGVpZ2h0CQEAAAAQZ2V0SW50ZWdlck9yRmFpbAAAAAEFAAAADmtleVN0YXJ0SGVpZ2h0AAAAAA1jdXJyZW50UGVyaW9kCQEAAAAQZ2V0SW50ZWdlck9yRmFpbAAAAAEFAAAAEGtleUN1cnJlbnRQZXJpb2QAAAAAEGJvb3N0aW5nQ29udHJhY3QJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAQAAAA9nZXRTdHJpbmdPckZhaWwAAAABBQAAABNrZXlCb29zdGluZ0NvbnRyYWN0AAAAABBlbWlzc2lvbkNvbnRyYWN0CQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAQUAAAATa2V5RW1pc3Npb25Db250cmFjdAAAAAATYXNzZXRzU3RvcmVDb250cmFjdAkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAEFAAAAFmtleUFzc2V0c1N0b3JlQ29udHJhY3QAAAAACG1heERlcHRoCQEA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AAALRGVsZXRlRW50cnkAAAABCQEAAAALa2V5TGlzdFByZXYAAAACBQAAAAhsaXN0TmFtZQUAAAACaWQJAARMAAAAAgkBAAAAC0RlbGV0ZUVudHJ5AAAAAQkBAAAAC2tleUxpc3ROZXh0AAAAAgUAAAAIbGlzdE5hbWUJAQAAAAV2YWx1ZQAAAAEFAAAABHByZXYFAAAAA25pbAMJAAAAAAAAAgUAAAACaWQFAAAABGhlYWQJAARMAAAAAgkBAAAAC0RlbGV0ZUVudHJ5AAAAAQkBAAAAC2tleUxpc3RIZWFkAAAAAQUAAAAIbGlzdE5hbWUFAAAAA25pbAkAAAIAAAABAgAAAAxJbnZhbGlkIG5vZGUBAAAAC3Byb2Nlc3NWb3RlAAAABAAAAAdhc3NldElkAAAAEXVzZXJBZGRyZXNzT3JVbml0AAAAF2xhdGVzdFByb2Nlc3NlZEFzc2V0S2V5AAAAFmxhdGVzdFByb2Nlc3NlZFVzZXJLZXkEAAAAIHVwZGF0ZUxhdGVzdFByb2Nlc3NlZEFzc2V0QWN0aW9uCQEAAAALU3RyaW5nRW50cnkAAAACBQAAABdsYXRlc3RQcm9jZXNzZWRBc3NldEtleQUAAAAHYXNzZXRJZAQAAAAfZGVsZXRlTGF0ZXN0UHJvY2Vzc2VkVXNlckFjdGlvbgkBAAAAC0RlbGV0ZUVudHJ5AAAAAQUAAAAWbGF0ZXN0UHJvY2Vzc2VkVXNlcktleQMJAAAAAAAAAgUAAAARdXNlckFkZHJlc3NPclVuaXQFAAAABHVuaXQJAARMAAAAAgUAAAAgdXBkYXRlTGF0ZXN0UHJvY2Vzc2VkQXNzZXRBY3Rpb24JAARMAAAAAgUAAAAfZGVsZXRlTGF0ZXN0UHJvY2Vzc2VkVXNlckFjdGlvbgUAAAADbmlsBAAAAAllbmRIZWlnaHQJAABkAAAAAgUAAAALc3RhcnRIZWlnaHQFAAAADnZvdGluZ0R1cmF0aW9uBAAAAAt1c2VyQWRkcmVzcwkBAAAABXZhbHVlAAAAAQUAAAARdXNlckFkZHJlc3NPclVuaXQEAAAAH3VwZGF0ZUxhdGVzdFByb2Nlc3NlZFVzZXJBY3Rpb24JAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAFmxhdGVzdFByb2Nlc3NlZFVzZXJLZXkFAAAAC3VzZXJBZGRyZXNzBAAAAAt1c2VyVm90ZUtleQkBAAAAE2tleVVzZXJWb3RlQnlQZXJpb2QAAAADBQAAAAt1c2VyQWRkcmVzcwUAAAAHYXNzZXRJZAUAAAANY3VycmVudFBlcmlvZAQAAAAOdXNlclZvdGVPclVuaXQJAAQiAAAAAQUAAAALdXNlclZvdGVLZXkEAAAAGHVzZXJHd3hBbW91bnRBdEVuZEhlaWdodAkBAAAAGGdldFVzZXJHd3hBbW91bnRBdEhlaWdodAAAAAIFAAAAC3VzZXJBZGRyZXNzBQAAAAllbmRIZWlnaHQEAAAAC3ZvdGVBY3Rpb25zAwkAAAAAAAACBQAAABh1c2VyR3d4QW1vdW50QXRFbmRIZWlnaHQAAAAAAAAAAAAEAAAADXZvdGVzTGlzdE5hbWUJAQAAABBnZXRWb3Rlc0xpc3ROYW1lAAAAAQUAAAAHYXNzZXRJZAkBAAAACmRlbGV0ZU5vZGUAAAACBQAAAA12b3Rlc0xpc3ROYW1lBQAAAAt1c2VyQWRkcmVzcwMJAAAAAAAAAgUAAAAOdXNlclZvdGVPclVuaXQFAAAABHVuaXQEAAAAFnVzZXJQcmV2aW91c1ZvdGVPclVuaXQJAAQiAAAAAQkBAAAAE2tleVVzZXJWb3RlQnlQZXJpb2QAAAADBQAAAAt1c2VyQWRkcmVzcwUAAAAHYXNzZXRJZAkAAGUAAAACBQAAAA1jdXJyZW50UGVyaW9kAAAAAAAAAAABAwkAAAAAAAACBQAAABZ1c2VyUHJldmlvdXNWb3RlT3JVbml0BQAAAAR1bml0BQAAAANuaWwEAAAACyR0MDk4ODU5OTU4CQEAAAANcGFyc2VVc2VyVm90ZQAAAAEJAQAAAAV2YWx1ZQAAAAEFAAAAFnVzZXJQcmV2aW91c1ZvdGVPclVuaXQEAAAACXByZXZUb3RhbAgFAAAACyR0MDk4ODU5OTU4AAAAAl8xBAAAAAdpbkZhdm9yCAUAAAALJHQwOTg4NTk5NTgAAAACXzIEAAAABXRvdGFsCQABlwAAAAEJAARMAAAAAgUAAAAJcHJldlRvdGFsCQAETAAAAAIFAAAAGHVzZXJHd3hBbW91bnRBdEVuZEhlaWdodAUAAAADbmlsCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAC3VzZXJWb3RlS2V5CQEAAAAOZm9ybWF0VXNlclZvdGUAAAACBQAAAAV0b3RhbAUAAAAHaW5GYXZvcgkABEwAAAACCQEAAAATZ2V0Vm90ZVJlc3VsdEFjdGlvbgAAAAUFAAAAB2Fzc2V0SWQFAAAABXRvdGFsBQAAAAdpbkZhdm9yBQAAAA1jdXJyZW50UGVyaW9kBQAAAAR1bml0BQAAAANuaWwFAAAAA25pbAkABE0AAAACCQAETQAAAAIFAAAAC3ZvdGVBY3Rpb25zBQAAACB1cGRhdGVMYXRlc3RQcm9jZXNzZWRBc3NldEFjdGlvbgUAAAAfdXBkYXRlTGF0ZXN0UHJvY2Vzc2VkVXNlckFjdGlvbgEAAAAXYXNzZXRTaG91bGRCZUVsaW1pbmF0ZWQAAAACAAAAB2Fzc2V0SWQAAAAGcGVyaW9kCQEAAAABIQAAAAEJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQgAAAAAQkBAAAAGGtleUFzc2V0VmVyaWZpZWRCeVBlcmlvZAAAAAIFAAAAB2Fzc2V0SWQFAAAABnBlcmlvZAYBAAAAEGVsaW1pbmF0aW9uQ2hlY2sAAAABAAAAB2Fzc2V0SWQDAwkBAAAAF2Fzc2V0U2hvdWxkQmVFbGltaW5hdGVkAAAAAgUAAAAHYXNzZXRJZAkAAGUAAAACBQAAAA1jdXJyZW50UGVyaW9kAAAAAAAAAAABCQEAAAAXYXNzZXRTaG91bGRCZUVsaW1pbmF0ZWQAAAACBQAAAAdhc3NldElkCQAAZQAAAAIFAAAADWN1cnJlbnRQZXJpb2QAAAAAAAAAAAIHCQEAAAAXYXNzZXRTaG91bGRCZUVsaW1pbmF0ZWQAAAACBQAAAAdhc3NldElkCQAAZQAAAAIFAAAADWN1cnJlbnRQZXJpb2QAAAAAAAAAAAMHAAAADgAAAAFpAQAAAAtjb25zdHJ1Y3RvcgAAAAoAAAATYm9vc3RpbmdDb250cmFjdFBybQAAABNlbWlzc2lvbkNvbnRyYWN0UHJtAAAAFmFzc2V0c1N0b3JlQ29udHJhY3RQcm0AAAAMZmVlQW1vdW50UHJtAAAADHd4QXNzZXRJZFBybQAAABJ2b3RpbmdUaHJlc2hvbGRQcm0AAAARdm90aW5nRHVyYXRpb25Qcm0AAAAYdm90ZUJlZm9yZUVsaW1pbmF0aW9uUHJtAAAADnN0YXJ0SGVpZ2h0UHJtAAAAC21heERlcHRoUHJtBAAAAAZjaGVja3MJAARMAAAAAgkBAAAACHRoaXNPbmx5AAAAAQUAAAABaQkABEwAAAACAwkBAAAACWlzRGVmaW5lZAAAAAEJAAQmAAAAAQUAAAATYm9vc3RpbmdDb250cmFjdFBybQYJAAACAAAAAQIAAAAhSW52YWxpZCBib29zdGluZyBjb250cmFjdCBhZGRyZXNzCQAETAAAAAIDCQEAAAAJaXNEZWZpbmVkAAAAAQkABCYAAAABBQAAABNlbWlzc2lvbkNvbnRyYWN0UHJtBgkAAAIAAAABAgAAACFJbnZhbGlkIGVtaXNzaW9uIGNvbnRyYWN0IGFkZHJlc3MJAARMAAAAAgMJAQAAAAlpc0RlZmluZWQAAAABCQAEJgAAAAEFAAAAFmFzc2V0c1N0b3JlQ29udHJhY3RQcm0GCQAAAgAAAAECAAAAJEludmFsaWQgYXNzZXRfc3RvcmUgY29udHJhY3QgYWRkcmVzcwkABEwAAAACAwkAAGcAAAACBQAAAAxmZWVBbW91bnRQcm0AAAAAAAAAAAAGCQAAAgAAAAECAAAAEkludmFsaWQgZmVlIGFtb3VudAkABEwAAAACAwkBAAAACWlzRGVmaW5lZAAAAAEJAAPsAAAAAQkAAlkAAAABBQAAAAx3eEFzc2V0SWRQcm0GCQAAAgAAAAECAAAAE0ludmFsaWQgV1ggYXNzZXQgSUQJAARMAAAAAgMJAABnAAAAAgUAAAASdm90aW5nVGhyZXNob2xkUHJtAAAAAAAAAAAABgkAAAIAAAABAgAAABhJbnZhbGlkIHZvdGluZyB0aHJlc2hvbGQJAARMAAAAAgMJAABmAAAAAgUAAAARdm90aW5nRHVyYXRpb25Qcm0AAAAAAAAAAAAGCQAAAgAAAAECAAAAF0ludmFsaWQgdm90aW5nIGR1cmF0aW9uCQAETAAAAAIDCQAAZgAAAAIJAABkAAAAAgUAAAAOc3RhcnRIZWlnaHRQcm0FAAAAEXZvdGluZ0R1cmF0aW9uUHJtBQAAAAZoZWlnaHQGCQAAAgAAAAECAAAAFEludmFsaWQgc3RhcnQgaGVpZ2h0BQAAAANuaWwDCQAAAAAAAAIFAAAABmNoZWNrcwUAAAAGY2hlY2tzCQAFFAAAAAIJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAATa2V5Qm9vc3RpbmdDb250cmFjdAUAAAATYm9vc3RpbmdDb250cmFjdFBybQkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAABNrZXlFbWlzc2lvbkNvbnRyYWN0BQAAABNlbWlzc2lvbkNvbnRyYWN0UHJtCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAFmtleUFzc2V0c1N0b3JlQ29udHJhY3QFAAAAFmFzc2V0c1N0b3JlQ29udHJhY3RQcm0JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAADGtleUZlZUFtb3VudAUAAAAMZmVlQW1vdW50UHJtCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAADGtleVd4QXNzZXRJZAUAAAAMd3hBc3NldElkUHJtCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABJrZXlWb3RpbmdUaHJlc2hvbGQFAAAAEnZvdGluZ1RocmVzaG9sZFBybQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARa2V5Vm90aW5nRHVyYXRpb24FAAAAEXZvdGluZ0R1cmF0aW9uUHJtCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABhrZXlWb3RlQmVmb3JlRWxpbWluYXRpb24FAAAAGHZvdGVCZWZvcmVFbGltaW5hdGlvblBybQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAOa2V5U3RhcnRIZWlnaHQFAAAADnN0YXJ0SGVpZ2h0UHJtCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABBrZXlDdXJyZW50UGVyaW9kAAAAAAAAAAAACQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtrZXlNYXhEZXB0aAUAAAALbWF4RGVwdGhQcm0FAAAAA25pbAUAAAAEdW5pdAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAHc3VnZ2VzdAAAAAIAAAAHYXNzZXRJZAAAAAphc3NldEltYWdlBAAAAARpbmZvCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAPsAAAAAQkAAlkAAAABBQAAAAdhc3NldElkAgAAABBJbnZhbGlkIGFzc2V0IElEBAAAAAdwYXltZW50CQEAAAAFdmFsdWUAAAABCQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAABAAAAAZjaGVja3MJAARMAAAAAgMJAAAAAAAAAggFAAAABGluZm8AAAAGaXNzdWVyCAUAAAABaQAAAAZjYWxsZXIGCQAAAgAAAAECAAAAKUFzc2V0IGNhbiBvbmx5IGJlIHN1Z2dlc3RlZCBieSBpdHMgaXNzdWVyCQAETAAAAAIDCQAAAAAAAAIJAQAAAAV2YWx1ZQAAAAEIBQAAAAdwYXltZW50AAAAB2Fzc2V0SWQFAAAACXd4QXNzZXRJZAYJAAACAAAAAQIAAAARSW52YWxpZCBmZWUgYXNzZXQJAARMAAAAAgMJAAAAAAAAAggFAAAAB3BheW1lbnQAAAAGYW1vdW50BQAAAAlmZWVBbW91bnQGCQAAAgAAAAECAAAAEkludmFsaWQgZmVlIGFtb3VudAUAAAADbmlsAwkAAAAAAAACBQAAAAZjaGVja3MFAAAABmNoZWNrcwQAAAAcYXNzZXRzU3RvcmVDcmVhdGVPclVwZGF0ZUludgkAA/wAAAAEBQAAABNhc3NldHNTdG9yZUNvbnRyYWN0AgAAAA5jcmVhdGVPclVwZGF0ZQkABEwAAAACBQAAAAdhc3NldElkCQAETAAAAAICAAAAAAkABEwAAAACBQAAAAphc3NldEltYWdlCQAETAAAAAIHBQAAAANuaWwFAAAAA25pbAMJAAAAAAAAAgUAAAAcYXNzZXRzU3RvcmVDcmVhdGVPclVwZGF0ZUludgUAAAAcYXNzZXRzU3RvcmVDcmVhdGVPclVwZGF0ZUludgQAAAAKYnVybkZlZUludgkAA/wAAAAEBQAAABBlbWlzc2lvbkNvbnRyYWN0AgAAAARidXJuBQAAAANuaWwJAARMAAAAAgkBAAAAD0F0dGFjaGVkUGF5bWVudAAAAAIIBQAAAAdwYXltZW50AAAAB2Fzc2V0SWQIBQAAAAdwYXltZW50AAAABmFtb3VudAUAAAADbmlsAwkAAAAAAAACBQAAAApidXJuRmVlSW52BQAAAApidXJuRmVlSW52BAAAAA9hZGRBc3NldEFjdGlvbnMJAQAAAAppbnNlcnROb2RlAAAAAgUAAAAOYXNzZXRzTGlzdE5hbWUFAAAAB2Fzc2V0SWQJAAUUAAAAAgkABE0AAAACBQAAAA9hZGRBc3NldEFjdGlvbnMJAQAAABNnZXRWb3RlUmVzdWx0QWN0aW9uAAAABQUAAAAHYXNzZXRJZAAAAAAAAAAAAAYFAAAADWN1cnJlbnRQZXJpb2QHBQAAAAR1bml0CQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAABHZvdGUAAAACAAAAB2Fzc2V0SWQAAAAHaW5GYXZvcgQAAAAJZW5kSGVpZ2h0CQAAZAAAAAIFAAAAC3N0YXJ0SGVpZ2h0BQAAAA52b3RpbmdEdXJhdGlvbgQAAAAKY2hlY2tBc3NldAMJAQAAAAxjb250YWluc05vZGUAAAACBQAAAA5hc3NldHNMaXN0TmFtZQUAAAAHYXNzZXRJZAYJAAACAAAAAQIAAAANSW52YWxpZCBhc3NldAMJAAAAAAAAAgUAAAAKY2hlY2tBc3NldAUAAAAKY2hlY2tBc3NldAQAAAALY2hlY2tIZWlnaHQDCQAAZgAAAAIFAAAACWVuZEhlaWdodAUAAAAGaGVpZ2h0BgkAAAIAAAABAgAAADRDdXJyZW50IHZvdGluZyBpcyBvdmVyIGJ1dCByZXN1bHRzIGFyZSBub3QgZmluYWxpemVkAwkAAAAAAAACBQAAAAtjaGVja0hlaWdodAUAAAALY2hlY2tIZWlnaHQEAAAAC3VzZXJBZGRyZXNzCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgQAAAAOZ3d4QW1vdW50QXRFbmQJAQAAABhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQAAAACBQAAAAt1c2VyQWRkcmVzcwUAAAAJZW5kSGVpZ2h0BAAAABNjaGVja0d3eEFtb3VudEF0RW5kAwkAAGYAAAACBQAAAA5nd3hBbW91bnRBdEVuZAAAAAAAAAAAAAYJAAACAAAAAQIAAAAoWW91J2xsIG5vdCBoYXZlIGdXWCBhdCB0aGUgZW5kIG9mIHZvdGluZwMJAAAAAAAAAgUAAAATY2hlY2tHd3hBbW91bnRBdEVuZAUAAAATY2hlY2tHd3hBbW91bnRBdEVuZAQAAAANdm90ZXNMaXN0TmFtZQkBAAAAEGdldFZvdGVzTGlzdE5hbWUAAAABBQAAAAdhc3NldElkBAAAAAt1c2VyVm90ZUtleQkBAAAAE2tleVVzZXJWb3RlQnlQZXJpb2QAAAADBQAAAAt1c2VyQWRkcmVzcwUAAAAHYXNzZXRJZAUAAAANY3VycmVudFBlcmlvZAQAAAAPdXNlclZvdGVBY3Rpb25zCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAC3VzZXJWb3RlS2V5CQEAAAAOZm9ybWF0VXNlclZvdGUAAAACBQAAAA5nd3hBbW91bnRBdEVuZAUAAAAHaW5GYXZvcgkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAASa2V5VXNlclZvdGVIaXN0b3J5AAAABQIAAAAEdm90ZQUAAAALdXNlckFkZHJlc3MFAAAAB2Fzc2V0SWQJAAJYAAAAAQgFAAAAAWkAAAANdHJhbnNhY3Rpb25JZAUAAAANY3VycmVudFBlcmlvZAkBAAAADmZvcm1hdFVzZXJWb3RlAAAAAgUAAAAOZ3d4QW1vdW50QXRFbmQFAAAAB2luRmF2b3IJAARMAAAAAgkBAAAAE2dldFZvdGVSZXN1bHRBY3Rpb24AAAAFBQAAAAdhc3NldElkBQAAAA5nd3hBbW91bnRBdEVuZAUAAAAHaW5GYXZvcgUAAAANY3VycmVudFBlcmlvZAUAAAAEdW5pdAUAAAADbmlsBAAAABB2b3Rlc0xpc3RBY3Rpb25zAwkBAAAADGNvbnRhaW5zTm9kZQAAAAIFAAAADXZvdGVzTGlzdE5hbWUFAAAAC3VzZXJBZGRyZXNzBQAAAANuaWwJAQAAAAppbnNlcnROb2RlAAAAAgUAAAANdm90ZXNMaXN0TmFtZQUAAAALdXNlckFkZHJlc3MJAAUUAAAAAgkABE4AAAACBQAAABB2b3Rlc0xpc3RBY3Rpb25zBQAAAA91c2VyVm90ZUFjdGlvbnMFAAAABHVuaXQJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAKY2FuY2VsVm90ZQAAAAEAAAAHYXNzZXRJZAQAAAALdXNlckFkZHJlc3MJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBAAAAA12b3Rlc0xpc3ROYW1lCQEAAAAQZ2V0Vm90ZXNMaXN0TmFtZQAAAAEFAAAAB2Fzc2V0SWQEAAAAC3VzZXJWb3RlS2V5CQEAAAATa2V5VXNlclZvdGVCeVBlcmlvZAAAAAMFAAAAC3VzZXJBZGRyZXNzBQAAAAdhc3NldElkBQAAAA1jdXJyZW50UGVyaW9kBAAAAA51c2VyVm90ZU9yVW5pdAkABCIAAAABBQAAAAt1c2VyVm90ZUtleQQAAAAJY2hlY2tWb3RlCQEAAAALdmFsdWVPckVsc2UAAAACCQAEIgAAAAEFAAAAC3VzZXJWb3RlS2V5AgAAABFOb3RoaW5nIHRvIGNhbmNlbAMJAAAAAAAAAgUAAAAJY2hlY2tWb3RlBQAAAAljaGVja1ZvdGUEAAAADSR0MDE1MDc0MTUxMzUJAQAAAA1wYXJzZVVzZXJWb3RlAAAAAQkBAAAABXZhbHVlAAAAAQUAAAAOdXNlclZvdGVPclVuaXQEAAAABXRvdGFsCAUAAAANJHQwMTUwNzQxNTEzNQAAAAJfMQQAAAAHaW5GYXZvcggFAAAADSR0MDE1MDc0MTUxMzUAAAACXzIEAAAAEHZvdGVzTGlzdEFjdGlvbnMJAQAAAApkZWxldGVOb2RlAAAAAgUAAAANdm90ZXNMaXN0TmFtZQUAAAALdXNlckFkZHJlc3MEAAAAD3VzZXJWb3RlQWN0aW9ucwkABEwAAAACCQEAAAALRGVsZXRlRW50cnkAAAABBQAAAAt1c2VyVm90ZUtleQkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAASa2V5VXNlclZvdGVIaXN0b3J5AAAABQIAAAAKY2FuY2VsVm90ZQUAAAALdXNlckFkZHJlc3MFAAAAB2Fzc2V0SWQJAAJYAAAAAQgFAAAAAWkAAAANdHJhbnNhY3Rpb25JZAUAAAANY3VycmVudFBlcmlvZAkBAAAADmZvcm1hdFVzZXJWb3RlAAAAAgAAAAAAAAAAAAYJAARMAAAAAgkBAAAAE2dldFZvdGVSZXN1bHRBY3Rpb24AAAAFBQAAAAdhc3NldElkCQEAAAABLQAAAAEFAAAABXRvdGFsBQAAAAdpbkZhdm9yBQAAAA1jdXJyZW50UGVyaW9kBQAAAAR1bml0BQAAAANuaWwJAAUUAAAAAgkABE4AAAACBQAAABB2b3Rlc0xpc3RBY3Rpb25zBQAAAA91c2VyVm90ZUFjdGlvbnMFAAAABHVuaXQJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAAFWZpbmFsaXplQXNzZXRJTlRFUk5BTAAAAAIAAAAHYXNzZXRJZAAAAAZwZXJpb2QEAAAAC2NoZWNrQ2FsbGVyCQEAAAAIdGhpc09ubHkAAAABBQAAAAFpAwkAAAAAAAACBQAAAAtjaGVja0NhbGxlcgUAAAALY2hlY2tDYWxsZXIEAAAADXZvdGVSZXN1bHRLZXkJAQAAABVrZXlWb3RlUmVzdWx0QnlQZXJpb2QAAAACBQAAAAdhc3NldElkBQAAAAZwZXJpb2QEAAAADSR0MDE1Nzk1MTU5NjgEAAAAByRtYXRjaDAJAAQiAAAAAQUAAAANdm90ZVJlc3VsdEtleQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAGU3RyaW5nBAAAAAFzBQAAAAckbWF0Y2gwBAAAAAFyCQEAAAAPcGFyc2VWb3RlUmVzdWx0AAAAAQUAAAABcwkABRQAAAACCAUAAAABcgAAAAJfMQgFAAAAAXIAAAACXzIDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABFVuaXQJAAUUAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAkAAAIAAAABAgAAAAtNYXRjaCBlcnJvcgQAAAAIdG90YWxZZXMIBQAAAA0kdDAxNTc5NTE1OTY4AAAAAl8xBAAAAAd0b3RhbE5vCAUAAAANJHQwMTU3OTUxNTk2OAAAAAJfMgQAAAAFdG90YWwJAABkAAAAAgUAAAAIdG90YWxZZXMFAAAAB3RvdGFsTm8EAAAACHZlcmlmaWVkAwkAAGcAAAACBQAAAAV0b3RhbAUAAAAPdm90aW5nVGhyZXNob2xkCQAAZgAAAAIFAAAACHRvdGFsWWVzBQAAAAd0b3RhbE5vBwQAAAATYXNzZXRWZXJpZmllZEFjdGlvbgkABEwAAAACCQEAAAAMQm9vbGVhbkVudHJ5AAAAAgkBAAAAGGtleUFzc2V0VmVyaWZpZWRCeVBlcmlvZAAAAAIFAAAAB2Fzc2V0SWQFAAAABnBlcmlvZAUAAAAIdmVyaWZpZWQFAAAAA25pbAQAAAAZYXNzZXRzU3RvcmVTZXRWZXJpZmllZEludgkAA/wAAAAEBQAAABNhc3NldHNTdG9yZUNvbnRyYWN0AgAAAAtzZXRWZXJpZmllZAkABEwAAAACBQAAAAdhc3NldElkCQAETAAAAAIFAAAACHZlcmlmaWVkBQAAAANuaWwFAAAAA25pbAMJAAAAAAAAAgUAAAAZYXNzZXRzU3RvcmVTZXRWZXJpZmllZEludgUAAAAZYXNzZXRzU3RvcmVTZXRWZXJpZmllZEludgQAAAAJZWxpbWluYXRlAwUAAAAIdmVyaWZpZWQHCQEAAAAQZWxpbWluYXRpb25DaGVjawAAAAEFAAAAB2Fzc2V0SWQEAAAAEXZvdGVSZXN1bHRBY3Rpb25zAwUAAAAJZWxpbWluYXRlBQAAAANuaWwJAARMAAAAAgkBAAAAE2dldFZvdGVSZXN1bHRBY3Rpb24AAAAFBQAAAAdhc3NldElkAAAAAAAAAAAABgkAAGQAAAACBQAAAA1jdXJyZW50UGVyaW9kAAAAAAAAAAABBQAAAAh2ZXJpZmllZAUAAAADbmlsBAAAABB2b3Rlc0xpc3RBY3Rpb25zAwUAAAAJZWxpbWluYXRlCQEAAAAKZGVsZXRlTm9kZQAAAAIFAAAADmFzc2V0c0xpc3ROYW1lBQAAAAdhc3NldElkBQAAAANuaWwJAAUUAAAAAgkABE4AAAACCQAETgAAAAIFAAAAEHZvdGVzTGlzdEFjdGlvbnMFAAAAEXZvdGVSZXN1bHRBY3Rpb25zBQAAABNhc3NldFZlcmlmaWVkQWN0aW9uBQAAAAR1bml0CQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAUZmluYWxpemVWb3RpbmdIZWxwZXIAAAAABAAAAAllbmRIZWlnaHQJAABkAAAAAgUAAAALc3RhcnRIZWlnaHQFAAAADnZvdGluZ0R1cmF0aW9uAwkAAGYAAAACBQAAAAllbmRIZWlnaHQFAAAABmhlaWdodAkABRQAAAACBQAAAANuaWwHBAAAABpsYXRlc3RQcm9jZXNzZWRBc3NldE9yVW5pdAkABCIAAAABBQAAABdrZXlMYXRlc3RQcm9jZXNzZWRBc3NldAQAAAAZbGF0ZXN0UHJvY2Vzc2VkVXNlck9yVW5pdAkABCIAAAABBQAAABZrZXlMYXRlc3RQcm9jZXNzZWRVc2VyBAAAAA9uZXh0UGVyaW9kRGVsYXkAAAAAAAAAAAAEAAAABmZpbmlzaAkABRQAAAACCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA5rZXlTdGFydEhlaWdodAkAAGQAAAACBQAAAAZoZWlnaHQFAAAAD25leHRQZXJpb2REZWxheQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAQa2V5Q3VycmVudFBlcmlvZAkAAGQAAAACBQAAAA1jdXJyZW50UGVyaW9kAAAAAAAAAAABCQAETAAAAAIJAQAAAAtEZWxldGVFbnRyeQAAAAEFAAAAF2tleUxhdGVzdFByb2Nlc3NlZEFzc2V0CQAETAAAAAIJAQAAAAtEZWxldGVFbnRyeQAAAAEFAAAAFmtleUxhdGVzdFByb2Nlc3NlZFVzZXIJAARMAAAAAgkBAAAAC0RlbGV0ZUVudHJ5AAAAAQUAAAAfa2V5TGF0ZXN0UHJvY2Vzc2VkQXNzZXRUcmFuc2ZlcgkABEwAAAACCQEAAAALRGVsZXRlRW50cnkAAAABBQAAAB5rZXlMYXRlc3RQcm9jZXNzZWRVc2VyVHJhbnNmZXIFAAAAA25pbAYDCQAAAAAAAAIFAAAAGmxhdGVzdFByb2Nlc3NlZEFzc2V0T3JVbml0BQAAAAR1bml0BAAAABBhc3NldHNIZWFkT3JVbml0CQAEIgAAAAEJAQAAAAtrZXlMaXN0SGVhZAAAAAEFAAAADmFzc2V0c0xpc3ROYW1lAwkAAAAAAAACBQAAABBhc3NldHNIZWFkT3JVbml0BQAAAAR1bml0BQAAAAZmaW5pc2gEAAAABWFzc2V0CQEAAAAFdmFsdWUAAAABBQAAABBhc3NldHNIZWFkT3JVbml0BAAAABF1c2VyQWRkcmVzc09yVW5pdAkABCIAAAABCQEAAAALa2V5TGlzdEhlYWQAAAABCQEAAAAQZ2V0Vm90ZXNMaXN0TmFtZQAAAAEFAAAABWFzc2V0BAAAABJwcm9jZXNzVm90ZUFjdGlvbnMJAQAAAAtwcm9jZXNzVm90ZQAAAAQFAAAABWFzc2V0BQAAABF1c2VyQWRkcmVzc09yVW5pdAUAAAAXa2V5TGF0ZXN0UHJvY2Vzc2VkQXNzZXQFAAAAFmtleUxhdGVzdFByb2Nlc3NlZFVzZXIJAAUUAAAAAgUAAAAScHJvY2Vzc1ZvdGVBY3Rpb25zBgQAAAAUbGF0ZXN0UHJvY2Vzc2VkQXNzZXQJAQAAAAV2YWx1ZQAAAAEFAAAAGmxhdGVzdFByb2Nlc3NlZEFzc2V0T3JVbml0AwkAAAAAAAACBQAAABlsYXRlc3RQcm9jZXNzZWRVc2VyT3JVbml0BQAAAAR1bml0BAAAAAthc3NldE9yVW5pdAkABCIAAAABCQEAAAALa2V5TGlzdE5leHQAAAACBQAAAA5hc3NldHNMaXN0TmFtZQUAAAAUbGF0ZXN0UHJvY2Vzc2VkQXNzZXQDCQAAAAAAAAIFAAAAC2Fzc2V0T3JVbml0BQAAAAthc3NldE9yVW5pdAQAAAAQZmluYWxpemVBc3NldEludgkAA/wAAAAEBQAAAAR0aGlzAgAAABVmaW5hbGl6ZUFzc2V0SU5URVJOQUwJAARMAAAAAgUAAAAUbGF0ZXN0UHJvY2Vzc2VkQXNzZXQJAARMAAAAAgUAAAANY3VycmVudFBlcmlvZAUAAAADbmlsBQAAAANuaWwDCQAAAAAAAAIFAAAAEGZpbmFsaXplQXNzZXRJbnYFAAAAEGZpbmFsaXplQXNzZXRJbnYDCQAAAAAAAAIFAAAAC2Fzc2V0T3JVbml0BQAAAAR1bml0BQAAAAZmaW5pc2gEAAAABWFzc2V0CQEAAAAFdmFsdWUAAAABBQAAAAthc3NldE9yVW5pdAQAAAARdXNlckFkZHJlc3NPclVuaXQJAAQiAAAAAQkBAAAAC2tleUxpc3RIZWFkAAAAAQkBAAAAEGdldFZvdGVzTGlzdE5hbWUAAAABBQAAAAVhc3NldAQAAAAScHJvY2Vzc1ZvdGVBY3Rpb25zCQEAAAALcHJvY2Vzc1ZvdGUAAAAEBQAAAAVhc3NldAUAAAARdXNlckFkZHJlc3NPclVuaXQFAAAAF2tleUxhdGVzdFByb2Nlc3NlZEFzc2V0BQAAABZrZXlMYXRlc3RQcm9jZXNzZWRVc2VyCQAFFAAAAAIFAAAAEnByb2Nlc3NWb3RlQWN0aW9ucwYJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgQAAAATbGF0ZXN0UHJvY2Vzc2VkVXNlcgkBAAAABXZhbHVlAAAAAQUAAAAZbGF0ZXN0UHJvY2Vzc2VkVXNlck9yVW5pdAQAAAARdXNlckFkZHJlc3NPclVuaXQJAAQiAAAAAQkBAAAAC2tleUxpc3ROZXh0AAAAAgkBAAAAEGdldFZvdGVzTGlzdE5hbWUAAAABBQAAABRsYXRlc3RQcm9jZXNzZWRBc3NldAUAAAATbGF0ZXN0UHJvY2Vzc2VkVXNlcgQAAAAScHJvY2Vzc1ZvdGVBY3Rpb25zCQEAAAALcHJvY2Vzc1ZvdGUAAAAEBQAAABRsYXRlc3RQcm9jZXNzZWRBc3NldAUAAAARdXNlckFkZHJlc3NPclVuaXQFAAAAF2tleUxhdGVzdFByb2Nlc3NlZEFzc2V0BQAAABZrZXlMYXRlc3RQcm9jZXNzZWRVc2VyCQAFFAAAAAIFAAAAEnByb2Nlc3NWb3RlQWN0aW9ucwYAAAABaQEAAAAVZmluYWxpemVWb3RpbmdXcmFwcGVyAAAAAQAAAAdjb3VudGVyBAAAAAZyZXN1bHQJAQAAAAZhc0Jvb2wAAAABCQAD/AAAAAQFAAAABHRoaXMCAAAAFGZpbmFsaXplVm90aW5nSGVscGVyBQAAAANuaWwFAAAAA25pbAMJAAAAAAAAAgUAAAAGcmVzdWx0BQAAAAZyZXN1bHQDCQEAAAABIQAAAAEFAAAABnJlc3VsdAMJAAAAAAAAAgUAAAAHY291bnRlcgAAAAAAAAAAAAkAAAIAAAABAgAAAB5DdXJyZW50IHZvdGluZyBpcyBub3Qgb3ZlciB5ZXQJAAUUAAAAAgUAAAADbmlsBQAAAAR1bml0AwkAAGYAAAACBQAAAAhtYXhEZXB0aAUAAAAHY291bnRlcgQAAAADaW52CQAD/AAAAAQFAAAABHRoaXMCAAAAFWZpbmFsaXplVm90aW5nV3JhcHBlcgkABEwAAAACCQAAZAAAAAIFAAAAB2NvdW50ZXIAAAAAAAAAAAEFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAAANpbnYFAAAAA2ludgkABRQAAAACBQAAAANuaWwFAAAABHVuaXQJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAFFAAAAAIFAAAAA25pbAUAAAAEdW5pdAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAOZmluYWxpemVWb3RpbmcAAAAABAAAAANpbnYJAAP8AAAABAUAAAAEdGhpcwIAAAAVZmluYWxpemVWb3RpbmdXcmFwcGVyCQAETAAAAAIAAAAAAAAAAAAFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAAANpbnYFAAAAA2ludgkABRQAAAACBQAAAANuaWwFAAAABHVuaXQJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAAE3RyYW5zZmVyVm90ZXNIZWxwZXIAAAAABAAAABh2b3Rlc1RyYW5zZmVyRmluaXNoZWRLZXkJAQAAACBrZXlWb3Rlc1RyYW5zZmVyRmluaXNoZWRCeVBlcmlvZAAAAAEFAAAADWN1cnJlbnRQZXJpb2QEAAAAFXZvdGVzVHJhbnNmZXJGaW5pc2hlZAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABCAAAAABBQAAABh2b3Rlc1RyYW5zZmVyRmluaXNoZWRLZXkHBAAAAAllbmRIZWlnaHQJAABkAAAAAgUAAAALc3RhcnRIZWlnaHQFAAAADnZvdGluZ0R1cmF0aW9uAwMDCQAAZgAAAAIFAAAAC3N0YXJ0SGVpZ2h0BQAAAAZoZWlnaHQGCQAAZwAAAAIFAAAABmhlaWdodAUAAAAJZW5kSGVpZ2h0BgUAAAAVdm90ZXNUcmFuc2ZlckZpbmlzaGVkCQAFFAAAAAIFAAAAA25pbAcEAAAAGmxhdGVzdFByb2Nlc3NlZEFzc2V0T3JVbml0CQAEIgAAAAEFAAAAH2tleUxhdGVzdFByb2Nlc3NlZEFzc2V0VHJhbnNmZXIEAAAAGWxhdGVzdFByb2Nlc3NlZFVzZXJPclVuaXQJAAQiAAAAAQUAAAAea2V5TGF0ZXN0UHJvY2Vzc2VkVXNlclRyYW5zZmVyBAAAAAZmaW5pc2gJAAUUAAAAAgkABEwAAAACCQEAAAAMQm9vbGVhbkVudHJ5AAAAAgUAAAAYdm90ZXNUcmFuc2ZlckZpbmlzaGVkS2V5BgkABEwAAAACCQEAAAALRGVsZXRlRW50cnkAAAABBQAAAB9rZXlMYXRlc3RQcm9jZXNzZWRBc3NldFRyYW5zZmVyCQAETAAAAAIJAQAAAAtEZWxldGVFbnRyeQAAAAEFAAAAHmtleUxhdGVzdFByb2Nlc3NlZFVzZXJUcmFuc2ZlcgUAAAADbmlsBgMJAAAAAAAAAgUAAAAabGF0ZXN0UHJvY2Vzc2VkQXNzZXRPclVuaXQFAAAABHVuaXQEAAAAEGFzc2V0c0hlYWRPclVuaXQJAAQiAAAAAQkBAAAAC2tleUxpc3RIZWFkAAAAAQUAAAAOYXNzZXRzTGlzdE5hbWUDCQAAAAAAAAIFAAAAEGFzc2V0c0hlYWRPclVuaXQFAAAABHVuaXQFAAAABmZpbmlzaAQAAAAFYXNzZXQJAQAAAAV2YWx1ZQAAAAEFAAAAEGFzc2V0c0hlYWRPclVuaXQEAAAAEXVzZXJBZGRyZXNzT3JVbml0CQAEIgAAAAEJAQAAAAtrZXlMaXN0SGVhZAAAAAEJAQAAABBnZXRWb3Rlc0xpc3ROYW1lAAAAAQUAAAAFYXNzZXQEAAAAEnByb2Nlc3NWb3RlQWN0aW9ucwkBAAAAC3Byb2Nlc3NWb3RlAAAABAUAAAAFYXNzZXQFAAAAEXVzZXJBZGRyZXNzT3JVbml0BQAAAB9rZXlMYXRlc3RQcm9jZXNzZWRBc3NldFRyYW5zZmVyBQAAAB5rZXlMYXRlc3RQcm9jZXNzZWRVc2VyVHJhbnNmZXIJAAUUAAAAAgUAAAAScHJvY2Vzc1ZvdGVBY3Rpb25zBgQAAAAUbGF0ZXN0UHJvY2Vzc2VkQXNzZXQJAQAAAAV2YWx1ZQAAAAEFAAAAGmxhdGVzdFByb2Nlc3NlZEFzc2V0T3JVbml0AwkAAAAAAAACBQAAABlsYXRlc3RQcm9jZXNzZWRVc2VyT3JVbml0BQAAAAR1bml0BAAAAAthc3NldE9yVW5pdAkABCIAAAABCQEAAAALa2V5TGlzdE5leHQAAAACBQAAAA5hc3NldHNMaXN0TmFtZQUAAAAUbGF0ZXN0UHJvY2Vzc2VkQXNzZXQDCQAAAAAAAAIFAAAAC2Fzc2V0T3JVbml0BQAAAAR1bml0BQAAAAZmaW5pc2gEAAAABWFzc2V0CQEAAAAFdmFsdWUAAAABBQAAAAthc3NldE9yVW5pdAQAAAARdXNlckFkZHJlc3NPclVuaXQJAAQiAAAAAQkBAAAAC2tleUxpc3RIZWFkAAAAAQkBAAAAEGdldFZvdGVzTGlzdE5hbWUAAAABBQAAAAVhc3NldAQAAAAScHJvY2Vzc1ZvdGVBY3Rpb25zCQEAAAALcHJvY2Vzc1ZvdGUAAAAEBQAAAAVhc3NldAUAAAARdXNlckFkZHJlc3NPclVuaXQFAAAAH2tleUxhdGVzdFByb2Nlc3NlZEFzc2V0VHJhbnNmZXIFAAAAHmtleUxhdGVzdFByb2Nlc3NlZFVzZXJUcmFuc2ZlcgkABRQAAAACBQAAABJwcm9jZXNzVm90ZUFjdGlvbnMGBAAAABNsYXRlc3RQcm9jZXNzZWRVc2VyCQEAAAAFdmFsdWUAAAABBQAAABlsYXRlc3RQcm9jZXNzZWRVc2VyT3JVbml0BAAAABF1c2VyQWRkcmVzc09yVW5pdAkABCIAAAABCQEAAAALa2V5TGlzdE5leHQAAAACCQEAAAAQZ2V0Vm90ZXNMaXN0TmFtZQAAAAEFAAAAFGxhdGVzdFByb2Nlc3NlZEFzc2V0BQAAABNsYXRlc3RQcm9jZXNzZWRVc2VyBAAAABJwcm9jZXNzVm90ZUFjdGlvbnMJAQAAAAtwcm9jZXNzVm90ZQAAAAQFAAAAFGxhdGVzdFByb2Nlc3NlZEFzc2V0BQAAABF1c2VyQWRkcmVzc09yVW5pdAUAAAAfa2V5TGF0ZXN0UHJvY2Vzc2VkQXNzZXRUcmFuc2ZlcgUAAAAea2V5TGF0ZXN0UHJvY2Vzc2VkVXNlclRyYW5zZmVyCQAFFAAAAAIFAAAAEnByb2Nlc3NWb3RlQWN0aW9ucwYAAAABaQEAAAAUdHJhbnNmZXJWb3Rlc1dyYXBwZXIAAAABAAAAB2NvdW50ZXIEAAAABnJlc3VsdAkBAAAABmFzQm9vbAAAAAEJAAP8AAAABAUAAAAEdGhpcwIAAAATdHJhbnNmZXJWb3Rlc0hlbHBlcgUAAAADbmlsBQAAAANuaWwDCQAAAAAAAAIFAAAABnJlc3VsdAUAAAAGcmVzdWx0AwkBAAAAASEAAAABBQAAAAZyZXN1bHQDCQAAAAAAAAIFAAAAB2NvdW50ZXIAAAAAAAAAAAAJAAACAAAAAQIAAAAZVm90aW5nIGlzIG5vdCBzdGFydGVkIHlldAkABRQAAAACBQAAAANuaWwFAAAABHVuaXQDCQAAZgAAAAIFAAAACG1heERlcHRoBQAAAAdjb3VudGVyBAAAAANpbnYJAAP8AAAABAUAAAAEdGhpcwIAAAAUdHJhbnNmZXJWb3Rlc1dyYXBwZXIJAARMAAAAAgkAAGQAAAACBQAAAAdjb3VudGVyAAAAAAAAAAABBQAAAANuaWwFAAAAA25pbAMJAAAAAAAAAgUAAAADaW52BQAAAANpbnYJAAUUAAAAAgUAAAADbmlsBQAAAAR1bml0CQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkABRQAAAACBQAAAANuaWwFAAAABHVuaXQJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAADXRyYW5zZmVyVm90ZXMAAAAABAAAAANpbnYJAAP8AAAABAUAAAAEdGhpcwIAAAAUdHJhbnNmZXJWb3Rlc1dyYXBwZXIJAARMAAAAAgAAAAAAAAAAAAUAAAADbmlsBQAAAANuaWwDCQAAAAAAAAIFAAAAA2ludgUAAAADaW52CQAFFAAAAAIFAAAAA25pbAUAAAAEdW5pdAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAASc2V0Vm90aW5nVGhyZXNob2xkAAAAAQAAAAxuZXdUaHJlc2hvbGQEAAAAC2NoZWNrQ2FsbGVyCQEAAAAIdGhpc09ubHkAAAABBQAAAAFpAwkAAAAAAAACBQAAAAtjaGVja0NhbGxlcgUAAAALY2hlY2tDYWxsZXIJAAUUAAAAAgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAASa2V5Vm90aW5nVGhyZXNob2xkBQAAAAxuZXdUaHJlc2hvbGQFAAAAA25pbAUAAAAEdW5pdAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAGc2V0RmVlAAAAAQAAAAZuZXdGZWUEAAAAC2NoZWNrQ2FsbGVyCQEAAAAIdGhpc09ubHkAAAABBQAAAAFpAwkAAAAAAAACBQAAAAtjaGVja0NhbGxlcgUAAAALY2hlY2tDYWxsZXIJAAUUAAAAAgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAMa2V5RmVlQW1vdW50BQAAAAZuZXdGZWUFAAAAA25pbAUAAAAEdW5pdAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAbZ3d4QXZhaWxhYmxlRm9yVm90ZVJFQURPTkxZAAAAAQAAAAt1c2VyQWRkcmVzcwQAAAAJZW5kSGVpZ2h0CQAAZAAAAAIFAAAAC3N0YXJ0SGVpZ2h0BQAAAA52b3RpbmdEdXJhdGlvbgQAAAAOZ3d4QW1vdW50QXRFbmQJAQAAABhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQAAAACBQAAAAt1c2VyQWRkcmVzcwUAAAAJZW5kSGVpZ2h0CQAFFAAAAAIFAAAAA25pbAUAAAAOZ3d4QW1vdW50QXRFbmQAAAAATVgICw==", "height": 1983460, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 9vUSWcpSF7614QcjHSJnyULRdbCjekxd2Fd8yqYPrGzV Next: AbEihX2FzJ5ZujcZNiAzjfTEfuPvx9BxVCAvwbgZkArn Diff:
OldNewDifferences
7777 func keyVoteResultByPeriod (assetId,period) = makeString(["%s%d%s", "votingResultAtAsset", toString(period), assetId], separator)
7878
7979
80-func formatVoteResult (totalYes,totalNo) = makeString(["%d%d", toString(totalYes), toString(totalNo)], separator)
80+func formatVoteResult (totalYes,totalNo,verified) = makeString(["%d%d%s", toString(totalYes), toString(totalNo), toString(verified)], separator)
8181
8282
8383 func parseVoteResult (input) = {
8484 let parts = split(input, separator)
8585 let totalYesIdx = 1
8686 let totalNoIdx = 2
87+ let verifiedIdx = 3
8788 let totalYes = parseIntValue(parts[totalYesIdx])
8889 let totalNo = parseIntValue(parts[totalNoIdx])
89- $Tuple2(totalYes, totalNo)
90+ let verified = if ((size(parts) == 3))
91+ then (parts[verifiedIdx] == "true")
92+ else false
93+ $Tuple3(totalYes, totalNo, verified)
9094 }
9195
9296
180184 }
181185
182186
183-func getVoteResultAction (assetId,total,inFavor,period) = {
187+func getVoteResultAction (assetId,total,inFavor,period,verified) = {
184188 let voteResultKey = keyVoteResultByPeriod(assetId, period)
185- let $t054515583 = match getString(voteResultKey) {
189+ let $t056885991 = match getString(voteResultKey) {
186190 case s: String =>
187191 parseVoteResult(s)
188192 case _: Unit =>
189- $Tuple2(0, 0)
193+ match getString(keyVoteResultByPeriod(assetId, (period - 1))) {
194+ case s: String =>
195+ $Tuple3(0, 0, parseVoteResult(s)._3)
196+ case _: Unit =>
197+ $Tuple3(0, 0, false)
198+ case _ =>
199+ throw("Match error")
200+ }
190201 case _ =>
191202 throw("Match error")
192203 }
193- let totalYes = $t054515583._1
194- let totalNo = $t054515583._2
195- StringEntry(voteResultKey, formatVoteResult((totalYes + (if (inFavor)
204+ let oldTotalYes = $t056885991._1
205+ let oldTotalNo = $t056885991._2
206+ let oldVerified = $t056885991._3
207+ StringEntry(voteResultKey, formatVoteResult((oldTotalYes + (if (inFavor)
196208 then total
197- else 0)), (totalNo + (if (inFavor)
209+ else 0)), (oldTotalNo + (if (inFavor)
198210 then 0
199- else total))))
211+ else total)), if ((verified == unit))
212+ then oldVerified
213+ else value(verified)))
200214 }
201215
202216
268282 if ((userPreviousVoteOrUnit == unit))
269283 then nil
270284 else {
271- let $t093859458 = parseUserVote(value(userPreviousVoteOrUnit))
272- let prevTotal = $t093859458._1
273- let inFavor = $t093859458._2
285+ let $t098859958 = parseUserVote(value(userPreviousVoteOrUnit))
286+ let prevTotal = $t098859958._1
287+ let inFavor = $t098859958._2
274288 let total = min([prevTotal, userGwxAmountAtEndHeight])
275-[StringEntry(userVoteKey, formatUserVote(total, inFavor)), getVoteResultAction(assetId, total, inFavor, currentPeriod)]
289+[StringEntry(userVoteKey, formatUserVote(total, inFavor)), getVoteResultAction(assetId, total, inFavor, currentPeriod, unit)]
276290 }
277291 }
278292 else nil
337351 if ((burnFeeInv == burnFeeInv))
338352 then {
339353 let addAssetActions = insertNode(assetsListName, assetId)
340- $Tuple2((addAssetActions :+ getVoteResultAction(assetId, 0, true, currentPeriod)), unit)
354+ $Tuple2((addAssetActions :+ getVoteResultAction(assetId, 0, true, currentPeriod, false)), unit)
341355 }
342356 else throw("Strict value is not equal to itself.")
343357 }
370384 then {
371385 let votesListName = getVotesListName(assetId)
372386 let userVoteKey = keyUserVoteByPeriod(userAddress, assetId, currentPeriod)
373- let userVoteActions = [StringEntry(userVoteKey, formatUserVote(gwxAmountAtEnd, inFavor)), StringEntry(keyUserVoteHistory("vote", userAddress, assetId, toBase58String(i.transactionId), currentPeriod), formatUserVote(gwxAmountAtEnd, inFavor)), getVoteResultAction(assetId, gwxAmountAtEnd, inFavor, currentPeriod)]
387+ let userVoteActions = [StringEntry(userVoteKey, formatUserVote(gwxAmountAtEnd, inFavor)), StringEntry(keyUserVoteHistory("vote", userAddress, assetId, toBase58String(i.transactionId), currentPeriod), formatUserVote(gwxAmountAtEnd, inFavor)), getVoteResultAction(assetId, gwxAmountAtEnd, inFavor, currentPeriod, unit)]
374388 let votesListActions = if (containsNode(votesListName, userAddress))
375389 then nil
376390 else insertNode(votesListName, userAddress)
394408 let checkVote = valueOrElse(getString(userVoteKey), "Nothing to cancel")
395409 if ((checkVote == checkVote))
396410 then {
397- let $t01455514616 = parseUserVote(value(userVoteOrUnit))
398- let total = $t01455514616._1
399- let inFavor = $t01455514616._2
411+ let $t01507415135 = parseUserVote(value(userVoteOrUnit))
412+ let total = $t01507415135._1
413+ let inFavor = $t01507415135._2
400414 let votesListActions = deleteNode(votesListName, userAddress)
401- let userVoteActions = [DeleteEntry(userVoteKey), StringEntry(keyUserVoteHistory("cancelVote", userAddress, assetId, toBase58String(i.transactionId), currentPeriod), formatUserVote(0, true)), getVoteResultAction(assetId, -(total), inFavor, currentPeriod)]
415+ let userVoteActions = [DeleteEntry(userVoteKey), StringEntry(keyUserVoteHistory("cancelVote", userAddress, assetId, toBase58String(i.transactionId), currentPeriod), formatUserVote(0, true)), getVoteResultAction(assetId, -(total), inFavor, currentPeriod, unit)]
402416 $Tuple2((votesListActions ++ userVoteActions), unit)
403417 }
404418 else throw("Strict value is not equal to itself.")
412426 if ((checkCaller == checkCaller))
413427 then {
414428 let voteResultKey = keyVoteResultByPeriod(assetId, period)
415- let $t01527015402 = match getString(voteResultKey) {
429+ let $t01579515968 = match getString(voteResultKey) {
416430 case s: String =>
417- parseVoteResult(s)
431+ let r = parseVoteResult(s)
432+ $Tuple2(r._1, r._2)
418433 case _: Unit =>
419434 $Tuple2(0, 0)
420435 case _ =>
421436 throw("Match error")
422437 }
423- let totalYes = $t01527015402._1
424- let totalNo = $t01527015402._2
438+ let totalYes = $t01579515968._1
439+ let totalNo = $t01579515968._2
425440 let total = (totalYes + totalNo)
426441 let verified = if ((total >= votingThreshold))
427442 then (totalYes > totalNo)
435450 else eliminationCheck(assetId)
436451 let voteResultActions = if (eliminate)
437452 then nil
438- else [getVoteResultAction(assetId, 0, true, (currentPeriod + 1))]
453+ else [getVoteResultAction(assetId, 0, true, (currentPeriod + 1), verified)]
439454 let votesListActions = if (eliminate)
440455 then deleteNode(assetsListName, assetId)
441456 else nil
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let separator = "__"
55
66 let maxDepthDefault = 10
77
88 func asInt (val) = match val {
99 case valInt: Int =>
1010 valInt
1111 case _ =>
1212 throw("Failed to cast into Integer")
1313 }
1414
1515
1616 func asBool (val) = match val {
1717 case valBool: Boolean =>
1818 valBool
1919 case _ =>
2020 throw("Failed to cast into Boolean")
2121 }
2222
2323
2424 let keyFeeAmount = makeString(["%s", "fee"], separator)
2525
2626 let keyWxAssetId = makeString(["%s", "wxAssetId"], separator)
2727
2828 let keyVotingThreshold = makeString(["%s", "votingThreshold"], separator)
2929
3030 let keyVotingDuration = makeString(["%s", "epochLength"], separator)
3131
3232 let keyVoteBeforeElimination = makeString(["%s", "voteBeforeElimination"], separator)
3333
3434 let keyStartHeight = makeString(["%s", "currentVotingHeightStart"], separator)
3535
3636 let keyCurrentPeriod = makeString(["%s", "currentEpoch"], separator)
3737
3838 let keyBoostingContract = makeString(["%s", "boostingContract"], separator)
3939
4040 let keyEmissionContract = makeString(["%s", "emissionContract"], separator)
4141
4242 let keyAssetsStoreContract = makeString(["%s", "assetsStoreContract"], separator)
4343
4444 let keyLatestProcessedAsset = makeString(["%s", "latestProcessedAsset"], separator)
4545
4646 let keyLatestProcessedUser = makeString(["%s", "latestProcessedUser"], separator)
4747
4848 let keyLatestProcessedAssetTransfer = makeString(["%s", "latestProcessedAssetTransfer"], separator)
4949
5050 let keyLatestProcessedUserTransfer = makeString(["%s", "latestProcessedUserTransfer"], separator)
5151
5252 let keyMaxDepth = makeString(["%s", "maxDepth"], separator)
5353
5454 func keyVotesTransferFinishedByPeriod (period) = makeString(["%s", "votesTransferFinished", toString(period)], separator)
5555
5656
5757 let assetsListName = "__assets"
5858
5959 func getVotesListName (assetId) = ("%s__votes__" + assetId)
6060
6161
6262 func keyListHead (listName) = makeString([("%s%s" + listName), "head"], separator)
6363
6464
6565 func keyListSize (listName) = makeString([("%s%s" + listName), "size"], separator)
6666
6767
6868 func keyListPrev (listName,id) = makeString([("%s%s%s" + listName), id, "prev"], separator)
6969
7070
7171 func keyListNext (listName,id) = makeString([("%s%s%s" + listName), id, "next"], separator)
7272
7373
7474 func keyAssetVerifiedByPeriod (assetId,period) = makeString(["%s%d%s", "verifiedAt", toString(period), assetId], separator)
7575
7676
7777 func keyVoteResultByPeriod (assetId,period) = makeString(["%s%d%s", "votingResultAtAsset", toString(period), assetId], separator)
7878
7979
80-func formatVoteResult (totalYes,totalNo) = makeString(["%d%d", toString(totalYes), toString(totalNo)], separator)
80+func formatVoteResult (totalYes,totalNo,verified) = makeString(["%d%d%s", toString(totalYes), toString(totalNo), toString(verified)], separator)
8181
8282
8383 func parseVoteResult (input) = {
8484 let parts = split(input, separator)
8585 let totalYesIdx = 1
8686 let totalNoIdx = 2
87+ let verifiedIdx = 3
8788 let totalYes = parseIntValue(parts[totalYesIdx])
8889 let totalNo = parseIntValue(parts[totalNoIdx])
89- $Tuple2(totalYes, totalNo)
90+ let verified = if ((size(parts) == 3))
91+ then (parts[verifiedIdx] == "true")
92+ else false
93+ $Tuple3(totalYes, totalNo, verified)
9094 }
9195
9296
9397 func keyUserVoteByPeriod (userAddress,assetId,period) = makeString(["%s%d%s%s", "vru", toString(period), assetId, userAddress], separator)
9498
9599
96100 func formatUserVote (total,inFavor) = {
97101 let totalYes = if (inFavor)
98102 then total
99103 else 0
100104 let totalNo = if (inFavor)
101105 then 0
102106 else total
103107 makeString(["%d%d", toString(totalYes), toString(totalNo)], separator)
104108 }
105109
106110
107111 func parseUserVote (input) = {
108112 let parts = split(input, separator)
109113 let totalYesIdx = 1
110114 let totalNoIdx = 2
111115 let totalYes = parseIntValue(parts[totalYesIdx])
112116 let totalNo = parseIntValue(parts[totalNoIdx])
113117 let inFavor = if ((totalYes > 0))
114118 then (totalNo == 0)
115119 else false
116120 let against = if ((totalYes == 0))
117121 then (totalNo > 0)
118122 else false
119123 let checkTotals = if (if (inFavor)
120124 then true
121125 else against)
122126 then true
123127 else throw("Invalid user vote value")
124128 if ((checkTotals == checkTotals))
125129 then {
126130 let total = if (inFavor)
127131 then totalYes
128132 else totalNo
129133 $Tuple2(total, inFavor)
130134 }
131135 else throw("Strict value is not equal to itself.")
132136 }
133137
134138
135139 func keyUserVoteHistory (type,userAddress,assetId,txId,period) = makeString(["%s%s%s%s%s%d", "history", type, assetId, userAddress, txId, toString(period)], separator)
136140
137141
138142 func thisOnly (i) = if ((i.caller == this))
139143 then true
140144 else throw("Permission denied")
141145
142146
143147 func getIntegerOrZero (key) = valueOrElse(getInteger(this, key), 0)
144148
145149
146150 func getIntegerOrFail (key) = valueOrErrorMessage(getInteger(this, key), (key + " is not defined"))
147151
148152
149153 func getStringOrEmpty (key) = valueOrElse(getString(this, key), "")
150154
151155
152156 func getStringOrFail (key) = valueOrErrorMessage(getString(this, key), (key + " is not defined"))
153157
154158
155159 let feeAmount = getIntegerOrFail(keyFeeAmount)
156160
157161 let wxAssetId = fromBase58String(getStringOrFail(keyWxAssetId))
158162
159163 let votingThreshold = getIntegerOrFail(keyVotingThreshold)
160164
161165 let votingDuration = getIntegerOrFail(keyVotingDuration)
162166
163167 let voteBeforeElimination = getIntegerOrFail(keyVoteBeforeElimination)
164168
165169 let startHeight = getIntegerOrFail(keyStartHeight)
166170
167171 let currentPeriod = getIntegerOrFail(keyCurrentPeriod)
168172
169173 let boostingContract = addressFromStringValue(getStringOrFail(keyBoostingContract))
170174
171175 let emissionContract = addressFromStringValue(getStringOrFail(keyEmissionContract))
172176
173177 let assetsStoreContract = addressFromStringValue(getStringOrFail(keyAssetsStoreContract))
174178
175179 let maxDepth = valueOrElse(getInteger(keyMaxDepth), maxDepthDefault)
176180
177181 func getUserGwxAmountAtHeight (userAddress,targetHeight) = {
178182 let gwxAmount = invoke(boostingContract, "getUserGwxAmountAtHeightREADONLY", [userAddress, targetHeight], nil)
179183 asInt(gwxAmount)
180184 }
181185
182186
183-func getVoteResultAction (assetId,total,inFavor,period) = {
187+func getVoteResultAction (assetId,total,inFavor,period,verified) = {
184188 let voteResultKey = keyVoteResultByPeriod(assetId, period)
185- let $t054515583 = match getString(voteResultKey) {
189+ let $t056885991 = match getString(voteResultKey) {
186190 case s: String =>
187191 parseVoteResult(s)
188192 case _: Unit =>
189- $Tuple2(0, 0)
193+ match getString(keyVoteResultByPeriod(assetId, (period - 1))) {
194+ case s: String =>
195+ $Tuple3(0, 0, parseVoteResult(s)._3)
196+ case _: Unit =>
197+ $Tuple3(0, 0, false)
198+ case _ =>
199+ throw("Match error")
200+ }
190201 case _ =>
191202 throw("Match error")
192203 }
193- let totalYes = $t054515583._1
194- let totalNo = $t054515583._2
195- StringEntry(voteResultKey, formatVoteResult((totalYes + (if (inFavor)
204+ let oldTotalYes = $t056885991._1
205+ let oldTotalNo = $t056885991._2
206+ let oldVerified = $t056885991._3
207+ StringEntry(voteResultKey, formatVoteResult((oldTotalYes + (if (inFavor)
196208 then total
197- else 0)), (totalNo + (if (inFavor)
209+ else 0)), (oldTotalNo + (if (inFavor)
198210 then 0
199- else total))))
211+ else total)), if ((verified == unit))
212+ then oldVerified
213+ else value(verified)))
200214 }
201215
202216
203217 func containsNode (listName,id) = {
204218 let head = getString(this, keyListHead(listName))
205219 let prev = getString(this, keyListPrev(listName, id))
206220 let next = getString(this, keyListNext(listName, id))
207221 if (if ((id == head))
208222 then true
209223 else (prev != unit))
210224 then true
211225 else (next != unit)
212226 }
213227
214228
215229 func insertNode (listName,id) = {
216230 let head = getString(this, keyListHead(listName))
217231 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
218232 let checkNode = if (!(containsNode(listName, id)))
219233 then true
220234 else throw("Node exists")
221235 if ((checkNode == checkNode))
222236 then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if (isDefined(head))
223237 then [StringEntry(keyListNext(listName, id), value(head)), StringEntry(keyListPrev(listName, value(head)), id)]
224238 else nil)) ++ [StringEntry(keyListHead(listName), id)])
225239 else throw("Strict value is not equal to itself.")
226240 }
227241
228242
229243 func deleteNode (listName,id) = {
230244 let head = getString(this, keyListHead(listName))
231245 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
232246 let prev = getString(this, keyListPrev(listName, id))
233247 let next = getString(this, keyListNext(listName, id))
234248 ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if (isDefined(prev))
235249 then isDefined(next)
236250 else false)
237251 then [StringEntry(keyListNext(listName, value(prev)), value(next)), StringEntry(keyListPrev(listName, value(next)), value(prev)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))]
238252 else if (isDefined(next))
239253 then [StringEntry(keyListHead(listName), value(next)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(next)))]
240254 else if (isDefined(prev))
241255 then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prev)))]
242256 else if ((id == head))
243257 then [DeleteEntry(keyListHead(listName))]
244258 else throw("Invalid node")))
245259 }
246260
247261
248262 func processVote (assetId,userAddressOrUnit,latestProcessedAssetKey,latestProcessedUserKey) = {
249263 let updateLatestProcessedAssetAction = StringEntry(latestProcessedAssetKey, assetId)
250264 let deleteLatestProcessedUserAction = DeleteEntry(latestProcessedUserKey)
251265 if ((userAddressOrUnit == unit))
252266 then [updateLatestProcessedAssetAction, deleteLatestProcessedUserAction]
253267 else {
254268 let endHeight = (startHeight + votingDuration)
255269 let userAddress = value(userAddressOrUnit)
256270 let updateLatestProcessedUserAction = StringEntry(latestProcessedUserKey, userAddress)
257271 let userVoteKey = keyUserVoteByPeriod(userAddress, assetId, currentPeriod)
258272 let userVoteOrUnit = getString(userVoteKey)
259273 let userGwxAmountAtEndHeight = getUserGwxAmountAtHeight(userAddress, endHeight)
260274 let voteActions = if ((userGwxAmountAtEndHeight == 0))
261275 then {
262276 let votesListName = getVotesListName(assetId)
263277 deleteNode(votesListName, userAddress)
264278 }
265279 else if ((userVoteOrUnit == unit))
266280 then {
267281 let userPreviousVoteOrUnit = getString(keyUserVoteByPeriod(userAddress, assetId, (currentPeriod - 1)))
268282 if ((userPreviousVoteOrUnit == unit))
269283 then nil
270284 else {
271- let $t093859458 = parseUserVote(value(userPreviousVoteOrUnit))
272- let prevTotal = $t093859458._1
273- let inFavor = $t093859458._2
285+ let $t098859958 = parseUserVote(value(userPreviousVoteOrUnit))
286+ let prevTotal = $t098859958._1
287+ let inFavor = $t098859958._2
274288 let total = min([prevTotal, userGwxAmountAtEndHeight])
275-[StringEntry(userVoteKey, formatUserVote(total, inFavor)), getVoteResultAction(assetId, total, inFavor, currentPeriod)]
289+[StringEntry(userVoteKey, formatUserVote(total, inFavor)), getVoteResultAction(assetId, total, inFavor, currentPeriod, unit)]
276290 }
277291 }
278292 else nil
279293 ((voteActions :+ updateLatestProcessedAssetAction) :+ updateLatestProcessedUserAction)
280294 }
281295 }
282296
283297
284298 func assetShouldBeEliminated (assetId,period) = !(valueOrElse(getBoolean(keyAssetVerifiedByPeriod(assetId, period)), true))
285299
286300
287301 func eliminationCheck (assetId) = if (if (assetShouldBeEliminated(assetId, (currentPeriod - 1)))
288302 then assetShouldBeEliminated(assetId, (currentPeriod - 2))
289303 else false)
290304 then assetShouldBeEliminated(assetId, (currentPeriod - 3))
291305 else false
292306
293307
294308 @Callable(i)
295309 func constructor (boostingContractPrm,emissionContractPrm,assetsStoreContractPrm,feeAmountPrm,wxAssetIdPrm,votingThresholdPrm,votingDurationPrm,voteBeforeEliminationPrm,startHeightPrm,maxDepthPrm) = {
296310 let checks = [thisOnly(i), if (isDefined(addressFromString(boostingContractPrm)))
297311 then true
298312 else throw("Invalid boosting contract address"), if (isDefined(addressFromString(emissionContractPrm)))
299313 then true
300314 else throw("Invalid emission contract address"), if (isDefined(addressFromString(assetsStoreContractPrm)))
301315 then true
302316 else throw("Invalid asset_store contract address"), if ((feeAmountPrm >= 0))
303317 then true
304318 else throw("Invalid fee amount"), if (isDefined(assetInfo(fromBase58String(wxAssetIdPrm))))
305319 then true
306320 else throw("Invalid WX asset ID"), if ((votingThresholdPrm >= 0))
307321 then true
308322 else throw("Invalid voting threshold"), if ((votingDurationPrm > 0))
309323 then true
310324 else throw("Invalid voting duration"), if (((startHeightPrm + votingDurationPrm) > height))
311325 then true
312326 else throw("Invalid start height")]
313327 if ((checks == checks))
314328 then $Tuple2([StringEntry(keyBoostingContract, boostingContractPrm), StringEntry(keyEmissionContract, emissionContractPrm), StringEntry(keyAssetsStoreContract, assetsStoreContractPrm), IntegerEntry(keyFeeAmount, feeAmountPrm), StringEntry(keyWxAssetId, wxAssetIdPrm), IntegerEntry(keyVotingThreshold, votingThresholdPrm), IntegerEntry(keyVotingDuration, votingDurationPrm), IntegerEntry(keyVoteBeforeElimination, voteBeforeEliminationPrm), IntegerEntry(keyStartHeight, startHeightPrm), IntegerEntry(keyCurrentPeriod, 0), IntegerEntry(keyMaxDepth, maxDepthPrm)], unit)
315329 else throw("Strict value is not equal to itself.")
316330 }
317331
318332
319333
320334 @Callable(i)
321335 func suggest (assetId,assetImage) = {
322336 let info = valueOrErrorMessage(assetInfo(fromBase58String(assetId)), "Invalid asset ID")
323337 let payment = value(i.payments[0])
324338 let checks = [if ((info.issuer == i.caller))
325339 then true
326340 else throw("Asset can only be suggested by its issuer"), if ((value(payment.assetId) == wxAssetId))
327341 then true
328342 else throw("Invalid fee asset"), if ((payment.amount == feeAmount))
329343 then true
330344 else throw("Invalid fee amount")]
331345 if ((checks == checks))
332346 then {
333347 let assetsStoreCreateOrUpdateInv = invoke(assetsStoreContract, "createOrUpdate", [assetId, "", assetImage, false], nil)
334348 if ((assetsStoreCreateOrUpdateInv == assetsStoreCreateOrUpdateInv))
335349 then {
336350 let burnFeeInv = invoke(emissionContract, "burn", nil, [AttachedPayment(payment.assetId, payment.amount)])
337351 if ((burnFeeInv == burnFeeInv))
338352 then {
339353 let addAssetActions = insertNode(assetsListName, assetId)
340- $Tuple2((addAssetActions :+ getVoteResultAction(assetId, 0, true, currentPeriod)), unit)
354+ $Tuple2((addAssetActions :+ getVoteResultAction(assetId, 0, true, currentPeriod, false)), unit)
341355 }
342356 else throw("Strict value is not equal to itself.")
343357 }
344358 else throw("Strict value is not equal to itself.")
345359 }
346360 else throw("Strict value is not equal to itself.")
347361 }
348362
349363
350364
351365 @Callable(i)
352366 func vote (assetId,inFavor) = {
353367 let endHeight = (startHeight + votingDuration)
354368 let checkAsset = if (containsNode(assetsListName, assetId))
355369 then true
356370 else throw("Invalid asset")
357371 if ((checkAsset == checkAsset))
358372 then {
359373 let checkHeight = if ((endHeight > height))
360374 then true
361375 else throw("Current voting is over but results are not finalized")
362376 if ((checkHeight == checkHeight))
363377 then {
364378 let userAddress = toString(i.caller)
365379 let gwxAmountAtEnd = getUserGwxAmountAtHeight(userAddress, endHeight)
366380 let checkGwxAmountAtEnd = if ((gwxAmountAtEnd > 0))
367381 then true
368382 else throw("You'll not have gWX at the end of voting")
369383 if ((checkGwxAmountAtEnd == checkGwxAmountAtEnd))
370384 then {
371385 let votesListName = getVotesListName(assetId)
372386 let userVoteKey = keyUserVoteByPeriod(userAddress, assetId, currentPeriod)
373- let userVoteActions = [StringEntry(userVoteKey, formatUserVote(gwxAmountAtEnd, inFavor)), StringEntry(keyUserVoteHistory("vote", userAddress, assetId, toBase58String(i.transactionId), currentPeriod), formatUserVote(gwxAmountAtEnd, inFavor)), getVoteResultAction(assetId, gwxAmountAtEnd, inFavor, currentPeriod)]
387+ let userVoteActions = [StringEntry(userVoteKey, formatUserVote(gwxAmountAtEnd, inFavor)), StringEntry(keyUserVoteHistory("vote", userAddress, assetId, toBase58String(i.transactionId), currentPeriod), formatUserVote(gwxAmountAtEnd, inFavor)), getVoteResultAction(assetId, gwxAmountAtEnd, inFavor, currentPeriod, unit)]
374388 let votesListActions = if (containsNode(votesListName, userAddress))
375389 then nil
376390 else insertNode(votesListName, userAddress)
377391 $Tuple2((votesListActions ++ userVoteActions), unit)
378392 }
379393 else throw("Strict value is not equal to itself.")
380394 }
381395 else throw("Strict value is not equal to itself.")
382396 }
383397 else throw("Strict value is not equal to itself.")
384398 }
385399
386400
387401
388402 @Callable(i)
389403 func cancelVote (assetId) = {
390404 let userAddress = toString(i.caller)
391405 let votesListName = getVotesListName(assetId)
392406 let userVoteKey = keyUserVoteByPeriod(userAddress, assetId, currentPeriod)
393407 let userVoteOrUnit = getString(userVoteKey)
394408 let checkVote = valueOrElse(getString(userVoteKey), "Nothing to cancel")
395409 if ((checkVote == checkVote))
396410 then {
397- let $t01455514616 = parseUserVote(value(userVoteOrUnit))
398- let total = $t01455514616._1
399- let inFavor = $t01455514616._2
411+ let $t01507415135 = parseUserVote(value(userVoteOrUnit))
412+ let total = $t01507415135._1
413+ let inFavor = $t01507415135._2
400414 let votesListActions = deleteNode(votesListName, userAddress)
401- let userVoteActions = [DeleteEntry(userVoteKey), StringEntry(keyUserVoteHistory("cancelVote", userAddress, assetId, toBase58String(i.transactionId), currentPeriod), formatUserVote(0, true)), getVoteResultAction(assetId, -(total), inFavor, currentPeriod)]
415+ let userVoteActions = [DeleteEntry(userVoteKey), StringEntry(keyUserVoteHistory("cancelVote", userAddress, assetId, toBase58String(i.transactionId), currentPeriod), formatUserVote(0, true)), getVoteResultAction(assetId, -(total), inFavor, currentPeriod, unit)]
402416 $Tuple2((votesListActions ++ userVoteActions), unit)
403417 }
404418 else throw("Strict value is not equal to itself.")
405419 }
406420
407421
408422
409423 @Callable(i)
410424 func finalizeAssetINTERNAL (assetId,period) = {
411425 let checkCaller = thisOnly(i)
412426 if ((checkCaller == checkCaller))
413427 then {
414428 let voteResultKey = keyVoteResultByPeriod(assetId, period)
415- let $t01527015402 = match getString(voteResultKey) {
429+ let $t01579515968 = match getString(voteResultKey) {
416430 case s: String =>
417- parseVoteResult(s)
431+ let r = parseVoteResult(s)
432+ $Tuple2(r._1, r._2)
418433 case _: Unit =>
419434 $Tuple2(0, 0)
420435 case _ =>
421436 throw("Match error")
422437 }
423- let totalYes = $t01527015402._1
424- let totalNo = $t01527015402._2
438+ let totalYes = $t01579515968._1
439+ let totalNo = $t01579515968._2
425440 let total = (totalYes + totalNo)
426441 let verified = if ((total >= votingThreshold))
427442 then (totalYes > totalNo)
428443 else false
429444 let assetVerifiedAction = [BooleanEntry(keyAssetVerifiedByPeriod(assetId, period), verified)]
430445 let assetsStoreSetVerifiedInv = invoke(assetsStoreContract, "setVerified", [assetId, verified], nil)
431446 if ((assetsStoreSetVerifiedInv == assetsStoreSetVerifiedInv))
432447 then {
433448 let eliminate = if (verified)
434449 then false
435450 else eliminationCheck(assetId)
436451 let voteResultActions = if (eliminate)
437452 then nil
438- else [getVoteResultAction(assetId, 0, true, (currentPeriod + 1))]
453+ else [getVoteResultAction(assetId, 0, true, (currentPeriod + 1), verified)]
439454 let votesListActions = if (eliminate)
440455 then deleteNode(assetsListName, assetId)
441456 else nil
442457 $Tuple2(((votesListActions ++ voteResultActions) ++ assetVerifiedAction), unit)
443458 }
444459 else throw("Strict value is not equal to itself.")
445460 }
446461 else throw("Strict value is not equal to itself.")
447462 }
448463
449464
450465
451466 @Callable(i)
452467 func finalizeVotingHelper () = {
453468 let endHeight = (startHeight + votingDuration)
454469 if ((endHeight > height))
455470 then $Tuple2(nil, false)
456471 else {
457472 let latestProcessedAssetOrUnit = getString(keyLatestProcessedAsset)
458473 let latestProcessedUserOrUnit = getString(keyLatestProcessedUser)
459474 let nextPeriodDelay = 0
460475 let finish = $Tuple2([IntegerEntry(keyStartHeight, (height + nextPeriodDelay)), IntegerEntry(keyCurrentPeriod, (currentPeriod + 1)), DeleteEntry(keyLatestProcessedAsset), DeleteEntry(keyLatestProcessedUser), DeleteEntry(keyLatestProcessedAssetTransfer), DeleteEntry(keyLatestProcessedUserTransfer)], true)
461476 if ((latestProcessedAssetOrUnit == unit))
462477 then {
463478 let assetsHeadOrUnit = getString(keyListHead(assetsListName))
464479 if ((assetsHeadOrUnit == unit))
465480 then finish
466481 else {
467482 let asset = value(assetsHeadOrUnit)
468483 let userAddressOrUnit = getString(keyListHead(getVotesListName(asset)))
469484 let processVoteActions = processVote(asset, userAddressOrUnit, keyLatestProcessedAsset, keyLatestProcessedUser)
470485 $Tuple2(processVoteActions, true)
471486 }
472487 }
473488 else {
474489 let latestProcessedAsset = value(latestProcessedAssetOrUnit)
475490 if ((latestProcessedUserOrUnit == unit))
476491 then {
477492 let assetOrUnit = getString(keyListNext(assetsListName, latestProcessedAsset))
478493 if ((assetOrUnit == assetOrUnit))
479494 then {
480495 let finalizeAssetInv = invoke(this, "finalizeAssetINTERNAL", [latestProcessedAsset, currentPeriod], nil)
481496 if ((finalizeAssetInv == finalizeAssetInv))
482497 then if ((assetOrUnit == unit))
483498 then finish
484499 else {
485500 let asset = value(assetOrUnit)
486501 let userAddressOrUnit = getString(keyListHead(getVotesListName(asset)))
487502 let processVoteActions = processVote(asset, userAddressOrUnit, keyLatestProcessedAsset, keyLatestProcessedUser)
488503 $Tuple2(processVoteActions, true)
489504 }
490505 else throw("Strict value is not equal to itself.")
491506 }
492507 else throw("Strict value is not equal to itself.")
493508 }
494509 else {
495510 let latestProcessedUser = value(latestProcessedUserOrUnit)
496511 let userAddressOrUnit = getString(keyListNext(getVotesListName(latestProcessedAsset), latestProcessedUser))
497512 let processVoteActions = processVote(latestProcessedAsset, userAddressOrUnit, keyLatestProcessedAsset, keyLatestProcessedUser)
498513 $Tuple2(processVoteActions, true)
499514 }
500515 }
501516 }
502517 }
503518
504519
505520
506521 @Callable(i)
507522 func finalizeVotingWrapper (counter) = {
508523 let result = asBool(invoke(this, "finalizeVotingHelper", nil, nil))
509524 if ((result == result))
510525 then if (!(result))
511526 then if ((counter == 0))
512527 then throw("Current voting is not over yet")
513528 else $Tuple2(nil, unit)
514529 else if ((maxDepth > counter))
515530 then {
516531 let inv = invoke(this, "finalizeVotingWrapper", [(counter + 1)], nil)
517532 if ((inv == inv))
518533 then $Tuple2(nil, unit)
519534 else throw("Strict value is not equal to itself.")
520535 }
521536 else $Tuple2(nil, unit)
522537 else throw("Strict value is not equal to itself.")
523538 }
524539
525540
526541
527542 @Callable(i)
528543 func finalizeVoting () = {
529544 let inv = invoke(this, "finalizeVotingWrapper", [0], nil)
530545 if ((inv == inv))
531546 then $Tuple2(nil, unit)
532547 else throw("Strict value is not equal to itself.")
533548 }
534549
535550
536551
537552 @Callable(i)
538553 func transferVotesHelper () = {
539554 let votesTransferFinishedKey = keyVotesTransferFinishedByPeriod(currentPeriod)
540555 let votesTransferFinished = valueOrElse(getBoolean(votesTransferFinishedKey), false)
541556 let endHeight = (startHeight + votingDuration)
542557 if (if (if ((startHeight > height))
543558 then true
544559 else (height >= endHeight))
545560 then true
546561 else votesTransferFinished)
547562 then $Tuple2(nil, false)
548563 else {
549564 let latestProcessedAssetOrUnit = getString(keyLatestProcessedAssetTransfer)
550565 let latestProcessedUserOrUnit = getString(keyLatestProcessedUserTransfer)
551566 let finish = $Tuple2([BooleanEntry(votesTransferFinishedKey, true), DeleteEntry(keyLatestProcessedAssetTransfer), DeleteEntry(keyLatestProcessedUserTransfer)], true)
552567 if ((latestProcessedAssetOrUnit == unit))
553568 then {
554569 let assetsHeadOrUnit = getString(keyListHead(assetsListName))
555570 if ((assetsHeadOrUnit == unit))
556571 then finish
557572 else {
558573 let asset = value(assetsHeadOrUnit)
559574 let userAddressOrUnit = getString(keyListHead(getVotesListName(asset)))
560575 let processVoteActions = processVote(asset, userAddressOrUnit, keyLatestProcessedAssetTransfer, keyLatestProcessedUserTransfer)
561576 $Tuple2(processVoteActions, true)
562577 }
563578 }
564579 else {
565580 let latestProcessedAsset = value(latestProcessedAssetOrUnit)
566581 if ((latestProcessedUserOrUnit == unit))
567582 then {
568583 let assetOrUnit = getString(keyListNext(assetsListName, latestProcessedAsset))
569584 if ((assetOrUnit == unit))
570585 then finish
571586 else {
572587 let asset = value(assetOrUnit)
573588 let userAddressOrUnit = getString(keyListHead(getVotesListName(asset)))
574589 let processVoteActions = processVote(asset, userAddressOrUnit, keyLatestProcessedAssetTransfer, keyLatestProcessedUserTransfer)
575590 $Tuple2(processVoteActions, true)
576591 }
577592 }
578593 else {
579594 let latestProcessedUser = value(latestProcessedUserOrUnit)
580595 let userAddressOrUnit = getString(keyListNext(getVotesListName(latestProcessedAsset), latestProcessedUser))
581596 let processVoteActions = processVote(latestProcessedAsset, userAddressOrUnit, keyLatestProcessedAssetTransfer, keyLatestProcessedUserTransfer)
582597 $Tuple2(processVoteActions, true)
583598 }
584599 }
585600 }
586601 }
587602
588603
589604
590605 @Callable(i)
591606 func transferVotesWrapper (counter) = {
592607 let result = asBool(invoke(this, "transferVotesHelper", nil, nil))
593608 if ((result == result))
594609 then if (!(result))
595610 then if ((counter == 0))
596611 then throw("Voting is not started yet")
597612 else $Tuple2(nil, unit)
598613 else if ((maxDepth > counter))
599614 then {
600615 let inv = invoke(this, "transferVotesWrapper", [(counter + 1)], nil)
601616 if ((inv == inv))
602617 then $Tuple2(nil, unit)
603618 else throw("Strict value is not equal to itself.")
604619 }
605620 else $Tuple2(nil, unit)
606621 else throw("Strict value is not equal to itself.")
607622 }
608623
609624
610625
611626 @Callable(i)
612627 func transferVotes () = {
613628 let inv = invoke(this, "transferVotesWrapper", [0], nil)
614629 if ((inv == inv))
615630 then $Tuple2(nil, unit)
616631 else throw("Strict value is not equal to itself.")
617632 }
618633
619634
620635
621636 @Callable(i)
622637 func setVotingThreshold (newThreshold) = {
623638 let checkCaller = thisOnly(i)
624639 if ((checkCaller == checkCaller))
625640 then $Tuple2([IntegerEntry(keyVotingThreshold, newThreshold)], unit)
626641 else throw("Strict value is not equal to itself.")
627642 }
628643
629644
630645
631646 @Callable(i)
632647 func setFee (newFee) = {
633648 let checkCaller = thisOnly(i)
634649 if ((checkCaller == checkCaller))
635650 then $Tuple2([IntegerEntry(keyFeeAmount, newFee)], unit)
636651 else throw("Strict value is not equal to itself.")
637652 }
638653
639654
640655
641656 @Callable(i)
642657 func gwxAvailableForVoteREADONLY (userAddress) = {
643658 let endHeight = (startHeight + votingDuration)
644659 let gwxAmountAtEnd = getUserGwxAmountAtHeight(userAddress, endHeight)
645660 $Tuple2(nil, gwxAmountAtEnd)
646661 }
647662
648663

github/deemru/w8io/3ef1775 
112.70 ms