链上数据是「公开的黄金」——每一笔转账、每一个合约调用都可查询。但原始链数据杂乱无章,直接读事件/交易非常低效。链上数据分析的工程就是**「原始链数据 → 结构化表 → 指标」**的三层管道:Dune 提供免运维的 SQL 分析、The Graph 提供可编程的链下索引与 GraphQL 查询、自建索引器提供完全掌控。
本文系统讲解链上数据栈:数据的获取与索引原理 → Dune Analytics 实战 → The Graph 子图开发 → 常用链上指标与仪表盘 → 协议分析的指标体系 → 自建索引器的工程权衡。
前置:/ethereum-evm-solidity/(事件/交易结构)、/smart-contract-development/(ABI 与事件)、/defi-protocols/(协议机制)。
目录
- 1. 链上数据全景:从区块到指标
- 2. 数据的获取与索引原理
- 3. Dune Analytics:SQL 分析实战
- 4. The Graph:子图开发与 GraphQL
- 5. 常用链上指标与仪表盘
- 6. 协议分析的指标框架
- 7. 自建索引器的工程路径
- 8. 数据分析的常见陷阱
- 9. 从数据到洞察的方法论
- 10. 速查表与一句话记忆
- 延伸阅读
1. 链上数据全景:从区块到指标
区块/交易/事件(原始数据)
│ 解析、索引
▼
结构化表(转账表/调用表/协议表)
│ 聚合、计算
▼
指标(TVL/活跃地址/费用/Gas)→ 仪表盘/报告
三种主流工具:
| 工具 | 定位 | 数据获取方式 |
|---|---|---|
| Dune Analytics | 免运维 SQL 分析 | 平台已索引好原始表 |
| The Graph | 可编程链下索引 | 自定义子图 + GraphQL |
| 自建索引器 | 完全掌控 | 自己跑节点 + 解析 |
认知:Dune 适合「快速出指标」,The Graph 适合「为 DApp 提供查询接口」,自建适合「特殊需求 + 高可控」。
2. 数据的获取与索引原理
链上数据从哪来:
□ 完整节点(Archive Node):全历史状态
□ 数据提供方:Alchemy / Infura / QuickNode 的索引 API
□ 事件日志:日志是「可检索的数据入口」
索引的核心:监听事件 → 解码 ABI → 写入结构化存储:
// 合约里的事件是分析的主数据源
event Transfer(address indexed from, address indexed to, uint256 value);
event Swap(address indexed sender, uint256 amount0In, uint256 amount1In, ...);
监听 Transfer 事件 → 解析成 (from, to, value, block, tx)
→ 聚合表:地址余额、转账量、活跃度
记忆:「事件日志」是链上分析的数据金矿——合约设计的每一个 event 都是未来分析的字段。
3. Dune Analytics:SQL 分析实战
Dune 已把主要链的原始数据索引成可 SQL 查询的表,写 SQL 即可出指标:
-- 查询某 DEX 的日交易量
SELECT
date_trunc('day', block_time) AS day,
SUM(amount_usd) AS volume_usd
FROM dex.trades
WHERE project = 'Uniswap'
AND block_time >= date_trunc('day', now()) - interval '30 days'
GROUP BY 1
ORDER BY 1;
Dune 的核心表:
□ ethereum.transactions / ethereum.logs —— 原始交易与日志
□ dex.trades —— 去中心化交易(标准化)
□ tokens.erc20.stablecoins —— 稳定币转移
□ nft.trades —— NFT 交易
□ labels.accounts —— 地址标签(交易所/协议/巨鲸)
Dune 实战技巧:
□ 用 Spellbook(社区贡献的标准化表)代替裸原始表
□ 地址标签(labels)让结果可读
□ 参数化查询做可复用仪表盘
□ 分区表 + 时间过滤控制查询成本
4. The Graph:子图开发与 GraphQL
The Graph 让开发者定义「子图(Subgraph)」——从链上索引自定义数据,暴露 GraphQL 接口给 DApp。
子图组成:
# subgraph.yaml
specVersion: 1.0.0
description: Uniswap v3 子图示例
schema:
file: ./schema.graphql
dataSources:
- kind: ethereum/contract
name: Factory
network: mainnet
source:
address: "0x1F98431c8aD98523631AE4a59f267346ea31F984"
abi: Factory
mapping:
kind: ethereum/events
apiVersion: 0.0.7
language: wasm/assemblyscript
entities:
- Pool
- Token
eventHandlers:
- event: PoolCreated(...)
handler: handlePoolCreated
# schema.graphql
type Pool @entity {
id: ID!
token0: Token!
token1: Token!
volumeUSD: BigDecimal!
}
// mapping.ts —— 事件处理器
export function handlePoolCreated(event: PoolCreated): void {
let pool = new Pool(event.params.pool.toHexString());
pool.token0 = event.params.token0.toHexString();
pool.volumeUSD = BigInt.fromI32(0);
pool.save();
}
子图开发流程:
1. 定义 schema(实体模型)
2. 写 mapping(事件 → 实体)
3. 部署到 Graph Network(去中心化索引)或自托管
4. DApp 通过 GraphQL 查询
记忆:The Graph = 「把链上事件变成可查询的图数据库」——schema 定义实体、mapping 消费事件、GraphQL 暴露查询,是 DApp 数据层的标准件。
5. 常用链上指标与仪表盘
通用链上指标:
| 指标 | 含义 | 数据源 |
|---|---|---|
| TVL | 锁仓价值 | 各协议持仓聚合 |
| 活跃地址 | 日/周活跃用户 | 交易 from/to 去重 |
| 交易量 | 转账/DEX 成交 | dex.trades |
| Gas 消耗 | 网络拥堵度 | 交易 gasUsed |
| 手续费 | 协议真实收入 | 各协议 fee 事件 |
| 净流入 | 交易所/协议资金流 | 标签地址转账 |
| 鲸鱼行为 | 大额转移/持仓变动 | 余额快照 |
仪表盘构建(Dune):
□ 顶层 KPI:TVL / 交易量 / 活跃用户 时间序列
□ 分布:前 N 协议 / 前 N 地址占比
□ 流入流出:净流向图
□ 异常告警:指标突变检测
6. 协议分析的指标框架
分析一个协议,用「增长 + 留存 + 收入」三层:
增长层:
□ 新增用户 / 新增流动性
□ 交易量增速
□ 活跃度(周/月活)
留存层:
□ 用户留存率(次周活跃)
□ 平均使用频率
□ 老用户 vs 新用户贡献占比
收入层:
□ 协议费用收入(真实现金流)
□ 费用分配(回购/分红/储备)
□ 单位经济(收入/成本)
示例:DEX 分析:
成交量 ✓ TVL ✓ 手续费 ✓ 活跃 trader ✓
周转率(volume/TVL)✓ 滑点与无常损失 ✓
记忆:协议分析三句话——增长看量、健康看留存、价值看收入;只有交易量没有收入的协议,增长是虚的。
7. 自建索引器的工程路径
需要完全掌控或特殊数据时自建:
架构:
节点(Archive)→ 事件抓取 → 解码 ABI → 存储(Postgres)→ 指标计算 → API
关键工程决策:
| 决策 | 选项 |
|---|---|
| 数据源 | 自建节点 / Alchemy API / 第三方索引 |
| 存储 | Postgres(关系)/ ClickHouse(分析) |
| 索引方式 | 实时事件流 + 定期重放(回填) |
| 解码 | ethers.js / viem / ABI 缓存 |
| 调度 | 从「最新区块」持续消费,失败重试 |
自建的坑:
□ 回填历史(从创世拉到最新)要大量时间与存储
□ 节点同步失败/重组 → 数据一致性处理
□ 多链扩展成本高
□ 维护成本(监控/升级)不可忽略
决策:多数场景 Dune/子图够用——自建留给「实时性要求高 + 指标特殊 + 数据量大」的场景。
8. 数据分析的常见陷阱
链上分析容易踩的坑:
□ 忽略「测试/刷量」地址:高额交易可能是自转/清洗交易
□ 只算总量不算子集:TVL 高但真实需求小
□ 指标口径不一:不同来源的「交易量」定义不同
□ 忽略 L2 与跨链:单链指标不完整
□ 时间序列未对齐:UTC 时区/分片
□ 地址标签过期:标签库更新滞后
规避方法:
□ 用「真实用户」过滤(去重 + 排除合约/机器人)
□ 多指标交叉验证(成交 + 用户 + 收入)
□ 明确指标口径并文档化
□ 数据快照与回溯(可复现)
记忆:链上数据公开不等于可信——刷量、自转、口径不一都会骗人,交叉验证与真实用户过滤是基本功。
9. 从数据到洞察的方法论
数据分析 ≠ 画图,产出洞察的路径:
1. 定义问题:要回答什么(如「新用户来自哪」)
2. 选指标:用哪些指标回答(新增/留存/来源分布)
3. 拆解:按渠道/时间/细分群
4. 找异常:对比基准与突变
5. 验证:假设与数据交叉
6. 行动:把洞察转成产品/策略决策
示例:
问题:为什么新用户活跃下降?
数据:新用户次日留存下降 + 渠道来源偏移 + 新手任务完成率低
洞察:导流渠道质量下降 + 新手引导缺陷
行动:渠道加权 + 优化 onboarding
心法:链上分析的价值在「可执行的洞察」,不在「漂亮的仪表盘」——先定义问题,再选指标。
10. 速查表与一句话记忆
| 需求 | 工具 |
|---|---|
| 快速出指标 | Dune(SQL + Spellbook) |
| DApp 数据接口 | The Graph 子图 + GraphQL |
| 地址归类 | labels.accounts 标签 |
| 实时/特殊需求 | 自建索引器 |
| 协议分析 | 增长/留存/收入三层 |
| 通用指标 | TVL/活跃/交易量/费用/Gas |
| 防刷量 | 真实用户过滤 + 交叉验证 |
| 洞察产出 | 定义问题 → 指标 → 验证 → 行动 |
一句话记忆:链上数据分析是「原始链数据 → 结构化表 → 指标 → 洞察」的管道——Dune 快、子图可编程、自建最可控;防刷量靠交叉验证,价值在可执行的洞察。
延伸阅读
- /ethereum-evm-solidity/ — 交易与事件结构
- /smart-contract-development/ — ABI 与事件设计
- /defi-protocols/ — 协议机制与数据对应
- /blockchain-mev-pbs/ — 交易排序与数据分析
- /blockchain-tokenomics-design/ — 指标驱动的代币分析
- [[blockchain-web3]] — 区块链 Web3 专题
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。