# 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](https://bsv.brc.dev/scripts/0014): Bitcoin Script Binary and Hex Formats - Ty Everett (<ty@projectbabbage.com>)
