Logo
新用户订阅 RPC,首月享 6.5 折优惠查看优惠
OnFinality Learn
网络与协议指南12分钟阅读

以太坊归档节点与历史RPC:查询过去的余额、日志和状态

了解以太坊归档节点存储什么,如何通过RPC查询历史余额、日志和状态,以及如何验证你的端点是否真正提供归档数据。

TL;DR

本指南解释了什么是以太坊归档节点,它与修剪过的全节点有何不同,以及如何通过RPC查询历史状态和日志。它涵盖了相关的JSON-RPC方法,提供了一个可运行的Node.js脚本测试归档支持,并包含一个检查清单以验证你的端点。

直接回答:查询以太坊历史数据需要什么

要查询以太坊历史余额、代码、存储或日志,你需要一个由归档节点支持的RPC端点——或者一个通过Erigon的debug/ots_方法暴露状态历史的节点。标准全节点只保留最新状态,只能回答最新区块的eth_getBalance。归档节点保留所有历史状态,使得在区块1,000,000处查询eth_getBalance成为可能。本指南解释了机制,展示了如何测试任何端点,并提供了一个可复现的脚本。

  • 归档节点:存储完整状态历史,支持在任何过去区块查询。
  • 全节点:修剪历史状态,仅提供最新状态。
  • 区块标签:'latest'、'earliest'、'pending'或十六进制区块号。
  • Erigon归档节点还暴露状态历史RPC方法(debug_和ots_)。

以太坊归档节点与全节点:保留哪些数据

以太坊执行客户端(geth、Erigon、Nethermind、Besu)都暴露相同的JSON-RPC接口,但它们能提供的数据取决于节点的同步模式。全节点(geth默认)下载并验证所有区块,但修剪历史状态树节点,仅保留最新状态。归档节点(geth --syncmode full --gcmode archive)保留每个状态树节点,允许在任何历史区块查询。

Erigon的归档模式更精细:它将状态历史存储为一系列状态差异,不仅支持在旧区块的eth_getBalance,还支持诸如debug_traceTransaction和ots_getTransactionOutput等专门方法。以太坊基金会的归档节点文档JSON-RPC规范是主要的协议参考;Erigon的文档和独立教程(例如M. Hansson的Erigon指南)提供了面向读者的细节。

  • geth全节点:修剪状态,仅提供最新状态。
  • geth归档节点:保留所有状态,提供任何区块。
  • Erigon归档:存储状态历史,支持额外的debug/ots方法。
  • 归档模式是启动配置,不是RPC参数。

读取历史数据的RPC方法

用于历史查询的核心JSON-RPC方法包括eth_getBlockByNumber、eth_getBalance、eth_getCode、eth_getStorageAt、eth_getTransactionCount、eth_getProof和eth_getLogs。每个方法接受一个区块参数,可以是区块号、哈希或标签。例如,使用区块标签'0x0'的eth_getBalance返回创世时的余额。方法集及其语义在官方以太坊JSON-RPC规范中有文档说明,其背后的数据深度在官方以太坊归档节点指南中有解释。

eth_getProof(EIP-1186)返回账户在给定区块的余额、代码哈希、存储根和Merkle证明,用于验证历史状态。eth_getLogs按地址和主题在区块范围内过滤日志,这对于索引历史事件至关重要。

Erigon归档节点还暴露debug_和ots_方法(例如ots_getTransactionOutput、debug_traceBlockByNumber),用于历史重建状态或追踪交易。这些不属于标准以太坊JSON-RPC,但由Erigon文档说明。

  • eth_getBlockByNumber:获取区块头和交易。
  • eth_getBalance / eth_getCode / eth_getStorageAt / eth_getTransactionCount:在区块处读取状态。
  • eth_getProof:获取区块处的Merkle证明(EIP-1186)。
  • eth_getLogs:在区块范围内查询日志。
  • Erigon debug_/ots_:状态历史和追踪。

关键微妙之处:归档是节点模式,不是RPC参数

一个常见的误解是你可以通过指定区块号从任何节点请求历史数据。实际上,节点必须存储了历史状态。如果你在全节点上使用旧区块调用eth_getBalance,它会返回类似'missing trie node'或'historical state not available'的错误。归档模式在节点启动时设置;你不能动态切换。

