tx · CcXRbcLQXjKzZViGJQ7CfPvJiqnfTGtMWcoY7fY5KSCY 3PA2w9i9GnbKR3HB7XTmwf3DnaFBFcDiP12: -0.01400000 Waves 2020.02.03 17:20 [1913641] smart account 3PA2w9i9GnbKR3HB7XTmwf3DnaFBFcDiP12 > SELF 0.00000000 Waves
{ "type": 13, "id": "CcXRbcLQXjKzZViGJQ7CfPvJiqnfTGtMWcoY7fY5KSCY", "fee": 1400000, "feeAssetId": null, "timestamp": 1580739373314, "version": 1, "sender": "3PA2w9i9GnbKR3HB7XTmwf3DnaFBFcDiP12", "senderPublicKey": "5G9pgymdyBYGnWF3oahQXQNPnVaWEthMkeFRUzHjZ7mX", "proofs": [ "rVmvPGDgHzbUgby1HsCniWmNVwHKexF6FAmgGaUSXNeCGqNKj6M7yVxS3kjwZL2UACP5inXqEr1zTWNgx9p8Me7", "2JSirMb8KVnJBoLsQzP7c25cywxNWZZKuRA8a3zjLkkQNRNp5dLa8TLUt78vSJuk83WJHQNYadPG8J3hL2k52Rp2", "677ZDMcHpNypPzzDV1G5JmLgco6hVmhe1mL4iXddVvwSDejfgiAf1WXGyCF7zAiMGMQgd39yBLktq9soBggppWcW" ], "script": "base64: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", "chainId": 87, "height": 1913641, "spentComplexity": 0 } View: original | compacted Prev: 77GzLmgJoXoBthBdKB42FqQAzrQCu1kS6Q49CgdYkdfX Next: J5riRfkd9W8cDjN8nL4GXqvAQV6TGAiWiWRyuvoyJVtD Diff:
Old | New | Differences | |
---|---|---|---|
4 | 4 | let assetName = "RusCoin" | |
5 | 5 | ||
6 | 6 | let decMult = 100000 | |
7 | + | ||
8 | + | let minConf = (960 * 1000) | |
7 | 9 | ||
8 | 10 | let lockPeriod = (2629746 * 1000) | |
9 | 11 | ||
23 | 25 | ||
24 | 26 | let frameCloseTime = (frameOpenTime + lockPeriod) | |
25 | 27 | ||
26 | - | let payoutOpenTime = ( | |
28 | + | let payoutOpenTime = (frameOpenTime + ((30 * 86400) * 1000)) | |
27 | 29 | ||
28 | 30 | func toFloatString (num,mult) = { | |
29 | 31 | let th = "," | |
55 | 57 | let q1 = (r2 / 1000) | |
56 | 58 | let r1 = (r2 % 1000) | |
57 | 59 | let is = { | |
58 | - | let $ | |
59 | - | let $ | |
60 | - | let $ | |
61 | - | if (($ | |
62 | - | then $ | |
60 | + | let $list33433399 = [q6, q5, q4, q3, q2, q1, r1] | |
61 | + | let $size33433399 = size($list33433399) | |
62 | + | let $acc033433399 = "" | |
63 | + | if (($size33433399 == 0)) | |
64 | + | then $acc033433399 | |
63 | 65 | else { | |
64 | - | let $ | |
65 | - | if (($ | |
66 | - | then $ | |
66 | + | let $acc133433399 = joinThousands($acc033433399, $list33433399[0]) | |
67 | + | if (($size33433399 == 1)) | |
68 | + | then $acc133433399 | |
67 | 69 | else { | |
68 | - | let $ | |
69 | - | if (($ | |
70 | - | then $ | |
70 | + | let $acc233433399 = joinThousands($acc133433399, $list33433399[1]) | |
71 | + | if (($size33433399 == 2)) | |
72 | + | then $acc233433399 | |
71 | 73 | else { | |
72 | - | let $ | |
73 | - | if (($ | |
74 | - | then $ | |
74 | + | let $acc333433399 = joinThousands($acc233433399, $list33433399[2]) | |
75 | + | if (($size33433399 == 3)) | |
76 | + | then $acc333433399 | |
75 | 77 | else { | |
76 | - | let $ | |
77 | - | if (($ | |
78 | - | then $ | |
78 | + | let $acc433433399 = joinThousands($acc333433399, $list33433399[3]) | |
79 | + | if (($size33433399 == 4)) | |
80 | + | then $acc433433399 | |
79 | 81 | else { | |
80 | - | let $ | |
81 | - | if (($ | |
82 | - | then $ | |
82 | + | let $acc533433399 = joinThousands($acc433433399, $list33433399[4]) | |
83 | + | if (($size33433399 == 5)) | |
84 | + | then $acc533433399 | |
83 | 85 | else { | |
84 | - | let $ | |
85 | - | if (($ | |
86 | - | then $ | |
86 | + | let $acc633433399 = joinThousands($acc533433399, $list33433399[5]) | |
87 | + | if (($size33433399 == 6)) | |
88 | + | then $acc633433399 | |
87 | 89 | else { | |
88 | - | let $ | |
89 | - | if (($ | |
90 | - | then $ | |
90 | + | let $acc733433399 = joinThousands($acc633433399, $list33433399[6]) | |
91 | + | if (($size33433399 == 7)) | |
92 | + | then $acc733433399 | |
91 | 93 | else { | |
92 | - | let $ | |
94 | + | let $acc833433399 = joinThousands($acc733433399, $list33433399[7]) | |
93 | 95 | throw("List size exceed 7") | |
94 | 96 | } | |
95 | 97 | } | |
261 | 263 | let dapp = toBase58String(this.bytes) | |
262 | 264 | let sumTotal = getIntegerValue(this, (dapp + "_balance")) | |
263 | 265 | let minStake = getIntegerValue(this, (dapp + "_starttime")) | |
266 | + | let dappTime = getIntegerValue(this, (dapp + "_updatetime")) | |
264 | 267 | let client = toBase58String(inv.caller.bytes) | |
265 | 268 | let updateTime = match getInteger(this, (client + "_updatetime")) { | |
266 | 269 | case x: Int => | |
284 | 287 | 0 | |
285 | 288 | } | |
286 | 289 | let expiration = (updateTime + lockPeriod) | |
290 | + | let lastUpdate = if ((dappTime > updateTime)) | |
291 | + | then dappTime | |
292 | + | else updateTime | |
287 | 293 | let amount = if ((RSCx100000 > 0)) | |
288 | 294 | then RSCx100000 | |
289 | 295 | else balance | |
300 | 306 | then throw((((((("It's impossible to withdraw more than the balance of " + toString(balance)) + " (") + toFloatString(balance, decMult)) + " ") + assetName) + ").")) | |
301 | 307 | else if ((minBalance > amount)) | |
302 | 308 | then throw((((((("The minimum withdrawal amount is " + toString(minBalance)) + " (") + toFloatString(minBalance, decMult)) + " ") + assetName) + ").")) | |
303 | - | else { | |
304 | - | let startTime = if (isOlder) | |
305 | - | then frameOpenTime | |
306 | - | else match getInteger(this, (client + "_starttime")) { | |
307 | - | case x: Int => | |
308 | - | x | |
309 | - | case _ => | |
310 | - | 0 | |
309 | + | else if (((lastUpdate + minConf) > lastBlockTime)) | |
310 | + | then throw((((("Please wait " + toString((minConf / 60000))) + " confirmations until ") + drop(toDateTimeString((lastUpdate + minConf)), 11)) + "...")) | |
311 | + | else { | |
312 | + | let startTime = if (isOlder) | |
313 | + | then frameOpenTime | |
314 | + | else match getInteger(this, (client + "_starttime")) { | |
315 | + | case x: Int => | |
316 | + | x | |
317 | + | case _ => | |
318 | + | 0 | |
319 | + | } | |
320 | + | let newStartTime = if ((startTime > lastBlockTime)) | |
321 | + | then frameCloseTime | |
322 | + | else if ((minBalance > newBalance)) | |
323 | + | then startTime | |
324 | + | else { | |
325 | + | let balWeight = (balance / minBalance) | |
326 | + | let sumWeight = (newBalance / minBalance) | |
327 | + | (fraction(startTime, balWeight, sumWeight) + fraction(lastBlockTime, (sumWeight - balWeight), sumWeight)) | |
328 | + | } | |
329 | + | if ((newBalance >= minBalance)) | |
330 | + | then ScriptResult(WriteSet([DataEntry((dapp + "_balance"), (sumTotal - amount)), DataEntry((client + "_balance"), newBalance), DataEntry((client + "_starttime"), newStartTime), DataEntry((client + "_updatetime"), lastBlockTime)]), TransferSet([ScriptTransfer(inv.caller, amount, myAssetId)])) | |
331 | + | else ScriptResult(WriteSet([DataEntry((dapp + "_balance"), (sumTotal - balance)), DataEntry((client + "_starttime"), newStartTime), DataEntry((client + "_status"), false), DataEntry((client + "_updatetime"), lastBlockTime)]), TransferSet([ScriptTransfer(inv.caller, balance, myAssetId)])) | |
311 | 332 | } | |
312 | - | let newStartTime = if ((startTime > lastBlockTime)) | |
313 | - | then frameCloseTime | |
314 | - | else if ((minBalance > newBalance)) | |
315 | - | then startTime | |
316 | - | else { | |
317 | - | let balWeight = (balance / minBalance) | |
318 | - | let sumWeight = (newBalance / minBalance) | |
319 | - | (fraction(startTime, balWeight, sumWeight) + fraction(lastBlockTime, (sumWeight - balWeight), sumWeight)) | |
320 | - | } | |
321 | - | if ((newBalance >= minBalance)) | |
322 | - | then ScriptResult(WriteSet([DataEntry((dapp + "_balance"), (sumTotal - amount)), DataEntry((client + "_balance"), newBalance), DataEntry((client + "_starttime"), newStartTime), DataEntry((client + "_updatetime"), lastBlockTime)]), TransferSet([ScriptTransfer(inv.caller, amount, myAssetId)])) | |
323 | - | else ScriptResult(WriteSet([DataEntry((dapp + "_balance"), (sumTotal - balance)), DataEntry((client + "_starttime"), newStartTime), DataEntry((client + "_status"), false), DataEntry((client + "_updatetime"), lastBlockTime)]), TransferSet([ScriptTransfer(inv.caller, balance, myAssetId)])) | |
324 | - | } | |
325 | 333 | } | |
326 | 334 | ||
327 | 335 | ||
328 | 336 | ||
329 | 337 | @Callable(inv) | |
330 | - | func | |
338 | + | func setMinStake (RSCx100000) = if (if ((inv.callerPublicKey != ownerPubKey)) | |
331 | 339 | then (inv.callerPublicKey != managerPubKey) | |
332 | 340 | else false) | |
333 | - | then throw("Only the administrator can send rewards to customers!") | |
341 | + | then throw("Only an administrator can set and modify minStake!") | |
342 | + | else if (isDefined(inv.payment)) | |
343 | + | then throw("Please do not attach payment when setting up minStake.") | |
344 | + | else { | |
345 | + | let dapp = toBase58String(this.bytes) | |
346 | + | if (isDefined(getString(this, (dapp + "_address")))) | |
347 | + | then WriteSet([DataEntry((dapp + "_starttime"), RSCx100000), DataEntry((dapp + "_updatetime"), lastBlockTime)]) | |
348 | + | else WriteSet([DataEntry((dapp + "_address"), dapp), DataEntry((dapp + "_balance"), 0), DataEntry((dapp + "_starttime"), RSCx100000), DataEntry((dapp + "_status"), false), DataEntry((dapp + "_updatetime"), lastBlockTime)]) | |
349 | + | } | |
350 | + | ||
351 | + | ||
352 | + | ||
353 | + | @Callable(inv) | |
354 | + | func sendRewards (addr0,amount0,addr1,amount1,addr2,amount2,addr3,amount3,addr4,amount4,addr5,amount5,addr6,amount6,addr7,amount7,addr8,amount8,addr9,amount9) = if (if ((inv.callerPublicKey != ownerPubKey)) | |
355 | + | then (inv.callerPublicKey != managerPubKey) | |
356 | + | else false) | |
357 | + | then throw("Only administrator can send rewards to customers!") | |
334 | 358 | else if ((payoutOpenTime > lastBlockTime)) | |
335 | 359 | then throw((("The time to send rewards has not yet come! Beginning at " + toDateTimeString(payoutOpenTime)) + ". Please wait...")) | |
336 | 360 | else { | |
351 | 375 | else if ((rewards > effBalance)) | |
352 | 376 | then throw((((("Insufficient effective balance! The required amount is " + toFloatString((rewards - effBalance), decMult)) + " ") + assetName) + ".")) | |
353 | 377 | else { | |
354 | - | let data9 = if (if (( | |
378 | + | let data9 = if (if ((addr9 == "-")) | |
355 | 379 | then (amount9 == 0) | |
356 | 380 | else false) | |
357 | 381 | then nil | |
358 | - | else if (!(getBooleanValue(this, ( | |
359 | - | then throw("The status of | |
382 | + | else if (!(getBooleanValue(this, (addr9 + "_status")))) | |
383 | + | then throw("The status of address #9 is inactive!") | |
360 | 384 | else if ((0 >= amount9)) | |
361 | 385 | then throw("Zero or negative amounts are not allowed.") | |
362 | 386 | else { | |
363 | - | let balance9 = getIntegerValue(this, (client9 + "_balance")) | |
364 | - | [DataEntry((client9 + "_balance"), (balance9 + amount9)), DataEntry((client9 + "_starttime"), frameCloseTime)] | |
387 | + | let newBalance = (getIntegerValue(this, (addr9 + "_balance")) + amount9) | |
388 | + | if ((newBalance > maxBalance)) | |
389 | + | then throw("Deposit of address #9 will be overfilled!") | |
390 | + | else [DataEntry((addr9 + "_balance"), newBalance), DataEntry((addr9 + "_starttime"), frameCloseTime)] | |
365 | 391 | } | |
366 | - | let data8 = if (if (( | |
392 | + | let data8 = if (if ((addr8 == "-")) | |
367 | 393 | then (amount8 == 0) | |
368 | 394 | else false) | |
369 | 395 | then data9 | |
370 | - | else if (!(getBooleanValue(this, ( | |
371 | - | then throw("The status of | |
396 | + | else if (!(getBooleanValue(this, (addr8 + "_status")))) | |
397 | + | then throw("The status of address #8 is inactive!") | |
372 | 398 | else if ((0 >= amount8)) | |
373 | 399 | then throw("Zero or negative amounts are not allowed.") | |
374 | 400 | else { | |
375 | - | let balance8 = getIntegerValue(this, (client8 + "_balance")) | |
376 | - | [DataEntry((client8 + "_balance"), (balance8 + amount8)), DataEntry((client8 + "_starttime"), frameCloseTime)] :: data9 | |
401 | + | let newBalance = (getIntegerValue(this, (addr8 + "_balance")) + amount8) | |
402 | + | if ((newBalance > maxBalance)) | |
403 | + | then throw("Deposit of address #8 will be overfilled!") | |
404 | + | else [DataEntry((addr8 + "_balance"), newBalance), DataEntry((addr8 + "_starttime"), frameCloseTime)] :: data9 | |
377 | 405 | } | |
378 | - | let data7 = if (if (( | |
406 | + | let data7 = if (if ((addr7 == "-")) | |
379 | 407 | then (amount7 == 0) | |
380 | 408 | else false) | |
381 | 409 | then data8 | |
382 | - | else if (!(getBooleanValue(this, ( | |
383 | - | then throw("The status of | |
410 | + | else if (!(getBooleanValue(this, (addr7 + "_status")))) | |
411 | + | then throw("The status of address #7 is inactive!") | |
384 | 412 | else if ((0 >= amount7)) | |
385 | 413 | then throw("Zero or negative amounts are not allowed.") | |
386 | 414 | else { | |
387 | - | let balance7 = getIntegerValue(this, (client7 + "_balance")) | |
388 | - | [DataEntry((client7 + "_balance"), (balance7 + amount7)), DataEntry((client7 + "_starttime"), frameCloseTime)] :: data8 | |
415 | + | let newBalance = (getIntegerValue(this, (addr7 + "_balance")) + amount7) | |
416 | + | if ((newBalance > maxBalance)) | |
417 | + | then throw("Deposit of address #7 will be overfilled!") | |
418 | + | else [DataEntry((addr7 + "_balance"), newBalance), DataEntry((addr7 + "_starttime"), frameCloseTime)] :: data8 | |
389 | 419 | } | |
390 | - | let data6 = if (if (( | |
420 | + | let data6 = if (if ((addr6 == "-")) | |
391 | 421 | then (amount6 == 0) | |
392 | 422 | else false) | |
393 | 423 | then data7 | |
394 | - | else if (!(getBooleanValue(this, ( | |
395 | - | then throw("The status of | |
424 | + | else if (!(getBooleanValue(this, (addr6 + "_status")))) | |
425 | + | then throw("The status of address #6 is inactive!") | |
396 | 426 | else if ((0 >= amount6)) | |
397 | 427 | then throw("Zero or negative amounts are not allowed.") | |
398 | 428 | else { | |
399 | - | let balance6 = getIntegerValue(this, (client6 + "_balance")) | |
400 | - | [DataEntry((client6 + "_balance"), (balance6 + amount6)), DataEntry((client6 + "_starttime"), frameCloseTime)] :: data7 | |
429 | + | let newBalance = (getIntegerValue(this, (addr6 + "_balance")) + amount6) | |
430 | + | if ((newBalance > maxBalance)) | |
431 | + | then throw("Deposit of address #6 will be overfilled!") | |
432 | + | else [DataEntry((addr6 + "_balance"), newBalance), DataEntry((addr6 + "_starttime"), frameCloseTime)] :: data7 | |
401 | 433 | } | |
402 | - | let data5 = if (if (( | |
434 | + | let data5 = if (if ((addr5 == "-")) | |
403 | 435 | then (amount5 == 0) | |
404 | 436 | else false) | |
405 | 437 | then data6 | |
406 | - | else if (!(getBooleanValue(this, ( | |
407 | - | then throw("The status of | |
438 | + | else if (!(getBooleanValue(this, (addr5 + "_status")))) | |
439 | + | then throw("The status of address #5 is inactive!") | |
408 | 440 | else if ((0 >= amount5)) | |
409 | 441 | then throw("Zero or negative amounts are not allowed.") | |
410 | 442 | else { | |
411 | - | let balance5 = getIntegerValue(this, (client5 + "_balance")) | |
412 | - | [DataEntry((client5 + "_balance"), (balance5 + amount5)), DataEntry((client5 + "_starttime"), frameCloseTime)] :: data6 | |
443 | + | let newBalance = (getIntegerValue(this, (addr5 + "_balance")) + amount5) | |
444 | + | if ((newBalance > maxBalance)) | |
445 | + | then throw("Deposit of address #5 will be overfilled!") | |
446 | + | else [DataEntry((addr5 + "_balance"), newBalance), DataEntry((addr5 + "_starttime"), frameCloseTime)] :: data6 | |
413 | 447 | } | |
414 | - | let data4 = if (if (( | |
448 | + | let data4 = if (if ((addr4 == "-")) | |
415 | 449 | then (amount4 == 0) | |
416 | 450 | else false) | |
417 | 451 | then data5 | |
418 | - | else if (!(getBooleanValue(this, ( | |
419 | - | then throw("The status of | |
452 | + | else if (!(getBooleanValue(this, (addr4 + "_status")))) | |
453 | + | then throw("The status of address #4 is inactive!") | |
420 | 454 | else if ((0 >= amount4)) | |
421 | 455 | then throw("Zero or negative amounts are not allowed.") | |
422 | 456 | else { | |
423 | - | let balance4 = getIntegerValue(this, (client4 + "_balance")) | |
424 | - | [DataEntry((client4 + "_balance"), (balance4 + amount4)), DataEntry((client4 + "_starttime"), frameCloseTime)] :: data5 | |
457 | + | let newBalance = (getIntegerValue(this, (addr4 + "_balance")) + amount4) | |
458 | + | if ((newBalance > maxBalance)) | |
459 | + | then throw("Deposit of address #4 will be overfilled!") | |
460 | + | else [DataEntry((addr4 + "_balance"), newBalance), DataEntry((addr4 + "_starttime"), frameCloseTime)] :: data5 | |
425 | 461 | } | |
426 | - | let data3 = if (if (( | |
462 | + | let data3 = if (if ((addr3 == "-")) | |
427 | 463 | then (amount3 == 0) | |
428 | 464 | else false) | |
429 | 465 | then data4 | |
430 | - | else if (!(getBooleanValue(this, ( | |
431 | - | then throw("The status of | |
466 | + | else if (!(getBooleanValue(this, (addr3 + "_status")))) | |
467 | + | then throw("The status of address #3 is inactive!") | |
432 | 468 | else if ((0 >= amount3)) | |
433 | 469 | then throw("Zero or negative amounts are not allowed.") | |
434 | 470 | else { | |
435 | - | let balance3 = getIntegerValue(this, (client3 + "_balance")) | |
436 | - | [DataEntry((client3 + "_balance"), (balance3 + amount3)), DataEntry((client3 + "_starttime"), frameCloseTime)] :: data4 | |
471 | + | let newBalance = (getIntegerValue(this, (addr3 + "_balance")) + amount3) | |
472 | + | if ((newBalance > maxBalance)) | |
473 | + | then throw("Deposit of address #3 will be overfilled!") | |
474 | + | else [DataEntry((addr3 + "_balance"), newBalance), DataEntry((addr3 + "_starttime"), frameCloseTime)] :: data4 | |
437 | 475 | } | |
438 | - | let data2 = if (if (( | |
476 | + | let data2 = if (if ((addr2 == "-")) | |
439 | 477 | then (amount2 == 0) | |
440 | 478 | else false) | |
441 | 479 | then data3 | |
442 | - | else if (!(getBooleanValue(this, ( | |
443 | - | then throw("The status of | |
480 | + | else if (!(getBooleanValue(this, (addr2 + "_status")))) | |
481 | + | then throw("The status of address #2 is inactive!") | |
444 | 482 | else if ((0 >= amount2)) | |
445 | 483 | then throw("Zero or negative amounts are not allowed.") | |
446 | 484 | else { | |
447 | - | let balance2 = getIntegerValue(this, (client2 + "_balance")) | |
448 | - | [DataEntry((client2 + "_balance"), (balance2 + amount2)), DataEntry((client2 + "_starttime"), frameCloseTime)] :: data3 | |
485 | + | let newBalance = (getIntegerValue(this, (addr2 + "_balance")) + amount2) | |
486 | + | if ((newBalance > maxBalance)) | |
487 | + | then throw("Deposit of address #2 will be overfilled!") | |
488 | + | else [DataEntry((addr2 + "_balance"), newBalance), DataEntry((addr2 + "_starttime"), frameCloseTime)] :: data3 | |
449 | 489 | } | |
450 | - | let data1 = if (if (( | |
490 | + | let data1 = if (if ((addr1 == "-")) | |
451 | 491 | then (amount1 == 0) | |
452 | 492 | else false) | |
453 | 493 | then data2 | |
454 | - | else if (!(getBooleanValue(this, ( | |
455 | - | then throw("The status of | |
494 | + | else if (!(getBooleanValue(this, (addr1 + "_status")))) | |
495 | + | then throw("The status of address #1 is inactive!") | |
456 | 496 | else if ((0 >= amount1)) | |
457 | 497 | then throw("Zero or negative amounts are not allowed.") | |
458 | 498 | else { | |
459 | - | let balance1 = getIntegerValue(this, (client1 + "_balance")) | |
460 | - | [DataEntry((client1 + "_balance"), (balance1 + amount1)), DataEntry((client1 + "_starttime"), frameCloseTime)] :: data2 | |
499 | + | let newBalance = (getIntegerValue(this, (addr1 + "_balance")) + amount1) | |
500 | + | if ((newBalance > maxBalance)) | |
501 | + | then throw("Deposit of address #1 will be overfilled!") | |
502 | + | else [DataEntry((addr1 + "_balance"), newBalance), DataEntry((addr1 + "_starttime"), frameCloseTime)] :: data2 | |
461 | 503 | } | |
462 | - | let data0 = if (if (( | |
504 | + | let data0 = if (if ((addr0 == "-")) | |
463 | 505 | then (amount0 == 0) | |
464 | 506 | else false) | |
465 | 507 | then data1 | |
466 | - | else if (!(getBooleanValue(this, ( | |
467 | - | then throw("The status of | |
508 | + | else if (!(getBooleanValue(this, (addr0 + "_status")))) | |
509 | + | then throw("The status of address #0 is inactive!") | |
468 | 510 | else if ((0 >= amount0)) | |
469 | 511 | then throw("Zero or negative amounts are not allowed.") | |
470 | 512 | else { | |
471 | - | let balance0 = getIntegerValue(this, (client0 + "_balance")) | |
472 | - | [DataEntry((client0 + "_balance"), (balance0 + amount0)), DataEntry((client0 + "_starttime"), frameCloseTime)] :: data1 | |
513 | + | let newBalance = (getIntegerValue(this, (addr0 + "_balance")) + amount0) | |
514 | + | if ((newBalance > maxBalance)) | |
515 | + | then throw("Deposit of address #0 will be overfilled!") | |
516 | + | else [DataEntry((addr0 + "_balance"), newBalance), DataEntry((addr0 + "_starttime"), frameCloseTime)] :: data1 | |
473 | 517 | } | |
474 | - | WriteSet(DataEntry((dapp + "_balance"), (sumTotal + rewards)) :: data0) | |
518 | + | WriteSet([DataEntry((dapp + "_balance"), (sumTotal + rewards)), DataEntry((dapp + "_updatetime"), lastBlockTime)] :: data0) | |
475 | 519 | } | |
476 | - | } | |
477 | - | ||
478 | - | ||
479 | - | ||
480 | - | @Callable(inv) | |
481 | - | func setMinStake (amount) = if (if ((inv.callerPublicKey != ownerPubKey)) | |
482 | - | then (inv.callerPublicKey != managerPubKey) | |
483 | - | else false) | |
484 | - | then throw("Only the administrator can set and modify minStake!") | |
485 | - | else if (isDefined(inv.payment)) | |
486 | - | then throw("Please do not attach payment when setting up minStake.") | |
487 | - | else { | |
488 | - | let dapp = toBase58String(this.bytes) | |
489 | - | if (isDefined(getString(this, (dapp + "_address")))) | |
490 | - | then WriteSet([DataEntry((dapp + "_starttime"), amount), DataEntry((dapp + "_updatetime"), lastBlockTime)]) | |
491 | - | else WriteSet([DataEntry((dapp + "_address"), dapp), DataEntry((dapp + "_balance"), 0), DataEntry((dapp + "_starttime"), amount), DataEntry((dapp + "_status"), false), DataEntry((dapp + "_updatetime"), lastBlockTime)]) | |
492 | 520 | } | |
493 | 521 | ||
494 | 522 | ||
495 | 523 | @Verifier(tx) | |
496 | 524 | func verify () = match tx { | |
525 | + | case a: CreateAliasTransaction => | |
526 | + | sigVerify(a.bodyBytes, a.proofs[0], a.senderPublicKey) | |
497 | 527 | case t: TransferTransaction => | |
498 | - | | |
528 | + | if (if ((t.assetId != myAssetId)) | |
499 | 529 | then (t.feeAssetId != myAssetId) | |
500 | 530 | else false) | |
501 | - | then sigVerify(t.bodyBytes, t.proofs[2], ownerPubKey) | |
502 | - | else false) | |
503 | - | then sigVerify(t.bodyBytes, t.proofs[1], managerPubKey) | |
531 | + | then sigVerify(t.bodyBytes, t.proofs[0], t.senderPublicKey) | |
504 | 532 | else false | |
505 | 533 | case s: SetScriptTransaction => | |
506 | 534 | if (sigVerify(s.bodyBytes, s.proofs[2], ownerPubKey)) |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 3 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let assetName = "RusCoin" | |
5 | 5 | ||
6 | 6 | let decMult = 100000 | |
7 | + | ||
8 | + | let minConf = (960 * 1000) | |
7 | 9 | ||
8 | 10 | let lockPeriod = (2629746 * 1000) | |
9 | 11 | ||
10 | 12 | let minBalance = (decMult / 100) | |
11 | 13 | ||
12 | 14 | let maxBalance = (10000 * decMult) | |
13 | 15 | ||
14 | 16 | let myAssetId = base58'EMdiF8uaySswfCdMxc114rSfzUsAKCtK9d8eSx6ruKP4' | |
15 | 17 | ||
16 | 18 | let ownerPubKey = base58'2in4yGNBKfitQbXbsHmL2unWrUnRo7GWyqcZXsmAzhQi' | |
17 | 19 | ||
18 | 20 | let managerPubKey = base58'EaKK5PAFUkgtnF7xcyABUzi8YBQADmUDnPzQBHjCTAKT' | |
19 | 21 | ||
20 | 22 | let lastBlockTime = lastBlock.timestamp | |
21 | 23 | ||
22 | 24 | let frameOpenTime = ((lastBlockTime / lockPeriod) * lockPeriod) | |
23 | 25 | ||
24 | 26 | let frameCloseTime = (frameOpenTime + lockPeriod) | |
25 | 27 | ||
26 | - | let payoutOpenTime = ( | |
28 | + | let payoutOpenTime = (frameOpenTime + ((30 * 86400) * 1000)) | |
27 | 29 | ||
28 | 30 | func toFloatString (num,mult) = { | |
29 | 31 | let th = "," | |
30 | 32 | let dp = "." | |
31 | 33 | func joinThousands (acc,val) = if (if ((acc == "")) | |
32 | 34 | then (val == 0) | |
33 | 35 | else false) | |
34 | 36 | then "" | |
35 | 37 | else if ((acc == "")) | |
36 | 38 | then toString(val) | |
37 | 39 | else ((acc + th) + drop(toString((val + 1000)), 1)) | |
38 | 40 | ||
39 | 41 | func dropRightZero (str) = if ((drop(str, (size(str) - 1)) != "0")) | |
40 | 42 | then str | |
41 | 43 | else take(str, (size(str) - 1)) | |
42 | 44 | ||
43 | 45 | let ip = (num / mult) | |
44 | 46 | let fp = (num % mult) | |
45 | 47 | let q6 = (ip / (((((1000 * 1000) * 1000) * 1000) * 1000) * 1000)) | |
46 | 48 | let r6 = (ip % (((((1000 * 1000) * 1000) * 1000) * 1000) * 1000)) | |
47 | 49 | let q5 = (r6 / ((((1000 * 1000) * 1000) * 1000) * 1000)) | |
48 | 50 | let r5 = (r6 % ((((1000 * 1000) * 1000) * 1000) * 1000)) | |
49 | 51 | let q4 = (r5 / (((1000 * 1000) * 1000) * 1000)) | |
50 | 52 | let r4 = (r5 % (((1000 * 1000) * 1000) * 1000)) | |
51 | 53 | let q3 = (r4 / ((1000 * 1000) * 1000)) | |
52 | 54 | let r3 = (r4 % ((1000 * 1000) * 1000)) | |
53 | 55 | let q2 = (r3 / (1000 * 1000)) | |
54 | 56 | let r2 = (r3 % (1000 * 1000)) | |
55 | 57 | let q1 = (r2 / 1000) | |
56 | 58 | let r1 = (r2 % 1000) | |
57 | 59 | let is = { | |
58 | - | let $ | |
59 | - | let $ | |
60 | - | let $ | |
61 | - | if (($ | |
62 | - | then $ | |
60 | + | let $list33433399 = [q6, q5, q4, q3, q2, q1, r1] | |
61 | + | let $size33433399 = size($list33433399) | |
62 | + | let $acc033433399 = "" | |
63 | + | if (($size33433399 == 0)) | |
64 | + | then $acc033433399 | |
63 | 65 | else { | |
64 | - | let $ | |
65 | - | if (($ | |
66 | - | then $ | |
66 | + | let $acc133433399 = joinThousands($acc033433399, $list33433399[0]) | |
67 | + | if (($size33433399 == 1)) | |
68 | + | then $acc133433399 | |
67 | 69 | else { | |
68 | - | let $ | |
69 | - | if (($ | |
70 | - | then $ | |
70 | + | let $acc233433399 = joinThousands($acc133433399, $list33433399[1]) | |
71 | + | if (($size33433399 == 2)) | |
72 | + | then $acc233433399 | |
71 | 73 | else { | |
72 | - | let $ | |
73 | - | if (($ | |
74 | - | then $ | |
74 | + | let $acc333433399 = joinThousands($acc233433399, $list33433399[2]) | |
75 | + | if (($size33433399 == 3)) | |
76 | + | then $acc333433399 | |
75 | 77 | else { | |
76 | - | let $ | |
77 | - | if (($ | |
78 | - | then $ | |
78 | + | let $acc433433399 = joinThousands($acc333433399, $list33433399[3]) | |
79 | + | if (($size33433399 == 4)) | |
80 | + | then $acc433433399 | |
79 | 81 | else { | |
80 | - | let $ | |
81 | - | if (($ | |
82 | - | then $ | |
82 | + | let $acc533433399 = joinThousands($acc433433399, $list33433399[4]) | |
83 | + | if (($size33433399 == 5)) | |
84 | + | then $acc533433399 | |
83 | 85 | else { | |
84 | - | let $ | |
85 | - | if (($ | |
86 | - | then $ | |
86 | + | let $acc633433399 = joinThousands($acc533433399, $list33433399[5]) | |
87 | + | if (($size33433399 == 6)) | |
88 | + | then $acc633433399 | |
87 | 89 | else { | |
88 | - | let $ | |
89 | - | if (($ | |
90 | - | then $ | |
90 | + | let $acc733433399 = joinThousands($acc633433399, $list33433399[6]) | |
91 | + | if (($size33433399 == 7)) | |
92 | + | then $acc733433399 | |
91 | 93 | else { | |
92 | - | let $ | |
94 | + | let $acc833433399 = joinThousands($acc733433399, $list33433399[7]) | |
93 | 95 | throw("List size exceed 7") | |
94 | 96 | } | |
95 | 97 | } | |
96 | 98 | } | |
97 | 99 | } | |
98 | 100 | } | |
99 | 101 | } | |
100 | 102 | } | |
101 | 103 | } | |
102 | 104 | } | |
103 | 105 | let fs = dropRightZero(dropRightZero(dropRightZero(dropRightZero(dropRightZero(dropRightZero(dropRightZero(dropRightZero(take(drop(toString((fp + mult)), 1), 8))))))))) | |
104 | 106 | ((if ((is != "")) | |
105 | 107 | then is | |
106 | 108 | else "0") + (if ((fs != "")) | |
107 | 109 | then (dp + fs) | |
108 | 110 | else "")) | |
109 | 111 | } | |
110 | 112 | ||
111 | 113 | ||
112 | 114 | func toDateTimeString (timestamp) = { | |
113 | 115 | let sp = " " | |
114 | 116 | let zz = " UTC" | |
115 | 117 | let norm = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365] | |
116 | 118 | let leap = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366] | |
117 | 119 | if (if ((-12212553600000 > timestamp)) | |
118 | 120 | then true | |
119 | 121 | else (timestamp > 253402300799999)) | |
120 | 122 | then throw("ISO 8601: Only years from 1583 to 9999 are permitted.") | |
121 | 123 | else { | |
122 | 124 | let epoch = (((((1969 * 365) + (1969 / 4)) - (1969 / 100)) + (1969 / 400)) + 366) | |
123 | 125 | let ce = (timestamp + ((epoch * 86400) * 1000)) | |
124 | 126 | let date = { | |
125 | 127 | let yy = ((ce / (31556952 * 1000)) - 1) | |
126 | 128 | let dty = (((((yy * 365) + (yy / 4)) - (yy / 100)) + (yy / 400)) + 366) | |
127 | 129 | let ytd = ((ce / (86400 * 1000)) - dty) | |
128 | 130 | let months = if (if (if ((((yy + 1) % 4) == 0)) | |
129 | 131 | then (((yy + 1) % 100) != 0) | |
130 | 132 | else false) | |
131 | 133 | then true | |
132 | 134 | else (((yy + 1) % 400) == 0)) | |
133 | 135 | then leap | |
134 | 136 | else norm | |
135 | 137 | let mm = if ((ytd >= months[12])) | |
136 | 138 | then throw() | |
137 | 139 | else if ((ytd >= months[11])) | |
138 | 140 | then 11 | |
139 | 141 | else if ((ytd >= months[10])) | |
140 | 142 | then 10 | |
141 | 143 | else if ((ytd >= months[9])) | |
142 | 144 | then 9 | |
143 | 145 | else if ((ytd >= months[8])) | |
144 | 146 | then 8 | |
145 | 147 | else if ((ytd >= months[7])) | |
146 | 148 | then 7 | |
147 | 149 | else if ((ytd >= months[6])) | |
148 | 150 | then 6 | |
149 | 151 | else if ((ytd >= months[5])) | |
150 | 152 | then 5 | |
151 | 153 | else if ((ytd >= months[4])) | |
152 | 154 | then 4 | |
153 | 155 | else if ((ytd >= months[3])) | |
154 | 156 | then 3 | |
155 | 157 | else if ((ytd >= months[2])) | |
156 | 158 | then 2 | |
157 | 159 | else if ((ytd >= months[1])) | |
158 | 160 | then 1 | |
159 | 161 | else if ((ytd >= months[0])) | |
160 | 162 | then 0 | |
161 | 163 | else throw() | |
162 | 164 | let dd = (ytd - months[mm]) | |
163 | 165 | ((((toString((yy + 1)) + "-") + drop(toString((mm + 101)), 1)) + "-") + drop(toString((dd + 101)), 1)) | |
164 | 166 | } | |
165 | 167 | let time = { | |
166 | 168 | let rd = (ce % (86400 * 1000)) | |
167 | 169 | let hh = (rd / (3600 * 1000)) | |
168 | 170 | let rh = (rd % (3600 * 1000)) | |
169 | 171 | let mm = (rh / (60 * 1000)) | |
170 | 172 | let rm = (rh % (60 * 1000)) | |
171 | 173 | let ss = (rm / 1000) | |
172 | 174 | let ms = (rm % 1000) | |
173 | 175 | ((((drop(toString((hh + 100)), 1) + ":") + drop(toString((mm + 100)), 1)) + ":") + drop(toString((ss + 100)), 1)) | |
174 | 176 | } | |
175 | 177 | (((date + sp) + time) + zz) | |
176 | 178 | } | |
177 | 179 | } | |
178 | 180 | ||
179 | 181 | ||
180 | 182 | @Callable(inv) | |
181 | 183 | func deposit () = { | |
182 | 184 | let attPayment = if (isDefined(inv.payment)) | |
183 | 185 | then extract(inv.payment) | |
184 | 186 | else throw((("There is no attached payment " + assetName) + ".")) | |
185 | 187 | if ((attPayment.assetId != myAssetId)) | |
186 | 188 | then throw((("Only " + assetName) + " is allowed to deposit.")) | |
187 | 189 | else { | |
188 | 190 | let dapp = toBase58String(this.bytes) | |
189 | 191 | let sumTotal = getIntegerValue(this, (dapp + "_balance")) | |
190 | 192 | let client = toBase58String(inv.caller.bytes) | |
191 | 193 | let updateTime = match getInteger(this, (client + "_updatetime")) { | |
192 | 194 | case x: Int => | |
193 | 195 | x | |
194 | 196 | case _ => | |
195 | 197 | 0 | |
196 | 198 | } | |
197 | 199 | let isOlder = (frameOpenTime >= updateTime) | |
198 | 200 | let isActive = match getBoolean(this, (client + "_status")) { | |
199 | 201 | case x: Boolean => | |
200 | 202 | x | |
201 | 203 | case _ => | |
202 | 204 | false | |
203 | 205 | } | |
204 | 206 | let balance = if (if (isOlder) | |
205 | 207 | then !(isActive) | |
206 | 208 | else false) | |
207 | 209 | then 0 | |
208 | 210 | else match getInteger(this, (client + "_balance")) { | |
209 | 211 | case x: Int => | |
210 | 212 | x | |
211 | 213 | case _ => | |
212 | 214 | 0 | |
213 | 215 | } | |
214 | 216 | let amount = attPayment.amount | |
215 | 217 | let newBalance = if (isActive) | |
216 | 218 | then (balance + amount) | |
217 | 219 | else amount | |
218 | 220 | if (if ((minBalance > newBalance)) | |
219 | 221 | then true | |
220 | 222 | else (newBalance > maxBalance)) | |
221 | 223 | then throw((((((((("The minimum allowable balance is " + toFloatString(minBalance, decMult)) + " ") + assetName) + ", and the maximum is ") + toFloatString(maxBalance, decMult)) + " ") + assetName) + ".")) | |
222 | 224 | else { | |
223 | 225 | let startTime = if (if (isOlder) | |
224 | 226 | then isActive | |
225 | 227 | else false) | |
226 | 228 | then frameOpenTime | |
227 | 229 | else if (if (isOlder) | |
228 | 230 | then !(isActive) | |
229 | 231 | else false) | |
230 | 232 | then lastBlockTime | |
231 | 233 | else match getInteger(this, (client + "_starttime")) { | |
232 | 234 | case x: Int => | |
233 | 235 | if (isActive) | |
234 | 236 | then x | |
235 | 237 | else ((x + lastBlockTime) - updateTime) | |
236 | 238 | case _ => | |
237 | 239 | 0 | |
238 | 240 | } | |
239 | 241 | let newStartTime = if ((startTime > lastBlockTime)) | |
240 | 242 | then frameCloseTime | |
241 | 243 | else { | |
242 | 244 | let balWeight = (balance / minBalance) | |
243 | 245 | let sumWeight = (newBalance / minBalance) | |
244 | 246 | (fraction(startTime, balWeight, sumWeight) + fraction(lastBlockTime, (sumWeight - balWeight), sumWeight)) | |
245 | 247 | } | |
246 | 248 | if (isActive) | |
247 | 249 | then WriteSet([DataEntry((dapp + "_balance"), (sumTotal + amount)), DataEntry((client + "_balance"), newBalance), DataEntry((client + "_starttime"), newStartTime), DataEntry((client + "_updatetime"), lastBlockTime)]) | |
248 | 250 | else if (isDefined(getString(this, (client + "_address")))) | |
249 | 251 | then WriteSet([DataEntry((dapp + "_balance"), (sumTotal + amount)), DataEntry((client + "_balance"), newBalance), DataEntry((client + "_starttime"), newStartTime), DataEntry((client + "_status"), true), DataEntry((client + "_updatetime"), lastBlockTime)]) | |
250 | 252 | else WriteSet([DataEntry((dapp + "_balance"), (sumTotal + amount)), DataEntry((client + "_address"), client), DataEntry((client + "_balance"), newBalance), DataEntry((client + "_starttime"), newStartTime), DataEntry((client + "_status"), true), DataEntry((client + "_updatetime"), lastBlockTime)]) | |
251 | 253 | } | |
252 | 254 | } | |
253 | 255 | } | |
254 | 256 | ||
255 | 257 | ||
256 | 258 | ||
257 | 259 | @Callable(inv) | |
258 | 260 | func withdraw (RSCx100000) = if (isDefined(inv.payment)) | |
259 | 261 | then throw("Please do not attach payment when withdrawing funds.") | |
260 | 262 | else { | |
261 | 263 | let dapp = toBase58String(this.bytes) | |
262 | 264 | let sumTotal = getIntegerValue(this, (dapp + "_balance")) | |
263 | 265 | let minStake = getIntegerValue(this, (dapp + "_starttime")) | |
266 | + | let dappTime = getIntegerValue(this, (dapp + "_updatetime")) | |
264 | 267 | let client = toBase58String(inv.caller.bytes) | |
265 | 268 | let updateTime = match getInteger(this, (client + "_updatetime")) { | |
266 | 269 | case x: Int => | |
267 | 270 | x | |
268 | 271 | case _ => | |
269 | 272 | 0 | |
270 | 273 | } | |
271 | 274 | let isOlder = (frameOpenTime >= updateTime) | |
272 | 275 | let isActive = match getBoolean(this, (client + "_status")) { | |
273 | 276 | case x: Boolean => | |
274 | 277 | x | |
275 | 278 | case _ => | |
276 | 279 | false | |
277 | 280 | } | |
278 | 281 | let balance = if (!(isActive)) | |
279 | 282 | then 0 | |
280 | 283 | else match getInteger(this, (client + "_balance")) { | |
281 | 284 | case x: Int => | |
282 | 285 | x | |
283 | 286 | case _ => | |
284 | 287 | 0 | |
285 | 288 | } | |
286 | 289 | let expiration = (updateTime + lockPeriod) | |
290 | + | let lastUpdate = if ((dappTime > updateTime)) | |
291 | + | then dappTime | |
292 | + | else updateTime | |
287 | 293 | let amount = if ((RSCx100000 > 0)) | |
288 | 294 | then RSCx100000 | |
289 | 295 | else balance | |
290 | 296 | let newBalance = (balance - amount) | |
291 | 297 | if (if (if ((minStake >= 0)) | |
292 | 298 | then (balance >= minStake) | |
293 | 299 | else false) | |
294 | 300 | then (expiration > lastBlockTime) | |
295 | 301 | else false) | |
296 | 302 | then throw((("Unable to withdraw coins! The account is locked for up to " + toDateTimeString(expiration)) + ". Please wait...")) | |
297 | 303 | else if ((0 >= amount)) | |
298 | 304 | then throw("It's impossible to withdraw a negative amount or no balance.") | |
299 | 305 | else if ((amount > balance)) | |
300 | 306 | then throw((((((("It's impossible to withdraw more than the balance of " + toString(balance)) + " (") + toFloatString(balance, decMult)) + " ") + assetName) + ").")) | |
301 | 307 | else if ((minBalance > amount)) | |
302 | 308 | then throw((((((("The minimum withdrawal amount is " + toString(minBalance)) + " (") + toFloatString(minBalance, decMult)) + " ") + assetName) + ").")) | |
303 | - | else { | |
304 | - | let startTime = if (isOlder) | |
305 | - | then frameOpenTime | |
306 | - | else match getInteger(this, (client + "_starttime")) { | |
307 | - | case x: Int => | |
308 | - | x | |
309 | - | case _ => | |
310 | - | 0 | |
309 | + | else if (((lastUpdate + minConf) > lastBlockTime)) | |
310 | + | then throw((((("Please wait " + toString((minConf / 60000))) + " confirmations until ") + drop(toDateTimeString((lastUpdate + minConf)), 11)) + "...")) | |
311 | + | else { | |
312 | + | let startTime = if (isOlder) | |
313 | + | then frameOpenTime | |
314 | + | else match getInteger(this, (client + "_starttime")) { | |
315 | + | case x: Int => | |
316 | + | x | |
317 | + | case _ => | |
318 | + | 0 | |
319 | + | } | |
320 | + | let newStartTime = if ((startTime > lastBlockTime)) | |
321 | + | then frameCloseTime | |
322 | + | else if ((minBalance > newBalance)) | |
323 | + | then startTime | |
324 | + | else { | |
325 | + | let balWeight = (balance / minBalance) | |
326 | + | let sumWeight = (newBalance / minBalance) | |
327 | + | (fraction(startTime, balWeight, sumWeight) + fraction(lastBlockTime, (sumWeight - balWeight), sumWeight)) | |
328 | + | } | |
329 | + | if ((newBalance >= minBalance)) | |
330 | + | then ScriptResult(WriteSet([DataEntry((dapp + "_balance"), (sumTotal - amount)), DataEntry((client + "_balance"), newBalance), DataEntry((client + "_starttime"), newStartTime), DataEntry((client + "_updatetime"), lastBlockTime)]), TransferSet([ScriptTransfer(inv.caller, amount, myAssetId)])) | |
331 | + | else ScriptResult(WriteSet([DataEntry((dapp + "_balance"), (sumTotal - balance)), DataEntry((client + "_starttime"), newStartTime), DataEntry((client + "_status"), false), DataEntry((client + "_updatetime"), lastBlockTime)]), TransferSet([ScriptTransfer(inv.caller, balance, myAssetId)])) | |
311 | 332 | } | |
312 | - | let newStartTime = if ((startTime > lastBlockTime)) | |
313 | - | then frameCloseTime | |
314 | - | else if ((minBalance > newBalance)) | |
315 | - | then startTime | |
316 | - | else { | |
317 | - | let balWeight = (balance / minBalance) | |
318 | - | let sumWeight = (newBalance / minBalance) | |
319 | - | (fraction(startTime, balWeight, sumWeight) + fraction(lastBlockTime, (sumWeight - balWeight), sumWeight)) | |
320 | - | } | |
321 | - | if ((newBalance >= minBalance)) | |
322 | - | then ScriptResult(WriteSet([DataEntry((dapp + "_balance"), (sumTotal - amount)), DataEntry((client + "_balance"), newBalance), DataEntry((client + "_starttime"), newStartTime), DataEntry((client + "_updatetime"), lastBlockTime)]), TransferSet([ScriptTransfer(inv.caller, amount, myAssetId)])) | |
323 | - | else ScriptResult(WriteSet([DataEntry((dapp + "_balance"), (sumTotal - balance)), DataEntry((client + "_starttime"), newStartTime), DataEntry((client + "_status"), false), DataEntry((client + "_updatetime"), lastBlockTime)]), TransferSet([ScriptTransfer(inv.caller, balance, myAssetId)])) | |
324 | - | } | |
325 | 333 | } | |
326 | 334 | ||
327 | 335 | ||
328 | 336 | ||
329 | 337 | @Callable(inv) | |
330 | - | func | |
338 | + | func setMinStake (RSCx100000) = if (if ((inv.callerPublicKey != ownerPubKey)) | |
331 | 339 | then (inv.callerPublicKey != managerPubKey) | |
332 | 340 | else false) | |
333 | - | then throw("Only the administrator can send rewards to customers!") | |
341 | + | then throw("Only an administrator can set and modify minStake!") | |
342 | + | else if (isDefined(inv.payment)) | |
343 | + | then throw("Please do not attach payment when setting up minStake.") | |
344 | + | else { | |
345 | + | let dapp = toBase58String(this.bytes) | |
346 | + | if (isDefined(getString(this, (dapp + "_address")))) | |
347 | + | then WriteSet([DataEntry((dapp + "_starttime"), RSCx100000), DataEntry((dapp + "_updatetime"), lastBlockTime)]) | |
348 | + | else WriteSet([DataEntry((dapp + "_address"), dapp), DataEntry((dapp + "_balance"), 0), DataEntry((dapp + "_starttime"), RSCx100000), DataEntry((dapp + "_status"), false), DataEntry((dapp + "_updatetime"), lastBlockTime)]) | |
349 | + | } | |
350 | + | ||
351 | + | ||
352 | + | ||
353 | + | @Callable(inv) | |
354 | + | func sendRewards (addr0,amount0,addr1,amount1,addr2,amount2,addr3,amount3,addr4,amount4,addr5,amount5,addr6,amount6,addr7,amount7,addr8,amount8,addr9,amount9) = if (if ((inv.callerPublicKey != ownerPubKey)) | |
355 | + | then (inv.callerPublicKey != managerPubKey) | |
356 | + | else false) | |
357 | + | then throw("Only administrator can send rewards to customers!") | |
334 | 358 | else if ((payoutOpenTime > lastBlockTime)) | |
335 | 359 | then throw((("The time to send rewards has not yet come! Beginning at " + toDateTimeString(payoutOpenTime)) + ". Please wait...")) | |
336 | 360 | else { | |
337 | 361 | let dapp = toBase58String(this.bytes) | |
338 | 362 | let sumTotal = getIntegerValue(this, (dapp + "_balance")) | |
339 | 363 | let available = (assetBalance(this, myAssetId) - sumTotal) | |
340 | 364 | let rewards = (((((((((amount0 + amount1) + amount2) + amount3) + amount4) + amount5) + amount6) + amount7) + amount8) + amount9) | |
341 | 365 | let effBalance = if (!(isDefined(inv.payment))) | |
342 | 366 | then available | |
343 | 367 | else { | |
344 | 368 | let attPayment = extract(inv.payment) | |
345 | 369 | if ((attPayment.assetId != myAssetId)) | |
346 | 370 | then throw((("Only " + assetName) + " is allowed to deposit.")) | |
347 | 371 | else (available + attPayment.amount) | |
348 | 372 | } | |
349 | 373 | if ((0 >= rewards)) | |
350 | 374 | then throw("Zero or negative rewards are not allowed.") | |
351 | 375 | else if ((rewards > effBalance)) | |
352 | 376 | then throw((((("Insufficient effective balance! The required amount is " + toFloatString((rewards - effBalance), decMult)) + " ") + assetName) + ".")) | |
353 | 377 | else { | |
354 | - | let data9 = if (if (( | |
378 | + | let data9 = if (if ((addr9 == "-")) | |
355 | 379 | then (amount9 == 0) | |
356 | 380 | else false) | |
357 | 381 | then nil | |
358 | - | else if (!(getBooleanValue(this, ( | |
359 | - | then throw("The status of | |
382 | + | else if (!(getBooleanValue(this, (addr9 + "_status")))) | |
383 | + | then throw("The status of address #9 is inactive!") | |
360 | 384 | else if ((0 >= amount9)) | |
361 | 385 | then throw("Zero or negative amounts are not allowed.") | |
362 | 386 | else { | |
363 | - | let balance9 = getIntegerValue(this, (client9 + "_balance")) | |
364 | - | [DataEntry((client9 + "_balance"), (balance9 + amount9)), DataEntry((client9 + "_starttime"), frameCloseTime)] | |
387 | + | let newBalance = (getIntegerValue(this, (addr9 + "_balance")) + amount9) | |
388 | + | if ((newBalance > maxBalance)) | |
389 | + | then throw("Deposit of address #9 will be overfilled!") | |
390 | + | else [DataEntry((addr9 + "_balance"), newBalance), DataEntry((addr9 + "_starttime"), frameCloseTime)] | |
365 | 391 | } | |
366 | - | let data8 = if (if (( | |
392 | + | let data8 = if (if ((addr8 == "-")) | |
367 | 393 | then (amount8 == 0) | |
368 | 394 | else false) | |
369 | 395 | then data9 | |
370 | - | else if (!(getBooleanValue(this, ( | |
371 | - | then throw("The status of | |
396 | + | else if (!(getBooleanValue(this, (addr8 + "_status")))) | |
397 | + | then throw("The status of address #8 is inactive!") | |
372 | 398 | else if ((0 >= amount8)) | |
373 | 399 | then throw("Zero or negative amounts are not allowed.") | |
374 | 400 | else { | |
375 | - | let balance8 = getIntegerValue(this, (client8 + "_balance")) | |
376 | - | [DataEntry((client8 + "_balance"), (balance8 + amount8)), DataEntry((client8 + "_starttime"), frameCloseTime)] :: data9 | |
401 | + | let newBalance = (getIntegerValue(this, (addr8 + "_balance")) + amount8) | |
402 | + | if ((newBalance > maxBalance)) | |
403 | + | then throw("Deposit of address #8 will be overfilled!") | |
404 | + | else [DataEntry((addr8 + "_balance"), newBalance), DataEntry((addr8 + "_starttime"), frameCloseTime)] :: data9 | |
377 | 405 | } | |
378 | - | let data7 = if (if (( | |
406 | + | let data7 = if (if ((addr7 == "-")) | |
379 | 407 | then (amount7 == 0) | |
380 | 408 | else false) | |
381 | 409 | then data8 | |
382 | - | else if (!(getBooleanValue(this, ( | |
383 | - | then throw("The status of | |
410 | + | else if (!(getBooleanValue(this, (addr7 + "_status")))) | |
411 | + | then throw("The status of address #7 is inactive!") | |
384 | 412 | else if ((0 >= amount7)) | |
385 | 413 | then throw("Zero or negative amounts are not allowed.") | |
386 | 414 | else { | |
387 | - | let balance7 = getIntegerValue(this, (client7 + "_balance")) | |
388 | - | [DataEntry((client7 + "_balance"), (balance7 + amount7)), DataEntry((client7 + "_starttime"), frameCloseTime)] :: data8 | |
415 | + | let newBalance = (getIntegerValue(this, (addr7 + "_balance")) + amount7) | |
416 | + | if ((newBalance > maxBalance)) | |
417 | + | then throw("Deposit of address #7 will be overfilled!") | |
418 | + | else [DataEntry((addr7 + "_balance"), newBalance), DataEntry((addr7 + "_starttime"), frameCloseTime)] :: data8 | |
389 | 419 | } | |
390 | - | let data6 = if (if (( | |
420 | + | let data6 = if (if ((addr6 == "-")) | |
391 | 421 | then (amount6 == 0) | |
392 | 422 | else false) | |
393 | 423 | then data7 | |
394 | - | else if (!(getBooleanValue(this, ( | |
395 | - | then throw("The status of | |
424 | + | else if (!(getBooleanValue(this, (addr6 + "_status")))) | |
425 | + | then throw("The status of address #6 is inactive!") | |
396 | 426 | else if ((0 >= amount6)) | |
397 | 427 | then throw("Zero or negative amounts are not allowed.") | |
398 | 428 | else { | |
399 | - | let balance6 = getIntegerValue(this, (client6 + "_balance")) | |
400 | - | [DataEntry((client6 + "_balance"), (balance6 + amount6)), DataEntry((client6 + "_starttime"), frameCloseTime)] :: data7 | |
429 | + | let newBalance = (getIntegerValue(this, (addr6 + "_balance")) + amount6) | |
430 | + | if ((newBalance > maxBalance)) | |
431 | + | then throw("Deposit of address #6 will be overfilled!") | |
432 | + | else [DataEntry((addr6 + "_balance"), newBalance), DataEntry((addr6 + "_starttime"), frameCloseTime)] :: data7 | |
401 | 433 | } | |
402 | - | let data5 = if (if (( | |
434 | + | let data5 = if (if ((addr5 == "-")) | |
403 | 435 | then (amount5 == 0) | |
404 | 436 | else false) | |
405 | 437 | then data6 | |
406 | - | else if (!(getBooleanValue(this, ( | |
407 | - | then throw("The status of | |
438 | + | else if (!(getBooleanValue(this, (addr5 + "_status")))) | |
439 | + | then throw("The status of address #5 is inactive!") | |
408 | 440 | else if ((0 >= amount5)) | |
409 | 441 | then throw("Zero or negative amounts are not allowed.") | |
410 | 442 | else { | |
411 | - | let balance5 = getIntegerValue(this, (client5 + "_balance")) | |
412 | - | [DataEntry((client5 + "_balance"), (balance5 + amount5)), DataEntry((client5 + "_starttime"), frameCloseTime)] :: data6 | |
443 | + | let newBalance = (getIntegerValue(this, (addr5 + "_balance")) + amount5) | |
444 | + | if ((newBalance > maxBalance)) | |
445 | + | then throw("Deposit of address #5 will be overfilled!") | |
446 | + | else [DataEntry((addr5 + "_balance"), newBalance), DataEntry((addr5 + "_starttime"), frameCloseTime)] :: data6 | |
413 | 447 | } | |
414 | - | let data4 = if (if (( | |
448 | + | let data4 = if (if ((addr4 == "-")) | |
415 | 449 | then (amount4 == 0) | |
416 | 450 | else false) | |
417 | 451 | then data5 | |
418 | - | else if (!(getBooleanValue(this, ( | |
419 | - | then throw("The status of | |
452 | + | else if (!(getBooleanValue(this, (addr4 + "_status")))) | |
453 | + | then throw("The status of address #4 is inactive!") | |
420 | 454 | else if ((0 >= amount4)) | |
421 | 455 | then throw("Zero or negative amounts are not allowed.") | |
422 | 456 | else { | |
423 | - | let balance4 = getIntegerValue(this, (client4 + "_balance")) | |
424 | - | [DataEntry((client4 + "_balance"), (balance4 + amount4)), DataEntry((client4 + "_starttime"), frameCloseTime)] :: data5 | |
457 | + | let newBalance = (getIntegerValue(this, (addr4 + "_balance")) + amount4) | |
458 | + | if ((newBalance > maxBalance)) | |
459 | + | then throw("Deposit of address #4 will be overfilled!") | |
460 | + | else [DataEntry((addr4 + "_balance"), newBalance), DataEntry((addr4 + "_starttime"), frameCloseTime)] :: data5 | |
425 | 461 | } | |
426 | - | let data3 = if (if (( | |
462 | + | let data3 = if (if ((addr3 == "-")) | |
427 | 463 | then (amount3 == 0) | |
428 | 464 | else false) | |
429 | 465 | then data4 | |
430 | - | else if (!(getBooleanValue(this, ( | |
431 | - | then throw("The status of | |
466 | + | else if (!(getBooleanValue(this, (addr3 + "_status")))) | |
467 | + | then throw("The status of address #3 is inactive!") | |
432 | 468 | else if ((0 >= amount3)) | |
433 | 469 | then throw("Zero or negative amounts are not allowed.") | |
434 | 470 | else { | |
435 | - | let balance3 = getIntegerValue(this, (client3 + "_balance")) | |
436 | - | [DataEntry((client3 + "_balance"), (balance3 + amount3)), DataEntry((client3 + "_starttime"), frameCloseTime)] :: data4 | |
471 | + | let newBalance = (getIntegerValue(this, (addr3 + "_balance")) + amount3) | |
472 | + | if ((newBalance > maxBalance)) | |
473 | + | then throw("Deposit of address #3 will be overfilled!") | |
474 | + | else [DataEntry((addr3 + "_balance"), newBalance), DataEntry((addr3 + "_starttime"), frameCloseTime)] :: data4 | |
437 | 475 | } | |
438 | - | let data2 = if (if (( | |
476 | + | let data2 = if (if ((addr2 == "-")) | |
439 | 477 | then (amount2 == 0) | |
440 | 478 | else false) | |
441 | 479 | then data3 | |
442 | - | else if (!(getBooleanValue(this, ( | |
443 | - | then throw("The status of | |
480 | + | else if (!(getBooleanValue(this, (addr2 + "_status")))) | |
481 | + | then throw("The status of address #2 is inactive!") | |
444 | 482 | else if ((0 >= amount2)) | |
445 | 483 | then throw("Zero or negative amounts are not allowed.") | |
446 | 484 | else { | |
447 | - | let balance2 = getIntegerValue(this, (client2 + "_balance")) | |
448 | - | [DataEntry((client2 + "_balance"), (balance2 + amount2)), DataEntry((client2 + "_starttime"), frameCloseTime)] :: data3 | |
485 | + | let newBalance = (getIntegerValue(this, (addr2 + "_balance")) + amount2) | |
486 | + | if ((newBalance > maxBalance)) | |
487 | + | then throw("Deposit of address #2 will be overfilled!") | |
488 | + | else [DataEntry((addr2 + "_balance"), newBalance), DataEntry((addr2 + "_starttime"), frameCloseTime)] :: data3 | |
449 | 489 | } | |
450 | - | let data1 = if (if (( | |
490 | + | let data1 = if (if ((addr1 == "-")) | |
451 | 491 | then (amount1 == 0) | |
452 | 492 | else false) | |
453 | 493 | then data2 | |
454 | - | else if (!(getBooleanValue(this, ( | |
455 | - | then throw("The status of | |
494 | + | else if (!(getBooleanValue(this, (addr1 + "_status")))) | |
495 | + | then throw("The status of address #1 is inactive!") | |
456 | 496 | else if ((0 >= amount1)) | |
457 | 497 | then throw("Zero or negative amounts are not allowed.") | |
458 | 498 | else { | |
459 | - | let balance1 = getIntegerValue(this, (client1 + "_balance")) | |
460 | - | [DataEntry((client1 + "_balance"), (balance1 + amount1)), DataEntry((client1 + "_starttime"), frameCloseTime)] :: data2 | |
499 | + | let newBalance = (getIntegerValue(this, (addr1 + "_balance")) + amount1) | |
500 | + | if ((newBalance > maxBalance)) | |
501 | + | then throw("Deposit of address #1 will be overfilled!") | |
502 | + | else [DataEntry((addr1 + "_balance"), newBalance), DataEntry((addr1 + "_starttime"), frameCloseTime)] :: data2 | |
461 | 503 | } | |
462 | - | let data0 = if (if (( | |
504 | + | let data0 = if (if ((addr0 == "-")) | |
463 | 505 | then (amount0 == 0) | |
464 | 506 | else false) | |
465 | 507 | then data1 | |
466 | - | else if (!(getBooleanValue(this, ( | |
467 | - | then throw("The status of | |
508 | + | else if (!(getBooleanValue(this, (addr0 + "_status")))) | |
509 | + | then throw("The status of address #0 is inactive!") | |
468 | 510 | else if ((0 >= amount0)) | |
469 | 511 | then throw("Zero or negative amounts are not allowed.") | |
470 | 512 | else { | |
471 | - | let balance0 = getIntegerValue(this, (client0 + "_balance")) | |
472 | - | [DataEntry((client0 + "_balance"), (balance0 + amount0)), DataEntry((client0 + "_starttime"), frameCloseTime)] :: data1 | |
513 | + | let newBalance = (getIntegerValue(this, (addr0 + "_balance")) + amount0) | |
514 | + | if ((newBalance > maxBalance)) | |
515 | + | then throw("Deposit of address #0 will be overfilled!") | |
516 | + | else [DataEntry((addr0 + "_balance"), newBalance), DataEntry((addr0 + "_starttime"), frameCloseTime)] :: data1 | |
473 | 517 | } | |
474 | - | WriteSet(DataEntry((dapp + "_balance"), (sumTotal + rewards)) :: data0) | |
518 | + | WriteSet([DataEntry((dapp + "_balance"), (sumTotal + rewards)), DataEntry((dapp + "_updatetime"), lastBlockTime)] :: data0) | |
475 | 519 | } | |
476 | - | } | |
477 | - | ||
478 | - | ||
479 | - | ||
480 | - | @Callable(inv) | |
481 | - | func setMinStake (amount) = if (if ((inv.callerPublicKey != ownerPubKey)) | |
482 | - | then (inv.callerPublicKey != managerPubKey) | |
483 | - | else false) | |
484 | - | then throw("Only the administrator can set and modify minStake!") | |
485 | - | else if (isDefined(inv.payment)) | |
486 | - | then throw("Please do not attach payment when setting up minStake.") | |
487 | - | else { | |
488 | - | let dapp = toBase58String(this.bytes) | |
489 | - | if (isDefined(getString(this, (dapp + "_address")))) | |
490 | - | then WriteSet([DataEntry((dapp + "_starttime"), amount), DataEntry((dapp + "_updatetime"), lastBlockTime)]) | |
491 | - | else WriteSet([DataEntry((dapp + "_address"), dapp), DataEntry((dapp + "_balance"), 0), DataEntry((dapp + "_starttime"), amount), DataEntry((dapp + "_status"), false), DataEntry((dapp + "_updatetime"), lastBlockTime)]) | |
492 | 520 | } | |
493 | 521 | ||
494 | 522 | ||
495 | 523 | @Verifier(tx) | |
496 | 524 | func verify () = match tx { | |
525 | + | case a: CreateAliasTransaction => | |
526 | + | sigVerify(a.bodyBytes, a.proofs[0], a.senderPublicKey) | |
497 | 527 | case t: TransferTransaction => | |
498 | - | | |
528 | + | if (if ((t.assetId != myAssetId)) | |
499 | 529 | then (t.feeAssetId != myAssetId) | |
500 | 530 | else false) | |
501 | - | then sigVerify(t.bodyBytes, t.proofs[2], ownerPubKey) | |
502 | - | else false) | |
503 | - | then sigVerify(t.bodyBytes, t.proofs[1], managerPubKey) | |
531 | + | then sigVerify(t.bodyBytes, t.proofs[0], t.senderPublicKey) | |
504 | 532 | else false | |
505 | 533 | case s: SetScriptTransaction => | |
506 | 534 | if (sigVerify(s.bodyBytes, s.proofs[2], ownerPubKey)) | |
507 | 535 | then sigVerify(s.bodyBytes, s.proofs[1], managerPubKey) | |
508 | 536 | else false | |
509 | 537 | case _ => | |
510 | 538 | false | |
511 | 539 | } | |
512 | 540 |
github/deemru/w8io/3ef1775 157.36 ms ◑