> For the complete documentation index, see [llms.txt](https://docs.rome.builders/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rome.builders/getting-started/architecture.md).

# Architecture

Rome embeds an EVM bytecode interpreter inside a Solana on-chain program. Users talk to the Rome Proxy over standard Ethereum JSON-RPC, and the proxy submits their transactions straight to the Rome EVM program on Solana. There is no separate execution layer to keep in sync — EVM state *is* Solana state.

## System overview

<figure><img src="/files/fB48w0bvALtCtneJewcg" alt="User to Rome Proxy to the Rome EVM program on Solana, with Hercules indexing back"><figcaption></figcaption></figure>

## Components

### Rome EVM Program (on-chain)

The core of Rome — a Solana BPF program containing a full EVM bytecode interpreter (a fork of SputnikVM). It:

* Receives serialized EVM transactions as Solana instructions
* Executes Solidity bytecode inside the Solana runtime
* Maps each Ethereum address (H160) to a Solana PDA
* Exposes precompiles for calling into Solana (CPI, System, Helper, Withdraw) alongside the standard Ethereum precompiles
* Stores EVM state (balances, nonce, code, storage) as Solana account data

### Rome Proxy (JSON-RPC server)

A standard Ethereum JSON-RPC server on port 9090 — the entry point for the public chains. It translates Ethereum API calls into Solana activity:

* `eth_sendRawTransaction` → serialize the EVM tx → submit a Solana instruction
* `eth_call` → emulate execution off-chain via the Mollusk SVM emulator
* `eth_estimateGas` → simulate for gas estimation
* `eth_getBalance`, `eth_getCode`, `eth_getBlockByNumber`, receipts, logs → served from indexed state

It also exposes Rome extensions: `rome_emulateTx`, `rome_emulateRegRollup`, `rome_mintId`, `rome_buildInfo`, `rome_getResources`, and more.

### Hercules (indexer)

Watches the Rome EVM program on Solana and reconstructs Ethereum-compatible blocks — transactions, receipts, logs, and state changes — backed by PostgreSQL. On the public chains it runs in slot-aligned mode, so a block number maps to a Solana slot and the same slot yields the same block on any indexer. The proxy serves these blocks to wallets and explorers.

### Precompiles

Rome implements the standard Ethereum precompiles (ecrecover, SHA-256, RIPEMD-160, identity, modexp, the BN254 curve operations, blake2f) with mainnet-equivalent semantics, plus non-EVM precompiles that reach into Solana: **CpiProgram** (`0xFF…08`, arbitrary CPI), **System** (`0xFF…07`, PDA derivation and base58 helpers), **HelperProgram** (`0xFF…09`, ATA/PDA creation, SPL transfers, gas↔lamports), and **Withdraw** (`0x42…16`). See the [Contract Addresses](/reference/contract-addresses.md) reference for the full table.

## Execution modes

Rome executes an EVM transaction in one of two ways:

### Atomic (VmAt)

A single Solana transaction. The whole EVM transaction executes within one Solana transaction's compute budget (\~1.4M compute units). Used for most operations — transfers, ordinary contract calls, swaps.

### Iterative (VmIt)

For work that exceeds a single transaction's budget. Execution is split across multiple Solana transactions:

1. Each step (a Solana transaction) runs as many EVM opcodes as fit in its compute budget — the step size is adaptive, not fixed
2. VM state is Borsh-serialized into a `StateHolder` account between steps
3. Accounts are TTL-locked for a few seconds during execution
4. Used for heavy operations such as BN254 pairing

## Account mapping

Every Ethereum address maps deterministically to a Solana PDA derived from the chain ID and the address under the Rome EVM program. That PDA owns the account's balance (as SPL token accounts), contract code, storage slots, and nonce — all as Solana account data.

## Holder accounts

Solana transactions are capped at 1,232 bytes, but EVM transactions (especially contract deployments) can be much larger. Rome stages large transactions into **holder accounts**: the transaction is split into chunks written sequentially into a holder (up to 80 KB), then assembled and executed on-chain. The Rome SDK manages this transparently.

## Gas and pricing

Each chain has its own gas token — any SPL token. Gas pricing reads a Meteora DAMM pool (v1 or v2, configurable) to convert between the gas token and SOL for the underlying Solana transaction fees.

## What's next

* [Networks](/networks/networks.md) — connect to Martius or Hadrian
* [Quickstart](/getting-started/quickstart.md) — deploy your first contract
* [Execution Model](/core-concepts/execution-model.md) — atomic vs iterative execution in depth


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.rome.builders/getting-started/architecture.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
