> ## 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.

# 模拟交易捆绑（Bundles）

> 使用 tenderly_simulateBundle 和 tenderly_estimateGasBundle JSON-RPC 方法模拟一组交易并获取精确的 gas 估算。

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

有两个方法针对给定区块按顺序执行一批交易而无需将其发送到链上。捆绑中的每笔交易都在前一笔交易留下的状态上执行：

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

### `tenderly_simulateBundle`

模拟一组交易在给定区块上的执行情况，并返回每笔交易的结果。

**参数**

1. **Transactions** 交易 `ARRAY`：捆绑中的交易列表
   * **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_simulateBundle",
      "params": [
      [
    {
      "from": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
      "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
      "data": "0x095ea7b300000000000000000000000020a5814b73ef3537c6e099a0d45c798f4bd6e1d60000000000000000000000000000000000000000000000000000000000000001"
    },
    {
      "from": "0x20a5814b73ef3537c6e099a0d45c798f4bd6e1d6",
      "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
      "data": "0x23b872dd000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa9604500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"
    }
      ],
      "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_simulateBundle",
    "params": [
    [
    {
    "from": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
    "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
    "data": "0x095ea7b300000000000000000000000020a5814b73ef3537c6e099a0d45c798f4bd6e1d60000000000000000000000000000000000000000000000000000000000000001"
    },
    {
    "from": "0x20a5814b73ef3537c6e099a0d45c798f4bd6e1d6",
    "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
    "data": "0x23b872dd000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa9604500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"
    }
    ],
    "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_simulateBundle", [
    [

    {
    "from": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
    "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
    "data": "0x095ea7b300000000000000000000000020a5814b73ef3537c6e099a0d45c798f4bd6e1d60000000000000000000000000000000000000000000000000000000000000001"
    },
    {
    "from": "0x20a5814b73ef3537c6e099a0d45c798f4bd6e1d6",
    "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
    "data": "0x23b872dd000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa9604500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"
    }
    ],
    "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": "0xb3a8",
      "cumulativeGasUsed": "0x0",
      "blockNumber": "0xf4d881",
      "type": "0x0",
      "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000002000000080000000000000000200000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000080000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000010200000800000000000000000000000000000000000000000000000000000",
      "logs": [
    {
      "name": "Approval",
      "anonymous": false,
      "inputs": [
    {
      "value": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
      "type": "address",
      "name": "src"
    },
    {
      "value": "0x20a5814b73ef3537c6e099a0d45c798f4bd6e1d6",
      "type": "address",
      "name": "guy"
    },
    {
      "value": "1",
      "type": "uint256",
      "name": "wad"
    }
      ],
      "raw": {
      "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
      "topics": [
      "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925",
      "0x000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045",
      "0x00000000000000000000000020a5814b73ef3537c6e099a0d45c798f4bd6e1d6"
      ],
      "data": "0x0000000000000000000000000000000000000000000000000000000000000001"
    }
    }
      ],
      "trace": [
    {
      "type": "CALL",
      "from": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
      "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
      "gas": "0x5f58cbc",
      "gasUsed": "0x5f64",
      "value": "0x0",
      "input": "0x095ea7b300000000000000000000000020a5814b73ef3537c6e099a0d45c798f4bd6e1d60000000000000000000000000000000000000000000000000000000000000001",
      "decodedInput": [
    {
      "value": "0x20a5814b73ef3537c6e099a0d45c798f4bd6e1d6",
      "type": "address",
      "name": "guy"
    },
    {
      "value": "1",
      "type": "uint256",
      "name": "wad"
    }
      ],
      "method": "approve",
      "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
      "decodedOutput": [
    {
      "value": true,
      "type": "bool",
      "name": ""
    }
      ],
      "subtraces": 0,
      "traceAddress": [
      0
      ]
    }
      ]
    },
    {
      "status": true,
      "gasUsed": "0x8a78",
      "cumulativeGasUsed": "0x0",
      "blockNumber": "0xf4d881",
      "type": "0x0",
      "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000080000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000010000000000000004000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000020000000200000800000000000000000000000000000000000000000000000000000",
      "logs": [
    {
      "name": "Transfer",
      "anonymous": false,
      "inputs": [
    {
      "value": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
      "type": "address",
      "name": "src"
    },
    {
      "value": "0x0000000000000000000000000000000000000000",
      "type": "address",
      "name": "dst"
    },
    {
      "value": "1",
      "type": "uint256",
      "name": "wad"
    }
      ],
      "raw": {
      "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
      "topics": [
      "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
      "0x000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045",
      "0x0000000000000000000000000000000000000000000000000000000000000000"
      ],
      "data": "0x0000000000000000000000000000000000000000000000000000000000000001"
    }
    }
      ],
      "trace": [
    {
      "type": "CALL",
      "from": "0x20a5814b73ef3537c6e099a0d45c798f4bd6e1d6",
      "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
      "gas": "0x5f58c3c",
      "gasUsed": "0x4874",
      "value": "0x0",
      "input": "0x23b872dd000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa9604500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
      "decodedInput": [
    {
      "value": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
      "type": "address",
      "name": "src"
    },
    {
      "value": "0x0000000000000000000000000000000000000000",
      "type": "address",
      "name": "dst"
    },
    {
      "value": "1",
      "type": "uint256",
      "name": "wad"
    }
      ],
      "method": "transferFrom",
      "output": "0x0000000000000000000000000000000000000000000000000000000000000001",
      "decodedOutput": [
    {
      "value": true,
      "type": "bool",
      "name": ""
    }
      ],
      "subtraces": 0,
      "traceAddress": [
      0
      ]
    }
      ]
    }
      ]
    }
    ```
  </Tab>
</Tabs>

**结果**

模拟结果 `ARRAY`：捆绑中的模拟结果列表

* **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_estimateGasBundle`

