# 傳送前先模擬：使用 eth_simulateV1 預演交易

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

在將交易廣播到區塊鏈網路之前，預演交易可讓開發者事先檢視執行結果、驗證合約狀態轉換並觀察事件日誌，避免因合約回滾而造成不必要的 gas 費用。

以太坊執行層提供多種在傳送前評估交易的方式：

* `eth_call`：執行單次唯讀訊息呼叫，連續呼叫之間不保留狀態。
* `eth_estimateGas`：計算執行所需的 gas 上限，但不提供多筆交易的連續狀態轉換或完整事件日誌。
* `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`。

## 請求結構與基本範例

根據執行層規格（[Ethereum Execution APIs eth\_simulateV1 定義](https://ethereum.github.io/execution-apis/api/methods/eth_simulateV1)），`eth_simulateV1` 接受兩個位置參數：

1. **Payload 物件**：
   * `blockStateCalls`（必填陣列）：模擬區塊物件的陣列。每個物件包含交易呼叫陣列 `calls`、選填的區塊標頭覆寫 `blockOverrides`，以及選填的帳戶狀態覆寫 `stateOverrides`。
   * `validation`（選填布林值，預設 `false`）：為 `false` 時，行為如同 `eth_call`；為 `true` 時，執行除了簽章檢查之外的所有 EVM 驗證。
   * `traceTransfers`（選填布林值）：為 `true` 時，回傳原生代幣轉帳的事件日誌。
2. **區塊標籤**（選填字串，預設 `'latest'`）：區塊編號、區塊雜湊或區塊標籤。

### 基本範例：預演 ERC-20 轉帳

以下範例在 Robinhood Chain 上預演 ERC-20 `transfer(address,uint256)` 呼叫。請將 `$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}`),
});

// 透過 viem 的 client.request 直接呼叫 eth_simulateV1
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);
```


### 檢視回應結構

根據以太坊執行規格，`result` 欄位包含模擬區塊結果的陣列，結構如下：

#### 區塊層級欄位

* `number`：模擬區塊的區塊編號（十六進位字串）。
* `hash`：模擬區塊雜湊（32 位元組十六進位字串）。
* `parentHash`：父區塊的雜湊。
* `timestamp`：區塊時間戳（十六進位字串）。
* `gasLimit`：區塊 gas 上限。
* `gasUsed`：此區塊中所有模擬呼叫消耗的 gas 總量。
* `baseFeePerGas`：該區塊每單位 gas 的基礎費用。
* `miner`：接收區塊費用的 coinbase 地址。
* `calls`：每個模擬呼叫的執行結果陣列。

#### 呼叫層級欄位（`calls` 陣列項目）

* `status`：呼叫狀態，十六進位字串。`0x1` 表示成功，`0x0` 表示失敗或回滾。
* `gasUsed`：此呼叫實際消耗的 gas（十六進位字串）。
* `maxUsedGas`（選填）：執行期間在退還之前的 gas 用量峰值。
* `returnData`：十六進位編碼的回傳資料。ERC-20 轉帳成功時，其中包含布林值 `true`；回滾時，其中包含錯誤選擇器或回滾資料。
* `logs`：呼叫發出的事件日誌陣列。成功時，包含如 `Transfer` 等事件日誌：
  * `address`：發出事件的合約地址。
  * `topics`：32 位元組主題雜湊的陣列（`topics[0]` 是事件簽章雜湊，例如 `Transfer` 事件簽章）。
  * `data`：十六進位編碼的非索引事件資料。
  * `blockNumber`、`blockHash`、`transactionHash`、`transactionIndex`、`logIndex`、`removed`。
* `error`（失敗時出現）：包含 `code`（`3` 表示回滾，`-32015` 表示 VM 錯誤）與 `message`（例如 `execution reverted`）的物件。

## 計價與 CU 權重

BlockVectra 以計算單位（CU）計量用量。每個 JSON-RPC 方法的權重由 `GET /v1/plans` 動態發布：

**單次呼叫的 CU 權重**

| 方法 | 單次呼叫 CU |
| --- | --- |
| `eth_simulateV1` | 20 |
| `eth_call` | 15 |
| `eth_estimateGas` | 20 |

單位換算公式與儲值詳情請參閱[定價頁面](https://blockvectra.com/zh-hant/pricing/)。

被拒絕的請求——包括節點同步中（`-32010`）、超出狀態視窗（`-32011`）或方法無法使用（`-32601`）——不計費。完整計費規則請參閱[哪些請求免費](https://docs.blockvectra.com/zh-hant/guides/billing-rules/)。

## 搭配 AI Agent 與 MCP 使用

自主 AI Agent 可以直接透過 BlockVectra 的 Model Context Protocol（MCP）伺服器叫用 `eth_simulateV1`。

需要 key 的 `rpc_call` 工具允許在支援的鏈上執行 JSON-RPC 方法。API key 必須設定在 MCP 用戶端的 HTTP 標頭中（`x-api-key: {api_key}` 或 `Authorization: Bearer {api_key}`），絕不可傳入工具參數或對話提示中。

在 Robinhood Chain 上叫用 `rpc_call` 工具的承載範例：

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

Agent 可以檢查 `status === "0x1"`，在提交原始交易前驗證合約互動是否有效並評估 gas 消耗。設定與使用說明請參閱 [AI Agent 整合指南](https://docs.blockvectra.com/zh-hant/guides/ai-agents/)。

## 下一步

* [查看免費方案與定價](https://blockvectra.com/zh-hant/pricing/#free)，確認你的帳戶包含哪些內容。
* [登入控制台](https://console.blockvectra.com/login/?next=%2Fkeys%2F)建立 API key。
