跳转到内容

数据索引

数据索引

本页内容正在整理中,欢迎贡献

概述

直接通过 RPC 轮询区块链以获取历史事件效率极低,且无法进行聚合查询。数据索引层将链上事件提取、存储和索引,让开发者可以通过 SQL 或 GraphQL 高效查询历史数据。

主要内容

主流索引方案对比

方案查询方式自定义程度适合场景
The GraphGraphQL高(自定义 Subgraph)DApp 特定数据、实时
Dune AnalyticsSQL高(自由查询)数据分析、仪表盘
AlchemyREST APINFT、Token、转账数据
MoralisREST API快速原型、NFT 游戏
CovalentREST API多链数据统一查询
Etherscan APIREST API简单查询、免费额度

The Graph

最适合 DApp 的去中心化索引协议:

# 查询 Uniswap V3 top 10 流动性池
{
pools(
first: 10
orderBy: totalValueLockedUSD
orderDirection: desc
where: { totalValueLockedUSD_gt: "1000000" }
) {
id
token0 { symbol }
token1 { symbol }
feeTier
totalValueLockedUSD
volumeUSD
}
}

详见 The Graph 数据查询 页面。

Dune Analytics

适合数据分析和 BI 仪表盘:

-- 查询以太坊每日 DEX 交易量
SELECT
date_trunc('day', block_time) AS day,
SUM(amount_usd) AS volume_usd,
COUNT(*) AS trade_count
FROM dex.trades
WHERE blockchain = 'ethereum'
AND block_time >= NOW() - INTERVAL '30 days'
GROUP BY 1
ORDER BY 1 DESC
  • 访问 dune.com 即可开始查询
  • 丰富的社区 Dashboard 可直接 Fork 使用
  • 支持 Python API 接入自己的应用

Alchemy 增强 API

无需自建索引,直接使用 Alchemy 提供的 API:

import { Alchemy, Network } from "alchemy-sdk";
const alchemy = new Alchemy({
apiKey: process.env.ALCHEMY_API_KEY,
network: Network.ETH_MAINNET,
});
// 获取 NFT
const nfts = await alchemy.nft.getNftsForOwner("0x地址");
// 获取代币余额
const balances = await alchemy.core.getTokenBalances("0x地址");
// 获取历史转账
const transfers = await alchemy.core.getAssetTransfers({
fromBlock: "0x0",
fromAddress: "0x地址",
category: ["erc20", "erc721"],
});
// 批量获取 Token 元数据
const metadata = await alchemy.core.getTokenMetadata("0xToken地址");

Etherscan API(简单场景)

// 获取账户的 ERC-20 代币转账记录
const url = `https://api.etherscan.io/api?module=account&action=tokentx&address=${ADDRESS}&apikey=${ETHERSCAN_KEY}`;
const response = await fetch(url);
const { result } = await response.json();

自建索引(高级)

对于完全自主控制的场景:

工具选项:

  • Ponder —— 基于 Node.js 的以太坊应用框架,类 The Graph 的本地开发体验
  • Envio —— 高性能 Rust 索引器
  • Subsquid —— 去中心化数据湖 + 索引框架
// Ponder 示例(ponder.config.ts)
import { createConfig } from "ponder";
import { MyContractAbi } from "./abis/MyContract";
export default createConfig({
networks: {
mainnet: { chainId: 1, transport: http(process.env.PONDER_RPC_URL_1) },
},
contracts: {
MyContract: {
abi: MyContractAbi,
address: "0x合约地址",
startBlock: 18000000,
},
},
});

选型指南

你的需求是什么?
├── DApp 前端需要查询合约历史事件
│ └── → The Graph(自定义 Subgraph)
├── 数据分析 / 仪表盘
│ └── → Dune Analytics
├── 快速查询 NFT / Token 数据(无需历史事件)
│ └── → Alchemy API / Moralis
├── 多链数据统一
│ └── → Covalent / Moralis
└── 完全自主 + 高性能
└── → Ponder / Envio / 自建 The Graph 节点

深入阅读