因此,在选择RPC提供商时,你必须验证端点是否由归档节点支持。像Chainstack、Infura、QuickNode和OnFinality这样的提供商提供归档端点,但保留和可用性各不相同。始终检查提供商的文档以了解归档支持和区块范围。

  • 全节点:在旧区块调用eth_getBalance → 错误。
  • 归档节点:在旧区块调用eth_getBalance → 正确值。
  • 提供商归档端点:有文档,但保留范围不同。
  • 始终使用测试查询验证。

可运行示例:测试你的端点是否支持归档

以下Node.js脚本使用ethers v6来(a)解析历史区块,(b)在该区块和最新区块读取eth_getBalance,以及(c)在有限窗口内分页eth_getLogs并带有退避。将RPC_URL替换为你的端点。脚本打印结果以及端点是否提供历史状态的判断。

预期输出:如果端点是归档的,区块1,000,000处的余额将是一个数字(可能为0),最新余额将不同。如果不是归档的,历史调用将抛出错误。

const { ethers } = require('ethers');

const RPC_URL = 'https://your-rpc-endpoint.example';
const provider = new ethers.JsonRpcProvider(RPC_URL);

async function testArchive() {
  const address = '0x0000000000000000000000000000000000000000'; // zero address
  const historicalBlock = 1000000; // block 1,000,000

  try {
    const historicalBalance = await provider.getBalance(address, historicalBlock);
    console.log(`Balance at block ${historicalBlock}: ${historicalBalance.toString()}`);
  } catch (e) {
    console.log('Historical balance failed:', e.message);
    console.log('Endpoint likely NOT archive.');
    return;
  }

  const latestBalance = await provider.getBalance(address, 'latest');
  console.log(`Balance at latest: ${latestBalance.toString()}`);

  // eth_getLogs paging example
  const filter = {
    address: '0x0000000000000000000000000000000000000000',
    fromBlock: 1000000,
    toBlock: 1000100
  };
  try {
    const logs = await provider.getLogs(filter);
    console.log(`Logs in range: ${logs.length}`);
  } catch (e) {
    console.log('getLogs failed:', e.message);
  }
}

testArchive();

结果表和归档检查清单

针对你的端点运行脚本,并填写下表。'Archive?'列应为'Yes'如果历史余额调用成功,'No'如果抛出错误,'Unknown'如果错误不明确(例如速率限制)。

  • 端点URL:______
  • 历史余额(区块1,000,000):______
  • 最新余额:______
  • 历史调用成功?是/否
  • 返回日志?是/否
  • 归档?是/否/未知

常见失败和修复

查询历史数据时,你可能会遇到错误。以下是常见错误及修复方法。

错误'missing trie node'或'historical state not available'意味着节点不是归档的。切换到归档端点。错误'block not found'可能意味着区块号无效或节点未完全同步。错误'rate limit exceeded'意味着你达到了提供商的速率限制;实现退避或使用更高等级的计划。

  • 缺少trie节点 → 使用归档端点。
  • 区块未找到 → 检查区块号和同步状态。
  • 速率限制 → 添加指数退避重试。
  • eth_getLogs超时 → 减少区块范围并分页。

权衡和限制

归档节点比全节点需要更多的磁盘空间和内存。确切大小因客户端和时间而异;截至2026年,以太坊归档节点可能需要数TB,但这被记录为'因提供商而异'并随时间变化。提供商通常因基础设施成本对归档访问收取更多费用。

历史查询比最新状态查询慢,因为它们需要遍历较旧的状态树。延迟因提供商和网络条件而异;我们不断言具体数字。此外,大范围的eth_getLogs可能消耗大量资源;提供商可能限制范围大小或要求分页。

  • 磁盘空间:归档节点需要更多存储(因提供商而异)。
  • 成本:归档端点通常更昂贵。
  • 性能:历史查询较慢。
  • 提供商限制:日志范围和速率限制各不相同。

后续步骤和进一步阅读

既然你了解了以太坊归档节点和历史RPC,探索相关指南以加深你的知识。有关网络特定细节,请参阅以太坊网络页面。有关一般历史数据技术,请阅读EVM历史数据手册归档节点与全节点比较

如果你正在选择RPC提供商,请查看以太坊RPC节点类型RPC定价。有关性能考虑,请参阅以太坊RPC延迟指南速率限制和429。最后,探索API服务以获取托管端点。

永远不用担心基础设施

OnFinality 消除了 DevOps 的繁重工作,让您能够更聪明、更快地构建。

开始