# Bitcoin Script ASM Format

Freddie Honohan (<freddie@yenpoint.jp>)

## Abstract

This proposal introduces a standardised method of dealing with the ASM representation of Bitcoin Script across the ecosystem language libraries (Py-SDK, TS-SDK, Go-SDK, Teranode etc).

## Motivation

The purpose of this proposal is to provide a generalised standard in order for deterministic translation of Bitcoin Script to and from ASM for cross-language compatibility.

Currently, different implementations may produce inconsistent ASM representations for the same script. For example, the boolean value `false` might be rendered as `OP_0`, `OP_FALSE` depending on the library used. This lack of standardisation creates interoperability issues when scripts are shared across different tools and platforms.

## Specification

1. It is important that ASM format scripts operate correctly regardless of where they were produced or processed.
2. The Hexadecimal and Binary representations are defined in BRC-14.
3. Since ASM format is primarily used for human-readability, op-codes with multiple representations like the boolean pair `[OP_0, OP_1]` are to be represented as their english full-name counterpart e.g. `[OP_FALSE, OP_TRUE]` **Example:**

```
   Hex:  0x00 0x51
   ASM:  OP_FALSE OP_TRUE
   Not:  OP_0 OP_1
```

4. Other discrepancies were found and documented [here](https://docs.google.com/spreadsheets/d/106aSWsOeNayzXOU9tRmRIvSu2Cz21YZQ5uCrwMZg1WU/) and rules are set out below to deal with them.

## Implementation

1. The logic dealing with Bitcoin Script ASM is to be standardised across libraries and languages as described hereunder.
2. Op-Codes with several names must be parsed into the correct hex/binary byte despite the chosen ASM format name. **Example Input Parsing:**

```javascript
   // All of these should parse to 0x00
   parseASM("OP_0")      // ✓ valid
   parseASM("OP_FALSE")  // ✓ valid
   
   // Both should output the same hex
   parseASM("OP_0") === parseASM("OP_FALSE")  // true
```

3. However op-codes with several names must be output into the most human-readable format (e.g. `OP_0` will always output as `OP_FALSE`). **Example Output Serialization:**

```javascript
   // Input hex, always outputs human-readable form
   toASM(0x00)  // "OP_FALSE" (not "OP_0")
   toASM(0x51)  // "OP_TRUE"  (not "OP_1")
```

4. Full Op-Code to Hex Table With Statuses

| Index | Word                    | Hex       | Legacy   | Chronicles |
| ----- | ----------------------- | --------- | -------- | ---------- |
| 0     | OP\_FALSE               | 0x00      | ✅        | ✅          |
| 1-75  | OP\_PUSHDATA            | 0x01-0x4b | ✅        | ✅          |
| 76    | OP\_PUSHDATA1           | 0x4c      | ✅        | ✅          |
| 77    | OP\_PUSHDATA2           | 0x4d      | ✅        | ✅          |
| 78    | OP\_PUSHDATA4           | 0x4e      | ✅        | ✅          |
| 79    | OP\_1NEGATE             | 0x4f      | ✅        | ✅          |
| 80    | OP\_RESERVED            | 0x50      | Reserved | Reserved   |
| 81    | OP\_TRUE                | 0x51      | ✅        | ✅          |
| 82    | OP\_2                   | 0x52      | ✅        | ✅          |
| 83    | OP\_3                   | 0x53      | ✅        | ✅          |
| 84    | OP\_4                   | 0x54      | ✅        | ✅          |
| 85    | OP\_5                   | 0x55      | ✅        | ✅          |
| 86    | OP\_6                   | 0x56      | ✅        | ✅          |
| 87    | OP\_7                   | 0x57      | ✅        | ✅          |
| 88    | OP\_8                   | 0x58      | ✅        | ✅          |
| 89    | OP\_9                   | 0x59      | ✅        | ✅          |
| 90    | OP\_10                  | 0x5a      | ✅        | ✅          |
| 91    | OP\_11                  | 0x5b      | ✅        | ✅          |
| 92    | OP\_12                  | 0x5c      | ✅        | ✅          |
| 93    | OP\_13                  | 0x5d      | ✅        | ✅          |
| 94    | OP\_14                  | 0x5e      | ✅        | ✅          |
| 95    | OP\_15                  | 0x5f      | ✅        | ✅          |
| 96    | OP\_16                  | 0x60      | ✅        | ✅          |
| 97    | OP\_NOP                 | 0x61      | ✅        | ✅          |
| 98    | OP\_VER                 | 0x62      | ❌        | ✅          |
| 99    | OP\_IF                  | 0x63      | ✅        | ✅          |
| 100   | OP\_NOTIF               | 0x64      | ✅        | ✅          |
| 101   | OP\_VERIF               | 0x65      | ❌        | ✅          |
| 102   | OP\_VERNOTIF            | 0x66      | ❌        | ✅          |
| 103   | OP\_ELSE                | 0x67      | ✅        | ✅          |
| 104   | OP\_ENDIF               | 0x68      | ✅        | ✅          |
| 105   | OP\_VERIFY              | 0x69      | ✅        | ✅          |
| 106   | OP\_RETURN              | 0x6a      | ✅        | ✅          |
| 107   | OP\_TOALTSTACK          | 0x6b      | ✅        | ✅          |
| 108   | OP\_FROMALTSTACK        | 0x6c      | ✅        | ✅          |
| 109   | OP\_2DROP               | 0x6d      | ✅        | ✅          |
| 110   | OP\_2DUP                | 0x6e      | ✅        | ✅          |
| 111   | OP\_3DUP                | 0x6f      | ✅        | ✅          |
| 112   | OP\_2OVER               | 0x70      | ✅        | ✅          |
| 113   | OP\_2ROT                | 0x71      | ✅        | ✅          |
| 114   | OP\_2SWAP               | 0x72      | ✅        | ✅          |
| 115   | OP\_IFDUP               | 0x73      | ✅        | ✅          |
| 116   | OP\_DEPTH               | 0x74      | ✅        | ✅          |
| 117   | OP\_DROP                | 0x75      | ✅        | ✅          |
| 118   | OP\_DUP                 | 0x76      | ✅        | ✅          |
| 119   | OP\_NIP                 | 0x77      | ✅        | ✅          |
| 120   | OP\_OVER                | 0x78      | ✅        | ✅          |
| 121   | OP\_PICK                | 0x79      | ✅        | ✅          |
| 122   | OP\_ROLL                | 0x7a      | ✅        | ✅          |
| 123   | OP\_ROT                 | 0x7b      | ✅        | ✅          |
| 124   | OP\_SWAP                | 0x7c      | ✅        | ✅          |
| 125   | OP\_TUCK                | 0x7d      | ✅        | ✅          |
| 126   | OP\_CAT                 | 0x7e      | ✅        | ✅          |
| 127   | OP\_SPLIT               | 0x7f      | ✅        | ✅          |
| 128   | OP\_NUM2BIN             | 0x80      | ✅        | ✅          |
| 129   | OP\_BIN2NUM             | 0x81      | ✅        | ✅          |
| 130   | OP\_SIZE                | 0x82      | ✅        | ✅          |
| 131   | OP\_INVERT              | 0x83      | ✅        | ✅          |
| 132   | OP\_AND                 | 0x84      | ✅        | ✅          |
| 133   | OP\_OR                  | 0x85      | ✅        | ✅          |
| 134   | OP\_XOR                 | 0x86      | ✅        | ✅          |
| 135   | OP\_EQUAL               | 0x87      | ✅        | ✅          |
| 136   | OP\_EQUALVERIFY         | 0x88      | ✅        | ✅          |
| 137   | OP\_RESERVED1           | 0x89      | Reserved | Reserved   |
| 138   | OP\_RESERVED2           | 0x8a      | Reserved | Reserved   |
| 139   | OP\_1ADD                | 0x8b      | ✅        | ✅          |
| 140   | OP\_1SUB                | 0x8c      | ✅        | ✅          |
| 141   | OP\_2MUL                | 0x8d      | ❌        | ✅          |
| 142   | OP\_2DIV                | 0x8e      | ❌        | ✅          |
| 143   | OP\_NEGATE              | 0x8f      | ✅        | ✅          |
| 144   | OP\_ABS                 | 0x90      | ✅        | ✅          |
| 145   | OP\_NOT                 | 0x91      | ✅        | ✅          |
| 146   | OP\_0NOTEQUAL           | 0x92      | ✅        | ✅          |
| 147   | OP\_ADD                 | 0x93      | ✅        | ✅          |
| 148   | OP\_SUB                 | 0x94      | ✅        | ✅          |
| 149   | OP\_MUL                 | 0x95      | ✅        | ✅          |
| 150   | OP\_DIV                 | 0x96      | ✅        | ✅          |
| 151   | OP\_MOD                 | 0x97      | ✅        | ✅          |
| 152   | OP\_LSHIFT              | 0x98      | ✅        | ✅          |
| 153   | OP\_RSHIFT              | 0x99      | ✅        | ✅          |
| 154   | OP\_BOOLAND             | 0x9a      | ✅        | ✅          |
| 155   | OP\_BOOLOR              | 0x9b      | ✅        | ✅          |
| 156   | OP\_NUMEQUAL            | 0x9c      | ✅        | ✅          |
| 157   | OP\_NUMEQUALVERIFY      | 0x9d      | ✅        | ✅          |
| 158   | OP\_NUMNOTEQUAL         | 0x9e      | ✅        | ✅          |
| 159   | OP\_LESSTHAN            | 0x9f      | ✅        | ✅          |
| 160   | OP\_GREATERTHAN         | 0xa0      | ✅        | ✅          |
| 161   | OP\_LESSTHANOREQUAL     | 0xa1      | ✅        | ✅          |
| 162   | OP\_GREATERTHANOREQUAL  | 0xa2      | ✅        | ✅          |
| 163   | OP\_MIN                 | 0xa3      | ✅        | ✅          |
| 164   | OP\_MAX                 | 0xa4      | ✅        | ✅          |
| 165   | OP\_WITHIN              | 0xa5      | ✅        | ✅          |
| 166   | OP\_RIPEMD160           | 0xa6      | ✅        | ✅          |
| 167   | OP\_SHA1                | 0xa7      | ✅        | ✅          |
| 168   | OP\_SHA256              | 0xa8      | ✅        | ✅          |
| 169   | OP\_HASH160             | 0xa9      | ✅        | ✅          |
| 170   | OP\_HASH256             | 0xaa      | ✅        | ✅          |
| 171   | OP\_CODESEPARATOR       | 0xab      | ✅        | ✅          |
| 172   | OP\_CHECKSIG            | 0xac      | ✅        | ✅          |
| 173   | OP\_CHECKSIGVERIFY      | 0xad      | ✅        | ✅          |
| 174   | OP\_CHECKMULTISIG       | 0xae      | ✅        | ✅          |
| 175   | OP\_CHECKMULTISIGVERIFY | 0xaf      | ✅        | ✅          |
| 176   | OP\_NOP1                | 0xb0      | ✅        | ✅          |
| 177   | OP\_NOP2                | 0xb1      | ✅        | ✅          |
| 178   | OP\_NOP3                | 0xb2      | ✅        | ✅          |
| 179   | OP\_SUBSTR              | 0xb3      | ❌        | ✅          |
| 180   | OP\_LEFT                | 0xb4      | ❌        | ✅          |
| 181   | OP\_RIGHT               | 0xb5      | ❌        | ✅          |
| 182   | OP\_NOP4                | 0xb6      | ✅        | ✅          |
| 183   | OP\_NOP5                | 0xb7      | ✅        | ✅          |
| 184   | OP\_NOP6                | 0xb8      | ✅        | ✅          |
| 185   | OP\_NOP7                | 0xb9      | ✅        | ✅          |
| 186   | OP\_NOP8                | 0xba      | ✅        | ✅          |
| 187   | OP\_NOP9                | 0xbb      | ✅        | ✅          |
| 188   | OP\_NOP10               | 0xbc      | ✅        | ✅          |
| 253   | OP\_PUBKEYHASH          | 0xfd      | Pseudo   | Pseudo     |
| 254   | OP\_PUBKEY              | 0xfe      | Pseudo   | Pseudo     |
| 255   | OP\_INVALIDOPCODE       | 0xff      | Invalid  | Invalid    |

## References

* [BRC-14](/scripts/0014.md): Bitcoin Script Binary and Hex Formats - Ty Everett (<ty@projectbabbage.com>)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bsv.brc.dev/scripts/0106.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
