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.
1501case SigVersion::TAPSCRIPT:1502ext_flag = 1;1503// key_version must be 0 for now, representing the current version of1504// 32-byte public keys in the tapscript signature opcode execution.1505// An upgradable public key version (with a size not 32-byte) may1506// request a different key_version with a new sigversion.1507key_version = 0;1508break;1509default:1510assert(false);1511}1512assert(in_pos < tx_to.vin.size());1513if (!(cache.m_bip341_taproot_ready && cache.m_spent_outputs_ready)) {1514return HandleMissingData(mdb);1515}1517HashWriter ss{HASHER_TAPSIGHASH};1519// Epoch1520static constexpr uint8_t EPOCH = 0;1521ss << EPOCH;1523// Hash type1524const uint8_t output_type = (hash_type == SIGHASH_DEFAULT) ? SIGHASH_ALL : (hash_type & SIGHASH_OUTPUT_MASK); // Default (no sighash byte) is equivalent to SIGHASH_ALL1525const uint8_t input_type = hash_type & SIGHASH_INPUT_MASK;1526if (!(hash_type <= 0x03 || (hash_type >= 0x81 && hash_type <= 0x83))) return false;1527ss << hash_type;1529// Transaction level data1530ss << tx_to.version;1531ss << tx_to.nLockTime;1532if (input_type != SIGHASH_ANYONECANPAY) {1533ss << cache.m_prevouts_single_hash;1534ss << cache.m_spent_amounts_single_hash;1535ss << cache.m_spent_scripts_single_hash;1536ss << cache.m_sequences_single_hash;1537}1538if (output_type == SIGHASH_ALL) {1539ss << cache.m_outputs_single_hash;1540}1542// Data about the input/prevout being spent1543assert(execdata.m_annex_init);1544const bool have_annex = execdata.m_annex_present;1545const uint8_t spend_type = (ext_flag << 1) + (have_annex ? 1 : 0); // The low bit indicates whether an annex is present.1546ss << spend_type;1547if (input_type == SIGHASH_ANYONECANPAY) {1548ss << tx_to.vin[in_pos].prevout;1549ss << cache.m_spent_outputs[in_pos];1550ss << tx_to.vin[in_pos].nSequence;1551} else {1552ss << in_pos;1553}1554if (have_annex) {1555ss << execdata.m_annex_hash;1556}1558// Data about the output (if only one).1559if (output_type == SIGHASH_SINGLE) {1560if (in_pos >= tx_to.vout.size()) return false;1561if (!execdata.m_output_hash) {1562HashWriter sha_single_output{};1563sha_single_output << tx_to.vout[in_pos];1564execdata.m_output_hash = sha_single_output.GetSHA256();1565}1566ss << execdata.m_output_hash.value();1567}1569// Additional data for BIP 342 signatures1570if (sigversion == SigVersion::TAPSCRIPT) {1571assert(execdata.m_tapleaf_hash_init);1572ss << execdata.m_tapleaf_hash;1573ss << key_version;1574assert(execdata.m_codeseparator_pos_init);1575ss << execdata.m_codeseparator_pos;1576}1578hash_out = ss.GetSHA256();1579return true;1580}1582int SigHashCache::CacheIndex(int32_t hash_type) const noexcept1583{1584// Note that we do not distinguish between BASE and WITNESS_V0 to determine the cache index,1585// because no input can simultaneously use both.1586return 3 * !!(hash_type & SIGHASH_ANYONECANPAY) +15872 * ((hash_type & 0x1f) == SIGHASH_SINGLE) +15881 * ((hash_type & 0x1f) == SIGHASH_NONE);1589}1591bool SigHashCache::Load(int32_t hash_type, const CScript& script_code, HashWriter& writer) const noexcept1592{1593auto& entry = m_cache_entries[CacheIndex(hash_type)];1594if (entry.has_value()) {1595if (script_code == entry->first) {1596writer = HashWriter(entry->second);1597return true;1598}1599}1600return false;1601}1603void SigHashCache::Store(int32_t hash_type, const CScript& script_code, const HashWriter& writer) noexcept1604{1605auto& entry = m_cache_entries[CacheIndex(hash_type)];1606entry.emplace(script_code, writer);1607}1609template <class T>1610uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn, int32_t nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache, SigHashCache* sighash_cache)1611{1612assert(nIn < txTo.vin.size());1614if (sigversion != SigVersion::WITNESS_V0) {1615// Check for invalid use of SIGHASH_SINGLE1616if ((nHashType & 0x1f) == SIGHASH_SINGLE) {1617if (nIn >= txTo.vout.size()) {1618// nOut out of range1619return uint256::ONE;1620}1621}1622}1624HashWriter ss{};1626// Try to compute using cached SHA256 midstate.1627if (sighash_cache && sighash_cache->Load(nHashType, scriptCode, ss)) {1628// Add sighash type and hash.1629ss << nHashType;1630return ss.GetHash();1631}1633if (sigversion == SigVersion::WITNESS_V0) {1634uint256 hashPrevouts;1635uint256 hashSequence;1636uint256 hashOutputs;1637const bool cacheready = cache && cache->m_bip143_segwit_ready;1639if (!(nHashType & SIGHASH_ANYONECANPAY)) {1640hashPrevouts = cacheready ? cache->hashPrevouts : SHA256Uint256(GetPrevoutsSHA256(txTo));1641}1643if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) {1644hashSequence = cacheready ? cache->hashSequence : SHA256Uint256(GetSequencesSHA256(txTo));1645}1647if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) {1648hashOutputs = cacheready ? cache->hashOutputs : SHA256Uint256(GetOutputsSHA256(txTo));1649} else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) {1650HashWriter inner_ss{};1651inner_ss << txTo.vout[nIn];1652hashOutputs = inner_ss.GetHash();1653}1655// Version1656ss << txTo.version;1657// Input prevouts/nSequence (none/all, depending on flags)1658ss << hashPrevouts;1659ss << hashSequence;1660// The input being signed (replacing the scriptSig with scriptCode + amount)1661// The prevout may already be contained in hashPrevout, and the nSequence1662// may already be contain in hashSequence.1663ss << txTo.vin[nIn].prevout;1664ss << scriptCode;1665ss << amount;1666ss << txTo.vin[nIn].nSequence;1667// Outputs (none/one/all, depending on flags)1668ss << hashOutputs;1669// Locktime1670ss << txTo.nLockTime;1671} else {1672// Wrapper to serialize only the necessary parts of the transaction being signed1673CTransactionSignatureSerializer<T> txTmp(txTo, scriptCode, nIn, nHashType);1675// Serialize1676ss << txTmp;1677}1679// If a cache object was provided, store the midstate there.1680if (sighash_cache != nullptr) {1681sighash_cache->Store(nHashType, scriptCode, ss);1682}1684// Add sighash type and hash.1685ss << nHashType;1686return ss.GetHash();1687}1689template <class T>1690bool GenericTransactionSignatureChecker<T>::VerifyECDSASignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const1691{1692return pubkey.Verify(sighash, vchSig);1693}1695template <class T>1696bool GenericTransactionSignatureChecker<T>::VerifySchnorrSignature(std::span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const1697{1698return pubkey.VerifySchnorr(sighash, sig);1699}1701template <class T>1702bool GenericTransactionSignatureChecker<T>::CheckECDSASignature(const std::vector<unsigned char>& vchSigIn, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const1703{1704CPubKey pubkey(vchPubKey);1705if (!pubkey.IsValid())1706return false;1708// Hash type is one byte tacked on to the end of the signature1709std::vector<unsigned char> vchSig(vchSigIn);1710if (vchSig.empty())1711return false;1712int nHashType = vchSig.back();1713vchSig.pop_back();1715// Witness sighashes need the amount.1716if (sigversion == SigVersion::WITNESS_V0 && amount < 0) return HandleMissingData(m_mdb);1718uint256 sighash = SignatureHash(scriptCode, *txTo, nIn, nHashType, amount, sigversion, this->txdata, &m_sighash_cache);1720if (!VerifyECDSASignature(vchSig, pubkey, sighash))1721return false;1723return true;1724}1726template <class T>1727bool GenericTransactionSignatureChecker<T>::CheckSchnorrSignature(std::span<const unsigned char> sig, std::span<const unsigned char> pubkey_in, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror) const1728{1729assert(sigversion == SigVersion::TAPROOT || sigversion == SigVersion::TAPSCRIPT);1730// Schnorr signatures have 32-byte public keys. The caller is responsible for enforcing this.1731assert(pubkey_in.size() == 32);1732// Note that in Tapscript evaluation, empty signatures are treated specially (invalid signature that does not1733// abort script execution). This is implemented in EvalChecksigTapscript, which won't invoke1734// CheckSchnorrSignature in that case. In other contexts, they are invalid like every other signature with1735// size different from 64 or 65.1736if (sig.size() != 64 && sig.size() != 65) return set_error(serror, SCRIPT_ERR_SCHNORR_SIG_SIZE);1738XOnlyPubKey pubkey{pubkey_in};1740uint8_t hashtype = SIGHASH_DEFAULT;1741if (sig.size() == 65) {1742hashtype = SpanPopBack(sig);1743if (hashtype == SIGHASH_DEFAULT) return set_error(serror, SCRIPT_ERR_SCHNORR_SIG_HASHTYPE);1744}1745uint256 sighash;1746if (!this->txdata) return HandleMissingData(m_mdb);1747if (!SignatureHashSchnorr(sighash, execdata, *txTo, nIn, hashtype, sigversion, *this->txdata, m_mdb)) {1748return set_error(serror, SCRIPT_ERR_SCHNORR_SIG_HASHTYPE);1749}1750if (!VerifySchnorrSignature(sig, pubkey, sighash)) return set_error(serror, SCRIPT_ERR_SCHNORR_SIG);