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