17 #include <boost/algorithm/string/classification.hpp>
18 #include <boost/algorithm/string/split.hpp>
27 static std::map<std::string, opcodetype> mapOpNames;
29 if (mapOpNames.empty())
31 for (
unsigned int op = 0; op <=
MAX_OPCODE; op++)
38 if (strName ==
"OP_UNKNOWN")
40 mapOpNames[strName] =
static_cast<opcodetype>(op);
42 if (strName.compare(0, 3,
"OP_") == 0) {
43 mapOpNames[strName.substr(3)] =
static_cast<opcodetype>(op);
48 auto it = mapOpNames.find(s);
49 if (
it == mapOpNames.end())
throw std::runtime_error(
"script parse error: unknown opcode");
59 std::vector<std::string> words;
60 boost::algorithm::split(words, s, boost::algorithm::is_any_of(
" \t\n"), boost::algorithm::token_compress_on);
62 for (std::vector<std::string>::const_iterator w = words.begin(); w != words.end(); ++w)
68 else if (std::all_of(w->begin(), w->end(), ::
IsDigit) ||
69 (w->front() ==
'-' && w->size() > 1 && std::all_of(w->begin()+1, w->end(), ::
IsDigit)))
76 if (n > int64_t{0xffffffff} || n < -1 * int64_t{0xffffffff}) {
77 throw std::runtime_error(
"script parse error: decimal numeric value only allowed in the "
78 "range -0xFFFFFFFF...0xFFFFFFFF");
83 else if (w->substr(0,2) ==
"0x" && w->size() > 2 &&
IsHex(std::string(w->begin()+2, w->end())))
86 std::vector<unsigned char> raw =
ParseHex(std::string(w->begin()+2, w->end()));
87 result.
insert(result.
end(), raw.begin(), raw.end());
89 else if (w->size() >= 2 && w->front() ==
'\'' && w->back() ==
'\'')
93 std::vector<unsigned char> value(w->begin()+1, w->end()-1);
99 result << ParseOpCode(*w);
111 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
118 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
143 bool ok_extended =
false, ok_legacy =
false;
150 ssData >> tx_extended;
151 if (ssData.
empty()) ok_extended =
true;
152 }
catch (
const std::exception&) {
160 tx = std::move(tx_extended);
165 if (try_no_witness) {
169 if (ssData.
empty()) ok_legacy =
true;
170 }
catch (
const std::exception&) {
178 tx = std::move(tx_legacy);
184 tx = std::move(tx_extended);
190 tx = std::move(tx_legacy);
200 if (!
IsHex(hex_tx)) {
204 std::vector<unsigned char> txData(
ParseHex(hex_tx));
205 return DecodeTx(tx, txData, try_no_witness, try_witness);
210 if (!
IsHex(hex_header))
return false;
212 const std::vector<unsigned char> header_data{
ParseHex(hex_header)};
215 ser_header >> header;
216 }
catch (
const std::exception&) {
224 if (!
IsHex(strHexBlk))
227 std::vector<unsigned char> blockData(
ParseHex(strHexBlk));
232 catch (
const std::exception&) {
241 if ((strHex.size() != 64) || !
IsHex(strHex))
254 throw std::runtime_error(strName +
" must be hexadecimal string (not '" + strHex +
"')");
262 static std::map<std::string, int> map_sighash_values = {
270 std::string strHashType = sighash.
get_str();
271 const auto&
it = map_sighash_values.find(strHashType);
272 if (
it != map_sighash_values.end()) {
273 hash_type =
it->second;
275 throw std::runtime_error(strHashType +
" is not a valid sighash parameter.");