You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

core_read.cpp 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright (c) 2009-2015 The Bitcoin Core developers
  2. // Distributed under the MIT software license, see the accompanying
  3. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4. #include "core_io.h"
  5. #include "primitives/block.h"
  6. #include "primitives/transaction.h"
  7. #include "script/script.h"
  8. #include "serialize.h"
  9. #include "streams.h"
  10. #include <univalue.h>
  11. #include "util.h"
  12. #include "utilstrencodings.h"
  13. #include "version.h"
  14. #include <boost/algorithm/string/classification.hpp>
  15. #include <boost/algorithm/string/predicate.hpp>
  16. #include <boost/algorithm/string/replace.hpp>
  17. #include <boost/algorithm/string/split.hpp>
  18. #include <boost/assign/list_of.hpp>
  19. using namespace std;
  20. CScript ParseScript(const std::string& s)
  21. {
  22. CScript result;
  23. static map<string, opcodetype> mapOpNames;
  24. if (mapOpNames.empty())
  25. {
  26. for (int op = 0; op <= OP_NOP10; op++)
  27. {
  28. // Allow OP_RESERVED to get into mapOpNames
  29. if (op < OP_NOP && op != OP_RESERVED)
  30. continue;
  31. const char* name = GetOpName((opcodetype)op);
  32. if (strcmp(name, "OP_UNKNOWN") == 0)
  33. continue;
  34. string strName(name);
  35. mapOpNames[strName] = (opcodetype)op;
  36. // Convenience: OP_ADD and just ADD are both recognized:
  37. boost::algorithm::replace_first(strName, "OP_", "");
  38. mapOpNames[strName] = (opcodetype)op;
  39. }
  40. }
  41. vector<string> words;
  42. boost::algorithm::split(words, s, boost::algorithm::is_any_of(" \t\n"), boost::algorithm::token_compress_on);
  43. for (std::vector<std::string>::const_iterator w = words.begin(); w != words.end(); ++w)
  44. {
  45. if (w->empty())
  46. {
  47. // Empty string, ignore. (boost::split given '' will return one word)
  48. }
  49. else if (all(*w, boost::algorithm::is_digit()) ||
  50. (boost::algorithm::starts_with(*w, "-") && all(string(w->begin()+1, w->end()), boost::algorithm::is_digit())))
  51. {
  52. // Number
  53. int64_t n = atoi64(*w);
  54. result << n;
  55. }
  56. else if (boost::algorithm::starts_with(*w, "0x") && (w->begin()+2 != w->end()) && IsHex(string(w->begin()+2, w->end())))
  57. {
  58. // Raw hex data, inserted NOT pushed onto stack:
  59. std::vector<unsigned char> raw = ParseHex(string(w->begin()+2, w->end()));
  60. result.insert(result.end(), raw.begin(), raw.end());
  61. }
  62. else if (w->size() >= 2 && boost::algorithm::starts_with(*w, "'") && boost::algorithm::ends_with(*w, "'"))
  63. {
  64. // Single-quoted string, pushed as data. NOTE: this is poor-man's
  65. // parsing, spaces/tabs/newlines in single-quoted strings won't work.
  66. std::vector<unsigned char> value(w->begin()+1, w->end()-1);
  67. result << value;
  68. }
  69. else if (mapOpNames.count(*w))
  70. {
  71. // opcode, e.g. OP_ADD or ADD:
  72. result << mapOpNames[*w];
  73. }
  74. else
  75. {
  76. throw runtime_error("script parse error");
  77. }
  78. }
  79. return result;
  80. }
  81. bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx)
  82. {
  83. if (!IsHex(strHexTx))
  84. return false;
  85. vector<unsigned char> txData(ParseHex(strHexTx));
  86. CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
  87. try {
  88. ssData >> tx;
  89. }
  90. catch (const std::exception&) {
  91. return false;
  92. }
  93. return true;
  94. }
  95. bool DecodeHexBlk(CBlock& block, const std::string& strHexBlk)
  96. {
  97. if (!IsHex(strHexBlk))
  98. return false;
  99. std::vector<unsigned char> blockData(ParseHex(strHexBlk));
  100. CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION);
  101. try {
  102. ssBlock >> block;
  103. }
  104. catch (const std::exception&) {
  105. return false;
  106. }
  107. return true;
  108. }
  109. uint256 ParseHashUV(const UniValue& v, const string& strName)
  110. {
  111. string strHex;
  112. if (v.isStr())
  113. strHex = v.getValStr();
  114. return ParseHashStr(strHex, strName); // Note: ParseHashStr("") throws a runtime_error
  115. }
  116. uint256 ParseHashStr(const std::string& strHex, const std::string& strName)
  117. {
  118. if (!IsHex(strHex)) // Note: IsHex("") is false
  119. throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')");
  120. uint256 result;
  121. result.SetHex(strHex);
  122. return result;
  123. }
  124. vector<unsigned char> ParseHexUV(const UniValue& v, const string& strName)
  125. {
  126. string strHex;
  127. if (v.isStr())
  128. strHex = v.getValStr();
  129. if (!IsHex(strHex))
  130. throw runtime_error(strName+" must be hexadecimal string (not '"+strHex+"')");
  131. return ParseHex(strHex);
  132. }