Inside Bitcoin
Opening the selected file…
Inside Bitcoin
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.
1// Copyright (c) 2023-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or https://www.opensource.org/licenses/mit-license.php.5#include <addresstype.h>7#include <crypto/sha256.h>8#include <hash.h>9#include <pubkey.h>10#include <script/script.h>11#include <script/solver.h>12#include <uint256.h>13#include <util/hash_type.h>15#include <cassert>16#include <vector>18typedef std::vector<unsigned char> valtype;20ScriptHash::ScriptHash(const CScript& in) : BaseHash(Hash160(in)) {}21ScriptHash::ScriptHash(const CScriptID& in) : BaseHash{in} {}23PKHash::PKHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}24PKHash::PKHash(const CKeyID& pubkey_id) : BaseHash(pubkey_id) {}26WitnessV0KeyHash::WitnessV0KeyHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}27WitnessV0KeyHash::WitnessV0KeyHash(const PKHash& pubkey_hash) : BaseHash{pubkey_hash} {}29CKeyID ToKeyID(const PKHash& key_hash)30{31return CKeyID{uint160{key_hash}};32}34CKeyID ToKeyID(const WitnessV0KeyHash& key_hash)35{36return CKeyID{uint160{key_hash}};37}39CScriptID ToScriptID(const ScriptHash& script_hash)40{41return CScriptID{uint160{script_hash}};42}44WitnessV0ScriptHash::WitnessV0ScriptHash(const CScript& in)45{46CSHA256().Write(in.data(), in.size()).Finalize(begin());47}49bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)50{51std::vector<valtype> vSolutions;52TxoutType whichType = Solver(scriptPubKey, vSolutions);54switch (whichType) {55case TxoutType::PUBKEY: {56CPubKey pubKey(vSolutions[0]);57if (!pubKey.IsValid()) {58addressRet = CNoDestination(scriptPubKey);59} else {60addressRet = PubKeyDestination(pubKey);61}62return false;63}64case TxoutType::PUBKEYHASH: {65addressRet = PKHash(uint160(vSolutions[0]));66return true;67}68case TxoutType::SCRIPTHASH: {69addressRet = ScriptHash(uint160(vSolutions[0]));70return true;71}72case TxoutType::WITNESS_V0_KEYHASH: {73WitnessV0KeyHash hash;74std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());75addressRet = hash;76return true;77}78case TxoutType::WITNESS_V0_SCRIPTHASH: {79WitnessV0ScriptHash hash;80std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());81addressRet = hash;82return true;83}84case TxoutType::WITNESS_V1_TAPROOT: {85WitnessV1Taproot tap;86std::copy(vSolutions[0].begin(), vSolutions[0].end(), tap.begin());87addressRet = tap;88return true;89}90case TxoutType::ANCHOR: {91addressRet = PayToAnchor();92return true;93}94case TxoutType::WITNESS_UNKNOWN: {95addressRet = WitnessUnknown{vSolutions[0][0], vSolutions[1]};96return true;97}98case TxoutType::MULTISIG:99case TxoutType::NULL_DATA:100case TxoutType::NONSTANDARD:101addressRet = CNoDestination(scriptPubKey);102return false;103} // no default case, so the compiler can warn about missing cases104assert(false);105}107namespace {108class CScriptVisitor109{110public:111CScript operator()(const CNoDestination& dest) const112{113return dest.GetScript();114}116CScript operator()(const PubKeyDestination& dest) const117{118return CScript() << ToByteVector(dest.GetPubKey()) << OP_CHECKSIG;119}121CScript operator()(const PKHash& keyID) const122{123return CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;124}126CScript operator()(const ScriptHash& scriptID) const127{128return CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;129}131CScript operator()(const WitnessV0KeyHash& id) const132{133return CScript() << OP_0 << ToByteVector(id);134}136CScript operator()(const WitnessV0ScriptHash& id) const137{138return CScript() << OP_0 << ToByteVector(id);139}141CScript operator()(const WitnessV1Taproot& tap) const142{143return CScript() << OP_1 << ToByteVector(tap);144}146CScript operator()(const WitnessUnknown& id) const147{148return CScript() << CScript::EncodeOP_N(id.GetWitnessVersion()) << id.GetWitnessProgram();149}150};152class ValidDestinationVisitor153{154public:155bool operator()(const CNoDestination& dest) const { return false; }156bool operator()(const PubKeyDestination& dest) const { return false; }157bool operator()(const PKHash& dest) const { return true; }158bool operator()(const ScriptHash& dest) const { return true; }159bool operator()(const WitnessV0KeyHash& dest) const { return true; }160bool operator()(const WitnessV0ScriptHash& dest) const { return true; }161bool operator()(const WitnessV1Taproot& dest) const { return true; }162bool operator()(const WitnessUnknown& dest) const { return true; }163};164} // namespace166CScript GetScriptForDestination(const CTxDestination& dest)167{168return std::visit(CScriptVisitor(), dest);169}171bool IsValidDestination(const CTxDestination& dest) {172return std::visit(ValidDestinationVisitor(), dest);173}
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.