引言在SuiMove中,UID、ID、Address是三个密切相关的概念,容易令人混淆。本文旨在通过阅读Sui::Object模块来澄清它们之间的区别与联系。
在 Sui Move 中,UID、ID、Address 是三个密切相关的概念,容易令人混淆。本文旨在通过阅读 Sui::Object 模块来澄清它们之间的区别与联系。
首先,Address 是 Sui Move 的基础类型之一,长度为 32 字节,用于标识链上账户或对象的唯一地址。
struct ID has copy, drop, store {
bytes: Address
}
ID 是一个封装了 Address 类型的结构体,具有 copy 和 store 特性,这样可以在链上存储。但是 ID 不能用于标识唯一的对象,因为它具有 copy 特性,任何人都可以复制拥有相同 Address 的 ID,并且可以随意丢弃。
struct UID has store {
id: ID,
}
UID 封装了 ID,它不能被复制,也不能被随意丢弃(只能调用 object::delete() 删除),并且与 ID 不同的是,它只能由交易上下文 ctx 创建(调用 object::new(ctx))。因此,它可以唯一地标识一个对象。
让我们阅读 Sui Move 示例中的例子,以更好地理解它们的区别,以及这样设计的原因。
struct Lock<T: store + key> has key {
id: UID,
locked: Option<T>
}
struct Key<phantom T: store + key> has key, store {
id: UID,
for: ID,
}
Lock 用于封装对象,Key 用于解封。
public entry fun create<T: store + key>(obj: T, ctx: &mut TxContext) {
let id = object::new(ctx);
let for_id = object::uid_to_inner(&id);
transfer::share_object(Lock<T> {
id,
locked: option::some(obj),
});
transfer::transfer(Key<T> {
for: for_id,
id: object::new(ctx)
}, tx_context::sender(ctx));
}
可以看到 Key 结构体中的 for 属性存储了 Lock 的 ID,表示这是哪一把锁的钥匙,因为 UID 是唯一的,不能被复制存储。
public fun unlock<T: store + key>(
lock: &mut Lock<T>,
key: &Key<T>,
): T {
assert!(option::is_some(&lock.locked), ELockIsEmpty);
assert!(&key.for == object::borrow_id(lock), EKeyMismatch);
option::extract(&mut lock.locked)
}
在解锁时,将key中的for属性,和从lock的uid中的id比对,确定钥匙与锁是否匹配。如果匹配,才能将其中的对象取出。
<!--StartFragment-->
Move语言学习交流QQ群: 79489587\ Sui官方中文开发者电报群: <https://t.me/sui_dev_cn>
<!--EndFragment-->
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!