跳转到主要内容
eth_simulateV1 是来自 Ethereum execution APIs 规范的标准多区块模拟方法。它在给定的基础区块之上模拟一系列区块,每个区块包含一批调用,而不会向链上发送任何内容。区块内的调用按顺序执行并共享状态,且每个模拟区块都构建在前一个区块之上。 该方法运行于 Node RPCVirtual Environments 之上;参见完整的 JSON-RPC 参考 以了解所有方法和网络。少数网络不支持该方法;参见网络可用性 当您需要可移植、符合规范标准且返回区块形态结果的模拟时,请使用 eth_simulateV1。如需已解码日志、调用跟踪以及资产和余额变化,单笔交易请使用 tenderly_simulateTransaction,交易序列请使用 tenderly_simulateBundle

eth_simulateV1

在给定的基础区块之上模拟一系列区块。每个区块包含一批调用:第 N 个调用能看到第 N-1 个调用的状态变化,且第一个区块之后的每个区块都构建在前一个区块之上。 参数
  1. Simulation payload 模拟负载 OBJECT
    • blockStateCalls ARRAY,元素为区块状态调用 OBJECT:要模拟的区块序列,按顺序排列
      • blockOverrides可选OBJECT:此区块中要覆盖的头字段集
        • number可选STRING:hex,覆盖区块号
        • difficulty可选STRING:hex,覆盖区块难度
        • time可选STRING:hex,覆盖区块时间戳
        • gasLimit可选STRING:hex,覆盖 gas 限制
        • coinbase可选STRING:hex,覆盖区块矿工
        • random可选STRING:hex,覆盖输入到 PREVRANDAO 操作码的值
        • baseFee可选STRING:hex,覆盖区块基础费
        • excessBlobGas可选STRING:hex,覆盖超额 blob gas
        • blobGasUsed可选STRING:hex,覆盖已使用的 blob gas
      • stateOverrides可选MAP:从账户(地址)到覆盖规范的映射。请在第一个区块条目上设置状态覆盖;参见 Tenderly 特有行为
        • key STRING:此覆盖适用的账户
        • value OBJECT:覆盖规范
          • balance可选STRING:账户的十六进制编码余额覆盖,单位为 wei
          • nonce可选STRING:账户的十六进制编码 nonce 覆盖
          • code可选STRING:账户代码覆盖的数据
          • stateDiff可选MAP:存储键到存储值覆盖的映射
            • key STRING:存储键
            • value STRING:给定存储键的值覆盖
      • calls ARRAY,元素为交易调用 OBJECT:按顺序执行;每个调用都能观察到在它之前的调用的状态变化
        • from可选STRING:十六进制编码地址;默认为零地址
        • to可选STRING:十六进制编码地址
        • gas可选STRING:该调用的十六进制编码 gas 限制
        • gasPrice可选STRING:hex,发送方愿意支付的 gas 价格,单位为 wei
        • maxFeePerGas可选STRING:hex,发送方愿意为每单位 gas 支付的最大总费用(包含网络/基础费用和矿工/优先费),单位为 wei
        • maxPriorityFeePerGas可选STRING:hex,发送方愿意支付给矿工的每单位 gas 最大费用,单位为 wei
        • value可选STRING:十六进制编码的 value,单位为 wei;默认为 0x0
        • input可选STRING:十六进制编码的调用数据;data 作为已弃用的别名仍被接受,两者同时设置时 input 优先
        • nonce可选STRING:十六进制编码的 nonce
        • type可选STRING:十六进制编码的交易类型
        • accessList可选ARRAY,元素为访问列表条目 OBJECT
          • address STRING:十六进制编码地址
          • storageKeys ARRAY,元素为 32 字节十六进制编码存储键的 STRING 表示
        • maxFeePerBlobGas可选STRING:hex,每单位 blob gas 的最大费用,单位为 wei
        • blobVersionedHashes可选ARRAY,元素为 STRING:32 字节十六进制编码的 blob 版本化哈希
        • authorizationList可选ARRAY:EIP-7702 授权元组
    • returnFullTransactions可选BOOLEAN:为 true 时,结果区块包含完整的交易对象而非交易哈希
  2. Base block number可选)模拟所基于的区块。默认为 latest。可为:
    • STRING 区块号
    • ENUM 区块标签 earliest|finalized|safe|latest|pending
