tx · EDhtmUk6Y7uuft39Lvu8caz29izTMJWKnTkSGBpaCqk 3PEvtRxPJyyps7cKRkLbKFAQ8qbdczpLkB9: -0.01400000 Waves 2020.01.13 11:47 [1882530] smart account 3PEvtRxPJyyps7cKRkLbKFAQ8qbdczpLkB9 > SELF 0.00000000 Waves
{ "type": 13, "id": "EDhtmUk6Y7uuft39Lvu8caz29izTMJWKnTkSGBpaCqk", "fee": 1400000, "feeAssetId": null, "timestamp": 1578905282930, "version": 1, "sender": "3PEvtRxPJyyps7cKRkLbKFAQ8qbdczpLkB9", "senderPublicKey": "4VStEwhXhsv6wQ6PBR5CfEYD8m91zYg2pcF7v17QGSbJ", "proofs": [ "3HvF3VxjiqpyRY8HPFKFm4riVdXmEG933ACLMUoBxGMMgHa64AkXW23NMLuAueE5Dk6H6hYm4ty96387fDoghBhX" ], "script": "base64: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AAAFaXRlbV8FAAAABml0ZW1JZAIAAAAGX2J1eWVyBAAAAAhwcmljZUtleQkAASwAAAACCQABLAAAAAICAAAABWl0ZW1fBQAAAAZpdGVtSWQCAAAABl9wcmljZQkBAAAACFdyaXRlU2V0AAAAAQkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgUAAAAIYnV5ZXJLZXkFAAAADGJ1eWVyQWRkcmVzcwkABEwAAAACCQEAAAAJRGF0YUVudHJ5AAAAAgUAAAAIcHJpY2VLZXkFAAAABXByaWNlCQAETAAAAAIJAQAAAAlEYXRhRW50cnkAAAACCQEAAAAMa2V5SXRlbU93bmVyAAAAAQUAAAAGaXRlbUlkBQAAAAxvd25lckFkZHJlc3MFAAAAA25pbAAAAAFpAQAAAAxzdGFydEZ1bmRpbmcAAAAEAAAAAmlkAAAAF2Z1bmRyYWlzaW5nRW5kVGltZXN0YW1wAAAAGmltcGxtZW5ldGF0aW9uRW5kVGltZXN0YW1wAAAACXRhcmdldFN1bQQAAAASbGFzdEJsb2NrVGltZXN0YW1wCAUAAAAJbGFzdEJsb2NrAAAACXRpbWVzdGFtcAMJAABmAAAAAgAAAAAAAAAAAAkAAGUAAAACCQAAZQAAAAIFAAAAF2Z1bmRyYWlzaW5nRW5kVGltZXN0YW1wBQAAABJsYXN0QmxvY2tUaW1lc3RhbXAAAAAAAAAAADwJAAACAAAAAQIAAABBRW5kIHRpbWUgc2hvdWxkIGF0IGxlYXN0IDYwIHNlY29uZHMgbW9yZSB0aGFuIHRoZSBsYXN0IGJsb2NrIHRpbWUDCQAAZgAAAAIFAAAAF2Z1bmRyYWlzaW5nRW5kVGltZXN0YW1wBQAAABppbXBsbWVuZXRhdGlvbkVuZFRpbWVzdGFtcAkAAAIAAAABAgAAADxJbXBsZW1lbnRhdGlvbiBlbmQgdGltZSBzaG91bGQgbW9yZSBvciBlcXVhbCB0byBlbmRUaW1lc3RhbXADCQEAAAAJaXNEZWZpbmVkAAAAAQkABBoAAAACBQAAAAR0aGlzCQEAAAAKa2V5RnVuZGluZwAAAAEFAAAAAmlkCQAAAgAAAAECAAAAJ0Z1bmRpbmcgd2l0aCB0aGUgc2FtZSBJRCBhbHJlYWR5IGV4aXN0cwMJAABmAAAAAgAAAAAAAAAD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", "chainId": 87, "height": 1882530, "spentComplexity": 0 } View: original | compacted Prev: EWNNjqNiZMqdKA3Azq4faU7tTqeVHPKanxX2Nyvsg923 Next: none Diff:
Old | New | Differences | |
---|---|---|---|
4 | 4 | let adminPublicKey = base58'G4Ywi2Ua6APjE691ynx8kGLQauzNcNZ1us1AnbgWSXTA' | |
5 | 5 | ||
6 | 6 | let thanksTokenId = base58'AAx7kicknEXkWUqSF1DKXp7bQHH6Z383Bw9H5v16MgFJ' | |
7 | + | ||
8 | + | func keyItemOwner (itemId) = (("item_" + itemId) + "_owner") | |
9 | + | ||
10 | + | ||
11 | + | func keyFunding (id) = ("funding_" + toString(id)) | |
12 | + | ||
13 | + | ||
14 | + | func keyEndTimestamp (id) = (keyFunding(id) + "_timestamp") | |
15 | + | ||
16 | + | ||
17 | + | func keyImplEndTimestamp (id) = (keyFunding(id) + "_impl_timestamp") | |
18 | + | ||
19 | + | ||
20 | + | func keyTargetSum (id) = (keyFunding(id) + "_targetSum") | |
21 | + | ||
22 | + | ||
23 | + | func keyOwner (id) = (keyFunding(id) + "_owner") | |
24 | + | ||
25 | + | ||
26 | + | func keyRaised (id) = (keyFunding(id) + "_raised") | |
27 | + | ||
28 | + | ||
29 | + | func keyReleaseVotes (id) = (keyFunding(id) + "_release_votes") | |
30 | + | ||
31 | + | ||
32 | + | func keyReleasedTokens (id) = (keyFunding(id) + "_released") | |
33 | + | ||
34 | + | ||
35 | + | func keyUserVoted (id,publicKey) = (((keyFunding(id) + "_") + publicKey) + "_voted") | |
36 | + | ||
37 | + | ||
38 | + | func keyUserFunded (id,publicKey) = (((keyFunding(id) + "_") + publicKey) + "_funded") | |
39 | + | ||
7 | 40 | ||
8 | 41 | @Callable(i) | |
9 | 42 | func addToWhiteList (address) = { | |
108 | 141 | case _ => | |
109 | 142 | throw("Bad address of buyer") | |
110 | 143 | } | |
144 | + | let priceKey = (("item_" + itemId) + "_price") | |
145 | + | let price = getIntegerValue(this, priceKey) | |
146 | + | let itemOwnerAddress = match getString(this, keyItemOwner(itemId)) { | |
147 | + | case a: String => | |
148 | + | match addressFromString(a) { | |
149 | + | case b: Address => | |
150 | + | b | |
151 | + | case _ => | |
152 | + | addressFromPublicKey(adminPublicKey) | |
153 | + | } | |
154 | + | case _ => | |
155 | + | addressFromPublicKey(adminPublicKey) | |
156 | + | } | |
111 | 157 | if ((i.callerPublicKey != adminPublicKey)) | |
112 | 158 | then throw("Only admin can call this function") | |
113 | 159 | else { | |
114 | 160 | let buyKey = (("item_" + itemId) + "_bought") | |
115 | 161 | let itemIdBytes = fromBase58String(itemId) | |
116 | - | ScriptResult(WriteSet([DataEntry(buyKey, "approved")]), TransferSet([ScriptTransfer(buyerAddressReal, 1, itemIdBytes)])) | |
162 | + | ScriptResult(WriteSet([DataEntry(buyKey, "approved")]), TransferSet([ScriptTransfer(buyerAddressReal, 1, itemIdBytes), ScriptTransfer(itemOwnerAddress, (price - ((price / 1) / 5)), thanksTokenId)])) | |
117 | 163 | } | |
118 | 164 | } | |
119 | 165 | ||
134 | 180 | ||
135 | 181 | ||
136 | 182 | @Callable(i) | |
137 | - | func addItem (buyerAddress,price) = { | |
183 | + | func addItem (buyerAddress,price,ownerAddress) = { | |
138 | 184 | let inWhiteListUnit = getBoolean(this, buyerAddress) | |
139 | 185 | let inWhiteList = match inWhiteListUnit { | |
140 | 186 | case w: Boolean => | |
175 | 221 | else (nftAssetInfoReal.issuerPublicKey != adminPublicKey)) | |
176 | 222 | then throw("Token should be an NFT and from admin user") | |
177 | 223 | else { | |
178 | - | let buyerKey = (("item_" + toBase58String(nftAssetInfoReal.id)) + "_buyer") | |
179 | - | let priceKey = (("item_" + toBase58String(nftAssetInfoReal.id)) + "_price") | |
180 | - | WriteSet([DataEntry(buyerKey, buyerAddress), DataEntry(priceKey, price)]) | |
224 | + | let itemId = toBase58String(nftAssetInfoReal.id) | |
225 | + | let buyerKey = (("item_" + itemId) + "_buyer") | |
226 | + | let priceKey = (("item_" + itemId) + "_price") | |
227 | + | WriteSet([DataEntry(buyerKey, buyerAddress), DataEntry(priceKey, price), DataEntry(keyItemOwner(itemId), ownerAddress)]) | |
181 | 228 | } | |
182 | 229 | } | |
230 | + | } | |
231 | + | ||
232 | + | ||
233 | + | ||
234 | + | @Callable(i) | |
235 | + | func startFunding (id,fundraisingEndTimestamp,implmenetationEndTimestamp,targetSum) = { | |
236 | + | let lastBlockTimestamp = lastBlock.timestamp | |
237 | + | if ((0 > ((fundraisingEndTimestamp - lastBlockTimestamp) - 60))) | |
238 | + | then throw("End time should at least 60 seconds more than the last block time") | |
239 | + | else if ((fundraisingEndTimestamp > implmenetationEndTimestamp)) | |
240 | + | then throw("Implementation end time should more or equal to endTimestamp") | |
241 | + | else if (isDefined(getInteger(this, keyFunding(id)))) | |
242 | + | then throw("Funding with the same ID already exists") | |
243 | + | else if ((1000 > targetSum)) | |
244 | + | then throw("You cannot fundraise less than 1000 tokens") | |
245 | + | else WriteSet([DataEntry(keyFunding(id), height), DataEntry(keyEndTimestamp(id), fundraisingEndTimestamp), DataEntry(keyImplEndTimestamp(id), implmenetationEndTimestamp), DataEntry(keyTargetSum(id), targetSum), DataEntry(keyOwner(id), toBase58String(i.callerPublicKey)), DataEntry(keyRaised(id), 0), DataEntry(keyReleaseVotes(id), 0), DataEntry(keyReleasedTokens(id), false)]) | |
246 | + | } | |
247 | + | ||
248 | + | ||
249 | + | ||
250 | + | @Callable(i) | |
251 | + | func fund (id) = { | |
252 | + | let pmt = extract(i.payment) | |
253 | + | let targetSum = getIntegerValue(this, keyTargetSum(id)) | |
254 | + | let endTimestamp = getIntegerValue(this, keyEndTimestamp(id)) | |
255 | + | let owner = getStringValue(this, keyOwner(id)) | |
256 | + | let raised = getIntegerValue(this, keyRaised(id)) | |
257 | + | let alreadyFundedByUser = match getInteger(this, keyUserFunded(id, toBase58String(i.callerPublicKey))) { | |
258 | + | case v: Int => | |
259 | + | v | |
260 | + | case _ => | |
261 | + | 0 | |
262 | + | } | |
263 | + | if ((pmt.assetId != thanksTokenId)) | |
264 | + | then throw(("You have to attach proper tokens with id: " + toBase58String(thanksTokenId))) | |
265 | + | else if ((owner == toBase58String(i.callerPublicKey))) | |
266 | + | then throw("You cannot fund your own target") | |
267 | + | else if ((endTimestamp > lastBlock.timestamp)) | |
268 | + | then throw("This target is finished already") | |
269 | + | else if (((alreadyFundedByUser + pmt.amount) > ((targetSum / 3) + 1))) | |
270 | + | then throw(("You cannot fund more than 33% of the whole sum which is " + toString((((targetSum / 3) + 1) - alreadyFundedByUser)))) | |
271 | + | else WriteSet([DataEntry(keyUserFunded(id, toBase58String(i.callerPublicKey)), (alreadyFundedByUser + pmt.amount)), DataEntry(keyRaised(id), (raised + pmt.amount))]) | |
272 | + | } | |
273 | + | ||
274 | + | ||
275 | + | ||
276 | + | @Callable(i) | |
277 | + | func voteForRelease (id) = { | |
278 | + | let endTimestamp = getIntegerValue(this, keyEndTimestamp(id)) | |
279 | + | let implEndTimestamp = getIntegerValue(this, keyImplEndTimestamp(id)) | |
280 | + | let votePower = getIntegerValue(this, keyUserFunded(id, toBase58String(i.callerPublicKey))) | |
281 | + | let votedPower = getIntegerValue(this, keyReleaseVotes(id)) | |
282 | + | let targetSum = getIntegerValue(this, keyTargetSum(id)) | |
283 | + | let raised = getIntegerValue(this, keyRaised(id)) | |
284 | + | let released = getBooleanValue(this, keyReleasedTokens(id)) | |
285 | + | let owner = keyOwner(id) | |
286 | + | if ((implEndTimestamp > lastBlock.timestamp)) | |
287 | + | then throw("This target is not finished yet") | |
288 | + | else if ((targetSum > raised)) | |
289 | + | then throw("This target didn't reach target") | |
290 | + | else if (released) | |
291 | + | then throw("This target was released already") | |
292 | + | else if (isDefined(getBoolean(this, keyUserVoted(id, toBase58String(i.callerPublicKey))))) | |
293 | + | then throw("You already voted for the target") | |
294 | + | else if (((votedPower + votePower) > (raised / 2))) | |
295 | + | then { | |
296 | + | let ownerPrize = (raised - ((raised / 1) / 5)) | |
297 | + | ScriptResult(WriteSet([DataEntry(keyReleaseVotes(id), (votedPower + votePower)), DataEntry(keyReleasedTokens(id), true)]), TransferSet([ScriptTransfer(addressFromPublicKey(toBytes(owner)), ownerPrize, thanksTokenId)])) | |
298 | + | } | |
299 | + | else WriteSet([DataEntry(keyReleaseVotes(id), (votedPower + votePower))]) | |
300 | + | } | |
301 | + | ||
302 | + | ||
303 | + | ||
304 | + | @Callable(i) | |
305 | + | func refundUser (id) = { | |
306 | + | let implEndTimestamp = getIntegerValue(this, keyImplEndTimestamp(id)) | |
307 | + | let fundedAmount = getIntegerValue(this, keyUserFunded(id, toBase58String(i.callerPublicKey))) | |
308 | + | let targetSum = getIntegerValue(this, keyTargetSum(id)) | |
309 | + | let raised = getIntegerValue(this, keyRaised(id)) | |
310 | + | if ((implEndTimestamp > lastBlock.timestamp)) | |
311 | + | then throw("This target is not finished yet") | |
312 | + | else if ((raised > targetSum)) | |
313 | + | then throw("This target raised enough tokens") | |
314 | + | else if ((fundedAmount > 0)) | |
315 | + | then throw("You have no power here") | |
316 | + | else ScriptResult(WriteSet([DataEntry(keyUserFunded(id, toBase58String(i.callerPublicKey)), 0)]), TransferSet([ScriptTransfer(i.caller, fundedAmount, thanksTokenId)])) | |
183 | 317 | } | |
184 | 318 | ||
185 | 319 |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 3 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let adminPublicKey = base58'G4Ywi2Ua6APjE691ynx8kGLQauzNcNZ1us1AnbgWSXTA' | |
5 | 5 | ||
6 | 6 | let thanksTokenId = base58'AAx7kicknEXkWUqSF1DKXp7bQHH6Z383Bw9H5v16MgFJ' | |
7 | + | ||
8 | + | func keyItemOwner (itemId) = (("item_" + itemId) + "_owner") | |
9 | + | ||
10 | + | ||
11 | + | func keyFunding (id) = ("funding_" + toString(id)) | |
12 | + | ||
13 | + | ||
14 | + | func keyEndTimestamp (id) = (keyFunding(id) + "_timestamp") | |
15 | + | ||
16 | + | ||
17 | + | func keyImplEndTimestamp (id) = (keyFunding(id) + "_impl_timestamp") | |
18 | + | ||
19 | + | ||
20 | + | func keyTargetSum (id) = (keyFunding(id) + "_targetSum") | |
21 | + | ||
22 | + | ||
23 | + | func keyOwner (id) = (keyFunding(id) + "_owner") | |
24 | + | ||
25 | + | ||
26 | + | func keyRaised (id) = (keyFunding(id) + "_raised") | |
27 | + | ||
28 | + | ||
29 | + | func keyReleaseVotes (id) = (keyFunding(id) + "_release_votes") | |
30 | + | ||
31 | + | ||
32 | + | func keyReleasedTokens (id) = (keyFunding(id) + "_released") | |
33 | + | ||
34 | + | ||
35 | + | func keyUserVoted (id,publicKey) = (((keyFunding(id) + "_") + publicKey) + "_voted") | |
36 | + | ||
37 | + | ||
38 | + | func keyUserFunded (id,publicKey) = (((keyFunding(id) + "_") + publicKey) + "_funded") | |
39 | + | ||
7 | 40 | ||
8 | 41 | @Callable(i) | |
9 | 42 | func addToWhiteList (address) = { | |
10 | 43 | let userInTheList = getBoolean(this, address) | |
11 | 44 | let newValue = match userInTheList { | |
12 | 45 | case b: Boolean => | |
13 | 46 | if (b) | |
14 | 47 | then throw("User is already in the list and enabled") | |
15 | 48 | else throw("User is in the list, but disabled") | |
16 | 49 | case _ => | |
17 | 50 | true | |
18 | 51 | } | |
19 | 52 | if ((i.callerPublicKey != adminPublicKey)) | |
20 | 53 | then throw("Only admin can call this function") | |
21 | 54 | else match i.payment { | |
22 | 55 | case pmt: AttachedPayment => | |
23 | 56 | ScriptResult(WriteSet([DataEntry(address, newValue)]), TransferSet([ScriptTransfer(addressFromStringValue(address), 1000000, unit)])) | |
24 | 57 | case _ => | |
25 | 58 | throw("Payment is needed to transfer to an account") | |
26 | 59 | } | |
27 | 60 | } | |
28 | 61 | ||
29 | 62 | ||
30 | 63 | ||
31 | 64 | @Callable(i) | |
32 | 65 | func removeFromWhiteList (address) = if ((i.callerPublicKey != adminPublicKey)) | |
33 | 66 | then throw("Only admin can call this function") | |
34 | 67 | else WriteSet([DataEntry(address, false)]) | |
35 | 68 | ||
36 | 69 | ||
37 | 70 | ||
38 | 71 | @Callable(i) | |
39 | 72 | func buyItem (itemId) = { | |
40 | 73 | let callerAddress = toBase58String(i.caller.bytes) | |
41 | 74 | let inWhiteListUnit = getBoolean(this, callerAddress) | |
42 | 75 | let inWhiteList = match inWhiteListUnit { | |
43 | 76 | case w: Boolean => | |
44 | 77 | if (w) | |
45 | 78 | then true | |
46 | 79 | else throw("Buyer is not in the white-list[removed]") | |
47 | 80 | case _ => | |
48 | 81 | throw(("Buyer is not in the white-list: " + callerAddress)) | |
49 | 82 | } | |
50 | 83 | let pmt = match i.payment { | |
51 | 84 | case pmt: AttachedPayment => | |
52 | 85 | if (if (!(isDefined(pmt.assetId))) | |
53 | 86 | then true | |
54 | 87 | else (pmt.assetId != thanksTokenId)) | |
55 | 88 | then throw("can accept thanks tokens only") | |
56 | 89 | else pmt | |
57 | 90 | case _ => | |
58 | 91 | throw("Payment is required") | |
59 | 92 | } | |
60 | 93 | let price = getInteger(this, (("item_" + itemId) + "_price")) | |
61 | 94 | let priceReal = match price { | |
62 | 95 | case in: Int => | |
63 | 96 | if ((pmt.amount >= in)) | |
64 | 97 | then in | |
65 | 98 | else throw(("Price is too low, you have to pay: " + toString(in))) | |
66 | 99 | case _ => | |
67 | 100 | throw(("The price is not defined: " + itemId)) | |
68 | 101 | } | |
69 | 102 | let buyer = getString(this, (("item_" + itemId) + "_buyer")) | |
70 | 103 | let buyerAddressString = match buyer { | |
71 | 104 | case b: String => | |
72 | 105 | if ((b == callerAddress)) | |
73 | 106 | then b | |
74 | 107 | else throw("You are not the buyer of it!") | |
75 | 108 | case _ => | |
76 | 109 | throw("buyerAddress not found") | |
77 | 110 | } | |
78 | 111 | if ((assetBalance(this, fromBase58String(itemId)) == 0)) | |
79 | 112 | then throw(("There is no such item: " + itemId)) | |
80 | 113 | else if (if (if (inWhiteList) | |
81 | 114 | then (callerAddress == buyerAddressString) | |
82 | 115 | else false) | |
83 | 116 | then (pmt.amount >= priceReal) | |
84 | 117 | else false) | |
85 | 118 | then { | |
86 | 119 | let callerPubKey = toBase58String(i.callerPublicKey) | |
87 | 120 | let buyKey = (("item_" + itemId) + "_bought") | |
88 | 121 | WriteSet([DataEntry(buyKey, "pending")]) | |
89 | 122 | } | |
90 | 123 | else throw("Unknown error") | |
91 | 124 | } | |
92 | 125 | ||
93 | 126 | ||
94 | 127 | ||
95 | 128 | @Callable(i) | |
96 | 129 | func approve (itemId) = { | |
97 | 130 | let buyerKey = (("item_" + itemId) + "_buyer") | |
98 | 131 | let buyer = getString(this, buyerKey) | |
99 | 132 | let buyerAddress = match buyer { | |
100 | 133 | case b: String => | |
101 | 134 | addressFromString(b) | |
102 | 135 | case _ => | |
103 | 136 | throw("buyerAddress not found") | |
104 | 137 | } | |
105 | 138 | let buyerAddressReal = match buyerAddress { | |
106 | 139 | case a: Address => | |
107 | 140 | a | |
108 | 141 | case _ => | |
109 | 142 | throw("Bad address of buyer") | |
110 | 143 | } | |
144 | + | let priceKey = (("item_" + itemId) + "_price") | |
145 | + | let price = getIntegerValue(this, priceKey) | |
146 | + | let itemOwnerAddress = match getString(this, keyItemOwner(itemId)) { | |
147 | + | case a: String => | |
148 | + | match addressFromString(a) { | |
149 | + | case b: Address => | |
150 | + | b | |
151 | + | case _ => | |
152 | + | addressFromPublicKey(adminPublicKey) | |
153 | + | } | |
154 | + | case _ => | |
155 | + | addressFromPublicKey(adminPublicKey) | |
156 | + | } | |
111 | 157 | if ((i.callerPublicKey != adminPublicKey)) | |
112 | 158 | then throw("Only admin can call this function") | |
113 | 159 | else { | |
114 | 160 | let buyKey = (("item_" + itemId) + "_bought") | |
115 | 161 | let itemIdBytes = fromBase58String(itemId) | |
116 | - | ScriptResult(WriteSet([DataEntry(buyKey, "approved")]), TransferSet([ScriptTransfer(buyerAddressReal, 1, itemIdBytes)])) | |
162 | + | ScriptResult(WriteSet([DataEntry(buyKey, "approved")]), TransferSet([ScriptTransfer(buyerAddressReal, 1, itemIdBytes), ScriptTransfer(itemOwnerAddress, (price - ((price / 1) / 5)), thanksTokenId)])) | |
117 | 163 | } | |
118 | 164 | } | |
119 | 165 | ||
120 | 166 | ||
121 | 167 | ||
122 | 168 | @Callable(i) | |
123 | 169 | func reject (itemId) = if ((i.callerPublicKey != adminPublicKey)) | |
124 | 170 | then throw("Only admin can call this function") | |
125 | 171 | else { | |
126 | 172 | let buyKey = (("item_" + itemId) + "_bought") | |
127 | 173 | let buyerKey = (("item_" + itemId) + "_buyer") | |
128 | 174 | let priceKey = (("item_" + itemId) + "_price") | |
129 | 175 | let buyerAddress = addressFromStringValue(getStringValue(this, buyerKey)) | |
130 | 176 | let price = getIntegerValue(this, priceKey) | |
131 | 177 | ScriptResult(WriteSet([DataEntry(buyKey, "rejected")]), TransferSet([ScriptTransfer(buyerAddress, price, thanksTokenId)])) | |
132 | 178 | } | |
133 | 179 | ||
134 | 180 | ||
135 | 181 | ||
136 | 182 | @Callable(i) | |
137 | - | func addItem (buyerAddress,price) = { | |
183 | + | func addItem (buyerAddress,price,ownerAddress) = { | |
138 | 184 | let inWhiteListUnit = getBoolean(this, buyerAddress) | |
139 | 185 | let inWhiteList = match inWhiteListUnit { | |
140 | 186 | case w: Boolean => | |
141 | 187 | if (w) | |
142 | 188 | then true | |
143 | 189 | else throw("Buyer is not in the white-list[removed]") | |
144 | 190 | case _ => | |
145 | 191 | throw(("Buyer is not in the white-list: " + buyerAddress)) | |
146 | 192 | } | |
147 | 193 | if (if ((i.callerPublicKey != adminPublicKey)) | |
148 | 194 | then true | |
149 | 195 | else (inWhiteList == false)) | |
150 | 196 | then throw("Only admin can call this function") | |
151 | 197 | else { | |
152 | 198 | let pmt = match i.payment { | |
153 | 199 | case pmt: AttachedPayment => | |
154 | 200 | pmt | |
155 | 201 | case _ => | |
156 | 202 | throw("Payment is required") | |
157 | 203 | } | |
158 | 204 | let paymentAssetId = match pmt.assetId { | |
159 | 205 | case d: ByteVector => | |
160 | 206 | d | |
161 | 207 | case _ => | |
162 | 208 | throw("You have attached waves to the payment *facepalm*") | |
163 | 209 | } | |
164 | 210 | let nftAssetInfo = assetInfo(paymentAssetId) | |
165 | 211 | let nftAssetInfoReal = match nftAssetInfo { | |
166 | 212 | case ai: Asset => | |
167 | 213 | ai | |
168 | 214 | case _ => | |
169 | 215 | throw("Cant get asset info") | |
170 | 216 | } | |
171 | 217 | if (if (if ((nftAssetInfoReal.quantity != 1)) | |
172 | 218 | then true | |
173 | 219 | else (nftAssetInfoReal.decimals != 0)) | |
174 | 220 | then true | |
175 | 221 | else (nftAssetInfoReal.issuerPublicKey != adminPublicKey)) | |
176 | 222 | then throw("Token should be an NFT and from admin user") | |
177 | 223 | else { | |
178 | - | let buyerKey = (("item_" + toBase58String(nftAssetInfoReal.id)) + "_buyer") | |
179 | - | let priceKey = (("item_" + toBase58String(nftAssetInfoReal.id)) + "_price") | |
180 | - | WriteSet([DataEntry(buyerKey, buyerAddress), DataEntry(priceKey, price)]) | |
224 | + | let itemId = toBase58String(nftAssetInfoReal.id) | |
225 | + | let buyerKey = (("item_" + itemId) + "_buyer") | |
226 | + | let priceKey = (("item_" + itemId) + "_price") | |
227 | + | WriteSet([DataEntry(buyerKey, buyerAddress), DataEntry(priceKey, price), DataEntry(keyItemOwner(itemId), ownerAddress)]) | |
181 | 228 | } | |
182 | 229 | } | |
230 | + | } | |
231 | + | ||
232 | + | ||
233 | + | ||
234 | + | @Callable(i) | |
235 | + | func startFunding (id,fundraisingEndTimestamp,implmenetationEndTimestamp,targetSum) = { | |
236 | + | let lastBlockTimestamp = lastBlock.timestamp | |
237 | + | if ((0 > ((fundraisingEndTimestamp - lastBlockTimestamp) - 60))) | |
238 | + | then throw("End time should at least 60 seconds more than the last block time") | |
239 | + | else if ((fundraisingEndTimestamp > implmenetationEndTimestamp)) | |
240 | + | then throw("Implementation end time should more or equal to endTimestamp") | |
241 | + | else if (isDefined(getInteger(this, keyFunding(id)))) | |
242 | + | then throw("Funding with the same ID already exists") | |
243 | + | else if ((1000 > targetSum)) | |
244 | + | then throw("You cannot fundraise less than 1000 tokens") | |
245 | + | else WriteSet([DataEntry(keyFunding(id), height), DataEntry(keyEndTimestamp(id), fundraisingEndTimestamp), DataEntry(keyImplEndTimestamp(id), implmenetationEndTimestamp), DataEntry(keyTargetSum(id), targetSum), DataEntry(keyOwner(id), toBase58String(i.callerPublicKey)), DataEntry(keyRaised(id), 0), DataEntry(keyReleaseVotes(id), 0), DataEntry(keyReleasedTokens(id), false)]) | |
246 | + | } | |
247 | + | ||
248 | + | ||
249 | + | ||
250 | + | @Callable(i) | |
251 | + | func fund (id) = { | |
252 | + | let pmt = extract(i.payment) | |
253 | + | let targetSum = getIntegerValue(this, keyTargetSum(id)) | |
254 | + | let endTimestamp = getIntegerValue(this, keyEndTimestamp(id)) | |
255 | + | let owner = getStringValue(this, keyOwner(id)) | |
256 | + | let raised = getIntegerValue(this, keyRaised(id)) | |
257 | + | let alreadyFundedByUser = match getInteger(this, keyUserFunded(id, toBase58String(i.callerPublicKey))) { | |
258 | + | case v: Int => | |
259 | + | v | |
260 | + | case _ => | |
261 | + | 0 | |
262 | + | } | |
263 | + | if ((pmt.assetId != thanksTokenId)) | |
264 | + | then throw(("You have to attach proper tokens with id: " + toBase58String(thanksTokenId))) | |
265 | + | else if ((owner == toBase58String(i.callerPublicKey))) | |
266 | + | then throw("You cannot fund your own target") | |
267 | + | else if ((endTimestamp > lastBlock.timestamp)) | |
268 | + | then throw("This target is finished already") | |
269 | + | else if (((alreadyFundedByUser + pmt.amount) > ((targetSum / 3) + 1))) | |
270 | + | then throw(("You cannot fund more than 33% of the whole sum which is " + toString((((targetSum / 3) + 1) - alreadyFundedByUser)))) | |
271 | + | else WriteSet([DataEntry(keyUserFunded(id, toBase58String(i.callerPublicKey)), (alreadyFundedByUser + pmt.amount)), DataEntry(keyRaised(id), (raised + pmt.amount))]) | |
272 | + | } | |
273 | + | ||
274 | + | ||
275 | + | ||
276 | + | @Callable(i) | |
277 | + | func voteForRelease (id) = { | |
278 | + | let endTimestamp = getIntegerValue(this, keyEndTimestamp(id)) | |
279 | + | let implEndTimestamp = getIntegerValue(this, keyImplEndTimestamp(id)) | |
280 | + | let votePower = getIntegerValue(this, keyUserFunded(id, toBase58String(i.callerPublicKey))) | |
281 | + | let votedPower = getIntegerValue(this, keyReleaseVotes(id)) | |
282 | + | let targetSum = getIntegerValue(this, keyTargetSum(id)) | |
283 | + | let raised = getIntegerValue(this, keyRaised(id)) | |
284 | + | let released = getBooleanValue(this, keyReleasedTokens(id)) | |
285 | + | let owner = keyOwner(id) | |
286 | + | if ((implEndTimestamp > lastBlock.timestamp)) | |
287 | + | then throw("This target is not finished yet") | |
288 | + | else if ((targetSum > raised)) | |
289 | + | then throw("This target didn't reach target") | |
290 | + | else if (released) | |
291 | + | then throw("This target was released already") | |
292 | + | else if (isDefined(getBoolean(this, keyUserVoted(id, toBase58String(i.callerPublicKey))))) | |
293 | + | then throw("You already voted for the target") | |
294 | + | else if (((votedPower + votePower) > (raised / 2))) | |
295 | + | then { | |
296 | + | let ownerPrize = (raised - ((raised / 1) / 5)) | |
297 | + | ScriptResult(WriteSet([DataEntry(keyReleaseVotes(id), (votedPower + votePower)), DataEntry(keyReleasedTokens(id), true)]), TransferSet([ScriptTransfer(addressFromPublicKey(toBytes(owner)), ownerPrize, thanksTokenId)])) | |
298 | + | } | |
299 | + | else WriteSet([DataEntry(keyReleaseVotes(id), (votedPower + votePower))]) | |
300 | + | } | |
301 | + | ||
302 | + | ||
303 | + | ||
304 | + | @Callable(i) | |
305 | + | func refundUser (id) = { | |
306 | + | let implEndTimestamp = getIntegerValue(this, keyImplEndTimestamp(id)) | |
307 | + | let fundedAmount = getIntegerValue(this, keyUserFunded(id, toBase58String(i.callerPublicKey))) | |
308 | + | let targetSum = getIntegerValue(this, keyTargetSum(id)) | |
309 | + | let raised = getIntegerValue(this, keyRaised(id)) | |
310 | + | if ((implEndTimestamp > lastBlock.timestamp)) | |
311 | + | then throw("This target is not finished yet") | |
312 | + | else if ((raised > targetSum)) | |
313 | + | then throw("This target raised enough tokens") | |
314 | + | else if ((fundedAmount > 0)) | |
315 | + | then throw("You have no power here") | |
316 | + | else ScriptResult(WriteSet([DataEntry(keyUserFunded(id, toBase58String(i.callerPublicKey)), 0)]), TransferSet([ScriptTransfer(i.caller, fundedAmount, thanksTokenId)])) | |
183 | 317 | } | |
184 | 318 | ||
185 | 319 |
github/deemru/w8io/3ef1775 67.42 ms ◑