BitcoinMachine
TERM_DEF // MODULE_1_THE_STACK / STACK
STACK
Stack. Last-in, first-out scratch pad the Script VM uses.

A stack is a data structure where the last item pushed is the first item removed (LIFO). In Bitcoin Script, the stack is the only place data lives — there are no variables, registers, or heap. Every opcode either pushes something onto the stack or pops something off it.

This page sits in the Module 1 — The Stack section — Vocabulary introduced in the The Stack module. Read on for what it is, why it exists, how it works under the hood, and what to watch out for.
Stack — at a glance
MODULE 1
The stack is the only data structure Bitcoin Script has. There are no variables, no registers, no heap, no memory addressing — everything an opcode reads or writes is pushed onto or popped off a single shared LIFO stack. If the stack doesn't have what an opcode expects, the script fails on the spot and the input is rejected.
A stack is a data structure where the last item pushed is the first item removed (LIFO). In Bitcoin Script, the stack is the only place data lives — there are no variables, registers, or heap. Every opcode either pushes something onto the stack or pops something off it.
Why it exists
DESIGN
A stack is the simplest data model that still expresses conditional spending. It is trivial to validate (one O(n) pass, no random access, bounded memory), trivial to specify (a handful of pure operations), and trivial to keep consensus-compatible across thousands of independent node implementations. The alternative — registers and addressable memory — would have made every line of Bitcoin Script a potential DoS vector.
Mechanism
HOW IT WORKS
Every transaction input runs scriptSig then scriptPubKey on the same fresh stack (witness then scriptPubKey for SegWit, or just the script for Taproot leaf scripts). Push opcodes append a single item to the top; consuming opcodes (OP_ADD, hash160/">OP_HASH160, OP_CHECKSIG, …) pop their inputs and push results. There is also an alt-stack reachable only via OP_TOALTSTACK and OP_FROMALTSTACK for temporary parking. A script succeeds if and only if the main stack ends with a single value that evaluates to true.
1. The combined script is decoded into opcodes and push-data items. 2. Main stack and alt-stack both start empty. 3. Each opcode executes in order: pushes grow the stack, consuming opcodes shrink it. 4. Branching opcodes (OP_IF, OP_NOTIF, OP_ELSE, OP_ENDIF) skip code paths based on the top of stack. 5. When the last opcode finishes, the interpreter checks the main stack — exactly one truthy item authorises the spend. 6. SegWit and Taproot enforce CLEANSTACK: leftover items on the main stack fail the spend, closing an old malleability vector.
Step-through of a real P2PKH spend (top-of-stack on the right)
EXAMPLE
Locking script (in the UTXO being spent): OP_DUP OP_HASH160 <20-byte hash> OP_EQUALVERIFY OP_CHECKSIG Unlocking script (provided by the spender): step 0 (empty) [] step 1 push signature [sig] step 2 push pubkey [sig pk] step 3 OP_DUP [sig pk pk] step 4 OP_HASH160 RIPEMD160(SHA256(pk)) [sig pk H(pk)] step 5 push expected hash [sig pk H(pk) exp] step 6 OP_EQUALVERIFY pops two, fails if H(pk) != exp [sig pk] step 7 OP_CHECKSIG verifies sig over the sighash [1] End state: single truthy 0x01 on the stack → input authorised.
LIFO
Last item pushed is the first popped. Deeper items reachable only via dedicated opcodes (OP_OVER, OP_ROT, OP_PICK).
BOUNDED
Max 1000 items on main + alt stacks combined; each item up to 520 bytes. Bounds make validation cost predictable.
FRESH PER INPUT
Every input gets its own empty stack. State does not leak across inputs or transactions.
CONSENSUS-CRITICAL
A divergent stack implementation forks a node off the network. Bitcoin Core is the de-facto spec.
Things that catch people out
PITFALLS
  • Leftover items on the stack are legal pre-SegWit but rejected under CLEANSTACK — a classic regtest-only bug if scripts aren't tested with SegWit rules enabled.
  • OP_CHECKMULTISIG pops one extra "dummy" item due to an off-by-one in the original implementation. Always lead its signatures with an OP_0; SegWit froze this quirk permanently.
  • CScriptNum encoding is sign-magnitude, not two's complement. -1 is 0x81, not 0xff — comparing the wrong encoding silently produces wrong stack results.
  • OP_RETURN immediately marks the script as failed and the output as unspendable. Using it to "comment out" code burns the UTXO.

Other terms from Module 1 — The Stack — click any to read its page:
TERMINOLOGY
Stack
Last-in, first-out scratch pad the Script VM uses.
LIFO
Last In, First Out — the ordering rule of a stack.
Opcode
A single instruction in a Bitcoin Script program.
Push
Place a value on top of the stack.
Pop
Remove the top value from the stack.
OP_DUP
Duplicate the top stack item.
Script
The bytecode program that locks and unlocks Bitcoin.