摘要
币安智能链(BNB Smart Chain)归档节点保存链的完整历史状态,因此您可以查询任意过去区块高度上的余额、存储槽和合约状态。标准全节点会修剪旧状态,这就是为什么针对它们的历史查询会失败。归档访问对于分析、税务和会计工具、索引器以及任何需要重建特定区块发生情况的后端来说都是必不可少的。您可以通过 OnFinality 的 RPC API 连接到支持归档的端点,或者在工作负载需要持续的历史吞吐量时运行专用归档节点。
如果您搜索了币安智能链归档节点,您可能遇到了两个障碍之一:历史查询返回错误,或者提供商告诉您归档访问费用更高。本页解释了归档节点实际存储什么,如何判断您是否需要它,以及如何连接到支持归档的 BNB Chain 基础设施而不会过度配置。
您真的需要归档节点吗?
大多数应用程序不需要。标准全节点保留最近状态和完整的区块,这足以发送交易、读取当前余额和订阅新事件。归档节点用于查询更早的状态。
在您配置任何东西之前,请使用这个快速测试:
- 如果您只读取最新区块或最近几千个区块,全节点就足够了。
- 如果您需要几个月或几年前特定区块的余额、存储槽或合约调用结果,则需要归档状态。
- 如果您运行从创世区块重放历史的索引器,则需要归档状态以及持续历史读取的计划。
- 如果您构建税务、会计或审计工具,归档状态通常是硬性要求,因为您必须在任意时间戳重建持有量。
一个有用的规则:当您将明确的历史区块号传入查询并期望得到正确答案时,您就进入了归档领域。
归档节点存储而全节点不存储的内容
BNB Smart Chain 与 EVM 兼容,因此归档概念与以太坊一致。节点维护两件事:区块和交易链,以及将账户和合约映射到其当前值的状态树。
全节点修剪旧状态以节省磁盘。如果您询问该区块中的交易,它仍然可以告诉您区块 20,000,000 中发生了什么,因为区块被保留。它无法可靠回答的是“该账户在区块 20,000,000 时的余额是多少”或“该存储槽当时持有什么值”,因为该高度的状态已被丢弃。
归档节点保留每个历史状态根,因此任何过去区块的状态查询都能正确解析。这就是全部区别,也是归档节点更大、运营成本更高的原因。
链设置一览
当您为 BNB Chain 配置客户端或钱包时,请使用正确的网络参数。下表反映了您需要的主网和测试网设置。
| 设置 | BNB Smart Chain 主网 | BNB Chain 测试网 |
|---|---|---|
| 链 ID | 56 | 97 |
| 原生货币 | BNB(18 位小数) | tBNB(18 位小数) |
| 区块浏览器 | https://bscscan.com | https://testnet.bscscan.com |
| 传输 | HTTP, WebSocket | HTTP |
| 典型用途 | 生产归档查询 | 在主网前测试归档逻辑 |
对于托管端点,OnFinality 通过其 BNB Chain RPC 服务 公开 BNB Smart Chain。测试网工作应指向 BNB Chain 测试网端点,以免意外查询生产状态。
如何通过 JSON-RPC 查询历史状态
需要归档状态的方法是那些接受区块参数的方法。如果您传入区块号而不是 latest,节点必须能够解析该高度的状态。
curl -s https://bnb.api.onfinality.io/public \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_getBalance",
"params": ["0x0000000000000000000000000000000000000000", "0x1B4AF0"]
}'
第二个参数是十六进制的区块号。将其替换为您关心的历史区块。同样的模式适用于 eth_getStorageAt、eth_getCode、eth_getTransactionCount 和 eth_call,当您传入区块标签时。
在 JavaScript 中使用标准 EVM 库时,区块标签是最后一个参数:
import { JsonRpcProvider } from "ethers";
const provider = new JsonRpcProvider("https://bnb.api.onfinality.io/public");
// Read a balance at a specific historical block
const balance = await provider.getBalance(
"0x0000000000000000000000000000000000000000",
28_000_000
);
console.log(balance.toString());
如果端点不支持归档,这些调用通常会失败并显示有关缺少 trie 节点或状态不可用的消息,而不是返回错误的数字。该错误是您指向了修剪节点的信号。
BNB Chain 的归档访问选项
有三种实用方法可以获取归档状态,它们的主要区别在于您承担多少运营工作。
| 选项 | 您获得什么 | 运营负载 | 最适合 |
|---|---|---|---|
| OnFinality RPC API | 通过 HTTP 和 WebSocket 的托管归档访问 | 低,提供商处理节点 | 希望无需运行硬件即可进行归档查询的应用、索引器和后端 |
| OnFinality 专用节点 | 为您的工作负载配置的节点 | 低到中,您负责规模和监控 | 具有稳定历史读取量或隔离需求的团队 |
| 自托管归档节点 | 完全控制客户端和数据 | 高,您处理磁盘、同步和升级 | 具有严格数据驻留或自定义客户端需求的团队 |
OnFinality 为 BNB Chain 提供托管的 RPC API 服务 和 专用节点 选项。正确的选择取决于您的历史查询量有多可预测。偶发的归档读取通常适合托管端点;连续重放或繁重的 eth_getLogs 和状态读取通常需要专用节点。
生产就绪检查清单
在将生产流量路由到归档状态之前,请确认以下内容:
- 您的客户端仅在需要归档状态的地方传递明确的区块号,这样您就不会为最新状态读取支付归档成本。
- 您有一个备用端点或第二个提供商路径,以便在单个端点降级时使用。
- 您了解您的历史读取量,特别是
eth_getLogs范围,这可能是最繁重的归档工作负载。 - 您已在测试网上测试了相同的查询,然后再指向主网。
- 您知道您的应用程序实际需要哪个区块范围,这样您就不会请求超出必要的历史记录。
如果您仍在共享和专用容量之间做决定,RPC 提供商选择指南 更深入地介绍了评估标准。
常见故障模式及如何解读
归档问题通常表现为特定错误,而不是静默的错误答案。了解症状可以节省调试时间。
| 症状 | 可能原因 | 下一步 |
|---|---|---|
| “missing trie node” 或状态不可用 | 端点是修剪的全节点 | 切换到支持归档的端点 |
| 查询对最近区块有效,对旧区块失败 | 部分归档或保留限制 | 确认您的提供商保留的归档深度 |
宽泛的 eth_getLogs 范围超时 | 范围对于单个请求太大 | 拆分为更小的区块范围并分页 |
| 不同提供商的结果不一致 | 不同的归档深度或重组处理 | 标准化一个归档源用于历史读取 |
| 首次查询慢,重复查询快 | 历史状态的冷缓存 | 预热关键范围或使用专用节点 |
一个常见的错误是假设每个 RPC 端点都支持归档。许多公共和共享端点不支持,它们会在历史状态调用时失败。在构建依赖之前,始终验证归档支持。
规模和成本考虑
归档节点很大,因为它们保留所有历史状态。磁盘、同步时间和 I/O 是主要成本,并且随着链龄增长。这就是为什么归档访问通常与标准 RPC 定价不同。
当您比较选项时,请查看归档读取如何计费或限制,是否支持 WebSocket 归档订阅,以及提供商是否为完整链历史保留归档状态还是仅保留最近窗口。有关当前计划详情,请参阅 RPC 定价 和 支持的 RPC 网络 列表以确认 BNB Chain 覆盖。
如果您的工作负载稳定且高容量,专用节点可能比按量计费的归档调用更可预测。如果是偶发的,托管端点避免了运行和同步自己的归档节点的开销。
关键要点
- 归档节点保留历史状态,因此您可以查询任意过去区块的余额、存储和合约状态。
- 全节点保留区块但修剪旧状态,这就是为什么历史状态查询对它们失败。
- 当您传递明确的历史区块号、重放历史或构建审计和会计工具时,您需要归档状态。
- BNB Smart Chain 主网使用链 ID 56;测试网使用链 ID 97。
- OnFinality 为 BNB Chain 提供托管 RPC 和专用节点选项,因此您可以根据工作负载而不是硬件来选择。
- 在依赖归档支持之前验证它,并拆分宽泛的日志查询以避免超时。
常见问题
BNB Chain 归档节点与以太坊归档节点相同吗?
概念上是的。BNB Smart Chain 与 EVM 兼容,因此归档模型、需要历史状态的 JSON-RPC 方法以及故障症状都相同。链设置不同,因此主网使用链 ID 56,测试网使用 97。
我可以使用公共 RPC 端点进行归档查询吗?
有时可以,但不可靠。许多公共和共享端点运行修剪的全节点,并会为历史状态返回缺少 trie 节点的错误。在端点上构建之前确认归档支持。
归档状态可以追溯到多久以前?
这取决于提供商或您自己的节点配置。有些保留完整历史;其他保留最近窗口。如果您的应用程序需要深层历史,请明确确认归档深度。
我需要专用节点进行归档访问吗?
不一定。偶发的历史读取通常适合托管端点。连续重放、繁重的日志查询或隔离要求更适合专用节点。
为什么我的历史查询返回错误而不是错误的值?
因为节点无法解析该高度的状态。修剪节点没有历史状态根,因此它使请求失败而不是猜测。将查询指向支持归档的端点即可修复。