- Script Operations and Execution Model
- P2PK and P2PKH: Core Payment Patterns
- Transaction Validation and Signature Hashing
- Script Puzzles and Security Lessons
Bitcoin Script is a small, stack-based smart contract language that defines how coins can be spent. Every output carries a scriptPubKey (locking script) and every input carries a scriptSig (unlocking script). Together they form a program that must evaluate to “true” for the spend to be valid. Script is intentionally not Turing-complete so that all execution paths are predictable and easy to validate across the network.
Script Operations and Execution Model
A script is a sequence of data elements and opcodes. Data pushes (signatures, public keys, hashes) are placed onto the stack, while opcodes starting with
OP_ transform the stack. After execution, the top stack element must be non-zero for success. Examples: OP_DUP duplicates the top element, OP_HASH160 applies SHA256 then RIPEMD160, and OP_CHECKSIG verifies a signature against the transaction’s sighash and a public key, pushing 1 for valid, 0 for invalid. Parsing rules distinguish between raw data (length-prefixed) and opcodes (looked up by byte value), and a small virtual machine executes them deterministically on every node.P2PK and P2PKH: Core Payment Patterns
The earliest pattern, Pay-to-Public-Key (P2PK), locked coins directly to a full public key: the scriptPubKey is
<pubkey> OP_CHECKSIG, and the scriptSig is just a signature. It is simple but space-inefficient and exposes the public key before the coins are spent.P2PKH and Addresses
Pay-to-Public-Key-Hash (P2PKH) improves this by locking to a 20‑byte hash of the public key. The scriptPubKey is
OP_DUP OP_HASH160 <pubkey_hash> OP_EQUALVERIFY OP_CHECKSIG, and the scriptSig provides <signature> <pubkey>. Execution checks that the provided public key hashes to the committed value and then verifies the signature. This hides the public key until spend time, reduces size, and matches the familiar “1…” mainnet address format.Transaction Validation and Signature Hashing
A node validating a transaction must ensure:
- Each input references an existing, unspent output.
- Total input value ≥ total output value (the difference is the fee).
- Each scriptSig correctly unlocks its referenced scriptPubKey.
Signature verification requires constructing the exact message that was signed, called the sighash. For legacy ECDSA, validation empties all scriptSigs, replaces the current input’s scriptSig with the corresponding scriptPubKey, appends a 4‑byte hash type (usually
SIGHASH_ALL), and double‑hashes the result. That 256‑bit value is what OP_CHECKSIG uses. Alternative hash types (e.g., SINGLE, NONE, with or without ANYONECANPAY) change which parts of the transaction are committed to, enabling niche use cases like collaborative funding or partially specified transactions, but they are rarely used in practice.Quadratic Hashing and SegWit
Because each input in a legacy transaction requires its own sighash computation over a structure that includes all inputs, validation time can grow quadratically with the number of inputs. Large multi‑input transactions once caused noticeable validation delays. SegWit redesigned sighash calculation to cache shared parts and reduce complexity to linear time, improving scalability and making denial‑of‑service attacks harder.
Script Puzzles and Security Lessons
Script can express far more than simple “one signature unlocks these coins.” Script puzzles demonstrate this by encoding arbitrary conditions—math problems, hash preimage challenges, or even collision bounties—where anyone who provides the correct data can spend the coins. However, outputs that rely only on public data (no signatures) are vulnerable to miner front‑running: once a valid solution appears in the mempool, any miner can copy it and redirect the payout to themselves.
The practical lesson is that real-world contracts almost always include signature checks, even when they contain more complex logic such as multisig, timelocks, or hashlocks. Signatures bind the solution to a specific party, preserving incentives and preventing others from stealing the payout. Understanding Script’s stack model, standard patterns, and subtle pitfalls is essential for designing secure Bitcoin smart contracts and for reasoning about how transactions are actually validated on the network.
Quiz
Quiz1/5
pro2023.2
What is the primary reason that script puzzles relying only on public data without signature checks are vulnerable in Bitcoin?