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.

Freddie Honohan7 min read
opcode aliascanonical nameasm text

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.

Reference for an AI

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

The specification

Abstract

This proposal introduces a standardised method of dealing with the 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
  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