tx · 9jrnk6eaDFn3JSrhCYTNQrWB6fCrrvHEwrWZgsVdM7To

3PPpppPpSCRStzVGeZTPsZb5h467qbyqadm:  -0.01400000 Waves

2019.10.16 21:28 [1753083] smart account 3PPpppPpSCRStzVGeZTPsZb5h467qbyqadm > SELF 0.00000000 Waves

{ "type": 13, "id": "9jrnk6eaDFn3JSrhCYTNQrWB6fCrrvHEwrWZgsVdM7To", "fee": 1400000, "feeAssetId": null, "timestamp": 1571250514464, "version": 1, "sender": "3PPpppPpSCRStzVGeZTPsZb5h467qbyqadm", "senderPublicKey": "9h8XTnBfjfoV5MWJVDUMkaLNMZbWpUqrTz1wjaAejUez", "proofs": [ "58EFCfy66QgZzEMKSzABMcE4HhjBp69PXtXRwNSQVj3NL9hae1Ak9faXoGo5vYnmNPcj5G7u2hPxk5anfYSTXprf" ], "script": "base64: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", "chainId": 87, "height": 1753083, "spentComplexity": 0 } View: original | compacted Prev: 5kgVNdUpiToDFQ5vmM3zu5PjfCRgS8upsjn4DfcdzhVn Next: 4se9jS3yRz5YkVqs8GzYoAebzjYt7pRxR8Xso2PL4Esn Diff:
OldNewDifferences
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let uTokenId = base58'GHh7EMnVnUBCYNJMktuLPVr3P2oCqBCb4c87fBCZ5CzY'
5+
6+let admin = addressFromStringValue("3P96VpN2dBS1111111ydADa5a6AD1Un9iUv")
7+
8+let shutdownFlag = match getBoolean(this, "shutdown_flag") {
9+ case bool: Boolean =>
10+ bool
11+ case _: Unit =>
12+ false
13+ case _ =>
14+ throw()
15+}
16+
17+let shutdownMessage = match getString(this, "shutdown_message") {
18+ case str: String =>
19+ str
20+ case _: Unit =>
21+ "Forbidden"
22+ case _ =>
23+ throw()
24+}
25+
26+let reserve = match getInteger(this, "reserve") {
27+ case int: Int =>
28+ int
29+ case _: Unit =>
30+ 0
31+ case _ =>
32+ throw()
33+}
34+
35+let balance = match getInteger(this, "balance") {
36+ case int: Int =>
37+ int
38+ case _: Unit =>
39+ 0
40+ case _ =>
41+ throw()
42+}
543
644 func checkStatus (address) = {
745 let statusUnlimited = match getBoolean(this, (address + "_unlimited")) {
2765
2866
2967 @Callable(i)
30-func addAsset (assetId) = {
31- let addingPrice = (100 * 100000000)
32- let addingPriceStr = "100"
33- let payment = valueOrErrorMessage(i.payment, "Where is payment?")
34- if (if (isDefined(payment.assetId))
35- then (payment.assetId != uTokenId)
36- else false)
37- then throw("OTCu or WAVES only")
38- else if ((payment.amount != addingPrice))
39- then throw((("You have to pay " + addingPriceStr) + " OTCu or WAVES"))
40- else if (!(isDefined(assetInfo(fromBase58String(assetId)))))
41- then throw("There is no asset with specified id")
68+func addAsset (assetId) = if (shutdownFlag)
69+ then throw(shutdownMessage)
70+ else {
71+ let addingPrice = (100 * 100000000)
72+ let addingPriceStr = "100"
73+ let payment = valueOrErrorMessage(i.payment, "Where is payment?")
74+ if (if (isDefined(payment.assetId))
75+ then (payment.assetId != uTokenId)
76+ else false)
77+ then throw("OTCu or WAVES only")
78+ else if ((payment.amount != addingPrice))
79+ then throw((("You have to pay " + addingPriceStr) + " OTCu or WAVES"))
80+ else if (!(isDefined(assetInfo(fromBase58String(assetId)))))
81+ then throw("There is no asset with specified id")
82+ else {
83+ let assets = match getString(this, "assets") {
84+ case str: String =>
85+ str
86+ case _: Unit =>
87+ ""
88+ case _ =>
89+ throw()
90+ }
91+ if (isDefined(indexOf(assets, assetId)))
92+ then throw("Asset is already available")
93+ else {
94+ let list0 = [DataEntry("assets", ((assets + assetId) + ","))]
95+ let list1 = if ((payment.assetId == uTokenId))
96+ then DataEntry("reserve", (reserve + payment.amount)) :: list0
97+ else if (!(isDefined(payment.assetId)))
98+ then DataEntry("balance", (balance + payment.amount)) :: list0
99+ else list0
100+ WriteSet(list1)
101+ }
102+ }
103+ }
104+
105+
106+
107+@Callable(i)
108+func pro () = if (shutdownFlag)
109+ then throw(shutdownMessage)
110+ else {
111+ let address = toBase58String(i.caller.bytes)
112+ let unlimitedPrice = (50 * 100000000)
113+ let unlimitedPriceStr = "50"
114+ let monthPrice = (10 * 100000000)
115+ let monthPriceStr = "10"
116+ let payment = valueOrErrorMessage(i.payment, "Where is payment?")
117+ if (if (isDefined(payment.assetId))
118+ then (payment.assetId != uTokenId)
119+ else false)
120+ then throw("OTCu or WAVES only")
121+ else if (if ((payment.amount != unlimitedPrice))
122+ then (payment.amount != monthPrice)
123+ else false)
124+ then throw("Invalid payment")
42125 else {
43- let assets = match getString(this, "assets") {
44- case str: String =>
45- str
126+ let unlimited = (payment.amount == unlimitedPrice)
127+ let currentUnlimited = match getBoolean(this, (address + "_unlimited")) {
128+ case bool: Boolean =>
129+ bool
46130 case _: Unit =>
47- ""
131+ false
48132 case _ =>
49133 throw()
50134 }
51- if (isDefined(indexOf(assets, assetId)))
52- then throw("Asset is already available")
135+ let currentTime = match getInteger(this, (address + "_time")) {
136+ case int: Int =>
137+ int
138+ case _: Unit =>
139+ lastBlock.timestamp
140+ case _ =>
141+ throw()
142+ }
143+ if (currentUnlimited)
144+ then throw("You have unlimited PRO status already. What do you want?")
53145 else {
54- let list0 = [DataEntry("assets", ((assets + assetId) + ","))]
55- let reserve = match getInteger(this, "reserve") {
56- case int: Int =>
57- int
58- case _: Unit =>
59- 0
60- case _ =>
61- throw()
62- }
63- let balance = match getInteger(this, "balance") {
64- case int: Int =>
65- int
66- case _: Unit =>
67- 0
68- case _ =>
69- throw()
70- }
146+ let month = 2629743000
147+ let list0 = [DataEntry((address + "_unlimited"), unlimited), DataEntry((address + "_time"), if (unlimited)
148+ then 0
149+ else (currentTime + month))]
71150 let list1 = if ((payment.assetId == uTokenId))
72151 then DataEntry("reserve", (reserve + payment.amount)) :: list0
73152 else if (!(isDefined(payment.assetId)))
76155 WriteSet(list1)
77156 }
78157 }
79- }
158+ }
80159
81160
82161
83162 @Callable(i)
84-func pro () = {
85- let address = toBase58String(i.caller.bytes)
86- let unlimitedPrice = (50 * 100000000)
87- let unlimitedPriceStr = "50"
88- let monthPrice = (10 * 100000000)
89- let monthPriceStr = "10"
90- let payment = valueOrErrorMessage(i.payment, "Where is payment?")
91- if (if (isDefined(payment.assetId))
92- then (payment.assetId != uTokenId)
93- else false)
94- then throw("OTCu or WAVES only")
95- else if (if ((payment.amount != unlimitedPrice))
96- then (payment.amount != monthPrice)
97- else false)
98- then throw("Invalid payment")
99- else {
100- let unlimited = (payment.amount == unlimitedPrice)
101- let currentUnlimited = match getBoolean(this, (address + "_unlimited")) {
102- case bool: Boolean =>
103- bool
104- case _: Unit =>
105- false
106- case _ =>
107- throw()
108- }
109- let currentTime = match getInteger(this, (address + "_time")) {
110- case int: Int =>
111- int
112- case _: Unit =>
113- lastBlock.timestamp
114- case _ =>
115- throw()
116- }
117- if (currentUnlimited)
118- then throw("You have unlimited PRO status already. What do you want?")
119- else {
120- let month = 2629743000
121- let list0 = [DataEntry((address + "_unlimited"), unlimited), DataEntry((address + "_time"), if (unlimited)
122- then 0
123- else (currentTime + month))]
124- let reserve = match getInteger(this, "reserve") {
125- case int: Int =>
126- int
127- case _: Unit =>
128- 0
129- case _ =>
130- throw()
131- }
132- let balance = match getInteger(this, "balance") {
133- case int: Int =>
134- int
135- case _: Unit =>
136- 0
137- case _ =>
138- throw()
139- }
140- let list1 = if ((payment.assetId == uTokenId))
141- then DataEntry("reserve", (reserve + payment.amount)) :: list0
142- else if (!(isDefined(payment.assetId)))
143- then DataEntry("balance", (balance + payment.amount)) :: list0
144- else list0
145- WriteSet(list1)
146- }
147- }
148- }
163+func buyUtilityToken () = if (shutdownFlag)
164+ then throw(shutdownMessage)
165+ else {
166+ let payment = valueOrErrorMessage(i.payment, "Where is payment?")
167+ if (isDefined(payment.assetId))
168+ then throw("WAVES only")
169+ else if ((payment.amount > reserve))
170+ then throw("Not enougth asset in dApp")
171+ else ScriptResult(WriteSet([DataEntry("reserve", (reserve - payment.amount)), DataEntry("balance", (balance + payment.amount))]), TransferSet([ScriptTransfer(i.caller, payment.amount, uTokenId)]))
172+ }
149173
150174
151175
152176 @Callable(i)
153-func buyUtilityToken () = {
154- let payment = valueOrErrorMessage(i.payment, "Where is payment?")
155- if (isDefined(payment.assetId))
156- then throw("WAVES only")
157- else {
158- let reserve = match getInteger(this, "reserve") {
159- case int: Int =>
160- int
161- case _: Unit =>
162- 0
163- case _ =>
164- throw()
165- }
166- let balance = match getInteger(this, "balance") {
167- case int: Int =>
168- int
169- case _: Unit =>
170- 0
171- case _ =>
172- throw()
173- }
174- if ((payment.amount > reserve))
175- then throw("Not enougth asset in dApp")
176- else ScriptResult(WriteSet([DataEntry("reserve", (reserve - payment.amount)), DataEntry("balance", (balance + payment.amount))]), TransferSet([ScriptTransfer(i.caller, payment.amount, uTokenId)]))
177- }
178- }
177+func makeSell (priceAsset,priceAssetAmount,all,password) = if (shutdownFlag)
178+ then throw(shutdownMessage)
179+ else if (if ((priceAsset != "WAVES"))
180+ then !(isDefined(assetInfo(fromBase58String(priceAsset))))
181+ else false)
182+ then throw("There is no asset with specified id")
183+ else if ((0 >= priceAssetAmount))
184+ then throw("Amount of price asset must be positive")
185+ else {
186+ let payment = valueOrErrorMessage(i.payment, "Where is payment?")
187+ if ((0 >= payment.amount))
188+ then throw("Amount must be positive")
189+ else {
190+ let amountAsset = match payment.assetId {
191+ case p: ByteVector =>
192+ toBase58String(p)
193+ case _ =>
194+ "WAVES"
195+ }
196+ let assets = valueOrErrorMessage(getString(this, "assets"), "There are not available assets")
197+ if (if (!(isDefined(indexOf(assets, priceAsset))))
198+ then true
199+ else !(isDefined(indexOf(assets, amountAsset))))
200+ then throw("Asset are not available for trading")
201+ else {
202+ let address = toBase58String(i.caller.bytes)
203+ if (if (!(checkStatus(address)))
204+ then if (all)
205+ then true
206+ else (password != "")
207+ else false)
208+ then throw("You must have pro status to use these features")
209+ else {
210+ let orderId = ("order_" + toBase58String(i.transactionId))
211+ let passwordValid = fromBase58String(password)
212+ let data = (((((((((((((((("sell" + "_") + toString(payment.amount)) + "_") + amountAsset) + "_") + toString(priceAssetAmount)) + "_") + priceAsset) + "_") + address) + "_") + toString(all)) + "_") + password) + "_") + toString(0))
213+ WriteSet([DataEntry(orderId, data)])
214+ }
215+ }
216+ }
217+ }
179218
180219
181220
182221 @Callable(i)
183-func makeSell (priceAsset,priceAssetAmount,all,password) = if (if ((priceAsset != "WAVES"))
184- then !(isDefined(assetInfo(fromBase58String(priceAsset))))
185- else false)
186- then throw("There is no asset with specified id")
187- else if ((0 >= priceAssetAmount))
188- then throw("Amount of price asset must be positive")
189- else {
190- let payment = valueOrErrorMessage(i.payment, "Where is payment?")
191- if ((0 >= payment.amount))
192- then throw("Amount must be positive")
193- else {
194- let amountAsset = match payment.assetId {
195- case p: ByteVector =>
196- toBase58String(p)
197- case _ =>
198- "WAVES"
199- }
200- let assets = valueOrErrorMessage(getString(this, "assets"), "There are not available assets")
201- if (if (!(isDefined(indexOf(assets, priceAsset))))
202- then true
203- else !(isDefined(indexOf(assets, amountAsset))))
204- then throw("Asset are not available for trading")
205- else {
206- let address = toBase58String(i.caller.bytes)
207- if (if (!(checkStatus(address)))
208- then if (all)
209- then true
210- else (password != "")
211- else false)
212- then throw("You must have pro status to use these features")
213- else {
214- let orderId = ("order_" + toBase58String(i.transactionId))
215- let passwordValid = fromBase58String(password)
216- let data = (((((((((((((((("sell" + "_") + toString(payment.amount)) + "_") + amountAsset) + "_") + toString(priceAssetAmount)) + "_") + priceAsset) + "_") + address) + "_") + toString(all)) + "_") + password) + "_") + toString(0))
217- WriteSet([DataEntry(orderId, data)])
218- }
219- }
220- }
221- }
222+func makeBuy (amountAsset,amount,all,password) = if (shutdownFlag)
223+ then throw(shutdownMessage)
224+ else if (if ((amountAsset != "WAVES"))
225+ then !(isDefined(assetInfo(fromBase58String(amountAsset))))
226+ else false)
227+ then throw("There is no asset with specified id")
228+ else if ((0 >= amount))
229+ then throw("Amount must be positive")
230+ else {
231+ let payment = valueOrErrorMessage(i.payment, "where is payment?")
232+ let priceAssetAmount = payment.amount
233+ if ((0 >= priceAssetAmount))
234+ then throw("amount must be positive")
235+ else {
236+ let priceAsset = match payment.assetId {
237+ case p: ByteVector =>
238+ toBase58String(p)
239+ case _ =>
240+ "WAVES"
241+ }
242+ let assets = valueOrErrorMessage(getString(this, "assets"), "There are not available assets")
243+ if (if (!(isDefined(indexOf(assets, priceAsset))))
244+ then true
245+ else !(isDefined(indexOf(assets, amountAsset))))
246+ then throw("Asset are not available for trading")
247+ else {
248+ let address = toBase58String(i.caller.bytes)
249+ if (if (!(checkStatus(address)))
250+ then if (all)
251+ then true
252+ else (password != "")
253+ else false)
254+ then throw("You must have pro status to use these features")
255+ else {
256+ let orderId = ("order_" + toBase58String(i.transactionId))
257+ if ((amount == 0))
258+ then throw("invalid buy amount")
259+ else {
260+ let data = (((((((((((((((("buy" + "_") + toString(amount)) + "_") + amountAsset) + "_") + toString(priceAssetAmount)) + "_") + priceAsset) + "_") + address) + "_") + toString(all)) + "_") + password) + "_") + toString(0))
261+ WriteSet([DataEntry(orderId, data)])
262+ }
263+ }
264+ }
265+ }
266+ }
222267
223268
224269
225270 @Callable(i)
226-func makeBuy (amountAsset,amount,all,password) = if (if ((amountAsset != "WAVES"))
227- then !(isDefined(assetInfo(fromBase58String(amountAsset))))
228- else false)
229- then throw("There is no asset with specified id")
230- else if ((0 >= amount))
231- then throw("Amount must be positive")
232- else {
233- let payment = valueOrErrorMessage(i.payment, "where is payment?")
234- let priceAssetAmount = payment.amount
235- if ((0 >= priceAssetAmount))
236- then throw("amount must be positive")
237- else {
238- let priceAsset = match payment.assetId {
239- case p: ByteVector =>
240- toBase58String(p)
241- case _ =>
242- "WAVES"
243- }
244- let assets = valueOrErrorMessage(getString(this, "assets"), "There are not available assets")
245- if (if (!(isDefined(indexOf(assets, priceAsset))))
246- then true
247- else !(isDefined(indexOf(assets, amountAsset))))
248- then throw("Asset are not available for trading")
271+func takeSell (orderId,sig) = if (shutdownFlag)
272+ then throw(shutdownMessage)
273+ else {
274+ let payment = valueOrErrorMessage(i.payment, "Where is payment?")
275+ let priceAssetAmount = payment.amount
276+ if ((0 >= priceAssetAmount))
277+ then throw("Amount must be positive")
278+ else {
279+ let priceAsset = match payment.assetId {
280+ case p: ByteVector =>
281+ toBase58String(p)
282+ case _ =>
283+ "WAVES"
284+ }
285+ let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id")
286+ let parts = split(data, "_")
287+ let orderType = parts[0]
288+ let orderAmount = parseIntValue(parts[1])
289+ let orderAmountAsset = parts[2]
290+ let orderPriceAssetAmount = parseIntValue(parts[3])
291+ let orderPriceAsset = parts[4]
292+ let orderOwner = value(addressFromString(parts[5]))
293+ let orderAll = if ((parts[6] == "true"))
294+ then true
295+ else false
296+ let orderPassword = parts[7]
297+ let orderSpent = parseIntValue(parts[8])
298+ if ((orderType != "sell"))
299+ then throw("Invalid order type")
300+ else if ((orderPriceAsset != priceAsset))
301+ then throw(("Payment asset must be " + orderPriceAsset))
249302 else {
250- let address = toBase58String(i.caller.bytes)
251- if (if (!(checkStatus(address)))
252- then if (all)
253- then true
254- else (password != "")
255- else false)
256- then throw("You must have pro status to use these features")
303+ let valid = if ((orderPassword != ""))
304+ then sigVerify(i.callerPublicKey, fromBase58String(sig), fromBase58String(orderPassword))
305+ else true
306+ if (!(valid))
307+ then throw("The order is private")
257308 else {
258- let orderId = ("order_" + toBase58String(i.transactionId))
309+ let amount = ((priceAssetAmount * orderAmount) / orderPriceAssetAmount)
259310 if ((amount == 0))
260- then throw("invalid buy amount")
261- else {
262- let data = (((((((((((((((("buy" + "_") + toString(amount)) + "_") + amountAsset) + "_") + toString(priceAssetAmount)) + "_") + priceAsset) + "_") + address) + "_") + toString(all)) + "_") + password) + "_") + toString(0))
263- WriteSet([DataEntry(orderId, data)])
264- }
311+ then throw("Invalid amount")
312+ else if (if (orderAll)
313+ then (orderAmount > amount)
314+ else false)
315+ then throw("You must take all or none")
316+ else if ((amount > (orderAmount - orderSpent)))
317+ then throw("Not enougth asset in order")
318+ else {
319+ let newData = (dropRight(data, size(parts[8])) + toString((orderSpent + amount)))
320+ let toCaller = ScriptTransfer(i.caller, amount, if ((orderAmountAsset == "WAVES"))
321+ then unit
322+ else fromBase58String(orderAmountAsset))
323+ let toOwner = ScriptTransfer(orderOwner, priceAssetAmount, if ((orderPriceAsset == "WAVES"))
324+ then unit
325+ else fromBase58String(orderPriceAsset))
326+ ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([toCaller, toOwner]))
327+ }
265328 }
266329 }
267- }
268- }
330+ }
331+ }
269332
270333
271334
272335 @Callable(i)
273-func takeSell (orderId,sig) = {
274- let payment = valueOrErrorMessage(i.payment, "Where is payment?")
275- let priceAssetAmount = payment.amount
276- if ((0 >= priceAssetAmount))
277- then throw("Amount must be positive")
278- else {
279- let priceAsset = match payment.assetId {
280- case p: ByteVector =>
281- toBase58String(p)
282- case _ =>
283- "WAVES"
284- }
285- let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id")
286- let parts = split(data, "_")
287- let orderType = parts[0]
288- let orderAmount = parseIntValue(parts[1])
289- let orderAmountAsset = parts[2]
290- let orderPriceAssetAmount = parseIntValue(parts[3])
291- let orderPriceAsset = parts[4]
292- let orderOwner = value(addressFromString(parts[5]))
293- let orderAll = if ((parts[6] == "true"))
294- then true
295- else false
296- let orderPassword = parts[7]
297- let orderSpent = parseIntValue(parts[8])
298- if ((orderType != "sell"))
299- then throw("Invalid order type")
300- else if ((orderPriceAsset != priceAsset))
301- then throw(("Payment asset must be " + orderPriceAsset))
302- else {
303- let valid = if ((orderPassword != ""))
304- then sigVerify(i.callerPublicKey, fromBase58String(sig), fromBase58String(orderPassword))
305- else true
306- if (!(valid))
307- then throw("The order is private")
308- else {
309- let amount = ((priceAssetAmount * orderAmount) / orderPriceAssetAmount)
310- if ((amount == 0))
311- then throw("Invalid amount")
312- else if (if (orderAll)
313- then (orderAmount > amount)
314- else false)
315- then throw("You must take all or none")
316- else if ((amount > (orderAmount - orderSpent)))
317- then throw("Not enougth asset in order")
318- else {
319- let newData = (dropRight(data, size(parts[8])) + toString((orderSpent + amount)))
320- let toCaller = ScriptTransfer(i.caller, amount, if ((orderAmountAsset == "WAVES"))
321- then unit
322- else fromBase58String(orderAmountAsset))
323- let toOwner = ScriptTransfer(orderOwner, priceAssetAmount, if ((orderPriceAsset == "WAVES"))
324- then unit
325- else fromBase58String(orderPriceAsset))
326- ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([toCaller, toOwner]))
327- }
328- }
329- }
330- }
331- }
332-
333-
334-
335-@Callable(i)
336-func takeBuy (orderId,sig) = {
337- let payment = valueOrErrorMessage(i.payment, "where is payment?")
338- let amount = payment.amount
339- if ((0 >= amount))
340- then throw("amount must be positive")
341- else {
342- let amountAsset = match payment.assetId {
343- case p: ByteVector =>
344- toBase58String(p)
345- case _ =>
346- "WAVES"
347- }
348- let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id")
349- let parts = split(data, "_")
350- let orderType = parts[0]
351- let orderAmount = parseIntValue(parts[1])
352- let orderAmountAsset = parts[2]
353- let orderPriceAssetAmount = parseIntValue(parts[3])
354- let orderPriceAsset = parts[4]
355- let orderOwner = value(addressFromString(parts[5]))
356- let orderAll = if ((parts[6] == "true"))
357- then true
358- else false
359- let orderPassword = parts[7]
360- let orderSpent = parseIntValue(parts[8])
361- if ((orderType != "buy"))
362- then throw("Invalid order type")
363- else if ((orderAmountAsset != amountAsset))
364- then throw(("payment asset must be " + orderAmountAsset))
365- else {
366- let valid = if ((orderPassword != ""))
367- then sigVerify(i.callerPublicKey, fromBase58String(sig), fromBase58String(orderPassword))
368- else true
369- if (!(valid))
370- then throw("The order is private")
371- else {
372- let priceAssetAmount = ((amount * orderPriceAssetAmount) / orderAmount)
373- if ((priceAssetAmount == 0))
374- then throw("Invalid amount")
375- else if (if (orderAll)
376- then (orderPriceAssetAmount > priceAssetAmount)
377- else false)
378- then throw("You must take all or none")
379- else if ((priceAssetAmount > (orderPriceAssetAmount - orderSpent)))
380- then throw("not enougth asset in order")
381- else {
382- let newData = (dropRight(data, size(parts[8])) + toString((orderSpent + priceAssetAmount)))
383- let toCaller = ScriptTransfer(i.caller, priceAssetAmount, if ((orderPriceAsset == "WAVES"))
384- then unit
385- else fromBase58String(orderPriceAsset))
386- let toOwner = ScriptTransfer(orderOwner, amount, if ((orderAmountAsset == "WAVES"))
387- then unit
388- else fromBase58String(orderAmountAsset))
389- ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([toCaller, toOwner]))
390- }
391- }
392- }
393- }
394- }
336+func takeBuy (orderId,sig) = if (shutdownFlag)
337+ then throw(shutdownMessage)
338+ else {
339+ let payment = valueOrErrorMessage(i.payment, "where is payment?")
340+ let amount = payment.amount
341+ if ((0 >= amount))
342+ then throw("amount must be positive")
343+ else {
344+ let amountAsset = match payment.assetId {
345+ case p: ByteVector =>
346+ toBase58String(p)
347+ case _ =>
348+ "WAVES"
349+ }
350+ let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id")
351+ let parts = split(data, "_")
352+ let orderType = parts[0]
353+ let orderAmount = parseIntValue(parts[1])
354+ let orderAmountAsset = parts[2]
355+ let orderPriceAssetAmount = parseIntValue(parts[3])
356+ let orderPriceAsset = parts[4]
357+ let orderOwner = value(addressFromString(parts[5]))
358+ let orderAll = if ((parts[6] == "true"))
359+ then true
360+ else false
361+ let orderPassword = parts[7]
362+ let orderSpent = parseIntValue(parts[8])
363+ if ((orderType != "buy"))
364+ then throw("Invalid order type")
365+ else if ((orderAmountAsset != amountAsset))
366+ then throw(("payment asset must be " + orderAmountAsset))
367+ else {
368+ let valid = if ((orderPassword != ""))
369+ then sigVerify(i.callerPublicKey, fromBase58String(sig), fromBase58String(orderPassword))
370+ else true
371+ if (!(valid))
372+ then throw("The order is private")
373+ else {
374+ let priceAssetAmount = ((amount * orderPriceAssetAmount) / orderAmount)
375+ if ((priceAssetAmount == 0))
376+ then throw("Invalid amount")
377+ else if (if (orderAll)
378+ then (orderPriceAssetAmount > priceAssetAmount)
379+ else false)
380+ then throw("You must take all or none")
381+ else if ((priceAssetAmount > (orderPriceAssetAmount - orderSpent)))
382+ then throw("not enougth asset in order")
383+ else {
384+ let newData = (dropRight(data, size(parts[8])) + toString((orderSpent + priceAssetAmount)))
385+ let toCaller = ScriptTransfer(i.caller, priceAssetAmount, if ((orderPriceAsset == "WAVES"))
386+ then unit
387+ else fromBase58String(orderPriceAsset))
388+ let toOwner = ScriptTransfer(orderOwner, amount, if ((orderAmountAsset == "WAVES"))
389+ then unit
390+ else fromBase58String(orderAmountAsset))
391+ ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([toCaller, toOwner]))
392+ }
393+ }
394+ }
395+ }
396+ }
395397
396398
397399
412414 let orderSpent = parseIntValue(parts[8])
413415 if ((orderType != "sell"))
414416 then throw("Invalid order type")
415- else if ((orderOwner != i.caller))
417+ else if (if ((orderOwner != i.caller))
418+ then !(shutdownFlag)
419+ else false)
416420 then throw("return should be called by order owner")
417421 else {
418422 let returnAmount = (orderAmount - orderSpent)
420424 then throw("nothing to return")
421425 else {
422426 let newData = (dropRight(data, size(parts[8])) + toString(orderAmount))
423- ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([ScriptTransfer(i.caller, returnAmount, if ((orderAmountAsset == "WAVES"))
427+ ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([ScriptTransfer(orderOwner, returnAmount, if ((orderAmountAsset == "WAVES"))
424428 then unit
425429 else fromBase58String(orderAmountAsset))]))
426430 }
446450 let orderSpent = parseIntValue(parts[8])
447451 if ((orderType != "buy"))
448452 then throw("Invalid order type")
449- else if ((orderOwner != i.caller))
453+ else if (if ((orderOwner != i.caller))
454+ then !(shutdownFlag)
455+ else false)
450456 then throw("Return should be called by order owner")
451457 else {
452458 let returnAmount = (orderPriceAssetAmount - orderSpent)
454460 then throw("nothing to return")
455461 else {
456462 let newData = (dropRight(data, size(parts[8])) + toString(orderPriceAssetAmount))
457- ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([ScriptTransfer(i.caller, returnAmount, if ((orderPriceAsset == "WAVES"))
463+ ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([ScriptTransfer(orderOwner, returnAmount, if ((orderPriceAsset == "WAVES"))
458464 then unit
459465 else fromBase58String(orderPriceAsset))]))
460466 }
462468 }
463469
464470
471+
472+@Callable(i)
473+func withdraw (mode) = if ((i.caller != admin))
474+ then throw("You should be an admin")
475+ else if (if (if ((mode != "balance"))
476+ then (mode != "reserve")
477+ else false)
478+ then (mode != "all")
479+ else false)
480+ then throw("Specify the mode: balance, reserve or all")
481+ else {
482+ let balanceEntry = DataEntry("balance", 0)
483+ let balanceTransfer = ScriptTransfer(admin, balance, unit)
484+ let reserveEntry = DataEntry("reserve", 0)
485+ let reserveTransfer = ScriptTransfer(admin, reserve, unit)
486+ let writeSet = if ((mode == "balance"))
487+ then [balanceEntry]
488+ else if ((mode == "reserve"))
489+ then [reserveEntry]
490+ else if ((mode == "all"))
491+ then [balanceEntry, reserveEntry]
492+ else nil
493+ let transferSet = if ((mode == "balance"))
494+ then [balanceTransfer]
495+ else if ((mode == "reserve"))
496+ then [reserveTransfer]
497+ else if ((mode == "all"))
498+ then [balanceTransfer, reserveTransfer]
499+ else nil
500+ ScriptResult(WriteSet(writeSet), TransferSet(transferSet))
501+ }
502+
503+
504+
505+@Callable(i)
506+func doShutdown (msg) = if ((i.caller != admin))
507+ then throw("You should be an admin")
508+ else WriteSet([DataEntry("shutdown_flag", true), DataEntry("shutdown_message", msg)])
509+
510+
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 3 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let uTokenId = base58'GHh7EMnVnUBCYNJMktuLPVr3P2oCqBCb4c87fBCZ5CzY'
5+
6+let admin = addressFromStringValue("3P96VpN2dBS1111111ydADa5a6AD1Un9iUv")
7+
8+let shutdownFlag = match getBoolean(this, "shutdown_flag") {
9+ case bool: Boolean =>
10+ bool
11+ case _: Unit =>
12+ false
13+ case _ =>
14+ throw()
15+}
16+
17+let shutdownMessage = match getString(this, "shutdown_message") {
18+ case str: String =>
19+ str
20+ case _: Unit =>
21+ "Forbidden"
22+ case _ =>
23+ throw()
24+}
25+
26+let reserve = match getInteger(this, "reserve") {
27+ case int: Int =>
28+ int
29+ case _: Unit =>
30+ 0
31+ case _ =>
32+ throw()
33+}
34+
35+let balance = match getInteger(this, "balance") {
36+ case int: Int =>
37+ int
38+ case _: Unit =>
39+ 0
40+ case _ =>
41+ throw()
42+}
543
644 func checkStatus (address) = {
745 let statusUnlimited = match getBoolean(this, (address + "_unlimited")) {
846 case bool: Boolean =>
947 bool
1048 case _: Unit =>
1149 false
1250 case _ =>
1351 throw()
1452 }
1553 let statusTime = match getInteger(this, (address + "_time")) {
1654 case int: Int =>
1755 int
1856 case _: Unit =>
1957 0
2058 case _ =>
2159 throw()
2260 }
2361 if (statusUnlimited)
2462 then true
2563 else (statusTime > lastBlock.timestamp)
2664 }
2765
2866
2967 @Callable(i)
30-func addAsset (assetId) = {
31- let addingPrice = (100 * 100000000)
32- let addingPriceStr = "100"
33- let payment = valueOrErrorMessage(i.payment, "Where is payment?")
34- if (if (isDefined(payment.assetId))
35- then (payment.assetId != uTokenId)
36- else false)
37- then throw("OTCu or WAVES only")
38- else if ((payment.amount != addingPrice))
39- then throw((("You have to pay " + addingPriceStr) + " OTCu or WAVES"))
40- else if (!(isDefined(assetInfo(fromBase58String(assetId)))))
41- then throw("There is no asset with specified id")
68+func addAsset (assetId) = if (shutdownFlag)
69+ then throw(shutdownMessage)
70+ else {
71+ let addingPrice = (100 * 100000000)
72+ let addingPriceStr = "100"
73+ let payment = valueOrErrorMessage(i.payment, "Where is payment?")
74+ if (if (isDefined(payment.assetId))
75+ then (payment.assetId != uTokenId)
76+ else false)
77+ then throw("OTCu or WAVES only")
78+ else if ((payment.amount != addingPrice))
79+ then throw((("You have to pay " + addingPriceStr) + " OTCu or WAVES"))
80+ else if (!(isDefined(assetInfo(fromBase58String(assetId)))))
81+ then throw("There is no asset with specified id")
82+ else {
83+ let assets = match getString(this, "assets") {
84+ case str: String =>
85+ str
86+ case _: Unit =>
87+ ""
88+ case _ =>
89+ throw()
90+ }
91+ if (isDefined(indexOf(assets, assetId)))
92+ then throw("Asset is already available")
93+ else {
94+ let list0 = [DataEntry("assets", ((assets + assetId) + ","))]
95+ let list1 = if ((payment.assetId == uTokenId))
96+ then DataEntry("reserve", (reserve + payment.amount)) :: list0
97+ else if (!(isDefined(payment.assetId)))
98+ then DataEntry("balance", (balance + payment.amount)) :: list0
99+ else list0
100+ WriteSet(list1)
101+ }
102+ }
103+ }
104+
105+
106+
107+@Callable(i)
108+func pro () = if (shutdownFlag)
109+ then throw(shutdownMessage)
110+ else {
111+ let address = toBase58String(i.caller.bytes)
112+ let unlimitedPrice = (50 * 100000000)
113+ let unlimitedPriceStr = "50"
114+ let monthPrice = (10 * 100000000)
115+ let monthPriceStr = "10"
116+ let payment = valueOrErrorMessage(i.payment, "Where is payment?")
117+ if (if (isDefined(payment.assetId))
118+ then (payment.assetId != uTokenId)
119+ else false)
120+ then throw("OTCu or WAVES only")
121+ else if (if ((payment.amount != unlimitedPrice))
122+ then (payment.amount != monthPrice)
123+ else false)
124+ then throw("Invalid payment")
42125 else {
43- let assets = match getString(this, "assets") {
44- case str: String =>
45- str
126+ let unlimited = (payment.amount == unlimitedPrice)
127+ let currentUnlimited = match getBoolean(this, (address + "_unlimited")) {
128+ case bool: Boolean =>
129+ bool
46130 case _: Unit =>
47- ""
131+ false
48132 case _ =>
49133 throw()
50134 }
51- if (isDefined(indexOf(assets, assetId)))
52- then throw("Asset is already available")
135+ let currentTime = match getInteger(this, (address + "_time")) {
136+ case int: Int =>
137+ int
138+ case _: Unit =>
139+ lastBlock.timestamp
140+ case _ =>
141+ throw()
142+ }
143+ if (currentUnlimited)
144+ then throw("You have unlimited PRO status already. What do you want?")
53145 else {
54- let list0 = [DataEntry("assets", ((assets + assetId) + ","))]
55- let reserve = match getInteger(this, "reserve") {
56- case int: Int =>
57- int
58- case _: Unit =>
59- 0
60- case _ =>
61- throw()
62- }
63- let balance = match getInteger(this, "balance") {
64- case int: Int =>
65- int
66- case _: Unit =>
67- 0
68- case _ =>
69- throw()
70- }
146+ let month = 2629743000
147+ let list0 = [DataEntry((address + "_unlimited"), unlimited), DataEntry((address + "_time"), if (unlimited)
148+ then 0
149+ else (currentTime + month))]
71150 let list1 = if ((payment.assetId == uTokenId))
72151 then DataEntry("reserve", (reserve + payment.amount)) :: list0
73152 else if (!(isDefined(payment.assetId)))
74153 then DataEntry("balance", (balance + payment.amount)) :: list0
75154 else list0
76155 WriteSet(list1)
77156 }
78157 }
79- }
158+ }
80159
81160
82161
83162 @Callable(i)
84-func pro () = {
85- let address = toBase58String(i.caller.bytes)
86- let unlimitedPrice = (50 * 100000000)
87- let unlimitedPriceStr = "50"
88- let monthPrice = (10 * 100000000)
89- let monthPriceStr = "10"
90- let payment = valueOrErrorMessage(i.payment, "Where is payment?")
91- if (if (isDefined(payment.assetId))
92- then (payment.assetId != uTokenId)
93- else false)
94- then throw("OTCu or WAVES only")
95- else if (if ((payment.amount != unlimitedPrice))
96- then (payment.amount != monthPrice)
97- else false)
98- then throw("Invalid payment")
99- else {
100- let unlimited = (payment.amount == unlimitedPrice)
101- let currentUnlimited = match getBoolean(this, (address + "_unlimited")) {
102- case bool: Boolean =>
103- bool
104- case _: Unit =>
105- false
106- case _ =>
107- throw()
108- }
109- let currentTime = match getInteger(this, (address + "_time")) {
110- case int: Int =>
111- int
112- case _: Unit =>
113- lastBlock.timestamp
114- case _ =>
115- throw()
116- }
117- if (currentUnlimited)
118- then throw("You have unlimited PRO status already. What do you want?")
119- else {
120- let month = 2629743000
121- let list0 = [DataEntry((address + "_unlimited"), unlimited), DataEntry((address + "_time"), if (unlimited)
122- then 0
123- else (currentTime + month))]
124- let reserve = match getInteger(this, "reserve") {
125- case int: Int =>
126- int
127- case _: Unit =>
128- 0
129- case _ =>
130- throw()
131- }
132- let balance = match getInteger(this, "balance") {
133- case int: Int =>
134- int
135- case _: Unit =>
136- 0
137- case _ =>
138- throw()
139- }
140- let list1 = if ((payment.assetId == uTokenId))
141- then DataEntry("reserve", (reserve + payment.amount)) :: list0
142- else if (!(isDefined(payment.assetId)))
143- then DataEntry("balance", (balance + payment.amount)) :: list0
144- else list0
145- WriteSet(list1)
146- }
147- }
148- }
163+func buyUtilityToken () = if (shutdownFlag)
164+ then throw(shutdownMessage)
165+ else {
166+ let payment = valueOrErrorMessage(i.payment, "Where is payment?")
167+ if (isDefined(payment.assetId))
168+ then throw("WAVES only")
169+ else if ((payment.amount > reserve))
170+ then throw("Not enougth asset in dApp")
171+ else ScriptResult(WriteSet([DataEntry("reserve", (reserve - payment.amount)), DataEntry("balance", (balance + payment.amount))]), TransferSet([ScriptTransfer(i.caller, payment.amount, uTokenId)]))
172+ }
149173
150174
151175
152176 @Callable(i)
153-func buyUtilityToken () = {
154- let payment = valueOrErrorMessage(i.payment, "Where is payment?")
155- if (isDefined(payment.assetId))
156- then throw("WAVES only")
157- else {
158- let reserve = match getInteger(this, "reserve") {
159- case int: Int =>
160- int
161- case _: Unit =>
162- 0
163- case _ =>
164- throw()
165- }
166- let balance = match getInteger(this, "balance") {
167- case int: Int =>
168- int
169- case _: Unit =>
170- 0
171- case _ =>
172- throw()
173- }
174- if ((payment.amount > reserve))
175- then throw("Not enougth asset in dApp")
176- else ScriptResult(WriteSet([DataEntry("reserve", (reserve - payment.amount)), DataEntry("balance", (balance + payment.amount))]), TransferSet([ScriptTransfer(i.caller, payment.amount, uTokenId)]))
177- }
178- }
177+func makeSell (priceAsset,priceAssetAmount,all,password) = if (shutdownFlag)
178+ then throw(shutdownMessage)
179+ else if (if ((priceAsset != "WAVES"))
180+ then !(isDefined(assetInfo(fromBase58String(priceAsset))))
181+ else false)
182+ then throw("There is no asset with specified id")
183+ else if ((0 >= priceAssetAmount))
184+ then throw("Amount of price asset must be positive")
185+ else {
186+ let payment = valueOrErrorMessage(i.payment, "Where is payment?")
187+ if ((0 >= payment.amount))
188+ then throw("Amount must be positive")
189+ else {
190+ let amountAsset = match payment.assetId {
191+ case p: ByteVector =>
192+ toBase58String(p)
193+ case _ =>
194+ "WAVES"
195+ }
196+ let assets = valueOrErrorMessage(getString(this, "assets"), "There are not available assets")
197+ if (if (!(isDefined(indexOf(assets, priceAsset))))
198+ then true
199+ else !(isDefined(indexOf(assets, amountAsset))))
200+ then throw("Asset are not available for trading")
201+ else {
202+ let address = toBase58String(i.caller.bytes)
203+ if (if (!(checkStatus(address)))
204+ then if (all)
205+ then true
206+ else (password != "")
207+ else false)
208+ then throw("You must have pro status to use these features")
209+ else {
210+ let orderId = ("order_" + toBase58String(i.transactionId))
211+ let passwordValid = fromBase58String(password)
212+ let data = (((((((((((((((("sell" + "_") + toString(payment.amount)) + "_") + amountAsset) + "_") + toString(priceAssetAmount)) + "_") + priceAsset) + "_") + address) + "_") + toString(all)) + "_") + password) + "_") + toString(0))
213+ WriteSet([DataEntry(orderId, data)])
214+ }
215+ }
216+ }
217+ }
179218
180219
181220
182221 @Callable(i)
183-func makeSell (priceAsset,priceAssetAmount,all,password) = if (if ((priceAsset != "WAVES"))
184- then !(isDefined(assetInfo(fromBase58String(priceAsset))))
185- else false)
186- then throw("There is no asset with specified id")
187- else if ((0 >= priceAssetAmount))
188- then throw("Amount of price asset must be positive")
189- else {
190- let payment = valueOrErrorMessage(i.payment, "Where is payment?")
191- if ((0 >= payment.amount))
192- then throw("Amount must be positive")
193- else {
194- let amountAsset = match payment.assetId {
195- case p: ByteVector =>
196- toBase58String(p)
197- case _ =>
198- "WAVES"
199- }
200- let assets = valueOrErrorMessage(getString(this, "assets"), "There are not available assets")
201- if (if (!(isDefined(indexOf(assets, priceAsset))))
202- then true
203- else !(isDefined(indexOf(assets, amountAsset))))
204- then throw("Asset are not available for trading")
205- else {
206- let address = toBase58String(i.caller.bytes)
207- if (if (!(checkStatus(address)))
208- then if (all)
209- then true
210- else (password != "")
211- else false)
212- then throw("You must have pro status to use these features")
213- else {
214- let orderId = ("order_" + toBase58String(i.transactionId))
215- let passwordValid = fromBase58String(password)
216- let data = (((((((((((((((("sell" + "_") + toString(payment.amount)) + "_") + amountAsset) + "_") + toString(priceAssetAmount)) + "_") + priceAsset) + "_") + address) + "_") + toString(all)) + "_") + password) + "_") + toString(0))
217- WriteSet([DataEntry(orderId, data)])
218- }
219- }
220- }
221- }
222+func makeBuy (amountAsset,amount,all,password) = if (shutdownFlag)
223+ then throw(shutdownMessage)
224+ else if (if ((amountAsset != "WAVES"))
225+ then !(isDefined(assetInfo(fromBase58String(amountAsset))))
226+ else false)
227+ then throw("There is no asset with specified id")
228+ else if ((0 >= amount))
229+ then throw("Amount must be positive")
230+ else {
231+ let payment = valueOrErrorMessage(i.payment, "where is payment?")
232+ let priceAssetAmount = payment.amount
233+ if ((0 >= priceAssetAmount))
234+ then throw("amount must be positive")
235+ else {
236+ let priceAsset = match payment.assetId {
237+ case p: ByteVector =>
238+ toBase58String(p)
239+ case _ =>
240+ "WAVES"
241+ }
242+ let assets = valueOrErrorMessage(getString(this, "assets"), "There are not available assets")
243+ if (if (!(isDefined(indexOf(assets, priceAsset))))
244+ then true
245+ else !(isDefined(indexOf(assets, amountAsset))))
246+ then throw("Asset are not available for trading")
247+ else {
248+ let address = toBase58String(i.caller.bytes)
249+ if (if (!(checkStatus(address)))
250+ then if (all)
251+ then true
252+ else (password != "")
253+ else false)
254+ then throw("You must have pro status to use these features")
255+ else {
256+ let orderId = ("order_" + toBase58String(i.transactionId))
257+ if ((amount == 0))
258+ then throw("invalid buy amount")
259+ else {
260+ let data = (((((((((((((((("buy" + "_") + toString(amount)) + "_") + amountAsset) + "_") + toString(priceAssetAmount)) + "_") + priceAsset) + "_") + address) + "_") + toString(all)) + "_") + password) + "_") + toString(0))
261+ WriteSet([DataEntry(orderId, data)])
262+ }
263+ }
264+ }
265+ }
266+ }
222267
223268
224269
225270 @Callable(i)
226-func makeBuy (amountAsset,amount,all,password) = if (if ((amountAsset != "WAVES"))
227- then !(isDefined(assetInfo(fromBase58String(amountAsset))))
228- else false)
229- then throw("There is no asset with specified id")
230- else if ((0 >= amount))
231- then throw("Amount must be positive")
232- else {
233- let payment = valueOrErrorMessage(i.payment, "where is payment?")
234- let priceAssetAmount = payment.amount
235- if ((0 >= priceAssetAmount))
236- then throw("amount must be positive")
237- else {
238- let priceAsset = match payment.assetId {
239- case p: ByteVector =>
240- toBase58String(p)
241- case _ =>
242- "WAVES"
243- }
244- let assets = valueOrErrorMessage(getString(this, "assets"), "There are not available assets")
245- if (if (!(isDefined(indexOf(assets, priceAsset))))
246- then true
247- else !(isDefined(indexOf(assets, amountAsset))))
248- then throw("Asset are not available for trading")
271+func takeSell (orderId,sig) = if (shutdownFlag)
272+ then throw(shutdownMessage)
273+ else {
274+ let payment = valueOrErrorMessage(i.payment, "Where is payment?")
275+ let priceAssetAmount = payment.amount
276+ if ((0 >= priceAssetAmount))
277+ then throw("Amount must be positive")
278+ else {
279+ let priceAsset = match payment.assetId {
280+ case p: ByteVector =>
281+ toBase58String(p)
282+ case _ =>
283+ "WAVES"
284+ }
285+ let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id")
286+ let parts = split(data, "_")
287+ let orderType = parts[0]
288+ let orderAmount = parseIntValue(parts[1])
289+ let orderAmountAsset = parts[2]
290+ let orderPriceAssetAmount = parseIntValue(parts[3])
291+ let orderPriceAsset = parts[4]
292+ let orderOwner = value(addressFromString(parts[5]))
293+ let orderAll = if ((parts[6] == "true"))
294+ then true
295+ else false
296+ let orderPassword = parts[7]
297+ let orderSpent = parseIntValue(parts[8])
298+ if ((orderType != "sell"))
299+ then throw("Invalid order type")
300+ else if ((orderPriceAsset != priceAsset))
301+ then throw(("Payment asset must be " + orderPriceAsset))
249302 else {
250- let address = toBase58String(i.caller.bytes)
251- if (if (!(checkStatus(address)))
252- then if (all)
253- then true
254- else (password != "")
255- else false)
256- then throw("You must have pro status to use these features")
303+ let valid = if ((orderPassword != ""))
304+ then sigVerify(i.callerPublicKey, fromBase58String(sig), fromBase58String(orderPassword))
305+ else true
306+ if (!(valid))
307+ then throw("The order is private")
257308 else {
258- let orderId = ("order_" + toBase58String(i.transactionId))
309+ let amount = ((priceAssetAmount * orderAmount) / orderPriceAssetAmount)
259310 if ((amount == 0))
260- then throw("invalid buy amount")
261- else {
262- let data = (((((((((((((((("buy" + "_") + toString(amount)) + "_") + amountAsset) + "_") + toString(priceAssetAmount)) + "_") + priceAsset) + "_") + address) + "_") + toString(all)) + "_") + password) + "_") + toString(0))
263- WriteSet([DataEntry(orderId, data)])
264- }
311+ then throw("Invalid amount")
312+ else if (if (orderAll)
313+ then (orderAmount > amount)
314+ else false)
315+ then throw("You must take all or none")
316+ else if ((amount > (orderAmount - orderSpent)))
317+ then throw("Not enougth asset in order")
318+ else {
319+ let newData = (dropRight(data, size(parts[8])) + toString((orderSpent + amount)))
320+ let toCaller = ScriptTransfer(i.caller, amount, if ((orderAmountAsset == "WAVES"))
321+ then unit
322+ else fromBase58String(orderAmountAsset))
323+ let toOwner = ScriptTransfer(orderOwner, priceAssetAmount, if ((orderPriceAsset == "WAVES"))
324+ then unit
325+ else fromBase58String(orderPriceAsset))
326+ ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([toCaller, toOwner]))
327+ }
265328 }
266329 }
267- }
268- }
330+ }
331+ }
269332
270333
271334
272335 @Callable(i)
273-func takeSell (orderId,sig) = {
274- let payment = valueOrErrorMessage(i.payment, "Where is payment?")
275- let priceAssetAmount = payment.amount
276- if ((0 >= priceAssetAmount))
277- then throw("Amount must be positive")
278- else {
279- let priceAsset = match payment.assetId {
280- case p: ByteVector =>
281- toBase58String(p)
282- case _ =>
283- "WAVES"
284- }
285- let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id")
286- let parts = split(data, "_")
287- let orderType = parts[0]
288- let orderAmount = parseIntValue(parts[1])
289- let orderAmountAsset = parts[2]
290- let orderPriceAssetAmount = parseIntValue(parts[3])
291- let orderPriceAsset = parts[4]
292- let orderOwner = value(addressFromString(parts[5]))
293- let orderAll = if ((parts[6] == "true"))
294- then true
295- else false
296- let orderPassword = parts[7]
297- let orderSpent = parseIntValue(parts[8])
298- if ((orderType != "sell"))
299- then throw("Invalid order type")
300- else if ((orderPriceAsset != priceAsset))
301- then throw(("Payment asset must be " + orderPriceAsset))
302- else {
303- let valid = if ((orderPassword != ""))
304- then sigVerify(i.callerPublicKey, fromBase58String(sig), fromBase58String(orderPassword))
305- else true
306- if (!(valid))
307- then throw("The order is private")
308- else {
309- let amount = ((priceAssetAmount * orderAmount) / orderPriceAssetAmount)
310- if ((amount == 0))
311- then throw("Invalid amount")
312- else if (if (orderAll)
313- then (orderAmount > amount)
314- else false)
315- then throw("You must take all or none")
316- else if ((amount > (orderAmount - orderSpent)))
317- then throw("Not enougth asset in order")
318- else {
319- let newData = (dropRight(data, size(parts[8])) + toString((orderSpent + amount)))
320- let toCaller = ScriptTransfer(i.caller, amount, if ((orderAmountAsset == "WAVES"))
321- then unit
322- else fromBase58String(orderAmountAsset))
323- let toOwner = ScriptTransfer(orderOwner, priceAssetAmount, if ((orderPriceAsset == "WAVES"))
324- then unit
325- else fromBase58String(orderPriceAsset))
326- ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([toCaller, toOwner]))
327- }
328- }
329- }
330- }
331- }
332-
333-
334-
335-@Callable(i)
336-func takeBuy (orderId,sig) = {
337- let payment = valueOrErrorMessage(i.payment, "where is payment?")
338- let amount = payment.amount
339- if ((0 >= amount))
340- then throw("amount must be positive")
341- else {
342- let amountAsset = match payment.assetId {
343- case p: ByteVector =>
344- toBase58String(p)
345- case _ =>
346- "WAVES"
347- }
348- let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id")
349- let parts = split(data, "_")
350- let orderType = parts[0]
351- let orderAmount = parseIntValue(parts[1])
352- let orderAmountAsset = parts[2]
353- let orderPriceAssetAmount = parseIntValue(parts[3])
354- let orderPriceAsset = parts[4]
355- let orderOwner = value(addressFromString(parts[5]))
356- let orderAll = if ((parts[6] == "true"))
357- then true
358- else false
359- let orderPassword = parts[7]
360- let orderSpent = parseIntValue(parts[8])
361- if ((orderType != "buy"))
362- then throw("Invalid order type")
363- else if ((orderAmountAsset != amountAsset))
364- then throw(("payment asset must be " + orderAmountAsset))
365- else {
366- let valid = if ((orderPassword != ""))
367- then sigVerify(i.callerPublicKey, fromBase58String(sig), fromBase58String(orderPassword))
368- else true
369- if (!(valid))
370- then throw("The order is private")
371- else {
372- let priceAssetAmount = ((amount * orderPriceAssetAmount) / orderAmount)
373- if ((priceAssetAmount == 0))
374- then throw("Invalid amount")
375- else if (if (orderAll)
376- then (orderPriceAssetAmount > priceAssetAmount)
377- else false)
378- then throw("You must take all or none")
379- else if ((priceAssetAmount > (orderPriceAssetAmount - orderSpent)))
380- then throw("not enougth asset in order")
381- else {
382- let newData = (dropRight(data, size(parts[8])) + toString((orderSpent + priceAssetAmount)))
383- let toCaller = ScriptTransfer(i.caller, priceAssetAmount, if ((orderPriceAsset == "WAVES"))
384- then unit
385- else fromBase58String(orderPriceAsset))
386- let toOwner = ScriptTransfer(orderOwner, amount, if ((orderAmountAsset == "WAVES"))
387- then unit
388- else fromBase58String(orderAmountAsset))
389- ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([toCaller, toOwner]))
390- }
391- }
392- }
393- }
394- }
336+func takeBuy (orderId,sig) = if (shutdownFlag)
337+ then throw(shutdownMessage)
338+ else {
339+ let payment = valueOrErrorMessage(i.payment, "where is payment?")
340+ let amount = payment.amount
341+ if ((0 >= amount))
342+ then throw("amount must be positive")
343+ else {
344+ let amountAsset = match payment.assetId {
345+ case p: ByteVector =>
346+ toBase58String(p)
347+ case _ =>
348+ "WAVES"
349+ }
350+ let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id")
351+ let parts = split(data, "_")
352+ let orderType = parts[0]
353+ let orderAmount = parseIntValue(parts[1])
354+ let orderAmountAsset = parts[2]
355+ let orderPriceAssetAmount = parseIntValue(parts[3])
356+ let orderPriceAsset = parts[4]
357+ let orderOwner = value(addressFromString(parts[5]))
358+ let orderAll = if ((parts[6] == "true"))
359+ then true
360+ else false
361+ let orderPassword = parts[7]
362+ let orderSpent = parseIntValue(parts[8])
363+ if ((orderType != "buy"))
364+ then throw("Invalid order type")
365+ else if ((orderAmountAsset != amountAsset))
366+ then throw(("payment asset must be " + orderAmountAsset))
367+ else {
368+ let valid = if ((orderPassword != ""))
369+ then sigVerify(i.callerPublicKey, fromBase58String(sig), fromBase58String(orderPassword))
370+ else true
371+ if (!(valid))
372+ then throw("The order is private")
373+ else {
374+ let priceAssetAmount = ((amount * orderPriceAssetAmount) / orderAmount)
375+ if ((priceAssetAmount == 0))
376+ then throw("Invalid amount")
377+ else if (if (orderAll)
378+ then (orderPriceAssetAmount > priceAssetAmount)
379+ else false)
380+ then throw("You must take all or none")
381+ else if ((priceAssetAmount > (orderPriceAssetAmount - orderSpent)))
382+ then throw("not enougth asset in order")
383+ else {
384+ let newData = (dropRight(data, size(parts[8])) + toString((orderSpent + priceAssetAmount)))
385+ let toCaller = ScriptTransfer(i.caller, priceAssetAmount, if ((orderPriceAsset == "WAVES"))
386+ then unit
387+ else fromBase58String(orderPriceAsset))
388+ let toOwner = ScriptTransfer(orderOwner, amount, if ((orderAmountAsset == "WAVES"))
389+ then unit
390+ else fromBase58String(orderAmountAsset))
391+ ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([toCaller, toOwner]))
392+ }
393+ }
394+ }
395+ }
396+ }
395397
396398
397399
398400 @Callable(i)
399401 func returnSell (orderId) = {
400402 let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id")
401403 let parts = split(data, "_")
402404 let orderType = parts[0]
403405 let orderAmount = parseIntValue(parts[1])
404406 let orderAmountAsset = parts[2]
405407 let orderPriceAssetAmount = parseIntValue(parts[3])
406408 let orderPriceAsset = parts[4]
407409 let orderOwner = value(addressFromString(parts[5]))
408410 let orderAll = if ((parts[6] == "true"))
409411 then true
410412 else false
411413 let orderPassword = parts[7]
412414 let orderSpent = parseIntValue(parts[8])
413415 if ((orderType != "sell"))
414416 then throw("Invalid order type")
415- else if ((orderOwner != i.caller))
417+ else if (if ((orderOwner != i.caller))
418+ then !(shutdownFlag)
419+ else false)
416420 then throw("return should be called by order owner")
417421 else {
418422 let returnAmount = (orderAmount - orderSpent)
419423 if ((0 >= returnAmount))
420424 then throw("nothing to return")
421425 else {
422426 let newData = (dropRight(data, size(parts[8])) + toString(orderAmount))
423- ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([ScriptTransfer(i.caller, returnAmount, if ((orderAmountAsset == "WAVES"))
427+ ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([ScriptTransfer(orderOwner, returnAmount, if ((orderAmountAsset == "WAVES"))
424428 then unit
425429 else fromBase58String(orderAmountAsset))]))
426430 }
427431 }
428432 }
429433
430434
431435
432436 @Callable(i)
433437 func returnBuy (orderId) = {
434438 let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id")
435439 let parts = split(data, "_")
436440 let orderType = parts[0]
437441 let orderAmount = parseIntValue(parts[1])
438442 let orderAmountAsset = parts[2]
439443 let orderPriceAssetAmount = parseIntValue(parts[3])
440444 let orderPriceAsset = parts[4]
441445 let orderOwner = value(addressFromString(parts[5]))
442446 let orderAll = if ((parts[6] == "true"))
443447 then true
444448 else false
445449 let orderPassword = parts[7]
446450 let orderSpent = parseIntValue(parts[8])
447451 if ((orderType != "buy"))
448452 then throw("Invalid order type")
449- else if ((orderOwner != i.caller))
453+ else if (if ((orderOwner != i.caller))
454+ then !(shutdownFlag)
455+ else false)
450456 then throw("Return should be called by order owner")
451457 else {
452458 let returnAmount = (orderPriceAssetAmount - orderSpent)
453459 if ((0 >= returnAmount))
454460 then throw("nothing to return")
455461 else {
456462 let newData = (dropRight(data, size(parts[8])) + toString(orderPriceAssetAmount))
457- ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([ScriptTransfer(i.caller, returnAmount, if ((orderPriceAsset == "WAVES"))
463+ ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([ScriptTransfer(orderOwner, returnAmount, if ((orderPriceAsset == "WAVES"))
458464 then unit
459465 else fromBase58String(orderPriceAsset))]))
460466 }
461467 }
462468 }
463469
464470
471+
472+@Callable(i)
473+func withdraw (mode) = if ((i.caller != admin))
474+ then throw("You should be an admin")
475+ else if (if (if ((mode != "balance"))
476+ then (mode != "reserve")
477+ else false)
478+ then (mode != "all")
479+ else false)
480+ then throw("Specify the mode: balance, reserve or all")
481+ else {
482+ let balanceEntry = DataEntry("balance", 0)
483+ let balanceTransfer = ScriptTransfer(admin, balance, unit)
484+ let reserveEntry = DataEntry("reserve", 0)
485+ let reserveTransfer = ScriptTransfer(admin, reserve, unit)
486+ let writeSet = if ((mode == "balance"))
487+ then [balanceEntry]
488+ else if ((mode == "reserve"))
489+ then [reserveEntry]
490+ else if ((mode == "all"))
491+ then [balanceEntry, reserveEntry]
492+ else nil
493+ let transferSet = if ((mode == "balance"))
494+ then [balanceTransfer]
495+ else if ((mode == "reserve"))
496+ then [reserveTransfer]
497+ else if ((mode == "all"))
498+ then [balanceTransfer, reserveTransfer]
499+ else nil
500+ ScriptResult(WriteSet(writeSet), TransferSet(transferSet))
501+ }
502+
503+
504+
505+@Callable(i)
506+func doShutdown (msg) = if ((i.caller != admin))
507+ then throw("You should be an admin")
508+ else WriteSet([DataEntry("shutdown_flag", true), DataEntry("shutdown_message", msg)])
509+
510+

github/deemru/w8io/3ef1775 
101.78 ms