一个轻量、高可靠、可扩展的以太坊区块同步与分叉检测中继服务 专为 实时监听、持久化、去重、防分叉 设计,开箱即用,适用于 DeFi、NFT、链上数据索引、监控告警等任何需要可靠链上数据的后端服务。
| 特性 | 说明 |
|---|---|
| 分叉自动检测 + 回滚 | 实时对比 parentHash,自动标记 fork=true,确保链上数据一致性 |
| 重试机制 | retryGetBlockInfoBy* 自动重试,应对节点临时不可用 |
| 批量 RPC 调用 | BatchCall 提升性能,支持一次查询多个余额/交易 |
| Nonce 管理器 | 内置 NonceManager,防止交易重放/丢失 |
| 数据库去重 | 区块/交易插入前查重,避免重复写入 |
| 协程安全 | sync.Mutex 保护共享状态 |
| 完整测试用例 | 覆盖核心功能,接入 Sepolia/本地测试节点 |
| 模块化设计 | dao、model、tool、rpc 分层清晰,易扩展 |
eth-relay/
├── dao/ # 数据库模型 & 连接器
│ ├── block.go # Block 结构体
│ ├── Transaction.go # 交易结构体
│ └── mysql.go # MySQL 连接封装
├── model/ # RPC 返回数据结构
│ ├── full_block.go # 完整区块 + 交易列表
│ ├── transaction.go # 交易数据结构
│ └── eth_call_arg.go # ETH Call 参数结构
├── tool/ # 工具函数
│ ├── tool.go # 工具函数实现
│ └── tool_test.go # 工具函数测试
├── keystores/ # 钱包密钥存储
├── ETH_RPC_Client.go # ETH RPC 客户端封装
├── ETH_RPC_Requester.go # ETH RPC 请求器实现
├── block_scanner.go # 核心:区块扫描器
├── nonce_manager.go # Nonce 管理器
├── main.go # 主程序入口
├── *_test.go # 单元测试
├── go.mod # Go 模块依赖
├── go.sum # 依赖校验
└── README.md # 项目说明文档[ETH Node] ←RPC→ [ETHRPCRequester]
↓
[BlockScanner.Start()]
↓
init() → 获取最新已同步区块
↓
scan() → 获取下一区块
┌─────────┴─────────┐
│ │
[forkCheck] [正常写入]
↓ ↓
标记 fork=true 插入 Block + Tx
↓
继续扫描下一区块
if s.lastBlock.BlockHash != currentBlock.ParentHash {
// 触发分叉 → 递归查找分叉起点 → 标记区间内所有区块为 fork
}- 递归查找
getStartForkBlock直到找到主链交点 - 使用
UPDATE ... WHERE block_number > X AND <= Y批量标记 - 避免数据不一致,适合索引服务
Retry:
fullBlock, err := GetBlockInfoByNumber(targetNumber)
if err != nil && strings.Contains(err.Error(), "empty") {
s.log("获取区块信息,重试一次......", targetNumber.String())
goto Retry
}- 防止节点同步延迟导致空响应
- 配合
time.Sleep(1s)轮询,稳定可靠
client.GetRpc().BatchCall(reqs)GetEthBalances,GetERC20Balances,GetTransactions均支持批量- 减少 RTT,提升性能 3~5 倍
nonceManager.GetNonce(addr) → *big.Int
nonceManager.PlusNonce(addr)- 内存缓存 + RPC 兜底
- 防止
nonce too low/replacement transaction underpriced
Go ≥ 1.23
MySQL ≥ 5.7
Ethereum Node (Infura / Alchemy / Self-hosted / Local)git clone https://github.com/ciphermagic/eth-relay.git
cd eth-relay
go mod tidy
go build -o eth-relayCREATE DATABASE eth_relay CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;# 使用命令行参数
./eth-relay \
--rpc https://sepolia.infura.io/v3/YOUR_INFURA_KEY \
--mysql "root:password@tcp(localhost:3306)/eth_relay?charset=utf8mb4&parseTime=true"
# 或使用环境变量
export ETH_RPC_URL="https://sepolia.infura.io/v3/YOUR_INFURA_KEY"
export MYSQL_DSN="root:password@tcp(localhost:3306)/eth_relay?charset=utf8mb4&parseTime=true"
go run main.go项目支持以太坊钱包的创建和管理:
# 程序将自动在 keystores/ 目录下创建和管理钱包文件-- 区块表
CREATE TABLE eth_block (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
block_number VARCHAR(66) NOT NULL,
block_hash VARCHAR(66) NOT NULL UNIQUE,
parent_hash VARCHAR(66),
create_time BIGINT NOT NULL,
fork TINYINT(1) DEFAULT 0,
INDEX idx_number (block_number),
INDEX idx_fork (fork)
);
-- 交易表
CREATE TABLE eth_transaction (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
hash VARCHAR(66) NOT NULL UNIQUE,
nonce VARCHAR(20),
block_hash VARCHAR(66),
block_number VARCHAR(66),
transaction_index VARCHAR(20),
from_addr VARCHAR(42),
to_addr VARCHAR(42),
value VARCHAR(78),
gas_price VARCHAR(50),
gas VARCHAR(50),
input TEXT,
INDEX idx_block_hash (block_hash),
INDEX idx_from_addr (from_addr),
INDEX idx_to_addr (to_addr)
);# 运行所有测试
go test -v ./...
# 运行特定测试
go test -v -run TestBlockScanner_Start
go test -v -run TestETHRPCRequester_| 测试 | 功能 |
|---|---|
TestBlockScanner_Start |
启动扫描器,监听 Sepolia |
TestETHRPCRequester_GetTransactionByHash |
单交易查询 |
TestETHRPCRequester_GetTransactions |
批量交易查询 |
TestETHRPCRequester_GetETHBalance |
ETH余额查询 |
TestETHRPCRequester_GetEthBalances |
批量ETH余额查询 |
TestETHRPCRequester_GetERC20Balance |
ERC20代币余额查询 |
TestETHRPCRequester_GetLastestBlockNumber |
获取最新区块号 |
TestETHRPCRequester_GetBlockInfoByNumber |
完整区块信息 |
TestETHRPCRequester_GetBlockInfoByHash |
通过哈希获取区块 |
TestETHRPCRequester_CreateETHWallet |
创建以太坊钱包 |
TestETHRPCRequester_SendETHTransaction |
发送ETH交易 |
TestETHRPCRequester_SendERC20Transaction |
发送ERC20代币交易 |
| 指标 | 数据 |
|---|---|
| 同步延迟 | < 3 秒 |
| 分叉检测时间 | < 1 秒 |
| QPS(批量查询) | > 50 |
| 内存占用 | ~30MB |
| CPU | 单核 < 10% |
| 方向 | 实现 |
|---|---|
| WebSocket 订阅 | 替换轮询,使用 eth_subscribe |
| 事件解析 | 集成 abi.Decode 解析 Transfer 事件 |
| Prometheus 监控 | 暴露 /metrics |
| Docker 部署 | Dockerfile + docker-compose.yml |
| 多链支持 | 抽象 ChainConfig,支持 BSC/Polygon |
| GraphQL API | 提供 GraphQL 接口查询链上数据 |
| 缓存层 | 集成 Redis 缓存热点数据 |
| 分布式部署 | 支持多个节点协同工作 |
# 克隆项目
git clone https://github.com/ciphermagic/eth-relay.git
cd eth-relay
# 运行测试
go test -v ./...
# 运行特定包的测试
go test -v ./dao/
go test -v ./model/
go test -v ./tool/
# 代码格式化
go fmt ./...
go vet ./...
# 提交代码
git add .
git commit -m "feat: add new feature"
git push origin main欢迎 PR!我们遵循 Conventional Commits.
MIT License © 2025 www.ciphermagic.cn
Star me on GitHub https://github.com/ciphermagic/eth-relay