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.
251return state;252}253CScript subscript(stack.back().begin(), stack.back().end());254unsigned int sigop_count = subscript.GetSigOpCount(true);255if (sigop_count > MAX_P2SH_SIGOPS) {256state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs", strprintf("p2sh redeemscript sigops exceed limit (input %u: %u > %u)", i, sigop_count, MAX_P2SH_SIGOPS));257return state;258}259}260}262return state;263}265bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)266{267if (tx.IsCoinBase())268return true; // Coinbases are skipped270for (unsigned int i = 0; i < tx.vin.size(); i++)271{272// We don't care if witness for this input is empty, since it must not be bloated.273// If the script is invalid without witness, it would be caught sooner or later during validation.274if (tx.vin[i].scriptWitness.IsNull())275continue;277const CTxOut &prev = mapInputs.AccessCoin(tx.vin[i].prevout).out;279// get the scriptPubKey corresponding to this input:280CScript prevScript = prev.scriptPubKey;282// witness stuffing detected283if (prevScript.IsPayToAnchor()) {284return false;285}287bool p2sh = false;288if (prevScript.IsPayToScriptHash()) {289std::vector <std::vector<unsigned char> > stack;290// If the scriptPubKey is P2SH, we try to extract the redeemScript casually by converting the scriptSig291// into a stack. We do not check IsPushOnly nor compare the hash as these will be done later anyway.292// If the check fails at this stage, we know that this txid must be a bad one.293if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE))294return false;295if (stack.empty())296return false;297prevScript = CScript(stack.back().begin(), stack.back().end());298p2sh = true;299}301int witnessversion = 0;302std::vector<unsigned char> witnessprogram;304// Non-witness program must not be associated with any witness305if (!prevScript.IsWitnessProgram(witnessversion, witnessprogram))306return false;308// Check P2WSH standard limits309if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE) {310if (tx.vin[i].scriptWitness.stack.back().size() > MAX_STANDARD_P2WSH_SCRIPT_SIZE)311return false;312size_t sizeWitnessStack = tx.vin[i].scriptWitness.stack.size() - 1;313if (sizeWitnessStack > MAX_STANDARD_P2WSH_STACK_ITEMS)314return false;315for (unsigned int j = 0; j < sizeWitnessStack; j++) {316if (tx.vin[i].scriptWitness.stack[j].size() > MAX_STANDARD_P2WSH_STACK_ITEM_SIZE)317return false;318}319}321// Check policy limits for Taproot spends:322// - MAX_STANDARD_TAPSCRIPT_STACK_ITEM_SIZE limit for stack item size323// - No annexes324if (witnessversion == 1 && witnessprogram.size() == WITNESS_V1_TAPROOT_SIZE && !p2sh) {325// Taproot spend (non-P2SH-wrapped, version 1, witness program size 32; see BIP 341)326std::span stack{tx.vin[i].scriptWitness.stack};327if (stack.size() >= 2 && !stack.back().empty() && stack.back()[0] == ANNEX_TAG) {328// Annexes are nonstandard as long as no semantics are defined for them.329return false;330}331if (stack.size() >= 2) {332// Script path spend (2 or more stack elements after removing optional annex)333const auto& control_block = SpanPopBack(stack);334SpanPopBack(stack); // Ignore script335if (control_block.empty()) return false; // Empty control block is invalid336if ((control_block[0] & TAPROOT_LEAF_MASK) == TAPROOT_LEAF_TAPSCRIPT) {337// Leaf version 0xc0 (aka Tapscript, see BIP 342)338for (const auto& item : stack) {339if (item.size() > MAX_STANDARD_TAPSCRIPT_STACK_ITEM_SIZE) return false;340}341}342} else if (stack.size() == 1) {343// Key path spend (1 stack element after removing optional annex)344// (no policy rules apply)345} else {346// 0 stack elements; this is already invalid by consensus rules347return false;348}349}350}351return true;352}354bool SpendsNonAnchorWitnessProg(const CTransaction& tx, const CCoinsViewCache& prevouts)355{356if (tx.IsCoinBase()) {357return false;358}360int version;361std::vector<uint8_t> program;362for (const auto& txin: tx.vin) {363const auto& prev_spk{prevouts.AccessCoin(txin.prevout).out.scriptPubKey};365// Note this includes not-yet-defined witness programs.366if (prev_spk.IsWitnessProgram(version, program) && !prev_spk.IsPayToAnchor(version, program)) {367return true;368}370// For P2SH extract the redeem script and check if it spends a non-Taproot witness program. Note371// this is fine to call EvalScript (as done in ValidateInputsStandardness/IsWitnessStandard) because this372// function is only ever called after IsStandardTx, which checks the scriptsig is pushonly.373if (prev_spk.IsPayToScriptHash()) {374// If EvalScript fails or results in an empty stack, the transaction is invalid by consensus.375std::vector <std::vector<uint8_t>> stack;376if (!EvalScript(stack, txin.scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker{}, SigVersion::BASE)377|| stack.empty()) {378continue;379}380const CScript redeem_script{stack.back().begin(), stack.back().end()};381if (redeem_script.IsWitnessProgram(version, program)) {382return true;383}384}385}387return false;388}390int64_t GetSigOpsAdjustedWeight(int64_t weight, int64_t sigop_cost, unsigned int bytes_per_sigop)391{392return std::max(weight, sigop_cost * bytes_per_sigop);393}395int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost, unsigned int bytes_per_sigop)396{397return (GetSigOpsAdjustedWeight(nWeight, nSigOpCost, bytes_per_sigop) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR;398}400int64_t GetVirtualTransactionSize(const CTransaction& tx, int64_t nSigOpCost, unsigned int bytes_per_sigop)401{402return GetVirtualTransactionSize(GetTransactionWeight(tx), nSigOpCost, bytes_per_sigop);403}405int64_t GetVirtualTransactionInputSize(const CTxIn& txin, int64_t nSigOpCost, unsigned int bytes_per_sigop)406{407return GetVirtualTransactionSize(GetTransactionInputWeight(txin), nSigOpCost, bytes_per_sigop);408}