第 19 章 Walrus 架构全景
Walrus 可以按三层理解:
- 控制层:Sui 上的合约、对象、epoch、费用和委员会状态。
- 数据层:存储节点保存 Blob 的编码片段,并参与可用性确认。
- 接入层:publisher 负责写入入口,aggregator 负责读取聚合,SDK/CLI 负责客户端流程。
这三层解耦是 Walrus 的核心。Sui 不存大文件,只存可验证状态;存储节点不决定你的业务权限;publisher 和 aggregator 是方便接入的服务,不应该被当成唯一可信源。
组件职责
| 组件 | 职责 | 生产边界 |
|---|---|---|
| Walrus CLI | 上传、下载、查询、调试 | 适合运维和脚本,不适合高并发服务入口 |
| TypeScript SDK | 应用内写入、读取、证明处理 | 适合前后端集成,注意版本和网络配置 |
| Publisher | 接收写请求,协调编码和注册 | 可自建,也可用公共服务;要做限流和鉴权 |
| Aggregator | 根据 blob_id 聚合片段并返回字节 | 可横向扩展;要监控延迟和错误率 |
| Storage node | 保存编码片段并响应协议请求 | 需要稳定磁盘、网络和密钥管理 |
| Sui 合约 | 记录 Blob 状态、费用、委员会信息 | 包 ID 和系统对象按网络区分 |
写入路径
写入不是简单上传到一台服务器:
- 客户端准备数据和存储参数。
- 数据被编码成多个片段。
- 片段分发给存储节点。
- 节点返回可用性相关确认。
- Sui 交易把 Blob 注册到链上状态。
- 客户端得到
blob_id和链上对象引用。
这意味着写入失败可能发生在不同阶段。工程上要区分:
- 编码或本地文件错误。
- publisher 请求失败。
- 存储节点确认不足。
- Sui 交易失败。
- 交易成功但客户端超时。
最后一种最容易误判。遇到超时时先查 Sui 交易或对象状态,不要立刻重复扣费上传。
读取路径
读取路径通常是:
- 客户端或后端拿到
blob_id。 - 请求 aggregator。
- aggregator 从足够多的存储节点取回片段。
- aggregator 重构原始字节并返回。
- 客户端做可选校验。
读取高峰时,瓶颈通常在 aggregator 到存储节点的网络、重构 CPU、出口带宽和缓存命中率。对公开热点内容,可以在 aggregator 前加 CDN,但不要让 CDN 成为唯一数据来源;源站仍要能从 Walrus 读取并校验。
Epoch 和委员会
Walrus 的存储承诺与 epoch 相关。你的应用不需要理解每个协议细节,但必须知道:
- Blob 有存储期,不是永久自动保存。
- 存储节点集合和参数会随 epoch 变化。
- 续期、过期、费用估算都要看当前 epoch。
- 运行节点或服务时,版本必须跟目标网络兼容。
主线稳定版本以 Mainnet mainnet-v1.47.1、Testnet testnet-v1.47.1 为准。Devnet devnet-v1.48.0 是预发布,适合提前测试,不适合作为生产依赖。
信任模型
Walrus 的目标不是让你信任某一个 HTTP 端点。正确的信任边界是:
- 链上对象和事件提供可审计状态。
- 存储协议提供数据可用性基础。
- aggregator 提供便利读取,但返回结果应可校验。
- 应用层负责加密、鉴权、业务哈希和合规删除策略。
如果数据敏感,上传前加密。Walrus 默认公开可读,blob_id 泄露就应视为内容可被读取。
架构选择
小型应用可以从公共 publisher/aggregator 起步:
frontend -> app backend -> public publisher
frontend -> public aggregator -> bytes
backend -> Sui RPC/indexer -> metadata
规模上来后,推荐自建接入层:
frontend -> app API -> private publisher -> Walrus
frontend -> CDN -> private aggregator -> Walrus
indexer -> Sui fullnode/RPC -> DB
自建 publisher/aggregator 的价值不是“更去中心化”,而是可控的 SLA、限流、审计、缓存策略和故障隔离。