Skip to content

Write an unnamed opcode in ASM as its raw byte, 0xba - #4

Merged
codenlighten merged 1 commit into
mainfrom
asm-raw-opcodes
Sep 17, 2026
Merged

codenlighten merged 1 commit into
mainfrom
asm-raw-opcodes

Conversation

@codenlighten

Copy link
Copy Markdown
Owner

Follow-up to #3, after @smartledger/bsv 9.11.1 (codenlighten/smartledger-bsv#175).

Change

  • toAsm(ops, { bare: true }), and so exactAsm and --asm -o, writes an opcode with no name (0xba0xfc) as 0xba, the form bsv 9.11.1 writes and reads. It used to write OP_UNKNOWN186, which nothing reads, so every such script was refused.
  • The read-back check is unchanged. With a peer @smartledger/bsv older than 9.11.1, fromASM('0xba') throws, so the script is still refused, and the message now says which version reads it back.
  • The display form (--explain, --json rewrites) still shows OP_UNKNOWN186.
  • The devDependency is now ^9.11.1, so CI tests against it. The peer range stays ^9.10.1.

Tests

  • Unit: 51ba6a05aabbccddeeOP_1 0xba OP_RETURN aabbccddee, and it reads back byte for byte.
  • npm test: 28/28 on 9.11.1.

Review of bsv 9.11.1 (#175)

Round-trip fuzz against the npm 9.11.1 package: every unnamed opcode, direct/OP_PUSHDATA1/OP_PUSHDATA2/OP_PUSHDATA4 pushes, OP_0, and the empty script.

9.11.0 9.11.1
toASMfromASM (29k scripts with minimal pushes) 11,748 differ 0
toStringfromString (29k scripts) 19,180 throw, 304 differ 3,046 throw, 663 differ
toStringfromString, no empty OP_PUSHDATA (25.5k) 0

Every remaining toString failure has the same cause, and 9.11.0 has it too: an empty push written with OP_PUSHDATA1/2/4 (4c00) prints as a bare OP_PUSHDATA1 with no length or data. fromString then throws (Cannot read properties of undefined (reading 'slice') or Pushdata data must start with 0x) or misreads the next token. Writing it as OP_PUSHDATA1 0 0x would need fromString to accept an empty 0x.

@smartledger/bsv 9.11.1 writes an opcode with no name as 0xba and reads it
back from ASM. exactAsm wrote OP_UNKNOWN186, which nothing reads, so it
refused any script holding one. It now writes 0xba; the read-back check still
refuses such scripts where an older @smartledger/bsv is installed. Tests run
against 9.11.1.
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​smartledger/​bsv@​9.11.0 ⏵ 9.11.181 +11009896 +1100

View full report

@codenlighten

Copy link
Copy Markdown
Owner Author

Reviewed and checked locally:

  • 28/28 tests pass on bsv 9.11.1.
  • exactAsm writes all 67 unnamed opcodes as 0xNN, and bsv 9.11.1 reads every one back byte for byte. OP_INVALIDOPCODE (0xff) is still written by name and reads back.
  • With bsv 9.11.0 installed (the peer range allows it) the script is refused, naming the version that reads it.

On the toString finding: confirmed, and it is worse in ASM. toASM drops an empty OP_PUSHDATA1/2/4 push altogether, so 514c0051 writes as OP_1 OP_1: a script with one fewer push. fromString already reads OP_PUSHDATA1 0 0x, so the fix is on the writing side. It is being fixed in @smartledger/bsv.

@codenlighten
codenlighten merged commit a6299a7 into main Sep 17, 2026
5 checks passed
@codenlighten
codenlighten deleted the asm-raw-opcodes branch September 17, 2026 15:34
codenlighten added a commit to codenlighten/smartledger-bsv that referenced this pull request Sep 17, 2026
toASM and toString wrote nothing for an empty data push. For one encoded with
OP_PUSHDATA1/2/4 (4c00), ASM dropped the push, so 514c0051 read back as 5151,
one stack element fewer, and toString wrote a bare OP_PUSHDATA1 that
fromString could not read. The empty push Script#add(Buffer.alloc(0)) builds,
and so buildDataOut(''), serializes to 0x00 but was written as nothing, so
6a00 read back as 6a.

ASM now writes an empty push minimally, as 0. toString writes
OP_PUSHDATA1 0 0x for the PUSHDATA encodings, which fromString already read,
and OP_0 otherwise, as it already did for 0x00 parsed from bytes. Four tests
had pinned the invisible form; they now assert the text reads back.

No reader changes. Of 4,000 generated scripts, the 909 whose text changed all
contain an empty push and all read back exactly; every text 9.11.1 wrote is
read the same way.

Reported in codenlighten/scriptmin#4.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant