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()) {
30 for (
unsigned int op = 0; op <=
MAX_OPCODE; op++) {
37 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 (
const std::string& w : words) {
65 }
else if (std::all_of(w.begin(), w.end(), ::
IsDigit) ||
66 (w.front() ==
'-' && w.size() > 1 && std::all_of(w.begin() + 1, w.end(), ::
IsDigit)))
69 const auto num{ToIntegral<int64_t>(w)};
73 if (!num.has_value() || num > int64_t{0xffffffff} || num < -1 * int64_t{0xffffffff}) {
74 throw std::runtime_error(
"script parse error: decimal numeric value only allowed in the "
75 "range -0xFFFFFFFF...0xFFFFFFFF");
78 result << num.value();
79 }
else if (w.substr(0, 2) ==
"0x" && w.size() > 2 &&
IsHex(std::string(w.begin() + 2, w.end()))) {
81 std::vector<unsigned char> raw =
ParseHex(std::string(w.begin() + 2, w.end()));
82 result.
insert(result.
end(), raw.begin(), raw.end());
83 }
else if (w.size() >= 2 && w.front() ==
'\'' && w.back() ==
'\'') {
86 std::vector<unsigned char> value(w.begin() + 1, w.end() - 1);
90 result << ParseOpCode(w);
102 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
109 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
134 bool ok_extended =
false, ok_legacy =
false;
141 ssData >> tx_extended;
142 if (ssData.
empty()) ok_extended =
true;
143 }
catch (
const std::exception&) {
151 tx = std::move(tx_extended);
156 if (try_no_witness) {
160 if (ssData.
empty()) ok_legacy =
true;
161 }
catch (
const std::exception&) {
169 tx = std::move(tx_legacy);
175 tx = std::move(tx_extended);
181 tx = std::move(tx_legacy);
191 if (!
IsHex(hex_tx)) {
195 std::vector<unsigned char> txData(
ParseHex(hex_tx));
196 return DecodeTx(tx, txData, try_no_witness, try_witness);
201 if (!
IsHex(hex_header))
return false;
203 const std::vector<unsigned char> header_data{
ParseHex(hex_header)};
206 ser_header >> header;
207 }
catch (
const std::exception&) {
215 if (!
IsHex(strHexBlk))
218 std::vector<unsigned char> blockData(
ParseHex(strHexBlk));
223 catch (
const std::exception&) {
232 if ((strHex.size() != 64) || !
IsHex(strHex))
245 throw std::runtime_error(strName +
" must be hexadecimal string (not '" + strHex +
"')");
253 static std::map<std::string, int> map_sighash_values = {
262 std::string strHashType =
sighash.get_str();
263 const auto& it = map_sighash_values.find(strHashType);
264 if (it != map_sighash_values.end()) {
265 hash_type = it->second;
267 throw std::runtime_error(strHashType +
" is not a valid sighash parameter.");
Double ended buffer combining vector and stream-like interfaces.
Serialized script, used inside transaction inputs and outputs.
The basic transaction that is broadcasted on the network and contained in blocks.
const std::string & getValStr() const
void SetHex(const char *psz)
iterator insert(iterator pos, const T &value)
CScript ParseScript(const std::string &s)
static bool CheckTxScriptsSanity(const CMutableTransaction &tx)
bool DecodeHexTx(CMutableTransaction &tx, const std::string &hex_tx, bool try_no_witness, bool try_witness)
std::vector< unsigned char > ParseHexUV(const UniValue &v, const std::string &strName)
int ParseSighashString(const UniValue &sighash)
bool DecodeHexBlockHeader(CBlockHeader &header, const std::string &hex_header)
bool ParseHashStr(const std::string &strHex, uint256 &result)
Parse a hex string into 256 bits.
static bool DecodeTx(CMutableTransaction &tx, const std::vector< unsigned char > &tx_data, bool try_no_witness, bool try_witness)
bool DecodeHexBlk(CBlock &block, const std::string &strHexBlk)
@ SIGHASH_DEFAULT
Taproot only; implied when sighash byte is missing, and equivalent to SIGHASH_ALL.
static unsigned const char sighash[]
static const int SERIALIZE_TRANSACTION_NO_WITNESS
A flag that is ORed into the protocol version to designate that a transaction should be (un)serialize...
std::string GetOpName(opcodetype opcode)
static const unsigned int MAX_OPCODE
static const int MAX_SCRIPT_SIZE
opcodetype
Script opcodes.
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.
A mutable version of CTransaction.
std::vector< CTxOut > vout
static const int PROTOCOL_VERSION
network protocol versioning