Move —— Sui 对象所有权模型与事件
Sui 对象在创建后必须显式指定其所有权归属。本文介绍三种所有权模式的区别:独有对象(Owned)只能被所有者操作、共享对象(Shared)允许任何人操作、不可变对象(Immutable)永久只读。同时讲解如何使用事件(Event)让链下应用监听链上状态变化。
1. Sui 资产的三种形态
Sui 对象被创建 (object::new) 后,必须通过 transfer 模块显式指定去向。
1.1 独有对象 (Owned Object)
- API:
transfer::transfer(obj, recipient) - 权限:私有。只有 Owner 能发起交易修改它。
- 场景:NFT、个人钱包资产。
1.2 共享对象 (Shared Object)
- API:
transfer::share_object(obj) - 权限:公开。任何人都可发起交易读取或修改。
- 场景:公共计数器、DEX 流动性池、投票箱。
1.3 不可变对象 (Immutable Object)
- API:
transfer::freeze_object(obj) - 权限:只读。包括创建者在内,无人能修改或删除。
- 场景:系统配置、固定规则。
2. 事件 (Event)
2.1 为什么要用事件?
在共享对象场景下,对象状态只保存”当前结果”(比如 value=100)。如果前端或数据库需要展示动态的历史记录(比如用户在什么时间调用了increment),只是从区块浏览器查对象状态是做不到的。通过 Indexer通过监听链上事件,可以高效地将动作同步到 SQL 数据库中,供前端查询历史轨迹。
2.2 定义与使用
- 定义:事件是一个标准的结构体,必须拥有
copy和drop能力,因为它只是一个临时消息,不需要存储在链上。 - 发射:使用
sui::event::emit发送消息。
3. Counter 合约
1 | use sui::event; |
4. 总结
| 概念 | API / 关键字 | 核心作用 |
|---|---|---|
| 共享对象 | share_object |
让全网用户共同操作同一个状态。 |
| 不可变对象 | freeze_object |
锁定数据,作为永久只读常量。 |
| 事件 | event::emit |
解决共享状态下的”可观测性”问题,通知链下应用。 |
5. CLI 参考
1 | sui client publish --gas-budget 100000000 |