摘要
了解如何使用 eth_getBlockByNumber JSON-RPC 方法获取最新的以太坊区块,包括 curl 和 ethers.js 示例、响应字段和常见陷阱。比较公共、托管和专用 RPC 选项,为您的 dApp 选择合适的端点。
快速解答:使用 eth_getBlockByNumber 并传入 "latest"
要获取最新的以太坊区块,请调用 eth_getBlockByNumber JSON-RPC 方法,参数为 "latest",第二个参数为 false(以省略完整的交易对象)。以下是一个针对公共以太坊端点的最小 curl 示例:
curl -X POST https://eth.api.onfinality.io/public \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false],"id":1}'
响应包含区块头、交易哈希、gas 使用量和时间戳。这是读取链当前头部以进行索引、监控或构建面向用户的功能(如区块浏览器)的标准方式。
决策指南:您应该使用哪个 RPC 端点?
在编写代码之前,请决定哪个以太坊 RPC 端点适合您的工作负载。正确的选择取决于您轮询的频率、是否需要 WebSocket 订阅,以及是否需要历史数据。
| 工作负载 | 推荐端点 | 原因 |
|---|---|---|
| 偶尔读取、原型开发 | 公共端点(例如 https://eth.api.onfinality.io/public) | 免费、无需注册、适合低流量 |
| 生产 dApp、中等流量 | 托管 RPC 服务(例如 OnFinality API) | 更好的可靠性、速率限制和支持 |
| 高频轮询、WebSocket | 专用节点(例如 OnFinality 专用节点) | 无共享速率限制、低延迟、自定义配置 |
| 归档数据、深层历史 | 归档节点(通常通过专用节点) | 需要用于旧区块的 eth_getLogs |
如果您正在构建生产应用,请从托管 RPC 提供商开始,以避免运行自己节点的运维负担。对于高吞吐量或对延迟敏感的场景,请考虑专用节点。有关详细信息,请参阅 RPC 定价 和 支持的 RPC 网络。
什么是 eth_getBlockByNumber?
eth_getBlockByNumber 是一个以太坊 JSON-RPC 方法,返回由区块号或标签指定的区块信息。该方法接受两个参数:
blockNumber(QUANTITY 或 TAG):区块号的十六进制字符串,或标签之一"earliest"、"latest"、"pending"、"safe"或"finalized"。fullTx(BOOLEAN):如果为true,返回完整的交易对象;如果为false,仅返回交易哈希。
当您传入 "latest" 时,节点返回规范链中最新的区块。这相当于其他以太坊 API 中 latest 标签引用的区块。
如何使用 curl 获取最新区块
以下是一个完整的 curl 示例,仅获取包含交易哈希的最新区块:
curl -X POST https://eth.api.onfinality.io/public \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["latest",false],"id":1}'
要获取完整的交易对象,请将 false 改为 true。请注意,如果区块包含许多交易,这可能会产生非常大的响应。
如何使用 ethers.js 获取最新区块
在 ethers.js v6 中,您可以在 provider 上使用 getBlock 方法:
import { ethers } from "ethers";
const provider = new ethers.JsonRpcProvider("https://eth.api.onfinality.io/public");
async function getLatestBlock() {
const block = await provider.getBlock("latest");
console.log(block.number);
console.log(block.hash);
console.log(block.timestamp);
console.log(block.transactions); // 交易哈希数组
}
getLatestBlock();
如果您需要完整的交易对象,请使用 provider.getBlock("latest", true)。
理解响应字段
响应对象包含许多字段。以下是对开发人员最有用的字段:
| 字段 | 描述 |
|---|---|
number | 区块号(十六进制)。 |
hash | 区块哈希。 |
parentHash | 父区块的哈希。 |
timestamp | 区块提议时的 Unix 时间戳。 |
transactions | 交易哈希数组或完整交易对象数组,取决于 fullTx。 |
gasUsed | 区块中所有交易使用的总 gas。 |
gasLimit | 区块 gas 限制。 |
miner | 区块生产者地址(合并后,这是费用接收者)。 |
baseFeePerGas | 此区块的每 gas 基础费用(EIP-1559)。 |
常见陷阱及如何避免
- 使用错误的标签:
"latest"是链的头部,但可能会被重组。如果您需要稳定的引用,请对需要最终性的应用使用"safe"或"finalized"。 - 响应过大:在繁忙的区块上请求
fullTx=true可能返回数兆字节的数据。使用false,并在需要时单独获取交易。 - 速率限制:公共端点通常有速率限制。如果您频繁轮询,可能会遇到错误。请考虑使用托管 RPC 服务或专用节点。
- WebSocket 与 HTTP:对于实时更新,请使用 WebSocket 订阅而不是轮询
eth_getBlockByNumber。OnFinality 在以太坊主网上支持 WebSocket;有关详细信息,请参阅 以太坊网络页面。
何时使用 WebSocket 而不是轮询
每几秒轮询一次 eth_getBlockByNumber 效率低下。如果您的应用需要立即响应新区块,请通过 WebSocket 订阅新区块头:
import { ethers } from "ethers";
const provider = new ethers.WebSocketProvider("wss://eth.api.onfinality.io/public");
provider.on("block", (blockNumber) => {
console.log("新区块:", blockNumber);
});
这会在新区块出现时将区块号推送到您的客户端,从而减少延迟和不必要的请求。
生产就绪检查清单
在您上线之前,请检查此清单:
- 根据您的流量和可靠性需求选择合适的 RPC 提供商。
- 为瞬时错误实现指数退避的重试逻辑。
- 对于需要最终性的应用,使用
"safe"或"finalized"标签。 - 监控您的 RPC 使用情况,并为速率限制错误设置警报。
- 如果您需要一致的性能,请考虑使用专用节点。
关键要点
- 使用
eth_getBlockByNumber并传入"latest"标签来获取当前头部区块。 - 该方法返回区块元数据和交易哈希或完整交易。
- 对于生产环境,请选择托管 RPC 提供商或专用节点,以避免速率限制和停机。
- 对于实时区块更新,WebSocket 订阅比轮询更高效。
常见问题解答
"latest" 和 "safe" 区块有什么区别?
"latest" 是规范链中最新的区块,但可能会被重组。"safe" 是不太可能被重组的区块,而 "finalized" 保证最终性。对于需要最终性的应用,请使用 "safe" 或 "finalized"。
如何仅获取最新的区块号?
您可以调用 eth_blockNumber 来获取最新的区块号(十六进制字符串)。这比获取整个区块更轻量。
为什么我的请求返回错误?
常见错误包括速率限制、无效 JSON 或使用不支持的标签。检查您的端点 URL,并确保您使用的是有效的 JSON-RPC 负载。
我可以在测试网上获取最新区块吗?
可以,在测试网端点上使用相同的方法,例如 Sepolia 的 https://eth-sepolia.api.onfinality.io/public。有关详细信息,请参阅 Sepolia 网络页面。
什么是以太坊的最佳 RPC 提供商?
没有单一的“最佳”提供商;这取决于您的工作负载。在我们的 以太坊 RPC 提供商比较 中比较公共、托管和专用选项。OnFinality 提供托管和专用节点;有关详细信息,请参阅 RPC 定价。