OP_VER - The Disabled Version Opcode
17. OP_VER — The Disabled Version Opcode
Overview
OP_VER is opcode 0x62 in Bitcoin Script. Despite occupying a byte immediately adjacent to OP_NOP (0x61), OP_VER has a radically different status: it is a disabled opcode that causes any script containing it to be immediately invalid, regardless of whether it appears in an executed or unexecuted code path. Unlike OP_RESERVED, which only fails when executed, OP_VER fails at validation time even in dead branches.
Original Intended Purpose
Based on early Bitcoin codebase history and commentary, OP_VER was intended to push the current protocol version number onto the stack, potentially enabling version-dependent script logic. A script could in theory have branched on the protocol version to behave differently in different protocol eras.
Hypothetical (never worked in practice) intended use:
OP_VER -- push current protocol version
<expected_ver> -- push expected version
OP_EQUAL -- check if they match
OP_IF ... OP_ENDIF
This design would have been deeply problematic: if the protocol version changed, previously valid scripts could become invalid (or vice versa), creating a minefield of consensus edge cases. Satoshi apparently recognized this and disabled the opcode early in Bitcoin's history.
Why It Is Disabled
OP_VER is classified as a "disabled opcode" — a category that also includes OP_CAT, OP_SUBSTR, OP_LEFT, OP_RIGHT, OP_INVERT, OP_AND, OP_OR, OP_XOR, OP_2MUL, OP_2DIV, OP_MUL, OP_DIV, OP_MOD, OP_LSHIFT, OP_RSHIFT.
// From src/script/interpreter.cpp
// Disabled opcodes check (happens before execution)
if (opcode == OP_CAT || opcode == OP_SUBSTR ||
opcode == OP_LEFT || opcode == OP_RIGHT ||
opcode == OP_INVERT || opcode == OP_AND ||
opcode == OP_OR || opcode == OP_XOR ||
opcode == OP_2MUL || opcode == OP_2DIV ||
opcode == OP_MUL || opcode == OP_DIV ||
opcode == OP_MOD || opcode == OP_LSHIFT ||
opcode == OP_RSHIFT || opcode == OP_VER)
{
return set_error(serror, SCRIPT_ERR_DISABLED_OPCODE);
}
The check happens at opcode processing time, but it is applied even to opcodes in branches that fExec (the execution flag) would otherwise skip.
Comparison with OP_RESERVED
OP_RESERVED (0x50):
- Fails only if executed (i.e., in active branch)
- Safe in dead branches (OP_FALSE OP_IF OP_RESERVED OP_ENDIF succeeds)
- Use case: delineating script templates, future upgrades
OP_VER (0x62):
- Fails unconditionally (in any branch, executed or not)
- Identical behavior to hard-disabled opcodes
- Use case: none (purely historical artifact)
Can OP_VER Be Re-Enabled?
Re-enabling OP_VER (or any disabled opcode) would require a hard fork, because it would make previously invalid scripts (those containing OP_VER) potentially valid. This is the opposite of a soft fork. For a disabled opcode to become valid again, all nodes in the network would need to upgrade simultaneously to the new rules — a hard fork by definition.
Given that no useful behavior was ever assigned to OP_VER and that its original intent (version-dependent scripts) is widely considered a bad idea, there is no serious proposal to re-enable it.
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: