Skip to main content

Purpose and Scope

This page provides detailed information about the Ethereum Virtual Machine (EVM) execution layer in StableNet, focusing on the interpreter architecture, opcode execution mechanics, jump tables, gas metering, and contract call handling.
For details on how transactions enter the execution pipeline, see Transaction Lifecycle.
For the state transition model that wraps EVM execution, see State Transitions and Gas.
For StableNet-specific gas pricing policies, see Gas Fee Policy.

EVM Architecture

The EVM is implemented as a stack-based virtual machine that executes bytecode and manages state changes.
Its core consists of several major structures.
Architecture Overview: EVM Component Hierarchy

EVM Structure

The EVM struct contains all context required for execution.

EVMInterpreter Structure

The interpreter executes bytecode using a jump table.

ScopeContext Structure

ScopeContext holds execution resources scoped to a single call.
It is created per contract execution and passed to all opcode execution functions, providing access to the stack and memory.

Interpreter Loop

The core execution loop of EVMInterpreter.Run() processes bytecode instructions one by one. Interpreter Loop Execution Flow

Stack and Memory Management

The EVM uses a stack for operands during execution and an expandable memory for data storage.

Stack Implementation

The Stack is a bounded array of 256-bit integers. Before executing each opcode, the stack guarantees:
  • stack.len() >= operation.minStack
  • stack.len() <= operation.maxStack

Memory Implementation

Memory is a byte array that expands in 32-byte words. Memory expansion gas calculation:

Major Execution Steps

  1. Initialization
    • Increase call depth
    • Set readOnly if STATICCALL
    • Reset returnData
    • Create new Stack and Memory
    • Construct ScopeContext
  2. Fetch Opcode
    • Load opcode at the program counter
  3. Stack Validation
    • Check for underflow and overflow
  4. Gas Consumption
    • Deduct fixed gas
    • Compute dynamic gas if required
    • Apply memory expansion gas
  5. Execution
    • Invoke the opcode execution function
  6. Program Counter Update
    • Increment pc unless a JUMP-family opcode is executed

Jump Table and Opcodes

The jump table maps 256 opcodes to execution functions, gas costs, and stack requirements.
Different instruction sets are selected depending on the active fork.

Instruction Sets by Fork

The jump table is selected in NewEVMInterpreter() based on chain rules.

Contract Calls

The EVM supports CALL, DELEGATECALL, STATICCALL, CREATE, and CREATE2.

Key Handling During Calls

  • Maximum call depth: 1024
  • Anzeon: value transfer destination restrictions
  • Blacklist checks
  • State snapshot creation and rollback on error
  • Tracer event invocation

Precompiled Contracts

Native Manager Contracts (Anzeon)

StableNet provides native Go-implemented contracts for system-level operations. These are integrated into the normal CALL flow and interact directly with StateDB.

Gas Metering

Gas is calculated across the following stages:
  • Intrinsic gas
  • Memory expansion gas
  • Opcode dynamic gas
  • Post-execution refunds
Refund caps:
  • Pre-London: gasUsed / 2
  • London+: gasUsed / 5

Error Handling

The REVERT opcode rolls back state changes while preserving return data.