Shardeum跨分片通信完全指南:分片间消息传递机制一文讲透
【免费下载链接】shardeumShardeum is an EVM based autoscaling blockchain项目地址: https://gitcode.com/GitHub_Trending/sh/shardeum
Shardeum 是一个基于 EVM 的自动扩缩容区块链平台,它的核心卖点正是"动态状态分片"。但分片带来的第一个问题就是:当一笔交易要读写的账户散落在不同分片时,数据怎么传?这就是 Shardeum 跨分片通信要解决的课题。本文用通俗的方式带你理解 Shardeum 分片间消息传递机制的完整链路:账户如何分片、跨分片如何取数、如何提前预热、交易如何被路由到正确的分片,以及这些机制在源码里的位置,零基础也能看懂。
一、先搞懂背景:为什么需要跨分片通信
单链区块链里,所有账户都在同一个状态树中,读写没有"距离"概念。而 Shardeum 采用动态状态分片:
| 概念 | 说明 |
|---|---|
| 状态分片 | 全网账户状态被切分,每个节点只完整保存自己分片的账户 |
| 账户键 | 每个账户(包括合同账户、合同存储槽、合同字节码)都有一个 64 位十六进制"分片地址" |
| 分片归属 | 由账户键的前缀决定,前缀相同的键落在同一个分片(同一个共识组) |
正因为"数据只在自己分片上是权威的",任何一次跨分片访问都必须走分片间消息传递:向远程分片发 P2P 请求、取回账户数据副本。
二、账户如何被分片:分片地址映射规则
跨分片通信的前提是"知道数据住在哪个分片",这由分片地址转换函数决定,核心实现在 evmAddress.ts:
- 普通账户:取 20 字节以太坊地址,后面补 24 个
0拼成 64 位键,保证同一账户永远在同一分片; - 合同存储槽:默认开启"存储隔离(Key Silo)",用
合同地址前缀 + 存储键哈希后缀生成键(见 toShardusAddressWithKey)。这样合同的所有存储槽都紧跟在合同账户所在分片附近,大幅减少跨分片访问次数; - 合同字节码:可按代码哈希生成键(由 shardeumFlags.ts 中的
contractCodeKeySilo开关控制)。
💡 一句话理解:键的前缀 = 数据所在的"分片门牌号"。门牌号对不上,就要跨分片通信。
三、跨分片读取账户:分片间消息传递的核心路径
当 EVM 执行中要读一个不在本分片的账户时,Shardeum 节点会通过回调tryGetRemoteAccountCB发起跨分片取数,完整流程在 src/index.ts:
- 生成分片地址:先把 EVM 地址 + 键换算成 64 位分片地址;
- 查预热缓存:如果本次运行带有
warmupCache,先查缓存命中,省去一次网络往返; - 向远程分片发请求:调用
shardus.getLocalOrRemoteAccount(...)走 P2P 网络向持有该键的分片请求数据; - 自动重试:按账户类型设置不同重试次数(普通账户 2 次、合同字节码 3 次、存储槽 1 次),网络抖动时可自动恢复;
- 反序列化修正:远程返回的账户在跨分片传输后可能字段变形,会经
fixDeserializedWrappedEVMAccount修复后才能进 EVM。
四、跨分片预热缓存:把"网络延迟"提前消化
跨分片请求一次是几十毫秒,一个交易动辄访问几十个账户,串行取数会拖垮吞吐。Shardeum 的答案是AALG 预热(warm-up)机制:
- AALG(自动访问列表生成)先跑一遍交易,算出它会碰哪些账户、存储槽和代码哈希(详见 AALG-warm-up.md);
- 拿到清单后,节点用并行"发射后不管"请求同时向多个远程分片取数,边取边写入预热缓存(fetchAndCacheAccountData);
- 预热缓存挂在交易状态对象上:transactionState.ts 中的
warmupCache,正式预跑时直接命中缓存; - 预热等待时长由网络参数 aalgWarmupSleep 控制,是"请求飞行时间"与"等待时长"之间的平衡点。
此外还有一层远程账户缓存(RI Accounts Cache):把从远程分片取回的热账户缓存在本地 SQLite,短期内再次跨分片读取无需重新请求,见 riAccountsCache.ts。
五、交易路由与一致性:分片间消息传递的另一半
跨分片通信不只是"读",还包括"交易该去哪个分片执行":
- 账户涉及检查:EVM 每读写一个账户都会触发 accountInvolved / contractStorageInvolved 回调,底层调用
shardus.tryInvolveAccount告诉核心层"这笔交易要动这个键"。核心层据此把交易放进对应分片(共识组)的队列,并检测同键冲突交易; - 访问列表驱动路由:AALG 生成的访问列表(含地址、存储槽、代码哈希)随交易传递,让不同分片知道各自要准备哪些数据;远程生成失败时按 numberOfAccessListRetry 自动重试;
- 共识与副本同步:分片间不是各写各的。Shardeus 核心按"周期(cycle)"组织共识组,跨分片共享的账户通过账户副本(Account Copies)在各分片间同步——例如创世账户创建后由首个节点通过 forwardAccounts 广播给全网,保证多分片对同一全局账户看到一致状态。
六、本地快速体验与调试
想亲手观察 Shardeum 跨分片通信的行为,最快的方式是在本地起一个 10 节点网络:
git clone https://gitcode.com/gh_mirrors/sh/shardeum cd shardeum npm ci && npm run prepare shardus start 10若需要在远程验证者节点上打断点跟踪跨分片取数逻辑,仓库自带一键调试脚本(SSH 隧道 + 端口转发 + VSCode 断点),说明见 shardeumValidatorDebuggingScript/README.md。观察跨分片行为时,可关注aalg相关日志(aalg-hit、aalg-miss即预热缓存命中/未命中)。
七、常见问题(FAQ)
Q1:跨分片通信会不会破坏 EVM 兼容性?不会。对 DApp 和智能合约而言,Shardeum 仍是标准 EVM 链;分片路由、跨分片取数都发生在共识与状态层之下,合约无感知。
Q2:为什么合同存储槽要和合同账户"待在一起"?存储隔离(Key Silo)让同合同的数据共享键前缀,落在同一分片,把大量本应跨分片的存储读写变成本地读写,是 Shardeum 降低跨分片通信成本的关键设计。
Q3:正式 Apply(共识执行)时还能跨分片取数吗?不能。共识执行要求交易所需数据提前经访问列表准备完毕(预热缓存兜底),执行阶段发现缺数据视为异常——这是保证各分片可并行、可重放一致性的必要约束。
总结
Shardeum 跨分片通信机制可以浓缩成一条链路:
分片地址定归属 → AALG 预跑算清单 → 并行预热取远程数据 → 访问列表路由交易 → 共识组保证副本一致
理解这条链路,就掌握了 Shardeum 如何在"状态被切碎"的前提下,依然做到 EVM 兼容、高吞吐与确定性执行。
【免费下载链接】shardeumShardeum is an EVM based autoscaling blockchain项目地址: https://gitcode.com/GitHub_Trending/sh/shardeum
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考