tx · BzAL94caPBNHrJANpPWPh5JiWNeJJbnpUyHVJWT3CkyM

3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy:  -0.01000000 Waves

2023.01.16 21:18 [2407835] smart account 3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy > SELF 0.00000000 Waves

{ "type": 13, "id": "BzAL94caPBNHrJANpPWPh5JiWNeJJbnpUyHVJWT3CkyM", "fee": 1000000, "feeAssetId": null, "timestamp": 1673893202231, "version": 2, "chainId": 84, "sender": "3MumkGGztCKAXpWDqxkddofqXSUbqQkvSJy", "senderPublicKey": "C3PaRKeL8AUKbwUqdniMQtThgcTh5DYHV1777Hkxy7rp", "proofs": [ "5mzZ6gm5Duau5VZrtJaFqaYQJ6HjfiLvyqyxHzc2QE9Zwt76477EXgjUriv28pn9DCYDDSFdJmWyDYjdB4jdWuBn" ], "script": "base64:BgIHCAISAwoBCAIABWNoYWluCQCwCQEJAMkBAgkAygECCAUEdGhpcwVieXRlcwABAAEAC3VzZG5Bc3NldElkBAckbWF0Y2gwBQVjaGFpbgMJAAACAgFXBQckbWF0Y2gwASC2JinDBPXOU5GkDkt1JC9kjFGx+t+vVCm9SNIdKrKq0QMJAAACAgFUBQckbWF0Y2gwASD3dur394PKZdtuE+4CO89YKZWpwdGN8kvabNgdYoDI3gkAAgECDVVua25vd24gY2hhaW4BAWkBEndhbGxldEluZm9SRUFET05MWQERdXNlckFkZHJlc3NTdHJPcHQEBGFkZHIJAKYIAQURdXNlckFkZHJlc3NTdHJPcHQEB2JhbGFuY2UDCQEJaXNEZWZpbmVkAQUEYWRkcgkA7wcBCQEFdmFsdWUBBQRhZGRyCQEOQmFsYW5jZURldGFpbHMEAAAAAAAAAAAEC3VzZG5CYWxhbmNlAwkBCWlzRGVmaW5lZAEFBGFkZHIJAPAHAgkBBXZhbHVlAQUEYWRkcgULdXNkbkFzc2V0SWQAAAkAlAoCBQNuaWwJALkJAgkAzAgCAgolZCVkJWQlZCVkCQDMCAIJAKQDAQgFB2JhbGFuY2UHcmVndWxhcgkAzAgCCQCkAwEIBQdiYWxhbmNlCWF2YWlsYWJsZQkAzAgCCQCkAwEIBQdiYWxhbmNlCmdlbmVyYXRpbmcJAMwIAgkApAMBCAUHYmFsYW5jZQllZmZlY3RpdmUJAMwIAgkApAMBBQt1c2RuQmFsYW5jZQUDbmlsAgFfAA6c+Q0=", "height": 2407835, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: BwWH6Pr1TivNLpmQR2raf93bsSAkbk9PGNeKDh2WCWUG Next: KxeNzrMhp4EsChMTVU7HAWStTu45vwiDoBBMLACbQGh Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let revisionNum = ""
4+let chain = toUtf8String(take(drop(this.bytes, 1), 1))
55
6-let SEP = "__"
7-
8-let LISTSEP = ":"
9-
10-let DEFAULTQUORUM = 500000
11-
12-let URLPATTERN = "https://forum.neutrino.at/"
13-
14-let MAXTITLE = 160
15-
16-let MAXURL = 250
17-
18-let MAXVOTINGTIME = 1209600000
19-
20-let MULT6 = 1000000
21-
22-let DEFAULTPAYMENT = 1000000000
23-
24-let DEFAULTCREATIONGNSBT = 1000000000
25-
26-let PASTMARGIN = 7200000
27-
28-let FUTUREMARGIN = 5400000
29-
30-let govIdxProposalTxId = 1
31-
32-let govIdxType = 2
33-
34-let govIdxAuthor = 3
35-
36-let govIdxUrl = 4
37-
38-let govIdxTitle = 5
39-
40-let govIdxCreationTime = 6
41-
42-let govIdxStart = 7
43-
44-let govIdxEnd = 8
45-
46-let govIdxTxIds = 9
47-
48-let govIdxQuorum = 10
49-
50-let govIdxOptions = 11
51-
52-let govStatusIdxIsValid = 1
53-
54-let govStatusIdxWinOpt = 2
55-
56-let govStatusIdxWinVotes = 3
57-
58-let govStatusIdxTotalVotes = 4
59-
60-let govStatusIdxScApplied = 5
61-
62-let govStatusIdxScTime = 6
63-
64-let govStatusIdxIsCanceled = 7
65-
66-func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
67-
68-
69-func getIntOrElse (key,defaultVal) = valueOrElse(getInteger(this, key), defaultVal)
70-
71-
72-let IdxControlCfgNeutrinoDapp = 1
73-
74-let IdxControlCfgAuctionDapp = 2
75-
76-let IdxControlCfgRpdDapp = 3
77-
78-let IdxControlCfgMathDapp = 4
79-
80-let IdxControlCfgLiquidationDapp = 5
81-
82-let IdxControlCfgRestDapp = 6
83-
84-let IdxControlCfgNodeRegistryDapp = 7
85-
86-let IdxControlCfgNsbtStakingDapp = 8
87-
88-let IdxControlCfgMediatorDapp = 9
89-
90-let IdxControlCfgSurfStakingDapp = 10
91-
92-let IdxControlCfgGnsbtControllerDapp = 11
93-
94-let IdxControlCfgRestV2Dapp = 12
95-
96-let IdxControlCfgGovernanceDapp = 13
97-
98-func keyControlAddress () = "%s%s__config__controlAddress"
99-
100-
101-func keyControlCfg () = "%s__controlConfig"
102-
103-
104-func readControlCfgOrFail (control) = split_4C(getStringOrFail(control, keyControlCfg()), SEP)
105-
106-
107-func getContractAddressOrFail (controlCfg,idx) = valueOrErrorMessage(addressFromString(controlCfg[idx]), ("Control cfg doesn't contain address at index " + toString(idx)))
108-
109-
110-let controlContract = addressFromStringValue(valueOrElse(getString(this, keyControlAddress()), "3P5Bfd58PPfNvBM2Hy8QfbcDqMeNtzg7KfP"))
111-
112-let controlCfg = readControlCfgOrFail(controlContract)
113-
114-let neutrinoContract = getContractAddressOrFail(controlCfg, IdxControlCfgNeutrinoDapp)
115-
116-let gnsbtControllerContract = getContractAddressOrFail(controlCfg, IdxControlCfgGnsbtControllerDapp)
117-
118-func keyQuorumRequiredPercent () = "%s__quorumRequired"
119-
120-
121-func keyPaymentRequired () = "%s__paymentRequired"
122-
123-
124-func keyGnsbtRequired () = "%s__gNsbtRequired"
125-
126-
127-func keyLastProposalId () = "%s__proposalId"
128-
129-
130-func keyProposalStatusDataById (proposalId) = ("%s%d__proposalStatusData__" + toString(proposalId))
131-
132-
133-func keyProposalDataById (proposalId) = ("%s%d__proposalData__" + toString(proposalId))
134-
135-
136-func keyProposalVotesByIdAndOption (proposalId,opt) = makeString(["%s%d%d", "votesByOpt", toString(proposalId), toString(opt)], SEP)
137-
138-
139-func keyProposalVotesByIdAndUser (proposalId,userAddr) = makeString(["%s%d%s", "votesByUser", toString(proposalId), userAddr], SEP)
140-
141-
142-func keyProposalChoiceByIdAndUser (proposalId,userAddr) = makeString(["%s%d%s", "optionByUser", toString(proposalId), userAddr], SEP)
143-
144-
145-func keyApplyInProgress () = "%s__applyInProgress"
146-
147-
148-func keyNumUniqueVotersByProposalId (proposalId) = ("%s%d__numVoters__" + toString(proposalId))
149-
150-
151-func keyStatsAverUniqueVoters () = "%s%s%s__stats__avg__uniqueVoters"
152-
153-
154-func keyStatsAverGnsbtVoted () = "%s%s%s__stats__avg__gnsbtVoted"
155-
156-
157-func keyStatsUniqueAuthors () = "%s%s__stats__uniqueAuthors"
158-
159-
160-func keyNumProposalsByAuthor (addressStr) = ("%s%s__numProposalsByAuthor__" + addressStr)
161-
162-
163-func asAnyList (v) = match v {
164- case l: List[Any] =>
165- l
6+let usdnAssetId = match chain {
1667 case _ =>
167- throw("fail to cast into List[Any]")
8+ if (("W" == $match0))
9+ then base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p'
10+ else if (("T" == $match0))
11+ then base58'HezsdQuRDtzksAYUy97gfhKy7Z1NW2uXYSHA3bgqenNZ'
12+ else throw("Unknown chain")
16813 }
16914
170-
171-func asInt (v) = match v {
172- case i: Int =>
173- i
174- case _ =>
175- throw("fail to cast into Int")
176-}
177-
178-
179-func statusData (isVotingValid,winOption,winOptionVotes,totalVotes,areScriptsApplied,scriptsTimestamp,canceledByTeam) = makeString(["%b%d%d%d%b%d%b", toString(isVotingValid), toString(winOption), toString(winOptionVotes), toString(totalVotes), toString(areScriptsApplied), toString(scriptsTimestamp), toString(canceledByTeam)], SEP)
180-
181-
182-func proposalData (proposalTxId,type,author,forumLink,title,proposalTime,votingStartTime,votingEndTime,txIds,quorumInGnsbt,options) = makeString(["%s%s%s%s%s%d%d%d%s%d%s", proposalTxId, type, author, forumLink, title, toString(proposalTime), toString(votingStartTime), toString(votingEndTime), txIds, toString(quorumInGnsbt), options], SEP)
183-
184-
185-func checkTxList (txList) = if ((size(txList) > 20))
186- then throw(("Too many transactions: " + toString(size(txList))))
187- else {
188- func combiner (acc,tx) = if ((size(fromBase58String(tx)) != 32))
189- then throw(("Wrong txId: " + tx))
190- else if ((acc == ""))
191- then tx
192- else ((acc + LISTSEP) + tx)
193-
194- let $l = txList
195- let $s = size($l)
196- let $acc0 = ""
197- func $f0_1 ($a,$i) = if (($i >= $s))
198- then $a
199- else combiner($a, $l[$i])
200-
201- func $f0_2 ($a,$i) = if (($i >= $s))
202- then $a
203- else throw("List size exceeds 20")
204-
205- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
206- }
207-
208-
209-func initiateVoting (payment,proposalTxId,type,author,forumLink,title,votingStartTime,votingEndTime,status,txList,optionsList) = if ((payment.assetId != unit))
210- then throw("Allowed WAVES payment only!")
211- else {
212- let pmtReq = getIntOrElse(keyPaymentRequired(), DEFAULTPAYMENT)
213- if ((pmtReq > payment.amount))
214- then throw(("Payment attached should be at least " + toString(pmtReq)))
215- else if ((value(indexOf(forumLink, URLPATTERN)) != 0))
216- then throw("Invalid url")
217- else if ((size(forumLink) > MAXURL))
218- then throw("Url too long!")
219- else if ((title == ""))
220- then throw("Title is empty")
221- else if ((size(title) > MAXTITLE))
222- then throw("Too long title")
223- else {
224- let proposalTime = lastBlock.timestamp
225- if ((proposalTime > votingStartTime))
226- then throw(((("votingStartTime=" + toString(votingStartTime)) + " < proposalTime=") + toString(proposalTime)))
227- else if ((votingStartTime > votingEndTime))
228- then throw(((("votingEndTime=" + toString(votingEndTime)) + " < votingStartTime=") + toString(votingStartTime)))
229- else if (((votingEndTime - votingStartTime) > MAXVOTINGTIME))
230- then throw(((("Voting period exceeds max: " + toString((votingEndTime - votingStartTime))) + " > ") + toString(MAXVOTINGTIME)))
231- else {
232- let txIds = if ((type == "IDEA"))
233- then ""
234- else checkTxList(txList)
235- if ((1 >= size(optionsList)))
236- then throw("Too few choices to vote")
237- else {
238- let gnsbtInfo = asAnyList(invoke(gnsbtControllerContract, "gnsbtInfoSYSREADONLY", [author, 0, 0], nil))
239- let gnsbtTotal = asInt(gnsbtInfo[1])
240- let gNsbtUser = asInt(gnsbtInfo[0])
241- let gnsbtReq = getIntOrElse(keyGnsbtRequired(), DEFAULTCREATIONGNSBT)
242- if ((gnsbtReq > gNsbtUser))
243- then throw((("You need at least " + toString(gnsbtReq)) + " gNsbt to create voting"))
244- else {
245- let amountLeased = invoke(neutrinoContract, "acceptWaves", nil, [payment])
246- if ((amountLeased == amountLeased))
247- then {
248- let quorum = getIntOrElse(keyQuorumRequiredPercent(), DEFAULTQUORUM)
249- let quorumInGnsbt = fraction(quorum, gnsbtTotal, MULT6)
250- let proposalId = (getIntOrElse(keyLastProposalId(), 0) + 1)
251- let numProposalsByAuthor = (getIntOrElse(keyNumProposalsByAuthor(author), 0) + 1)
252- let uniqAuthors = (getIntOrElse(keyStatsUniqueAuthors(), 0) + (if ((numProposalsByAuthor == 1))
253- then 1
254- else 0))
255- let optionsStr = makeString(optionsList, LISTSEP)
256- $Tuple2([IntegerEntry(keyLastProposalId(), proposalId), StringEntry(keyProposalStatusDataById(proposalId), statusData(false, 0, 0, 0, false, 0, false)), StringEntry(keyProposalDataById(proposalId), proposalData(proposalTxId, type, author, forumLink, title, proposalTime, votingStartTime, votingEndTime, txIds, quorumInGnsbt, optionsStr)), IntegerEntry(keyNumProposalsByAuthor(author), numProposalsByAuthor), IntegerEntry(keyStatsUniqueAuthors(), uniqAuthors)], proposalTxId)
257- }
258- else throw("Strict value is not equal to itself.")
259- }
260- }
261- }
262- }
263- }
264-
265-
266-func calcWinOption (proposalId,optionsList,isPrevOptional,oldChoice,optionalTotalOld,newChoice,newTotalByNewChoice) = {
267- func findBest (acc,elem) = {
268- let idx = value(indexOf(optionsList, elem))
269- let val = if (isPrevOptional)
270- then if ((idx == newChoice))
271- then newTotalByNewChoice
272- else getIntOrElse(keyProposalVotesByIdAndOption(proposalId, idx), 0)
273- else if ((idx == value(oldChoice)))
274- then optionalTotalOld
275- else if ((idx == newChoice))
276- then newTotalByNewChoice
277- else getIntOrElse(keyProposalVotesByIdAndOption(proposalId, idx), 0)
278- if ((acc._2 > val))
279- then acc
280- else $Tuple2(idx, val)
281- }
282-
283- let $l = optionsList
284- let $s = size($l)
285- let $acc0 = $Tuple2(0, 0)
286- func $f0_1 ($a,$i) = if (($i >= $s))
287- then $a
288- else findBest($a, $l[$i])
289-
290- func $f0_2 ($a,$i) = if (($i >= $s))
291- then $a
292- else throw("List size exceeds 10")
293-
294- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
295- }
296-
297-
298-func updateStatusData (oldData,isValid,newWinOpt,newTotalVotes) = makeString(["%b%d%d%d%b%d%b", toString(isValid), toString(newWinOpt._1), toString(newWinOpt._2), toString(newTotalVotes), oldData[govStatusIdxScApplied], oldData[govStatusIdxScTime], oldData[govStatusIdxIsCanceled]], SEP)
299-
300-
301-func statusApplyScript (oldData) = makeString(["%b%d%d%d%b%d%b", oldData[govStatusIdxIsValid], oldData[govStatusIdxWinOpt], oldData[govStatusIdxWinVotes], oldData[govStatusIdxTotalVotes], "true", oldData[govStatusIdxScTime], oldData[govStatusIdxIsCanceled]], SEP)
302-
303-
30415 @Callable(i)
305-func castVote (proposalId,choice) = {
306- let userAddressStr = toString(i.caller)
307- let dynamicData = split(getStringOrFail(this, keyProposalStatusDataById(proposalId)), SEP)
308- if ((dynamicData[govStatusIdxIsCanceled] == "true"))
309- then throw("Voting is canceled by team")
310- else {
311- let propData = split(getStringOrFail(this, keyProposalDataById(proposalId)), SEP)
312- let start = parseIntValue(propData[govIdxStart])
313- let end = parseIntValue(propData[govIdxEnd])
314- let now = lastBlock.timestamp
315- if ((start > now))
316- then throw("Voting not started yet")
317- else if ((now >= end))
318- then throw("Voting already finished")
319- else {
320- let availableOptions = split(propData[govIdxOptions], LISTSEP)
321- let numOptions = size(availableOptions)
322- if ((1 >= numOptions))
323- then throw("Too few choices to vote")
324- else if ((choice >= numOptions))
325- then throw(("Unknown choice! Must be 0.." + toString((numOptions - 1))))
326- else {
327- let gnsbtData = asAnyList(invoke(gnsbtControllerContract, "gnsbtInfoSYSREADONLY", [userAddressStr, 0, 0], nil))
328- let gnsbtAmt = asInt(gnsbtData[0])
329- if ((0 >= gnsbtAmt))
330- then throw("no gnsbt to vote")
331- else {
332- let gnsbtTotal = asInt(gnsbtData[1])
333- let oldChoice = getInteger(keyProposalChoiceByIdAndUser(proposalId, userAddressStr))
334- let oldUserVotes = if (!(isDefined(oldChoice)))
335- then 0
336- else getIntOrElse(keyProposalVotesByIdAndUser(proposalId, userAddressStr), 0)
337- let oldTotalByOldChoice = if (isDefined(oldChoice))
338- then getIntOrElse(keyProposalVotesByIdAndOption(proposalId, value(oldChoice)), 0)
339- else 0
340- let oldTotalByNewChoice = getIntOrElse(keyProposalVotesByIdAndOption(proposalId, choice), 0)
341- let oldTotal = parseIntValue(dynamicData[govStatusIdxTotalVotes])
342- let newTotalByOldChoice = if (!(isDefined(oldChoice)))
343- then 0
344- else ((oldTotalByOldChoice - oldUserVotes) + (if ((value(oldChoice) == choice))
345- then gnsbtAmt
346- else 0))
347- let newTotalByNewChoice = if (if (isDefined(oldChoice))
348- then (value(oldChoice) == choice)
349- else false)
350- then newTotalByOldChoice
351- else (oldTotalByNewChoice + gnsbtAmt)
352- let newTotal = ((oldTotal - oldUserVotes) + gnsbtAmt)
353- let isQuorumReached = (newTotal > parseIntValue(propData[govIdxQuorum]))
354- let numVotersByProposalId = getIntOrElse(keyNumUniqueVotersByProposalId(proposalId), 0)
355- let oldAverUniqueVoters6 = getIntOrElse(keyStatsAverUniqueVoters(), 0)
356- let numProposals = getIntegerValue(keyLastProposalId())
357- let uniqueDiff = if ((oldUserVotes == 0))
358- then 1
359- else 0
360- let newAverUniqueVoters6 = (oldAverUniqueVoters6 + fraction(uniqueDiff, MULT6, numProposals))
361- let oldAverGnsbt = getIntOrElse(keyStatsAverGnsbtVoted(), 0)
362- let newAverGnsbt = (oldAverGnsbt + ((gnsbtAmt - oldUserVotes) / numProposals))
363- let isPrevOptional = if (!(isDefined(oldChoice)))
364- then true
365- else (value(oldChoice) == choice)
366- let optionalTotalOld = if (isPrevOptional)
367- then nil
368- else [IntegerEntry(keyProposalVotesByIdAndOption(proposalId, value(oldChoice)), newTotalByOldChoice)]
369- let winOpt = calcWinOption(proposalId, availableOptions, isPrevOptional, oldChoice, newTotalByOldChoice, choice, newTotalByNewChoice)
370- $Tuple2(([IntegerEntry(keyProposalChoiceByIdAndUser(proposalId, userAddressStr), choice), IntegerEntry(keyProposalVotesByIdAndUser(proposalId, userAddressStr), gnsbtAmt), IntegerEntry(keyProposalVotesByIdAndOption(proposalId, choice), newTotalByNewChoice), IntegerEntry(keyNumUniqueVotersByProposalId(proposalId), (numVotersByProposalId + uniqueDiff)), IntegerEntry(keyStatsAverUniqueVoters(), newAverUniqueVoters6), IntegerEntry(keyStatsAverGnsbtVoted(), newAverGnsbt), StringEntry(keyProposalStatusDataById(proposalId), updateStatusData(dynamicData, isQuorumReached, winOpt, newTotal))] ++ optionalTotalOld), unit)
371- }
372- }
373- }
374- }
375- }
376-
377-
378-
379-@Callable(i)
380-func initiateIdeaVoting (forumLink,title,votingStartTime,votingEndTime,optionsList) = if ((size(i.payments) != 1))
381- then throw("Exactly one payment required")
382- else initiateVoting(value(i.payments[0]), toBase58String(i.transactionId), "IDEA", toString(i.caller), forumLink, title, votingStartTime, votingEndTime, "PENDING", nil, optionsList)
383-
384-
385-
386-@Callable(i)
387-func initiateUpdateVoting (forumLink,title,votingStartTime,votingEndTime,txList) = if ((size(i.payments) != 1))
388- then throw("Exactly one payment required")
389- else if ((1 > size(txList)))
390- then throw("Transactions list is empty")
391- else initiateVoting(value(i.payments[0]), toBase58String(i.transactionId), "UPDATE", toString(i.caller), forumLink, title, votingStartTime, votingEndTime, "PENDING", txList, ["NO", "YES"])
392-
393-
394-
395-@Callable(i)
396-func cancelVoting (proposalId) = if ((i.caller != this))
397- then throw("not authorized")
398- else {
399- let currentData = getStringOrFail(this, keyProposalStatusDataById(proposalId))
400- let updatedData = ((take(currentData, value(lastIndexOf(currentData, SEP))) + SEP) + "true")
401- $Tuple2([StringEntry(keyProposalStatusDataById(proposalId), updatedData)], unit)
402- }
403-
404-
405-
406-@Callable(i)
407-func applyUpdate (proposalId) = {
408- let propData = split(getStringOrFail(this, keyProposalDataById(proposalId)), SEP)
409- let end = parseIntValue(propData[govIdxEnd])
410- let now = lastBlock.timestamp
411- if ((end > now))
412- then throw("Voting is not finished yet")
413- else if (("UPDATE" != propData[govIdxType]))
414- then throw("Only UPDATE type can be applied")
415- else {
416- let dynamicData = split(getStringOrFail(this, keyProposalStatusDataById(proposalId)), SEP)
417- if ((dynamicData[govStatusIdxIsCanceled] == "true"))
418- then throw("Voting is canceled")
419- else if ((dynamicData[govStatusIdxIsValid] != "true"))
420- then throw("Voting status invalid")
421- else if ((dynamicData[govStatusIdxWinOpt] != "1"))
422- then throw("Winner is 'NO' - nothing to apply")
423- else if ((dynamicData[govStatusIdxScApplied] == "true"))
424- then throw("Scripts are already applied")
425- else {
426- let scriptTime = parseIntValue(dynamicData[govStatusIdxScTime])
427- if (((now - PASTMARGIN) > scriptTime))
428- then throw((("Scripts timestamp=" + toString(scriptTime)) + " is too far in the past, max 2 hrs allowed"))
429- else if ((scriptTime > (now + FUTUREMARGIN)))
430- then throw((("Scripts timestamp=" + toString(scriptTime)) + " is too far in the future, max 1.5 hrs allowed"))
431- else {
432- let inProgressId = getIntOrElse(keyApplyInProgress(), -1)
433- if ((inProgressId != -1))
434- then throw((("proposalId=" + toString(inProgressId)) + " is already being applied. Finish it first!"))
435- else {
436- let shutdown = invoke(controlContract, "callEmergencyShutdown", ["Applying Governance UPDATE"], nil)
437- if ((shutdown == shutdown))
438- then $Tuple2([IntegerEntry(keyApplyInProgress(), proposalId)], unit)
439- else throw("Strict value is not equal to itself.")
440- }
441- }
442- }
443- }
444- }
445-
446-
447-
448-@Callable(i)
449-func finishApply () = {
450- let proposalId = valueOrErrorMessage(getInteger(keyApplyInProgress()), "No apply in progress, nothing to finish")
451- let propData = split(getStringOrFail(this, keyProposalDataById(proposalId)), SEP)
452- let txList = split(propData[govIdxTxIds], LISTSEP)
453- let dynamicData = split(getStringOrFail(this, keyProposalStatusDataById(proposalId)), SEP)
454- if ((dynamicData[govStatusIdxScApplied] == "true"))
455- then throw("Scripts are already applied")
456- else {
457- func checker (acc,tx) = if (!(isDefined(transactionHeightById(fromBase58String(tx)))))
458- then throw(("NOT applied txId: " + tx))
459- else unit
460-
461- let ignored = {
462- let $l = txList
463- let $s = size($l)
464- let $acc0 = unit
465- func $f0_1 ($a,$i) = if (($i >= $s))
466- then $a
467- else checker($a, $l[$i])
468-
469- func $f0_2 ($a,$i) = if (($i >= $s))
470- then $a
471- else throw("List size exceeds 20")
472-
473- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
474- }
475- $Tuple2([DeleteEntry(keyApplyInProgress()), StringEntry(keyProposalStatusDataById(proposalId), statusApplyScript(dynamicData))], ignored)
476- }
16+func walletInfoREADONLY (userAddressStrOpt) = {
17+ let addr = addressFromString(userAddressStrOpt)
18+ let balance = if (isDefined(addr))
19+ then wavesBalance(value(addr))
20+ else BalanceDetails(0, 0, 0, 0)
21+ let usdnBalance = if (isDefined(addr))
22+ then assetBalance(value(addr), usdnAssetId)
23+ else 0
24+ $Tuple2(nil, makeString(["%d%d%d%d%d", toString(balance.regular), toString(balance.available), toString(balance.generating), toString(balance.effective), toString(usdnBalance)], "_"))
47725 }
47826
47927

github/deemru/w8io/026f985 
49.49 ms