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

# 模拟交易

> 使用 tenderly_simulateTransaction 和 tenderly_estimateGas JSON-RPC 方法模拟单笔交易并获得精确的 gas 估算。

<Note>自定义 RPC 方法位于 **`tenderly_`** 命名空间下。</Note>

这些方法运行于 [Node RPC](/node-rpc/overview) 之上；参见完整的 [JSON-RPC 参考](/node-rpc/rpc-reference) 以了解所有方法和网络。

有两个方法针对给定区块执行单笔交易而不将其发送到链上：

* [`tenderly_simulateTransaction`](#tenderly_simulatetransaction) 返回完整的已解码执行结果：日志、调用跟踪、资产变化和余额变化。
* [`tenderly_estimateGas`](#tenderly_estimategas) 以同样的方式执行交易，但仅返回 gas 数值。当您需要精确的 gas 值而无需完整模拟负载时使用此方法。

### `tenderly_simulateTransaction`

模拟交易在给定区块上的执行情况。

**参数**

1. **Transaction** 交易 `OBJECT`
   * **from**（*可选*）`STRING`：十六进制编码地址
   * **to** `STRING`：十六进制编码地址
   * **gas**（*可选*）`NUMBER`
   * **maxFeePerGas**（*可选*）`NUMBER` 最高费用：发送方愿意为每单位 gas 支付的最大总费用（包含网络/基础费用和矿工/优先费），单位为 wei
   * **maxPriorityFeePerGas**（*可选*）`NUMBER` 最高优先费：发送方愿意支付给矿工的每单位 gas 最大费用，单位为 wei
   * **gasPrice**（*可选*）`NUMBER`：发送方愿意支付的 gas 价格，单位为 wei
   * **value**（*可选*）`NUMBER`
   * **data**（*可选*）`STRING`：十六进制编码字节
   * **accessList**（*可选*）`ARRAY`，元素为访问列表条目 `OBJECT`
     * **address** `STRING` 十六进制编码地址
     * **storageKeys** `ARRAY`，元素为 32 字节十六进制编码存储键的 `STRING` 表示
2. **Simulation Block Number**（*可选*）交易应据以模拟的区块号。可为：
   * `STRING` 区块号
   * `ENUM` 区块标签 `earliest|finalized|safe|latest|pending`
3. **State Overrides**（*可选*）`MAP`：从账户（地址）到覆盖规范的映射
   * **key** `STRING`：此覆盖适用的账户
   * **value** `OBJECT`：覆盖规范
     * **nonce**（*可选*）`STRING`：账户的十六进制编码 8 字节 nonce 覆盖
     * **code**（*可选*）`STRING`：账户代码覆盖的数据
     * **balance**（*可选*）`STRING`：账户十六进制编码 32 字节余额覆盖，单位为 wei
     * **stateDiff**（*可选*）`MAP`：存储键到存储值覆盖的映射
       * **key** `STRING`：存储键
       * **value** `STRING`：给定存储键的值覆盖
4. **Block Overrides**（可选）`OBJECT`：区块中要覆盖的头字段集。
   * **number** *（可选）* `STRING`：hex，覆盖区块号
   * **difficulty** *（可选）* `STRING`：hex，覆盖区块难度
   * **time**（*可选*）`STRING`：hex，覆盖区块时间戳
   * **gasLimit** *（可选）* `STRING`：hex，覆盖 gas 限制
   * **coinbase** *（可选）* `STRING`：hex，覆盖区块矿工
   * **random** *（可选）* `STRING`：hex，覆盖区块的额外数据，该数据将输入到 RANDOM 操作码
   * **baseFee** *（可选）* `STRING`：hex，覆盖区块基础费

**示例**

<Tabs>
  <Tab title="example.json">
    ```json title="example.json" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    {
      "id": 0,
      "jsonrpc": "2.0",
      "method": "tenderly_simulateTransaction",
      "params": [
        {
          "from": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
          "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
          "data": "0xa9059cbb00000000000000000000000020a5814b73ef3537c6e099a0d45c798f4bd6e1d60000000000000000000000000000000000000000000000000000000000000001"
        },
        "0xF4D880"
      ]
    }
    ```
  </Tab>

  <Tab title="example">
    ```bash title="example" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    curl https://mainnet.gateway.tenderly.co/$TENDERLY_NODE_ACCESS_KEY \
    -X POST \
    -H "Content-Type: application/json" \
    -d \
    '{
    "id": 0,
    "jsonrpc": "2.0",
    "method": "tenderly_simulateTransaction",
    "params": [
    {
    "from": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
    "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
    "data": "0xa9059cbb00000000000000000000000020a5814b73ef3537c6e099a0d45c798f4bd6e1d60000000000000000000000000000000000000000000000000000000000000001"
    },
    "0xF4D880"
    ]
    }'
    ```
  </Tab>

  <Tab title="example.js">
    ```javascript title="example.js" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    // Installation Instructions: https://docs.ethers.io/v5/getting-started/#installing
    const { ethers } = require('ethers');

    async function runSimulateTransaction() {
    // Initialize an ethers instance
    const provider = new ethers.providers.JsonRpcProvider(
    'https://goerli.gateway.tenderly.co/$TENDERLY_WEB3_GATEWAY_KEY',
    );

    // Execute method
    const result = await provider.send('tenderly_simulateTransaction', [

    {
    from: '0xd8da6bf26964af9d7eed9e03e53415d37aa96045',
    to: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
    data: '0xa9059cbb00000000000000000000000020a5814b73ef3537c6e099a0d45c798f4bd6e1d60000000000000000000000000000000000000000000000000000000000000001',
    },
    '0xF4D880',
    ]);

    // Print the output to console
    console.log(result);
    }

    (async () => {
    runSimulateTransaction();
    })();
    ```
  </Tab>

  <Tab title="example.json">
    ```json title="example.json" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    {
      "id": 0,
      "jsonrpc": "2.0",
      "result": {
      "status": true,
      "gasUsed": "0xc94e",
      "cumulativeGasUsed": "0x0",
      "blockNumber": "0x1103aae",
      "type": "0x0",
      "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000002000000080000000000000000000000000000000000000000000008000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000004000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000200000800000000000000000000000000000000000000000000000000000",
      "logs": [
    {
      "name": "Transfer",
      "anonymous": false,
      "inputs": [
    {
      "value": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
      "type": "address",
      "name": "src"
    },
    {
      "value": "0x20a5814b73ef3537c6e099a0d45c798f4bd6e1d6",
      "type": "address",
      "name": "dst"
    },
    {
      "value": "1",
      "type": "uint256",
      "name": "wad"
    }
      ],
      "raw": {
      "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
      "topics": [
      "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
      "0x000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045",
      "0x00000000000000000000000020a5814b73ef3537c6e099a0d45c798f4bd6e1d6"
      ],
      "data": "0x0000000000000000000000000000000000000000000000000000000000000001"
    }
    }
      ],
      "trace": [
    {
      "type": "CALL",
      "from": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
      "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
      "gas": "0xbeb6dbc",
      "gasUsed": "0x750a",
      "value": "0x0",
      "input": "0xa9059cbb00000000000000000000000020a5814b73ef3537c6e099a0d45c798f4bd6e1d60000000000000000000000000000000000000000000000000000000000000001",
      "decodedInput": [
    {
      "value": "0x20a5814b73ef3537c6e099a0d45c798f4bd6e1d6",
      "type": "address",
      "name": "dst"
    },
    {
      "value": "1",
      "type": "uint256",
      "name": "wad"
    }
      ],
      "method": "transfer",
      "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
      "decodedOutput": [
    {
      "value": true,
      "type": "bool",
      "name": ""
    }
      ],
      "subtraces": 0,
      "traceAddress": [
      0
      ]
    }
      ],
      "assetChanges": [
    {
      "assetInfo": {
      "standard": "ERC20",
      "type": "Fungible",
      "contractAddress": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
      "symbol": "weth",
      "name": "WETH",
      "logo": "https://assets.coingecko.com/coins/images/2518/large/weth.webp?1628852295",
      "decimals": 18,
      "dollarValue": "1834.6199951171875"
    },
      "type": "Transfer",
      "from": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
      "to": "0x20a5814b73ef3537c6e099a0d45c798f4bd6e1d6",
      "rawAmount": "0x1",
      "amount": "0.000000000000000001",
      "dollarValue": "0.0000000000000018346199951171875"
    }
      ],
      "balanceChanges": [
    {
      "address": "0x20a5814b73ef3537c6e099a0d45c798f4bd6e1d6",
      "dollarValue": "0.0000000000000018346199951171875",
      "transfers": [
      0
      ]
    },
    {
      "address": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
      "dollarValue": "-0.0000000000000018346199951171875",
      "transfers": [
      0
      ]
    }
      ]
    }
    }
    ```
  </Tab>
</Tabs>

**结果**

模拟结果 `OBJECT`

* **status** `NUMBER：``1`（成功）或 `0`（失败）
* **gasUsed** `NUMBER`：单笔交易本身使用的 gas 数量
* **cumulativeGasUsed** `NUMBER`：该交易在区块中执行时使用的总 gas 数量
* **blockNumber** `NUMBER`：该交易被模拟所在的区块号
* **type** `NUMBER`：交易类型，`0x00` 为传统交易，`0x01` 为访问列表类型，`0x02` 为动态费用
* **logsBloom** `STRING`：供轻客户端快速检索相关日志的布隆过滤器
* **logs**：发出的事件数组 `ARRAY`，元素为 `OBJECT`
  * **name** `STRING`：事件名称
  * **anonymous** `BOOLEAN`：指示事件是否为匿名
  * **inputs**：已解码日志参数数组 `ARRAY`，元素为已解码日志 `OBJECT`
    * **name** `STRING`：事件参数名称
    * **type** `STRING`：来自 Solidity 类型系统的事件参数类型
    * **value**（*可选*）`STRING`：参数值的字符串表示；请根据 `type` 字段解读
  * **raw** `OBJECT`：原始日志
    * **address** `STRING` 十六进制编码地址：发出日志的合约地址
    * **topics** `ARRAY`，元素为 `STRING` 32 十六进制编码字节
    * **data** `STRING` 表示事件数据的十六进制编码字符串
* **trace**：跟踪 `ARRAY`，元素为 `OBJECT`
  * **type** `STRING` 类型：跟踪项类型——`CALL`、`CALLCODE`、`STATICCALL`、`DELEGATECALL`、`CREATE`、`CREATE2`、`SELFDESTRUCT` 之一
  * **from** `STRING`：十六进制编码地址
  * **to** `STRING`：十六进制编码地址
  * **gas** `STRING`：表示事件 gas 的十六进制编码无符号 64 字节整数
  * **gasUsed** `STRING`：表示事件 gasUsed 的十六进制编码无符号 64 字节整数
  * **value** `STRING`：表示事件 value（单位 wei）的十六进制编码无符号 64 字节整数
  * **error** `STRING`：来自虚拟机的低级错误
  * **errorReason** `STRING`：回滚时提取的错误原因
  * **input** `STRING`：表示跟踪点原始输入字节的十六进制编码字符串
  * **method** `STRING`：被调用的合约方法
  * **decodedInput**：被调用方法的已解码输入——`ARRAY`，元素为已解码入参 `OBJECT`
    * **value** `STRING`：参数值的字符串表示；请根据 `type` 字段解读。
    * **type** `STRING`：该参数的 Solidity 类型
    * **name** `STRING`：该参数的名称
  * **output** `STRING`：原始跟踪输出
  * **decodedOutput**：被调用方法的已解码输出——`ARRAY`，元素为已解码出参 `OBJECT`
    * **value** `STRING`：参数值的字符串表示；请根据 `type` 字段解读。
    * **type** `STRING`：该参数的 Solidity 类型
    * **name** `STRING`：该参数的名称
  * **subtraces** `NUMBER`：子跟踪数量
  * **traceAddress**：跟踪位置 `ARRAY`，元素为 `NUMBER`
* **`assetChanges`** `ARRAY`：
  * **`type`** `STRING` 资产变化类型，可为 transfer、mint、burn
  * **`from`** `STRING`：发送方地址（mint 转账时为空）
  * **`to`** `STRING`：接收方地址（burn 转账时为空）
  * **`amount`** `STRING`：转移的代币数量
  * **`rawAmount`** `STRING`：代币的原始转移数量
  * **`dollarValue`** `STRING`：转移代币的美元价值
  * **`assetInfo`** `OBJECT`：资产信息
    * **`standard`** `STRING`：受支持的代币标准：ERC20、ERC721、NativeCurrency
    * **`type`** `STRING`：代币类型：Native、Fungible、Non-Fungible
    * **`contractAddress`** `STRING`：合约地址
    * **`symbol`** `STRING`：代币符号
    * **`name`** `STRING`：代币名称
    * **`logo`** `STRING`：代币图标的 URL
    * **`decimals`** `NUMBER`：代币小数位数
    * **`dollarValue`** `STRING`：单个代币的美元价值
* **`balanceChanges`** `ARRAY`：余额变化数组——累计资产变化
  * **`address`** `STRING` 地址
  * **`dollarValue`** `STRING`：累计资产变化的美元价值
  * **`transfers`** `ARRAY`：资产变化索引数组

### `tenderly_estimateGas`

为给定交易计算精确的 gas 估算，可选地采用类似模拟的状态和区块覆盖。即便指定的 `gas` 不足，估算也基于完全执行的交易，因此返回值是准确的。相反，`eth_estimateGas` 可能会回滚并给出低估值。

**与 `tenderly_simulateTransaction` 的差异：**

* 两种方法都以相同方式针对给定区块执行交易，并且都接受相同的状态和区块覆盖。
* `tenderly_simulateTransaction` 返回完整的已解码执行结果：日志、调用跟踪、资产变化和余额变化。
* `tenderly_estimateGas` 仅返回两个 gas 数值：推荐 gas 限制和实际消耗的 gas。当您只需要 gas 值时使用它；当您需要预览交易效果时，请使用 `tenderly_simulateTransaction`。

**参数**

1. **Transaction** 交易 `OBJECT`：结构与 [`tenderly_simulateTransaction`](#tenderly_simulatetransaction) 相同（`from`、`to`、`gas`、`gasPrice`、`value`、`data`、`accessList`）
2. **Simulation Block Number**（*可选*）执行交易所依据的区块号。可为：
   * `STRING` 区块号
   * `ENUM` 区块标签 `earliest|finalized|safe|latest|pending`
3. **State Overrides**（*可选*）`MAP`：从账户（地址）到覆盖规范的映射，结构与 [`tenderly_simulateTransaction`](#tenderly_simulatetransaction) 相同
4. **Block Overrides**（*可选*）`OBJECT`：区块中要覆盖的头字段集，结构与 [`tenderly_simulateTransaction`](#tenderly_simulatetransaction) 相同

**示例**

<Tabs>
  <Tab title="example.json">
    ```json title="example.json" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    {
      "id": 0,
      "jsonrpc": "2.0",
      "method": "tenderly_estimateGas",
      "params": [
        {
          "from": "0x8516feaea147ea0db64d1c5b97bb651ca5435155",
          "to": "0x6b175474e89094c44da98b954eedeac495271d0f",
          "data": "0xa9059cbb0000000000000000000000003fc3c4c84bdd2db5ab2cc62f93b2a9a347de25fb00000000000000000000000000000000000000000000001869c36187f3430000",
          "value": "0x0"
        },
        "21285787"
      ]
    }
    ```
  </Tab>

  <Tab title="example">
    ```bash title="example" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    curl https://mainnet.gateway.tenderly.co/$TENDERLY_NODE_ACCESS_KEY \
    -X POST \
    -H "Content-Type: application/json" \
    -d \
    '{
    "id": 0,
    "jsonrpc": "2.0",
    "method": "tenderly_estimateGas",
    "params": [
    {
    "from": "0x8516feaea147ea0db64d1c5b97bb651ca5435155",
    "to": "0x6b175474e89094c44da98b954eedeac495271d0f",
    "data": "0xa9059cbb0000000000000000000000003fc3c4c84bdd2db5ab2cc62f93b2a9a347de25fb00000000000000000000000000000000000000000000001869c36187f3430000",
    "value": "0x0"
    },
    "21285787"
    ]
    }'
    ```
  </Tab>

  <Tab title="response.json">
    ```json title="response.json" showLineNumbers theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
    {
      "id": 0,
      "jsonrpc": "2.0",
      "result": {
        "gas": "0x12579",
        "gasUsed": "0xff06"
      }
    }
    ```
  </Tab>
</Tabs>

**结果**

Gas 估算 `OBJECT`

* **gas** `STRING`：十六进制编码的推荐 gas 限制，用于交易设置（在实际消耗 gas 的基础上包含安全余量）
* **gasUsed** `STRING`：十六进制编码的已执行交易实际消耗 gas 数量
