跳转到主要内容

概述

OrbitFlare 运行完整归档节点,保留自 Solana 启动以来的每一个区块、交易和账户状态。标准 RPC 提供商通常会裁剪较旧的数据以节省存储空间,仅保留最近的 epoch。使用 OrbitFlare,您可以查询 Solana 历史中的任何 slot。

使用场景

历史区块链数据支持多种重要工作流:
  • 事件恢复:在索引器停机或 webhook 失败后回填缺失的交易
  • 合规:检索用于审计和监管要求的交易记录
  • 研究:分析链上趋势、代币分布和协议指标的历史变化
  • 浏览器应用:构建显示完整历史的区块浏览器和仪表板

相关 RPC 方法

这些方法支持在 OrbitFlare 归档节点上的历史查询:

区块方法

方法描述
getBlock检索任何 slot 的完整区块数据
getBlocks获取两个 slot 之间的已确认区块列表
getBlocksWithLimit从某个 slot 开始获取指定数量的已确认区块
getBlockTime获取区块的预估 Unix 时间戳
getBlockHeight获取当前区块高度
getFirstAvailableBlock获取有区块数据的最低 slot

交易方法

方法描述
getTransaction按签名检索已确认的交易
getSignaturesForAddress获取某地址的交易签名
getSignatureStatuses获取交易签名的状态

账户方法

方法描述
getAccountInfo获取账户数据(仅当前状态)
getMultipleAccounts单次调用获取多个账户的数据
getProgramAccounts获取程序拥有的所有账户

Slot 方法

方法描述
getSlot获取当前 slot
minimumLedgerSlot获取节点拥有数据的最低 slot

示例

从历史中检索区块

使用 getBlock 获取 slot 100,000,000 的区块数据:
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getBlock",
  "params": [
    100000000,
    {
      "encoding": "json",
      "transactionDetails": "full",
      "rewards": false,
      "maxSupportedTransactionVersion": 0
    }
  ]
}'

获取区块时间戳

使用 getBlockTime 查询特定区块的生产时间:
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getBlockTime",
  "params": [100000000]
}'

列出范围内的区块

使用 getBlocks 获取两个 slot 之间的所有已确认区块:
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getBlocks",
  "params": [100000000, 100000100]
}'

获取交易

使用 getTransaction 按签名检索交易详情:
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getTransaction",
  "params": [
    "5wHu1qwD7q5menP8rgbzknAHruqg7rq1BwLNjmKnMwVH2VNhVvPLT6jGfKNLwKUTG4Xn2vRvDz5Q6Z8zCLN5gLp1",
    {
      "encoding": "json",
      "maxSupportedTransactionVersion": 0
    }
  ]
}'

获取地址的交易历史

使用 getSignaturesForAddress 检索地址的签名:
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getSignaturesForAddress",
  "params": [
    "Vote111111111111111111111111111111111111111",
    {"limit": 100}
  ]
}'

TypeScript 示例

获取历史区块数据

import { Connection } from '@solana/web3.js';

const connection = new Connection('https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY');

async function getHistoricalBlock(slot: number) {
  const block = await connection.getBlock(slot, {
    maxSupportedTransactionVersion: 0,
  });

  if (block) {
    console.log(`Block ${slot}:`);
    console.log(`  Transactions: ${block.transactions.length}`);
    console.log(`  Block time: ${block.blockTime}`);
    console.log(`  Parent slot: ${block.parentSlot}`);
  }

  return block;
}

// Fetch a block from early 2023
const block = await getHistoricalBlock(175000000);

构建完整交易历史

结合 getSignaturesForAddressgetTransaction 构建完整历史:
import { Connection, PublicKey } from '@solana/web3.js';

const connection = new Connection('https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY');

