TeachMeBitcoin

OP_ELSE - The Alternative Branch

From TeachMeBitcoin, the free encyclopedia Reading time: 3 min

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