Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251return false;253std::vector<unsigned char> blockData(ParseHex(strHexBlk));254try {255SpanReader{blockData} >> TX_WITH_WITNESS(block);256}257catch (const std::exception&) {258return false;259}261return true;262}264util::Result<int> SighashFromStr(const std::string& sighash)265{266static const std::map<std::string, int> map_sighash_values = {267{std::string("DEFAULT"), int(SIGHASH_DEFAULT)},268{std::string("ALL"), int(SIGHASH_ALL)},269{std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)},270{std::string("NONE"), int(SIGHASH_NONE)},271{std::string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)},272{std::string("SINGLE"), int(SIGHASH_SINGLE)},273{std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)},274};275const auto& it = map_sighash_values.find(sighash);276if (it != map_sighash_values.end()) {277return it->second;278} else {279return util::Error{Untranslated("'" + sighash + "' is not a valid sighash parameter.")};280}281}283UniValue ValueFromAmount(const CAmount amount)284{285static_assert(COIN > 1);286int64_t quotient = amount / COIN;287int64_t remainder = amount % COIN;288if (amount < 0) {289quotient = -quotient;290remainder = -remainder;291}292return UniValue(UniValue::VNUM,293strprintf("%s%d.%08d", amount < 0 ? "-" : "", quotient, remainder));294}296std::string FormatScript(const CScript& script)297{298std::string ret;299CScript::const_iterator it = script.begin();300opcodetype op;301while (it != script.end()) {302CScript::const_iterator it2 = it;303std::vector<unsigned char> vch;304if (script.GetOp(it, op, vch)) {305if (op == OP_0) {306ret += "0 ";307continue;308} else if ((op >= OP_1 && op <= OP_16) || op == OP_1NEGATE) {309ret += strprintf("%i ", op - OP_1NEGATE - 1);310continue;311} else if (op >= OP_NOP && op <= OP_NOP10) {312std::string str(GetOpName(op));313if (str.substr(0, 3) == std::string("OP_")) {314ret += str.substr(3, std::string::npos) + " ";315continue;316}317}318if (vch.size() > 0) {319ret += strprintf("0x%x 0x%x ", HexStr(std::vector<uint8_t>(it2, it - vch.size())),320HexStr(std::vector<uint8_t>(it - vch.size(), it)));321} else {322ret += strprintf("0x%x ", HexStr(std::vector<uint8_t>(it2, it)));323}324continue;325}326ret += strprintf("0x%x ", HexStr(std::vector<uint8_t>(it2, script.end())));327break;328}329return ret.substr(0, ret.empty() ? ret.npos : ret.size() - 1);330}332const std::map<unsigned char, std::string> mapSigHashTypes = {333{static_cast<unsigned char>(SIGHASH_ALL), std::string("ALL")},334{static_cast<unsigned char>(SIGHASH_ALL|SIGHASH_ANYONECANPAY), std::string("ALL|ANYONECANPAY")},335{static_cast<unsigned char>(SIGHASH_NONE), std::string("NONE")},336{static_cast<unsigned char>(SIGHASH_NONE|SIGHASH_ANYONECANPAY), std::string("NONE|ANYONECANPAY")},337{static_cast<unsigned char>(SIGHASH_SINGLE), std::string("SINGLE")},338{static_cast<unsigned char>(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY), std::string("SINGLE|ANYONECANPAY")},339};341std::string SighashToStr(int32_t sighash_type)342{343// Signatures encode the sighash type in a single byte, but the PSBT field344// for it is a 32 bit unsigned integer in BIP 174 (signed in PSBTInput)345if (sighash_type < 0 || sighash_type > 0xff) return "";346const uint8_t sighash_byte(sighash_type);347const auto& it = mapSigHashTypes.find(sighash_byte);348if (it == mapSigHashTypes.end()) return "";349return it->second;350}352/**353* Create the assembly string representation of a CScript object.354* @param[in] script CScript object to convert into the asm string representation.355* @param[in] fAttemptSighashDecode Whether to attempt to decode sighash types on data within the script that matches the format356* of a signature. Only pass true for scripts you believe could contain signatures. For example,357* pass false, or omit the this argument (defaults to false), for scriptPubKeys.358*/359std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDecode)360{361std::string str;362opcodetype opcode;363std::vector<unsigned char> vch;364CScript::const_iterator pc = script.begin();365while (pc < script.end()) {366if (!str.empty()) {367str += " ";368}369if (!script.GetOp(pc, opcode, vch)) {370str += "[error]";371return str;372}373if (0 <= opcode && opcode <= OP_PUSHDATA4) {374if (vch.size() <= static_cast<std::vector<unsigned char>::size_type>(4)) {375str += strprintf("%d", CScriptNum(vch, false).getint());376} else {377// the IsUnspendable check makes sure not to try to decode OP_RETURN data that may match the format of a signature378if (fAttemptSighashDecode && !script.IsUnspendable()) {379std::string strSigHashDecode;380// goal: only attempt to decode a defined sighash type from data that looks like a signature within a scriptSig.381// this won't decode correctly formatted public keys in Pubkey or Multisig scripts due to382// the restrictions on the pubkey formats (see IsCompressedOrUncompressedPubKey) being incongruous with the383// checks in CheckSignatureEncoding.384if (CheckSignatureEncoding(vch, SCRIPT_VERIFY_STRICTENC, nullptr)) {385const unsigned char chSigHashType = vch.back();386const auto it = mapSigHashTypes.find(chSigHashType);387if (it != mapSigHashTypes.end()) {388strSigHashDecode = "[" + it->second + "]";389vch.pop_back(); // remove the sighash type byte. it will be replaced by the decode.390}391}392str += HexStr(vch) + strSigHashDecode;393} else {394str += HexStr(vch);395}396}397} else {398str += GetOpName(opcode);399}400}401return str;402}404std::string EncodeHexTx(const CTransaction& tx)405{406DataStream ssTx;407ssTx << TX_WITH_WITNESS(tx);408return HexStr(ssTx);409}411void ScriptToUniv(const CScript& script, UniValue& out, bool include_hex, bool include_address, const SigningProvider* provider)412{413CTxDestination address;415out.pushKV("asm", ScriptToAsmStr(script));416if (include_address) {417out.pushKV("desc", InferDescriptor(script, provider ? *provider : DUMMY_SIGNING_PROVIDER)->ToString());418}419if (include_hex) {420out.pushKV("hex", HexStr(script));421}423std::vector<std::vector<unsigned char>> solns;424const TxoutType type{Solver(script, solns)};426if (include_address && ExtractDestination(script, address) && type != TxoutType::PUBKEY) {427out.pushKV("address", EncodeDestination(address));428}429out.pushKV("type", GetTxnOutputType(type));430}432void 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)433{434CHECK_NONFATAL(verbosity >= TxVerbosity::SHOW_DETAILS);436entry.pushKV("txid", tx.GetHash().GetHex());437entry.pushKV("hash", tx.GetWitnessHash().GetHex());438entry.pushKV("version", tx.version);439entry.pushKV("size", tx.ComputeTotalSize());440entry.pushKV("vsize", (GetTransactionWeight(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR);441entry.pushKV("weight", GetTransactionWeight(tx));442entry.pushKV("locktime", tx.nLockTime);444UniValue vin{UniValue::VARR};445vin.reserve(tx.vin.size());447// If available, use Undo data to calculate the fee. Note that txundo == nullptr448// for coinbase transactions and for transactions where undo data is unavailable.449const bool have_undo = txundo != nullptr;450CAmount amt_total_in = 0;451CAmount amt_total_out = 0;453for (unsigned int i = 0; i < tx.vin.size(); i++) {454const CTxIn& txin = tx.vin[i];455UniValue in(UniValue::VOBJ);456if (tx.IsCoinBase()) {457in.pushKV("coinbase", HexStr(txin.scriptSig));458} else {459in.pushKV("txid", txin.prevout.hash.GetHex());460in.pushKV("vout", txin.prevout.n);461UniValue o(UniValue::VOBJ);462o.pushKV("asm", ScriptToAsmStr(txin.scriptSig, true));463o.pushKV("hex", HexStr(txin.scriptSig));464in.pushKV("scriptSig", std::move(o));465}466if (!tx.vin[i].scriptWitness.IsNull()) {467UniValue txinwitness(UniValue::VARR);468txinwitness.reserve(tx.vin[i].scriptWitness.stack.size());469for (const auto& item : tx.vin[i].scriptWitness.stack) {470txinwitness.push_back(HexStr(item));471}472in.pushKV("txinwitness", std::move(txinwitness));473}474if (have_undo) {475const Coin& prev_coin = txundo->vprevout[i];476const CTxOut& prev_txout = prev_coin.out;478amt_total_in += prev_txout.nValue;480if (verbosity == TxVerbosity::SHOW_DETAILS_AND_PREVOUT) {481UniValue o_script_pub_key(UniValue::VOBJ);482ScriptToUniv(prev_txout.scriptPubKey, /*out=*/o_script_pub_key, /*include_hex=*/true, /*include_address=*/true);484UniValue p(UniValue::VOBJ);485p.pushKV("generated", prev_coin.IsCoinBase());486p.pushKV("height", prev_coin.nHeight);487p.pushKV("value", ValueFromAmount(prev_txout.nValue));488p.pushKV("scriptPubKey", std::move(o_script_pub_key));489in.pushKV("prevout", std::move(p));490}491}492in.pushKV("sequence", txin.nSequence);493vin.push_back(std::move(in));494}495entry.pushKV("vin", std::move(vin));497UniValue vout(UniValue::VARR);498vout.reserve(tx.vout.size());499for (unsigned int i = 0; i < tx.vout.size(); i++) {500const CTxOut& txout = tx.vout[i];
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.