> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stablenet.network/llms.txt
> Use this file to discover all available pages before exploring further.

# EVM Execution

## 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](/en/transaction-processing/6.1-transaction-lifecycle).\
For the state transition model that wraps EVM execution, see [State Transitions and Gas](/en/transaction-processing/6.2-state-transitions-and-gas).\
For StableNet-specific gas pricing policies, see [Gas Fee Policy](/en/transaction-processing/6.4-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.

| Field         | Type                  | Purpose                                                                      |
| ------------- | --------------------- | ---------------------------------------------------------------------------- |
| `Context`     | `BlockContext`        | Block-level information (coinbase, gas limit, block number, timestamp, etc.) |
| `TxContext`   | `TxContext`           | Transaction-level information (origin, gas price, blob hashes)               |
| `StateDB`     | `StateDB`             | Interface for account and storage state                                      |
| `depth`       | `int`                 | Current call stack depth (max 1024)                                          |
| `chainConfig` | `*params.ChainConfig` | Chain configuration                                                          |
| `chainRules`  | `params.Rules`        | Fork rules for the current block                                             |
| `Config`      | `Config`              | VM configuration (tracer, ExtraEips, NoBaseFee, etc.)                        |
| `interpreter` | `*EVMInterpreter`     | Bytecode interpreter                                                         |
| `abort`       | `atomic.Bool`         | Asynchronous abort flag                                                      |
| `callGasTemp` | `uint64`              | Temporary gas calculation space for CALL-family opcodes                      |

## EVMInterpreter Structure

The interpreter executes bytecode using a jump table.

| Field        | Type                 | Purpose                               |
| ------------ | -------------------- | ------------------------------------- |
| `evm`        | `*EVM`               | Reference to the parent EVM           |
| `table`      | `*JumpTable`         | Array defining 256 opcodes            |
| `hasher`     | `crypto.KeccakState` | Hash instance for KECCAK256 opcode    |
| `hasherBuf`  | `common.Hash`        | Hash output buffer                    |
| `readOnly`   | `bool`               | STATICCALL mode flag                  |
| `returnData` | `[]byte`             | Return data from the most recent call |

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

| Component  | Description                          |
| ---------- | ------------------------------------ |
| Structure  | `[]uint256.Int`, maximum size 1024   |
| Pool       | `sync.Pool` for reuse across calls   |
| Operations | `push`, `pop`, `peek`, `swap`, `dup` |
| Validation | Checked before each opcode execution |

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.

| Component    | Description                                         |
| ------------ | --------------------------------------------------- |
| Storage      | `[]byte`                                            |
| Gas Tracking | Cumulative expansion cost tracked via `lastGasCost` |
| Operations   | `Set`, `Set32`, `Resize`, `GetPtr`, `GetCopy`       |
| Cost Model   | `3 * words + words² / 512`                          |

Memory expansion gas calculation:

```
newMemSizeWords = (newMemSize + 31) / 32
newTotalFee = 3 * newMemSizeWords + newMemSizeWords² / 512
expansionCost = newTotalFee - lastGasCost
```

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

| Instruction Set | Fork           | Features                                               |
| --------------- | -------------- | ------------------------------------------------------ |
| frontier        | Frontier       | Base opcodes                                           |
| homestead       | Homestead      | DELEGATECALL                                           |
| byzantium       | Byzantium      | STATICCALL, REVERT                                     |
| constantinople  | Constantinople | CREATE2                                                |
| istanbul        | Istanbul       | Gas repricing                                          |
| berlin          | Berlin         | EIP-2929                                               |
| london          | London         | BASEFEE                                                |
| shanghai        | Shanghai       | PUSH0                                                  |
| cancun          | Cancun         | BLOB-related opcodes                                   |
| **anzeon**      | **Anzeon**     | **London + Shanghai + partial Cancun (blob excluded)** |

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

| Address      | Contract   | Purpose                            |
| ------------ | ---------- | ---------------------------------- |
| 0x01         | ecrecover  | ECDSA recovery                     |
| 0x02         | sha256     | Hashing                            |
| 0x03         | ripemd160  | Hashing                            |
| 0x04         | identity   | Data copy                          |
| 0x05         | modexp     | Modular exponentiation             |
| 0x06–0x08    | bn256      | Pairing operations                 |
| 0x09         | blake2F    | Compression                        |
| **0xb00001** | **blsPoP** | **Anzeon BLS Proof-of-Possession** |

## Native Manager Contracts (Anzeon)

StableNet provides native Go-implemented contracts for system-level operations.

| Address  | Contract          | Purpose                       |
| -------- | ----------------- | ----------------------------- |
| 0xb00002 | NativeCoinManager | Direct balance manipulation   |
| 0xb00003 | AccountManager    | Account extra-data management |

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

| Error Type | Behavior                            | Example              |
| ---------- | ----------------------------------- | -------------------- |
| Consensus  | Transaction invalid                 | ErrNonceTooLow       |
| Execution  | Consume all gas                     | ErrOutOfGas          |
| Revert     | Roll back state, partial gas refund | ErrExecutionReverted |
| Internal   | Should not occur                    | ErrGasUintOverflow   |

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