第一章:Uniswap V4 Hook开发中Solidity的不可替代性
在Uniswap V4架构中,Hook作为链上可编程扩展点,其生命周期钩子(如beforeSwap、afterInitialize)必须直接运行于EVM环境中。这决定了Solidity不仅是首选语言,更是技术约束下的唯一可行选择——Vyper虽为替代方案,但缺乏对call上下文变量(如msg.sender、block.timestamp)的细粒度访问能力,且不支持内联汇编中对calldata长度与偏移的动态校验,而这些恰是Hook安全验证的关键。
为什么不能用高级语言生成字节码
- WebAssembly(WASM)无法原生访问EVM状态(如
slot读写),而Hook需实时读取池状态变量; - TypeScript/Python等语言编译出的字节码不兼容EVM调用约定,无法响应
UNISWAP_V4_HOOK接口ABI; - EVM没有标准系统调用层,所有存储、调用、事件均依赖Solidity内置操作符(如
assembly { sload(slot) })。
Hook合约必须满足的底层契约
// 示例:一个合规的流动性激励Hook片段
contract LiquidityIncentiveHook {
// 必须实现IHook接口,且函数签名严格匹配V4预期
function beforeSwap(
address, // pool
bool zeroForOne,
int256 amountSpecified,
uint160 sqrtPriceLimitX96,
bytes calldata hookData // ← 此参数由调用方传入,Solidity可直接解码
) external override {
// 仅Solidity能在此处安全解析hookData:
// 1. 使用abi.decode()提取结构化数据
// 2. 调用sload()校验激励池余额
// 3. 发送emit事件供前端监听
(uint128 liquidityReward) = abi.decode(hookData, (uint128));
if (liquidityReward > 0) {
emit RewardClaimed(msg.sender, liquidityReward);
}
}
}
关键能力对比表
| 能力 | Solidity | Vyper | Rust(via WASM) |
|---|---|---|---|
直接访问slot地址 |
✅ | ⚠️(受限) | ❌ |
动态calldata长度检查 |
✅(calldatasize()) |
❌ | ❌ |
| 内联EVM汇编控制gas消耗 | ✅ | ❌ | ❌ |
实现IHook ABI兼容函数 |
✅ | ❌(无override语义) |
❌ |
任何试图绕过Solidity的方案,都会在beforeSwap执行时因revert或invalid opcode失败——因为Uniswap V4 Router在调用Hook前,会强制校验目标合约是否包含正确selector且返回值布局匹配。这是协议层硬编码的安全栅栏,不可协商。
第二章:Go语言在区块链监控系统中的工程化优势
2.1 Go并发模型与高吞吐链上事件采集的实践验证
为支撑每秒万级区块事件的实时捕获,我们基于 Go 的 goroutine + channel 模型构建了分层采集器:
数据同步机制
采用“监听-分发-处理”三级流水线:
- 监听层:长连接轮询节点 RPC,按区块高度切片;
- 分发层:通过带缓冲 channel(
make(chan *Event, 1024))解耦生产/消费; - 处理层:启动固定 worker 池(
runtime.NumCPU()个 goroutine)并行解析 ABI。
// 初始化事件分发通道与工作池
eventCh := make(chan *Event, 1024)
for i := 0; i < runtime.NumCPU(); i++ {
go func() {
for evt := range eventCh {
processABI(evt) // 同步解析日志Topic与Data
}
}()
}
buffer size=1024 平衡内存占用与背压响应;runtime.NumCPU() 避免过度调度开销,实测吞吐提升 3.2×。
性能对比(单节点采集 10k 事件/秒)
| 方案 | 延迟 P95 (ms) | CPU 利用率 | GC 次数/分钟 |
|---|---|---|---|
| 单 goroutine | 420 | 38% | 12 |
| goroutine 池 | 86 | 71% | 3 |
graph TD
A[RPC 轮询] --> B[区块解析]
B --> C[事件过滤]
C --> D[chan<- Event]
D --> E[Worker Pool]
E --> F[DB 写入 & Kafka 推送]
2.2 Go模块化设计支撑多源异构节点(Ethereum、Base、Polygon)统一监控
Go 的接口抽象与依赖注入机制天然适配多链适配场景。核心采用 NodeClient 接口统一收口差异:
type NodeClient interface {
GetBlockByNumber(ctx context.Context, num *big.Int) (*types.Block, error)
GetTransactionCount(ctx context.Context, addr common.Address, blockNum *big.Int) (uint64, error)
ChainID() *big.Int
}
// 实现示例:Polygon 客户端复用以太坊 SDK,仅重写链标识与 RPC 路由策略
逻辑分析:
ChainID()方法驱动路由分发;GetBlockByNumber封装各链对blockNumber参数的语义差异(如 Polygon 支持"latest"或"safe"标签,Ethereum 仅支持"latest"/"pending")。参数ctx支持超时与取消,保障跨链调用可观测性。
多链能力映射表
| 链名 | RPC 协议兼容性 | 原生区块确认模型 | 监控指标扩展点 |
|---|---|---|---|
| Ethereum | JSON-RPC 2.0 | 最终性弱(PoW/PoS) | uncle rate, reorg depth |
| Base | 兼容 Ethereum | Optimistic Rollup | batch submission lag |
| Polygon | 扩展 JSON-RPC | PoS + Checkpoint | sync progress % |
数据同步机制
- 所有客户端共享
BlockPoller模块,通过chainID动态注册轮询周期(Ethereum: 12s,Base: 2s,Polygon: 2.5s) - 使用
sync.Map缓存各链最新区块头,避免重复解析
graph TD
A[统一Metrics Collector] --> B{Router by chainID}
B --> C[Ethereum Client]
B --> D[Base Client]
B --> E[Polygon Client]
C --> F[Prometheus Exporter]
D --> F
E --> F
2.3 Go原生交叉编译能力实现跨平台eBPF探针快速分发
Go 的 GOOS/GOARCH 环境变量与 //go:build 指令天然支持无依赖交叉编译,为 eBPF 用户态加载器(如 libbpf-go 封装程序)提供跨平台构建能力。
编译流程示意
# 构建 ARM64 Linux 探针加载器(无需目标平台工具链)
GOOS=linux GOARCH=arm64 go build -o probe-arm64 ./cmd/probe
该命令生成静态链接二进制,内嵌 eBPF 字节码(通过
--ldflags="-extldflags '-static'"保证 libc 隔离),规避目标环境 glibc 版本兼容问题。
支持的目标平台矩阵
| GOOS | GOARCH | 典型场景 |
|---|---|---|
| linux | amd64 | x86_64 云主机 |
| linux | arm64 | AWS Graviton / 边缘设备 |
| linux | riscv64 | 新兴国产服务器平台 |
构建策略演进
- ✅ 单仓库多架构:
make build-all并行触发全平台构建 - ✅ eBPF 字节码分离:
.o文件通过embed.FS打包进二进制,运行时按需加载 - ❌ 不依赖 Docker 构建容器:避免引入额外调度与镜像分发开销
graph TD
A[源码含eBPF C + Go加载器] --> B{go build<br>GOOS=linux GOARCH=arm64}
B --> C[静态二进制 probe-arm64]
C --> D[直接scp至ARM64节点]
D --> E[./probe-arm64 --load]
2.4 Go+eBPF零拷贝数据通路构建亚毫秒级交易流捕获管道
为突破传统 socket + userspace copy 的延迟瓶颈,本方案在内核态部署 eBPF 程序直接解析 TCP payload 中的 FIX/Protobuf 交易报文,并通过 perf_event_array 零拷贝环形缓冲区投递至 Go 用户态。
数据同步机制
Go 端使用 github.com/cilium/ebpf/perf 库轮询 perf ring buffer,避免系统调用阻塞:
// 初始化 perf reader,ring size = 4MB(64 pages)
reader, _ := perf.NewReader(ringMap, 4*1024*1024)
for {
record, err := reader.Read()
if err != nil { continue }
// 解析二进制交易头:ts_ns(uint64) + symbol_len(uint8) + symbol([]byte)
ts := binary.LittleEndian.Uint64(record.Raw[:8])
symLen := uint8(record.Raw[8])
symbol := string(record.Raw[9 : 9+symLen])
}
逻辑分析:
perf.NewReader绑定 eBPF map 后,内核自动将bpf_perf_event_output()写入的数据以页对齐方式提交;record.Raw指向 mmap 映射的只读内存页,无内存复制。ts_ns提供纳秒级时间戳,用于后续微秒级排序。
关键参数对照表
| 参数 | 推荐值 | 说明 |
|---|---|---|
ring_size |
4 MiB | 平衡延迟与丢包率,实测 >200k msg/s 下丢包率 |
sample_period |
1 | 每匹配报文触发一次 eBPF 输出 |
map_type |
BPF_MAP_TYPE_PERF_EVENT_ARRAY |
唯一支持零拷贝用户态消费的 map 类型 |
流程概览
graph TD
A[TCP RX SKB] --> B[eBPF TC_INGRESS]
B --> C{FIX header pattern match?}
C -->|Yes| D[bpf_perf_event_output]
D --> E[Perf Ring Buffer]
E --> F[Go perf.Reader.Read]
F --> G[无锁通道分发至处理 goroutine]
2.5 Go生态工具链(pprof、trace、ebpf-go)驱动监控系统可观测性闭环
Go 生态提供三类互补的可观测性支柱:运行时性能剖析、全链路追踪与内核级行为捕获。
pprof:轻量级运行时火焰图生成
启用 HTTP 端点采集 CPU/heap 数据:
import _ "net/http/pprof"
func main() {
go func() {
log.Println(http.ListenAndServe("localhost:6060", nil))
}()
// 应用主逻辑...
}
net/http/pprof 自动注册 /debug/pprof/* 路由;go tool pprof http://localhost:6060/debug/pprof/profile 触发 30 秒 CPU 采样,支持火焰图可视化与调用热点下钻。
trace:用户态事件时间线建模
import "runtime/trace"
func handler(w http.ResponseWriter, r *http.Request) {
trace.WithRegion(r.Context(), "http-handler", func() {
// 业务处理
})
}
trace.WithRegion 在 go tool trace 可视化中生成嵌套时间块,精确对齐 goroutine 调度、GC、阻塞 I/O 事件。
ebpf-go:内核态零侵入观测
| 工具 | 观测维度 | 数据源 |
|---|---|---|
| pprof | Go 运行时指标 | GC、goroutine、heap |
| trace | 用户代码时序 | runtime trace events |
| ebpf-go | 系统调用/网络栈 | eBPF probes |
graph TD
A[应用代码] --> B[pprof HTTP 端点]
A --> C[runtime/trace 注入]
A --> D[ebpf-go attach kprobe]
B --> E[火焰图/内存分析]
C --> F[时序事件流]
D --> G[syscall 延迟/连接跟踪]
E & F & G --> H[统一指标平台]
第三章:eBPF作为确定性与实时性交汇点的技术本质
3.1 eBPF verifier机制保障内核级执行的确定性边界
eBPF程序在加载到内核前,必须通过严格静态验证——verifier是唯一可信守门人,确保程序无死循环、内存安全、类型正确且资源有界。
验证核心约束
- ✅ 有限指令数(默认上限1M条,可调)
- ✅ 所有分支必须可达且收敛(DAG化控制流)
- ✅ 每次内存访问需经指针类型与范围双重校验
- ❌ 禁止任意跳转、函数指针调用、全局变量写入
控制流不可达性检测示例
// bpf_prog.c:触发verifier拒绝的典型模式
if (ctx->len < 10) {
return 0;
}
// verifier推导出:此后ctx->data + 10必在有效范围内
char val = *(u8*)(ctx->data + 10); // ✅ 合法访问
if (false) {
*(u64*)0 = 0; // ⚠️ 不可达代码,但verifier仍会解析其内存操作语义
}
该代码中
if(false)块虽永不执行,verifier仍对其做完整路径分析——因需保证所有代码路径均满足内存安全。ctx->data + 10的合法性依赖ctx->len前置断言,verifier通过符号执行建模数据依赖关系。
verifier关键检查项对比
| 检查维度 | 静态分析方式 | 失败示例 |
|---|---|---|
| 循环检测 | DFS + 状态哈希 | while(1) { ... } |
| 指针解引用 | 类型+范围区间推理 | *(u32*)(ptr - 1) |
| 栈空间使用 | 编译期累加帧大小 | 超过512B栈限制 |
graph TD
A[加载bpf_prog] --> B{Verifier启动}
B --> C[CFG构建与环检测]
B --> D[寄存器类型推导]
B --> E[内存访问范围验证]
C & D & E --> F[全部通过?]
F -->|Yes| G[插入内核BPF子系统]
F -->|No| H[拒绝加载并返回错误码]
3.2 eBPF程序在协议栈层拦截Uniswap V4 Hook调用的实证分析
Uniswap V4 的 Hook 机制依赖 EVM 外部调用(如 CALL 或 STATICCALL)触发链下服务,而真实流量常经 Linux 协议栈(如 tcp_v4_connect 或 sk_msg_verdict)外泄至监控代理。eBPF 程序可在此层捕获含 Hook 目标地址的 TLS SNI 或 HTTP Host 字段。
关键 hook 点选择
sk_msg_verdict:适用于已建立连接的加密流量元数据提取tcp_connect:可获取原始目标 IP:Port,结合bpf_get_socket_cookie()关联后续流量
示例:SNI 提取 eBPF 代码
SEC("sk_msg")
int sk_msg_sni_intercept(struct sk_msg_md *msg) {
char sni[256] = {};
// 从 TLS ClientHello 的 SNI 扩展偏移处读取(简化示意)
bpf_skb_load_bytes(msg, 42, &sni, sizeof(sni)); // 假设固定偏移
if (bpf_memcmp(sni, "hook.uniswap.org", 16) == 0) {
bpf_sk_msg_redirect_hash(msg, &redirect_map, &key, BPF_F_INGRESS);
}
return SK_PASS;
}
该代码在 sk_msg 程序中解析 TLS 握手载荷,通过硬编码偏移提取 SNI 字段;实际部署需结合 bpf_probe_read_kernel 和 TLS 解析状态机避免越界。redirect_map 用于将匹配流量导向用户态代理进行 Hook 参数还原。
拦截效果对比表
| 指标 | 传统用户态代理 | eBPF 协议栈层拦截 |
|---|---|---|
| 延迟开销 | ~8–12 μs | ~0.3–0.7 μs |
| Hook 地址识别率 | 92%(依赖 TLS 解密) | 99.1%(SNI 明文) |
graph TD
A[Client 发起 HTTPS 请求] --> B{eBPF sk_msg 程序}
B --> C[提取 SNI: hook.uniswap.org]
C --> D[查 redirect_map]
D --> E[重定向至用户态 proxy]
E --> F[解析 calldata 中 hookSelector & params]
3.3 eBPF Map与Go用户态协同实现状态快照一致性同步
数据同步机制
eBPF程序将实时网络连接状态写入BPF_MAP_TYPE_HASH,Go用户态通过bpf.Map.LookupWithNextKey()遍历全量条目,避免竞态导致的漏读。
一致性保障策略
- 使用
BPF_F_NO_PREALLOC标志启用延迟分配,降低内存抖动 - Go端在遍历前调用
bpf.Map.GetNextKey()获取初始key,配合原子计数器标记快照起始时刻 - eBPF侧在更新前检查
bpf_ktime_get_ns()与快照时间戳差值,超阈值则暂存至per-CPU buffer
核心代码示例
// 遍历Map并构建一致快照
snap := make(map[string]ConnStats)
it := m.Iterate()
for it.Next(&key, &value) {
snap[key.String()] = value // key为四元组,value含rx/tx字节数
}
逻辑分析:
Iterate()内部封装了BPF_MAP_GET_NEXT_KEY系统调用链,确保单次遍历期间内核Map结构不被resize;key.String()隐式调用encoding/binary反序列化,需与eBPF端struct conn_key内存布局严格对齐(字段顺序、padding)。
| 组件 | 同步粒度 | 一致性模型 |
|---|---|---|
| eBPF Map | 条目级更新 | 最终一致性 |
| Go用户态 | 全量快照 | 弱时序一致性 |
| ringbuf辅助通道 | 事件增量 | 实时但非强一致 |
第四章:Solidity与Go/eBPF双栈协同架构的设计范式
4.1 链上Hook逻辑(Solidity)与链下监控逻辑(Go+eBPF)的责任边界划分
链上逻辑专注不可篡改的业务断言,链下系统承担高频率、低延迟的观测与响应。
职责划分原则
- ✅ 链上:校验交易有效性、触发事件(
emit Executed(...))、执行状态变更 - ✅ 链下:捕获原始系统调用、解析EVM日志、执行告警/限流等副作用操作
典型事件协同流程
// Hook合约片段:仅发出带语义的轻量事件
event TransferMonitored(
address indexed from,
address indexed to,
uint256 amount,
bytes32 txHash
);
此事件不包含敏感上下文(如IP、进程ID),避免链上存储膨胀;
txHash供链下索引回溯,indexed字段支持高效过滤。链上不执行任何外部HTTP调用或时间敏感判断。
边界对齐表
| 维度 | 链上(Solidity) | 链下(Go + eBPF) |
|---|---|---|
| 执行环境 | EVM(确定性、高Gas成本) | Linux内核/用户态(非确定性、毫秒级) |
| 数据来源 | 合约状态 + calldata | perf_event + JSON-RPC日志流 |
graph TD
A[用户交易] --> B[链上Hook合约]
B -->|emit TransferMonitored| C[RPC节点日志]
C --> D[eBPF探针捕获syscall]
D --> E[Go服务关联txHash+系统上下文]
E --> F[实时风控决策]
4.2 基于Calldata解码与eBPF tracepoint的跨栈调试流水线搭建
跨栈调试需打通应用层调用上下文与内核执行轨迹。核心在于将用户态函数调用的 calldata(如 ABI 编码参数)与内核中对应 syscall 或函数入口的 eBPF tracepoint 关联。
数据同步机制
利用 bpf_probe_read_user() 安全提取用户栈中 calldata 地址,结合 bpf_get_current_pid_tgid() 实现进程级关联。
// 在 userspace 函数入口处注入 eBPF uprobe
SEC("uprobe/contract_call")
int trace_contract_call(struct pt_regs *ctx) {
u64 pid = bpf_get_current_pid_tgid();
void *calldata_ptr = (void *)PT_REGS_PARM2(ctx); // 假设 calldata 为第2参数
bpf_map_update_elem(&calldata_map, &pid, &calldata_ptr, BPF_ANY);
return 0;
}
逻辑说明:
PT_REGS_PARM2依 ABI(如 System V AMD64)定位 calldata 指针;calldata_map为BPF_MAP_TYPE_HASH,键为pid_tgid,值为用户态地址,供后续 tracepoint 查找。
流水线协同流程
graph TD
A[uprobe捕获calldata地址] --> B[写入pid→ptr映射]
C[sys_enter tracepoint触发] --> D[查pid→calldata]
D --> E[ABI解码+日志聚合]
| 组件 | 作用 | 关键约束 |
|---|---|---|
uprobe |
用户态入口钩子 | 需符号调试信息或 offset 手动定位 |
tracepoint:syscalls/sys_enter_* |
内核态上下文锚点 | 仅支持已注册 tracepoint 的 syscall |
4.3 Hook触发事件→eBPF捕获→Go聚合→Prometheus暴露的端到端延迟压测报告
数据同步机制
压测中,内核态通过 kprobe 在 tcp_sendmsg 和 tcp_recvmsg 处触发 eBPF 程序,精准捕获每个 TCP 流的收发时间戳与 socket ID。
// bpf_prog.c:记录发送起点
SEC("kprobe/tcp_sendmsg")
int BPF_KPROBE(trace_tcp_send, struct sock *sk, struct msghdr *msg, size_t size) {
u64 ts = bpf_ktime_get_ns();
u32 pid = bpf_get_current_pid_tgid() >> 32;
struct tcp_event_t event = {};
event.pid = pid;
event.ts = ts;
event.type = TCP_SEND;
bpf_map_update_elem(&events, &sk, &event, BPF_ANY);
return 0;
}
逻辑说明:
bpf_ktime_get_ns()提供纳秒级单调时钟;&sk作 map key 可唯一标识连接上下文;events是BPF_MAP_TYPE_HASH类型,超时自动清理旧条目。
指标流转路径
graph TD
A[Hook: tcp_sendmsg/recvmsg] --> B[eBPF ringbuf 输出事件]
B --> C[Go 用户态读取 ringbuf]
C --> D[按 conn_id 聚合 P99/P999 延迟]
D --> E[Prometheus Counter/Gauge 暴露]
延迟统计维度
| 维度 | 标签示例 | 用途 |
|---|---|---|
direction |
"send", "recv" |
区分收/发链路瓶颈 |
status |
"success", "timeout" |
异常路径归因 |
payload_kb |
"1", "64", "1024" |
分析大小敏感性 |
4.4 双栈安全对齐:Solidity重入防护与eBPF内存访问沙箱的联合验证
双栈协同防御需在合约层与内核层建立语义一致的安全契约。
数据同步机制
Solidity 合约通过 ReentrancyGuard 修饰器标记临界区,eBPF 程序则依据同一元数据(如 reentry_nonce 全局槽位)进行运行时校验:
// 合约端:写入防重入令牌(slot 0x123)
assembly {
sstore(0x123, 1) // 标记进入
// ... 业务逻辑 ...
sstore(0x123, 0) // 安全退出
}
该操作确保状态变更原子性;eBPF 沙箱在 bpf_probe_read_user() 前强制校验该 slot 值为 ,否则拒绝内存访问。
验证策略对比
| 维度 | Solidity 层 | eBPF 层 |
|---|---|---|
| 检查时机 | 调用入口/出口 | 内存读取前 |
| 状态源 | EVM 存储槽 | 映射到用户空间的共享页 |
| 失败响应 | revert() | BPF_PROG_RUN_FAIL |
graph TD
A[外部调用] --> B{Solidity ReentrancyGuard}
B -->|sstore(0x123, 1)| C[执行业务]
C --> D[eBPF 沙箱拦截]
D -->|读取0x123 == 0?| E[放行内存访问]
D -->|否| F[拒绝并记录]
第五章:面向MEV与实时风控的下一代区块链基础设施演进路径
MEV感知型内存池的工程实践
以Flashbots Auction v2(FAv2)升级为基准,主流以太坊客户端Geth已集成mev-boost中间件,支持PBS(Proposer-Builder Separation)架构。某DeFi聚合器在2024年Q2部署自研内存池监听服务,通过订阅mev-boost中继的builder_bid事件流,结合本地Gas Price预测模型(XGBoost训练于30天链上交易数据),将用户交易打包延迟从平均12.7秒压缩至3.2秒。关键代码片段如下:
# 实时监听builder bid并触发风控校验
async def on_builder_bid(bid: dict):
tx_hash = bid["message"]["transaction_hash"]
if await is_sandwich_risk(tx_hash, window_blocks=5):
emit_alert("sandwich_detected", tx_hash)
await route_to_safe_mempool(tx_hash)
链下风控引擎与链上验证的协同机制
某跨链期权平台采用“双轨验证”设计:所有期权订单先经链下Rust编写的风控引擎(基于WASM沙箱)执行保证金率、Delta对冲敞口、清算阈值三重校验;仅当校验通过后,才生成零知识证明(zk-SNARKs via Circom)提交至链上合约验证。实测显示,该方案将单笔期权开仓TPS从82提升至1,460,同时将恶意套利攻击拦截率提升至99.87%(基于2024年3月主网攻击模拟测试集)。
实时链上行为图谱构建
利用Apache Flink实时处理Ethereum Beacon Chain区块流,构建动态账户关系图谱。节点属性包含:is_contract, avg_gas_used_24h, MEV_profit_ratio_7d;边权重为transfer_amount_eth * (1 + 0.05 * tx_priority_fee)。下表展示某MEV机器人集群的关联分析结果:
| 账户地址 | 出度(调用合约数) | 入度(被调用次数) | 近7日MEV收益(ETH) | 图中心性 |
|---|---|---|---|---|
| 0x…a1f2 | 1,842 | 37 | 124.6 | 0.921 |
| 0x…b7c9 | 93 | 2,105 | 89.3 | 0.887 |
| 0x…e5d0 | 5 | 4 | 0.0 | 0.012 |
硬件加速的共识层风控模块
某Layer-1公链在FPGA上部署定制化共识验证单元,将BLS签名聚合验证耗时从软件实现的8.4ms降至0.37ms。其Mermaid流程图描述了交易进入风控流水线的关键路径:
flowchart LR
A[新区块广播] --> B{FPGA签名验证}
B -->|通过| C[内存池实时图谱查询]
B -->|失败| D[丢弃并告警]
C --> E[调用WASM风控策略]
E -->|拒绝| F[标记为高风险区块]
E -->|通过| G[提交至PoS共识层]
多链MEV监控联邦网络
由Coinbase、Kraken与Chainalysis联合运营的MEV Watchdog联邦网络,已接入Ethereum、Base、Arbitrum、Polygon zkEVM四条链。各节点运行轻量级探针(
