Beersy
BRC-106

Bitcoin Script ASM Format

Every library prints Bitcoin script in a slightly different readable form, so output from one tool is not accepted by another. This fixes one form so scripts can be moved between tools and languages.

About Script encoding, writing a script as text a person can read.

AlsoLocking

Freddie Honohan7 min read

Reference for an AI

Everything an assistant needs to answer questions about BRC-106 accurately, including what it depends on.

Summary

Why
Different code libraries produce inconsistent text representations of the same Bitcoin Script, which breaks comparisons and interoperability across tools.
What
BRC-106 is a standard that fixes exactly which text name each Bitcoin Script opcode must use when converted to and from its human-readable form.
How
A library parses any valid alias of an opcode (such as OP_0 or ) into the same underlying byte, but always outputs the single designated human-readable name (such as OP_FALSE) when converting that byte back to ASM text.

What this lets you do

  • Parse any known opcode alias into its correct byte value
  • Serialize a script to ASM using one consistent name per opcode
  • Compare ASM output from different libraries and expect a byte-for-byte match
  • Look up any opcode's canonical ASM name and hex value in a shared table

Written by claude-sonnet-5 from the specification text. Where the two differ, the original is correct.

opcode aliascanonical nameasm text

The specification

Abstract

This proposal introduces a standardised method of dealing with the representation of Bitcoin Script across the 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
  1. Other discrepancies were found and documented here 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:
   // 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
  1. 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:
   // Input hex, always outputs human-readable form
   toASM(0x00)  // "OP_FALSE" (not "OP_0")
   toASM(0x51)  // "OP_TRUE"  (not "OP_1")
  1. Full Op-Code to Hex Table With Statuses
IndexWordHexLegacyChronicles
00x00✅✅
1-75OP_PUSHDATA0x01-0x4b✅✅
76OP_PUSHDATA10x4c✅✅
77OP_PUSHDATA20x4d✅✅
78OP_PUSHDATA40x4e✅✅
79OP_1NEGATE0x4f✅✅
80OP_RESERVED0x50ReservedReserved
810x51✅✅
82OP_20x52✅✅
83OP_30x53✅✅
84OP_40x54✅✅
85OP_50x55✅✅
86OP_60x56✅✅
87OP_70x57✅✅
88OP_80x58✅✅
89OP_90x59✅✅
90OP_100x5a✅✅
91OP_110x5b✅✅
92OP_120x5c✅✅
93OP_130x5d✅✅
94OP_140x5e✅✅
95OP_150x5f✅✅
96OP_160x60✅✅
97OP_NOP0x61✅✅
98OP_VER0x62❌✅
99OP_IF0x63✅✅
100OP_NOTIF0x64✅✅
101OP_VERIF0x65❌✅
102OP_VERNOTIF0x66❌✅
103OP_ELSE0x67✅✅
104OP_ENDIF0x68✅✅
105OP_VERIFY0x69✅✅
1060x6a✅✅
107OP_TOALTSTACK0x6b✅✅
108OP_FROMALTSTACK0x6c✅✅
109OP_2DROP0x6d✅✅
110OP_2DUP0x6e✅✅
111OP_3DUP0x6f✅✅
112OP_2OVER0x70✅✅
113OP_2ROT0x71✅✅
114OP_2SWAP0x72✅✅
115OP_IFDUP0x73✅✅
116OP_DEPTH0x74✅✅
117OP_DROP0x75✅✅
118OP_DUP0x76✅✅
119OP_NIP0x77✅✅
120OP_OVER0x78✅✅
121OP_PICK0x79✅✅
122OP_ROLL0x7a✅✅
123OP_ROT0x7b✅✅
124OP_SWAP0x7c✅✅
125OP_TUCK0x7d✅✅
126OP_CAT0x7e✅✅
127OP_SPLIT0x7f✅✅
128OP_NUM2BIN0x80✅✅
129OP_BIN2NUM0x81✅✅
130OP_SIZE0x82✅✅
131OP_INVERT0x83✅✅
132OP_AND0x84✅✅
133OP_OR0x85✅✅
134OP_XOR0x86✅✅
135OP_EQUAL0x87✅✅
136OP_EQUALVERIFY0x88✅✅
137OP_RESERVED10x89ReservedReserved
138OP_RESERVED20x8aReservedReserved
139OP_1ADD0x8b✅✅
140OP_1SUB0x8c✅✅
141OP_2MUL0x8d❌✅
142OP_2DIV0x8e❌✅
143OP_NEGATE0x8f✅✅
144OP_ABS0x90✅✅
145OP_NOT0x91✅✅
146OP_0NOTEQUAL0x92✅✅
147OP_ADD0x93✅✅
148OP_SUB0x94✅✅
149OP_MUL0x95✅✅
150OP_DIV0x96✅✅
151OP_MOD0x97✅✅
152OP_LSHIFT0x98✅✅
153OP_RSHIFT0x99✅✅
154OP_BOOLAND0x9a✅✅
155OP_BOOLOR0x9b✅✅
156OP_NUMEQUAL0x9c✅✅
157OP_NUMEQUALVERIFY0x9d✅✅
158OP_NUMNOTEQUAL0x9e✅✅
159OP_LESSTHAN0x9f✅✅
160OP_GREATERTHAN0xa0✅✅
161OP_LESSTHANOREQUAL0xa1✅✅
162OP_GREATERTHANOREQUAL0xa2✅✅
163OP_MIN0xa3✅✅
164OP_MAX0xa4✅✅
165OP_WITHIN0xa5✅✅
166OP_RIPEMD1600xa6✅✅
167OP_SHA10xa7✅✅
168OP_SHA2560xa8✅✅
169OP_0xa9✅✅
170OP_HASH2560xaa✅✅
171OP_CODESEPARATOR0xab✅✅
172OP_CHECKSIG0xac✅✅
173OP_CHECKSIGVERIFY0xad✅✅
174OP_CHECKMULTISIG0xae✅✅
175OP_CHECKMULTISIGVERIFY0xaf✅✅
176OP_NOP10xb0✅✅
177OP_NOP20xb1✅✅
178OP_NOP30xb2✅✅
179OP_SUBSTR0xb3❌✅
180OP_LEFT0xb4❌✅
181OP_RIGHT0xb5❌✅
182OP_NOP40xb6✅✅
183OP_NOP50xb7✅✅
184OP_NOP60xb8✅✅
185OP_NOP70xb9✅✅
186OP_NOP80xba✅✅
187OP_NOP90xbb✅✅
188OP_NOP100xbc✅✅
253OP_PUBKEYHASH0xfdPseudoPseudo
254OP_PUBKEY0xfePseudoPseudo
255OP_INVALIDOPCODE0xffInvalidInvalid

References

Was this helpful?

Search Beersy

Search standards by number, title, author or topic