tx · 2wQL7mPTEmK7eMynTFHPQoaeem9RbnDhzUtaknZVU7JA 3PPPpppPdJqaKjC6HBdrXadTeVYBipz6kAE: -0.01400000 Waves 2019.10.11 00:16 [1744509] smart account 3PPPpppPdJqaKjC6HBdrXadTeVYBipz6kAE > SELF 0.00000000 Waves
{ "type": 13, "id": "2wQL7mPTEmK7eMynTFHPQoaeem9RbnDhzUtaknZVU7JA", "fee": 1400000, "feeAssetId": null, "timestamp": 1570742298516, "version": 1, "sender": "3PPPpppPdJqaKjC6HBdrXadTeVYBipz6kAE", "senderPublicKey": "7WHNSvrBxV3qc9gettXmhmgmQBqE2opoyiabPQnfALpp", "proofs": [ "42a52hr6Xh88YyAk6J3djpB1zWCxMZYearCGXx9iU4LNnYoyGpDcEXD97mGskLijwzmCbwQG4EHgjmCgdK1j6QLF" ], "script": "base64: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", "chainId": 87, "height": 1744509, "spentComplexity": 0 } View: original | compacted Prev: EtWeT19gqEvd1EzfAoRwuD9KiStn4T3WCQwiCXVASoTD Next: Djqam2ZuyxEwPNr3Z944n2fp1VSSrzk4hCwbMFVY1HrS Diff:
Old | New | Differences | |
---|---|---|---|
50 | 50 | } | |
51 | 51 | if (isDefined(indexOf(assets, assetId))) | |
52 | 52 | then throw("Asset is already available") | |
53 | - | else WriteSet([DataEntry("assets", ((assets + assetId) + ","))]) | |
53 | + | else { | |
54 | + | let list0 = [DataEntry("assets", ((assets + assetId) + ","))] | |
55 | + | let list1 = if ((payment.assetId == uTokenId)) | |
56 | + | then { | |
57 | + | let reserve = match getInteger(this, "reserve") { | |
58 | + | case int: Int => | |
59 | + | int | |
60 | + | case _: Unit => | |
61 | + | 0 | |
62 | + | case _ => | |
63 | + | throw() | |
64 | + | } | |
65 | + | DataEntry("reserve", (reserve + payment.amount)) :: list0 | |
66 | + | } | |
67 | + | else list0 | |
68 | + | WriteSet(list1) | |
69 | + | } | |
54 | 70 | } | |
55 | 71 | } | |
56 | 72 | ||
57 | 73 | ||
58 | 74 | ||
59 | 75 | @Callable(i) | |
60 | - | func pro ( | |
76 | + | func pro () = { | |
61 | 77 | let address = toBase58String(i.caller.bytes) | |
62 | 78 | let unlimitedPrice = (50 * 100000000) | |
63 | 79 | let unlimitedPriceStr = "50" | |
68 | 84 | then (payment.assetId != uTokenId) | |
69 | 85 | else false) | |
70 | 86 | then throw("OTCu or WAVES only") | |
71 | - | else if (if ( | |
72 | - | then (payment.amount != | |
87 | + | else if (if ((payment.amount != unlimitedPrice)) | |
88 | + | then (payment.amount != monthPrice) | |
73 | 89 | else false) | |
74 | - | then throw((("You have to pay " + unlimitedPriceStr) + " OTCu or WAVES")) | |
75 | - | else if (if (!(unlimited)) | |
76 | - | then (payment.amount != monthPrice) | |
77 | - | else false) | |
78 | - | then throw((("You have to pay " + monthPriceStr) + " OTCu or WAVES")) | |
79 | - | else { | |
80 | - | let currentUnlimited = match getBoolean(this, (address + "_unlimited")) { | |
81 | - | case bool: Boolean => | |
82 | - | bool | |
83 | - | case _: Unit => | |
84 | - | false | |
85 | - | case _ => | |
86 | - | throw() | |
87 | - | } | |
88 | - | let currentTime = match getInteger(this, (address + "_time")) { | |
89 | - | case int: Int => | |
90 | - | int | |
91 | - | case _: Unit => | |
92 | - | lastBlock.timestamp | |
93 | - | case _ => | |
94 | - | throw() | |
95 | - | } | |
96 | - | if (currentUnlimited) | |
97 | - | then throw("You have unlimited PRO status already. What do you want?") | |
98 | - | else { | |
99 | - | let month = 2629743000 | |
100 | - | WriteSet([DataEntry((address + "_unlimited"), unlimited), DataEntry((address + "_time"), if (unlimited) | |
101 | - | then 0 | |
102 | - | else (currentTime + month))]) | |
103 | - | } | |
104 | - | } | |
90 | + | then throw("Invalid payment") | |
91 | + | else { | |
92 | + | let unlimited = (payment.amount == unlimitedPrice) | |
93 | + | let currentUnlimited = match getBoolean(this, (address + "_unlimited")) { | |
94 | + | case bool: Boolean => | |
95 | + | bool | |
96 | + | case _: Unit => | |
97 | + | false | |
98 | + | case _ => | |
99 | + | throw() | |
100 | + | } | |
101 | + | let currentTime = match getInteger(this, (address + "_time")) { | |
102 | + | case int: Int => | |
103 | + | int | |
104 | + | case _: Unit => | |
105 | + | lastBlock.timestamp | |
106 | + | case _ => | |
107 | + | throw() | |
108 | + | } | |
109 | + | if (currentUnlimited) | |
110 | + | then throw("You have unlimited PRO status already. What do you want?") | |
111 | + | else { | |
112 | + | let month = 2629743000 | |
113 | + | let list0 = [DataEntry((address + "_unlimited"), unlimited), DataEntry((address + "_time"), if (unlimited) | |
114 | + | then 0 | |
115 | + | else (currentTime + month))] | |
116 | + | let list1 = if ((payment.assetId == uTokenId)) | |
117 | + | then { | |
118 | + | let reserve = match getInteger(this, "reserve") { | |
119 | + | case int: Int => | |
120 | + | int | |
121 | + | case _: Unit => | |
122 | + | 0 | |
123 | + | case _ => | |
124 | + | throw() | |
125 | + | } | |
126 | + | DataEntry("reserve", (reserve + payment.amount)) :: list0 | |
127 | + | } | |
128 | + | else list0 | |
129 | + | WriteSet(list1) | |
130 | + | } | |
131 | + | } | |
105 | 132 | } | |
106 | 133 | ||
107 | 134 | ||
111 | 138 | let payment = valueOrErrorMessage(i.payment, "Where is payment?") | |
112 | 139 | if (isDefined(payment.assetId)) | |
113 | 140 | then throw("WAVES only") | |
114 | - | else TransferSet([ScriptTransfer(i.caller, payment.amount, uTokenId)]) | |
141 | + | else { | |
142 | + | let reserve = match getInteger(this, "reserve") { | |
143 | + | case int: Int => | |
144 | + | int | |
145 | + | case _: Unit => | |
146 | + | 0 | |
147 | + | case _ => | |
148 | + | throw() | |
149 | + | } | |
150 | + | if ((payment.amount > reserve)) | |
151 | + | then throw("Not enougth asset in dApp") | |
152 | + | else ScriptResult(WriteSet([DataEntry("reserve", (reserve - payment.amount))]), TransferSet([ScriptTransfer(i.caller, payment.amount, uTokenId)])) | |
153 | + | } | |
115 | 154 | } | |
116 | 155 | ||
117 | 156 | ||
282 | 321 | let newOrders = if ((orderAmount == (amount + orderSpent))) | |
283 | 322 | then (take(orders, index) + drop(orders, ((index + size(orderId)) + 1))) | |
284 | 323 | else orders | |
285 | - | | |
324 | + | let toCaller = ScriptTransfer(i.caller, amount, if ((orderAmountAsset == "WAVES")) | |
286 | 325 | then unit | |
287 | - | else fromBase58String(orderAmountAsset)), ScriptTransfer(orderOwner, priceAssetAmount, if ((orderPriceAsset == "WAVES")) | |
326 | + | else fromBase58String(orderAmountAsset)) | |
327 | + | let toOwner = ScriptTransfer(orderOwner, priceAssetAmount, if ((orderPriceAsset == "WAVES")) | |
288 | 328 | then unit | |
289 | - | else fromBase58String(orderPriceAsset))])) | |
329 | + | else fromBase58String(orderPriceAsset)) | |
330 | + | ScriptResult(WriteSet([DataEntry("orders", newOrders), DataEntry(orderId, newData)]), TransferSet([toCaller, toOwner])) | |
290 | 331 | } | |
291 | 332 | } | |
292 | 333 | } | |
355 | 396 | let newOrders = if ((orderPriceAssetAmount == (priceAssetAmount + orderSpent))) | |
356 | 397 | then (take(orders, index) + drop(orders, ((index + size(orderId)) + 1))) | |
357 | 398 | else orders | |
358 | - | | |
399 | + | let toCaller = ScriptTransfer(i.caller, priceAssetAmount, if ((orderPriceAsset == "WAVES")) | |
359 | 400 | then unit | |
360 | - | else fromBase58String(orderPriceAsset)), ScriptTransfer(orderOwner, amount, if ((orderAmountAsset == "WAVES")) | |
401 | + | else fromBase58String(orderPriceAsset)) | |
402 | + | let toOwner = ScriptTransfer(orderOwner, amount, if ((orderAmountAsset == "WAVES")) | |
361 | 403 | then unit | |
362 | - | else fromBase58String(orderAmountAsset))])) | |
404 | + | else fromBase58String(orderAmountAsset)) | |
405 | + | ScriptResult(WriteSet([DataEntry("orders", newOrders), DataEntry(orderId, newData)]), TransferSet([toCaller, toOwner])) | |
363 | 406 | } | |
364 | 407 | } | |
365 | 408 | } |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 3 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let uTokenId = base58'GHh7EMnVnUBCYNJMktuLPVr3P2oCqBCb4c87fBCZ5CzY' | |
5 | 5 | ||
6 | 6 | func checkStatus (address) = { | |
7 | 7 | let statusUnlimited = match getBoolean(this, (address + "_unlimited")) { | |
8 | 8 | case bool: Boolean => | |
9 | 9 | bool | |
10 | 10 | case _: Unit => | |
11 | 11 | false | |
12 | 12 | case _ => | |
13 | 13 | throw() | |
14 | 14 | } | |
15 | 15 | let statusTime = match getInteger(this, (address + "_time")) { | |
16 | 16 | case int: Int => | |
17 | 17 | int | |
18 | 18 | case _: Unit => | |
19 | 19 | 0 | |
20 | 20 | case _ => | |
21 | 21 | throw() | |
22 | 22 | } | |
23 | 23 | if (statusUnlimited) | |
24 | 24 | then true | |
25 | 25 | else (statusTime > lastBlock.timestamp) | |
26 | 26 | } | |
27 | 27 | ||
28 | 28 | ||
29 | 29 | @Callable(i) | |
30 | 30 | func addAsset (assetId) = { | |
31 | 31 | let addingPrice = (100 * 100000000) | |
32 | 32 | let addingPriceStr = "100" | |
33 | 33 | let payment = valueOrErrorMessage(i.payment, "Where is payment?") | |
34 | 34 | if (if (isDefined(payment.assetId)) | |
35 | 35 | then (payment.assetId != uTokenId) | |
36 | 36 | else false) | |
37 | 37 | then throw("OTCu or WAVES only") | |
38 | 38 | else if ((payment.amount != addingPrice)) | |
39 | 39 | then throw((("You have to pay " + addingPriceStr) + " OTCu or WAVES")) | |
40 | 40 | else if (!(isDefined(assetInfo(fromBase58String(assetId))))) | |
41 | 41 | then throw("There is no asset with specified id") | |
42 | 42 | else { | |
43 | 43 | let assets = match getString(this, "assets") { | |
44 | 44 | case str: String => | |
45 | 45 | str | |
46 | 46 | case _: Unit => | |
47 | 47 | "" | |
48 | 48 | case _ => | |
49 | 49 | throw() | |
50 | 50 | } | |
51 | 51 | if (isDefined(indexOf(assets, assetId))) | |
52 | 52 | then throw("Asset is already available") | |
53 | - | else WriteSet([DataEntry("assets", ((assets + assetId) + ","))]) | |
53 | + | else { | |
54 | + | let list0 = [DataEntry("assets", ((assets + assetId) + ","))] | |
55 | + | let list1 = if ((payment.assetId == uTokenId)) | |
56 | + | then { | |
57 | + | let reserve = match getInteger(this, "reserve") { | |
58 | + | case int: Int => | |
59 | + | int | |
60 | + | case _: Unit => | |
61 | + | 0 | |
62 | + | case _ => | |
63 | + | throw() | |
64 | + | } | |
65 | + | DataEntry("reserve", (reserve + payment.amount)) :: list0 | |
66 | + | } | |
67 | + | else list0 | |
68 | + | WriteSet(list1) | |
69 | + | } | |
54 | 70 | } | |
55 | 71 | } | |
56 | 72 | ||
57 | 73 | ||
58 | 74 | ||
59 | 75 | @Callable(i) | |
60 | - | func pro ( | |
76 | + | func pro () = { | |
61 | 77 | let address = toBase58String(i.caller.bytes) | |
62 | 78 | let unlimitedPrice = (50 * 100000000) | |
63 | 79 | let unlimitedPriceStr = "50" | |
64 | 80 | let monthPrice = (10 * 100000000) | |
65 | 81 | let monthPriceStr = "10" | |
66 | 82 | let payment = valueOrErrorMessage(i.payment, "Where is payment?") | |
67 | 83 | if (if (isDefined(payment.assetId)) | |
68 | 84 | then (payment.assetId != uTokenId) | |
69 | 85 | else false) | |
70 | 86 | then throw("OTCu or WAVES only") | |
71 | - | else if (if ( | |
72 | - | then (payment.amount != | |
87 | + | else if (if ((payment.amount != unlimitedPrice)) | |
88 | + | then (payment.amount != monthPrice) | |
73 | 89 | else false) | |
74 | - | then throw((("You have to pay " + unlimitedPriceStr) + " OTCu or WAVES")) | |
75 | - | else if (if (!(unlimited)) | |
76 | - | then (payment.amount != monthPrice) | |
77 | - | else false) | |
78 | - | then throw((("You have to pay " + monthPriceStr) + " OTCu or WAVES")) | |
79 | - | else { | |
80 | - | let currentUnlimited = match getBoolean(this, (address + "_unlimited")) { | |
81 | - | case bool: Boolean => | |
82 | - | bool | |
83 | - | case _: Unit => | |
84 | - | false | |
85 | - | case _ => | |
86 | - | throw() | |
87 | - | } | |
88 | - | let currentTime = match getInteger(this, (address + "_time")) { | |
89 | - | case int: Int => | |
90 | - | int | |
91 | - | case _: Unit => | |
92 | - | lastBlock.timestamp | |
93 | - | case _ => | |
94 | - | throw() | |
95 | - | } | |
96 | - | if (currentUnlimited) | |
97 | - | then throw("You have unlimited PRO status already. What do you want?") | |
98 | - | else { | |
99 | - | let month = 2629743000 | |
100 | - | WriteSet([DataEntry((address + "_unlimited"), unlimited), DataEntry((address + "_time"), if (unlimited) | |
101 | - | then 0 | |
102 | - | else (currentTime + month))]) | |
103 | - | } | |
104 | - | } | |
90 | + | then throw("Invalid payment") | |
91 | + | else { | |
92 | + | let unlimited = (payment.amount == unlimitedPrice) | |
93 | + | let currentUnlimited = match getBoolean(this, (address + "_unlimited")) { | |
94 | + | case bool: Boolean => | |
95 | + | bool | |
96 | + | case _: Unit => | |
97 | + | false | |
98 | + | case _ => | |
99 | + | throw() | |
100 | + | } | |
101 | + | let currentTime = match getInteger(this, (address + "_time")) { | |
102 | + | case int: Int => | |
103 | + | int | |
104 | + | case _: Unit => | |
105 | + | lastBlock.timestamp | |
106 | + | case _ => | |
107 | + | throw() | |
108 | + | } | |
109 | + | if (currentUnlimited) | |
110 | + | then throw("You have unlimited PRO status already. What do you want?") | |
111 | + | else { | |
112 | + | let month = 2629743000 | |
113 | + | let list0 = [DataEntry((address + "_unlimited"), unlimited), DataEntry((address + "_time"), if (unlimited) | |
114 | + | then 0 | |
115 | + | else (currentTime + month))] | |
116 | + | let list1 = if ((payment.assetId == uTokenId)) | |
117 | + | then { | |
118 | + | let reserve = match getInteger(this, "reserve") { | |
119 | + | case int: Int => | |
120 | + | int | |
121 | + | case _: Unit => | |
122 | + | 0 | |
123 | + | case _ => | |
124 | + | throw() | |
125 | + | } | |
126 | + | DataEntry("reserve", (reserve + payment.amount)) :: list0 | |
127 | + | } | |
128 | + | else list0 | |
129 | + | WriteSet(list1) | |
130 | + | } | |
131 | + | } | |
105 | 132 | } | |
106 | 133 | ||
107 | 134 | ||
108 | 135 | ||
109 | 136 | @Callable(i) | |
110 | 137 | func buyUtilityToken () = { | |
111 | 138 | let payment = valueOrErrorMessage(i.payment, "Where is payment?") | |
112 | 139 | if (isDefined(payment.assetId)) | |
113 | 140 | then throw("WAVES only") | |
114 | - | else TransferSet([ScriptTransfer(i.caller, payment.amount, uTokenId)]) | |
141 | + | else { | |
142 | + | let reserve = match getInteger(this, "reserve") { | |
143 | + | case int: Int => | |
144 | + | int | |
145 | + | case _: Unit => | |
146 | + | 0 | |
147 | + | case _ => | |
148 | + | throw() | |
149 | + | } | |
150 | + | if ((payment.amount > reserve)) | |
151 | + | then throw("Not enougth asset in dApp") | |
152 | + | else ScriptResult(WriteSet([DataEntry("reserve", (reserve - payment.amount))]), TransferSet([ScriptTransfer(i.caller, payment.amount, uTokenId)])) | |
153 | + | } | |
115 | 154 | } | |
116 | 155 | ||
117 | 156 | ||
118 | 157 | ||
119 | 158 | @Callable(i) | |
120 | 159 | func makeSell (priceAsset,priceAssetAmount,all,password) = if (if ((priceAsset != "WAVES")) | |
121 | 160 | then !(isDefined(assetInfo(fromBase58String(priceAsset)))) | |
122 | 161 | else false) | |
123 | 162 | then throw("There is no asset with specified id") | |
124 | 163 | else if ((0 >= priceAssetAmount)) | |
125 | 164 | then throw("Amount of price asset must be positive") | |
126 | 165 | else { | |
127 | 166 | let payment = valueOrErrorMessage(i.payment, "Where is payment?") | |
128 | 167 | if ((0 >= payment.amount)) | |
129 | 168 | then throw("Amount must be positive") | |
130 | 169 | else { | |
131 | 170 | let amountAsset = match payment.assetId { | |
132 | 171 | case p: ByteVector => | |
133 | 172 | toBase58String(p) | |
134 | 173 | case _ => | |
135 | 174 | "WAVES" | |
136 | 175 | } | |
137 | 176 | let assets = valueOrErrorMessage(getString(this, "assets"), "There are not available assets") | |
138 | 177 | if (if (!(isDefined(indexOf(assets, priceAsset)))) | |
139 | 178 | then true | |
140 | 179 | else !(isDefined(indexOf(assets, amountAsset)))) | |
141 | 180 | then throw("Asset are not available for trading") | |
142 | 181 | else { | |
143 | 182 | let address = toBase58String(i.caller.bytes) | |
144 | 183 | if (if (!(checkStatus(address))) | |
145 | 184 | then if (all) | |
146 | 185 | then true | |
147 | 186 | else (password != "") | |
148 | 187 | else false) | |
149 | 188 | then throw("You must have pro status to use these features") | |
150 | 189 | else { | |
151 | 190 | let orderId = toBase58String(i.transactionId) | |
152 | 191 | let orders = match getString(this, "orders") { | |
153 | 192 | case s: String => | |
154 | 193 | s | |
155 | 194 | case _: Unit => | |
156 | 195 | "" | |
157 | 196 | case _ => | |
158 | 197 | throw() | |
159 | 198 | } | |
160 | 199 | let passwordValid = fromBase58String(password) | |
161 | 200 | let data = (((((((((((((((("sell" + "_") + toString(payment.amount)) + "_") + amountAsset) + "_") + toString(priceAssetAmount)) + "_") + priceAsset) + "_") + address) + "_") + toString(all)) + "_") + password) + "_") + toString(0)) | |
162 | 201 | WriteSet([DataEntry("orders", ((orders + orderId) + ",")), DataEntry(orderId, data)]) | |
163 | 202 | } | |
164 | 203 | } | |
165 | 204 | } | |
166 | 205 | } | |
167 | 206 | ||
168 | 207 | ||
169 | 208 | ||
170 | 209 | @Callable(i) | |
171 | 210 | func makeBuy (amountAsset,amount,all,password) = if (if ((amountAsset != "WAVES")) | |
172 | 211 | then !(isDefined(assetInfo(fromBase58String(amountAsset)))) | |
173 | 212 | else false) | |
174 | 213 | then throw("There is no asset with specified id") | |
175 | 214 | else if ((0 >= amount)) | |
176 | 215 | then throw("Amount must be positive") | |
177 | 216 | else { | |
178 | 217 | let payment = valueOrErrorMessage(i.payment, "where is payment?") | |
179 | 218 | let priceAssetAmount = payment.amount | |
180 | 219 | if ((0 >= priceAssetAmount)) | |
181 | 220 | then throw("amount must be positive") | |
182 | 221 | else { | |
183 | 222 | let priceAsset = match payment.assetId { | |
184 | 223 | case p: ByteVector => | |
185 | 224 | toBase58String(p) | |
186 | 225 | case _ => | |
187 | 226 | "WAVES" | |
188 | 227 | } | |
189 | 228 | let assets = valueOrErrorMessage(getString(this, "assets"), "There are not available assets") | |
190 | 229 | if (if (!(isDefined(indexOf(assets, priceAsset)))) | |
191 | 230 | then true | |
192 | 231 | else !(isDefined(indexOf(assets, amountAsset)))) | |
193 | 232 | then throw("Asset are not available for trading") | |
194 | 233 | else { | |
195 | 234 | let address = toBase58String(i.caller.bytes) | |
196 | 235 | if (if (!(checkStatus(address))) | |
197 | 236 | then if (all) | |
198 | 237 | then true | |
199 | 238 | else (password != "") | |
200 | 239 | else false) | |
201 | 240 | then throw("You must have pro status to use these features") | |
202 | 241 | else { | |
203 | 242 | let orderId = toBase58String(i.transactionId) | |
204 | 243 | let orders = match getString(this, "orders") { | |
205 | 244 | case s: String => | |
206 | 245 | s | |
207 | 246 | case _: Unit => | |
208 | 247 | "" | |
209 | 248 | case _ => | |
210 | 249 | throw() | |
211 | 250 | } | |
212 | 251 | if ((amount == 0)) | |
213 | 252 | then throw("invalid buy amount") | |
214 | 253 | else { | |
215 | 254 | let data = (((((((((((((((("buy" + "_") + toString(amount)) + "_") + amountAsset) + "_") + toString(priceAssetAmount)) + "_") + priceAsset) + "_") + address) + "_") + toString(all)) + "_") + password) + "_") + toString(0)) | |
216 | 255 | WriteSet([DataEntry("orders", ((orders + orderId) + ",")), DataEntry(orderId, data)]) | |
217 | 256 | } | |
218 | 257 | } | |
219 | 258 | } | |
220 | 259 | } | |
221 | 260 | } | |
222 | 261 | ||
223 | 262 | ||
224 | 263 | ||
225 | 264 | @Callable(i) | |
226 | 265 | func takeSell (orderId,sig) = { | |
227 | 266 | let payment = valueOrErrorMessage(i.payment, "Where is payment?") | |
228 | 267 | let priceAssetAmount = payment.amount | |
229 | 268 | if ((0 >= priceAssetAmount)) | |
230 | 269 | then throw("Amount must be positive") | |
231 | 270 | else { | |
232 | 271 | let priceAsset = match payment.assetId { | |
233 | 272 | case p: ByteVector => | |
234 | 273 | toBase58String(p) | |
235 | 274 | case _ => | |
236 | 275 | "WAVES" | |
237 | 276 | } | |
238 | 277 | let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id") | |
239 | 278 | let parts = split(data, "_") | |
240 | 279 | let orderType = parts[0] | |
241 | 280 | let orderAmount = parseIntValue(parts[1]) | |
242 | 281 | let orderAmountAsset = parts[2] | |
243 | 282 | let orderPriceAssetAmount = parseIntValue(parts[3]) | |
244 | 283 | let orderPriceAsset = parts[4] | |
245 | 284 | let orderOwner = value(addressFromString(parts[5])) | |
246 | 285 | let orderAll = if ((parts[6] == "true")) | |
247 | 286 | then true | |
248 | 287 | else false | |
249 | 288 | let orderPassword = parts[7] | |
250 | 289 | let orderSpent = parseIntValue(parts[8]) | |
251 | 290 | if ((orderType != "sell")) | |
252 | 291 | then throw("Invalid order type") | |
253 | 292 | else if ((orderPriceAsset != priceAsset)) | |
254 | 293 | then throw(("Payment asset must be " + orderPriceAsset)) | |
255 | 294 | else { | |
256 | 295 | let valid = if ((orderPassword != "")) | |
257 | 296 | then sigVerify(i.callerPublicKey, fromBase58String(sig), fromBase58String(orderPassword)) | |
258 | 297 | else true | |
259 | 298 | if (!(valid)) | |
260 | 299 | then throw("The order is private") | |
261 | 300 | else { | |
262 | 301 | let amount = ((priceAssetAmount * orderAmount) / orderPriceAssetAmount) | |
263 | 302 | if ((amount == 0)) | |
264 | 303 | then throw("Invalid amount") | |
265 | 304 | else if (if (orderAll) | |
266 | 305 | then (orderAmount > amount) | |
267 | 306 | else false) | |
268 | 307 | then throw("You must take all or none") | |
269 | 308 | else if ((amount > (orderAmount - orderSpent))) | |
270 | 309 | then throw("Not enougth asset in order") | |
271 | 310 | else { | |
272 | 311 | let orders = match getString(this, "orders") { | |
273 | 312 | case s: String => | |
274 | 313 | s | |
275 | 314 | case _: Unit => | |
276 | 315 | "" | |
277 | 316 | case _ => | |
278 | 317 | throw() | |
279 | 318 | } | |
280 | 319 | let newData = (dropRight(data, size(parts[8])) + toString((orderSpent + amount))) | |
281 | 320 | let index = value(indexOf(orders, orderId)) | |
282 | 321 | let newOrders = if ((orderAmount == (amount + orderSpent))) | |
283 | 322 | then (take(orders, index) + drop(orders, ((index + size(orderId)) + 1))) | |
284 | 323 | else orders | |
285 | - | | |
324 | + | let toCaller = ScriptTransfer(i.caller, amount, if ((orderAmountAsset == "WAVES")) | |
286 | 325 | then unit | |
287 | - | else fromBase58String(orderAmountAsset)), ScriptTransfer(orderOwner, priceAssetAmount, if ((orderPriceAsset == "WAVES")) | |
326 | + | else fromBase58String(orderAmountAsset)) | |
327 | + | let toOwner = ScriptTransfer(orderOwner, priceAssetAmount, if ((orderPriceAsset == "WAVES")) | |
288 | 328 | then unit | |
289 | - | else fromBase58String(orderPriceAsset))])) | |
329 | + | else fromBase58String(orderPriceAsset)) | |
330 | + | ScriptResult(WriteSet([DataEntry("orders", newOrders), DataEntry(orderId, newData)]), TransferSet([toCaller, toOwner])) | |
290 | 331 | } | |
291 | 332 | } | |
292 | 333 | } | |
293 | 334 | } | |
294 | 335 | } | |
295 | 336 | ||
296 | 337 | ||
297 | 338 | ||
298 | 339 | @Callable(i) | |
299 | 340 | func takeBuy (orderId,sig) = { | |
300 | 341 | let payment = valueOrErrorMessage(i.payment, "where is payment?") | |
301 | 342 | let amount = payment.amount | |
302 | 343 | if ((0 >= amount)) | |
303 | 344 | then throw("amount must be positive") | |
304 | 345 | else { | |
305 | 346 | let amountAsset = match payment.assetId { | |
306 | 347 | case p: ByteVector => | |
307 | 348 | toBase58String(p) | |
308 | 349 | case _ => | |
309 | 350 | "WAVES" | |
310 | 351 | } | |
311 | 352 | let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id") | |
312 | 353 | let parts = split(data, "_") | |
313 | 354 | let orderType = parts[0] | |
314 | 355 | let orderAmount = parseIntValue(parts[1]) | |
315 | 356 | let orderAmountAsset = parts[2] | |
316 | 357 | let orderPriceAssetAmount = parseIntValue(parts[3]) | |
317 | 358 | let orderPriceAsset = parts[4] | |
318 | 359 | let orderOwner = value(addressFromString(parts[5])) | |
319 | 360 | let orderAll = if ((parts[6] == "true")) | |
320 | 361 | then true | |
321 | 362 | else false | |
322 | 363 | let orderPassword = parts[7] | |
323 | 364 | let orderSpent = parseIntValue(parts[8]) | |
324 | 365 | if ((orderType != "buy")) | |
325 | 366 | then throw("Invalid order type") | |
326 | 367 | else if ((orderAmountAsset != amountAsset)) | |
327 | 368 | then throw(("payment asset must be " + orderAmountAsset)) | |
328 | 369 | else { | |
329 | 370 | let valid = if ((orderPassword != "")) | |
330 | 371 | then sigVerify(i.callerPublicKey, fromBase58String(sig), fromBase58String(orderPassword)) | |
331 | 372 | else true | |
332 | 373 | if (!(valid)) | |
333 | 374 | then throw("The order is private") | |
334 | 375 | else { | |
335 | 376 | let priceAssetAmount = ((amount * orderPriceAssetAmount) / orderAmount) | |
336 | 377 | if ((priceAssetAmount == 0)) | |
337 | 378 | then throw("Invalid amount") | |
338 | 379 | else if (if (orderAll) | |
339 | 380 | then (orderPriceAssetAmount > priceAssetAmount) | |
340 | 381 | else false) | |
341 | 382 | then throw("You must take all or none") | |
342 | 383 | else if ((priceAssetAmount > (orderPriceAssetAmount - orderSpent))) | |
343 | 384 | then throw("not enougth asset in order") | |
344 | 385 | else { | |
345 | 386 | let orders = match getString(this, "orders") { | |
346 | 387 | case s: String => | |
347 | 388 | s | |
348 | 389 | case _: Unit => | |
349 | 390 | "" | |
350 | 391 | case _ => | |
351 | 392 | throw() | |
352 | 393 | } | |
353 | 394 | let newData = (dropRight(data, size(parts[8])) + toString((orderSpent + priceAssetAmount))) | |
354 | 395 | let index = value(indexOf(orders, orderId)) | |
355 | 396 | let newOrders = if ((orderPriceAssetAmount == (priceAssetAmount + orderSpent))) | |
356 | 397 | then (take(orders, index) + drop(orders, ((index + size(orderId)) + 1))) | |
357 | 398 | else orders | |
358 | - | | |
399 | + | let toCaller = ScriptTransfer(i.caller, priceAssetAmount, if ((orderPriceAsset == "WAVES")) | |
359 | 400 | then unit | |
360 | - | else fromBase58String(orderPriceAsset)), ScriptTransfer(orderOwner, amount, if ((orderAmountAsset == "WAVES")) | |
401 | + | else fromBase58String(orderPriceAsset)) | |
402 | + | let toOwner = ScriptTransfer(orderOwner, amount, if ((orderAmountAsset == "WAVES")) | |
361 | 403 | then unit | |
362 | - | else fromBase58String(orderAmountAsset))])) | |
404 | + | else fromBase58String(orderAmountAsset)) | |
405 | + | ScriptResult(WriteSet([DataEntry("orders", newOrders), DataEntry(orderId, newData)]), TransferSet([toCaller, toOwner])) | |
363 | 406 | } | |
364 | 407 | } | |
365 | 408 | } | |
366 | 409 | } | |
367 | 410 | } | |
368 | 411 | ||
369 | 412 | ||
370 | 413 | ||
371 | 414 | @Callable(i) | |
372 | 415 | func returnSell (orderId) = { | |
373 | 416 | let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id") | |
374 | 417 | let parts = split(data, "_") | |
375 | 418 | let orderType = parts[0] | |
376 | 419 | let orderAmount = parseIntValue(parts[1]) | |
377 | 420 | let orderAmountAsset = parts[2] | |
378 | 421 | let orderPriceAssetAmount = parseIntValue(parts[3]) | |
379 | 422 | let orderPriceAsset = parts[4] | |
380 | 423 | let orderOwner = value(addressFromString(parts[5])) | |
381 | 424 | let orderAll = if ((parts[6] == "true")) | |
382 | 425 | then true | |
383 | 426 | else false | |
384 | 427 | let orderPassword = parts[7] | |
385 | 428 | let orderSpent = parseIntValue(parts[8]) | |
386 | 429 | if ((orderType != "sell")) | |
387 | 430 | then throw("Invalid order type") | |
388 | 431 | else if ((orderOwner != i.caller)) | |
389 | 432 | then throw("return should be called by order owner") | |
390 | 433 | else { | |
391 | 434 | let returnAmount = (orderAmount - orderSpent) | |
392 | 435 | if ((0 >= returnAmount)) | |
393 | 436 | then throw("nothing to return") | |
394 | 437 | else { | |
395 | 438 | let orders = match getString(this, "orders") { | |
396 | 439 | case s: String => | |
397 | 440 | s | |
398 | 441 | case _: Unit => | |
399 | 442 | "" | |
400 | 443 | case _ => | |
401 | 444 | throw() | |
402 | 445 | } | |
403 | 446 | let newData = (dropRight(data, size(parts[8])) + toString(orderAmount)) | |
404 | 447 | let index = value(indexOf(orders, orderId)) | |
405 | 448 | let newOrders = (take(orders, index) + drop(orders, ((index + size(orderId)) + 1))) | |
406 | 449 | ScriptResult(WriteSet([DataEntry("orders", newOrders), DataEntry(orderId, newData)]), TransferSet([ScriptTransfer(i.caller, returnAmount, if ((orderAmountAsset == "WAVES")) | |
407 | 450 | then unit | |
408 | 451 | else fromBase58String(orderAmountAsset))])) | |
409 | 452 | } | |
410 | 453 | } | |
411 | 454 | } | |
412 | 455 | ||
413 | 456 | ||
414 | 457 | ||
415 | 458 | @Callable(i) | |
416 | 459 | func returnBuy (orderId) = { | |
417 | 460 | let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id") | |
418 | 461 | let parts = split(data, "_") | |
419 | 462 | let orderType = parts[0] | |
420 | 463 | let orderAmount = parseIntValue(parts[1]) | |
421 | 464 | let orderAmountAsset = parts[2] | |
422 | 465 | let orderPriceAssetAmount = parseIntValue(parts[3]) | |
423 | 466 | let orderPriceAsset = parts[4] | |
424 | 467 | let orderOwner = value(addressFromString(parts[5])) | |
425 | 468 | let orderAll = if ((parts[6] == "true")) | |
426 | 469 | then true | |
427 | 470 | else false | |
428 | 471 | let orderPassword = parts[7] | |
429 | 472 | let orderSpent = parseIntValue(parts[8]) | |
430 | 473 | if ((orderType != "buy")) | |
431 | 474 | then throw("Invalid order type") | |
432 | 475 | else if ((orderOwner != i.caller)) | |
433 | 476 | then throw("Return should be called by order owner") | |
434 | 477 | else { | |
435 | 478 | let returnAmount = (orderPriceAssetAmount - orderSpent) | |
436 | 479 | if ((0 >= returnAmount)) | |
437 | 480 | then throw("nothing to return") | |
438 | 481 | else { | |
439 | 482 | let orders = match getString(this, "orders") { | |
440 | 483 | case s: String => | |
441 | 484 | s | |
442 | 485 | case _: Unit => | |
443 | 486 | "" | |
444 | 487 | case _ => | |
445 | 488 | throw() | |
446 | 489 | } | |
447 | 490 | let newData = (dropRight(data, size(parts[8])) + toString(orderPriceAssetAmount)) | |
448 | 491 | let index = value(indexOf(orders, orderId)) | |
449 | 492 | let newOrders = (take(orders, index) + drop(orders, ((index + size(orderId)) + 1))) | |
450 | 493 | ScriptResult(WriteSet([DataEntry("orders", newOrders), DataEntry(orderId, newData)]), TransferSet([ScriptTransfer(i.caller, returnAmount, if ((orderPriceAsset == "WAVES")) | |
451 | 494 | then unit | |
452 | 495 | else fromBase58String(orderPriceAsset))])) | |
453 | 496 | } | |
454 | 497 | } | |
455 | 498 | } | |
456 | 499 | ||
457 | 500 |
github/deemru/w8io/873ac7e 132.10 ms ◑