TeachMeBitcoin

Tapscript sighash commits to (simplified):

From TeachMeBitcoin, the free encyclopedia Reading time: 3 min

2. How Tapscript Differs from Legacy Script

Tapscript is deliberately close to legacy Bitcoin Script. The goal was evolutionary improvement, not revolutionary replacement. Most opcodes work identically. The differences are targeted and purposeful.

Differences in Signature Opcodes

The most significant behavioral difference is in how signature-checking opcodes work.

Legacy Script uses ECDSA signatures. Tapscript uses Schnorr signatures.

In legacy Script, OP_CHECKSIG verifies a DER-encoded ECDSA signature. In Tapscript, OP_CHECKSIG verifies a 64-byte (or 65-byte with sighash type) Schnorr signature. The opcode byte is the same (0xac), but the signature format is entirely different.

Legacy OP_CHECKSIG input format:
Stack before: [<DER-encoded ECDSA sig + sighash_byte>, <33-byte compressed pubkey>]

Tapscript OP_CHECKSIG input format:
Stack before: [<64-byte Schnorr sig> or <65-byte Schnorr sig with sighash>, <32-byte x-only pubkey>]

Notice the public key format change: legacy Script uses 33-byte compressed public keys. Tapscript uses 32-byte x-only public keys — just the x-coordinate of the elliptic curve point. This is possible because for any x-coordinate, there are only two possible y-coordinates, and the convention is to always use the even one.

OP_CHECKMULTISIG is replaced by OP_CHECKSIGADD.

In legacy Script, OP_CHECKMULTISIG takes multiple signatures and public keys and checks M-of-N in a single opcode. In Tapscript, this opcode is disabled (causes immediate failure). Instead, Tapscript introduces OP_CHECKSIGADD which checks one signature at a time and accumulates a count:

Legacy 2-of-3 multisig:
OP_0 <sig1> <sig2> OP_2 <pk1> <pk2> <pk3> OP_3 OP_CHECKMULTISIG

Tapscript 2-of-3 equivalent:
<sig1> <sig2> <sig3>
<pk1> OP_CHECKSIGADD
<pk2> OP_CHECKSIGADD
<pk3> OP_CHECKSIGADD
OP_2 OP_GREATERTHANOREQUAL

Differences in Disabled Opcodes

Tapscript disables several opcodes that were previously available in legacy Script, and re-enables the semantics of some that were previously NOP-repurposed.

Opcodes disabled in Tapscript (cause immediate failure):

- OP_CHECKMULTISIG (0xae)

- OP_CHECKMULTISIGVERIFY (0xaf)

Opcodes that are OP_SUCCESS in Tapscript (cause immediate success):

- Many previously undefined/reserved opcodes

- See the OP_SUCCESS topic for the full list

Differences in Resource Limits

Legacy Script    Tapscript
Script size limit:        10,000 bytes     weight-limited (no fixed byte cap)
Non-push opcode limit:    201              NONE (removed entirely)
Stack item size:          520 bytes        520 bytes (unchanged)
Stack depth:              1,000 items      1,000 items (unchanged)
Numeric size:             4 bytes          4 bytes (unchanged)

Differences in Signature Hashing

The data that gets hashed to produce the signature hash (sighash) is structured differently in Tapscript. Legacy Script had several sighash hash algorithm variants (original, BIP 143 for SegWit v0). Tapscript uses the algorithm defined in BIP 341, which:

# Tapscript sighash commits to (simplified):
sighash_data = (
    hash_type          +   # 1 byte
    nVersion           +   # 4 bytes
    nLockTime          +   # 4 bytes
    sha_prevouts       +   # 32 bytes (hash of all outpoints)
    sha_amounts        +   # 32 bytes (hash of all input amounts) ← NEW
    sha_scriptpubkeys  +   # 32 bytes (hash of all input scripts) ← NEW
    sha_sequences      +   # 32 bytes
    sha_outputs        +   # 32 bytes
    spend_type         +   # 1 byte
    input_index            # 4 bytes
)

Technical Insight

This topic covers essential mechanics for Chapter 11. Understanding these details is key to mastering advanced Bitcoin script constructions like Taproot and specialized covenants.

☕ Help support TeachMeBitcoin

TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation:

Ethereum: 0x578417C51783663D8A6A811B3544E1f779D39A85
Bitcoin: bc1q77k9e95rn669kpzyjr8ke9w95zhk7pa5s63qzz
Solana: 4ycT2ayqeMucixj3wS8Ay8Tq9NRDYRPKYbj3UGESyQ4J
Address copied to clipboard!