56 std::map<std::string, opcodetype> mapOpNames;
61 for (
unsigned int op = 0; op <=
MAX_OPCODE; ++op) {
68 if (strName ==
"OP_UNKNOWN") {
71 mapOpNames[strName] =
static_cast<opcodetype>(op);
73 if (strName.starts_with(
"OP_")) {
74 mapOpNames[strName.substr(3)] =
static_cast<opcodetype>(op);
80 auto it = mapOpNames.find(
s);
81 if (it == mapOpNames.end())
throw std::runtime_error(
"script parse error: unknown opcode");
88 static const OpCodeParser ocp;
98 std::vector<std::string> words =
SplitString(
s,
" \t\n");
100 for (
const std::string& w : words) {
103 }
else if (std::all_of(w.begin(), w.end(),
::IsDigit) ||
104 (w.front() ==
'-' && w.size() > 1 && std::all_of(w.begin() + 1, w.end(),
::IsDigit)))
107 const auto num{ToIntegral<int64_t>(w)};
111 if (!num.has_value() || num > int64_t{0xffffffff} || num < -1 * int64_t{0xffffffff}) {
112 throw std::runtime_error(
"script parse error: decimal numeric value only allowed in the "
113 "range -0xFFFFFFFF...0xFFFFFFFF");
116 result << num.value();
117 }
else if (w.starts_with(
"0x") && w.size() > 2 &&
IsHex(std::string(w.begin() + 2, w.end()))) {
119 std::vector<unsigned char> raw =
ParseHex(std::string(w.begin() + 2, w.end()));
120 result.
insert(result.
end(), raw.begin(), raw.end());
121 }
else if (w.size() >= 2 && w.front() ==
'\'' && w.back() ==
'\'') {
124 std::vector<unsigned char> value(w.begin() + 1, w.end() - 1);
128 result << ParseOpCode(w);
140 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
147 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
172 bool ok_extended =
false, ok_legacy =
false;
180 if (ssData.empty()) ok_extended =
true;
181 }
catch (
const std::exception&) {
189 tx = std::move(tx_extended);
194 if (try_no_witness) {
198 if (ssData.empty()) ok_legacy =
true;
199 }
catch (
const std::exception&) {
207 tx = std::move(tx_legacy);
213 tx = std::move(tx_extended);
219 tx = std::move(tx_legacy);
229 if (!
IsHex(hex_tx)) {
233 std::vector<unsigned char> txData(
ParseHex(hex_tx));
234 return DecodeTx(tx, txData, try_no_witness, try_witness);
239 if (!
IsHex(hex_header))
return false;
241 const std::vector<unsigned char> header_data{
ParseHex(hex_header)};
244 }
catch (
const std::exception&) {
252 if (!
IsHex(strHexBlk))
255 std::vector<unsigned char> blockData(
ParseHex(strHexBlk));
259 catch (
const std::exception&) {
268 static const std::map<std::string, int> map_sighash_values = {
277 const auto& it = map_sighash_values.find(sighash);
278 if (it != map_sighash_values.end()) {
287 static_assert(
COIN > 1);
288 int64_t quotient = amount /
COIN;
289 int64_t remainder = amount %
COIN;
291 quotient = -quotient;
292 remainder = -remainder;
295 strprintf(
"%s%d.%08d", amount < 0 ?
"-" :
"", quotient, remainder));
303 while (it !=
script.end()) {
305 std::vector<unsigned char> vch;
306 if (
script.GetOp(it, op, vch)) {
315 if (str.substr(0, 3) == std::string(
"OP_")) {
316 ret += str.substr(3, std::string::npos) +
" ";
320 if (vch.size() > 0) {
322 HexStr(std::vector<uint8_t>(it - vch.size(), it)));
331 return ret.substr(0,
ret.empty() ?
ret.npos :
ret.size() - 1);
335 {
static_cast<unsigned char>(
SIGHASH_ALL), std::string(
"ALL")},
337 {
static_cast<unsigned char>(
SIGHASH_NONE), std::string(
"NONE")},
339 {
static_cast<unsigned char>(
SIGHASH_SINGLE), std::string(
"SINGLE")},
361 std::vector<unsigned char> vch;
363 while (pc <
script.end()) {
367 if (!
script.GetOp(pc, opcode, vch)) {
372 if (vch.size() <=
static_cast<std::vector<unsigned char>::size_type
>(4)) {
376 if (fAttemptSighashDecode && !
script.IsUnspendable()) {
377 std::string strSigHashDecode;
383 const unsigned char chSigHashType = vch.back();
386 strSigHashDecode =
"[" + it->second +
"]";
390 str +=
HexStr(vch) + strSigHashDecode;
414 if (include_address) {
421 std::vector<std::vector<unsigned char>> solns;
443 vin.reserve(tx.
vin.size());
447 const bool have_undo = txundo !=
nullptr;
451 for (
unsigned int i = 0; i < tx.
vin.size(); i++) {
462 in.
pushKV(
"scriptSig", std::move(o));
464 if (!tx.
vin[i].scriptWitness.IsNull()) {
466 txinwitness.
reserve(tx.
vin[i].scriptWitness.stack.size());
467 for (
const auto& item : tx.
vin[i].scriptWitness.stack) {
470 in.
pushKV(
"txinwitness", std::move(txinwitness));
474 const CTxOut& prev_txout = prev_coin.
out;
476 amt_total_in += prev_txout.
nValue;
486 p.
pushKV(
"scriptPubKey", std::move(o_script_pub_key));
487 in.
pushKV(
"prevout", std::move(p));
491 vin.push_back(std::move(in));
493 entry.
pushKV(
"vin", std::move(vin));
497 for (
unsigned int i = 0; i < tx.
vout.size(); i++) {
507 out.pushKV(
"scriptPubKey", std::move(o));
509 if (is_change_func && is_change_func(txout)) {
510 out.pushKV(
"ischange",
true);
516 amt_total_out += txout.
nValue;
519 entry.
pushKV(
"vout", std::move(vout));
522 const CAmount fee = amt_total_in - amt_total_out;
527 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)