# Simulate before you send: dry-running transactions with eth_simulateV1

> Original page: https://docs.blockvectra.com/en/guides/simulate-transactions/

Before broadcasting transactions to a blockchain network, dry-running them allows developers to inspect execution results, verify contract state transitions, and observe event logs in advance, avoiding unnecessary gas fees caused by contract reverts.

The Ethereum execution layer provides several ways to evaluate transactions before sending:

* `eth_call`: Executes a single read-only message call without state persistence across successive calls.
* `eth_estimateGas`: Calculates the gas limit required for execution, but does not provide multi-transaction sequential state transitions or full event logs.
* `eth_simulateV1`: Defined in the Ethereum Execution APIs standard specification, this method allows sequential simulation of multiple transactions across blocks, accumulates state changes between transactions, and supports overriding block parameters and account state.

## Supported chains and method policy

Network capabilities are published dynamically via `GET /v1/chains`. On Robinhood Chain, the method policy (`methods.allow`) permits `eth_simulateV1` (chain slug `robinhood_mainnet`, EIP-155 chain ID 4663).

Chains where `eth_simulateV1` is not included in `methods.allow` reject calls with JSON-RPC error `-32601` (`method not available`, not billed). The standard read-only call `eth_call` and gas estimation `eth_estimateGas` are allowed across all four networks.

The table below lists the allowed chains for each method based on `GET /v1/chains`:

| JSON-RPC method   | Allowed chain (`chain`)                                                           | Chain name                                                       | EIP-155 chain ID             | Purpose                                                       |
| ----------------- | --------------------------------------------------------------------------------- | ---------------------------------------------------------------- | ---------------------------- | ------------------------------------------------------------- |
| `eth_simulateV1`  | `robinhood_mainnet`                                                               | Robinhood Chain                                                  | 4663                         | Multi-call sequential execution and state override simulation |
| `eth_call`        | `robinhood_mainnet`<br />`eth_mainnet`<br />`bsc_mainnet`<br />`hyperevm_mainnet` | Robinhood Chain<br />Ethereum<br />BNB Smart Chain<br />HyperEVM | 4663<br />1<br />56<br />999 | Single read-only message call                                 |
| `eth_estimateGas` | `robinhood_mainnet`<br />`eth_mainnet`<br />`bsc_mainnet`<br />`hyperevm_mainnet` | Robinhood Chain<br />Ethereum<br />BNB Smart Chain<br />HyperEVM | 4663<br />1<br />56<br />999 | Estimate gas limit required for execution                     |

### Node state guards

Under the published platform specification, `eth_simulateV1` is a state query method subject to node state guards:

* **Sync gate (`-32010`)**: When the node of the target chain is syncing and not yet ready, the call returns `-32010` (`node is syncing`); it is neither forwarded nor billed.
* **State window (`-32011`)**: On Robinhood Chain, the state window is 900 blocks (`state_window_blocks: 900`). Requests targeting blocks older than this window, or specifying `safe`, `finalized`, or `earliest` block tags, return `-32011` (not billed). The default block tag is `latest`.

## Request structure and basic example

According to the execution layer specification ([Ethereum Execution APIs eth\_simulateV1 definition](https://ethereum.github.io/execution-apis/api/methods/eth_simulateV1)), `eth_simulateV1` accepts two positional parameters:

1. **Payload object**:
   * `blockStateCalls` (required array): An array of simulated block objects. Each object contains an array of transaction calls `calls`, optional block header overrides `blockOverrides`, and optional account state overrides `stateOverrides`.
   * `validation` (optional boolean, default `false`): When `false`, base fee is treated as zero and strict balance checks are bypassed; when `true`, strict EVM validation rules (such as nonce and balance checks) are enforced.
   * `traceTransfers` (optional boolean): When `true`, returns event logs for native token transfers.
2. **Block tag** (optional string, default `'latest'`): Block number, block hash, or block tag.

### Basic example: dry-running an ERC-20 transfer

The following example dry-runs an ERC-20 `transfer(address,uint256)` call on Robinhood Chain. Replace `$BLOCKVECTRA_API_KEY` with your actual API key:

**cURL**

```bash
export BLOCKVECTRA_API_KEY=rgw_your_api_key

curl -s "https://api.blockvectra.com/v1/robinhood_mainnet" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "eth_simulateV1",
    "params": [
      {
        "blockStateCalls": [
          {
            "calls": [
              {
                "from": "0x1111111111111111111111111111111111111111",
                "to": "0x2222222222222222222222222222222222222222",
                "data": "0xa9059cbb00000000000000000000000033333333333333333333333333333333333333330000000000000000000000000000000000000000000000000de0b6b3a7640000",
                "value": "0x0"
              }
            ]
          }
        ]
      },
      "latest"
    ]
  }'
```


  **TypeScript (viem)**

```ts
import { createPublicClient, http } from "viem";

const apiKey = process.env.BLOCKVECTRA_API_KEY!;
const client = createPublicClient({
  transport: http(`https://api.blockvectra.com/v1/robinhood_mainnet/${apiKey}`),
});

// Call eth_simulateV1 directly via viem's client.request
const simulationResult = await client.request({
  method: "eth_simulateV1" as any,
  params: [
    {
      blockStateCalls: [
        {
          calls: [
            {
              from: "0x1111111111111111111111111111111111111111",
              to: "0x2222222222222222222222222222222222222222",
              data: "0xa9059cbb00000000000000000000000033333333333333333333333333333333333333330000000000000000000000000000000000000000000000000de0b6b3a7640000",
              value: "0x0",
            },
          ],
        },
      ],
    },
    "latest",
  ],
});

console.log(simulationResult);
```


### Inspecting the response structure

Under the Ethereum execution specification, the `result` field contains an array of simulated block results with the following schema:

#### Block-level fields

* `number`: Block number of the simulated block (hex string).
* `hash`: Simulated block hash (32-byte hex string).
* `parentHash`: Hash of the parent block.
* `timestamp`: Block timestamp (hex string).
* `gasLimit`: Block gas limit.
* `gasUsed`: Total gas consumed across all simulated calls in this block.
* `baseFeePerGas`: Base fee per gas for the block.
* `feeRecipient`: Coinbase address receiving block fees.
* `calls`: Array of execution results for each simulated call.

#### Call-level fields (`calls` array items)

* `status`: Call status as a hex string. `0x1` indicates success, while `0x0` indicates failure or revert.
* `gasUsed`: Actual gas consumed by this call (hex string).
* `maxUsedGas` (optional): Peak gas used during execution before refunds.
* `returnData`: Hex-encoded return data. On a successful ERC-20 transfer, this contains boolean `true`; on revert, it contains the error selector or revert data.
* `logs`: Array of event logs emitted by the call. On success, contains event logs such as `Transfer`:
  * `address`: Contract address that emitted the event.
  * `topics`: Array of 32-byte topic hashes (`topics[0]` is the event signature hash, such as the `Transfer` event signature).
  * `data`: Hex-encoded non-indexed event data.
  * `blockNumber`, `blockHash`, `transactionHash`, `transactionIndex`, `logIndex`, `removed`.
* `error` (present on failure): Object containing `message` (such as `execution reverted`).

## Pricing and CU weights

BlockVectra measures consumption in Compute Units (CU). The weight for each JSON-RPC method is published dynamically by `GET /v1/plans` and loaded at build time:

**CU weight per call**

| Method | CU per call |
| --- | --- |
| `eth_simulateV1` | 20 |
| `eth_call` | 15 |
| `eth_estimateGas` | 20 |

For unit conversion formulas and top-up details, visit the [Pricing page](https://blockvectra.com/en/pricing/).

Requests rejected at the ingress layer — including node syncing (`-32010`), outside state window (`-32011`), or method not available (`-32601`) — are not billed. See [Which requests are free](https://docs.blockvectra.com/en/guides/billing-rules/) for complete billing rules.

## Using with AI Agents and MCP

Autonomous AI Agents can invoke `eth_simulateV1` directly through BlockVectra's Model Context Protocol (MCP) server.

The keyed `rpc_call` tool allows executing JSON-RPC methods on supported chains. The API key must be configured in the MCP client HTTP headers (`x-api-key: {api_key}` or `Authorization: Bearer {api_key}`), never passed inside tool parameters or conversation prompts.

Example `rpc_call` tool invocation payload on Robinhood Chain:

```json
{
  "chain": "robinhood_mainnet",
  "method": "eth_simulateV1",
  "params": [
    {
      "blockStateCalls": [
        {
          "calls": [
            {
              "from": "0x1111111111111111111111111111111111111111",
              "to": "0x2222222222222222222222222222222222222222",
              "data": "0xa9059cbb00000000000000000000000033333333333333333333333333333333333333330000000000000000000000000000000000000000000000000de0b6b3a7640000",
              "value": "0x0"
            }
          ]
        }
      ]
    },
    "latest"
  ]
}
```

Agents can check `status === "0x1"` to verify contract interaction validity and assess gas consumption before submitting raw transactions. For setup and usage instructions, see the [AI Agent integration guide](https://docs.blockvectra.com/en/guides/ai-agents/).

## Next steps

* [Browse the datasets directory](https://blockvectra.com/en/data/) to see every dataset BlockVectra indexes.
* [See the free plan and pricing](https://blockvectra.com/en/pricing/#free) to check what your account includes.
* [Log in to the console](https://console.blockvectra.com/en/login/?next=%2Fen%2Fkeys%2F) to create an API key.
