tx · 77YR3DXmXnjPC7Fh8MaZrApGg2LSwiYDzbeyV3XzddYN

3NCfoVSE59j5Avcebr746sd4qoWe31WScNE:  -0.00400000 Waves

2024.09.24 00:02 [3296749] smart account 3NCfoVSE59j5Avcebr746sd4qoWe31WScNE > SELF 0.00000000 Waves

{ "type": 13, "id": "77YR3DXmXnjPC7Fh8MaZrApGg2LSwiYDzbeyV3XzddYN", "fee": 400000, "feeAssetId": null, "timestamp": 1727125358722, "version": 2, "chainId": 84, "sender": "3NCfoVSE59j5Avcebr746sd4qoWe31WScNE", "senderPublicKey": "GYSXJm8C223boDFdBz46Li7rtuN99yRNzMcAHGpFJVjQ", "proofs": [ "5vr78eGNJv7oPUCAmt2SANGiJ1rYLtspeLwK273R2eVSLQGSJWVgRrnvLiMJjrq2GrwgLMaxo3jtAFJQcGspoM1J" ], "script": "base64:BgIbCAISABIDCgEBEgQKAggBEgMKAQgSABIDCgEIFQEQd3JpdGVDb25zdFN0cmluZwIDa2V5BXZhbHVlAwkBASEBCQEJaXNEZWZpbmVkAQkAnQgCBQR0aGlzBQNrZXkJAQtTdHJpbmdFbnRyeQIFA2tleQUFdmFsdWUJAAIBCQCsAgICFWFscmVhZHkgaW5pdGlhbGl6ZWQ6IAUDa2V5AQh3cml0ZUludAIDa2V5BXZhbHVlAwkAZgIAAAUFdmFsdWUJAAIBCQCsAgIJAKwCAgkArAICAhd3cml0aW5nIG5lZ2F0aXZlIHZhbHVlIAkApAMBBQV2YWx1ZQIJIGZvciBrZXkgBQNrZXkJAQxJbnRlZ2VyRW50cnkCBQNrZXkFBXZhbHVlAQhjaGFuZ2VCeQIDa2V5BXZhbHVlCQEId3JpdGVJbnQCBQNrZXkJAGQCCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFA2tleQAABQV2YWx1ZQASY29uZmlnQWRkcmVzc1N0b3JlAgZjb25maWcABmNvbmZpZwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzBRJjb25maWdBZGRyZXNzU3RvcmUCGGNvbmZpZyBhZGRyZXNzIG5vdCBmb3VuZAIWaW52YWxpZCBjb25maWcgYWRkcmVzcwAHdm91dGluZwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQZjb25maWcCD2NvbnRyYWN0X3ZvdGluZwIXY29udHJhY3Rfdm90aW5nIG5vdCBzZXQCH2ludmFsaWQgY29udHJhY3Rfdm90aW5nIGFkZHJlc3MBB2FsbG93ZWQBAm9wCQD8BwQFBmNvbmZpZwIJb3BBbGxvd2VkCQDMCAIFAm9wBQNuaWwFA25pbAAPdW5pdHNBc3NldElkU3RyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUGY29uZmlnAgt1bml0c19hc3NldAIVdW5pdHNfYXNzZXQgbm90IGZvdW5kAAx1bml0c0Fzc2V0SWQJANkEAQUPdW5pdHNBc3NldElkU3RyABVzdGFraW5nQWRkcmVzc2VzU3RvcmUCEHN0YWtpbmdBZGRyZXNzZXMAEHN0YWtpbmdBZGRyZXNzZXMJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUGY29uZmlnBRVzdGFraW5nQWRkcmVzc2VzU3RvcmUCAAELc3Rha2VkU3RvcmUBB2FkZHJlc3MJAKwCAgIHc3Rha2VkXwUHYWRkcmVzcwEJbG9ja0Jsb2NrAQdhZGRyZXNzCQCsAgICC2Jsb2NrX2xvY2tfBQdhZGRyZXNzAQt1bmxvY2tCbG9jawEHYWRkcmVzcwkArAICAg1ibG9ja191bmxvY2tfBQdhZGRyZXNzAQZzdGFrZWQBB2FkZHJlc3MJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBC3N0YWtlZFN0b3JlAQUHYWRkcmVzcwAAABB0b3RhbFN0YWtlZFN0b3JlAgxzdGFrZWRfdG90YWwAC3RvdGFsU3Rha2VkCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFEHRvdGFsU3Rha2VkU3RvcmUAAAALbWluTG9ja1RpbWUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQZjb25maWcJAKwCAgkApQgBBQR0aGlzAhBfbWluX2xvY2tfYmxvY2tzAhhfbWluX2xvY2tfYmxvY2tzIG5vdCBzZXQABkhFSUdIVAUGaGVpZ2h0AQZhZHZpc2UACQCsAgIJAKwCAgkArAICAghoZWlnaHQ6IAkApAMBBQZIRUlHSFQCECwgdG90YWxfc3Rha2VkOiAJAKQDAQULdG90YWxTdGFrZWQBCmFkdmlzZVVzZXIBB2FjY291bnQECnVzZXJTdGFrZWQJAQZzdGFrZWQBBQdhY2NvdW50CQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAghoZWlnaHQ6IAkApAMBBQZIRUlHSFQCCywgYWNjb3VudDogBQdhY2NvdW50AgosIHN0YWtlZDogCQCkAwEFCnVzZXJTdGFrZWQDCQAAAgUKdXNlclN0YWtlZAAAAiIsIGxvY2tfYmxvY2s6IC0xLCB1bmxvY2tfYmxvY2s6IC0xCQCsAgIJAKwCAgkArAICAg4sIGxvY2tfYmxvY2s6IAkApAMBCQERQGV4dHJOYXRpdmUoMTA1NSkBCQEJbG9ja0Jsb2NrAQUHYWNjb3VudAIQLCB1bmxvY2tfYmxvY2s6IAkApAMBCQERQGV4dHJOYXRpdmUoMTA1NSkBCQELdW5sb2NrQmxvY2sBBQdhY2NvdW50BgFpAQVzdGFrZQAEAWEJAQdhbGxvd2VkAQIFc3Rha2UDCQAAAgUBYQUBYQMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECGXNpbmdsZSBwYXltZW50IGlzIGFsbG93ZWQDCQECIT0CCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQFDHVuaXRzQXNzZXRJZAkAAgECFWludmFsaWQgcGF5bWVudCBhc3NldAQEdXNlcgkApQgBCAUBaQZjYWxsZXIECnVzZXJTdGFrZWQJAQtzdGFrZWRTdG9yZQEFBHVzZXIED2FkZGl0aW9uYWxTdGFrZQgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQJAMwIAgkBCGNoYW5nZUJ5AgUKdXNlclN0YWtlZAUPYWRkaXRpb25hbFN0YWtlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEJbG9ja0Jsb2NrAQUEdXNlcgUGSEVJR0hUCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQELdW5sb2NrQmxvY2sBBQR1c2VyCQBkAgUGSEVJR0hUBQttaW5Mb2NrVGltZQkAzAgCCQEIY2hhbmdlQnkCBRB0b3RhbFN0YWtlZFN0b3JlBQ9hZGRpdGlvbmFsU3Rha2UFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQd1bnN0YWtlAQZhbW91bnQEAWEJAQdhbGxvd2VkAQIHdW5zdGFrZQMJAAACBQFhBQFhAwkAZwIAAAUGYW1vdW50CQACAQIZYW1vdW50IHNob3VsZCBiZSBwb3NpdGl2ZQQEdXNlcgkApQgBCAUBaQZjYWxsZXIECnVzZXJTdGFrZWQJAQtzdGFrZWRTdG9yZQEFBHVzZXIEDHN0YWtlZEFtb3VudAkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwUKdXNlclN0YWtlZAMJAGcCAAAFDHN0YWtlZEFtb3VudAkAAgECDm5vdGhpbmcgc3Rha2VkBAx1bmxvY2tIZWlnaHQJARFAZXh0ck5hdGl2ZSgxMDU1KQEJAQt1bmxvY2tCbG9jawEFBHVzZXIDCQBmAgUMdW5sb2NrSGVpZ2h0BQZIRUlHSFQJAAIBCQCsAgICEmxvY2tlZCB0aWxsIGJsb2NrIAkApAMBBQx1bmxvY2tIZWlnaHQJAM4IAgkAzAgCCQEIY2hhbmdlQnkCBRB0b3RhbFN0YWtlZFN0b3JlCQEBLQEFBmFtb3VudAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFBmFtb3VudAUMdW5pdHNBc3NldElkBQNuaWwDCQAAAgUMc3Rha2VkQW1vdW50BQZhbW91bnQJAMwIAgkBC0RlbGV0ZUVudHJ5AQUKdXNlclN0YWtlZAkAzAgCCQELRGVsZXRlRW50cnkBCQEJbG9ja0Jsb2NrAQUEdXNlcgkAzAgCCQELRGVsZXRlRW50cnkBCQELdW5sb2NrQmxvY2sBBQR1c2VyBQNuaWwJAMwIAgkBCGNoYW5nZUJ5AgUKdXNlclN0YWtlZAkBAS0BBQZhbW91bnQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQdsb2NrRm9yAgdhZGRyZXNzBnVubG9jawMJAQIhPQIIBQFpBmNhbGxlcgUHdm91dGluZwkAAgECBmRlbmllZAQNY3VycmVudFVubG9jawkBC3ZhbHVlT3JFbHNlAgkAnwgBCQELdW5sb2NrQmxvY2sBBQdhZGRyZXNzAAADCQBnAgUNY3VycmVudFVubG9jawUGdW5sb2NrBQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAQt1bmxvY2tCbG9jawEFB2FkZHJlc3MFBnVubG9jawUDbmlsAWkBCXVzZXJTdGFrZQEHYWRkcmVzcwkAlAoCBQNuaWwJAQZzdGFrZWQBBQdhZGRyZXNzAWkBCnRvdGFsU3Rha2UACQCUCgIFA25pbAULdG90YWxTdGFrZWQBaQEEaW5pdAEEY29uZgkAzAgCCQEQd3JpdGVDb25zdFN0cmluZwIFEmNvbmZpZ0FkZHJlc3NTdG9yZQUEY29uZgUDbmlsAO1cMXY=", "height": 3296749, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
OldNewDifferences
1-# no script
1+{-# STDLIB_VERSION 6 #-}
2+{-# SCRIPT_TYPE ACCOUNT #-}
3+{-# CONTENT_TYPE DAPP #-}
4+func writeConstString (key,value) = if (!(isDefined(getString(this, key))))
5+ then StringEntry(key, value)
6+ else throw(("already initialized: " + key))
7+
8+
9+func writeInt (key,value) = if ((0 > value))
10+ then throw(((("writing negative value " + toString(value)) + " for key ") + key))
11+ else IntegerEntry(key, value)
12+
13+
14+func changeBy (key,value) = writeInt(key, (valueOrElse(getInteger(this, key), 0) + value))
15+
16+
17+let configAddressStore = "config"
18+
19+let config = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, configAddressStore), "config address not found")), "invalid config address")
20+
21+let vouting = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(config, "contract_voting"), "contract_voting not set")), "invalid contract_voting address")
22+
23+func allowed (op) = invoke(config, "opAllowed", [op], nil)
24+
25+
26+let unitsAssetIdStr = valueOrErrorMessage(getString(config, "units_asset"), "units_asset not found")
27+
28+let unitsAssetId = fromBase58String(unitsAssetIdStr)
29+
30+let stakingAddressesStore = "stakingAddresses"
31+
32+let stakingAddresses = valueOrElse(getString(config, stakingAddressesStore), "")
33+
34+func stakedStore (address) = ("staked_" + address)
35+
36+
37+func lockBlock (address) = ("block_lock_" + address)
38+
39+
40+func unlockBlock (address) = ("block_unlock_" + address)
41+
42+
43+func staked (address) = valueOrElse(getInteger(this, stakedStore(address)), 0)
44+
45+
46+let totalStakedStore = "staked_total"
47+
48+let totalStaked = valueOrElse(getInteger(this, totalStakedStore), 0)
49+
50+let minLockTime = valueOrErrorMessage(getInteger(config, (toString(this) + "_min_lock_blocks")), "_min_lock_blocks not set")
51+
52+let HEIGHT = height
53+
54+func advise () = ((("height: " + toString(HEIGHT)) + ", total_staked: ") + toString(totalStaked))
55+
56+
57+func adviseUser (account) = {
58+ let userStaked = staked(account)
59+ (((((("height: " + toString(HEIGHT)) + ", account: ") + account) + ", staked: ") + toString(userStaked)) + (if ((userStaked == 0))
60+ then ", lock_block: -1, unlock_block: -1"
61+ else (((", lock_block: " + toString(getIntegerValue(lockBlock(account)))) + ", unlock_block: ") + toString(getIntegerValue(unlockBlock(account))))))
62+ }
63+
64+
65+@Callable(i)
66+func stake () = {
67+ let a = allowed("stake")
68+ if ((a == a))
69+ then if ((size(i.payments) != 1))
70+ then throw("single payment is allowed")
71+ else if ((i.payments[0].assetId != unitsAssetId))
72+ then throw("invalid payment asset")
73+ else {
74+ let user = toString(i.caller)
75+ let userStaked = stakedStore(user)
76+ let additionalStake = i.payments[0].amount
77+[changeBy(userStaked, additionalStake), IntegerEntry(lockBlock(user), HEIGHT), IntegerEntry(unlockBlock(user), (HEIGHT + minLockTime)), changeBy(totalStakedStore, additionalStake)]
78+ }
79+ else throw("Strict value is not equal to itself.")
80+ }
81+
82+
83+
84+@Callable(i)
85+func unstake (amount) = {
86+ let a = allowed("unstake")
87+ if ((a == a))
88+ then if ((0 >= amount))
89+ then throw("amount should be positive")
90+ else {
91+ let user = toString(i.caller)
92+ let userStaked = stakedStore(user)
93+ let stakedAmount = getIntegerValue(this, userStaked)
94+ if ((0 >= stakedAmount))
95+ then throw("nothing staked")
96+ else {
97+ let unlockHeight = getIntegerValue(unlockBlock(user))
98+ if ((unlockHeight > HEIGHT))
99+ then throw(("locked till block " + toString(unlockHeight)))
100+ else ([changeBy(totalStakedStore, -(amount)), ScriptTransfer(i.caller, amount, unitsAssetId)] ++ (if ((stakedAmount == amount))
101+ then [DeleteEntry(userStaked), DeleteEntry(lockBlock(user)), DeleteEntry(unlockBlock(user))]
102+ else [changeBy(userStaked, -(amount))]))
103+ }
104+ }
105+ else throw("Strict value is not equal to itself.")
106+ }
107+
108+
109+
110+@Callable(i)
111+func lockFor (address,unlock) = if ((i.caller != vouting))
112+ then throw("denied")
113+ else {
114+ let currentUnlock = valueOrElse(getInteger(unlockBlock(address)), 0)
115+ if ((currentUnlock >= unlock))
116+ then nil
117+ else [IntegerEntry(unlockBlock(address), unlock)]
118+ }
119+
120+
121+
122+@Callable(i)
123+func userStake (address) = $Tuple2(nil, staked(address))
124+
125+
126+
127+@Callable(i)
128+func totalStake () = $Tuple2(nil, totalStaked)
129+
130+
131+
132+@Callable(i)
133+func init (conf) = [writeConstString(configAddressStore, conf)]
134+
135+

github/deemru/w8io/026f985 
19.51 ms