# evm_disassemble

Decodes bytecode with evmone advanced static analysis fixed to the Osaka revision. It exposes 27 instruction, PUSH, block, stack, gas, storage, and call-hint columns without executing the code.

Canonical HTML: <https://determica.com/docs/functions/evm_disassemble>

- Kind: table function
- Category: [Development and bytecode](/docs/category/development-and-bytecode.md)
- Tags: EVM

Decodes bytecode with evmone advanced static analysis fixed to the Osaka revision. It exposes 27 instruction, PUSH, block, stack, gas, storage, and call-hint columns without executing the code.

## Overload 1: evm_disassemble(BYTES)

```sql
evm_disassemble(BYTES)
```

Disassembles BYTES using Osaka meanings and gas tables; no EVM-revision argument is available.

- Kind: table
- Execution context: Offline
- Behavior: Osaka Static Disassembly
- Execution modes: Offline
- Input shape: Scalar Argument
- Planning contract: Bind Time Analysis
- Cardinality: One Per Decoded Instruction
- Determinism: Deterministic
- Return shape: Table
- Schema stability: Fixed
- Stability: Stable
- Side effects: None documented

### Requirements

- evmone_advanced_analysis_a5d916a6646e37fe1ccc8d74bd639541ed6eaf26

### Risks

- fixed_osaka_revision
- heuristic_static_analysis
- dynamic_jump_incompleteness
- static_gas_only

### Inputs

- `bytecode` (BYTES; required; positional) — Bytecode to decode as BYTES. Use deployed runtime bytecode, such as `compile(...).bin_runtime` or `code_at(...)`, when inspecting contract behavior; deployment init code is valid but represents the constructor path.

### Result columns

Instruction-level bytecode table

Returns one row per decoded instruction at a zero-based byte-offset PC. NULL bytecode errors and empty bytecode returns zero rows. Analysis is fixed to Osaka with no revision argument; earlier-fork bytecode can therefore receive Osaka opcode meanings and gas tables.

- `pc` (INTEGER) — Zero-based byte offset of the decoded opcode
- `label` (VARCHAR) — Static jump-destination label, otherwise NULL
- `mnemonic` (VARCHAR) — Osaka instruction name, or UNKNOWN for an undefined opcode
- `opcode` (UTINYINT) — Raw opcode byte value (0x00-0xFF)
- `push_value` (BYTES32) — Right-aligned, zero-padded PUSH value; PUSH0 is zero; NULL for non-PUSH
- `push_length` (UTINYINT) — Declared PUSH width 0-32, including unavailable bytes; NULL for non-PUSH
- `push_truncated` (BOOLEAN) — Whether PUSH ran past bytecode end and was implicitly zero-padded (NULL if not PUSH)
- `instruction_size` (UTINYINT) — Actual bytes available for this instruction
- `is_terminating` (BOOLEAN) — Whether instruction terminates execution (STOP, RETURN, REVERT, etc.)
- `is_jumpdest` (BOOLEAN) — Whether this is a valid jump destination (JUMPDEST opcode)
- `is_reachable` (BOOLEAN) — Static CFG reachability; conservative or incomplete around dynamic jumps
- `block_id` (INTEGER) — Basic block identifier assigned from evmone analysis
- `is_block_start` (BOOLEAN) — Whether this instruction starts a basic block
- `is_block_end` (BOOLEAN) — Whether this instruction ends a basic block (jump/terminating)
- `block_entry_stack` (SMALLINT) — Stack height required at block entry (BlockInfo::stack_req)
- `block_max_stack` (SMALLINT) — Maximum stack height reachable within the block (entry + max_growth)
- `stack_depth` (SMALLINT) — Stack height at this instruction (clamped to block bounds)
- `stack_req` (UTINYINT) — Minimum stack items required by the opcode
- `stack_change` (TINYINT) — Net stack delta after executing the opcode
- `gas_cost` (SMALLINT) — Osaka static base opcode gas, excluding dynamic charges
- `block_gas_cost` (INTEGER) — evmone block metadata gas, excluding dynamic execution-path costs
- `analysis_instr_index` (INTEGER) — Index into evmone's advanced instruction stream (for trace correlation)
- `storage_slot` (BYTES32) — Constant storage slot for SLOAD/SSTORE instructions when statically known
- `storage_access_pattern` (VARCHAR) — Heuristic constant, array, mapping, or computed classification; NULL when not applicable
- `storage_slot_is_constant` (BOOLEAN) — True when storage_slot is a compile-time constant
- `call_address_constant` (BLOB) — Literal 20-byte call target only when statically recovered; otherwise NULL
- `call_type_metadata` (VARCHAR) — JSON text for CALL-like instructions; NULL otherwise; has_value=false is not proof of zero value

Instruction-level bytecode table. Returns one row per decoded instruction at a zero-based byte-offset PC. NULL bytecode errors and empty bytecode returns zero rows. Analysis is fixed to Osaka with no revision argument; earlier-fork bytecode can therefore receive Osaka opcode meanings and gas tables.

### Examples

_Local SQL · Local_

```sql
-- Disassemble PUSH0, CLZ and a truncated PUSH4 with Osaka gas costs
SELECT
  pc,
  mnemonic,
  opcode,
  CASE WHEN push_value IS NULL THEN NULL ELSE concat('0x', lower(hex(push_value))) END AS push_value,
  push_length,
  push_truncated,
  instruction_size,
  gas_cost
FROM evm_disassemble('0x5f1e63aabb'::BYTES)
ORDER BY pc;
-- => [{"pc":0,"mnemonic":"PUSH0","opcode":95,"push_value":"0x0000000000000000000000000000000000000000000000000000000000000000","push_length":0,"push_truncated":"false","instruction_size":1,"gas_cost":2},{"pc":1,"mnemonic":"CLZ","opcode":30,"push_value":null,"push_length":null,"push_truncated":null,"instruction_size":1,"gas_cost":5},{"pc":2,"mnemonic":"PUSH4","opcode":99,"push_value":"0x000000000000000000000000000000000000000000000000000000000000aabb","push_length":4,"push_truncated":"true","instruction_size":3,"gas_cost":3}]
```

## Guidance

### PUSH decoding

PUSH0 has declared width zero and value zero. PUSH1 through PUSH32 report their declared width even when fewer immediate bytes remain; `instruction_size` reports bytes actually present.

- `push_value` right-aligns available immediate bytes and zero-pads to BYTES32.
- `push_truncated` marks a missing immediate suffix.
- PUSH-only fields are NULL on other instructions.

### Static-analysis interpretation

Block IDs and boundaries, entry/max stack, instruction stack depth, and `analysis_instr_index` come from evmone advanced analysis. Reachability is static CFG analysis and can be conservative or incomplete around dynamic jumps.

- `gas_cost` is static base opcode gas and `block_gas_cost` is evmone block metadata; neither includes memory expansion, warm/cold access, refunds, or execution-path gas.
- Storage classifications are heuristics: constant, array, mapping, or computed.
- Constant call targets appear only when statically recovered.
- `call_type_metadata` is VARCHAR containing JSON. `has_value = false` can mean zero, unknown, or a call type without a value operand.

### Boundary

This table is not a decompiler, formal verifier, symbolic executor, or security finding engine.

- Full function, dominance, loop, memory, and data-flow analysis remains internal.

## Related functions

- [code_at](/docs/functions/code_at.md) — Usually After
- [compile](/docs/functions/compile.md) — Usually After
