> ## 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.

# Opcode Validation

> Validating opcodes and checking opcode categories

<Card title="Try it Live" icon="play" href="https://playground.tevm.sh?example=primitives/opcode.ts">
  Run Opcode examples in the interactive playground
</Card>

# Validation

Methods for validating opcodes and checking opcode categories.

## Opcode Validity

### `Opcode.isValid(opcode)`

Check if byte value is a valid EVM opcode.

```typescript theme={null}
import * as Opcode from '@tevm/primitives/Opcode'

Opcode.isValid(0x00)  // true (STOP)
Opcode.isValid(0x01)  // true (ADD)
Opcode.isValid(0x60)  // true (PUSH1)
Opcode.isValid(0xFF)  // true (SELFDESTRUCT)

// Invalid opcodes
Opcode.isValid(0x0C)  // false (undefined)
Opcode.isValid(0x0D)  // false (undefined)
Opcode.isValid(0x21)  // false (undefined, between KECCAK256 and ADDRESS)
Opcode.isValid(0x4B)  // false (undefined, after BLOBBASEFEE)
```

**Parameters:**

* `opcode: number` - Byte value to check (0x00-0xFF)

**Returns:** `boolean` - True if valid EVM opcode

**Use cases:**

* Validate bytecode before execution
* Filter out undefined opcodes during disassembly
* Detect malformed or invalid bytecode

