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