Move
Sui Move / Aptos MoveSui / Aptos
资源即类型:资产不能被复制、不能被丢弃,只能移动
Move 的核心是线性类型系统:带 key 与 store 能力的结构体代表资产,编译器保证它要么被转移、要么被消耗,绝不会凭空复制或被遗忘。这让「双花」「意外销毁」在语言层面就不可表达。Sui 与 Aptos 的语法相近但模块与对象模型有差异。
3 个语法章节3 段可复制代码含在线练习
从 Solidity 视角看差异
如果已经会 Solidity,这张表比从头读语法快得多。
| 差异点 | 说明 |
|---|---|
| 资产表示 | 没有 mapping 记账式的余额表,资产是真实存在于账户/对象里的资源。 |
| ability | key(可作对象/全局存储键)、store(可被嵌套存储)、copy、drop 四种能力决定结构体行为。 |
| 模块与包 | 代码组织成 module,模块地址固定后不可升级内容(除非走特定的升级策略)。 |
| Sui 对象 | Sui 里带 key 的结构体就是对象,有唯一 ID,可被转移、共享(shared)或冻结(frozen)。 |
1
Sui 模块与对象
1 段代码Sui 的入口函数分 public / entry,交易由对象驱动。
- has key 的结构体是对象,必须包含 id: UID 字段
- has store 才允许被放进其他结构体或集合里
- 共享对象(share_object)可被任意人访问,需要自己实现权限校验
- tx_context::sender(ctx) 取代了 msg.sender,用来做权限判断
Sui 计数器对象
Sui 计数器对象Move
Sui 里 &mut 参数代表可变借用,只有对象的所有者(或共享对象)能通过这种调用修改它。
2
Aptos 模块与全局存储
1 段代码Aptos 用 move_to / borrow_global_mut 管理账户下的资源,风格更接近「账户账本」。
- move_to(&signer, resource) 把资源存到签名者账户下
- borrow_global_mut<T>(addr) 借出可变引用,不存在则 abort
- signer 是特权类型,只有交易发起方持有,不能被伪造
- entry 函数可以作为交易入口被直接调用
Aptos 账户资源与事件
Aptos 账户资源与事件Move
acquires 标注是 Move 的强制要求:凡访问全局存储的函数都必须显式声明访问的类型。
3
代币与能力约束
1 段代码Move 里发币要处理「铸币权」这个资源,通常用 Capability 模式实现权限。
- 铸币权做成带 key + store 的结构体并转移给团队地址,比地址白名单更安全
- 没有 copy 能力 → 不可复制;没有 drop 能力 → 不可丢弃,必须被处理
- phantom 类型参数用于把「币种」这种纯类型信息挂到通用结构体上
- 升级策略(兼容/不可变)在发布时就确定,事后不能改
铸币权能力模式(Sui)
铸币权能力模式(Sui)Move
把 treasury 冻结(freeze)就等于「放弃增发权」,是社区最看重的信任信号之一。
本章练习
这一段要让你看懂:Move 把「能力」做成类型系统的一部分。没有 copy 就不能复制,没有 drop 就不能丢弃——「双花」和「意外销毁」在语言层面就无法表达,而不是靠代码审查发现。
▶
试一试 · 线性类型:为什么资产不能被复制
可直接改代码 · 在浏览器沙箱里真跑playground.jsJavaScript
运行环境:iframe 沙箱(无 cookie 权限)。只支持纯 JS 片段,不支持 import / require;需要模块请用下方的完整示例复制到项目里。
检查点(跑完后逐条核对)
- Coin<SUI> 提示「不可复制」与「不可丢弃」
- u64 提示「普通值,可自由复制与丢弃」
- MintCap 同时不可复制、不可丢弃(铸币权不能被备份或丢弃)
- 最后的复制尝试在 Move 里是编译错误而不是运行时错误