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#!/usr/bin/env python32# Copyright (c) 2019-present The Bitcoin Core developers3# Distributed under the MIT software license, see the accompanying4# file COPYING or http://www.opensource.org/licenses/mit-license.php.5# Test Taproot softfork (BIPs 340-342)7from test_framework.blocktools import (8COINBASE_MATURITY,9create_coinbase,10create_block,11add_witness_commitment,12MAX_BLOCK_SIGOPS_WEIGHT,13)14from test_framework.messages import (15COutPoint,16CTransaction,17CTxIn,18CTxInWitness,19CTxOut,20SEQUENCE_FINAL,21tx_from_hex,22TX_MAX_STANDARD_VERSION,23WITNESS_SCALE_FACTOR,24)25from test_framework.script import (26ANNEX_TAG,27BIP341_sha_amounts,28BIP341_sha_outputs,29BIP341_sha_prevouts,30BIP341_sha_scriptpubkeys,31BIP341_sha_sequences,32CScript,33CScriptNum,34CScriptOp,35hash256,36LEAF_VERSION_TAPSCRIPT,37LegacySignatureMsg,38LOCKTIME_THRESHOLD,39MAX_SCRIPT_ELEMENT_SIZE,40OP_0,41OP_1,42OP_2,43OP_3,44OP_4,45OP_5,46OP_6,47OP_7,48OP_8,49OP_9,50OP_10,51OP_11,52OP_12,53OP_16,54OP_2DROP,55OP_2DUP,56OP_CHECKMULTISIG,57OP_CHECKMULTISIGVERIFY,58OP_CHECKSIG,59OP_CHECKSIGADD,60OP_CHECKSIGVERIFY,61OP_CODESEPARATOR,62OP_DROP,63OP_DUP,64OP_ELSE,65OP_ENDIF,66OP_EQUAL,67OP_EQUALVERIFY,68OP_IF,69OP_NOP,70OP_NOT,71OP_NOTIF,72OP_PUSHDATA1,73OP_RETURN,74OP_SWAP,75OP_TUCK,76OP_VERIFY,77SIGHASH_DEFAULT,78SIGHASH_ALL,79SIGHASH_NONE,80SIGHASH_SINGLE,81SIGHASH_ANYONECANPAY,82SegwitV0SignatureMsg,83TaggedHash,84TaprootSignatureMsg,85is_op_success,86taproot_construct,87)88from test_framework.script_util import (89key_to_p2pk_script,90key_to_p2pkh_script,91key_to_p2wpkh_script,92keyhash_to_p2pkh_script,93script_to_p2sh_script,94script_to_p2wsh_script,95)96from test_framework.test_framework import BitcoinTestFramework97from test_framework.util import (98assert_not_equal,99assert_raises_rpc_error,100assert_equal,101)102from test_framework.wallet import NodeSigner103from test_framework.wallet_util import generate_keypair104from test_framework.key import (105generate_privkey,106compute_xonly_pubkey,107sign_schnorr,108tweak_add_privkey,109ECKey,110)111from test_framework.crypto import secp256k1112from test_framework.address import (113hash160,114program_to_witness,115)116from collections import OrderedDict, namedtuple117import json118import hashlib119import os120import random122# Whether or not to output generated test vectors, in JSON format.123GEN_TEST_VECTORS = False125# === Framework for building spending transactions. ===126#127# The computation is represented as a "context" dict, whose entries store potentially-unevaluated expressions that128# refer to lower-level ones. By overwriting these expression, many aspects - both high and low level - of the signing129# process can be overridden.130#131# Specifically, a context object is a dict that maps names to compositions of:132# - values133# - lists of values134# - callables which, when fed the context object as argument, produce any of these135#136# The DEFAULT_CONTEXT object specifies a standard signing process, with many overridable knobs.137#138# The get(ctx, name) function can evaluate a name, and cache its result in the context.139# getter(name) can be used to construct a callable that evaluates name. For example:140#141# ctx1 = {**DEFAULT_CONTEXT, inputs=[getter("sign"), b'\x01']}142#143# creates a context where the script inputs are a signature plus the bytes 0x01.144#145# override(expr, name1=expr1, name2=expr2, ...) can be used to cause an expression to be evaluated in a selectively146# modified context. For example:147#148# ctx2 = {**DEFAULT_CONTEXT, sighash=override(default_sighash, hashtype=SIGHASH_DEFAULT)}149#150# creates a context ctx2 where the sighash is modified to use hashtype=SIGHASH_DEFAULT. This differs from151#152# ctx3 = {**DEFAULT_CONTEXT, hashtype=SIGHASH_DEFAULT}153#154# in that ctx3 will globally use hashtype=SIGHASH_DEFAULT (including in the hashtype byte appended to the signature)155# while ctx2 only uses the modified hashtype inside the sighash calculation.157def deep_eval(ctx, expr):158"""Recursively replace any callables c in expr (including inside lists) with c(ctx)."""159while callable(expr):160expr = expr(ctx)161if isinstance(expr, list):162expr = [deep_eval(ctx, x) for x in expr]163return expr165# Data type to represent fully-evaluated expressions in a context dict (so we can avoid reevaluating them).166Final = namedtuple("Final", "value")168def get(ctx, name):169"""Evaluate name in context ctx."""170assert name in ctx, "Missing '%s' in context" % name171expr = ctx[name]172if not isinstance(expr, Final):173# Evaluate and cache the result.174expr = Final(deep_eval(ctx, expr))175ctx[name] = expr176return expr.value178def getter(name, **kwargs):179"""Return a callable that evaluates name in its passed context."""180return lambda ctx: get({**ctx, **kwargs}, name)182def override(expr, **kwargs):183"""Return a callable that evaluates expr in a modified context."""184return lambda ctx: deep_eval({**ctx, **kwargs}, expr)186# === Implementations for the various default expressions in DEFAULT_CONTEXT ===188def default_hashtype(ctx):189"""Default expression for "hashtype": SIGHASH_DEFAULT for taproot, SIGHASH_ALL otherwise."""190mode = get(ctx, "mode")191if mode == "taproot":192return SIGHASH_DEFAULT193else:194return SIGHASH_ALL196def default_tapleaf(ctx):197"""Default expression for "tapleaf": looking up leaf in tap[2]."""198return get(ctx, "tap").leaves[get(ctx, "leaf")]200def default_script_taproot(ctx):201"""Default expression for "script_taproot": tapleaf.script."""202return get(ctx, "tapleaf").script204def default_leafversion(ctx):205"""Default expression for "leafversion": tapleaf.version"""206return get(ctx, "tapleaf").version208def default_negflag(ctx):209"""Default expression for "negflag": tap.negflag."""210return get(ctx, "tap").negflag212def default_pubkey_internal(ctx):213"""Default expression for "pubkey_internal": tap.internal_pubkey."""214return get(ctx, "tap").internal_pubkey216def default_merklebranch(ctx):217"""Default expression for "merklebranch": tapleaf.merklebranch."""218return get(ctx, "tapleaf").merklebranch220def default_controlblock(ctx):221"""Default expression for "controlblock": combine leafversion, negflag, pubkey_internal, merklebranch."""222return bytes([get(ctx, "leafversion") + get(ctx, "negflag")]) + get(ctx, "pubkey_internal") + get(ctx, "merklebranch")224def default_scriptcode_suffix(ctx):225"""Default expression for "scriptcode_suffix", the actually used portion of the scriptcode."""226scriptcode = get(ctx, "scriptcode")227codesepnum = get(ctx, "codesepnum")228if codesepnum == -1:229return scriptcode230codeseps = 0231for (opcode, data, sop_idx) in scriptcode.raw_iter():232if opcode == OP_CODESEPARATOR:233if codeseps == codesepnum:234return CScript(scriptcode[sop_idx+1:])235codeseps += 1236assert False238def default_sigmsg(ctx):239"""Default expression for "sigmsg": depending on mode, compute BIP341, BIP143, or legacy sigmsg."""240tx = get(ctx, "tx")241idx = get(ctx, "idx")242hashtype = get(ctx, "hashtype_actual")243mode = get(ctx, "mode")244if mode == "taproot":245# BIP341 signature hash246utxos = get(ctx, "utxos")247annex = get(ctx, "annex")248if get(ctx, "leaf") is not None:249codeseppos = get(ctx, "codeseppos")250leaf_ver = get(ctx, "leafversion")
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.