Skip to main content
Monad 支持通过 JSON-RPC 接口与区块链进行交互。Monad 力求尽可能匹配 Geth 的 RPC 行为,但由于架构上的根本差异,某些行为会偏离以太坊。

支持的方法

与以太坊的差异

Monad 与 Geth 兼容,但其架构 —— 包括 异步执行 与亚秒级出块时间 —— 在若干方面引入了行为差异。

交易生命周期

延迟的 nonce/余额验证。 eth_sendRawTransaction 可能不会立即拒绝存在 nonce 缺口或 gas 余额不足的交易。由于 Monad 的 RPC 服务器面向异步执行设计,提交时它可能没有最新的账户状态。这些交易会先被接受,因为它们可能在区块创建期间变为有效。 不支持挂起交易查询。 eth_getTransactionByHash 仅返回已被打包到区块中的交易。查询仍在 mempool 中的交易将返回 null

状态可用性

引用旧状态的 eth_call 调用(即使用旧的区块号)可能失败,因为全节点不提供对任意历史状态的访问。详见 历史数据,了解哪些状态可用以及如何访问。

手续费估算

eth_maxPriorityFeePerGas 目前返回硬编码的建议手续费 2 gwei。这是暂时的做法。 eth_feeHistorynewest_block = latest 时:按照惯例,该方法会返回所请求范围内的手续费历史,加上 一个针对下一区块的额外预测手续费。Monad 没有计算下一区块 base fee 所需的全部输入,因此当最新请求的区块为 latest 时,最新的 baseFeePerGas 会被返回两次。

调试 / 跟踪

必须提供 trace 选项参数。 debug_traceCalldebug_traceTransaction 及相关的 debug_trace* 方法要求显式提供 trace 选项对象。与该参数为可选的标准 EVM 客户端不同,如果省略,Monad RPC 会返回错误 -32602 Invalid params。即使为空也务必包含该参数:
默认 tracer 为 callTracer 当提供空的 trace 选项对象 {} 时,Monad 默认使用 callTracer,而不是其他 EVM 客户端中常见的 struct logs tracer。Monad 目前不支持 VM 级别的操作码 struct logs。

不支持的功能

区块标签

Monad 区块会经历四个 提交状态:ProposedVotedFinalizedVerified。JSON-RPC API 通过标准的以太坊兼容区块标签来暴露这些状态。
"pending" 标签受支持,但其行为与 "latest" 相同。了解更多

未终结的数据

任何包含来自未终结区块数据的 RPC 响应,在后续对同一请求进行时其结果可能发生变化。
  • 带有区块号/标签参数的方法(eth_calleth_getBalanceeth_getLogs 等)—— 当以 "latest" 或未终结的区块号调用时,可能返回未终结的数据。
  • 交易哈希查询(eth_getTransactionByHasheth_getTransactionReceipt)—— 可能命中处于未终结区块中的交易。返回的 blockNumber、日志索引,甚至结果本身(null)都可能发生变化。
  • 隐式 latest 的方法(eth_gasPriceeth_maxPriorityFeePerGas)—— 始终使用 "latest" 标签返回未终结的数据。
将来自未终结区块的数据视为临时数据。对于交易哈希查询,在采取行动之前,请将返回的 blockNumber"finalized" 区块高度(在客户端跟踪)进行比较。

限制

eth_call / eth_estimateGas

每次调用的 gas 限制

节点运营者。使用 --eth-call-provider-gas-limit(默认 30M)和 --eth-estimate-gas-provider-gas-limit(默认 30M)来配置这些限制。

Gas 限制的解析

当调用者指定了 gas 价格(gasPricemaxFeePerGas)时,有效的 gas 限制为 min(gas 限制额度, 提供商 gas 限制),其中 gas 限制额度是给定调用者余额和所指定价格下的最大 gas。当未指定 gas 价格时,直接使用提供商 gas 限制。这与 Geth 的行为一致。

双池执行模型

eth_calleth_estimateGas 请求会根据调用者指定的 gas 限制被路由到两个执行池之一: 当调用者未指定 gas 限制时,请求会先尝试使用低 gas 池。如果出现 gas 耗尽,则会自动重试到高 gas 池。
节点运营者。使用 --eth-call-max-concurrent-requests(默认 1000)和 --eth-call-high-max-concurrent-requests(默认 20)来配置池的并发度。

eth_getLogs

每次调用的区块范围限制

节点运营者。使用 --eth-get-logs-max-block-range 来配置区块范围限制。

为什么区块范围限制这么低?

Monad 每 300ms 产生一个区块,每个区块可容纳最多 3,750 笔交易和高达 150M gas 的计算量。区块既极为频繁,又显著大于以太坊的区块,这是保持每次调用区块范围限制较低的主要原因。

错误

Monad 的 JSON-RPC 错误码力求与以太坊等价,但由于以太坊各客户端之间缺乏标准化,某些错误码有所偏差。

请求级错误 (-32601)

参数错误 (-32602)

执行错误 (-32603)

WebSocket 订阅

Monad 的 RPC 服务器通过 WebSocket 连接支持 JSON-RPC,从而通过 eth_subscribe 实现持久连接和实时数据。有关 eth_subscribe 的一般行为,请参见 Geth 文档 Monad 在标准订阅类型基础上扩展了两种变体(monadNewHeadsmonadLogs),它们包含用于跟踪区块在共识中进展的额外数据。有关推测执行的背景,请参阅 推测式实时数据;关于完整的区块生命周期,请参阅 区块状态

订阅类型

不支持 syncingnewPendingTransactions 订阅类型。

推测型订阅行为

monadNewHeadsmonadLogs 的更新包含两个标准变体中不存在的额外字段:
  • blockId —— 此特定区块提案的唯一标识符(不同于区块号,因为同一高度可能存在多个提案)。
  • commitState —— 区块当前的 提交状态:ProposedVotedFinalizedVerified
同一个区块通常会随着其 commitState 在生命周期内推进而产生多次更新。当共识领先于执行时,区块可能会跳过 Voted 直接从 Proposed 进入 Finalized。当区块未能被终结时,它会被隐式放弃 —— 同一高度上不同区块的终结会取代它,但不会发布明确的放弃事件。