1 #include <qtum/qtumtoken.h>
2 #include <validation.h>
3 #include <util/moneystr.h>
4 #include <util/contractabi.h>
5 #include <key_io.h>
6 #include <util/strencodings.h>
7 #include <util/convert.h>
8 #include <libethcore/ABI.h>
9
10 namespace QtumToken_NS
11 {
12 const char *TOKEN_ABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_spender\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"burnFrom\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_spender\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"},{\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"approveAndCall\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"},{\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"initialSupply\",\"type\":\"uint256\"},{\"name\":\"tokenName\",\"type\":\"string\"},{\"name\":\"decimalUnits\",\"type\":\"uint8\"},{\"name\":\"tokenSymbol\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Burn\",\"type\":\"event\"}]";
13 const char *PARAM_ADDRESS = "address";
14 const char *PARAM_DATAHEX = "datahex";
15 const char *PARAM_AMOUNT = "amount";
16 const char *PARAM_GASLIMIT = "gaslimit";
17 const char *PARAM_GASPRICE = "gasprice";
18 const char *PARAM_SENDER = "sender";
19 const char *PARAM_BROADCAST = "broadcast";
20 const char *PARAM_CHANGE_TO_SENDER = "changeToSender";
21 }
22
execValid(const int &,const bool &)23 bool QtumTokenExec::execValid(const int &, const bool &)
24 {
25 return false;
26 }
27
execEventsValid(const int &,const int64_t &)28 bool QtumTokenExec::execEventsValid(const int &, const int64_t &)
29 {
30 return false;
31 }
32
exec(const bool &,const std::map<std::string,std::string> &,std::string &,std::string &)33 bool QtumTokenExec::exec(const bool &, const std::map<std::string, std::string> &, std::string &, std::string &)
34 {
35 return false;
36 }
37
execEvents(const int64_t &,const int64_t &,const int64_t &,const std::string &,const std::string &,const std::string &,const int &,std::vector<TokenEvent> &)38 bool QtumTokenExec::execEvents(const int64_t &, const int64_t &, const int64_t&, const std::string &, const std::string &, const std::string &, const int &, std::vector<TokenEvent> &)
39 {
40 return false;
41 }
42
~QtumTokenExec()43 QtumTokenExec::~QtumTokenExec()
44 {}
45
46 struct QtumTokenData
47 {
48 std::map<std::string, std::string> lstParams;
49 std::string address;
50 QtumTokenExec* tokenExec;
51 ContractABI* ABI;
52 int funcName;
53 int funcApprove;
54 int funcTotalSupply;
55 int funcTransferFrom;
56 int funcDecimals;
57 int funcBurn;
58 int funcBalanceOf;
59 int funcBurnFrom;
60 int funcSymbol;
61 int funcTransfer;
62 int funcApproveAndCall;
63 int funcAllowance;
64 int evtTransfer;
65 int evtBurn;
66
67 std::string txid;
68 std::string errorMessage;
69
QtumTokenDataQtumTokenData70 QtumTokenData():
71 tokenExec(0),
72 ABI(0),
73 funcName(-1),
74 funcApprove(-1),
75 funcTotalSupply(-1),
76 funcTransferFrom(-1),
77 funcDecimals(-1),
78 funcBurn(-1),
79 funcBalanceOf(-1),
80 funcBurnFrom(-1),
81 funcSymbol(-1),
82 funcTransfer(-1),
83 funcApproveAndCall(-1),
84 funcAllowance(-1),
85 evtTransfer(-1),
86 evtBurn(-1)
87 {}
88 };
89
ToHash160(const std::string & strQtumAddress,std::string & strHash160)90 bool QtumToken::ToHash160(const std::string& strQtumAddress, std::string& strHash160)
91 {
92 CTxDestination qtumAddress = DecodeDestination(strQtumAddress);
93 if(!IsValidDestination(qtumAddress))
94 return false;
95 const PKHash * keyid = boost::get<PKHash>(&qtumAddress);
96 if(keyid){
97 strHash160 = HexStr(valtype(keyid->begin(),keyid->end()));
98 }else{
99 return false;
100 }
101 return true;
102 }
103
ToQtumAddress(const std::string & strHash160,std::string & strQtumAddress)104 bool QtumToken::ToQtumAddress(const std::string& strHash160, std::string& strQtumAddress)
105 {
106 uint160 key(ParseHex(strHash160.c_str()));
107 PKHash keyid(key);
108 CTxDestination qtumAddress = keyid;
109 if(IsValidDestination(qtumAddress)){
110 strQtumAddress = EncodeDestination(qtumAddress);
111 return true;
112 }
113 return false;
114 }
115
ToUint256(const std::string & data)116 uint256 QtumToken::ToUint256(const std::string &data)
117 {
118 dev::bytes rawData = dev::fromHex(data);
119 dev::bytesConstRef o(&rawData);
120 dev::u256 outData = dev::eth::ABIDeserialiser<dev::u256>::deserialise(o);
121 return u256Touint(outData);
122 }
123
QtumToken()124 QtumToken::QtumToken():
125 d(0)
126 {
127 d = new QtumTokenData();
128 clear();
129
130 // Compute functions indexes
131 d->ABI = new ContractABI();
132 if(d->ABI->loads(QtumToken_NS::TOKEN_ABI))
133 {
134 for(size_t i = 0; i < d->ABI->functions.size(); i++)
135 {
136 FunctionABI func = d->ABI->functions[i];
137 if(func.name == "name")
138 {
139 d->funcName = i;
140 }
141 else if(func.name == "approve")
142 {
143 d->funcApprove = i;
144 }
145 else if(func.name == "totalSupply")
146 {
147 d->funcTotalSupply = i;
148 }
149 else if(func.name == "transferFrom")
150 {
151 d->funcTransferFrom = i;
152 }
153 else if(func.name == "decimals")
154 {
155 d->funcDecimals = i;
156 }
157 else if(func.name == "burn")
158 {
159 d->funcBurn = i;
160 }
161 else if(func.name == "balanceOf")
162 {
163 d->funcBalanceOf = i;
164 }
165 else if(func.name == "burnFrom")
166 {
167 d->funcBurnFrom = i;
168 }
169 else if(func.name == "symbol")
170 {
171 d->funcSymbol = i;
172 }
173 else if(func.name == "transfer")
174 {
175 d->funcTransfer = i;
176 }
177 else if(func.name == "approveAndCall")
178 {
179 d->funcApproveAndCall = i;
180 }
181 else if(func.name == "allowance")
182 {
183 d->funcAllowance = i;
184 }
185 else if(func.name == "Transfer")
186 {
187 d->evtTransfer = i;
188 }
189 else if(func.name == "Burn")
190 {
191 d->evtBurn = i;
192 }
193 }
194 }
195 }
196
~QtumToken()197 QtumToken::~QtumToken()
198 {
199 d->tokenExec = 0;
200
201 if(d)
202 delete d;
203 d = 0;
204 }
205
setAddress(const std::string & address)206 void QtumToken::setAddress(const std::string &address)
207 {
208 d->lstParams[QtumToken_NS::PARAM_ADDRESS] = address;
209 }
210
setDataHex(const std::string & datahex)211 void QtumToken::setDataHex(const std::string &datahex)
212 {
213 d->lstParams[QtumToken_NS::PARAM_DATAHEX] = datahex;
214 }
215
setAmount(const std::string & amount)216 void QtumToken::setAmount(const std::string &amount)
217 {
218 d->lstParams[QtumToken_NS::PARAM_AMOUNT] = amount;
219 }
220
setGasLimit(const std::string & gaslimit)221 void QtumToken::setGasLimit(const std::string &gaslimit)
222 {
223 d->lstParams[QtumToken_NS::PARAM_GASLIMIT] = gaslimit;
224 }
225
setGasPrice(const std::string & gasPrice)226 void QtumToken::setGasPrice(const std::string &gasPrice)
227 {
228 d->lstParams[QtumToken_NS::PARAM_GASPRICE] = gasPrice;
229 }
230
setSender(const std::string & sender)231 void QtumToken::setSender(const std::string &sender)
232 {
233 d->lstParams[QtumToken_NS::PARAM_SENDER] = sender;
234 }
235
clear()236 void QtumToken::clear()
237 {
238 d->lstParams.clear();
239
240 setAmount("0");
241 setGasPrice(FormatMoney(DEFAULT_GAS_PRICE));
242 setGasLimit(std::to_string(DEFAULT_GAS_LIMIT_OP_SEND));
243
244 d->lstParams[QtumToken_NS::PARAM_BROADCAST] = "true";
245 d->lstParams[QtumToken_NS::PARAM_CHANGE_TO_SENDER] = "true";
246 }
247
getTxId()248 std::string QtumToken::getTxId()
249 {
250 return d->txid;
251 }
252
name(std::string & result,bool sendTo)253 bool QtumToken::name(std::string &result, bool sendTo)
254 {
255 std::vector<std::string> input;
256 std::vector<std::string> output;
257 if(!exec(input, d->funcName, output, sendTo))
258 return false;
259
260 if(!sendTo)
261 {
262 if(output.size() == 0)
263 return false;
264 else
265 result = output[0];
266 }
267
268 return true;
269 }
270
approve(const std::string & _spender,const std::string & _value,bool & success,bool sendTo)271 bool QtumToken::approve(const std::string &_spender, const std::string &_value, bool &success, bool sendTo)
272 {
273 std::string spender = _spender;
274 if(!ToHash160(spender, spender))
275 {
276 return false;
277 }
278
279 std::vector<std::string> input;
280 input.push_back(spender);
281 input.push_back(_value);
282 std::vector<std::string> output;
283
284 if(!exec(input, d->funcApprove, output, sendTo))
285 return false;
286
287 if(!sendTo)
288 {
289 if(output.size() == 0)
290 return false;
291 else
292 success = output[0] == "true";
293 }
294
295 return true;
296 }
297
totalSupply(std::string & result,bool sendTo)298 bool QtumToken::totalSupply(std::string &result, bool sendTo)
299 {
300 std::vector<std::string> input;
301 std::vector<std::string> output;
302 if(!exec(input, d->funcTotalSupply, output, sendTo))
303 return false;
304
305 if(!sendTo)
306 {
307 if(output.size() == 0)
308 return false;
309 else
310 result = output[0];
311 }
312
313 return true;
314 }
315
transferFrom(const std::string & _from,const std::string & _to,const std::string & _value,bool & success,bool sendTo)316 bool QtumToken::transferFrom(const std::string &_from, const std::string &_to, const std::string &_value, bool &success, bool sendTo)
317 {
318 std::string from = _from;
319 if(!ToHash160(from, from))
320 {
321 return false;
322 }
323 std::string to = _to;
324 if(!ToHash160(to, to))
325 {
326 return false;
327 }
328
329 std::vector<std::string> input;
330 input.push_back(from);
331 input.push_back(to);
332 input.push_back(_value);
333 std::vector<std::string> output;
334
335 if(!exec(input, d->funcTransferFrom, output, sendTo))
336 return false;
337
338 if(!sendTo)
339 {
340 if(output.size() == 0)
341 return false;
342 else
343 success = output[0] == "true";
344 }
345
346 return true;
347 }
348
decimals(std::string & result,bool sendTo)349 bool QtumToken::decimals(std::string &result, bool sendTo)
350 {
351 std::vector<std::string> input;
352 std::vector<std::string> output;
353 if(!exec(input, d->funcDecimals, output, sendTo))
354 return false;
355
356 if(!sendTo)
357 {
358 if(output.size() == 0)
359 return false;
360 else
361 result = output[0];
362 }
363
364 return true;
365 }
366
decimals(uint32_t & result)367 bool QtumToken::decimals(uint32_t &result)
368 {
369 std::string str;
370 bool ret = decimals(str);
371 if(ret) ret &= ParseUInt32(str, &result);
372 if(ret) ret &= result <= 77;
373 return ret;
374 }
375
burn(const std::string & _value,bool & success,bool sendTo)376 bool QtumToken::burn(const std::string &_value, bool &success, bool sendTo)
377 {
378 std::vector<std::string> input;
379 input.push_back(_value);
380 std::vector<std::string> output;
381
382 if(!exec(input, d->funcBurn, output, sendTo))
383 return false;
384
385 if(!sendTo)
386 {
387 if(output.size() == 0)
388 return false;
389 else
390 success = output[0] == "true";
391 }
392
393 return true;
394 }
395
balanceOf(std::string & result,bool sendTo)396 bool QtumToken::balanceOf(std::string &result, bool sendTo)
397 {
398 std::string spender = d->lstParams[QtumToken_NS::PARAM_SENDER];
399 return balanceOf(spender, result, sendTo);
400 }
401
balanceOf(const std::string & _spender,std::string & result,bool sendTo)402 bool QtumToken::balanceOf(const std::string &_spender, std::string &result, bool sendTo)
403 {
404 std::string spender = _spender;
405 if(!ToHash160(spender, spender))
406 {
407 return false;
408 }
409
410 std::vector<std::string> input;
411 input.push_back(spender);
412 std::vector<std::string> output;
413
414 if(!exec(input, d->funcBalanceOf, output, sendTo))
415 return false;
416
417 if(!sendTo)
418 {
419 if(output.size() == 0)
420 return false;
421 else
422 result = output[0];
423 }
424
425 return true;
426 }
427
burnFrom(const std::string & _from,const std::string & _value,bool & success,bool sendTo)428 bool QtumToken::burnFrom(const std::string &_from, const std::string &_value, bool &success, bool sendTo)
429 {
430 std::string from = _from;
431 if(!ToHash160(from, from))
432 {
433 return false;
434 }
435
436 std::vector<std::string> input;
437 input.push_back(from);
438 input.push_back(_value);
439 std::vector<std::string> output;
440
441 if(!exec(input, d->funcBurnFrom, output, sendTo))
442 return false;
443
444 if(!sendTo)
445 {
446 if(output.size() == 0)
447 return false;
448 else
449 success = output[0] == "true";
450 }
451
452 return true;
453 }
454
symbol(std::string & result,bool sendTo)455 bool QtumToken::symbol(std::string &result, bool sendTo)
456 {
457 std::vector<std::string> input;
458 std::vector<std::string> output;
459 if(!exec(input, d->funcSymbol, output, sendTo))
460 return false;
461
462 if(!sendTo)
463 {
464 if(output.size() == 0)
465 return false;
466 else
467 result = output[0];
468 }
469
470 return true;
471 }
472
transfer(const std::string & _to,const std::string & _value,bool & success,bool sendTo)473 bool QtumToken::transfer(const std::string &_to, const std::string &_value, bool& success, bool sendTo)
474 {
475 std::string to = _to;
476 if(!ToHash160(to, to))
477 {
478 return false;
479 }
480
481 std::vector<std::string> input;
482 input.push_back(to);
483 input.push_back(_value);
484 std::vector<std::string> output;
485
486 if(!exec(input, d->funcTransfer, output, sendTo))
487 return false;
488
489 if(!sendTo)
490 {
491 if(output.size() == 0)
492 return false;
493 else
494 success = output[0] == "true";
495 }
496
497 return true;
498 }
499
approveAndCall(const std::string & _spender,const std::string & _value,const std::string & _extraData,bool & success,bool sendTo)500 bool QtumToken::approveAndCall(const std::string &_spender, const std::string &_value, const std::string &_extraData, bool &success, bool sendTo)
501 {
502 std::string spender = _spender;
503 if(!ToHash160(spender, spender))
504 {
505 return false;
506 }
507
508 std::vector<std::string> input;
509 input.push_back(spender);
510 input.push_back(_value);
511 input.push_back(_extraData);
512 std::vector<std::string> output;
513
514 if(!exec(input, d->funcApproveAndCall, output, sendTo))
515 return false;
516
517 if(!sendTo)
518 {
519 if(output.size() == 0)
520 return false;
521 else
522 success = output[0] == "true";
523 }
524
525 return true;
526 }
527
allowance(const std::string & _from,const std::string & _to,std::string & result,bool sendTo)528 bool QtumToken::allowance(const std::string &_from, const std::string &_to, std::string &result, bool sendTo)
529 {
530 std::string from = _from;
531 if(!ToHash160(from, from))
532 {
533 return false;
534 }
535 std::string to = _to;
536 if(!ToHash160(to, to))
537 {
538 return false;
539 }
540
541 std::vector<std::string> input;
542 input.push_back(from);
543 input.push_back(to);
544 std::vector<std::string> output;
545
546 if(!exec(input, d->funcAllowance, output, sendTo))
547 return false;
548
549 if(!sendTo)
550 {
551 if(output.size() == 0)
552 return false;
553 else
554 result = output[0];
555 }
556
557 return true;
558 }
559
transferEvents(std::vector<TokenEvent> & tokenEvents,int64_t fromBlock,int64_t toBlock,int64_t minconf)560 bool QtumToken::transferEvents(std::vector<TokenEvent> &tokenEvents, int64_t fromBlock, int64_t toBlock, int64_t minconf)
561 {
562 return execEvents(fromBlock, toBlock, minconf, d->evtTransfer, tokenEvents);
563 }
564
burnEvents(std::vector<TokenEvent> & tokenEvents,int64_t fromBlock,int64_t toBlock,int64_t minconf)565 bool QtumToken::burnEvents(std::vector<TokenEvent> &tokenEvents, int64_t fromBlock, int64_t toBlock, int64_t minconf)
566 {
567 return execEvents(fromBlock, toBlock, minconf, d->evtBurn, tokenEvents);
568 }
569
exec(const std::vector<std::string> & input,int func,std::vector<std::string> & output,bool sendTo)570 bool QtumToken::exec(const std::vector<std::string> &input, int func, std::vector<std::string> &output, bool sendTo)
571 {
572 // Convert the input data into hex encoded binary data
573 d->txid = "";
574 if(d->tokenExec == 0 || !(d->tokenExec->execValid(func, sendTo)))
575 return false;
576 std::string strData;
577 FunctionABI function = d->ABI->functions[func];
578 std::vector<std::vector<std::string>> values;
579 for(size_t i = 0; i < input.size(); i++)
580 {
581 std::vector<std::string> param;
582 param.push_back(input[i]);
583 values.push_back(param);
584 }
585 std::vector<ParameterABI::ErrorType> errors;
586 if(!function.abiIn(values, strData, errors))
587 return false;
588 setDataHex(strData);
589
590 // Execute the command and get the result
591 std::string result;
592 d->errorMessage.clear();
593 if(!(d->tokenExec->exec(sendTo, d->lstParams, result, d->errorMessage)))
594 return false;
595
596 // Get the result from calling function
597 if(!sendTo)
598 {
599 std::string rawData = result;
600 std::vector<std::vector<std::string>> values;
601 std::vector<ParameterABI::ErrorType> errors;
602 if(!function.abiOut(rawData, values, errors))
603 return false;
604 for(size_t i = 0; i < values.size(); i++)
605 {
606 std::vector<std::string> param = values[i];
607 output.push_back(param.size() ? param[0] : "");
608 }
609 }
610 else
611 {
612 d->txid = result;
613 }
614
615 return true;
616 }
617
addTokenEvent(std::vector<TokenEvent> & tokenEvents,TokenEvent tokenEvent)618 void QtumToken::addTokenEvent(std::vector<TokenEvent> &tokenEvents, TokenEvent tokenEvent)
619 {
620 // Check if the event is from an existing token transaction and update the value
621 bool found = false;
622 for(size_t i = 0; i < tokenEvents.size(); i++)
623 {
624 // Compare the event data
625 TokenEvent tokenTx = tokenEvents[i];
626 if(tokenTx.address != tokenEvent.address) continue;
627 if(tokenTx.sender != tokenEvent.sender) continue;
628 if(tokenTx.receiver != tokenEvent.receiver) continue;
629 if(tokenTx.blockHash != tokenEvent.blockHash) continue;
630 if(tokenTx.blockNumber != tokenEvent.blockNumber) continue;
631 if(tokenTx.transactionHash != tokenEvent.transactionHash) continue;
632
633 // Update the value
634 dev::u256 tokenValue = uintTou256(tokenTx.value) + uintTou256(tokenEvent.value);
635 tokenTx.value = u256Touint(tokenValue);
636 tokenEvents[i] = tokenTx;
637 found = true;
638 break;
639 }
640
641 // Add new event
642 if(!found)
643 tokenEvents.push_back(tokenEvent);
644 }
645
execEvents(int64_t fromBlock,int64_t toBlock,int64_t minconf,int func,std::vector<TokenEvent> & tokenEvents)646 bool QtumToken::execEvents(int64_t fromBlock, int64_t toBlock, int64_t minconf, int func, std::vector<TokenEvent> &tokenEvents)
647 {
648 // Check parameters
649 if(d->tokenExec == 0 || !(d->tokenExec->execEventsValid(func, fromBlock)))
650 return false;
651
652 // Get function
653 FunctionABI function = d->ABI->functions[func];
654
655 // Search for events
656 std::vector<TokenEvent> result;
657 std::string eventName = function.selector();
658 std::string contractAddress = d->lstParams[QtumToken_NS::PARAM_ADDRESS];
659 std::string senderAddress = d->lstParams[QtumToken_NS::PARAM_SENDER];
660 ToHash160(senderAddress, senderAddress);
661 senderAddress = "000000000000000000000000" + senderAddress;
662 int numTopics = function.numIndexed() + 1;
663 if(!(d->tokenExec->execEvents(fromBlock, toBlock, minconf, eventName, contractAddress, senderAddress, numTopics, result)))
664 return false;
665
666 // Parse the result events
667 for(const TokenEvent& tokenEvent : result)
668 {
669 addTokenEvent(tokenEvents, tokenEvent);
670 }
671
672 return true;
673 }
674
getErrorMessage()675 std::string QtumToken::getErrorMessage()
676 {
677 return d->errorMessage;
678 }
679
setQtumTokenExec(QtumTokenExec * tokenExec)680 void QtumToken::setQtumTokenExec(QtumTokenExec *tokenExec)
681 {
682 d->tokenExec = tokenExec;
683 }
684
paramAddress()685 const char* QtumToken::paramAddress()
686 {
687 return QtumToken_NS::PARAM_ADDRESS;
688 }
689
paramDatahex()690 const char* QtumToken::paramDatahex()
691 {
692 return QtumToken_NS::PARAM_DATAHEX;
693 }
694
paramAmount()695 const char* QtumToken::paramAmount()
696 {
697 return QtumToken_NS::PARAM_AMOUNT;
698 }
699
paramGasLimit()700 const char* QtumToken::paramGasLimit()
701 {
702 return QtumToken_NS::PARAM_GASLIMIT;
703 }
704
paramGasPrice()705 const char* QtumToken::paramGasPrice()
706 {
707 return QtumToken_NS::PARAM_GASPRICE;
708 }
709
paramSender()710 const char* QtumToken::paramSender()
711 {
712 return QtumToken_NS::PARAM_SENDER;
713 }
714
paramBroadcast()715 const char* QtumToken::paramBroadcast()
716 {
717 return QtumToken_NS::PARAM_BROADCAST;
718 }
719
paramChangeToSender()720 const char* QtumToken::paramChangeToSender()
721 {
722 return QtumToken_NS::PARAM_CHANGE_TO_SENDER;
723 }
724