45 | | - | func ParseNextAttribute (remaining) = { |
---|
46 | | - | let s = size(remaining) |
---|
47 | | - | if ((s > 0)) |
---|
48 | | - | then { |
---|
49 | | - | let nn = parseIntValue(take(remaining, 2)) |
---|
50 | | - | let v = take(drop(remaining, 2), nn) |
---|
51 | | - | let tmpRemaining = drop(remaining, (nn + 2)) |
---|
52 | | - | let remainingState = RemoveUnderscoreIfPresent(tmpRemaining) |
---|
53 | | - | [v, remainingState] |
---|
54 | | - | } |
---|
55 | | - | else throw("Empty string was passed into parseNextAttribute func") |
---|
56 | | - | } |
---|
57 | | - | |
---|
58 | | - | |
---|
59 | | - | func FormatOrderDataStr (traidPair,sender,orderType,price,amount,assetId) = { |
---|
60 | | - | let fullStateStr = ((((((((((FormatDataParam(traidPair) + "_") + FormatDataParam(sender)) + "_") + FormatDataParam(orderType)) + "_") + FormatDataParam(toString(price))) + "_") + FormatDataParam(toString(amount))) + "_") + FormatDataParam(assetId)) |
---|
61 | | - | fullStateStr |
---|
62 | | - | } |
---|
63 | | - | |
---|
64 | | - | |
---|
65 | | - | func ParseOrderRawDataStr (rawStateStr) = { |
---|
66 | | - | let tradePair = ParseNextAttribute(rawStateStr) |
---|
67 | | - | let sender = ParseNextAttribute(tradePair[1]) |
---|
68 | | - | let orderType = ParseNextAttribute(sender[1]) |
---|
69 | | - | let price = ParseNextAttribute(orderType[1]) |
---|
70 | | - | let amount = ParseNextAttribute(price[1]) |
---|
71 | | - | let assetId = ParseNextAttribute(amount[1]) |
---|
72 | | - | [price[0], amount[0], tradePair[0], orderType[0], sender[0], assetId[0]] |
---|
73 | | - | } |
---|
74 | | - | |
---|
75 | | - | |
---|
76 | | - | func pow10 (exp) = if ((exp == 0)) |
---|
77 | | - | then 1 |
---|
78 | | - | else if ((exp == 1)) |
---|
79 | | - | then 10 |
---|
80 | | - | else if ((exp == 2)) |
---|
81 | | - | then 100 |
---|
82 | | - | else if ((exp == 3)) |
---|
83 | | - | then 1000 |
---|
84 | | - | else if ((exp == 4)) |
---|
85 | | - | then 10000 |
---|
86 | | - | else if ((exp == 5)) |
---|
87 | | - | then 100000 |
---|
88 | | - | else if ((exp == 6)) |
---|
89 | | - | then 1000000 |
---|
90 | | - | else if ((exp == 7)) |
---|
91 | | - | then 10000000 |
---|
92 | | - | else if ((exp == 8)) |
---|
93 | | - | then 100000000 |
---|
94 | | - | else if ((exp == 9)) |
---|
95 | | - | then 1000000000 |
---|
96 | | - | else if ((exp == 10)) |
---|
97 | | - | then 10000000000 |
---|
98 | | - | else if ((exp == 11)) |
---|
99 | | - | then 100000000000 |
---|
100 | | - | else if ((exp == 12)) |
---|
101 | | - | then 1000000000000 |
---|
102 | | - | else throw("Pow10 more then 12 is not supported") |
---|
103 | | - | |
---|
104 | | - | |
---|
105 | | - | func assetIdFromString (assetId) = if (if ((assetId == "WAVES")) |
---|
106 | | - | then true |
---|
107 | | - | else (assetId == "")) |
---|
108 | | - | then unit |
---|
109 | | - | else fromBase58String(assetId) |
---|
110 | | - | |
---|
111 | | - | |
---|
113 | | - | func order (assetId,price) = { |
---|
114 | | - | let pmt = extract(i.payment) |
---|
115 | | - | let pmtAssetIdStr = if (isDefined(pmt.assetId)) |
---|
116 | | - | then toBase58String(value(pmt.assetId)) |
---|
117 | | - | else "WAVES" |
---|
118 | | - | let possibleTraidPair1 = getString(this, ((assetId + "/") + pmtAssetIdStr)) |
---|
119 | | - | let possibleTraidPair2 = getString(this, ((pmtAssetIdStr + "/") + assetId)) |
---|
120 | | - | let traidPair = if (isDefined(possibleTraidPair1)) |
---|
121 | | - | then value(possibleTraidPair1) |
---|
122 | | - | else if (isDefined(possibleTraidPair2)) |
---|
123 | | - | then value(possibleTraidPair2) |
---|
124 | | - | else throw("Traiding for that assets is not supported") |
---|
125 | | - | let orderType = if (isDefined(possibleTraidPair1)) |
---|
126 | | - | then BUY |
---|
127 | | - | else SELL |
---|
128 | | - | let orderStr = FormatOrderDataStr(traidPair, toBase58String(i.caller.bytes), orderType, price, pmt.amount, pmtAssetIdStr) |
---|
129 | | - | WriteSet([DataEntry(toBase58String(i.transactionId), orderStr)]) |
---|
130 | | - | } |
---|
131 | | - | |
---|
132 | | - | |
---|
133 | | - | |
---|
134 | | - | @Callable(i) |
---|
135 | | - | func matchOrders (order1Id,order2Id) = { |
---|
136 | | - | let order1 = ParseOrderRawDataStr(getStringValue(this, order1Id)) |
---|
137 | | - | let order2 = ParseOrderRawDataStr(getStringValue(this, order2Id)) |
---|
138 | | - | if ((order1[IdxTradePair] != order2[IdxTradePair])) |
---|
139 | | - | then throw("Trying to match orders from different trading pairs") |
---|
140 | | - | else if ((order1[IdxOrderType] == order2[IdxOrderType])) |
---|
141 | | - | then throw("Trying to match orders of the same type") |
---|
142 | | - | else { |
---|
143 | | - | let order1isSell = (order1[IdxOrderType] == SELL) |
---|
144 | | - | let sellOrder = if (order1isSell) |
---|
145 | | - | then order1 |
---|
146 | | - | else order2 |
---|
147 | | - | let buyOrder = if (!(order1isSell)) |
---|
148 | | - | then order1 |
---|
149 | | - | else order2 |
---|
150 | | - | let sellPrice = parseIntValue(sellOrder[IdxPrice]) |
---|
151 | | - | let buyPrice = parseIntValue(buyOrder[IdxPrice]) |
---|
152 | | - | let sellOrderAmount = parseIntValue(sellOrder[IdxAmount]) |
---|
153 | | - | let buyOrderAmount = parseIntValue(buyOrder[IdxAmount]) |
---|
154 | | - | if ((sellPrice > buyPrice)) |
---|
155 | | - | then throw("Orders are not match by price") |
---|
156 | | - | else { |
---|
157 | | - | let exchangePrice = sellPrice |
---|
158 | | - | let amountAssetDecimals = if ((sellOrder[IdxAssetId] == "WAVES")) |
---|
159 | | - | then 8 |
---|
160 | | - | else value(assetInfo(value(assetIdFromString(sellOrder[IdxAssetId])))).decimals |
---|
161 | | - | let priceAssetDecimals = if ((buyOrder[IdxAssetId] == "WAVES")) |
---|
162 | | - | then 8 |
---|
163 | | - | else value(assetInfo(value(assetIdFromString(buyOrder[IdxAssetId])))).decimals |
---|
164 | | - | let buyAmount = ((buyOrderAmount * pow10(amountAssetDecimals)) / exchangePrice) |
---|
165 | | - | let sellAmount = sellOrderAmount |
---|
166 | | - | let amountAssetAmount = if ((buyAmount >= sellAmount)) |
---|
167 | | - | then sellAmount |
---|
168 | | - | else buyAmount |
---|
169 | | - | let priceAssetAmount = ((amountAssetAmount * exchangePrice) / pow10(amountAssetDecimals)) |
---|
170 | | - | let updatedBuyStr = FormatOrderDataStr(buyOrder[IdxTradePair], buyOrder[IdxSender], buyOrder[IdxOrderType], buyPrice, (buyOrderAmount - priceAssetAmount), sellOrder[IdxAssetId]) |
---|
171 | | - | let updatedSellStr = FormatOrderDataStr(sellOrder[IdxTradePair], sellOrder[IdxSender], sellOrder[IdxOrderType], sellPrice, (sellOrderAmount - amountAssetAmount), buyOrder[IdxAssetId]) |
---|
172 | | - | ScriptResult(WriteSet([DataEntry(if (!(order1isSell)) |
---|
173 | | - | then order1Id |
---|
174 | | - | else order2Id, updatedBuyStr), DataEntry(if (order1isSell) |
---|
175 | | - | then order1Id |
---|
176 | | - | else order2Id, updatedSellStr)]), TransferSet([ScriptTransfer(addressFromStringValue(buyOrder[IdxSender]), retainMatcherFee(amountAssetAmount), assetIdFromString(sellOrder[IdxAssetId])), ScriptTransfer(addressFromStringValue(sellOrder[IdxSender]), retainMatcherFee(priceAssetAmount), assetIdFromString(buyOrder[IdxAssetId])), ScriptTransfer(i.caller, matcherFee(amountAssetAmount), assetIdFromString(sellOrder[IdxAssetId])), ScriptTransfer(i.caller, matcherFee(priceAssetAmount), assetIdFromString(buyOrder[IdxAssetId]))])) |
---|
177 | | - | } |
---|
178 | | - | } |
---|
179 | | - | } |
---|
180 | | - | |
---|
181 | | - | |
---|
182 | | - | |
---|
183 | | - | @Callable(i) |
---|
184 | | - | func cancelOrder (orderId) = { |
---|
185 | | - | let order = ParseOrderRawDataStr(getStringValue(this, orderId)) |
---|
186 | | - | if ((addressFromStringValue(order[IdxSender]) != i.caller)) |
---|
187 | | - | then throw("Only order owner can cancel it") |
---|
188 | | - | else { |
---|
189 | | - | let updatedOrderStr = FormatOrderDataStr(order[IdxTradePair], order[IdxSender], order[IdxOrderType], parseIntValue(order[IdxPrice]), 0, order[IdxAssetId]) |
---|
190 | | - | ScriptResult(WriteSet([DataEntry(orderId, updatedOrderStr)]), TransferSet([ScriptTransfer(i.caller, parseIntValue(order[IdxAmount]), assetIdFromString(order[IdxAssetId]))])) |
---|
191 | | - | } |
---|
192 | | - | } |
---|
193 | | - | |
---|
194 | | - | |
---|
195 | | - | |
---|
196 | | - | @Callable(i) |
---|
197 | | - | func registerTraidPair (asset1,priceAsset,traidPair) = if ((i.caller == addressFromStringValue(toBase58String(adminAddress)))) |
---|
198 | | - | then WriteSet([DataEntry(((asset1 + "/") + priceAsset), traidPair)]) |
---|
199 | | - | else throw("Only administrator can register traiding pair") |
---|
| 16 | + | func vote (theVote) = if (!(voterIsAllowedToVote(i.callerPublicKey))) |
---|
| 17 | + | then throw("You can not vote because you are not in the list of voters!") |
---|
| 18 | + | else { |
---|
| 19 | + | let dataFromStorage = getInteger(this, toBase58String(i.callerPublicKey)) |
---|
| 20 | + | if (isDefined(dataFromStorage)) |
---|
| 21 | + | then throw("You have already voted! Voting the second time is not allowed.") |
---|
| 22 | + | else WriteSet([DataEntry(toBase58String(i.callerPublicKey), theVote)]) |
---|
| 23 | + | } |
---|