> For the complete documentation index, see [llms.txt](https://protocol.bsvblockchain.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://protocol.bsvblockchain.org/specification/opcodes.md).

# Opcodes

Every Script opcode — value, operand, stack effect, and era status

This page is the reference for every Script word (opcode) recognised by the BSV protocol: its exact byte value, how many script bytes its operand occupies, its effect on the stack, and the protocol era in which it is enabled, disabled, or re-instated.

**Ground truth.** Every opcode value on this page derives from `enum opcodetype` in [`src/script/opcodes.h`](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/opcodes.h#L10). Per-opcode stack behaviour and era gating derive from `EvalScript` in [`src/script/interpreter.cpp`](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/interpreter.cpp#L388). All citations are pinned to release **v1.2.2** (commit `879fc8b`).

## How to read this page

Every opcode table has the following columns:

| Column                   | Meaning                                                                                                                                                                                                                                                                                                                       |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Word**                 | The opcode mnemonic. Where two names share a value (e.g. `OP_0`/`OP_FALSE`), both are given.                                                                                                                                                                                                                                  |
| **Decimal**              | The opcode's value in decimal.                                                                                                                                                                                                                                                                                                |
| **Hex**                  | The opcode's value as a single byte in hexadecimal.                                                                                                                                                                                                                                                                           |
| **Operand (bytes read)** | How many **additional** script bytes the interpreter consumes *from the script stream* for this opcode's operand, and how the length is encoded. This concerns only the leading push opcodes; for every other opcode it is **none** (the opcode is a single byte and takes all its arguments from the stack, not the script). |
| **Input**                | Stack items consumed, top of stack rightmost. An item annotated **(num)** is interpreted as a number, not a raw byte array — see [Numeric arguments](#numeric-arguments) for the encoding and size rules.                                                                                                                     |
| **Output**               | Stack items produced, top of stack rightmost.                                                                                                                                                                                                                                                                                 |
| **Description**          | Precise behaviour, including failure conditions.                                                                                                                                                                                                                                                                              |
| **Status by era**        | Whether the opcode is enabled, disabled, or a no-op in each protocol era (see [Protocol eras](#protocol-eras)).                                                                                                                                                                                                               |

**Truth values.** *False* is a zero-length array, a value that is all zero bytes, or a value that is zero bytes followed by a sign byte of `0x80` (negative zero). *True* is anything else.

### Numeric arguments

Wherever a stack item is consumed as a **number** (marked **(num)** in the Input column — e.g. the shift count of `OP_LSHIFTNUM`, the position of `OP_SPLIT`, the `start`/`length` of `OP_SUBSTR`, or the operands of the arithmetic opcodes) it is decoded as a `CScriptNum` ([`src/script/script_num.h`](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/script_num.h#L42-L96)):

* **Encoding:** little-endian, sign-magnitude — the most-significant bit of the last byte is the sign, so the value is negative when that bit is set.
* **Minimal encoding:** when minimal-data enforcement is active, a number must use the fewest possible bytes (no redundant trailing `0x00`/`0x80`), otherwise the script fails. From Chronicle, transactions with version > 1 may opt out of this check (see [Script](/specification/script.md)).
* **Maximum length** of the *serialized* number, by era (`MaxScriptNumLength`, [`src/consensus/consensus.h`](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/consensus/consensus.h#L62-L66)): **4 bytes** Pre-Genesis (range `[−2³¹+1, 2³¹−1]`), **750,000 bytes** Genesis, **32 MB** Chronicle. A number longer than the era limit is rejected.
* **Integer domain:** when a number is used as a machine integer (e.g. a length or index, via `getint`/`getint64`) it must fit in a signed 64-bit integer (`INT64_SERIALIZED_SIZE = 9` bytes on the wire, including the sign byte); a value outside that domain, or one that fails an opcode's own range test, fails the script with `SCRIPT_ERR_INVALID_NUMBER_RANGE`.

Stack items that are *not* marked **(num)** (e.g. the source string of `OP_SUBSTR`, the inputs to `OP_CAT`, a signature or public key) are treated as raw byte arrays and are **not** subject to the numeric-length limit above — only to the element/ stack-memory limits described in [Script](/specification/script.md).

### Protocol eras

The interpreter recognises three eras, selected per input from the era in force when the **spent UTXO** was confirmed (the "UTXO height" rule; the Protocol Upgrade History page will catalogue the activation heights):

| Era             | Mainnet activation   | Meaning                                             |
| --------------- | -------------------- | --------------------------------------------------- |
| **Pre-Genesis** | before block 620,538 | Original rules with the 2017–2018 upgrades applied. |
| **Genesis**     | height ≥ 620,538     | Genesis upgrade (2020-02-04).                       |
| **Chronicle**   | height ≥ 943,816     | Chronicle upgrade (2026-04-07).                     |

In the source these correspond to `ProtocolEra::PreGenesis`, `PostGenesis`, and `PostChronicle`, resolved from the script flags at the top of [`EvalScript`](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/interpreter.cpp#L411).

## Constants (push opcodes)

These value-pushing words place data onto the stack. They are the only opcodes that read operand bytes from the script; see [Push-data operands](#push-data-operands-detail) for the byte-exact encoding.

| Word               | Decimal | Hex       | Operand (bytes read)                                                | Input | Output  | Description                                                                          | Status by era |
| ------------------ | ------- | --------- | ------------------------------------------------------------------- | ----- | ------- | ------------------------------------------------------------------------------------ | ------------- |
| `OP_0`, `OP_FALSE` | 0       | 0x00      | none                                                                | —     | (empty) | Pushes an empty byte array. Not a no-op: an item **is** added to the stack.          | All           |
| (direct push)      | 1–75    | 0x01–0x4b | the operand **is** the next *N* bytes, where *N* = the opcode value | —     | data    | Push the next *opcode-value* bytes as one stack item. No separate length field.      | All           |
| `OP_PUSHDATA1`     | 76      | 0x4c      | 1 length byte, then that many data bytes                            | —     | data    | Next **1 byte** is the length; then that many data bytes are pushed.                 | All           |
| `OP_PUSHDATA2`     | 77      | 0x4d      | 2 length bytes (LE), then data                                      | —     | data    | Next **2 bytes** little-endian are the length; then that many data bytes are pushed. | All           |
| `OP_PUSHDATA4`     | 78      | 0x4e      | 4 length bytes (LE), then data                                      | —     | data    | Next **4 bytes** little-endian are the length; then that many data bytes are pushed. | All           |
| `OP_1NEGATE`       | 79      | 0x4f      | none                                                                | —     | -1      | Pushes the number −1.                                                                | All           |
| `OP_1`, `OP_TRUE`  | 81      | 0x51      | none                                                                | —     | 1       | Pushes the number 1.                                                                 | All           |
| `OP_2`–`OP_16`     | 82–96   | 0x52–0x60 | none                                                                | —     | 2–16    | Pushes the number named in the word (2–16).                                          | All           |

*(source:* [*`opcodes.h` L13–L36*](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/opcodes.h#L13-L36)*; push decode:* [*`script.h`* *`GetOp2` L163*](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/script.h#L163-L198)*)*

## Flow control

| Word          | Decimal | Hex  | Operand | Input | Output       | Description                                                                                                       | Status by era                                                                                                                                                         |
| ------------- | ------- | ---- | ------- | ----- | ------------ | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `OP_NOP`      | 97      | 0x61 | none    | —     | —            | Does nothing.                                                                                                     | All                                                                                                                                                                   |
| `OP_VER`      | 98      | 0x62 | none    | —     | tx version   | Pushes the spending transaction's version (4-byte LE) onto the stack.                                             | Pre-Genesis / Genesis: **invalid** (`SCRIPT_ERR_BAD_OPCODE`). Chronicle: **enabled**.                                                                                 |
| `OP_IF`       | 99      | 0x63 | none    | value | —            | If the top value is true, the following branch executes. The top value is removed. Must be closed by `OP_ENDIF`.  | All                                                                                                                                                                   |
| `OP_NOTIF`    | 100     | 0x64 | none    | value | —            | If the top value is false, the following branch executes. The top value is removed. Must be closed by `OP_ENDIF`. | All                                                                                                                                                                   |
| `OP_VERIF`    | 101     | 0x65 | none    | value | —            | Chronicle: as `OP_IF` but the condition is "top item equals the tx version (4-byte LE)".                          | Pre-Genesis / Genesis: **invalid** if executed (`SCRIPT_ERR_BAD_OPCODE`). Chronicle: **enabled**.                                                                     |
| `OP_VERNOTIF` | 102     | 0x66 | none    | value | —            | Chronicle: negated `OP_VERIF`.                                                                                    | Pre-Genesis / Genesis: **invalid** if executed. Chronicle: **enabled**.                                                                                               |
| `OP_ELSE`     | 103     | 0x67 | none    | —     | —            | Executes if the matching `OP_IF`/`OP_NOTIF` branch did not.                                                       | All                                                                                                                                                                   |
| `OP_ENDIF`    | 104     | 0x68 | none    | —     | —            | Ends an `OP_IF`/`OP_NOTIF`/`OP_ELSE` block. An unbalanced conditional makes the script invalid.                   | All                                                                                                                                                                   |
| `OP_VERIFY`   | 105     | 0x69 | none    | value | — / *fail*   | Fails the script if the top value is not true; otherwise removes it.                                              | All                                                                                                                                                                   |
| `OP_RETURN`   | 106     | 0x6a | none    | —     | *terminates* | See [OP\_RETURN semantics](#opreturn-semantics).                                                                  | Pre-Genesis: fails the script (`SCRIPT_ERR_OP_RETURN`). Genesis / Chronicle: terminates evaluation; at top level the script succeeds and remaining bytes are ignored. |

*(source:* [*`opcodes.h` L39–L48*](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/opcodes.h#L39-L48)*; gating:* [*`interpreter.cpp`* *`EvalScript`*](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/interpreter.cpp#L388)*)*

## Stack

| Word              | Decimal | Hex  | Operand | Input                     | Output                  | Description                                                                         | Status by era |
| ----------------- | ------- | ---- | ------- | ------------------------- | ----------------------- | ----------------------------------------------------------------------------------- | ------------- |
| `OP_TOALTSTACK`   | 107     | 0x6b | none    | x1                        | (alt) x1                | Moves the top item to the alt stack.                                                | All           |
| `OP_FROMALTSTACK` | 108     | 0x6c | none    | (alt) x1                  | x1                      | Moves the top alt-stack item to the main stack.                                     | All           |
| `OP_2DROP`        | 109     | 0x6d | none    | x1 x2                     | —                       | Removes the top two items.                                                          | All           |
| `OP_2DUP`         | 110     | 0x6e | none    | x1 x2                     | x1 x2 x1 x2             | Duplicates the top two items.                                                       | All           |
| `OP_3DUP`         | 111     | 0x6f | none    | x1 x2 x3                  | x1 x2 x3 x1 x2 x3       | Duplicates the top three items.                                                     | All           |
| `OP_2OVER`        | 112     | 0x70 | none    | x1 x2 x3 x4               | x1 x2 x3 x4 x1 x2       | Copies the pair two back to the top.                                                | All           |
| `OP_2ROT`         | 113     | 0x71 | none    | x1 x2 x3 x4 x5 x6         | x3 x4 x5 x6 x1 x2       | Moves the fifth/sixth items to the top.                                             | All           |
| `OP_2SWAP`        | 114     | 0x72 | none    | x1 x2 x3 x4               | x3 x4 x1 x2             | Swaps the top two pairs.                                                            | All           |
| `OP_IFDUP`        | 115     | 0x73 | none    | x                         | x / x x                 | Duplicates the top item if it is not zero.                                          | All           |
| `OP_DEPTH`        | 116     | 0x74 | none    | —                         | \<stack size> **(num)** | Pushes the current stack depth as a number.                                         | All           |
| `OP_DROP`         | 117     | 0x75 | none    | x                         | —                       | Removes the top item.                                                               | All           |
| `OP_DUP`          | 118     | 0x76 | none    | x                         | x x                     | Duplicates the top item.                                                            | All           |
| `OP_NIP`          | 119     | 0x77 | none    | x1 x2                     | x2                      | Removes the second-from-top item.                                                   | All           |
| `OP_OVER`         | 120     | 0x78 | none    | x1 x2                     | x1 x2 x1                | Copies the second-from-top item to the top.                                         | All           |
| `OP_PICK`         | 121     | 0x79 | none    | xn … x1 x0 \<n> **(num)** | xn … x1 x0 xn           | Copies the item *n* back to the top. Fails if *n* is negative or ≥ the stack depth. | All           |
| `OP_ROLL`         | 122     | 0x7a | none    | xn … x1 x0 \<n> **(num)** | … x1 x0 xn              | Moves the item *n* back to the top. Fails if *n* is negative or ≥ the stack depth.  | All           |
| `OP_ROT`          | 123     | 0x7b | none    | x1 x2 x3                  | x2 x3 x1                | Rotates the top three items left.                                                   | All           |
| `OP_SWAP`         | 124     | 0x7c | none    | x1 x2                     | x2 x1                   | Swaps the top two items.                                                            | All           |
| `OP_TUCK`         | 125     | 0x7d | none    | x1 x2                     | x2 x1 x2                | Copies the top item behind the second item.                                         | All           |

*(source:* [*`opcodes.h` L51–L69*](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/opcodes.h#L51-L69)*)*

## Data manipulation

| Word         | Decimal | Hex  | Operand | Input                   | Output            | Description                                                                                                                                                                                      | Status by era          |
| ------------ | ------- | ---- | ------- | ----------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------- |
| `OP_CAT`     | 126     | 0x7e | none    | x1 x2                   | out               | Concatenates byte arrays x1 and x2. Pre-Genesis the result must be ≤ 520 bytes (else `SCRIPT_ERR_PUSH_SIZE`).                                                                                    | Enabled from May 2018. |
| `OP_SPLIT`   | 127     | 0x7f | none    | x n **(num)**           | x1 x2             | Splits byte array *x* into `x1 = x[0:n]` and `x2 = x[n:]`. Fails (`SCRIPT_ERR_INVALID_SPLIT_RANGE`) if `n < 0` or `n > len(x)`.                                                                  | Enabled from May 2018. |
| `OP_NUM2BIN` | 128     | 0x80 | none    | a **(num)** b **(num)** | out               | Encodes numeric value *a* as a byte array of length *b*. Fails (`SCRIPT_ERR_IMPOSSIBLE_ENCODING`) if *a* does not fit in *b* bytes; Pre-Genesis *b* must also be ≤ 520 (`SCRIPT_ERR_PUSH_SIZE`). | Enabled from May 2018. |
| `OP_BIN2NUM` | 129     | 0x81 | none    | x                       | out **(num)**     | Minimally re-encodes byte array *x* as a number. Fails if the result exceeds the era's max script-number length.                                                                                 | Enabled from May 2018. |
| `OP_SIZE`    | 130     | 0x82 | none    | in                      | in size **(num)** | Pushes the byte length of the top item (as a number) without removing it.                                                                                                                        | All                    |

*(source:* [*`opcodes.h` L72–L76*](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/opcodes.h#L72-L76)*. The May-2018 re-enable date is historical, sourced from the consensus specs; the v1.2.2 interpreter applies no era gate to these opcodes.)*

## Bitwise logic

| Word             | Decimal | Hex  | Operand | Input | Output     | Description                                            | Status by era          |
| ---------------- | ------- | ---- | ------- | ----- | ---------- | ------------------------------------------------------ | ---------------------- |
| `OP_INVERT`      | 131     | 0x83 | none    | in    | out        | Flips every bit of the input.                          | Enabled from Nov 2018. |
| `OP_AND`         | 132     | 0x84 | none    | x1 x2 | out        | Bitwise AND. Operands must be equal length.            | Enabled from May 2018. |
| `OP_OR`          | 133     | 0x85 | none    | x1 x2 | out        | Bitwise OR. Operands must be equal length.             | Enabled from May 2018. |
| `OP_XOR`         | 134     | 0x86 | none    | x1 x2 | out        | Bitwise XOR. Operands must be equal length.            | Enabled from May 2018. |
| `OP_EQUAL`       | 135     | 0x87 | none    | x1 x2 | 1 / 0      | Pushes 1 if the two inputs are byte-identical, else 0. | All                    |
| `OP_EQUALVERIFY` | 136     | 0x88 | none    | x1 x2 | — / *fail* | As `OP_EQUAL` then `OP_VERIFY`.                        | All                    |

*(source:* [*`opcodes.h` L79–L86*](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/opcodes.h#L79-L86)*)*

## Arithmetic

Arithmetic operates on numeric values (`CScriptNum`): little-endian, sign-magnitude (the high bit of the last byte is the sign), minimally encoded. Pre-Genesis a numeric operand must be ≤ 4 bytes (range `[−2³¹+1, 2³¹−1]`); from Genesis operands may be up to 750,000 bytes, and from Chronicle up to 32 MB. Byte sequences longer than the numeric-length limit are still valid script data but are not accepted as numbers. See [Script](/specification/script.md) for the number model.

| Word                    | Decimal | Hex  | Operand | Input                                   | Output        | Description                                                                                                                                                                                                  | Status by era                                                                                |
| ----------------------- | ------- | ---- | ------- | --------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------- |
| `OP_1ADD`               | 139     | 0x8b | none    | in **(num)**                            | out **(num)** | Adds 1.                                                                                                                                                                                                      | All                                                                                          |
| `OP_1SUB`               | 140     | 0x8c | none    | in **(num)**                            | out **(num)** | Subtracts 1.                                                                                                                                                                                                 | All                                                                                          |
| `OP_2MUL`               | 141     | 0x8d | none    | in **(num)**                            | out **(num)** | Multiplies by 2.                                                                                                                                                                                             | **Disabled** Pre-Genesis & Genesis (`SCRIPT_ERR_DISABLED_OPCODE`). **Enabled** at Chronicle. |
| `OP_2DIV`               | 142     | 0x8e | none    | in **(num)**                            | out **(num)** | Divides by 2 (rounding toward zero).                                                                                                                                                                         | **Disabled** Pre-Genesis & Genesis (`SCRIPT_ERR_DISABLED_OPCODE`). **Enabled** at Chronicle. |
| `OP_NEGATE`             | 143     | 0x8f | none    | in **(num)**                            | out **(num)** | Flips the sign.                                                                                                                                                                                              | All                                                                                          |
| `OP_ABS`                | 144     | 0x90 | none    | in **(num)**                            | out **(num)** | Absolute value.                                                                                                                                                                                              | All                                                                                          |
| `OP_NOT`                | 145     | 0x91 | none    | in **(num)**                            | out **(num)** | 1 → 0, 0 → 1, else 0.                                                                                                                                                                                        | All                                                                                          |
| `OP_0NOTEQUAL`          | 146     | 0x92 | none    | in **(num)**                            | out **(num)** | 0 → 0, else 1.                                                                                                                                                                                               | All                                                                                          |
| `OP_ADD`                | 147     | 0x93 | none    | a **(num)** b **(num)**                 | out **(num)** | a + b.                                                                                                                                                                                                       | All                                                                                          |
| `OP_SUB`                | 148     | 0x94 | none    | a **(num)** b **(num)**                 | out **(num)** | a − b.                                                                                                                                                                                                       | All                                                                                          |
| `OP_MUL`                | 149     | 0x95 | none    | a **(num)** b **(num)**                 | out **(num)** | a × b.                                                                                                                                                                                                       | Enabled from Nov 2018.                                                                       |
| `OP_DIV`                | 150     | 0x96 | none    | a **(num)** b **(num)**                 | out **(num)** | a ÷ b. Fails on divisor 0 (`SCRIPT_ERR_DIV_BY_ZERO`).                                                                                                                                                        | Enabled from May 2018.                                                                       |
| `OP_MOD`                | 151     | 0x97 | none    | a **(num)** b **(num)**                 | out **(num)** | Remainder of a ÷ b. Fails on divisor 0 (`SCRIPT_ERR_MOD_BY_ZERO`).                                                                                                                                           | Enabled from May 2018.                                                                       |
| `OP_LSHIFT`             | 152     | 0x98 | none    | a b **(num)**                           | out           | Bit-string left shift: shifts the **byte array** *a* left by *b* bits (sign not interpreted). Fails (`SCRIPT_ERR_INVALID_NUMBER_RANGE`) if `b < 0`. Contrast `OP_LSHIFTNUM`, which treats *a* as a number.   | Enabled from Nov 2018.                                                                       |
| `OP_RSHIFT`             | 153     | 0x99 | none    | a b **(num)**                           | out           | Bit-string right shift: shifts the **byte array** *a* right by *b* bits (sign not interpreted). Fails (`SCRIPT_ERR_INVALID_NUMBER_RANGE`) if `b < 0`. Contrast `OP_RSHIFTNUM`, which treats *a* as a number. | Enabled from Nov 2018.                                                                       |
| `OP_BOOLAND`            | 154     | 0x9a | none    | a **(num)** b **(num)**                 | out **(num)** | 1 if both a and b are non-zero, else 0.                                                                                                                                                                      | All                                                                                          |
| `OP_BOOLOR`             | 155     | 0x9b | none    | a **(num)** b **(num)**                 | out **(num)** | 1 if a or b is non-zero, else 0.                                                                                                                                                                             | All                                                                                          |
| `OP_NUMEQUAL`           | 156     | 0x9c | none    | a **(num)** b **(num)**                 | out **(num)** | 1 if numerically equal, else 0.                                                                                                                                                                              | All                                                                                          |
| `OP_NUMEQUALVERIFY`     | 157     | 0x9d | none    | a **(num)** b **(num)**                 | — / *fail*    | As `OP_NUMEQUAL` then `OP_VERIFY`.                                                                                                                                                                           | All                                                                                          |
| `OP_NUMNOTEQUAL`        | 158     | 0x9e | none    | a **(num)** b **(num)**                 | out **(num)** | 1 if numerically unequal, else 0.                                                                                                                                                                            | All                                                                                          |
| `OP_LESSTHAN`           | 159     | 0x9f | none    | a **(num)** b **(num)**                 | out **(num)** | 1 if a < b.                                                                                                                                                                                                  | All                                                                                          |
| `OP_GREATERTHAN`        | 160     | 0xa0 | none    | a **(num)** b **(num)**                 | out **(num)** | 1 if a > b.                                                                                                                                                                                                  | All                                                                                          |
| `OP_LESSTHANOREQUAL`    | 161     | 0xa1 | none    | a **(num)** b **(num)**                 | out **(num)** | 1 if a ≤ b.                                                                                                                                                                                                  | All                                                                                          |
| `OP_GREATERTHANOREQUAL` | 162     | 0xa2 | none    | a **(num)** b **(num)**                 | out **(num)** | 1 if a ≥ b.                                                                                                                                                                                                  | All                                                                                          |
| `OP_MIN`                | 163     | 0xa3 | none    | a **(num)** b **(num)**                 | out **(num)** | Smaller of a and b.                                                                                                                                                                                          | All                                                                                          |
| `OP_MAX`                | 164     | 0xa4 | none    | a **(num)** b **(num)**                 | out **(num)** | Larger of a and b.                                                                                                                                                                                           | All                                                                                          |
| `OP_WITHIN`             | 165     | 0xa5 | none    | x **(num)** min **(num)** max **(num)** | out **(num)** | 1 if min ≤ x < max, else 0.                                                                                                                                                                                  | All                                                                                          |

*(source:* [*`opcodes.h` L89–L118*](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/opcodes.h#L89-L118)*; OP\_2MUL/OP\_2DIV gating:* [*`interpreter.cpp`* *`IsOpcodeDisabled` L360*](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/interpreter.cpp#L360-L375)*. Re-enable dates are historical, from the consensus specs.)*

## Cryptography

| Word                     | Decimal | Hex  | Operand | Input                     | Output     | Description                                                                                                                                     | Status by era |
| ------------------------ | ------- | ---- | ------- | ------------------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `OP_RIPEMD160`           | 166     | 0xa6 | none    | in                        | hash       | RIPEMD-160 of the input.                                                                                                                        | All           |
| `OP_SHA1`                | 167     | 0xa7 | none    | in                        | hash       | SHA-1 of the input.                                                                                                                             | All           |
| `OP_SHA256`              | 168     | 0xa8 | none    | in                        | hash       | SHA-256 of the input.                                                                                                                           | All           |
| `OP_HASH160`             | 169     | 0xa9 | none    | in                        | hash       | RIPEMD-160 of SHA-256 of the input.                                                                                                             | All           |
| `OP_HASH256`             | 170     | 0xaa | none    | in                        | hash       | Double SHA-256 of the input.                                                                                                                    | All           |
| `OP_CODESEPARATOR`       | 171     | 0xab | none    | —                         | —          | Signature checks after this point cover only the script following the most recent `OP_CODESEPARATOR`.                                           | All           |
| `OP_CHECKSIG`            | 172     | 0xac | none    | sig pubkey                | 1 / 0      | Verifies *sig* against *pubkey* over the transaction signature-hash digest (see [Sighash](/specification/signature-hashing.md)). Pushes 1 or 0. | All           |
| `OP_CHECKSIGVERIFY`      | 173     | 0xad | none    | sig pubkey                | — / *fail* | As `OP_CHECKSIG` then `OP_VERIFY`.                                                                                                              | All           |
| `OP_CHECKMULTISIG`       | 174     | 0xae | none    | dummy sig… \<m> pub… \<n> | 1 / 0      | Verifies *m* signatures against *n* pubkeys in order. Consumes one extra dummy item (the historical off-by-one). Pushes 1 or 0.                 | All           |
| `OP_CHECKMULTISIGVERIFY` | 175     | 0xaf | none    | dummy sig… \<m> pub… \<n> | — / *fail* | As `OP_CHECKMULTISIG` then `OP_VERIFY`.                                                                                                         | All           |

*(source:* [*`opcodes.h` L121–L130*](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/opcodes.h#L121-L130)*)*

## Locktime

These occupy former NOP slots. They enforce locktime **only Pre-Genesis** (and only when the matching verify flag is set); from Genesis onward they revert to no-ops, mirroring the restoration of the original `nLockTime`/`nSequence` semantics at the transaction level.

| Word                                 | Decimal | Hex  | Operand | Input           | Output     | Description                                                                                                 | Status by era                                |
| ------------------------------------ | ------- | ---- | ------- | --------------- | ---------- | ----------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| `OP_CHECKLOCKTIMEVERIFY` (`OP_NOP2`) | 177     | 0xb1 | none    | x (Pre-Genesis) | — / *fail* | Pre-Genesis: fails unless the tx `nLockTime` has passed the top stack value (BIP65). Genesis onward: no-op. | Pre-Genesis: CLTV. Genesis / Chronicle: NOP. |
| `OP_CHECKSEQUENCEVERIFY` (`OP_NOP3`) | 178     | 0xb2 | none    | x (Pre-Genesis) | — / *fail* | Pre-Genesis: fails unless the input's relative locktime (BIP68/112) is satisfied. Genesis onward: no-op.    | Pre-Genesis: CSV. Genesis / Chronicle: NOP.  |

*(source:* [*`opcodes.h` L134–L137*](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/opcodes.h#L134-L137)*; gating:* [*`interpreter.cpp`* *`EvalScript`*](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/interpreter.cpp#L519-L597)*)*

## String operations (Chronicle)

`OP_SUBSTR`, `OP_LEFT`, and `OP_RIGHT` occupy the former `OP_NOP4`–`OP_NOP6` slots. Before Chronicle they act as upgradable no-ops; at Chronicle they perform their string function.

| Word        | Decimal | Hex  | Operand | Input                                   | Output    | Description                                                                                                                                                                                                                    | Status by era                                                |
| ----------- | ------- | ---- | ------- | --------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------ |
| `OP_SUBSTR` | 179     | 0xb3 | none    | string start **(num)** length **(num)** | substring | Chronicle: returns the *length*-byte substring of *string* beginning at byte offset *start*. Fails (`SCRIPT_ERR_INVALID_NUMBER_RANGE`) if `start < 0`, `start ≥ len(string)`, `length < 0`, or `length > len(string) − start`. | Pre-Genesis / Genesis: NOP (upgradable). Chronicle: enabled. |
| `OP_LEFT`   | 180     | 0xb4 | none    | string length **(num)**                 | substring | Chronicle: returns the leftmost *length* bytes of *string*. Fails (`SCRIPT_ERR_INVALID_NUMBER_RANGE`) if `length < 0` or `length > len(string)`.                                                                               | Pre-Genesis / Genesis: NOP (upgradable). Chronicle: enabled. |
| `OP_RIGHT`  | 181     | 0xb5 | none    | string length **(num)**                 | substring | Chronicle: returns the rightmost *length* bytes of *string*. Fails (`SCRIPT_ERR_INVALID_NUMBER_RANGE`) if `length < 0` or `length > len(string)`.                                                                              | Pre-Genesis / Genesis: NOP (upgradable). Chronicle: enabled. |

## Numeric shift (Chronicle)

`OP_LSHIFTNUM` and `OP_RSHIFTNUM` occupy the former `OP_NOP7`/`OP_NOP8` slots. Unlike `OP_LSHIFT`/`OP_RSHIFT` (bit-string shifts), these are arithmetic shifts that preserve the numeric sign.

| Word           | Decimal | Hex  | Operand | Input                   | Output        | Description                                                                                                                                                                                     | Status by era                                                |
| -------------- | ------- | ---- | ------- | ----------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ |
| `OP_LSHIFTNUM` | 182     | 0xb6 | none    | a **(num)** b **(num)** | out **(num)** | Chronicle: arithmetic left shift of number *a* by *b* bits, preserving sign. Fails (`SCRIPT_ERR_INVALID_NUMBER_RANGE`) if `b < 0`. The result is bounded by the era's max script-number length. | Pre-Genesis / Genesis: NOP (upgradable). Chronicle: enabled. |
| `OP_RSHIFTNUM` | 183     | 0xb7 | none    | a **(num)** b **(num)** | out **(num)** | Chronicle: arithmetic right shift of number *a* by *b* bits, preserving sign. Fails (`SCRIPT_ERR_INVALID_NUMBER_RANGE`) if `b < 0`.                                                             | Pre-Genesis / Genesis: NOP (upgradable). Chronicle: enabled. |

*(source for the string/shift opcodes:* [*`opcodes.h` L138–L147*](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/opcodes.h#L138-L147)*; gating:* [*`interpreter.cpp`* *`EvalScript`*](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/interpreter.cpp#L609-L763)*. "Upgradable NOP" means the opcode does nothing unless the `DISCOURAGE_UPGRADABLE_NOPS` flag is set, in which case it fails.)*

## Reserved and no-op words

Using a reserved word in an **executed** branch makes the transaction invalid. The remaining pure no-ops are `OP_NOP1` and `OP_NOP9`–`OP_NOP10`; note that the former `OP_NOP4`–`OP_NOP8` (0xb3–0xb7) are now the string/shift opcodes above.

| Word                  | Decimal | Hex       | Description                                                             | Status by era |
| --------------------- | ------- | --------- | ----------------------------------------------------------------------- | ------------- |
| `OP_RESERVED`         | 80      | 0x50      | Invalid unless in an unexecuted `OP_IF` branch.                         | All           |
| `OP_RESERVED1`        | 137     | 0x89      | Invalid unless in an unexecuted `OP_IF` branch.                         | All           |
| `OP_RESERVED2`        | 138     | 0x8a      | Invalid unless in an unexecuted `OP_IF` branch.                         | All           |
| `OP_NOP1`             | 176     | 0xb0      | Ignored (no-op). Fails if the `DISCOURAGE_UPGRADABLE_NOPS` flag is set. | All           |
| `OP_NOP9`, `OP_NOP10` | 184–185 | 0xb8–0xb9 | Ignored (no-op). Fails if the `DISCOURAGE_UPGRADABLE_NOPS` flag is set. | All           |

*(source:* [*`opcodes.h` L19, L85–L86, L133, L148–L149*](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/opcodes.h#L133-L149)*)*

## Pseudo-words

These are used internally for transaction-template matching and are **invalid** if they appear in a real script.

| Word               | Decimal | Hex  | Description                                      |
| ------------------ | ------- | ---- | ------------------------------------------------ |
| `OP_SMALLINTEGER`  | 250     | 0xfa | Matches a small integer push in a template.      |
| `OP_PUBKEYS`       | 251     | 0xfb | Matches a sequence of public keys in a template. |
| `OP_PUBKEYHASH`    | 253     | 0xfd | Matches a public key hashed with `OP_HASH160`.   |
| `OP_PUBKEY`        | 254     | 0xfe | Matches a public key usable by `OP_CHECKSIG`.    |
| `OP_INVALIDOPCODE` | 255     | 0xff | Sentinel for any opcode not yet assigned.        |

*(source:* [*`opcodes.h` L155–L160*](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/opcodes.h#L155-L160)*)*

## Push-data operands (detail)

This is the byte-exact reading of a push operation, from [`CScript::GetOp2`](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/script.h#L163-L198). After reading the leading opcode byte, if the opcode value is `≤ 0x4e` (`OP_PUSHDATA4`) the interpreter reads a length and then that many data bytes:

| Leading opcode | Value         | Length field                                     | Data bytes pushed      |
| -------------- | ------------- | ------------------------------------------------ | ---------------------- |
| direct push    | `0x01`–`0x4b` | none — the **opcode value itself** is the length | 1–75                   |
| `OP_PUSHDATA1` | `0x4c`        | next **1 byte**                                  | value of that byte     |
| `OP_PUSHDATA2` | `0x4d`        | next **2 bytes**, little-endian (`ReadLE16`)     | value of those 2 bytes |
| `OP_PUSHDATA4` | `0x4e`        | next **4 bytes**, little-endian (`ReadLE32`)     | value of those 4 bytes |

If fewer bytes remain in the script than the length field demands, decoding fails and the script is invalid.

### Minimal-push rule

When minimal-encoding is enforced, a data push must use the **shortest** possible encoding, checked by [`CheckMinimalPush`](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/interpreter.cpp#L331-L358):

| Data being pushed  | Required encoding           |
| ------------------ | --------------------------- |
| empty              | `OP_0` (`0x00`)             |
| single byte 1–16   | `OP_1`…`OP_16`              |
| single byte `0x81` | `OP_1NEGATE`                |
| 1–75 bytes         | direct push (`0x01`–`0x4b`) |
| 76–255 bytes       | `OP_PUSHDATA1`              |
| 256–65,535 bytes   | `OP_PUSHDATA2`              |
| larger             | `OP_PUSHDATA4`              |

Minimal-push is enforced as part of script verification (it is active when both `VerifyMinimalData` and non-malleability enforcement apply); from Chronicle, transactions with version > 1 may opt out of this and other malleability checks. See [Script](/specification/script.md).

## OP\_RETURN semantics

`OP_RETURN` (`0x6a`) behaves differently by era ([`interpreter.cpp` `EvalScript`](https://github.com/bitcoin-sv/bitcoin-sv/blob/879fc8b42168dd0e608dafd51b39c6dabad37d4d/src/script/interpreter.cpp#L856-L871)):

* **Pre-Genesis:** encountering `OP_RETURN` in an executed branch immediately fails the script (`SCRIPT_ERR_OP_RETURN`), which is why an `OP_FALSE OP_RETURN <data>` output is provably unspendable.
* **Genesis onward:** at the top level `OP_RETURN` terminates evaluation **successfully** — the rest of the script is ignored, even if it contains unbalanced conditionals or otherwise-invalid opcodes. Inside a conditional it instead flags the script for the grammatical-validity check on the remainder.

A common convention is the `OP_FALSE OP_RETURN <data>` (also written "`OP_0 OP_RETURN`") prefix for carrying data in provably-unspendable outputs.

## Notes

* **All values are consensus.** The opcode set, its byte values, and the era gating above determine transaction validity. Miner-configurable relay limits are **policy**, not protocol, and are out of scope here.
* **Attribution.** Portions of the opcode descriptions derive from the community Bitcoin wiki ([en.bitcoin.it/wiki/Script](https://en.bitcoin.it/wiki/Script), [CC-BY 3.0](https://creativecommons.org/licenses/by/3.0/)) and have been revised and verified against the node source code.
