Definition
The script stack is the core data structure of Bitcoin Script, the Forth-like, stack-based language that decides whether a transaction may spend an output. Script has no loops and is intentionally simple: opcodes push data onto and pop data off a single last-in-first-out (LIFO) stack, processed strictly left to right. Every rule about who can move which coins ultimately resolves to the question: after execution, what is left on this stack?
How evaluation works
Spending an output combines two scripts. The unlocking script (legacy scriptSig, or the witness in SegWit) is supplied by the spender; the locking script (scriptPubKey) was attached to the output by its creator. The unlocking script effectively runs first, pushing items such as a signature and public key onto the stack. The locking script then runs, consuming those items with opcodes like OP_DUP, OP_HASH160, OP_EQUALVERIFY, and OP_CHECKSIG. Walk through the classic pay-to-pubkey-hash pattern and the stack tells the whole story: the signature and pubkey go on; the pubkey is duplicated, hashed, and compared against the committed hash; then OP_CHECKSIG pops the signature and pubkey and pushes the verification result. A transaction input is valid only if, after both scripts finish, the stack holds a single truthy value on top. Anything else — an empty stack, a zero, leftover clutter under modern cleanstack rules — means the spend is rejected by every node on the network.
Why a stack
A constrained, stack-based model keeps validation deterministic and bounded: every node processes the same opcodes in the same order and reaches the same verdict, with no unbounded computation that could exhaust a validator's resources. There is deliberately no way to loop, jump backward, or read external state — a script's outcome depends only on the transaction and the items on its stack. That predictability is what allows scripts to encode multisig policies, hashlocks, and timelocks while remaining safe for every node — from a datacenter server to a Raspberry Pi — to execute on every input of every transaction. It is a purpose-built verification machine, not a general-purpose computer, and Bitcoin's security model depends on that restraint.
Branches, altstack, and modern script
Conditional opcodes let one script offer multiple spending paths over the same stack: branching is handled by OP_IF / Script Conditional opcodes, which is how a Lightning HTLC expresses "claim with the preimage now, or refund after the timeout." A secondary stack, the altstack, offers scratch space for temporarily parking values. In SegWit the unlocking data arrives via the Witness Stack rather than scriptSig, and in P2SH spends the stack is used twice — once to check the redeem script's hash, then again to execute the revealed script itself. Taproot continues the tradition with tapscript, refining the opcode set while keeping the same LIFO evaluation model. For a node runner, the stack is worth genuinely understanding: it is the exact machinery your own hardware executes when it enforces the rules — the place where "don't trust, verify" stops being a slogan and becomes a sequence of pushes and pops.
Watching the stack yourself
The stack rewards direct observation. Bitcoin Core's decodescript RPC and any competent script debugger will disassemble a locking script into its opcodes, and stepping through a P2PKH or multisig spend item by item — push, push, duplicate, hash, compare, verify — turns the abstraction into something you can hold. It is the same instinct that makes a repair tech trace a signal instead of trusting a schematic. Ten minutes of stepping through one real spend teaches more about why Bitcoin's validation is trustworthy than any summary: you see that there is no interpreter magic, no hidden state, just a short list of operations any machine can replay — which is precisely why every node on Earth agrees on the result.
In Simple Terms
The script stack is the core data structure of Bitcoin Script, the Forth-like, stack-based language that decides whether a transaction may spend an output. Script…
