20 #include <boost/algorithm/string/classification.hpp> 21 #include <boost/algorithm/string/replace.hpp> 22 #include <boost/algorithm/string/split.hpp> 29 static std::map<std::string, opcodetype> mapOpNames;
31 if (mapOpNames.empty()) {
38 if (strcmp(name,
"OP_UNKNOWN") == 0) {
42 std::string strName(name);
43 mapOpNames[strName] =
static_cast<opcodetype>(op);
45 boost::algorithm::replace_first(strName,
"OP_",
"");
46 mapOpNames[strName] =
static_cast<opcodetype>(op);
50 std::vector<std::string> words;
51 boost::algorithm::split(words, s, boost::algorithm::is_any_of(
" \t\n"),
52 boost::algorithm::token_compress_on);
54 size_t push_size = 0, next_push_size = 0;
55 size_t script_size = 0;
57 size_t push_data_size = 0;
59 for (
const auto &w : words) {
67 script_size = result.
size();
70 push_size = next_push_size;
74 if (std::all_of(w.begin(), w.end(),
::IsDigit) ||
75 (w.front() ==
'-' && w.size() > 1 &&
76 std::all_of(w.begin() + 1, w.end(),
::IsDigit))) {
83 if (n > int64_t{0xffffffff} || n < -1 * int64_t{0xffffffff}) {
84 throw std::runtime_error(
"script parse error: decimal numeric " 85 "value only allowed in the " 86 "range -0xFFFFFFFF...0xFFFFFFFF");
94 if (w.substr(0, 2) ==
"0x" && w.size() > 2) {
95 if (!
IsHex(std::string(w.begin() + 2, w.end()))) {
97 throw std::runtime_error(
"Hex numbers expected to be formatted " 98 "in full-byte chunks (ex: 0x00 " 103 std::vector<uint8_t> raw =
104 ParseHex(std::string(w.begin() + 2, w.end()));
106 result.
insert(result.
end(), raw.begin(), raw.end());
110 if (w.size() >= 2 && w.front() ==
'\'' && w.back() ==
'\'') {
114 std::vector<uint8_t> value(w.begin() + 1, w.end() - 1);
119 if (mapOpNames.count(w)) {
127 throw std::runtime_error(
"Error parsing script: " + s);
130 size_t size_change = result.
size() - script_size;
133 if (push_size != 0 && size_change != push_size) {
134 throw std::runtime_error(
135 "Wrong number of bytes being pushed. Expected:" +
142 if (push_size != 0 && push_data_size != 0) {
143 auto offset = &result[script_size];
148 if (push_data_size == 1) {
149 next_push_size = *offset;
150 }
else if (push_data_size == 2) {
152 }
else if (push_data_size == 4) {
162 if (push_size == 0 && size_change == 1) {
174 push_data_size = next_push_size = 1;
177 push_data_size = next_push_size = 2;
180 push_data_size = next_push_size = 4;
192 if (!
IsHex(strHexTx)) {
196 std::vector<uint8_t> txData(
ParseHex(strHexTx));
204 }
catch (
const std::exception &e) {
212 if (!
IsHex(hex_header)) {
216 const std::vector<uint8_t> header_data{
ParseHex(hex_header)};
219 ser_header >> header;
220 }
catch (
const std::exception &) {
227 if (!
IsHex(strHexBlk)) {
231 std::vector<uint8_t> blockData(
ParseHex(strHexBlk));
235 }
catch (
const std::exception &) {
243 if ((strHex.size() != 64) || !
IsHex(strHex)) {
257 if (!
IsHex(strHex)) {
258 throw std::runtime_error(
259 strName +
" must be hexadecimal string (not '" + strHex +
"')");
268 static std::map<std::string, int> map_sighash_values = {
272 {
"ALL|FORKID|ANYONECANPAY",
277 {
"NONE|FORKID|ANYONECANPAY",
282 {
"SINGLE|FORKID|ANYONECANPAY",
285 std::string strHashType = sighash.
get_str();
286 const auto &it = map_sighash_values.find(strHashType);
287 if (it != map_sighash_values.end()) {
290 throw std::runtime_error(strHashType +
291 " is not a valid sighash parameter.");
bool DecodeHexBlockHeader(CBlockHeader &header, const std::string &hex_header)
static uint16_t ReadLE16(const uint8_t *ptr)
std::vector< uint8_t > ParseHexUV(const UniValue &v, const std::string &strName)
iterator insert(iterator pos, const T &value)
SigHashType ParseSighashString(const UniValue &sighash)
constexpr bool IsDigit(char c)
Tests if the given character is a decimal digit.
const std::string & get_str() const
Double ended buffer combining vector and stream-like interfaces.
const std::string & getValStr() const
std::string ToString(const T &t)
Locale-independent version of std::to_string.
opcodetype
Script opcodes.
SigHashType withForkId(bool forkId=true) const
bool IsHex(const std::string &str)
Returns true if each character in str is a hex character, and has an even number of hex digits...
reverse_iterator rbegin()
static uint32_t ReadLE32(const uint8_t *ptr)
const char * GetOpName(opcodetype opcode)
CScript ParseScript(const std::string &s)
int64_t atoi64(const char *psz)
Serialized script, used inside transaction inputs and outputs.
static const int PROTOCOL_VERSION
network protocol versioning
std::vector< uint8_t > ParseHex(const char *psz)
A mutable version of CTransaction.
bool DecodeHexTx(CMutableTransaction &tx, const std::string &strHexTx)
bool ParseHashStr(const std::string &strHex, uint256 &result)
Parse a hex string into 256 bits.
void SetHex(const char *psz)
bool DecodeHexBlk(CBlock &block, const std::string &strHexBlk)
Signature hash type wrapper class.