发布者(Publisher)

发布者(publisher)对象用于代表发布者的权限。这个对象本身并不表示任何特定的用例,它主要运用于只有两个函数:package::from_module<T>package::from_package<T>,允许检查类型 T 是否属于由“Publisher”对象创建的模块或包。

English Version

Publisher Object serves as a way to represent the publisher authority. The object itself does not imply any specific use case and has only two main functions: package::from_module<T> and package::from_package<T> which allow checking whether a type T belongs to a module or a package for which the Publisher object was created.

我们强烈建议为大多数定义新对象的包创建“Publisher”对象 - 这是设置“显示”以及允许该类型在“Kiosk”生态系统中进行交易的前提条件。

尽管 Publisher 本身是一种实用工具, 但是它实现了所有权证明("proof of ownership")的功能 例如在对象显示(Object Display)扮演了重要的角色.

English Version

We strongly advise to issue the Publisher object for most of the packages that define new Objects - it is required to set the "Display" as well as to allow the type to be traded in the "Kiosk" ecosystem.

Although Publisher itself is a utility, it enables the "proof of ownership" functionality, for example, it is crucial for the Object Display.

我们需要 OTW(One-Time-Witness)来设置发布者(publisher)以确保 Publisher 对象只在相应的模块中初始化一次(在包中可以初始化/创建多次), 同时创建 publisher 函数在发布模块的交易中调用。

English Version

To set up a Publisher, a One-Time-Witness (OTW) is required - this way we ensure the Publisher object is initialized only once for a specific module (but can be multiple for a package) as well as that the creation function is called in the publish transaction.

/// 在这个模块中,将定义一个OTW,并为模块发布者创建/声明一个`Publisher`对象
/// A simple package that defines an OTW and claims a `Publisher`
/// object for the sender.
module examples::owner {
    use sui::tx_context::TxContext;
    use sui::package;

    /// OTW 是一个与模块名相同(字母大写)并只含有`drop`的结构体
    /// OTW is a struct with only `drop` and is named
    /// after the module - but uppercased. See "One Time
    /// Witness" page for more details.
    struct OWNER has drop {}

    /// 定义另一个类型
    /// Some other type to use in a dummy check
    struct ThisType {}

    /// 在模块发布后,交易的发起者将获得一个`Publisher`对象。
    /// 可以用来在`Kiosk`系统中设置对象的显示或管理对象转移的规则。
    /// After the module is published, the sender will receive
    /// a `Publisher` object. Which can be used to set Display
    /// or manage the transfer policies in the `Kiosk` system.
    fun init(otw: OWNER, ctx: &mut TxContext) {
        package::claim_and_keep(otw, ctx)
    }
}

/// 一个利用“Publisher”对象为其所拥有的类型创建“TypeOwnerCap”对象的示例。
/// A module that utilizes the `Publisher` object to give a token
/// of appreciation and a `TypeOwnerCap` for the owned type.
module examples::type_owner {
    use sui::object::{Self, UID};
    use sui::tx_context::TxContext;
    use sui::package::{Self, Publisher};

    /// 错误码0:当提供的类型无法与给定的`Publisher`匹配时触发
    /// Trying to claim ownership of a type with a wrong `Publisher`.
    const ENotOwner: u64 = 0;

    /// 当所给的类型(`T`)可以用给定的`Publisher`证明来源时,所创建的权限凭证
    /// A capability granted to those who want an "objective"
    /// confirmation of their ownership :)
    struct TypeOwnerCap<phantom T> has key, store {
        id: UID
    }

    /// 利用`Publisher`检查调用者是否拥有类型`T`
    /// Uses the `Publisher` object to check if the caller owns the type `T`.
    public fun prove_ownership<T>(
        publisher: &Publisher, ctx: &mut TxContext
    ): TypeOwnerCap<T> {
        assert!(package::from_package<T>(publisher), ENotOwner);
        TypeOwnerCap<T> { id: object::new(ctx) }
    }
}