TeachMeBitcoin

The Stack-Based Execution Model

From TeachMeBitcoin, the free encyclopedia Reading time: 4 min

The Stack-Based Execution Model

Bitcoin Script is a stack-based language. To understand how any Bitcoin transaction is validated, you must understand what a stack is and how opcodes interact with it.

What is a Stack?

A stack is a data structure that operates on a last-in, first-out (LIFO) principle. Think of a physical stack of plates. You can only add a plate to the top (push) or remove the top plate (pop). You cannot reach into the middle of the stack.

In Bitcoin Script, data items are pushed onto the stack and opcodes operate on them. The result of each opcode either leaves new data on the stack or removes data. At the end of script execution, if the top item on the stack is non-zero (true), the script succeeds.

Stack Operations:

PUSH 5        Stack: [5]
PUSH 3        Stack: [5, 3]
OP_ADD        Stack: [8]       (pops 5 and 3, pushes 8)
PUSH 8        Stack: [8, 8]
OP_EQUAL      Stack: [1]       (pops both 8s, pushes 1 = TRUE)

Result: Stack top is 1 (TRUE) — script succeeds.

The Main Stack and the Alt Stack

Bitcoin Script actually maintains two stacks simultaneously:

  1. The Main Stack: Where all normal operations happen. Opcodes push and pop from here by default.

  2. The Alt Stack: An auxiliary stack used to temporarily store items. Only OP_TOALTSTACK and OP_FROMALTSTACK interact with it.

The alt stack allows scripts to save intermediate values without losing their position in a computation. It is an essential tool for complex script patterns like Hash Time Locked Contracts (HTLCs).

// Example using alt stack:
PUSH <value_A>
OP_TOALTSTACK      // Move A to alt stack. Main: [], Alt: [A]
PUSH <value_B>
PUSH <value_C>
OP_ADD             // Main: [B+C], Alt: [A]
OP_FROMALTSTACK    // Main: [B+C, A], Alt: []
OP_ADD             // Main: [A+B+C], Alt: []

How Opcodes Interact with the Stack

Every opcode in Bitcoin Script is one of three types:

1. Push opcodes: These place data onto the stack without performing any computation.

OP_1        // Pushes the integer 1
OP_16       // Pushes the integer 16
<20 bytes>  // Pushes arbitrary byte data

2. Operation opcodes: These pop one or more items from the stack, perform a computation, and push the result.

OP_DUP          // Pops top item, pushes it twice (duplicates)
OP_HASH160      // Pops top item, hashes it, pushes result
OP_CHECKSIG     // Pops signature and pubkey, pushes 1 or 0

3. Flow control opcodes: These conditionally skip sections of script based on stack values.

OP_IF           // Pops top item; if true, executes next branch
OP_ELSE         // Switches to alternative branch
OP_ENDIF        // Closes conditional block

Walking Through a Real P2PKH Script

The most common Bitcoin script type is Pay-to-Public-Key-Hash (P2PKH). Here is the full execution trace:

Initial stack: []

Unlocking script provides:
<sig>       → Stack: [sig]
<pubKey>    → Stack: [sig, pubKey]

Locking script executes:
OP_DUP      → Stack: [sig, pubKey, pubKey]         (duplicates top)
OP_HASH160  → Stack: [sig, pubKey, hash160(pubKey)] (hashes top)
<pubKeyHash>→ Stack: [sig, pubKey, hash160(pubKey), pubKeyHash]
OP_EQUALVERIFY → Stack: [sig, pubKey]              (checks equality, fails if mismatch)
OP_CHECKSIG    → Stack: [1]                        (verifies sig against pubKey)

Final stack: [1] → TRUE → Transaction valid.

Stack Overflow and Underflow

The Script interpreter enforces limits on stack operations:

These limits prevent resource exhaustion attacks where a script could fill up a node's memory.

☕ 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!