系统对象:一次性见证对象和发布者对象

我们已经见过 TxContext 对象,它可以作为可变或不可变引用传递。现在让我们讨论其他特殊对象。

在部署模块时,任何 init 函数都会自动被调用。init 函数还可以接收一个见证对象 —— 一种特殊的系统对象,只在模块第一次部署时创建一次:

module 0x123::my_module {
    public struct MY_MODULE has drop {}
    
    fun init(witness: MY_MODULE) {
        // Do something with the witness object.
    }
}

为了在 init 函数中接收见证对象,您需要声明一个与模块同名但全大写的结构体(任何 _ 都保留)。 该结构体必须具有 drop 能力。现在,当您定义 init 函数时,可以将该类型的见证对象添加为第一个参数。

见证对象目前只有两种主要情况,但 Sui 团队在不久的将来可能会添加更多:

  1. 声明发布者对象。发布者对象是证明持有人已部署对象的证据。
fun init(witness: MY_MODULE, ctx: &mut TxContext) {
    assert!(types::is_one_time_witness(&witness), ENotOneTimeWitness);
    let publisher_object = package::claim(witness, ctx);
    // Use or store the publisher object...
}
  1. 当调用其他模块的函数时,证明这是在初始化流程的中间。这通常在需要与多个不同模块一起完成一系列初始化项目的操作时很有用。
module 0x123::module_b {
    fun init(module_a_witness: MODULE_A, ctx: &mut TxContext) {
        assert!(types::is_one_time_witness(&module_a_witness), ENotOneTimeWitness);
        // We know that this is being called from module A's init function.
    }
}

发布者对象目前也只有两个使用案例,但很快会添加更多:

  1. 创建显示对象。更多内容将在下一课中介绍。
  2. 在 Sui 的 Kiosk(NFT 标准)中设置转移政策。这将在 NFT 课程中讲解。