区块链基础与链上数据本质:区块、交易、地址、账户模型
链上数据分析的前提,是准确理解区块链底层的数据组织方式。比特币白皮书将区块链定义为“时间戳服务器”,而现代公链(如以太坊、Solana)则在此基础上引入了智能合约与状态机模型。无论哪条链,链上数据的本质都是“状态转换日志”——每一笔交易都在改变全球共享账本的状态。分析师若不能区分UTXO与Account模型的差异,不理解交易生命周期中“广播、打包、确认、回滚”的边界,很容易在地址归集、余额计算、交易有效性判断上出现系统性偏差。本章从区块结构、交易生命周期、账户模型、数据存储索引四个维度,建立链上数据分析的底层坐标系。
一、区块与交易:链上数据的最小单元
1. 核心原理:区块如何组织交易
区块链由按时间顺序链接的区块构成,每个区块包含两部分:区块头与区块体。区块头存储元信息(前一区块哈希、Merkle根、时间戳、难度目标、Nonce),区块体则打包该区块内所有交易。比特币的Merkle树保证交易不可篡改——任意交易变动都会导致Merkle根变化,进而影响后续所有区块哈希。以太坊在此基础上增加了状态根(StateRoot),不仅记录交易,还记录交易执行后的全局状态(账户余额、合约存储)。
| 维度 | 比特币 (UTXO) | 以太坊 (Account) |
|---|---|---|
| 状态存储 | UTXO集合(未花费输出) | 账户状态树(余额+Nonce+存储) |
| 交易本质 | 消费旧UTXO,创建新UTXO | 修改账户状态(转账/合约调用) |
| 余额计算 | 遍历所有UTXO求和 | 直接读取账户字段 |
| 并行性 | 天然支持并行验证 | 需处理Nonce顺序与状态冲突 |
| 隐私性 | 地址可复用但建议一次性 | 同一地址状态累积 |
2. 判断方法:从区块头提取关键指标
链上分析的第一步是解析区块头。以以太坊为例,通过JSON-RPC接口 eth_getBlockByNumber 可获取以下字段:
{
"number": "0x10d4f",
"hash": "0x...",
"parentHash": "0x...",
"timestamp": "0x5f5e100",
"gasUsed": "0x1c9c380",
"baseFeePerGas": "0x3b9aca00",
"transactions": ["0x...", "0x..."]
}
关键分析点:GasUsed/区块GasLimit 反映网络拥堵程度;BaseFee 反映EIP-1559后的基础费用;Timestamp间隔 可用于检测出块异常(如抢跑攻击)。
3. 案例拆解:识别一笔异常转账
假设某地址A向地址B转账100 ETH,但该交易在区块高度15000000被包含,且GasPrice异常高(500 Gwei)。分析路径:
- 检查交易状态:通过
eth_getTransactionReceipt确认status为0x1(成功),否则为0x0(失败)。 - 对比历史行为:地址A过去30天平均GasPrice为20 Gwei,本次异常高说明其急于确认交易(可能是抢购NFT或清算)。
- 追踪资金流向:地址B若为交易所热钱包,则可能是充值;若为合约地址,则可能是参与DeFi操作。
二、地址与账户模型:UTXO vs Account
1. 核心原理:两种模型的本质差异
UTXO模型(比特币、Litecoin、Cardano)中,地址是脚本哈希,余额由多个UTXO组成。每笔交易输入引用之前的UTXO,输出创建新的UTXO。这种设计天然支持隐私(一次性地址)和并行验证,但状态查询复杂。Account模型(以太坊、BSC、Polygon)中,地址是账户标识,余额直接存储在状态树中。合约账户(CA)包含代码和存储,普通账户(EOA)由私钥控制。
2. 判断方法:地址类型识别
- EOA vs CA:通过
eth_getCode判断,若返回"0x"则为EOA,否则为合约。 - 地址生成规则:比特币地址以1/3/bc1开头;以太坊地址为0x+40位十六进制;Solana地址为Base58编码。
- 行为特征:EOA通常直接发起交易;CA只能被调用,其内部逻辑可通过字节码反编译分析。
3. 实战场景:地址归集与风险评分
在反洗钱(AML)场景中,分析师需要将多个地址归集到同一实体。方法包括:
- 共享提现地址:多个地址向同一交易所地址充值,且时间相近。
- 资金链分析:通过图数据库追踪UTXO的合并与拆分(比特币)或账户间转账网络(以太坊)。
- 行为指纹:GasPrice设置习惯、交易时间分布、合约交互偏好。
三、交易生命周期:从构造到不可逆
1. 核心原理:交易的六个阶段
| 阶段 | 状态 | 关键特征 | 分析意义 |
|---|---|---|---|
| 构造 | 本地签名 | Nonce、GasPrice、Data | 可预计算交易哈希 |
| 广播 | Mempool | 等待矿工/验证者打包 | 可监控pending交易 |
| 打包 | 已入块 | 区块高度+索引 | 确认交易已上链 |
| 执行 | 状态变更 | Gas消耗、事件日志 | 解析合约调用结果 |
| 确认 | 1个确认 | 后续区块链接 | 防止双花(重组风险) |
| 不可逆 | 深度确认 | 6+确认(BTC)/ 12+(ETH) | 最终性保障 |
2. 操作流程:监控交易状态
# 以太坊交易状态轮询
tx_hash = "0x..."
receipt = w3.eth.get_transaction_receipt(tx_hash)
if receipt is None:
print("Pending in mempool")
elif receipt.status == 1:
print(f"Success in block {receipt.blockNumber}")
else:
print(f"Failed: {receipt.status}")
3. 案例拆解:抢跑交易分析
某DeFi清算机器人提交清算交易,但被验证者/MEV机器人抢跑。分析步骤:
- 获取Mempool数据:通过Flashbots或私有RPC监控pending交易。
- 对比GasPrice:抢跑者通常设置更高GasPrice(如500 Gwei vs 50 Gwei)。
- 检查区块内顺序:抢跑交易在目标交易之前被打包。
- 计算损失:原交易因滑点或状态变更失败,Gas费损失。
四、数据存储与索引:链上数据的物理层
1. 核心原理:节点如何存储数据
以太坊节点使用LevelDB存储四类数据:区块头、区块体、收据(Receipts)、状态快照。状态数据采用Merkle Patricia Trie结构,键为账户地址或存储槽位,值为RLP编码的状态。比特币使用LevelDB存储UTXO集合和区块索引。
2. 索引策略:从原始数据到分析就绪
- 全节点:存储所有历史数据,可验证但占用空间大(ETH约1TB+)。
- 归档节点:存储所有历史状态,支持任意区块查询,空间需求更高。
- 轻节点:仅存储区块头,依赖其他节点获取状态。
- 外部索引器:如Etherscan、Dune Analytics,将链上数据解析为SQL表,支持复杂查询。
3. 实战场景:构建地址行为分析数据集
以Dune为例,创建地址行为分析查询:
SELECT
from_address,
COUNT(*) AS tx_count,
SUM(value)/1e18 AS total_eth_sent,
MIN(block_time) AS first_seen,
MAX(block_time) AS last_seen
FROM ethereum.transactions
WHERE block_time > NOW() - INTERVAL '30 days'
GROUP BY from_address
HAVING COUNT(*) > 100
ORDER BY total_eth_sent DESC;
五、常见误区与总结复盘
| 误区 | 正确理解 |
|---|---|
| 认为交易确认=最终性 | 存在重组风险,需等待足够确认数 |
| 混淆EOA与合约地址 | 合约地址无私钥,只能被调用 |
| 忽略交易失败记录 | 失败交易也消耗Gas,且可能暴露意图 |
| 只分析转账不解析Input Data | 合约调用才是DeFi分析的核心 |
| 将UTXO地址视为账户 | 比特币地址余额需聚合多个UTXO |