Blockchain/Level IV · Protocol depth/4.1 Script/Lesson 1
Script: a stack language
The stack that keeps execution bounded and the opcodes Satoshi disabled
MaterialsA sheet of paper and penAccess to a Bitcoin block explorerThe ‘Script’ page from the Bitcoin Wiki
Wonder
- Why does a language without loops protect every node from infinite computation?
- What specific bug in 2010 allowed anyone to spend others’ coins before it was patched?
- How can an output be marked as provably unspendable while still carrying data?
Explore
- Bitcoin Script is a small, stack-based language in the style of Forth. It lacks loops and recursion, making it deliberately not Turing-complete. This design ensures that every script’s execution cost is bounded and predictable. No script can run infinitely or consume unbounded resources, protecting the network from denial-of-service attacks inherent in general-purpose code. The simplicity allows any node to validate transactions deterministically without risking resource exhaustion.
- Every output carries a locking script (scriptPubKey) that defines spending conditions. A spender supplies unlocking data via scriptSig or, since SegWit, witness data. Execution pushes data onto a stack and applies opcodes left-to-right. The spend is valid if execution finishes without error and leaves a true value on top of the stack. This binary outcome secures bitcoins without ever revealing private keys, relying on cryptographic verification rather than identity checks.
- In 2010 Satoshi Nakamoto disabled several opcodes, including OP_CAT and OP_MUL, as a precaution after bugs were found, one of which (in OP_LSHIFT) could crash nodes. A worse flaw lay in how scriptSig and scriptPubKey were joined and run as one script: a scriptSig ending in OP_RETURN could finish execution with ‘true’ before the locking script ever ran, letting anyone spend anyone’s coins. The first fix made OP_RETURN fail outright; a later release went further and ran scriptSig and scriptPubKey as separate scripts. This change hardened the security model and removed dangerous operations that could have been exploited or caused unpredictable behavior.
- OP_RETURN marks an output as provably unspendable. It is used to embed small amounts of data on-chain without creating a valid spending path. Because no signature can satisfy OP_RETURN, the coins are permanently locked but the associated data remains part of the blockchain history. Because such outputs can never be spent, nodes leave them out of the set of spendable coins.
- To understand the mechanics, step through ‘2 3 OP_ADD 5 OP_EQUAL’ on paper. Start with an empty stack. Push 2, then push 3. Apply OP_ADD to pop both and push their sum (5). Push 5 again. Apply OP_EQUAL to compare the top two items; since they match, it pushes true (1). The stack ends with a single true value, satisfying the validity requirement. This simple arithmetic demonstrates how opcodes manipulate the stack to evaluate conditions.
- Open a block explorer and locate any standard transaction. Identify the scriptPubKey in the output section, which starts with OP_DUP for a legacy P2PKH output, OP_0 for native SegWit, or OP_1 for Taproot. Then open a transaction that spends such an output and find the signature and key, in the scriptSig for legacy outputs or in the witness for SegWit and Taproot, that satisfy it, leaving a true value on the execution stack for all validating nodes.
Key facts
- Bitcoin Script is not Turing-complete; it has no loops or recursion.
- Satoshi disabled OP_CAT, OP_MUL and other opcodes in 2010 as a precaution after bugs were found.
- scriptSig and scriptPubKey have executed separately rather than concatenated since 2010.
- OP_RETURN marks an output as provably unspendable for data embedding.
- A valid spend leaves a true value on top of the execution stack.
- Every script’s cost is bounded due to the lack of arbitrary computation.
Exercise nine, six, three, one
9CollectList 9 opcodes from Bitcoin Script. Note which are disabled, which modify the stack directly, and which perform cryptographic checks.
6ClusterGroup the 9 into 6 by function: arithmetic, comparison, stack manipulation, crypto verification, data embedding, or deprecated/removed.
3DistillReduce the 6 to 3 reasons Script was kept deliberately limited.
1CrystallizeWrite 1 sentence on how bounded execution protects the network from malicious scripts.
Fact check
Dates, figures and claims checked against the published sources listed below.