BIP-342 (Tapscript)
The specification defining the updated script validation rules for Taproot's script-path spending, with improved opcodes.
Key Takeaways
- BIP-342 defines Tapscript, the upgraded scripting language used inside Taproot script-path spends. It replaces legacy multisig opcodes with OP_CHECKSIGADD and enforces Schnorr signature validation for all signature checks.
- OP_SUCCESS opcodes replace previously disabled opcodes, providing a clean mechanism for introducing new Bitcoin Script features through future soft forks without the limitations of OP_NOP-based upgrades.
- Tapscript removes the 10,000-byte script size limit and 201-opcode cap from legacy Script, enabling more complex contracts while using a per-script signature operations budget for DoS protection.
What Is BIP-342 (Tapscript)?
BIP-342 is a Bitcoin Improvement Proposal authored by Pieter Wuille, Jonas Nick, and Anthony Towns that specifies Tapscript: the set of script validation rules governing Taproot script-path spends. While BIP-341 defines the Taproot output structure and its Merkle tree of scripts, BIP-342 defines what happens when one of those scripts actually executes.
Tapscript activated alongside Taproot on November 14, 2021, at block height 709,632. It modernizes Bitcoin Script by integrating Schnorr signatures, removing artificial resource limits, and adding upgrade hooks that make future soft forks easier to deploy. It is identified by leaf version 0xc0 within the BIP-341 framework.
Together, BIP-340 (Schnorr signatures), BIP-341 (Taproot output structure), and BIP-342 (Tapscript validation rules) form a single integrated upgrade to Bitcoin's transaction capabilities. For a broader overview of this upgrade, see the research article on Taproot and Schnorr signatures.
How It Works
When a Taproot output is spent via the script path (rather than the key path), the witness data reveals a script leaf from the Merkle tree. If that leaf has version 0xc0, the script executes under Tapscript rules. These rules modify several aspects of legacy Bitcoin Script.
OP_CHECKSIGADD Replaces OP_CHECKMULTISIG
Legacy Bitcoin Script uses OP_CHECKMULTISIG for multi-signature operations, but this opcode is incompatible with Schnorr batch verification. The problem: OP_CHECKMULTISIG does not associate specific signatures with specific public keys until runtime, creating a combinatorial search that prevents efficient batch validation.
Tapscript disables OP_CHECKMULTISIG and OP_CHECKMULTISIGVERIFY entirely (they cause immediate script failure). In their place, BIP-342 introduces OP_CHECKSIGADD (opcode 0xba). This opcode pops three elements from the stack: a public key, a counter, and a signature. If the signature is valid, it pushes the counter incremented by one. If the signature is empty, it pushes the counter unchanged.
A k-of-n multisig in Tapscript chains individual signature checks rather than bundling them:
# Legacy OP_CHECKMULTISIG (disabled in Tapscript)
OP_2 <pubkeyA> <pubkeyB> <pubkeyC> OP_3 OP_CHECKMULTISIG
# Tapscript equivalent: 2-of-3 using OP_CHECKSIGADD
<pubkeyA> OP_CHECKSIG
<pubkeyB> OP_CHECKSIGADD
<pubkeyC> OP_CHECKSIGADD
OP_2 OP_EQUALEach public key pairs with exactly one signature (or an empty value), enabling Schnorr batch verification across an entire block of transactions.
Schnorr Signature Validation
Tapscript modifies OP_CHECKSIG and OP_CHECKSIGVERIFY to verify Schnorr signatures per BIP-340 instead of ECDSA. The signature format is strict:
- 64-byte signatures use the default sighash type
- 65-byte signatures append a one-byte sighash flag (which must be non-zero)
- Any other length causes immediate validation failure
- Empty signatures return false without failing the script, enabling k-of-n constructions with OP_CHECKSIGADD
Public keys in Tapscript follow a versioning scheme: 32-byte keys are validated as BIP-340 Schnorr keys, while keys of unknown sizes are treated as valid but unverified. This allows future soft forks to introduce new signature algorithms without modifying Tapscript itself.
The Signature Message
Tapscript extends the BIP-341 common signature message with three additional fields that commit to the specific script being executed:
- tapleaf_hash (32 bytes): commits to the executed script and its leaf version, replacing the legacy scriptCode commitment
- key_version (1 byte): currently 0x00, reserved for future public key types
- codesep_pos (4 bytes): the position of the last executed OP_CODESEPARATOR, or 0xffffffff if none has been encountered
All hash computations use tagged hashes for domain separation, following the pattern: SHA256(SHA256(tag) || SHA256(tag) || message). The Tapscript signature hash uses the tag "TapSighash".
OP_SUCCESS: A Soft Fork Upgrade Mechanism
BIP-342 redefines a set of previously disabled opcodes (80, 98, 126-129, 131-134, 137-138, 141-142, 149-153, 187-254) as OP_SUCCESSx. When any of these opcodes appears in a Tapscript, the entire script succeeds unconditionally during the decoding phase, before any execution begins.
This design is a significant improvement over legacy OP_NOP-based upgrades. OP_NOP opcodes can only add new validation conditions because they cannot modify the stack. OP_SUCCESS opcodes bypass all validation, which means a future soft fork can redefine them with full stack read and write access. The redefinition simply makes a previously-always-succeeding opcode sometimes fail, which is a valid soft fork (tightening of rules).
Removed Resource Limits
Tapscript lifts two constraints that limited legacy Bitcoin Script:
| Limit | Legacy Script | Tapscript |
|---|---|---|
| Maximum script size | 10,000 bytes | No limit (bounded by block weight) |
| Non-push opcodes | 201 per script | No limit |
| Signature operation counting | Block-wide limit | Per-script budget |
The script size limit was safe to remove because the Tapscript signature hash commits to scripts indirectly through a precomputable tapleaf_hash, eliminating the O(n²) hashing concern that justified the original limit. For DoS protection, Tapscript uses a per-script signature operations budget calculated as 50 plus the total serialized size of the input witness in bytes. Each successful signature check costs 50 units from this budget.
MINIMALIF Consensus Enforcement
In legacy Script, the MINIMALIF rule (requiring OP_IF and OP_NOTIF arguments to be exactly empty or exactly the byte 0x01) was only a relay policy. Tapscript promotes this to a consensus rule, closing a script malleability vector where third parties could alter transaction witnesses without invalidating them.
Use Cases
Efficient Multi-Signature Schemes
OP_CHECKSIGADD enables clean k-of-n multisig scripts where each signer provides exactly one signature or an empty value. This pairs naturally with threshold signature schemes: simple cases use the Taproot key path with aggregated keys, while complex fallback conditions live in Tapscript leaves.
Advanced Smart Contracts
The removal of script size and opcode limits opens the door for more sophisticated Bitcoin contracts. Miniscript policies that previously bumped against the 201-opcode ceiling can now express richer spending conditions. Combined with Taproot's Merkle tree of scripts, developers can encode dozens of spending paths without bloating on-chain data, as explored in the research article on Bitcoin Script programmability.
Future Protocol Upgrades
OP_SUCCESS opcodes provide a clean path for introducing new functionality via soft fork. Proposals like covenants (OP_CHECKTEMPLATEVERIFY, OP_VAULT) and other advanced opcodes can be deployed by redefining an OP_SUCCESS opcode. The public key versioning mechanism similarly allows future signature schemes to coexist with Schnorr without modifying Tapscript's core logic.
Layer 2 Protocols
Tapscript improvements benefit Layer 2 protocols that rely on complex on-chain scripts for dispute resolution and exit mechanisms. Protocols like Spark, Lightning, and Ark can use more expressive Tapscript leaves for their on-chain components while keeping the common cooperative case in the efficient key path.
Risks and Considerations
Complexity for Wallet Developers
Tapscript introduces new signature hashing, opcode behavior, and resource limit rules that wallet and library developers must implement correctly. The interaction between leaf versions, public key versions, and OP_SUCCESS semantics requires careful handling. Wallets that support Taproot script-path spending must fully implement BIP-342 validation to avoid accepting invalid transactions or producing invalid signatures.
Script Size and Witness Costs
While Tapscript removes the script size limit, larger scripts still cost more in witness data weight. The per-script sigops budget also ties signature capacity to witness size, meaning complex multi-signature arrangements require proportionally larger witnesses. Developers must balance contract expressiveness against on-chain cost.
OP_SUCCESS and Validation Risks
Any Tapscript containing an OP_SUCCESS opcode is unconditionally valid today. If a wallet or application accidentally includes an OP_SUCCESS opcode in a script, anyone can spend the output. This is by design for upgradability, but it means developers must avoid using undefined opcodes in production scripts until they are redefined by a future soft fork.
Adoption and Compatibility
Tapscript is only available within Taproot (SegWit v1) outputs. Legacy and SegWit v0 scripts continue using the old rules. Applications that want Tapscript benefits must migrate to P2TR output types, which requires updates across the wallet stack: key generation, address encoding, signing, and transaction construction. The research article on Bitcoin address types covers this migration path in detail.
This glossary entry is for informational purposes only and does not constitute financial or investment advice. Always do your own research before using any protocol or technology.