54 std::map<std::string, opcodetype> mapOpNames;
59 for (
unsigned int op = 0; op <=
MAX_OPCODE; ++op) {
66 if (strName ==
"OP_UNKNOWN") {
69 mapOpNames[strName] =
static_cast<opcodetype>(op);
71 if (strName.starts_with(
"OP_")) {
72 mapOpNames[strName.substr(3)] =
static_cast<opcodetype>(op);
78 auto it = mapOpNames.find(
s);
79 if (it == mapOpNames.end())
throw std::runtime_error(
"script parse error: unknown opcode");
86 static const OpCodeParser ocp;
96 std::vector<std::string> words =
SplitString(
s,
" \t\n");
98 for (
const std::string& w : words) {
101 }
else if (std::all_of(w.begin(), w.end(),
::IsDigit) ||
102 (w.front() ==
'-' && w.size() > 1 && std::all_of(w.begin() + 1, w.end(),
::IsDigit)))
105 const auto num{ToIntegral<int64_t>(w)};
109 if (!num.has_value() || num > int64_t{0xffffffff} || num < -1 * int64_t{0xffffffff}) {
110 throw std::runtime_error(
"script parse error: decimal numeric value only allowed in the "
111 "range -0xFFFFFFFF...0xFFFFFFFF");
114 result << num.value();
115 }
else if (w.starts_with(
"0x") && w.size() > 2 &&
IsHex(std::string(w.begin() + 2, w.end()))) {
117 std::vector<unsigned char> raw =
ParseHex(std::string(w.begin() + 2, w.end()));
118 result.
insert(result.
end(), raw.begin(), raw.end());
119 }
else if (w.size() >= 2 && w.front() ==
'\'' && w.back() ==
'\'') {
122 std::vector<unsigned char> value(w.begin() + 1, w.end() - 1);
126 result << ParseOpCode(w);
138 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
145 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
170 bool ok_extended =
false, ok_legacy =
false;
178 if (ssData.empty()) ok_extended =
true;
179 }
catch (
const std::exception&) {
187 tx = std::move(tx_extended);
192 if (try_no_witness) {
196 if (ssData.empty()) ok_legacy =
true;
197 }
catch (
const std::exception&) {
205 tx = std::move(tx_legacy);
211 tx = std::move(tx_extended);
217 tx = std::move(tx_legacy);
227 if (!
IsHex(hex_tx)) {
231 std::vector<unsigned char> txData(
ParseHex(hex_tx));
232 return DecodeTx(tx, txData, try_no_witness, try_witness);
237 if (!
IsHex(hex_header))
return false;
239 const std::vector<unsigned char> header_data{
ParseHex(hex_header)};
242 }
catch (
const std::exception&) {
250 if (!
IsHex(strHexBlk))
253 std::vector<unsigned char> blockData(
ParseHex(strHexBlk));
257 catch (
const std::exception&) {
266 static const std::map<std::string, int> map_sighash_values = {
275 const auto& it = map_sighash_values.find(sighash);
276 if (it != map_sighash_values.end()) {
285 static_assert(
COIN > 1);
286 int64_t quotient = amount /
COIN;
287 int64_t remainder = amount %
COIN;
289 quotient = -quotient;
290 remainder = -remainder;
293 strprintf(
"%s%d.%08d", amount < 0 ?
"-" :
"", quotient, remainder));
301 while (it !=
script.end()) {
303 std::vector<unsigned char> vch;
304 if (
script.GetOp(it, op, vch)) {
313 if (str.substr(0, 3) == std::string(
"OP_")) {
314 ret += str.substr(3, std::string::npos) +
" ";
318 if (vch.size() > 0) {
320 HexStr(std::vector<uint8_t>(it - vch.size(), it)));
329 return ret.substr(0,
ret.empty() ?
ret.npos :
ret.size() - 1);
333 {
static_cast<unsigned char>(
SIGHASH_ALL), std::string(
"ALL")},
335 {
static_cast<unsigned char>(
SIGHASH_NONE), std::string(
"NONE")},
337 {
static_cast<unsigned char>(
SIGHASH_SINGLE), std::string(
"SINGLE")},
359 std::vector<unsigned char> vch;
361 while (pc <
script.end()) {
365 if (!
script.GetOp(pc, opcode, vch)) {
370 if (vch.size() <=
static_cast<std::vector<unsigned char>::size_type
>(4)) {
374 if (fAttemptSighashDecode && !
script.IsUnspendable()) {
375 std::string strSigHashDecode;
381 const unsigned char chSigHashType = vch.back();
384 strSigHashDecode =
"[" + it->second +
"]";
388 str +=
HexStr(vch) + strSigHashDecode;
412 if (include_address) {
419 std::vector<std::vector<unsigned char>> solns;
441 vin.reserve(tx.
vin.size());
445 const bool have_undo = txundo !=
nullptr;
449 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
460 in.
pushKV(
"scriptSig", std::move(o));
462 if (!tx.
vin[i].scriptWitness.IsNull()) {
464 txinwitness.
reserve(tx.
vin[i].scriptWitness.stack.size());
465 for (
const auto& item : tx.
vin[i].scriptWitness.stack) {
468 in.
pushKV(
"txinwitness", std::move(txinwitness));
472 const CTxOut& prev_txout = prev_coin.
out;
474 amt_total_in += prev_txout.
nValue;
484 p.
pushKV(
"scriptPubKey", std::move(o_script_pub_key));
485 in.
pushKV(
"prevout", std::move(p));
489 vin.push_back(std::move(in));
491 entry.
pushKV(
"vin", std::move(vin));
495 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
505 out.pushKV(
"scriptPubKey", std::move(o));
507 if (is_change_func && is_change_func(txout)) {
508 out.pushKV(
"ischange",
true);
514 amt_total_out += txout.
nValue;
517 entry.
pushKV(
"vout", std::move(vout));
520 const CAmount fee = amt_total_in - amt_total_out;
525 if (!block_hash.
IsNull()) {
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
bool MoneyRange(const CAmount &nValue)
int64_t CAmount
Amount in satoshis (Can be negative)
static constexpr CAmount COIN
The amount of satoshis in one BTC.
#define CHECK_NONFATAL(condition)
Identity function.
Serialized script, used inside transaction inputs and outputs.
The basic transaction that is broadcasted on the network and contained in blocks.
unsigned int ComputeTotalSize() const
Calculate the total transaction size in bytes, including witness data.
const std::vector< CTxOut > vout
const Wtxid & GetWitnessHash() const LIFETIMEBOUND
const Txid & GetHash() const LIFETIMEBOUND
const std::vector< CTxIn > vin
An input of a transaction.
An output of a transaction.
Undo information for a CTransaction.
std::vector< Coin > vprevout
CTxOut out
unspent transaction output
uint32_t nHeight
at which height this containing transaction was included in the active block chain
Double ended buffer combining vector and stream-like interfaces.
An interface to be implemented by keystores that support signing.
Minimal stream for reading from an existing byte array by std::span.
void push_back(UniValue val)
void reserve(size_t new_cap)
void pushKV(std::string key, UniValue val)
constexpr bool IsNull() const
std::string GetHex() const
iterator insert(iterator pos, const T &value)
std::string GetHex() const
static UniValue Parse(std::string_view raw, ParamFormat format=ParamFormat::JSON)
Parse string to UniValue or throw runtime_error if string contains invalid JSON.
static int32_t GetTransactionWeight(const CTransaction &tx)
static const int WITNESS_SCALE_FACTOR
std::string EncodeHexTx(const CTransaction &tx)
std::string SighashToStr(unsigned char sighash_type)
CScript ParseScript(const std::string &s)
std::string FormatScript(const CScript &script)
static bool CheckTxScriptsSanity(const CMutableTransaction &tx)
Check that all of the input and output scripts of a transaction contain valid opcodes.
bool DecodeHexTx(CMutableTransaction &tx, const std::string &hex_tx, bool try_no_witness, bool try_witness)
void ScriptToUniv(const CScript &script, UniValue &out, bool include_hex, bool include_address, const SigningProvider *provider)
bool DecodeHexBlockHeader(CBlockHeader &header, const std::string &hex_header)
util::Result< int > SighashFromStr(const std::string &sighash)
void TxToUniv(const CTransaction &tx, const uint256 &block_hash, UniValue &entry, bool include_hex, const CTxUndo *txundo, TxVerbosity verbosity, std::function< bool(const CTxOut &)> is_change_func)
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode)
Create the assembly string representation of a CScript object.
static bool DecodeTx(CMutableTransaction &tx, const std::vector< unsigned char > &tx_data, bool try_no_witness, bool try_witness)
const std::map< unsigned char, std::string > mapSigHashTypes
bool DecodeHexBlk(CBlock &block, const std::string &strHexBlk)
UniValue ValueFromAmount(const CAmount amount)
TxVerbosity
Verbose level for block's transaction.
@ SHOW_DETAILS_AND_PREVOUT
The same as previous option with information about prevouts if available.
@ SHOW_DETAILS
Include TXID, inputs, outputs, and other common block's transaction information.
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
bool CheckSignatureEncoding(const std::vector< unsigned char > &vchSig, script_verify_flags flags, ScriptError *serror)
@ SIGHASH_DEFAULT
Taproot only; implied when sighash byte is missing, and equivalent to SIGHASH_ALL.
@ SCRIPT_VERIFY_STRICTENC
std::string EncodeDestination(const CTxDestination &dest)
std::vector< std::string > SplitString(std::string_view str, char sep)
std::string ToString(const T &t)
Locale-independent version of std::to_string.
static constexpr TransactionSerParams TX_NO_WITNESS
static constexpr TransactionSerParams TX_WITH_WITNESS
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
std::string GetOpName(opcodetype opcode)
static const unsigned int MAX_OPCODE
static const int MAX_SCRIPT_SIZE
opcodetype
Script opcodes.
const SigningProvider & DUMMY_SIGNING_PROVIDER
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
std::string GetTxnOutputType(TxoutType t)
Get the name of a TxoutType as a string.
constexpr bool IsDigit(char c)
Tests if the given character is a decimal digit.
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
A mutable version of CTransaction.
std::vector< CTxOut > vout
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
bool IsHex(std::string_view str)