OP_ELSE - The Alternative Branch
3. OP_ELSE — The Alternative Branch
Overview
OP_ELSE serves as the dividing marker between the true and false branches of a conditional block. It must always be paired with a preceding OP_IF or OP_NOTIF and a following OP_ENDIF. When the interpreter encounters OP_ELSE, it toggles its execution state: if it was executing (inside the true branch), it stops; if it was skipping (inside the false branch), it resumes.
Opcode Reference
Opcode: OP_ELSE
Hex: 0x67
Byte value: 103 (decimal)
Category: Flow Control
How the Interpreter Handles OP_ELSE
The Bitcoin Script interpreter maintains an internal execution state stack (sometimes called the vfExec or condition stack in reference implementations). This tracks whether each conditional level is currently active or being skipped.
; Interpreter state transitions:
OP_IF (condition = true)
--> executing = true
[opcodes run]
OP_ELSE
--> executing = false (toggle)
[opcodes skipped]
OP_ENDIF
--> pop conditional level
And the inverse:
OP_IF (condition = false)
--> executing = false
[opcodes skipped]
OP_ELSE
--> executing = true (toggle)
[opcodes run]
OP_ENDIF
OP_ELSE is Optional
OP_ELSE is not required. An OP_IF block can terminate directly with OP_ENDIF if there is no meaningful alternative action:
; Without OP_ELSE:
<condition>
OP_IF
<do something>
OP_ENDIF
; If condition is false, nothing happens and execution continues after ENDIF
This pattern is useful for optional verification or cleanup steps that only matter in certain spending paths.
OP_ELSE Cannot Appear Twice in One Block
A single OP_IF/OP_NOTIF block can contain at most one OP_ELSE. The following is invalid:
; INVALID SCRIPT
OP_IF
<branch A>
OP_ELSE
<branch B>
OP_ELSE ; ERROR: second OP_ELSE in same block
<branch C>
OP_ENDIF
To achieve three-way branching, nested OP_IF structures must be used (see section 5).
Stack Considerations with OP_ELSE
Since OP_ELSE does not interact with the stack directly, the stack state entering the OP_ELSE branch is exactly what the stack looked like after OP_IF popped its condition. Script authors must ensure both branches leave compatible stack states for the code following OP_ENDIF.
; Stack must be consistent after both branches:
<x>
OP_IF
OP_SHA256 ; hashes x, leaves 32-byte hash
OP_ELSE
OP_HASH160 ; hashes x, leaves 20-byte hash
OP_ENDIF
; Stack now has one item — but it might be 20 or 32 bytes
; Script author must handle this correctly downstream
Practical Usage: Two-Party Spend
; Alice spends with preimage; Bob spends with signature after timeout
OP_IF
; Preimage path (Alice)
OP_SHA256
<payment_hash>
OP_EQUALVERIFY
<alice_pubkey>
OP_CHECKSIG
OP_ELSE
; Timeout path (Bob)
<expiry_time>
OP_CHECKLOCKTIMEVERIFY
OP_DROP
<bob_pubkey>
OP_CHECKSIG
OP_ENDIF
Spending with Alice's path (scriptSig / witness):
<alice_sig> <preimage> OP_1
Spending with Bob's path:
<bob_sig> OP_0
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: