# Симуляция перед отправкой: тестирование транзакций с помощью eth_simulateV1

> Source: https://docs.blockvectra.com/ru/guides/simulate-transactions/

Перед трансляцией транзакций в сеть блокчейна их предварительная симуляция позволяет разработчикам заранее проверить результаты выполнения, переходы состояния контрактов и логи событий, избегая лишних затрат на газ из-за отката контрактов (revert).

Уровень исполнения Ethereum предоставляет несколько способов оценки транзакций перед отправкой:

* `eth_call`: выполняет один вызов сообщения только для чтения без сохранения состояния между последовательными вызовами.
* `eth_estimateGas`: рассчитывает лимит газа, необходимый для выполнения, но не предоставляет последовательных переходов состояния для нескольких транзакций или полных логов событий.
* `eth_simulateV1`: определенный в стандартной спецификации Ethereum Execution APIs, этот метод позволяет последовательно моделировать выполнение нескольких транзакций между блоками, накапливает изменения состояния между транзакциями и поддерживает переопределение параметров блоков и состояния аккаунтов.

## Поддерживаемые сети и политика методов

Возможности сетей публикуются динамически через `GET /v1/chains`. Проверьте `methods.allow` в этом ответе, чтобы узнать, какие сети разрешают `eth_simulateV1`; сеть, в которой этот метод не указан, отклоняет вызов с ошибкой JSON-RPC `-32601` (`method not available`, не тарифицируется).

### Условия состояния узла

`eth_simulateV1` является методом запроса состояния:

* **Блокировка синхронизации (`-32010`)**: если узел целевой сети находится в процессе синхронизации и еще не готов, вызов возвращает ошибку `-32010` (`node is syncing`, не тарифицируется).
* **Окно состояния (`-32011`)**: в Robinhood Chain запросы к блокам старше `state_window_blocks` сети (`GET /v1/chains`) или с указанием тегов блоков `safe`, `finalized` или `earliest` возвращают `-32011` (не тарифицируется). Тег блока по умолчанию — `latest`.

## Структура запроса и базовый пример

Согласно спецификации уровня исполнения ([определение eth\_simulateV1 в Ethereum Execution APIs](https://ethereum.github.io/execution-apis/api/methods/eth_simulateV1)), метод `eth_simulateV1` принимает два позиционных параметра:

1. **Объект полезной нагрузки (Payload object)**:
   * `blockStateCalls` (обязательный массив): массив объектов симулируемых блоков. Каждый объект содержит массив вызовов транзакций `calls`, необязательные переопределения заголовка блока `blockOverrides` и необязательные переопределения состояния аккаунтов `stateOverrides`.
   * `validation` (необязательный логический тип, по умолчанию `false`): при значении `false` работает аналогично `eth_call`; при `true` выполняет полную валидацию EVM, за исключением проверки подписей.
   * `traceTransfers` (необязательный логический тип): при значении `true` возвращает логи событий для переводов нативного токена.
2. **Тег блока** (необязательная строка, по умолчанию `'latest'`): номер блока, хеш блока или тег блока.

### Базовый пример: симуляция перевода ERC-20

Следующий пример выполняет симуляцию вызова ERC-20 `transfer(address,uint256)` в Robinhood Chain. Замените `$BLOCKVECTRA_API_KEY` на ваш действующий 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);
```


### Анализ структуры ответа

В соответствии со спецификацией исполнения Ethereum поле `result` содержит массив результатов симулированных блоков со следующей схемой:

#### Поля уровня блока

* `number`: номер симулированного блока (шестнадцатеричная строка).
* `hash`: хеш симулированного блока (32-байтовая шестнадцатеричная строка).
* `parentHash`: хеш родительского блока.
* `timestamp`: временная метка блока (шестнадцатеричная строка).
* `gasLimit`: лимит газа блока.
* `gasUsed`: общий объем газа, израсходованный всеми симулированными вызовами в этом блоке.
* `baseFeePerGas`: базовая комиссия за единицу газа (base fee per gas) для блока.
* `miner`: адрес coinbase, получающий комиссии блока.
* `calls`: массив результатов выполнения для каждого симулированного вызова.

#### Поля уровня вызова (элементы массива `calls`)

* `status`: статус вызова в виде шестнадцатеричной строки. `0x1` указывает на успешное выполнение, `0x0` — на сбой или откат (revert).
* `gasUsed`: фактический объем газа, израсходованный этим вызовом (шестнадцатеричная строка).
* `maxUsedGas` (необязательно): пиковый объем газа, использованный во время выполнения до возврата газа (refunds).
* `returnData`: шестнадцатеричные возвращаемые данные. При успешном переводе ERC-20 содержит логическое значение `true`; при откате (revert) содержит селектор ошибки или данные отката.
* `logs`: массив логов событий, сгенерированных вызовом. При успехе содержит логи событий, такие как `Transfer`:
  * `address`: адрес контракта, сгенерировавшего событие.
  * `topics`: массив 32-байтовых хешей топиков (`topics[0]` — хеш сигнатуры события, например сигнатуры события `Transfer`).
  * `data`: шестнадцатеричные неиндексированные данные события.
  * `blockNumber`, `blockHash`, `transactionHash`, `transactionIndex`, `logIndex`, `removed`.
* `error` (присутствует при сбое): объект, содержащий `code` (`3` для отката revert, `-32015` для ошибки виртуальной машины VM) и `message` (например, `execution reverted`).

## Тарифы и веса CU

BlockVectra измеряет потребление ресурсов в Compute Units (CU). Вес каждого метода JSON-RPC динамически публикуется в `GET /v1/plans`:

**Вес в CU за вызов**

| Метод | CU за вызов |
| --- | --- |
| `eth_simulateV1` | 20 |
| `eth_call` | 15 |
| `eth_estimateGas` | 20 |

Формулы конвертации расчетных единиц и информацию о пополнении см. на странице [Цены](https://blockvectra.com/ru/pricing/).

Отклоненные запросы — включая синхронизацию узла (`-32010`), выход за пределы окна состояния (`-32011`) или недоступность метода (`-32601`) — не тарифицируются. Полные правила биллинга см. в руководстве [Какие запросы бесплатны](https://docs.blockvectra.com/ru/guides/billing-rules/).

## Использование с AI Agent и MCP

Автономные AI Agent могут вызывать `eth_simulateV1` напрямую через сервер Model Context Protocol (MCP) BlockVectra.

Инструмент `rpc_call` с авторизацией позволяет выполнять методы JSON-RPC в поддерживаемых сетях. API key должен быть настроен в HTTP-заголовках MCP-клиента (`x-api-key: {api_key}` или `Authorization: Bearer {api_key}`) и никогда не должен передаваться в параметрах инструментов или диалоговых промптах.

Пример полезной нагрузки для вызова инструмента `rpc_call` в Robinhood Chain:

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

Агенты могут проверять `status === "0x1"`, чтобы подтвердить корректность взаимодействия с контрактом и оценить расход газа перед отправкой необработанных транзакций. Инструкции по настройке и использованию см. в [руководстве по интеграции AI Agent](https://docs.blockvectra.com/ru/guides/ai-agents/).

## Следующие шаги

* [Ознакомьтесь с бесплатным тарифом и ценами](https://blockvectra.com/ru/pricing/#free), чтобы узнать, что включено в ваш аккаунт.
* [Войдите в консоль](https://console.blockvectra.com/login/?next=%2Fkeys%2F), чтобы создать API key.
