TeachMeBitcoin

OP_WITHIN - Range Check Operation

From TeachMeBitcoin, the free encyclopedia Reading time: 2 min

18. OP_WITHIN — Range Check Operation

Opcode Reference

Opcode:     OP_WITHIN
Hex:        0xA5
Decimal:    165
Input:      x min max
Output:     1 if min <= x < max, else 0

Overview

OP_WITHIN is a three-operand opcode that checks whether a value falls within a half-open interval [min, max). It pops three elements: max (top), min (second), and x (third). It returns 1 if min <= x < max.

Note the asymmetry: the lower bound is inclusive and the upper bound is exclusive.

Stack Layout

Stack before OP_WITHIN (top → bottom):
  [ max | min | x | ... ]

Condition evaluated: min <= x < max

Stack Examples

x=5, min=1, max=10 → Is 1 <= 5 < 10? Yes → [1]
x=1, min=1, max=10 → Is 1 <= 1 < 10? Yes → [1]  (inclusive lower bound)
x=10, min=1, max=10 → Is 1 <= 10 < 10? No → [0]  (exclusive upper bound)
x=0, min=1, max=10  → Is 1 <= 0 < 10? No → [0]
x=-5, min=-10, max=0 → Is -10 <= -5 < 0? Yes → [1]

Bitcoin Core Implementation

case OP_WITHIN:
{
    if (stack.size() < 3)
        return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
    CScriptNum bn1(stacktop(-3), fRequireMinimal);  // x
    CScriptNum bn2(stacktop(-2), fRequireMinimal);  // min
    CScriptNum bn3(stacktop(-1), fRequireMinimal);  // max
    popstack(stack);
    popstack(stack);
    popstack(stack);
    bool fValue = (bn2 <= bn1 && bn1 < bn3);
    stack.push_back(fValue ? vchTrue : vchFalse);
}
break;

Use Cases

OP_WITHIN is one of the most practical arithmetic opcodes for real contracts. It's perfect for:

1. Timelock range validation:

Script: <nLockTime> <earliest> <latest> OP_WITHIN OP_VERIFY
Meaning: Transaction is only valid within a specific time window

2. Amount range checks:

Script: <payment_amount> <min_payment> <max_payment> OP_WITHIN OP_VERIFY

3. Sequence / counter validation:

Script: <counter> <0> <100> OP_WITHIN OP_VERIFY
Meaning: Counter must be between 0 (inclusive) and 100 (exclusive)

The half-open interval semantics [min, max) are borrowed from common interval conventions in mathematics and computing, making range chaining intuitive:

Range [0, 10) and [10, 20) together cover [0, 20) without overlap.
☕ 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!