2022.05.11 17:25 [3112611] smart account 3PE8xSXKC8NiYUGW5mZuMeJqQbibhXqTcHE > SELF 0.00000000 Waves

{ "type": 13, "id": "3Mvr1rLxcfQpwWkKZyjE9kMf4ndU1yRPFe8c28vRYMoR", "fee": 1000000, "feeAssetId": null, "timestamp": 1652279141089, "version": 1, "sender": "3PE8xSXKC8NiYUGW5mZuMeJqQbibhXqTcHE", "senderPublicKey": "5k2UWS7wygmRcxBwEgn852bk5KPTt5435nWprBqxXooc", "proofs": [ "3pV7jVtEHdwVcGhPatjFKy3xK5htEZqYooHnCY9Y4cMVXfabL1aJqJc32F4CdVFAp9V3eWt8GXSULMkUNuhxfq4v" ], "script": "base64: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YWJsZVRvQ2xhaW1Ob3cAAAABBQAAAAdhZGRyZXNzBAAAAAxlbnN1cmVBbW91bnQDCQEAAAACIT0AAAACBQAAAAZhbW91bnQAAAAAAAAAAAAGCQEAAAAIdGhyb3dFcnIAAAABAgAAABBub3RoaW5nIHRvIGNsYWltAwkAAAAAAAACBQAAAAxlbnN1cmVBbW91bnQFAAAADGVuc3VyZUFtb3VudAQAAAALdG90YWxBbW91bnQJAQAAABJnZXRVc2VyVG90YWxBbW91bnQAAAABBQAAAAdhZGRyZXNzBAAAAA9yZW1haW5pbmdBbW91bnQJAQAAABZnZXRVc2VyUmVtYWluaW5nQW1vdW50AAAAAQUAAAAHYWRkcmVzcwQAAAAPY2xhaW1lZFdYQW1vdW50CQEAAAAUZ2V0VXNlckNsYWltZWRBbW91bnQAAAABBQAAAAdhZGRyZXNzBAAAAA1pc1Jldm9rZWRVc2VyCQEAAAALdmFsdWVPckVsc2UAAAACCQAEIAAAAAEJAQAAAAprZXlSZXZva2VkAAAAAQUAAAAHYWRkcmVzcwcDBQAAAA1pc1Jldm9rZWRVc2VyCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMFAAAABGFkZHIFAAAAD3JlbWFpbmluZ0Ftb3VudAUAAAACd3gJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAB2tleVVzZXIAAAABBQAAAAdhZGRyZXNzCQEAAAAJdmFsdWVVc2VyAAAABAUAAAALdG90YWxBbW91bnQAAAAAAAAAAAAJAABkAAAAAgUAAAAPY2xhaW1lZFdYQW1vdW50BQAAAA9yZW1haW5pbmdBbW91bnQFAAAABmhlaWdodAUAAAADbmlsCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMFAAAABGFkZHIFAAAABmFtb3VudAUAAAACd3gJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAB2tleVVzZXIAAAABBQAAAAdhZGRyZXNzCQEAAAAJdmFsdWVVc2VyAAAABAUAAAALdG90YWxBbW91bnQJAABlAAAAAgUAAAAPcmVtYWluaW5nQW1vdW50BQAAAAZhbW91bnQJAABkAAAAAgUAAAAPY2xhaW1lZFdYQW1vdW50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cgAAAAQFAAAABmFtb3VudAUAAAAGYW1vdW50AAAAAAAAAAAABQAAAAZoZWlnaHQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABNrZXlVc2VyVmVzdGluZ1N0YXJ0AAAAAQUAAAAHYWRkcmVzcwUAAAAGaGVpZ2h0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAARa2V5VXNlclZlc3RpbmdFbmQAAAABBQAAAAdhZGRyZXNzBQAAAAllbmRIZWlnaHQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABVrZXlVc2VyQW1vdW50UGVyQmxvY2sAAAABBQAAAAdhZGRyZXNzBQAAAA5hbW91bnRQZXJCbG9jawUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAABJpbmNyZWFzZURlcG9zaXRGb3IAAAABAAAAB2FkZHJlc3MEAAAAEGF2YWlsYWJsZVRvQ2xhaW0JAQAAABNhdmFpbGFibGVUb0NsYWltTm93AAAAAQUAAAAHYWRkcmVzcwQAAAAKZm9yY2VDbGFpbQMJAABmAAAAAgUAAAAQYXZhaWxhYmxlVG9DbGFpbQAAAAAAAAAAAAkBAAAADWNsYWltSW50ZXJuYWwAAAABBQAAAAdhZGRyZXNzBQAAAAR1bml0AwkAAAAAAAACBQAAAApmb3JjZUNsYWltBQAAAApmb3JjZUNsYWltBAAAAAZhbW91bnQICQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAABmFtb3VudAQAAAAJZW5kSGVpZ2h0CQEAAAAFdmFsdWUAAAABCQAEHwAAAAEJAQAAABFrZXlVc2VyVmVzdGluZ0VuZAAAAAEFAAAAB2FkZHJlc3MEAAAACnZlc3RpbmdMZW4JAABlAAAAAgUAAAAJZW5kSGVpZ2h0BQAAAAZoZWlnaHQEAAAADmFtb3VudFBlckJsb2NrCQEAAAAFdmFsdWUAAAABCQAEHwAAAAEJAQAAABVrZXlVc2VyQW1vdW50UGVyQmxvY2sAAAABBQAAAAdhZGRyZXNzBAAAABFpbmNBbW91bnRQZXJCbG9jawkAAGkAAAACBQAAAAZhbW91bnQFAAAACnZlc3RpbmdMZW4EAAAAD3VzZXJUb3RhbEFtb3VudAkBAAAAEmdldFVzZXJUb3RhbEFtb3VudAAAAAEFAAAAB2FkZHJlc3MEAAAAE3VzZXJSZW1haW5pbmdBbW91bnQJAQAAABZnZXRVc2VyUmVtYWluaW5nQW1vdW50AAAAAQUAAAAHYWRkcmVzcwQAAAARdXNlckNsYWltZWRBbW91bnQJAQAAABRnZXRVc2VyQ2xhaW1lZEFtb3VudAAAAAEFAAAAB2FkZHJlc3MEAAAAFXVzZXJMYXN0Q2xhaW1lZEhlaWdodAkBAAAAGGdldFVzZXJMYXN0Q2xhaW1lZEhlaWdodAAAAAEFAAAAB2FkZHJlc3MEAAAABmNoZWNrcwkABEwAAAACAwkAAAAAAAACCQEAAAALdmFsdWVPckVsc2UAAAACCQAEIAAAAAEJAQAAAAprZXlSZXZva2VkAAAAAQUAAAAHYWRkcmVzcwcHBgkBAAAACHRocm93RXJyAAAAAQIAAAAbZGVwb3NpdCBmb3IgdXNlciBpcyByZXZva2VkCQAETAAAAAIDCQEAAAACIT0AAAACCQAEIgAAAAEJAQAAAAdrZXlVc2VyAAAAAQUAAAAHYWRkcmVzcwUAAAAEdW5pdAYJAQAAAAh0aHJvd0VycgAAAAECAAAAH2RlcG9zaXQgZm9yIHVzZXIgZG9lc24ndCBleGlzdHMJAARMAAAAAgMJAAAAAAAAAgkAAlgAAAABCQEAAAAFdmFsdWUAAAABCAkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAdhc3NldElkCQEAAAAFdmFsdWUAAAABCQAEIgAAAAEJAQAAAAxrZXlXeEFzc2V0SWQAAAAABgkBAAAACHRocm93RXJyAAAAAQIAAAAaYXR0YWNoZWQgcGF5bWVudCBpcyBub3QgV1gJAARMAAAAAgMJAQAAAAIhPQAAAAIFAAAAEWluY0Ftb3VudFBlckJsb2NrAAAAAAAAAAAABgkBAAAACHRocm93RXJyAAAAAQIAAAA4YXR0YWNoZWQgYW1vdW50IHRvbyBzbWFsbCDigJQgaW5jcmVhc2UgaXMgemVybyBwZXIgYmxvY2sFAAAAA25pbAMJAAAAAAAAAgUAAAAGY2hlY2tzBQAAAAZjaGVja3MJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAB2tleVVzZXIAAAABBQAAAAdhZGRyZXNzCQEAAAAJdmFsdWVVc2VyAAAABAkAAGQAAAACBQAAAA91c2VyVG90YWxBbW91bnQFAAAABmFtb3VudAkAAGQAAAACBQAAABN1c2VyUmVtYWluaW5nQW1vdW50BQAAAAZhbW91bnQFAAAAEXVzZXJDbGFpbWVkQW1vdW50BQAAABV1c2VyTGFzdENsYWltZWRIZWlnaHQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABVrZXlVc2VyQW1vdW50UGVyQmxvY2sAAAABBQAAAAdhZGRyZXNzCQAAZAAAAAIFAAAADmFtb3VudFBlckJsb2NrBQAAABFpbmNBbW91bnRQZXJCbG9jawUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAQcmV2b2tlRGVwb3NpdEZvcgAAAAEAAAAHYWRkcmVzcwQAAAALdG90YWxBbW91bnQJAQAAABJnZXRVc2VyVG90YWxBbW91bnQAAAABBQAAAAdhZGRyZXNzBAAAAA9yZW1haW5pbmdBbW91bnQJAQAAABZnZXRVc2VyUmVtYWluaW5nQW1vdW50AAAAAQUAAAAHYWRkcmVzcwQAAAAPY2xhaW1lZFdYQW1vdW50CQEAAAAUZ2V0VXNlckNsYWltZWRBbW91bnQAAAABBQAAAAdhZGRyZXNzBAAAABFsYXN0Q2xhaW1lZEhlaWdodAkBAAAAGGdldFVzZXJMYXN0Q2xhaW1lZEhlaWdodAAAAAEFAAAAB2FkZHJlc3MEAAAAEnVuY2xhaW1lZEFtb3VudE5vdwkBAAAAE2F2YWlsYWJsZVRvQ2xhaW1Ob3cAAAABBQAAAAdhZGRyZXNzBAAAAAxyZXZva2VkVG90YWwJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQfAAAAAQkBAAAAD2tleVJldm9rZWRUb3RhbAAAAAAAAAAAAAAAAAAEAAAADmFtb3VudFRvUmV2b2tlCQAAZQAAAAIFAAAAD3JlbWFpbmluZ0Ftb3VudAUAAAASdW5jbGFpbWVkQW1vdW50Tm93BAAAAA9uZXdSZXZva2VkVG90YWwJAABkAAAAAgUAAAAMcmV2b2tlZFRvdGFsBQAAAA5hbW91bnRUb1Jldm9rZQQAAAAGY2hlY2tzCQAETAAAAAIJAQAAAAttdXN0TWFuYWdlcgAAAAEFAAAAAWkJAARMAAAAAgMJAQAAAAIhPQAAAAIJAAQiAAAAAQkBAAAAB2tleVVzZXIAAAABBQAAAAdhZGRyZXNzBQAAAAR1bml0BgkBAAAACHRocm93RXJyAAAAAQIAAAAeZGVwb3NpdCBmb3IgdXNlciBpcyBub3QgZXhpc3RzCQAETAAAAAIDCQAAZgAAAAIFAAAAD25ld1Jldm9rZWRUb3RhbAUAAAAMcmV2b2tlZFRvdGFsBgkBAAAACHRocm93RXJyAAAAAQIAAAA4bmV3UmV2b2tlZFRvdGFsIGNhbid0IGJlIGxlc3Mgb3IgZXF1YWwgdGhhbiByZXZva2VkVG90YWwFAAAAA25pbAMJAAAAAAAAAgUAAAAGY2hlY2tzBQAAAAZjaGVja3MJAARMAAAAAgkBAAAADEJvb2xlYW5FbnRyeQAAAAIJAQAAAAprZXlSZXZva2VkAAAAAQUAAAAHYWRkcmVzcwYJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA9rZXlSZXZva2VkVG90YWwAAAAABQAAAA9uZXdSZXZva2VkVG90YWwJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAB2tleVVzZXIAAAABBQAAAAdhZGRyZXNzCQEAAAAJdmFsdWVVc2VyAAAABAUAAAALdG90YWxBbW91bnQFAAAAEnVuY2xhaW1lZEFtb3VudE5vdwUAAAAPY2xhaW1lZFdYQW1vdW50BQAAABFsYXN0Q2xhaW1lZEhlaWdodAUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAAVjbGFpbQAAAAAJAQAAAA1jbGFpbUludGVybmFsAAAAAQkAAlgAAAABCAgFAAAAAWkAAAAGY2FsbGVyAAAABWJ5dGVzAAAAAWkBAAAADWNsYWltUkVBRE9OTFkAAAABAAAAB2FkZHJlc3MEAAAABmFtb3VudAkBAAAAE2F2YWlsYWJsZVRvQ2xhaW1Ob3cAAAABBQAAAAdhZGRyZXNzCQAFFAAAAAIFAAAAA25pbAUAAAAGYW1vdW50AAAAAWkBAAAABXN0YXRzAAAAAQAAAAdhZGRyZXNzCQAFFAAAAAIFAAAAA25pbAkABEwAAAACCQEAAAAFdmFsdWUAAAABCQAEHwAAAAEJAQAAABNrZXlVc2VyVmVzdGluZ1N0YXJ0AAAAAQUAAAAHYWRkcmVzcwkABEwAAAACCQEAAAAFdmFsdWUAAAABCQAEHwAAAAEJAQAAABFrZXlVc2VyVmVzdGluZ0VuZAAAAAEFAAAAB2FkZHJlc3MJAARMAAAAAgkBAAAAEmdldFVzZXJUb3RhbEFtb3VudAAAAAEFAAAAB2FkZHJlc3MJAARMAAAAAgkBAAAAFGdldFVzZXJDbGFpbWVkQW1vdW50AAAAAQUAAAAHYWRkcmVzcwkABEwAAAACCQEAAAAWZ2V0VXNlclJlbWFpbmluZ0Ftb3VudAAAAAEFAAAAB2FkZHJlc3MJAARMAAAAAgkBAAAAE2F2YWlsYWJsZVRvQ2xhaW1Ob3cAAAABBQAAAAdhZGRyZXNzBQAAAANuaWwAAAABaQEAAAAKc2V0TWFuYWdlcgAAAAEAAAAXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkEAAAAC2NoZWNrQ2FsbGVyCQEAAAALbXVzdE1hbmFnZXIAAAABBQAAAAFpAwkAAAAAAAACBQAAAAtjaGVja0NhbGxlcgUAAAALY2hlY2tDYWxsZXIEAAAAFWNoZWNrTWFuYWdlclB1YmxpY0tleQkAAlkAAAABBQAAABdwZW5kaW5nTWFuYWdlclB1YmxpY0tleQMJAAAAAAAAAgUAAAAVY2hlY2tNYW5hZ2VyUHVibGljS2V5BQAAABVjaGVja01hbmFnZXJQdWJsaWNLZXkJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAAAAAUAAAAXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkFAAAAA25pbAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAADmNvbmZpcm1NYW5hZ2VyAAAAAAQAAAACcG0JAQAAAB1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdAAAAAAEAAAABWhhc1BNAwkBAAAACWlzRGVmaW5lZAAAAAEFAAAAAnBtBgkBAAAACHRocm93RXJyAAAAAQIAAAASbm8gcGVuZGluZyBtYW5hZ2VyAwkAAAAAAAACBQAAAAVoYXNQTQUAAAAFaGFzUE0EAAAAB2NoZWNrUE0DCQAAAAAAAAIIBQAAAAFpAAAAD2NhbGxlclB1YmxpY0tleQkBAAAABXZhbHVlAAAAAQUAAAACcG0GCQEAAAAIdGhyb3dFcnIAAAABAgAAABt5b3UgYXJlIG5vdCBwZW5kaW5nIG1hbmFnZXIDCQAAAAAAAAIFAAAAB2NoZWNrUE0FAAAAB2NoZWNrUE0JAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAE2tleU1hbmFnZXJQdWJsaWNLZXkAAAAACQACWAAAAAEJAQAAAAV2YWx1ZQAAAAEFAAAAAnBtCQAETAAAAAIJAQAAAAtEZWxldGVFbnRyeQAAAAEJAQAAABprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQAAAAAFAAAAA25pbAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAQAAAAJ0eAEAAAAGdmVyaWZ5AAAAAAQAAAAPdGFyZ2V0UHVibGljS2V5BAAAAAckbWF0Y2gwCQEAAAAWbWFuYWdlclB1YmxpY0tleU9yVW5pdAAAAAADCQAAAQAAAAIFAAAAByRtYXRjaDACAAAACkJ5dGVWZWN0b3IEAAAAAnBrBQAAAAckbWF0Y2gwBQAAAAJwawMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAEVW5pdAgFAAAAAnR4AAAAD3NlbmRlclB1YmxpY0tleQkAAAIAAAABAgAAAAtNYXRjaCBlcnJvcgkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAAFAAAAD3RhcmdldFB1YmxpY0tleVmWwKA=", "chainId": 87, "height": 3112611, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: ETkfL1edF1QNKo37uxXzkXKTKBuurFdqijDYCYifBAU Diff:
OldNewDifferences
1-# no script
1+{-# STDLIB_VERSION 5 #-}
2+{-# SCRIPT_TYPE ACCOUNT #-}
3+{-# CONTENT_TYPE DAPP #-}
4+let SEP = "__"
5+
6+func keyManagerPublicKey () = "%s__managerPublicKey"
7+
8+
9+func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
10+
11+
12+func keyUser (address) = makeString(["%s", address], SEP)
13+
14+
15+func keyRevoked (address) = makeString(["%s%s", "revoked", address], SEP)
16+
17+
18+func keyRevokedTotal () = makeString(["%s", "revokedTotal"], SEP)
19+
20+
21+func keyUserVestingStart (address) = makeString(["%s%s", "vestingStart", address], SEP)
22+
23+
24+func keyUserVestingEnd (address) = makeString(["%s%s", "vestingEnd", address], SEP)
25+
26+
27+func keyUserAmountPerBlock (address) = makeString(["%s%s", "amountPerBlock", address], SEP)
28+
29+
30+func keyWxAssetId () = makeString(["%s", "wxAssetId"], SEP)
31+
32+
33+func throwErr (msg) = throw(makeString(["vesting.ride:", msg], " "))
34+
35+
36+func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
37+ case s: String =>
38+ fromBase58String(s)
39+ case _: Unit =>
40+ unit
41+ case _ =>
42+ throw("Match error")
43+}
44+
45+
46+func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
47+ case s: String =>
48+ fromBase58String(s)
49+ case _: Unit =>
50+ unit
51+ case _ =>
52+ throw("Match error")
53+}
54+
55+
56+func mustManager (i) = {
57+ let pd = throwErr("permission denied")
58+ match managerPublicKeyOrUnit() {
59+ case pk: ByteVector =>
60+ if ((i.callerPublicKey == pk))
61+ then true
62+ else pd
63+ case _: Unit =>
64+ if ((i.caller == this))
65+ then true
66+ else pd
67+ case _ =>
68+ throw("Match error")
69+ }
70+ }
71+
72+
73+func valueUserS (totalAmount,remainingAmount,claimedWXAmount,lastClaimedHeight) = makeString(["%d%d%d%d%d", totalAmount, remainingAmount, "0", claimedWXAmount, lastClaimedHeight], SEP)
74+
75+
76+func valueUser (totalAmount,remainingAmount,claimedWXAmount,lastClaimedHeight) = valueUserS(toString(totalAmount), toString(remainingAmount), toString(claimedWXAmount), toString(lastClaimedHeight))
77+
78+
79+func getUserTotalAmount (address) = parseIntValue(split(value(getString(keyUser(address))), SEP)[1])
80+
81+
82+func getUserRemainingAmount (address) = parseIntValue(split(value(getString(keyUser(address))), SEP)[2])
83+
84+
85+func getUserClaimedAmount (address) = parseIntValue(split(value(getString(keyUser(address))), SEP)[3])
86+
87+
88+func getUserLastClaimedHeight (address) = parseIntValue(split(value(getString(keyUser(address))), SEP)[5])
89+
90+
91+func availableToClaimNow (address) = {
92+ let isRevokedUser = valueOrElse(getBoolean(keyRevoked(address)), false)
93+ if (isRevokedUser)
94+ then getUserRemainingAmount(address)
95+ else {
96+ let lastHeight = getUserLastClaimedHeight(address)
97+ if ((lastHeight >= height))
98+ then 0
99+ else {
100+ let end = value(getInteger(keyUserVestingEnd(address)))
101+ if ((height > end))
102+ then getUserRemainingAmount(address)
103+ else {
104+ let unclaimedPeriod = (height - lastHeight)
105+ (value(getInteger(keyUserAmountPerBlock(address))) * unclaimedPeriod)
106+ }
107+ }
108+ }
109+ }
110+
111+
112+func claimInternal (address) = {
113+ let addr = addressFromStringValue(address)
114+ let wx = fromBase58String(value(getString(keyWxAssetId())))
115+ let amount = availableToClaimNow(address)
116+ let ensureAmount = if ((amount != 0))
117+ then true
118+ else throwErr("nothing to claim")
119+ if ((ensureAmount == ensureAmount))
120+ then {
121+ let totalAmount = getUserTotalAmount(address)
122+ let remainingAmount = getUserRemainingAmount(address)
123+ let claimedWXAmount = getUserClaimedAmount(address)
124+ let isRevokedUser = valueOrElse(getBoolean(keyRevoked(address)), false)
125+ if (isRevokedUser)
126+ then [ScriptTransfer(addr, remainingAmount, wx), StringEntry(keyUser(address), valueUser(totalAmount, 0, (claimedWXAmount + remainingAmount), height))]
127+ else [ScriptTransfer(addr, amount, wx), StringEntry(keyUser(address), valueUser(totalAmount, (remainingAmount - amount), (claimedWXAmount + amount), height))]
128+ }
129+ else throw("Strict value is not equal to itself.")
130+ }
131+
132+
133+@Callable(i)
134+func constructor (wxAssetId) = {
135+ let check = mustManager(i)
136+ if ((check == check))
137+ then [StringEntry(keyWxAssetId(), wxAssetId)]
138+ else throw("Strict value is not equal to itself.")
139+ }
140+
141+
142+
143+@Callable(i)
144+func withdrawRevoked () = {
145+ let amount = valueOrElse(getInteger(keyRevokedTotal()), 0)
146+ let wx = fromBase58String(value(getString(keyWxAssetId())))
147+ let checks = [mustManager(i), if ((amount > 0))
148+ then true
149+ else throwErr("revoked amount is zero, nothing to withdraw")]
150+ if ((checks == checks))
151+ then [ScriptTransfer(i.caller, amount, wx), IntegerEntry(keyRevokedTotal(), 0)]
152+ else throw("Strict value is not equal to itself.")
153+ }
154+
155+
156+
157+@Callable(i)
158+func createDepositFor (address,blocksDuration) = {
159+ let amount = i.payments[0].amount
160+ let endHeight = (height + blocksDuration)
161+ let vestingLen = (endHeight - height)
162+ let amountPerBlock = (amount / vestingLen)
163+ let checks = [if ((endHeight > height))
164+ then true
165+ else throwErr("endHeight must be more than height"), if ((getString(keyUser(address)) == unit))
166+ then true
167+ else throwErr("deposit for user already exists"), if ((toBase58String(value(i.payments[0].assetId)) == value(getString(keyWxAssetId()))))
168+ then true
169+ else throwErr("attached payment is not WX"), if ((amountPerBlock != 0))
170+ then true
171+ else throwErr("attached amount too small or blocksDuration too large — will claimed zero per block")]
172+ if ((checks == checks))
173+ then [StringEntry(keyUser(address), valueUser(amount, amount, 0, height)), IntegerEntry(keyUserVestingStart(address), height), IntegerEntry(keyUserVestingEnd(address), endHeight), IntegerEntry(keyUserAmountPerBlock(address), amountPerBlock)]
174+ else throw("Strict value is not equal to itself.")
175+ }
176+
177+
178+
179+@Callable(i)
180+func increaseDepositFor (address) = {
181+ let availableToClaim = availableToClaimNow(address)
182+ let forceClaim = if ((availableToClaim > 0))
183+ then claimInternal(address)
184+ else unit
185+ if ((forceClaim == forceClaim))
186+ then {
187+ let amount = i.payments[0].amount
188+ let endHeight = value(getInteger(keyUserVestingEnd(address)))
189+ let vestingLen = (endHeight - height)
190+ let amountPerBlock = value(getInteger(keyUserAmountPerBlock(address)))
191+ let incAmountPerBlock = (amount / vestingLen)
192+ let userTotalAmount = getUserTotalAmount(address)
193+ let userRemainingAmount = getUserRemainingAmount(address)
194+ let userClaimedAmount = getUserClaimedAmount(address)
195+ let userLastClaimedHeight = getUserLastClaimedHeight(address)
196+ let checks = [if ((valueOrElse(getBoolean(keyRevoked(address)), false) == false))
197+ then true
198+ else throwErr("deposit for user is revoked"), if ((getString(keyUser(address)) != unit))
199+ then true
200+ else throwErr("deposit for user doesn't exists"), if ((toBase58String(value(i.payments[0].assetId)) == value(getString(keyWxAssetId()))))
201+ then true
202+ else throwErr("attached payment is not WX"), if ((incAmountPerBlock != 0))
203+ then true
204+ else throwErr("attached amount too small — increase is zero per block")]
205+ if ((checks == checks))
206+ then [StringEntry(keyUser(address), valueUser((userTotalAmount + amount), (userRemainingAmount + amount), userClaimedAmount, userLastClaimedHeight)), IntegerEntry(keyUserAmountPerBlock(address), (amountPerBlock + incAmountPerBlock))]
207+ else throw("Strict value is not equal to itself.")
208+ }
209+ else throw("Strict value is not equal to itself.")
210+ }
211+
212+
213+
214+@Callable(i)
215+func revokeDepositFor (address) = {
216+ let totalAmount = getUserTotalAmount(address)
217+ let remainingAmount = getUserRemainingAmount(address)
218+ let claimedWXAmount = getUserClaimedAmount(address)
219+ let lastClaimedHeight = getUserLastClaimedHeight(address)
220+ let unclaimedAmountNow = availableToClaimNow(address)
221+ let revokedTotal = valueOrElse(getInteger(keyRevokedTotal()), 0)
222+ let amountToRevoke = (remainingAmount - unclaimedAmountNow)
223+ let newRevokedTotal = (revokedTotal + amountToRevoke)
224+ let checks = [mustManager(i), if ((getString(keyUser(address)) != unit))
225+ then true
226+ else throwErr("deposit for user is not exists"), if ((newRevokedTotal > revokedTotal))
227+ then true
228+ else throwErr("newRevokedTotal can't be less or equal than revokedTotal")]
229+ if ((checks == checks))
230+ then [BooleanEntry(keyRevoked(address), true), IntegerEntry(keyRevokedTotal(), newRevokedTotal), StringEntry(keyUser(address), valueUser(totalAmount, unclaimedAmountNow, claimedWXAmount, lastClaimedHeight))]
231+ else throw("Strict value is not equal to itself.")
232+ }
233+
234+
235+
236+@Callable(i)
237+func claim () = claimInternal(toBase58String(i.caller.bytes))
238+
239+
240+
241+@Callable(i)
242+func claimREADONLY (address) = {
243+ let amount = availableToClaimNow(address)
244+ $Tuple2(nil, amount)
245+ }
246+
247+
248+
249+@Callable(i)
250+func stats (address) = $Tuple2(nil, [value(getInteger(keyUserVestingStart(address))), value(getInteger(keyUserVestingEnd(address))), getUserTotalAmount(address), getUserClaimedAmount(address), getUserRemainingAmount(address), availableToClaimNow(address)])
251+
252+
253+
254+@Callable(i)
255+func setManager (pendingManagerPublicKey) = {
256+ let checkCaller = mustManager(i)
257+ if ((checkCaller == checkCaller))
258+ then {
259+ let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
260+ if ((checkManagerPublicKey == checkManagerPublicKey))
261+ then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
262+ else throw("Strict value is not equal to itself.")
263+ }
264+ else throw("Strict value is not equal to itself.")
265+ }
266+
267+
268+
269+@Callable(i)
270+func confirmManager () = {
271+ let pm = pendingManagerPublicKeyOrUnit()
272+ let hasPM = if (isDefined(pm))
273+ then true
274+ else throwErr("no pending manager")
275+ if ((hasPM == hasPM))
276+ then {
277+ let checkPM = if ((i.callerPublicKey == value(pm)))
278+ then true
279+ else throwErr("you are not pending manager")
280+ if ((checkPM == checkPM))
281+ then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
282+ else throw("Strict value is not equal to itself.")
283+ }
284+ else throw("Strict value is not equal to itself.")
285+ }
286+
287+
288+@Verifier(tx)
289+func verify () = {
290+ let targetPublicKey = match managerPublicKeyOrUnit() {
291+ case pk: ByteVector =>
292+ pk
293+ case _: Unit =>
294+ tx.senderPublicKey
295+ case _ =>
296+ throw("Match error")
297+ }
298+ sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
299+ }
300+
Full:
OldNewDifferences
1-# no script
1+{-# STDLIB_VERSION 5 #-}
2+{-# SCRIPT_TYPE ACCOUNT #-}
3+{-# CONTENT_TYPE DAPP #-}
4+let SEP = "__"
5+
6+func keyManagerPublicKey () = "%s__managerPublicKey"
7+
8+
9+func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
10+
11+
12+func keyUser (address) = makeString(["%s", address], SEP)
13+
14+
15+func keyRevoked (address) = makeString(["%s%s", "revoked", address], SEP)
16+
17+
18+func keyRevokedTotal () = makeString(["%s", "revokedTotal"], SEP)
19+
20+
21+func keyUserVestingStart (address) = makeString(["%s%s", "vestingStart", address], SEP)
22+
23+
24+func keyUserVestingEnd (address) = makeString(["%s%s", "vestingEnd", address], SEP)
25+
26+
27+func keyUserAmountPerBlock (address) = makeString(["%s%s", "amountPerBlock", address], SEP)
28+
29+
30+func keyWxAssetId () = makeString(["%s", "wxAssetId"], SEP)
31+
32+
33+func throwErr (msg) = throw(makeString(["vesting.ride:", msg], " "))
34+
35+
36+func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
37+ case s: String =>
38+ fromBase58String(s)
39+ case _: Unit =>
40+ unit
41+ case _ =>
42+ throw("Match error")
43+}
44+
45+
46+func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
47+ case s: String =>
48+ fromBase58String(s)
49+ case _: Unit =>
50+ unit
51+ case _ =>
52+ throw("Match error")
53+}
54+
55+
56+func mustManager (i) = {
57+ let pd = throwErr("permission denied")
58+ match managerPublicKeyOrUnit() {
59+ case pk: ByteVector =>
60+ if ((i.callerPublicKey == pk))
61+ then true
62+ else pd
63+ case _: Unit =>
64+ if ((i.caller == this))
65+ then true
66+ else pd
67+ case _ =>
68+ throw("Match error")
69+ }
70+ }
71+
72+
73+func valueUserS (totalAmount,remainingAmount,claimedWXAmount,lastClaimedHeight) = makeString(["%d%d%d%d%d", totalAmount, remainingAmount, "0", claimedWXAmount, lastClaimedHeight], SEP)
74+
75+
76+func valueUser (totalAmount,remainingAmount,claimedWXAmount,lastClaimedHeight) = valueUserS(toString(totalAmount), toString(remainingAmount), toString(claimedWXAmount), toString(lastClaimedHeight))
77+
78+
79+func getUserTotalAmount (address) = parseIntValue(split(value(getString(keyUser(address))), SEP)[1])
80+
81+
82+func getUserRemainingAmount (address) = parseIntValue(split(value(getString(keyUser(address))), SEP)[2])
83+
84+
85+func getUserClaimedAmount (address) = parseIntValue(split(value(getString(keyUser(address))), SEP)[3])
86+
87+
88+func getUserLastClaimedHeight (address) = parseIntValue(split(value(getString(keyUser(address))), SEP)[5])
89+
90+
91+func availableToClaimNow (address) = {
92+ let isRevokedUser = valueOrElse(getBoolean(keyRevoked(address)), false)
93+ if (isRevokedUser)
94+ then getUserRemainingAmount(address)
95+ else {
96+ let lastHeight = getUserLastClaimedHeight(address)
97+ if ((lastHeight >= height))
98+ then 0
99+ else {
100+ let end = value(getInteger(keyUserVestingEnd(address)))
101+ if ((height > end))
102+ then getUserRemainingAmount(address)
103+ else {
104+ let unclaimedPeriod = (height - lastHeight)
105+ (value(getInteger(keyUserAmountPerBlock(address))) * unclaimedPeriod)
106+ }
107+ }
108+ }
109+ }
110+
111+
112+func claimInternal (address) = {
113+ let addr = addressFromStringValue(address)
114+ let wx = fromBase58String(value(getString(keyWxAssetId())))
115+ let amount = availableToClaimNow(address)
116+ let ensureAmount = if ((amount != 0))
117+ then true
118+ else throwErr("nothing to claim")
119+ if ((ensureAmount == ensureAmount))
120+ then {
121+ let totalAmount = getUserTotalAmount(address)
122+ let remainingAmount = getUserRemainingAmount(address)
123+ let claimedWXAmount = getUserClaimedAmount(address)
124+ let isRevokedUser = valueOrElse(getBoolean(keyRevoked(address)), false)
125+ if (isRevokedUser)
126+ then [ScriptTransfer(addr, remainingAmount, wx), StringEntry(keyUser(address), valueUser(totalAmount, 0, (claimedWXAmount + remainingAmount), height))]
127+ else [ScriptTransfer(addr, amount, wx), StringEntry(keyUser(address), valueUser(totalAmount, (remainingAmount - amount), (claimedWXAmount + amount), height))]
128+ }
129+ else throw("Strict value is not equal to itself.")
130+ }
131+
132+
133+@Callable(i)
134+func constructor (wxAssetId) = {
135+ let check = mustManager(i)
136+ if ((check == check))
137+ then [StringEntry(keyWxAssetId(), wxAssetId)]
138+ else throw("Strict value is not equal to itself.")
139+ }
140+
141+
142+
143+@Callable(i)
144+func withdrawRevoked () = {
145+ let amount = valueOrElse(getInteger(keyRevokedTotal()), 0)
146+ let wx = fromBase58String(value(getString(keyWxAssetId())))
147+ let checks = [mustManager(i), if ((amount > 0))
148+ then true
149+ else throwErr("revoked amount is zero, nothing to withdraw")]
150+ if ((checks == checks))
151+ then [ScriptTransfer(i.caller, amount, wx), IntegerEntry(keyRevokedTotal(), 0)]
152+ else throw("Strict value is not equal to itself.")
153+ }
154+
155+
156+
157+@Callable(i)
158+func createDepositFor (address,blocksDuration) = {
159+ let amount = i.payments[0].amount
160+ let endHeight = (height + blocksDuration)
161+ let vestingLen = (endHeight - height)
162+ let amountPerBlock = (amount / vestingLen)
163+ let checks = [if ((endHeight > height))
164+ then true
165+ else throwErr("endHeight must be more than height"), if ((getString(keyUser(address)) == unit))
166+ then true
167+ else throwErr("deposit for user already exists"), if ((toBase58String(value(i.payments[0].assetId)) == value(getString(keyWxAssetId()))))
168+ then true
169+ else throwErr("attached payment is not WX"), if ((amountPerBlock != 0))
170+ then true
171+ else throwErr("attached amount too small or blocksDuration too large — will claimed zero per block")]
172+ if ((checks == checks))
173+ then [StringEntry(keyUser(address), valueUser(amount, amount, 0, height)), IntegerEntry(keyUserVestingStart(address), height), IntegerEntry(keyUserVestingEnd(address), endHeight), IntegerEntry(keyUserAmountPerBlock(address), amountPerBlock)]
174+ else throw("Strict value is not equal to itself.")
175+ }
176+
177+
178+
179+@Callable(i)
180+func increaseDepositFor (address) = {
181+ let availableToClaim = availableToClaimNow(address)
182+ let forceClaim = if ((availableToClaim > 0))
183+ then claimInternal(address)
184+ else unit
185+ if ((forceClaim == forceClaim))
186+ then {
187+ let amount = i.payments[0].amount
188+ let endHeight = value(getInteger(keyUserVestingEnd(address)))
189+ let vestingLen = (endHeight - height)
190+ let amountPerBlock = value(getInteger(keyUserAmountPerBlock(address)))
191+ let incAmountPerBlock = (amount / vestingLen)
192+ let userTotalAmount = getUserTotalAmount(address)
193+ let userRemainingAmount = getUserRemainingAmount(address)
194+ let userClaimedAmount = getUserClaimedAmount(address)
195+ let userLastClaimedHeight = getUserLastClaimedHeight(address)
196+ let checks = [if ((valueOrElse(getBoolean(keyRevoked(address)), false) == false))
197+ then true
198+ else throwErr("deposit for user is revoked"), if ((getString(keyUser(address)) != unit))
199+ then true
200+ else throwErr("deposit for user doesn't exists"), if ((toBase58String(value(i.payments[0].assetId)) == value(getString(keyWxAssetId()))))
201+ then true
202+ else throwErr("attached payment is not WX"), if ((incAmountPerBlock != 0))
203+ then true
204+ else throwErr("attached amount too small — increase is zero per block")]
205+ if ((checks == checks))
206+ then [StringEntry(keyUser(address), valueUser((userTotalAmount + amount), (userRemainingAmount + amount), userClaimedAmount, userLastClaimedHeight)), IntegerEntry(keyUserAmountPerBlock(address), (amountPerBlock + incAmountPerBlock))]
207+ else throw("Strict value is not equal to itself.")
208+ }
209+ else throw("Strict value is not equal to itself.")
210+ }
211+
212+
213+
214+@Callable(i)
215+func revokeDepositFor (address) = {
216+ let totalAmount = getUserTotalAmount(address)
217+ let remainingAmount = getUserRemainingAmount(address)
218+ let claimedWXAmount = getUserClaimedAmount(address)
219+ let lastClaimedHeight = getUserLastClaimedHeight(address)
220+ let unclaimedAmountNow = availableToClaimNow(address)
221+ let revokedTotal = valueOrElse(getInteger(keyRevokedTotal()), 0)
222+ let amountToRevoke = (remainingAmount - unclaimedAmountNow)
223+ let newRevokedTotal = (revokedTotal + amountToRevoke)
224+ let checks = [mustManager(i), if ((getString(keyUser(address)) != unit))
225+ then true
226+ else throwErr("deposit for user is not exists"), if ((newRevokedTotal > revokedTotal))
227+ then true
228+ else throwErr("newRevokedTotal can't be less or equal than revokedTotal")]
229+ if ((checks == checks))
230+ then [BooleanEntry(keyRevoked(address), true), IntegerEntry(keyRevokedTotal(), newRevokedTotal), StringEntry(keyUser(address), valueUser(totalAmount, unclaimedAmountNow, claimedWXAmount, lastClaimedHeight))]
231+ else throw("Strict value is not equal to itself.")
232+ }
233+
234+
235+
236+@Callable(i)
237+func claim () = claimInternal(toBase58String(i.caller.bytes))
238+
239+
240+
241+@Callable(i)
242+func claimREADONLY (address) = {
243+ let amount = availableToClaimNow(address)
244+ $Tuple2(nil, amount)
245+ }
246+
247+
248+
249+@Callable(i)
250+func stats (address) = $Tuple2(nil, [value(getInteger(keyUserVestingStart(address))), value(getInteger(keyUserVestingEnd(address))), getUserTotalAmount(address), getUserClaimedAmount(address), getUserRemainingAmount(address), availableToClaimNow(address)])
251+
252+
253+
254+@Callable(i)
255+func setManager (pendingManagerPublicKey) = {
256+ let checkCaller = mustManager(i)
257+ if ((checkCaller == checkCaller))
258+ then {
259+ let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
260+ if ((checkManagerPublicKey == checkManagerPublicKey))
261+ then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
262+ else throw("Strict value is not equal to itself.")
263+ }
264+ else throw("Strict value is not equal to itself.")
265+ }
266+
267+
268+
269+@Callable(i)
270+func confirmManager () = {
271+ let pm = pendingManagerPublicKeyOrUnit()
272+ let hasPM = if (isDefined(pm))
273+ then true
274+ else throwErr("no pending manager")
275+ if ((hasPM == hasPM))
276+ then {
277+ let checkPM = if ((i.callerPublicKey == value(pm)))
278+ then true
279+ else throwErr("you are not pending manager")
280+ if ((checkPM == checkPM))
281+ then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
282+ else throw("Strict value is not equal to itself.")
283+ }
284+ else throw("Strict value is not equal to itself.")
285+ }
286+
287+
288+@Verifier(tx)
289+func verify () = {
290+ let targetPublicKey = match managerPublicKeyOrUnit() {
291+ case pk: ByteVector =>
292+ pk
293+ case _: Unit =>
294+ tx.senderPublicKey
295+ case _ =>
296+ throw("Match error")
297+ }
298+ sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
299+ }
300+

github/deemru/w8io/db10caa 
37.96 ms