Documentation Index
Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
Use this file to discover all available pages before exploring further.
Try it Live
Run Opcode examples in the interactive playground
Opcode.disassemble()
Disassemble bytecode into array of formatted assembly strings.
import { disassemble } from 'tevm/Opcode'
const bytecode = new Uint8Array([
0x60, 0x01, // PUSH1 1
0x60, 0x02, // PUSH1 2
0x01, // ADD
])
const lines = disassemble(bytecode)
// ["0000: PUSH1 0x01", "0002: PUSH1 0x02", "0004: ADD"]
Parameters
bytecode: Uint8Array - Raw bytecode to disassemble
Returns
string[] - Array of formatted instruction strings
Each line format: "<offset>: <mnemonic> [immediate]"
- Offset: 4-digit hex with leading zeros (e.g.,
0000, 002A)
- Mnemonic: Opcode name (e.g.,
PUSH1, ADD, SSTORE)
- Immediate: Hex value for PUSH operations (e.g.,
0x80, 0x0102)
Use Cases
Print Contract Disassembly
import * as Opcode from 'tevm/Opcode'
function printDisassembly(bytecode: Uint8Array): void {
const lines = Opcode.disassemble(bytecode)
console.log('=== Disassembly ===')
for (const line of lines) {
console.log(line)
}
console.log(`\nTotal instructions: ${lines.length}`)
}
Annotated Disassembly with Gas
function disassembleWithGas(bytecode: Uint8Array): string[] {
const instructions = Opcode.parse(bytecode)
const lines: string[] = []
for (const inst of instructions) {
const formatted = Opcode.format(inst)
const info = Opcode.info(inst.opcode)
lines.push(`${formatted} // gas: ${info?.gasCost ?? 'unknown'}`)
}
return lines
}
// Example output:
// 0000: PUSH1 0x80 // gas: 3
// 0002: PUSH1 0x40 // gas: 3
// 0004: MSTORE // gas: 3
Side-by-Side Comparison
function compareDisassembly(
bytecode1: Uint8Array,
bytecode2: Uint8Array
): string[] {
const lines1 = Opcode.disassemble(bytecode1)
const lines2 = Opcode.disassemble(bytecode2)
const maxLen = Math.max(lines1.length, lines2.length)
const output: string[] = []
output.push('Original'.padEnd(40) + ' | ' + 'Optimized')
output.push('-'.repeat(80))
for (let i = 0; i < maxLen; i++) {
const left = (lines1[i] ?? '').padEnd(40)
const right = lines2[i] ?? ''
output.push(`${left} | ${right}`)
}
return output
}
Find Pattern Locations
function findPattern(
bytecode: Uint8Array,
pattern: string
): number[] {
const lines = Opcode.disassemble(bytecode)
const matches: number[] = []
lines.forEach((line, index) => {
if (line.includes(pattern)) {
matches.push(index)
}
})
return matches
}
// Find all SSTORE operations
const sstoreLocations = findPattern(bytecode, 'SSTORE')
Export to File
import * as fs from 'fs'
function exportDisassembly(
bytecode: Uint8Array,
filename: string
): void {
const lines = Opcode.disassemble(bytecode)
const content = lines.join('\n')
fs.writeFileSync(filename, content, 'utf-8')
}
exportDisassembly(contractBytecode, 'contract.asm')
Highlight Instructions
function highlightJumps(bytecode: Uint8Array): string[] {
const instructions = Opcode.parse(bytecode)
const jumpDests = Opcode.jumpDests(bytecode)
const lines: string[] = []
for (const inst of instructions) {
let line = Opcode.format(inst)
if (Opcode.isJump(inst.opcode)) {
line += ' <-- JUMP'
}
if (jumpDests.has(inst.offset)) {
line += ' <-- JUMPDEST'
}
lines.push(line)
}
return lines
}
- O(n) time where n is number of instructions
- String allocation for each instruction line
- Single pass through parsed instructions
- Uses
parse() internally, so includes parsing overhead