async function getFullTransactionHistory(address: string) {
  const pubkey = new PublicKey(address);
  const allTransactions = [];
  let before: string | undefined;

  // Paginate through all signatures
  while (true) {
    const signatures = await connection.getSignaturesForAddress(pubkey, {
      limit: 1000,
      before,
    });

    if (signatures.length === 0) break;

    // Fetch full transaction data in batches
    for (let i = 0; i < signatures.length; i += 10) {
      const batch = signatures.slice(i, i + 10);
      const txs = await Promise.all(
        batch.map(sig =>
          connection.getTransaction(sig.signature, {
            maxSupportedTransactionVersion: 0,
          })
        )
      );
      allTransactions.push(...txs.filter(tx => tx !== null));
    }

    before = signatures[signatures.length - 1].signature;
  }

  return allTransactions;
}

按时间范围查询区块

查找特定时间段内的区块:
async function getBlocksInTimeRange(startTime: number, endTime: number) {
  // Get a starting slot estimate
  const currentSlot = await connection.getSlot();
  const currentTime = Math.floor(Date.now() / 1000);

  // Solana produces ~2-3 blocks per second
  const slotsPerSecond = 2.5;
  const estimatedStartSlot = currentSlot - Math.floor((currentTime - startTime) * slotsPerSecond);

  const blocks = [];
  let slot = estimatedStartSlot;

  while (true) {
    const blockTime = await connection.getBlockTime(slot);

    if (blockTime && blockTime >= startTime && blockTime <= endTime) {
      const block = await connection.getBlock(slot, {
        maxSupportedTransactionVersion: 0,
      });
      if (block) blocks.push({ slot, block });
    }

    if (blockTime && blockTime > endTime) break;
    slot++;
  }

  return blocks;
}

性能提示

  1. 批量请求:使用 JSON-RPC 批量请求在一次调用中获取多个区块或交易
  2. 大查询分页getSignaturesForAddress 方法每次调用最多返回 1000 个签名——使用 before 参数进行分页
  3. 谨慎并行化:以 10-20 个为一批并行获取交易,以平衡速度和速率限制
  4. 缓存不可变数据:历史区块和交易一旦确认就不会改变——在本地缓存它们
  5. 使用 maxSupportedTransactionVersion:始终包含此参数以处理版本化交易

限制

账户状态历史:Solana 节点存储当前账户状态,而非历史快照。您可以检索修改了某账户的交易,但无法获取该账户在特定过去 slot 的余额或数据。 速率限制:历史查询可能消耗更多资源。检查您计划的速率限制并实施适当的节流。

更快的交易历史

要高效查询地址历史,请使用 getTransactionsForAddress,它将签名查找和交易检索合并为单次调用,并提供过滤和排序选项。

管理回填

对于需要大规模历史数据交付而无需自行编写 ETL 管道的团队,OrbitFlare 提供管理回填服务。
管理回填是一项企业服务。在 Discord 上联系团队或发送邮件至 sales@orbitflare.com 讨论您的需求。

服务内容

OrbitFlare 工程师将结构化的 Solana 历史数据直接提取并交付到您的存储系统:
输出格式支持的目标存储
JSON(换行分隔)AWS S3、Google Cloud Storage
ParquetAWS S3、Google Cloud Storage
SQLPostgreSQL、ClickHouse

可交付内容

  • 特定程序、钱包或代币铸造地址的所有交易
  • 任意 slot 范围的完整区块数据
  • 代币转账历史(SPL Token / Token-2022)
  • 基于您需求的自定义查询和数据结构

服务级别协议

项目详情
交付时间标准回填 3–5 个工作日
数据覆盖范围创世块(2020 年 3 月)至今
格式JSON、Parquet 或 SQL——由您选择
专属支持任务期间分配专属工程师

适用场景

管理回填最适合以下情况:
  • 初始化新的索引器或分析数据库
  • 一次性合规或审计数据请求
  • 历史机器学习/AI 训练数据集
  • 长时间停机后的数据回填
如需持续流式传输新数据,请改用 gRPC 流式传输 端点。