为给定的交易列表计算精确的 gas 估算，可选地采用类似模拟的状态和区块覆盖。与 [`tenderly_estimateGas`](/node-rpc/guides/simulate-json-rpc#tenderly_estimategas) 类似，每次估算都基于完全执行的交易，因此在 `eth_estimateGas` 可能回滚并给出低估值的情况下，返回值仍然准确。交易按顺序执行，每笔都基于前一笔留下的状态。

**与 `tenderly_simulateBundle` 的差异：**

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

**参数**

1. **Transactions** 交易 `ARRAY`：捆绑中的交易列表，结构与 [`tenderly_simulateBundle`](#tenderly_simulatebundle) 相同
2. **Simulation Block Number**（*可选*）执行捆绑所依据的区块号。可为：
   * `STRING` 区块号
   * `ENUM` 区块标签 `earliest|finalized|safe|latest|pending`
3. **State Overrides**（*可选*）`MAP`：从账户（地址）到覆盖规范的映射，结构与 [`tenderly_simulateBundle`](#tenderly_simulatebundle) 相同
4. **Block Overrides**（*可选*）`OBJECT`：区块中要覆盖的头字段集，结构与 [`tenderly_simulateBundle`](#tenderly_simulatebundle) 相同

**示例**

<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_estimateGasBundle",
      "params": [
        [
          {
            "from": "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
            "to": "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84",
            "data": "0x095ea7b30000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab410000000000000000000000000000000000000000000000000c1291a92f17a100"
          },
          {
            "from": "0x9008D19f58AAbD9eD0D60971565AA8510560ab41",
            "to": "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84",
            "data": "0x23b872dd0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca00000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab410000000000000000000000000000000000000000000000000c1291a92f17a100"
          },
          {
            "from": "0x9008D19f58AAbD9eD0D60971565AA8510560ab41",
            "to": "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84",
            "data": "0x095ea7b30000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca00000000000000000000000000000000000000000000000000c1291a92f17a100"
          },
          {
            "from": "0x9008D19f58AAbD9eD0D60971565AA8510560ab41",
            "to": "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
            "data": "0xea598cb00000000000000000000000000000000000000000000000000c1291a92f17a100"
          }
        ],
        "latest"
      ]
    }
    ```
  </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_estimateGasBundle",
    "params": [
    [
    {
    "from": "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
    "to": "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84",
    "data": "0x095ea7b30000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab410000000000000000000000000000000000000000000000000c1291a92f17a100"
    },
    {
    "from": "0x9008D19f58AAbD9eD0D60971565AA8510560ab41",
    "to": "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84",
    "data": "0x23b872dd0000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca00000000000000000000000009008d19f58aabd9ed0d60971565aa8510560ab410000000000000000000000000000000000000000000000000c1291a92f17a100"
    },
    {
    "from": "0x9008D19f58AAbD9eD0D60971565AA8510560ab41",
    "to": "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84",
    "data": "0x095ea7b30000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca00000000000000000000000000000000000000000000000000c1291a92f17a100"
    },
    {
    "from": "0x9008D19f58AAbD9eD0D60971565AA8510560ab41",
    "to": "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
    "data": "0xea598cb00000000000000000000000000000000000000000000000000c1291a92f17a100"
    }
    ],
    "latest"
    ]
    }'
    ```
  </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" },
        { "gas": "0x10918", "gasUsed": "0xb551" },
        { "gas": "0xa621", "gasUsed": "0x6625" },
        { "gas": "0x10649", "gasUsed": "0xb249" }
      ]
    }
    ```
  </Tab>
</Tabs>

**结果**

Gas 估算 `ARRAY`：gas 估算列表，捆绑中每笔交易对应一项

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