BitcoinMachine

Module 04

Branching

Bitcoin Script has no loops and no goto — but it does have conditionals. OP_IF lets a script take different paths based on a value on the stack, enabling scripts that respond to their inputs.

0 / 4 sections

What you'll learn

  • Write OP_IF / OP_ELSE / OP_ENDIF blocks
  • Use OP_NOTIF for inverted conditions
  • Explain how the condition stack tracks nested branches
  • Apply OP_VERIFY and OP_RETURN for guard clauses

01

OP_IF / OP_ELSE / OP_ENDIF

OP_IF pops the top item. If it's truthy, the block between IF and ELSE executes. If falsy, the ELSE block executes (if present). OP_ENDIF closes the block. This is the only form of branching in Bitcoin Script.

The condition value is consumed — it's popped from the stack before any branch executes.

OP_IF (true branch)

Condition is 1 (truthy) → the IF branch runs, pushing 7.

Script
OP_1
OP_IF
OP_7
OP_ELSE
OP_9
OP_ENDIF
Stack0 items

↑ top of stack

nothing here yet

press Step or Run to push an item

bottom
OP_1Pushes the number 1 onto the stack.
0 stepsReady
OP_IF (false branch)

Condition is 0 (falsy) → the ELSE branch runs, pushing 9.

Script
OP_0
OP_IF
OP_7
OP_ELSE
OP_9
OP_ENDIF
Stack0 items

↑ top of stack

nothing here yet

press Step or Run to push an item

bottom
OP_0Pushes an empty byte array (false / zero) onto the stack.
0 stepsReady
Notice the opcodes in the skipped branch don't execute and don't touch the stack — the interpreter jumps over them entirely. The internal condition stack tracks which level is active.
Real Bitcoin

Branching in Lightning

Hash Time-Locked Contracts (HTLCs) — the mechanism behind every Lightning payment — use OP_IF to encode two settlement paths: reveal a preimage or wait for a timeout. Branching is what makes multi-hop routing safe.

02

OP_NOTIF and nesting

OP_NOTIF is the mirror image of OP_IF: it executes its block when the condition is falsy. Conditionals can be nested — each OP_ENDIF closes the innermost open block.

OP_NOTIF

Condition is 0 (falsy) → the NOTIF block runs, pushing 5.

Script
OP_0
OP_NOTIF
OP_5
OP_ENDIF
Stack0 items

↑ top of stack

nothing here yet

press Step or Run to push an item

bottom
OP_0Pushes an empty byte array (false / zero) onto the stack.
0 stepsReady
Nested OP_IF

Two nested conditionals. Both conditions are true → innermost IF branch runs, pushing 16.

Script
OP_1
OP_IF
OP_1
OP_IF
OP_16
OP_ELSE
OP_15
OP_ENDIF
OP_ELSE
OP_0
OP_ENDIF
Stack0 items

↑ top of stack

nothing here yet

press Step or Run to push an item

bottom
OP_1Pushes the number 1 onto the stack.
0 stepsReady

03

OP_VERIFY and OP_RETURN

OP_VERIFY pops the top item and immediately fails the entire script if it's falsy. It's the assertion opcode — used when you need to guarantee a condition is true before proceeding. Many opcodes end with VERIFY as a suffix (e.g. OP_EQUALVERIFY) — these are shorthand for running the base opcode then verifying the result.

OP_RETURN unconditionally fails the script and marks the output as unspendable. It's used in data-carrier outputs for embedding metadata.

OP_VERIFY (pass)

5 == 5 → OP_VERIFY passes → OP_1 pushes true. Script succeeds.

Script
OP_5
OP_5
OP_EQUAL
OP_VERIFY
OP_1
Stack0 items

↑ top of stack

nothing here yet

press Step or Run to push an item

bottom
OP_5Pushes the number 5 onto the stack.
0 stepsReady
OP_VERIFY (fail)

5 ≠ 6 → OP_VERIFY fails the script immediately.

Script
OP_5
OP_6
OP_EQUAL
OP_VERIFY
OP_1
Stack0 items

↑ top of stack

nothing here yet

press Step or Run to push an item

bottom
OP_5Pushes the number 5 onto the stack.
0 stepsReady
Experiment: what happens if you put data after an OP_RETURN? Try OP_1 OP_RETURN OP_2 below.

Ctrl+Enter to run

Script
OP_1
OP_RETURN
OP_2
Stack0 items

↑ top of stack

nothing here yet

press Step or Run to push an item

bottom
OP_1Pushes the number 1 onto the stack.
0 stepsReady

04

Your turn

Challenge

Conditional result

Write a script that uses OP_IF to leave 42 on the stack when the condition is true, and anything else when false. Make the true branch execute.

Ctrl+Enter to check

← Home