关于 walrus-blob-lifecycle
面向 Walrus 用户的 Blob 生命周期操作指导技能,涵盖存储期限、删除、共享、属性管理及大容量上传规划。它重点说明 Blob ID 与 Sui 对象 ID 的区别,以及过期和不可逆操作的限制。
主要功能
- 01检查 Blob 状态与到期时间
- 02延长 Blob 存储期限
- 03删除或销毁 Blob 对象
- 04共享 Blob 并管理资金
- 05设置和读取 Blob 属性
- 06规划大容量上传
适用场景
- 01在到期前延长存储期限
- 02清理可删除的 Blob
- 03为多人使用的 Blob 提供资金
- 04规划超过 1 GiB 的上传
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mystenlabs/ walrus-skills --skill walrus-blob-lifecycle安装后在 Claude Code 中输入/walrus-blob-lifecycle确认已加载。
附带文件evals/evals.jsonlarge-uploads.md
详细介绍
Walrus Blob 生命周期
来源限制: 本技能中的所有信息均来自 Walrus 管理 Blob 文档 和大文件上传指南。 扩展本技能时,只能从这些来源获取内容。
Walrus Blob 的生命周期有限,以 epoch 为单位计算。本技能涵盖存储后的所有操作:延长生命周期、删除、销毁、共享、设置属性,以及规划大数据上传。
本技能中的所有模式均源自:
- https://docs.wal.app/docs/walrus-client/managing-blobs
- https://docs.wal.app/docs/walrus-client/storing-blobs(生命周期选项)
- https://docs.wal.app/docs/large-uploads
如果不确定某项生命周期操作,请先获取相关页面,再作答。
参考文件
large-uploads — 大数据上传模式
路径: large-uploads.md
在以下情况下加载: 规划超过 1 GiB 的上传、估算大型数据集的存储费用、管理并发上传的内存,或构建数据摄取管道。
涵盖内容: 费用估算、针对 >1 GiB 上传的调优、上传可观测性、管道状态持久化、吞吐量管理、内存开销(Blob 大小的 4.5 倍)。
相关技能
| 主题 | 技能 | 加载时机 |
|---|---|---|
| 基本存储/读取 | walrus-cli | 存储和读取 Blob |
| HTTP API | walrus-http-api | 通过 REST 存储/读取 |
| TypeScript SDK | walrus-ts-sdk | 以编程方式管理 Blob |
| Quilts | walrus-quilts | 对 Quilts 执行生命周期操作(作用于整个 Quilt) |
| 加密 | walrus-data-security | 存储前加密 |
| Move 集成 | walrus-move-integration | 链上 Blob 引用 |
路由指南
| 任务 | 加载内容 |
|---|---|
| 延长 Blob 的生命周期 | 技能内容 |
| 删除可删除的 Blob | 技能内容 |
| 销毁 Blob 的 Sui 对象 | 技能内容 |
| 创建或为共享 Blob 注资 | 技能内容 |
| 设置/获取/移除 Blob 属性 | 技能内容 |
| 规划大数据上传(>1 GiB) | large-uploads.md |
| 估算存储费用 | large-uploads.md |
| 构建数据摄取管道 | large-uploads.md |
| 管理并发上传的内存 | large-uploads.md |
技能内容
关键概念
-
纪元和存储期限。 Blob 存储时长以纪元为单位计算。Mainnet 上一个纪元为 14 天。最长存储时长为 53 个纪元(约 2 年)。Blob 会在其结束纪元开始时过期。使用
walrus info或聚合器上的GET /v1/info检查当前纪元和存储时长。 -
Blob ID 与 Sui 对象 ID。 Blob ID 是根据 Blob 内容生成的 URL 安全 base64 字符串(内容寻址)。相同内容始终会生成相同的 Blob ID。Sui 对象 ID 是用于标识链上
Blob对象的0x...十六进制字符串。每次上传都会创建新的对象 ID,即使内容相同也是如此。读取内容时使用 Blob ID;执行生命周期操作(延长、删除、共享)时使用对象 ID。 -
可删除与永久存储。 新存储的 Blob 默认可删除。可删除的 Blob 可由 Sui 对象所有者在过期前移除。永久存储的 Blob 在过期前无法删除,即使上传者也不例外。
-
Blob 过期后会发生什么。 Blob 到达结束纪元后,数据将无法访问。没有宽限期。存储节点会丢弃分片。必须重新上传数据才能再次提供访问。过期的 Blob 无法延长存储期限。
-
将 Blob 包装在共享对象中。
Blob对象可以包装到任意 Sui 共享对象中,从而允许多方为其提供资金并延长存储期限。Walrus 合约提供了shared_blob::SharedBlob,作为此模式的一种参考实现;开发者也可以自行创建带有自定义逻辑(访问控制、元数据等)的共享包装对象。 -
存储池。 一项预览功能:多个 Blob 共用一个存储预留。池中的 Blob 使用池内预付的容量,因此每次存储只需支付写入费用,且池中的所有 Blob 会同时过期。可通过 Rust SDK(
walrus-sdk、walrus-sui)和 Move 合约使用;walrusCLI、HTTP 发布者和聚合器 API 以及 TypeScript SDK 暂不支持存储池。 -
Blob 属性。 存储在 Blob 的 Sui 对象上的键值元数据对。聚合器会识别某些键(
content-type、content-disposition等),并在通过对象 ID 读取时将其作为 HTTP 标头返回。 -
每个 Blob 的存储开销。 每个 Blob 都会产生约 64 MB 的元数据开销,与其大小无关。对于小于约 10 MB 的 Blob,元数据成本占主导。可使用 quilts 批量处理许多小 Blob,以分摊此开销。
执行操作前检查状态并验证可用性
延长 Blob 的存储期限或依赖 Blob 前,请确认它仍在存储中,并查看其过期时间:
walrus blob-status --blob-id <BLOB_ID> # stored? availability period; event ID for certified permanent blobs
walrus info # current epoch, to compare against the end epoch
过期不会发出通知:到达结束纪元时,存储节点会停止提供 Blob,且不会发出任何事件。请按计划定期检查,而不要等到读取失败后再检查,并务必在结束纪元之前尽早延长存储期限。
写入后若要以编程方式检查,请使用写入结果中的对象 ID,从 Sui 重新读取 Blob 对象。当 Blob 已通过认证、当前纪元早于其结束纪元且它不可删除时,该 Blob 即为持久存储:
const blob = await walrusClient.getBlobObject(blobObjectId);
const durable = blob.certified_epoch != null && currentEpoch < blob.storage.end_epoch && !blob.deletable;
为确保完整性,请通过设置 strict_consistency_check=true 的聚合器按对象 ID 读取字节数据,这样数据就会与已验证认证信息的对象绑定。Sui 对象上的 blob_id 字段类型为 u256,并非 URL 中使用的 base64 ID。
延长 Blob 存储期限
# Extend by blob Sui object ID
walrus extend --blob-obj-id <BLOB_OBJECT_ID>
# Extend with a specific new end epoch
walrus extend --blob-obj-id <BLOB_OBJECT_ID> --end-epoch <EPOCH>
# Extend a shared blob (requires --shared flag)
walrus extend --blob-obj-id <BLOB_OBJECT_ID> --shared
- Blob 不得已过期。
- 自有 Blob 和共享 Blob 均可延长存储期限。
- 只有所有者才能延长自有 Blob 的存储期限。任何人都可以延长共享 Blob 的存储期限。
- 需要 Blob 的 Sui 对象 ID(而不是 Blob ID)。
删除 Blob
# Delete by blob ID
walrus delete --blob-id <BLOB_ID>
# Delete by file (derives blob ID)
walrus delete --file <PATH>
# Delete by Sui object ID
walrus delete --object-id <SUI_ID>
# Skip confirmation prompt
walrus delete --blob-id <BLOB_ID> --yes
# Skip post-delete status check
walrus delete --blob-id <BLOB_ID> --yes --no-status-check
重要注意事项:
- 只有 Sui
Blob对象的所有者才能删除可删除的 Blob。 - 删除会回收存储资源,之后会自动重复使用。
- 删除只会从当前和未来的存储节点中移除数据分片。如果同一 Blob 还有其他副本(由其他人上传),数据仍可访问。
- 删除对于保护隐私的作用有限。所有 Blob 都是公开的,不会影响缓存的副本或此前下载的副本。
销毁 Blob
销毁会移除 Blob 的 Sui 对象,但不会删除 Walrus 中的数据,也不会退还存储费用:
# Burn a specific blob by object ID
walrus burn-blobs --object-ids <BLOB_OBJECT_ID>
# Burn all blob objects owned by the current wallet
walrus burn-blobs --all
# Burn all expired blob objects
walrus burn-blobs --all-expired
销毁后,你无法延长永久 Blob 的存储期限,也无法延长或删除可删除的 Blob。你将失去对该 Blob 的所有控制权。
共享 Blob
Blob 可以封装为 Sui 共享对象,让任何人都能为其提供资金并延长存储期限。Walrus 合约提供了 shared_blob::SharedBlob 作为一种参考实现;你也可以根据所需逻辑,将 Blob 封装到自己的自定义共享对象中。
通过 CLI 使用内置的 SharedBlob:
# Share an existing blob using the built-in SharedBlob
walrus share --blob-obj-id <SUI_OBJ_ID>
# Fund an existing shared blob
walrus fund-shared-blob --blob-obj-id <SHARED_OBJ_ID> --amount <WAL_AMOUNT>
# Store and share in one step
walrus store myfile.png --epochs 10 --share
内置共享 Blob:
- 只能包含永久 Blob
- 到期前无法删除
- 任何人都可以为其提供资金并延长存储期限
如需更多控制权,可以考虑将 Blob 封装到自己的共享对象中(参见 walrus-move-integration)。
存储池(预览版)
存储池是一项由多个 Blob 共用的存储预留。标准流程中,每个 Blob 都会按其确切大小和存储期限购买自己的存储资源;使用存储池时,只需一次性预留一块具有一定存储期限的编码容量,注册到池中的每个 Blob 只需支付写入费用。
| 普通 Blob | 池化 Blob | |
|---|---|---|
| 存储费用 | 每个 Blob 独立拥有存储资源 | 使用池的预付容量;注册时只支付写入费用 |
| 存储期限 | 每个 Blob 独立到期,逐个延长 | 共用池的到期时间;延长存储池会延长其中所有 Blob 的存储期限 |
| 删除 | 将存储资源返还给你 | 释放其编码大小的容量,供池中的下一个 Blob 使用(不退还 WAL) |
| 所有权 | Blob 可以被拥有、转移和共享 | PooledBlob 位于池内,不能单独转移 |
| 读取 | 按 Blob ID 读取 | 相同;池化 Blob 使用普通 Blob ID |
费用:创建存储池时,无论是否填满,都要按其完整预留容量和完整存储期限支付存储费用;注册 Blob 时,按其编码大小支付写入费用;延长或扩容存储池时,按新增的纪元数或容量支付存储费用;删除不收费,也不退款。池化 Blob 仍需支付固定的每 Blob 元数据开销,因此存储池并不会让许多小 Blob 更便宜;对此请使用 quilts,也可以在存储池中使用。
如果你会持续写入并删除 Blob,且总存储占用可预测,希望每次写入只需支付写入费用,并且可以接受共用一个到期时间,那么可以使用存储池。如果 Blob 需要独立的存储期限、需要转移或共享单个 Blob 对象,或者容量需求难以预测,则优先使用普通 Blob。
可通过 Rust SDK(create_storage_pool、reserve_and_store_blobs_in_storage_pool、storage_pool_status、delete_pooled_blob、extend_storage_pool、increase_storage_pool_capacity)和 walrus::system Move 模块使用存储池。walrus CLI 不支持存储池;没有 --storage-pool 标志。Rust 和 Move 示例请参阅存储池页面。
Blob 属性
# Set attributes (multiple key-value pairs supported)
walrus set-blob-attribute <BLOB_OBJECT_ID> --attr "content-type" "image/png" --attr "creator" "myapp"
# Get attributes
walrus get-blob-attribute <BLOB_OBJECT_ID>
# Remove all attributes
walrus remove-blob-attribute <BLOB_OBJECT_ID>
# Remove specific keys
walrus remove-blob-attribute-fields <BLOB_OBJECT_ID> --keys "creator"
可识别的 HTTP 标头属性键:content-disposition、content-encoding、content-language、content-location、content-type、link。按对象 ID 读取时,这些属性会作为 HTTP 标头返回。
规则
- Blob 会在结束纪元开始时过期。 结束纪元为 314 的 Blob 会在纪元 314 开始时变得不可用。请做好规划。
- 无法延长已过期的 Blob。 请在过期前延长。使用
walrus blob-status监控过期时间。 - 删除不保证数据被移除。 同一 Blob 可能还有其他副本。缓存和过去的存储节点不受影响。
- 共享的 Blob 必须是永久的。 不能共享可删除的 Blob。请先将其转换为永久 Blob,或使用
--share将其作为永久 Blob 存储。 - 销毁操作不可逆。 销毁 Blob 对象会放弃所有控制权,且不会退还存储费用。使用
--all-expired安全清理已过期的 Blob。 - Blob 的最大大小约为 13.6 GiB。 使用
walrus info查看“Maximum blob size”下的当前上限。有关大型上传,请参阅参考文件large-uploads.md。
常见错误
- 臆造
--storage-poolCLI 标志。 CLI 中没有存储池;它们属于 Rust SDK 和 Move 预览功能。 - 等待读取失败后才发现 Blob 已过期。 过期不会发出事件。请定期将
blob-status与walrus info的结果进行核对。 - 使用 Blob ID 而非对象 ID 来延长。
extend命令需要--blob-obj-id(Sui 对象 ID),而不是 Blob ID。 - 尝试延长已过期的 Blob。 Blob 一旦过期,就无法延长。你必须重新上传。
- 以为删除会让数据完全不可用。 如果其他用户上传了相同内容,数据仍会保留。加密是唯一可靠的隐私保护机制。
- 销毁仍有价值的 Blob。 销毁是永久性的,会放弃存储,且不会退款。请使用
delete来回收存储空间。 - 共享可删除的 Blob。 共享的 Blob 必须是永久的。请使用
--permanent --share存储,或确保 Blob 在共享前已设为永久。 - 在纪元边界附近使用
--epochs 1存储。 Blob 几乎会立即过期。请使用较大的纪元数。