Defined in: [primitives/Opcode/BrandedOpcode/isValid.js](https://github.com/evmts/voltaire/blob/main/src/primitives/Opcode/BrandedOpcode/isValid.js)

### `Opcode.isValidOpcode(opcode)`

Alias for `isValid()`.

```typescript theme={null}
const valid = Opcode.isValidOpcode(0x60)  // true
```

**Parameters:**

* `opcode: number` - Byte value

**Returns:** `boolean` - True if valid opcode

## Jump Validation

### `Opcode.isValidJumpDest(bytecode, offset)`

Check if offset is a valid JUMPDEST in bytecode.

```typescript theme={null}
import * as Opcode from '@tevm/primitives/Opcode'

const bytecode = new Uint8Array([
  0x60, 0x04,     // PUSH1 0x04
  0x56,           // JUMP
  0x5B,           // JUMPDEST (offset 3)
  0x00            // STOP
])

Opcode.isValidJumpDest(bytecode, 3)  // true (valid JUMPDEST)
Opcode.isValidJumpDest(bytecode, 0)  // false (PUSH1, not JUMPDEST)
Opcode.isValidJumpDest(bytecode, 1)  // false (inside PUSH data)
Opcode.isValidJumpDest(bytecode, 99) // false (out of bounds)
```

**Parameters:**

* `bytecode: Uint8Array` - Contract bytecode
* `offset: number` - Program counter offset to check

**Returns:** `boolean` - True if offset is valid JUMPDEST

**Validation rules:**

* Offset must be within bytecode bounds
* Byte at offset must be JUMPDEST (0x5B)
* Offset must not be inside PUSH immediate data

Defined in: [primitives/Opcode/BrandedOpcode/isValidJumpDest.js](https://github.com/evmts/voltaire/blob/main/src/primitives/Opcode/BrandedOpcode/isValidJumpDest.js)

### `Opcode.isJumpDestination(opcode)`

Check if opcode is JUMPDEST (0x5B).

```typescript theme={null}
Opcode.isJumpDestination(0x5B)  // true
Opcode.isJumpDestination(0x56)  // false (JUMP, not JUMPDEST)
```

**Parameters:**

* `opcode: BrandedOpcode` - Opcode to check

**Returns:** `boolean` - True if JUMPDEST

Defined in: [primitives/Opcode/BrandedOpcode/isJumpDestination.js](https://github.com/evmts/voltaire/blob/main/src/primitives/Opcode/BrandedOpcode/isJumpDestination.js)

## Category Checks

### `Opcode.isPush(opcode)`

Check if opcode is PUSH0-PUSH32.

```typescript theme={null}
import * as Opcode from '@tevm/primitives/Opcode'

Opcode.isPush(0x5F)  // true (PUSH0)
Opcode.isPush(0x60)  // true (PUSH1)
Opcode.isPush(0x7F)  // true (PUSH32)
Opcode.isPush(0x01)  // false (ADD)
Opcode.isPush(0x80)  // false (DUP1)
```

**Parameters:**

* `opcode: BrandedOpcode` - Opcode to check

**Returns:** `boolean` - True if PUSH0-PUSH32 (0x5F-0x7F)

Defined in: [primitives/Opcode/BrandedOpcode/isPush.js](https://github.com/evmts/voltaire/blob/main/src/primitives/Opcode/BrandedOpcode/isPush.js)

### `Opcode.isDup(opcode)`

Check if opcode is DUP1-DUP16.

```typescript theme={null}
Opcode.isDup(0x80)  // true (DUP1)
Opcode.isDup(0x8F)  // true (DUP16)
Opcode.isDup(0x60)  // false (PUSH1)
Opcode.isDup(0x90)  // false (SWAP1)
```

**Parameters:**

* `opcode: BrandedOpcode` - Opcode to check

**Returns:** `boolean` - True if DUP1-DUP16 (0x80-0x8F)

Defined in: [primitives/Opcode/BrandedOpcode/isDup.js](https://github.com/evmts/voltaire/blob/main/src/primitives/Opcode/BrandedOpcode/isDup.js)

### `Opcode.isSwap(opcode)`

Check if opcode is SWAP1-SWAP16.

```typescript theme={null}
Opcode.isSwap(0x90)  // true (SWAP1)
Opcode.isSwap(0x9F)  // true (SWAP16)
Opcode.isSwap(0x80)  // false (DUP1)
Opcode.isSwap(0xA0)  // false (LOG0)
```

**Parameters:**

* `opcode: BrandedOpcode` - Opcode to check

**Returns:** `boolean` - True if SWAP1-SWAP16 (0x90-0x9F)

Defined in: [primitives/Opcode/BrandedOpcode/isSwap.js](https://github.com/evmts/voltaire/blob/main/src/primitives/Opcode/BrandedOpcode/isSwap.js)

### `Opcode.isLog(opcode)`

Check if opcode is LOG0-LOG4.

```typescript theme={null}
Opcode.isLog(0xA0)  // true (LOG0)
Opcode.isLog(0xA4)  // true (LOG4)
Opcode.isLog(0xA5)  // false (undefined)
Opcode.isLog(0x9F)  // false (SWAP16)
```

**Parameters:**

* `opcode: BrandedOpcode` - Opcode to check

**Returns:** `boolean` - True if LOG0-LOG4 (0xA0-0xA4)

Defined in: [primitives/Opcode/BrandedOpcode/isLog.js](https://github.com/evmts/voltaire/blob/main/src/primitives/Opcode/BrandedOpcode/isLog.js)

### `Opcode.isJump(opcode)`

Check if opcode is JUMP or JUMPI.

```typescript theme={null}
Opcode.isJump(0x56)  // true (JUMP)
Opcode.isJump(0x57)  // true (JUMPI)
Opcode.isJump(0x5B)  // false (JUMPDEST)
Opcode.isJump(0x00)  // false (STOP)
```

**Parameters:**

* `opcode: BrandedOpcode` - Opcode to check

**Returns:** `boolean` - True if JUMP (0x56) or JUMPI (0x57)

Defined in: [primitives/Opcode/BrandedOpcode/isJump.js](https://github.com/evmts/voltaire/blob/main/src/primitives/Opcode/BrandedOpcode/isJump.js)

### `Opcode.isTerminating(opcode)`

Check if opcode terminates execution.

```typescript theme={null}
Opcode.isTerminating(0x00)  // true (STOP)
Opcode.isTerminating(0xF3)  // true (RETURN)
Opcode.isTerminating(0xFD)  // true (REVERT)
Opcode.isTerminating(0xFE)  // true (INVALID)
Opcode.isTerminating(0xFF)  // true (SELFDESTRUCT)
Opcode.isTerminating(0x01)  // false (ADD)
```

**Parameters:**

* `opcode: BrandedOpcode` - Opcode to check

**Returns:** `boolean` - True if STOP, RETURN, REVERT, INVALID, or SELFDESTRUCT

**Terminating opcodes:**

* `STOP` (0x00) - Halts execution
* `RETURN` (0xF3) - Returns from call
* `REVERT` (0xFD) - Reverts state changes
* `INVALID` (0xFE) - Invalid opcode trap
* `SELFDESTRUCT` (0xFF) - Destroys contract

Defined in: [primitives/Opcode/BrandedOpcode/isTerminating.js](https://github.com/evmts/voltaire/blob/main/src/primitives/Opcode/BrandedOpcode/isTerminating.js)

### `Opcode.isTerminator(opcode)`

Alias for `isTerminating()`.

```typescript theme={null}
const terminates = Opcode.isTerminator(0xF3)  // true
```

## Validation Patterns

### Validate Bytecode

```typescript theme={null}
function validateBytecode(bytecode: Uint8Array): string[] {
  const errors: string[] = []
  const instructions = Opcode.parse(bytecode)

  for (const inst of instructions) {
    if (!Opcode.isValid(inst.opcode)) {
      errors.push(`Invalid opcode 0x${inst.opcode.toString(16)} at offset ${inst.offset}`)
    }
  }

  return errors
}
```

### Check Jump Safety

```typescript theme={null}
function hasUnsafeJumps(bytecode: Uint8Array): boolean {
  const instructions = Opcode.parse(bytecode)
  const validDests = Opcode.jumpDests(bytecode)

  for (const inst of instructions) {
    if (Opcode.isJump(inst.opcode)) {
      // In real analysis, would need symbolic execution to get jump target
      // This is simplified
      if (validDests.size === 0) {
        return true  // Has jumps but no valid destinations
      }
    }
  }

  return false
}
```

### Categorize Instructions

```typescript theme={null}
interface InstructionCategories {
  push: number
  dup: number
  swap: number
  log: number
  jump: number
  terminating: number
  other: number
}

function categorizeInstructions(bytecode: Uint8Array): InstructionCategories {
  const instructions = Opcode.parse(bytecode)
  const categories: InstructionCategories = {
    push: 0,
    dup: 0,
    swap: 0,
    log: 0,
    jump: 0,
    terminating: 0,
    other: 0
  }

  for (const inst of instructions) {
    if (Opcode.isPush(inst.opcode)) categories.push++
    else if (Opcode.isDup(inst.opcode)) categories.dup++
    else if (Opcode.isSwap(inst.opcode)) categories.swap++
    else if (Opcode.isLog(inst.opcode)) categories.log++
    else if (Opcode.isJump(inst.opcode)) categories.jump++
    else if (Opcode.isTerminating(inst.opcode)) categories.terminating++
    else categories.other++
  }

  return categories
}
```

### Find Invalid Opcodes

```typescript theme={null}
function findInvalidOpcodes(bytecode: Uint8Array): number[] {
  const instructions = Opcode.parse(bytecode)
  const invalidOffsets: number[] = []

  for (const inst of instructions) {
    if (!Opcode.isValid(inst.opcode)) {
      invalidOffsets.push(inst.offset)
    }
  }

  return invalidOffsets
}
```

### Validate PUSH Consistency

```typescript theme={null}
function validatePushInstructions(bytecode: Uint8Array): boolean {
  const instructions = Opcode.parse(bytecode)

  for (const inst of instructions) {
    if (Opcode.isPush(inst.opcode)) {
      const expectedBytes = Opcode.pushBytes(inst.opcode)

      // PUSH0 has no immediate
      if (expectedBytes === 0 && inst.immediate !== undefined) {
        return false
      }

      // Other PUSHes must have immediate data
      if (expectedBytes > 0) {
        if (!inst.immediate || inst.immediate.length !== expectedBytes) {
          return false
        }
      }
    }
  }

  return true
}
```

### Check for Unreachable Code

```typescript theme={null}
function findUnreachableCode(bytecode: Uint8Array): Set<number> {
  const instructions = Opcode.parse(bytecode)
  const reachable = new Set<number>([0])  // Start is reachable

  for (const inst of instructions) {
    if (!reachable.has(inst.offset)) {
      continue  // Skip unreachable instructions
    }

    // Next instruction is reachable unless this terminates
    if (!Opcode.isTerminating(inst.opcode)) {
      // Find next instruction offset
      const nextOffset = inst.offset + 1 + (inst.immediate?.length ?? 0)
      reachable.add(nextOffset)
    }

    // JUMP/JUMPI make destinations reachable (would need symbolic execution for actual targets)
  }

  const unreachable = new Set<number>()
  for (const inst of instructions) {
    if (!reachable.has(inst.offset)) {
      unreachable.add(inst.offset)
    }
  }

  return unreachable
}
```

## See Also

* [Constructors](/primitives/opcode/constructors) - Parsing bytecode
* [Utilities](/primitives/opcode/utilities) - Opcode metadata
* [Usage Patterns](/primitives/opcode/usage-patterns) - Bytecode analysis
