53 std::map<std::string, opcodetype> mapOpNames;
58 for (
unsigned int op = 0; op <=
MAX_OPCODE; ++op) {
65 if (strName ==
"OP_UNKNOWN") {
68 mapOpNames[strName] =
static_cast<opcodetype>(op);
70 if (strName.starts_with(
"OP_")) {
71 mapOpNames[strName.substr(3)] =
static_cast<opcodetype>(op);
77 auto it = mapOpNames.find(
s);
78 if (it == mapOpNames.end())
throw std::runtime_error(
"script parse error: unknown opcode");
85 static const OpCodeParser ocp;
95 std::vector<std::string> words =
SplitString(
s,
" \t\n");
97 for (
const std::string& w : words) {
100 }
else if (std::all_of(w.begin(), w.end(),
::IsDigit) ||
101 (w.front() ==
'-' && w.size() > 1 && std::all_of(w.begin() + 1, w.end(),
::IsDigit)))
104 const auto num{ToIntegral<int64_t>(w)};
108 if (!num.has_value() || num > int64_t{0xffffffff} || num < -1 * int64_t{0xffffffff}) {
109 throw std::runtime_error(
"script parse error: decimal numeric value only allowed in the "
110 "range -0xFFFFFFFF...0xFFFFFFFF");
113 result << num.value();
114 }
else if (w.starts_with(
"0x") && w.size() > 2 &&
IsHex(std::string(w.begin() + 2, w.end()))) {
116 std::vector<unsigned char> raw =
ParseHex(std::string(w.begin() + 2, w.end()));
117 result.
insert(result.
end(), raw.begin(), raw.end());
118 }
else if (w.size() >= 2 && w.front() ==
'\'' && w.back() ==
'\'') {
121 std::vector<unsigned char> value(w.begin() + 1, w.end() - 1);
125 result << ParseOpCode(w);
137 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
144 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
169 bool ok_extended =
false, ok_legacy =
false;
177 if (ssData.empty()) ok_extended =
true;
178 }
catch (
const std::exception&) {
186 tx = std::move(tx_extended);
191 if (try_no_witness) {
195 if (ssData.empty()) ok_legacy =
true;
196 }
catch (
const std::exception&) {
204 tx = std::move(tx_legacy);
210 tx = std::move(tx_extended);
216 tx = std::move(tx_legacy);
226 if (!
IsHex(hex_tx)) {
230 std::vector<unsigned char> txData(
ParseHex(hex_tx));
231 return DecodeTx(tx, txData, try_no_witness, try_witness);
236 if (!
IsHex(hex_header))
return false;
238 const std::vector<unsigned char> header_data{
ParseHex(hex_header)};
241 }
catch (
const std::exception&) {
249 if (!
IsHex(strHexBlk))
252 std::vector<unsigned char> blockData(
ParseHex(strHexBlk));
256 catch (
const std::exception&) {
265 static const std::map<std::string, int> map_sighash_values = {
274 const auto& it = map_sighash_values.find(sighash);
275 if (it != map_sighash_values.end()) {
284 static_assert(
COIN > 1);
285 int64_t quotient = amount /
COIN;
286 int64_t remainder = amount %
COIN;
288 quotient = -quotient;
289 remainder = -remainder;
292 strprintf(
"%s%d.%08d", amount < 0 ?
"-" :
"", quotient, remainder));
300 while (it !=
script.end()) {
302 std::vector<unsigned char> vch;
303 if (
script.GetOp(it, op, vch)) {
312 if (str.substr(0, 3) == std::string(
"OP_")) {
313 ret += str.substr(3, std::string::npos) +
" ";
317 if (vch.size() > 0) {
319 HexStr(std::vector<uint8_t>(it - vch.size(), it)));
328 return ret.substr(0,
ret.empty() ?
ret.npos :
ret.size() - 1);
332 {
static_cast<unsigned char>(
SIGHASH_ALL), std::string(
"ALL")},
334 {
static_cast<unsigned char>(
SIGHASH_NONE), std::string(
"NONE")},
336 {
static_cast<unsigned char>(
SIGHASH_SINGLE), std::string(
"SINGLE")},
358 std::vector<unsigned char> vch;
360 while (pc <
script.end()) {
364 if (!
script.GetOp(pc, opcode, vch)) {
369 if (vch.size() <=
static_cast<std::vector<unsigned char>::size_type
>(4)) {
373 if (fAttemptSighashDecode && !
script.IsUnspendable()) {
374 std::string strSigHashDecode;
380 const unsigned char chSigHashType = vch.back();
383 strSigHashDecode =
"[" + it->second +
"]";
387 str +=
HexStr(vch) + strSigHashDecode;
411 if (include_address) {
418 std::vector<std::vector<unsigned char>> solns;
440 vin.reserve(tx.
vin.size());
444 const bool have_undo = txundo !=
nullptr;
448 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
459 in.
pushKV(
"scriptSig", std::move(o));
461 if (!tx.
vin[i].scriptWitness.IsNull()) {
463 txinwitness.
reserve(tx.
vin[i].scriptWitness.stack.size());
464 for (
const auto& item : tx.
vin[i].scriptWitness.stack) {
467 in.
pushKV(
"txinwitness", std::move(txinwitness));
471 const CTxOut& prev_txout = prev_coin.
out;
473 amt_total_in += prev_txout.
nValue;
483 p.
pushKV(
"scriptPubKey", std::move(o_script_pub_key));
484 in.
pushKV(
"prevout", std::move(p));
488 vin.push_back(std::move(in));
490 entry.
pushKV(
"vin", std::move(vin));
494 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
504 out.pushKV(
"scriptPubKey", std::move(o));
506 if (is_change_func && is_change_func(txout)) {
507 out.pushKV(
"ischange",
true);
513 amt_total_out += txout.
nValue;
516 entry.
pushKV(
"vout", std::move(vout));
519 const CAmount fee = amt_total_in - amt_total_out;
524 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
unsigned int fCoinBase
whether containing transaction was a coinbase
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)