示例 该请求模拟两个区块。第一个区块通过状态覆盖为发送方注资,然后发送 ETH 并将 1 ETH 包装为 WETH;第二个区块设置自定义时间戳并转移在第一个区块中铸造的 WETH。
example.json
{
  "id": 0,
  "jsonrpc": "2.0",
  "method": "eth_simulateV1",
  "params": [
    {
      "blockStateCalls": [
        {
          "stateOverrides": {
            "0xe2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2": {
              "balance": "0x3635c9adc5dea00000"
            }
          },
          "calls": [
            {
              "from": "0xe2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2",
              "to": "0x1111111111111111111111111111111111111111",
              "value": "0x1bc16d674ec80000"
            },
            {
              "from": "0xe2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2",
              "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
              "value": "0xde0b6b3a7640000",
              "input": "0xd0e30db0"
            }
          ]
        },
        {
          "blockOverrides": { "time": "0x6ae00000" },
          "calls": [
            {
              "from": "0xe2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2",
              "to": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
              "input": "0xa9059cbb00000000000000000000000011111111111111111111111111111111111111110000000000000000000000000000000000000000000000000de0b6b3a7640000"
            }
          ]
        }
      ]
    },
    "latest"
  ]
}
结果 ARRAY,元素为区块结果 OBJECT,每个 blockStateCalls 条目对应一个,按顺序排列。每个区块结果携带 eth_getBlockByNumber 返回的标准区块头字段(numberhashparentHashtimestampgasLimitgasUsedbaseFeePerGaslogsBloomminer 等),另加:
  • transactions ARRAY:模拟调用的交易哈希;当 returnFullTransactionstrue 时为完整的交易对象
  • calls ARRAY,元素为调用结果 OBJECT,每个调用对应一个,按顺序排列:
    • returnData STRING:该调用的十六进制编码返回数据
    • logs ARRAY,元素为日志 OBJECT:该调用发出的事件(addresstopicsdatablockNumbertransactionHashtransactionIndexblockHashlogIndexremoved);调用回滚时为空
    • gasUsed STRING:该调用消耗的 gas 数量,十六进制编码
    • status STRING0x1 表示成功,0x0 表示失败
    • error OBJECT:仅在调用失败时存在
      • code NUMBER:错误码
      • message STRING:错误信息,在可用时包含回滚原因

Tenderly 特有行为

Tenderly 的实现与参考的 execution-apis 规范在以下方面存在差异:
  • 不支持 validation 设置 validation: true 会返回错误 validation flag is not supported。模拟始终以非验证模式运行:不对调用强制执行 nonce、余额和费用要求。
  • 不支持 traceTransfers 设置 traceTransfers: true 会返回错误 traceTransfers flag is not supported。不会产生合成的 ETH 转账日志。
  • 不支持 state 覆盖。 状态覆盖中的 state 字段(完全替换存储)会返回 not supported 错误。请使用 stateDiff 覆盖单个存储槽。
  • 状态覆盖从第一个区块起生效。 请在第一个 blockStateCalls 条目上设置 stateOverrides;后续条目上的 stateOverrides 不会被应用。
  • 单个调用的 gas 会被钳制。 超过区块 gas 限制加 600,000,000 的 gas 值会被钳制到该上限,而不是被拒绝。
  • 没有区块数或调用数限制。blockStateCalls 条目数量或每个区块的调用数量没有强制上限。
  • 交易哈希是合成的。 结果区块中的哈希用于标识模拟调用,但并非已签名交易的哈希。
  • 区块递进。 第一个区块之后的每个模拟区块都会获得 number = 前一区块号 + 1 以及链接到前一个结果的 parentHash,同时重新计算基础费和 gas 限制。自动生成的时间戳是节点的系统时钟时间,因此当时间戳有影响时请显式设置 blockOverrides.time。被覆盖的区块号和时间戳会按原样应用,不会验证其单调性。当第一个区块条目提供了 blockOverrides 但未指定 number 时,区块号默认为基础区块号加 1。

网络可用性

eth_simulateV1 在 Node RPC 网络和 Virtual Environments 上可用,但以下网络除外,其底层网络节点不支持该方法:
  • ApeChain
  • Avalanche C-Chain
  • Avalanche C-Chain Fuji
  • Blast
  • Curtis
  • Flare
  • Immutable
  • Immutable Testnet
  • Lens
  • Lens Testnet
  • Metis Andromeda
  • Metis Sepolia
  • Monad
  • Monad Testnet
  • Moonbase Alpha
  • Moonbeam
  • Moonriver
  • Scroll Mainnet
  • Scroll Sepolia
  • Sonic
  • Sonic Testnet
  • Stable
  • Stable Testnet
  • ZKsync
  • ZKsync Sepolia