(四)Let's Move共学,浅分析一下coin库

  • aimotee
  • 更新于 4小时前
  • 阅读 45

首先感谢Let'sMove共学,感谢HOH社区我会把详细的过程和注意的点都写上,适合和我一样的小白开始学习move今天我们来分析一下Coin源码github源码:https://github.com/MystenLabs/sui/blo

<!--StartFragment--> 首先感谢Let's Move共学,感谢HOH社区 8b84cc26a04f2077f2209b67997fe39.png\ 我会把详细的过程和注意的点都写上,适合和我一样的小白开始学习move

<!--EndFragment-->

今天我们来分析一下Coin源码

github源码:https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/packages/sui-framework/sources/coin.move 本期文章使用文献:https://docs.sui.io/references/framework/sui-framework/coin 源代码很长就不贴了这里仅做解析

// Allows calling `.split_vec(amounts, ctx)` on `coin`
public use fun sui::pay::split_vec as Coin.split_vec;

// Allows calling `.join_vec(coins)` on `coin`
public use fun sui::pay::join_vec as Coin.join_vec;

// Allows calling `.split_and_transfer(amount, recipient, ctx)` on `coin`
public use fun sui::pay::split_and_transfer as Coin.split_and_transfer;

// Allows calling `.divide_and_keep(n, ctx)` on `coin`
public use fun sui::pay::divide_and_keep as Coin.divide_and_keep;

这些行是Rust语言的模块化和函数重新导出的声明。每一行都以 public use 开头,表示它们将某些函数公开为当前模块的一部分。fun 关键字表示它们是函数。这些函数原本定义在 sui::pay 模块中,现在通过这些声明,它们可以在 Coin 类型上被调用。下面是对每一行的详细解释:

// Allows calling .split_vec(amounts, ctx) on coin 这是一条注释,解释了下一行代码的功能。它说明接下来的 public use 声明允许用户在 coin 类型上调用 .split_vec(amounts, ctx) 方法。

/// A type passed to create_supply is not a one-time witness.
const EBadWitness: u64 = 0;
/// Invalid arguments are passed to a function.
const EInvalidArg: u64 = 1;
/// Trying to split a coin more times than its balance allows.
const ENotEnough: u64 = 2;
// #[error]
// const EGlobalPauseNotAllowed: vector&lt;u8> =
//    b"Kill switch was not allowed at the creation of the DenyCapV2";
const EGlobalPauseNotAllowed: u64 = 3;

这些行定义了一些常量,它们用作错误码,以便于在函数执行过程中遇到特定错误情况时引用。

  1. EBadWitness: 当传递给 create_supply 函数的类型不是一次性见证(one-time witness)时,返回此错误码。一次性见证是一种确保某个操作只执行一次的机制。

  2. EInvalidArg: 当传递给函数的参数无效时,返回此错误码。

  3. ENotEnough: 当尝试分割的硬币数量超过其余额允许的次数时,返回此错误码。

  4. EGlobalPauseNotAllowed: 当尝试启用全局暂停功能,但在创建 DenyCapV2 时未允许此操作时,返回此错误码。这里的注释表明原本有一个错误消息的字节向量定义,但现在已被替换为一个简单的 u64 错误码。

/// A coin of type `T` worth `value`. Transferable and storable
public struct Coin&lt;phantom T> has key, store {
    id: UID,
    balance: Balance&lt;T>,
}

这里定义了一个名为 Coin 的结构体,它是一个泛型类型,其中 phantom T 表示 T 是一个不出现在结构体中的类型参数,它用于影响类型而不存储任何值。Coin 结构体有两个字段:

  1. id: 一个 UID 类型的字段,唯一标识一个 Coin 实例。

  2. balance: 一个 Balance&lt;T> 类型的字段,表示硬币的余额。

Coin 结构体被标记为 has keystore,意味着它可以在数据库中被索引和存储。

/// Each Coin type T created through `create_currency` function will have a
/// unique instance of CoinMetadata&lt;T> that stores the metadata for this coin type.
public struct CoinMetadata&lt;phantom T> has key, store {
    id: UID,
    /// Number of decimal places the coin uses.
    /// A coin with `value ` N and `decimals` D should be shown as N / 10^D
    /// E.g., a coin with `value` 7002 and decimals 3 should be displayed as 7.002
    /// This is metadata for display usage only.
    decimals: u8,
    /// Name for the token
    name: string::String,
    /// Symbol for the token
    symbol: ascii::String,
    /// Description of the token
    description: string::String,
    /// URL for the token logo
    icon_url: Option&lt;Url>,
}

CoinMetadata 结构体用于存储特定 Coin 类型的元数据。它也是泛型结构体,使用 phantom T。字段包括:

  1. id: 一个 UID 类型的字段,唯一标识一个 CoinMetadata 实例。

  2. decimals: 一个 u8 类型的字段,表示硬币使用的小数位数。

  3. name: 一个 string::String 类型的字段,表示代币的名称。

  4. symbol: 一个 ascii::String 类型的字段,表示代币的符号。

  5. description: 一个 string::String 类型的字段,表示代币的描述。

  6. icon_url: 一个 Option&lt;Url> 类型的字段,表示代币图标的 URL,可以是 None,表示没有图标。

CoinMetadata 也被标记为 has keystore,意味着它可以被索引和存储。

接下来,我们继续分析代码中的其他部分:

/// Similar to CoinMetadata, but created only for regulated coins that use the DenyList.
/// This object is always immutable.
public struct RegulatedCoinMetadata&lt;phantom T> has key {
    id: UID,
    /// The ID of the coin's CoinMetadata object.
    coin_metadata_object: ID,
    /// The ID of the coin's DenyCap object.
    deny_cap_object: ID,
}

这里定义了一个名为 RegulatedCoinMetadata 的结构体,它是为受监管的硬币类型创建的,这些硬币类型使用 DenyList(黑名单)。这个结构体是不可变的,意味着一旦创建,其内容不能被修改。

  1. id: 一个 UID 类型的字段,唯一标识一个 RegulatedCoinMetadata 实例。

  2. coin_metadata_object: 一个 ID 类型的字段,存储这个受监管硬币类型对应的 CoinMetadata 对象的 ID。

  3. deny_cap_object: 一个 ID 类型的字段,存储这个受监管硬币类型对应的 DenyCap 对象的 ID。

RegulatedCoinMetadata 被标记为 has key,意味着它可以在数据库中被索引。

/// Capability allowing the bearer to mint and burn
/// coins of type `T`. Transferable
public struct TreasuryCap&lt;phantom T> has key, store {
    id: UID,
    total_supply: Supply&lt;T>,
}

TreasuryCap 结构体表示一种能力,允许持有者铸造和销毁类型为 T 的硬币。它是可转移的。

  1. id: 一个 UID 类型的字段,唯一标识一个 TreasuryCap 实例。

  2. total_supply: 一个 Supply&lt;T> 类型的字段,表示这种类型硬币的总供应量。

TreasuryCap 被标记为 has keystore,意味着它可以被索引和存储。

/// Capability allowing the bearer to deny addresses from using the currency's coins--
/// immediately preventing those addresses from interacting with the coin as an input to a
/// transaction and at the start of the next preventing them from receiving the coin.
/// If `allow_global_pause` is true, the bearer can enable a global pause that behaves as if
/// all addresses were added to the deny list.
public struct DenyCapV2&lt;phantom T> has key, store {
    id: UID,
    allow_global_pause: bool,
}

DenyCapV2 结构体表示一种能力,允许持有者阻止地址使用特定货币的硬币,立即阻止这些地址与硬币作为交易输入的交互,并在下一个时期开始时阻止它们接收硬币。如果 allow_global_pausetrue,持有者可以启用全局暂停,表现得就好像所有地址都被添加到了黑名单中。

  1. id: 一个 UID 类型的字段,唯一标识一个 DenyCapV2 实例。

  2. allow_global_pause: 一个 bool 类型的字段,表示是否允许全局暂停。

DenyCapV2 被标记为 has keystore,意味着它可以被索引和存储。

/// Return the total number of `T`'s in circulation.
public fun total_supply&lt;T>(cap: &TreasuryCap&lt;T>): u64 {
    balance::supply_value(&cap.total_supply)
}

这个函数接受一个对 TreasuryCap&lt;T> 的引用,并返回流通中的 T 类型硬币的总数。它通过调用 balance::supply_value 函数来获取 Supply&lt;T> 中的值。

/// Unwrap `TreasuryCap` getting the `Supply`.
///
/// Operation is irreversible. Supply cannot be converted into a `TreasuryCap` due
/// to different security guarantees (TreasuryCap can be created only once for a type)
public fun treasury_into_supply&lt;T>(treasury: TreasuryCap&lt;T>): Supply&lt;T> {
    let TreasuryCap { id, total_supply } = treasury;
    id.delete();
    total_supply
}

这个函数将 TreasuryCap&lt;T> 转换为 Supply&lt;T>,这个操作是不可逆的。一旦 TreasuryCap 被转换成 Supply,就不能逆转,因为 TreasuryCap 只能为每种类型创建一次,这提供了不同的安全保证。

/// Get immutable reference to the treasury's `Supply`.
public fun supply_immut&lt;T>(treasury: &TreasuryCap&lt;T>): &Supply&lt;T> {
    &treasury.total_supply
}

这个函数返回对 TreasuryCap&lt;T>Supply&lt;T> 的不可变引用。

/// Get mutable reference to the treasury's `Supply`.
public fun supply_mut&lt;T>(treasury: &mut TreasuryCap&lt;T>): &mut Supply&lt;T> {
    &mut treasury.total_supply
}

这个函数返回对 TreasuryCap&lt;T>Supply&lt;T> 的可变引用。

余额与硬币访问器和类型转换

/// Public getter for the coin's value
public fun value&lt;T>(self: &Coin&lt;T>): u64 {
    self.balance.value()
}

这个函数是一个公共的访问器,用于获取 Coin&lt;T> 的值,通过调用其 balancevalue 方法。

/// Get immutable reference to the balance of a coin.
public fun balance&lt;T>(coin: &Coin&lt;T>): &Balance&lt;T> {
    &coin.balance
}

这个函数返回对 Coin&lt;T>Balance&lt;T> 的不可变引用。

/// Get a mutable reference to the balance of a coin.
public fun balance_mut&lt;T>(coin: &mut Coin&lt;T>): &mut Balance&lt;T> {
    &mut coin.balance
}

这个函数返回对 Coin&lt;T>Balance&lt;T> 的可变引用。

/// Wrap a balance into a Coin to make it transferable.
public fun from_balance&lt;T>(balance: Balance&lt;T>, ctx: &mut TxContext): Coin&lt;T> {
    Coin { id: object::new(ctx), balance }
}

这个函数将 Balance&lt;T> 包装成 Coin&lt;T>,使其可以被转移。它接受一个 Balance&lt;T> 和一个事务上下文 TxContext,并返回一个新的 Coin&lt;T>

/// Destruct a Coin wrapper and keep the balance.
public fun into_balance&lt;T>(coin: Coin&lt;T>): Balance&lt;T> {
    let Coin { id, balance } = coin;
    id.delete();
    balance
}

这个函数销毁 Coin&lt;T> 包装器并保留余额。它接受一个 Coin&lt;T>,销毁其 id,然后返回 Balance&lt;T>

/// Take a `Coin` worth `value` from `Balance`.
/// Aborts if `value > balance.value`
public fun take&lt;T>(balance: &mut Balance&lt;T>, value: u64, ctx: &mut TxContext): Coin&lt;T> {
    Coin {
        id: object::new(ctx),
        balance: balance.split(value),
    }
}

这个函数从 Balance&lt;T> 中取出价值 valueCoin&lt;T>。如果 value 大于 balance.value,则中止操作。它接受一个可变引用的 Balance&lt;T>、一个值 value 和一个事务上下文 TxContext,并返回一个新的 Coin&lt;T>

/// Put a `Coin&lt;T>` to the `Balance&lt;T>`.
public fun put&lt;T>(balance: &mut Balance&lt;T>, coin: Coin&lt;T>) {
    balance.join(into_balance(coin));
}

这个函数将 Coin&lt;T> 放入 Balance&lt;T>。它接受一个可变引用的 Balance&lt;T> 和一个 Coin&lt;T>,并将 Coin&lt;T> 的余额加入到 Balance&lt;T> 中。

继续分析代码中剩余的部分:

基础硬币功能

/// Consume the coin `c` and add its value to `self`.
/// Aborts if `c.value + self.value > U64_MAX`
public entry fun join&lt;T>(self: &mut Coin&lt;T>, c: Coin&lt;T>) {
    let Coin { id, balance } = c;
    id.delete();
    self.balance.join(balance);
}

这个函数用于将两个 Coin 对象合并。它接受一个可变引用的 self(当前 Coin 对象)和一个要合并的 Coin 对象 c。函数会将 c 的余额加入到 self 的余额中,并删除 c 的 ID。如果合并后的总价值超过了 u64 类型的最大值,操作将中止。

/// Split coin `self` to two coins, one with balance `split_amount`,
/// and the remaining balance is left in `self`.
public fun split&lt;T>(self: &mut Coin&lt;T>, split_amount: u64, ctx: &mut TxContext): Coin&lt;T> {
    take(&mut self.balance, split_amount, ctx)
}

这个函数用于将当前 Coin 对象 self 分割成两个 Coin 对象,一个包含指定的 split_amount 金额,剩余的余额留在原 Coin 对象中。它调用 take 函数来从 self 的余额中取出 split_amount 金额,并创建一个新的 Coin 对象。

/// Split coin `self` into `n - 1` coins with equal balances. The remainder is left in
/// `self`. Return newly created coins.
public fun divide_into_n&lt;T>(self: &mut Coin&lt;T>, n: u64, ctx: &mut TxContext): vector&lt;Coin&lt;T>> {
    assert!(n > 0, EInvalidArg);
    assert!(n &lt;= value(self), ENotEnough);

    let mut vec = vector[];
    let mut i = 0;
    let split_amount = value(self) / n;
    while (i &lt; n - 1) {
        vec.push_back(self.split(split_amount, ctx));
        i = i + 1;
    };
    vec
}

这个函数用于将当前 Coin 对象 self 分割成 n 个等额的 Coin 对象,其中 n - 1 个是等额的,剩余的余额留在原 Coin 对象中。它首先检查 n 是否大于 0 且不超过 self 的总价值,然后将 self 的价值除以 n 得到每个分割后的 Coin 对象的价值,并循环调用 split 函数来创建新的 Coin 对象,最后返回包含新创建的 Coin 对象的向量。

/// Make any Coin with a zero value. Useful for placeholding
/// bids/payments or preemptively making empty balances.
public fun zero&lt;T>(ctx: &mut TxContext): Coin&lt;T> {
    Coin { id: object::new(ctx), balance: balance::zero() }
}

这个函数用于创建一个价值为零的 Coin 对象。它接受一个事务上下文 TxContext,并返回一个新的 Coin 对象,其余额为零。这在需要占位符或预先创建空余额时非常有用。

/// Destroy a coin with value zero
public fun destroy_zero&lt;T>(c: Coin&lt;T>) {
    let Coin { id, balance } = c;
    id.delete();
    balance.destroy_zero()
}

这个函数用于销毁一个价值为零的 Coin 对象。它接受一个 Coin&lt;T> 对象,分解出其 ID 和余额,然后分别销毁它们。

注册新货币类型和管理货币供应

/// Create a new currency type `T` as and return the `TreasuryCap` for
/// `T` to the caller. Can only be called with a `one-time-witness`
/// type, ensuring that there's only one `TreasuryCap` per `T`.
public fun create_currency&lt;T: drop>(
    witness: T,
    decimals: u8,
    symbol: vector&lt;u8>,
    name: vector&lt;u8>,
    description: vector&lt;u8>,
    icon_url: Option&lt;Url>,
    ctx: &mut TxContext,
): (TreasuryCap&lt;T>, CoinMetadata&lt;T>) {
    // Make sure there's only one instance of the type T
    assert!(sui::types::is_one_time_witness(&witness), EBadWitness);

    (
        TreasuryCap {
            id: object::new(ctx),
            total_supply: balance::create_supply(witness),
        },
        CoinMetadata {
            id: object::new(ctx),
            decimals,
            name: string::utf8(name),
            symbol: ascii::string(symbol),
            description: string::utf8(description),
            icon_url,
        },
    )
}

这个函数用于创建一个新的货币类型 T,并返回该货币类型的 TreasuryCapCoinMetadata。它接受一个一次性见证 witness(确保每个货币类型只有一个 TreasuryCap),以及其他元数据参数,如小数位数、符号、名称、描述和图标 URL。函数首先检查 witness 是否为一次性见证,然后创建 TreasuryCapCoinMetadata,并返回它们。

接下来,我们继续分析代码中的剩余部分:

创建受监管货币类型

/// This creates a new currency, via `create_currency`, but with an extra capability that
/// allows for specific addresses to have their coins frozen. When an address is added to the
/// deny list, it is immediately unable to interact with the currency's coin as input objects.
/// Additionally at the start of the next epoch, they will be unable to receive the currency's
/// coin.
/// The `allow_global_pause` flag enables an additional API that will cause all addresses to be
/// be denied. Note however, that this doesn't affect per-address entries of the deny list and
/// will not change the result of the "contains" APIs.
public fun create_regulated_currency_v2&lt;T: drop>(
    witness: T,
    decimals: u8,
    symbol: vector&lt;u8>,
    name: vector&lt;u8>,
    description: vector&lt;u8>,
    icon_url: Option&lt;Url>,
    allow_global_pause: bool,
    ctx: &mut TxContext,
): (TreasuryCap&lt;T>, DenyCapV2&lt;T>, CoinMetadata&lt;T>) {
    let (treasury_cap, metadata) = create_currency(
        witness,
        decimals,
        symbol,
        name,
        description,
        icon_url,
        ctx,
    );
    let deny_cap = DenyCapV2 {
        id: object::new(ctx),
        allow_global_pause,
    };
    transfer::freeze_object(RegulatedCoinMetadata&lt;T> {
        id: object::new(ctx),
        coin_metadata_object: object::id(&metadata),
        deny_cap_object: object::id(&deny_cap),
    });
    (treasury_cap, deny_cap, metadata)
}

这个函数创建一个新的受监管货币类型,除了创建货币的基本操作外,还提供了冻结特定地址的能力。这些地址将无法使用该货币类型的硬币作为交易输入,并且在下一个时期开始时,将无法接收该货币类型的硬币。allow_global_pause 参数允许持有者启用全局暂停,阻止所有地址使用该货币类型的硬币。

迁移受监管货币到新版本

/// Given the `DenyCap` for a regulated currency, migrate it to the new `DenyCapV2` type.
/// All entries in the deny list will be migrated to the new format.
/// See `create_regulated_currency_v2` for details on the new v2 of the deny list.
public fun migrate_regulated_currency_to_v2&lt;T>(
    deny_list: &mut DenyList,
    cap: DenyCap&lt;T>,
    allow_global_pause: bool,
    ctx: &mut TxContext,
): DenyCapV2&lt;T> {
    let DenyCap { id } = cap;
    object::delete(id);
    let ty = type_name::get_with_original_ids&lt;T>().into_string().into_bytes();
    deny_list.migrate_v1_to_v2(DENY_LIST_COIN_INDEX, ty, ctx);
    DenyCapV2 {
        id: object::new(ctx),
        allow_global_pause,
    }
}

这个函数用于将旧的 DenyCap 迁移到新的 DenyCapV2 类型。它删除旧的 DenyCap 对象,并迁移黑名单中的所有条目到新的格式。

铸造和销毁硬币

/// Create a coin worth `value` and increase the total supply
/// in `cap` accordingly.
public fun mint&lt;T>(cap: &mut TreasuryCap&lt;T>, value: u64, ctx: &mut TxContext): Coin&lt;T> {
    Coin {
        id: object::new(ctx),
        balance: cap.total_supply.increase_supply(value),
    }
}

这个函数用于铸造价值为 value 的新硬币,并相应地增加 TreasuryCap 中的总供应量。

/// Mint some amount of T as a `Balance` and increase the total
/// supply in `cap` accordingly.
/// Aborts if `value` + `cap.total_supply` >= U64_MAX
public fun mint_balance&lt;T>(cap: &mut TreasuryCap&lt;T>, value: u64): Balance&lt;T> {
    cap.total_supply.increase_supply(value)
}

这个函数用于铸造一定数量的 Balance&lt;T>,并增加 TreasuryCap 中的总供应量。如果铸造后总供应量达到 u64 最大值,操作将中止。

/// Destroy the coin `c` and decrease the total supply in `cap`
/// accordingly.
public entry fun burn&lt;T>(cap: &mut TreasuryCap&lt;T>, c: Coin&lt;T>): u64 {
    let Coin { id, balance } = c;
    id.delete();
    cap.total_supply.decrease_supply(balance)
}

这个函数用于销毁 Coin&lt;T> 对象 c,并相应地减少 TreasuryCap 中的总供应量。

管理黑名单

/// Adds the given address to the deny list, preventing it from interacting with the specified
/// coin type as an input to a transaction. Additionally at the start of the next epoch, the
/// address will be unable to receive objects of this coin type.
public fun deny_list_v2_add&lt;T>(
    deny_list: &mut DenyList,
    _deny_cap: &mut DenyCapV2&lt;T>,
    addr: address,
    ctx: &mut TxContext,
) {
    let ty = type_name::get_with_original_ids&lt;T>().into_string().into_bytes();
    deny_list.v2_add(DENY_LIST_COIN_INDEX, ty, addr, ctx)
}

这个函数用于将给定地址添加到黑名单中,阻止它与特定货币类型的硬币作为交易输入进行交互,并在下一个时期开始时,阻止它接收该货币类型的硬币。

/// Removes an address from the deny list. Similar to `deny_list_v2_add`, the effect for input
/// objects will be immediate, but the effect for receiving objects will be delayed until the
/// next epoch.
public fun deny_list_v2_remove&lt;T>(
    deny_list: &mut DenyList,
    _deny_cap: &mut DenyCapV2&lt;T>,
    addr: address,
    ctx: &mut TxContext,
) {
    let ty = type_name::get_with_original_ids&lt;T>().into_string().into_bytes();
    deny_list.v2_remove(DENY_LIST_COIN_INDEX, ty, addr, ctx)
}

这个函数用于从黑名单中移除地址,立即生效于输入对象,但对于接收对象的影响将延迟到下一个时期。

继续分析代码中的剩余部分:

检查黑名单状态

/// Check if the deny list contains the given address for the current epoch. Denied addresses
/// in the current epoch will be unable to receive objects of this coin type.
public fun deny_list_v2_contains_current_epoch&lt;T>(
    deny_list: &DenyList,
    addr: address,
    ctx: &TxContext,
): bool {
    let ty = type_name::get_with_original_ids&lt;T>().into_string().into_bytes();
    deny_list.v2_contains_current_epoch(DENY_LIST_COIN_INDEX, ty, addr, ctx)
}

这个函数检查给定地址是否在当前时期的黑名单中。如果在黑名单中,这些地址将无法接收特定货币类型的硬币。

/// Check if the deny list contains the given address for the next epoch. Denied addresses in
/// the next epoch will immediately be unable to use objects of this coin type as inputs. At the
/// start of the next epoch, the address will be unable to receive objects of this coin type.
public fun deny_list_v2_contains_next_epoch&lt;T>(deny_list: &DenyList, addr: address): bool {
    let ty = type_name::get_with_original_ids&lt;T>().into_string().into_bytes();
    deny_list.v2_contains_next_epoch(DENY_LIST_COIN_INDEX, ty, addr)
}

这个函数检查给定地址是否在下一个时期的黑名单中。如果在黑名单中,这些地址将无法立即使用特定货币类型的硬币作为交易输入,并且在下一个时期开始时,将无法接收该货币类型的硬币。

全局暂停功能

/// Enable the global pause for the given coin type. This will immediately prevent all addresses
/// from using objects of this coin type as inputs. At the start of the next epoch, all
/// addresses will be unable to receive objects of this coin type.
public fun deny_list_v2_enable_global_pause&lt;T>(
    deny_list: &mut DenyList,
    deny_cap: &mut DenyCapV2&lt;T>,
    ctx: &mut TxContext,
) {
    assert!(deny_cap.allow_global_pause, EGlobalPauseNotAllowed);
    let ty = type_name::get_with_original_ids&lt;T>().into_string().into_bytes();
    deny_list.v2_enable_global_pause(DENY_LIST_COIN_INDEX, ty, ctx)
}

这个函数用于启用特定货币类型的全局暂停。一旦启用,所有地址将立即无法使用该货币类型的硬币作为交易输入,并且在下一个时期开始时,所有地址将无法接收该货币类型的硬币。

/// Disable the global pause for the given coin type. This will immediately allow all addresses
/// to resume using objects of this coin type as inputs. However, receiving objects of this coin
/// type will still be paused until the start of the next epoch.
public fun deny_list_v2_disable_global_pause&lt;T>(
    deny_list: &mut DenyList,
    deny_cap: &mut DenyCapV2&lt;T>,
    ctx: &mut TxContext,
) {
    assert!(deny_cap.allow_global_pause, EGlobalPauseNotAllowed);
    let ty = type_name::get_with_original_ids&lt;T>().into_string().into_bytes();
    deny_list.v2_disable_global_pause(DENY_LIST_COIN_INDEX, ty, ctx)
}

这个函数用于禁用特定货币类型的全局暂停。禁用后,所有地址将可以立即恢复使用该货币类型的硬币作为交易输入,但是接收该货币类型的硬币的功能将一直保持暂停,直到下一个时期开始。

检查全局暂停状态

/// Check if the global pause is enabled for the given coin type in the current epoch.
public fun deny_list_v2_is_global_pause_enabled_current_epoch&lt;T>(
    deny_list: &DenyList,
    ctx: &TxContext,
): bool {
    let ty = type_name::get_with_original_ids&lt;T>().into_string().into_bytes();
    deny_list.v2_is_global_pause_enabled_current_epoch(DENY_LIST_COIN_INDEX, ty, ctx)
}

这个函数检查特定货币类型的全局暂停是否在当前时期启用。

/// Check if the global pause is enabled for the given coin type in the next epoch.
public fun deny_list_v2_is_global_pause_enabled_next_epoch&lt;T>(deny_list: &DenyList): bool {
    let ty = type_name::get_with_original_ids&lt;T>().into_string().into_bytes();
    deny_list.v2_is_global_pause_enabled_next_epoch(DENY_LIST_COIN_INDEX, ty)
}

这个函数检查特定货币类型的全局暂停是否在下一个时期启用。

入口点

/// Mint `amount` of `Coin` and send it to `recipient`. Invokes `mint()`.
public entry fun mint_and_transfer&lt;T>(
    c: &mut TreasuryCap&lt;T>,
    amount: u64,
    recipient: address,
    ctx: &mut TxContext,
) {
    transfer::public_transfer(mint(c, amount, ctx), recipient)
}

这个入口点函数用于铸造一定数量的 Coin 并将其发送给指定的接收者。它首先调用 mint 函数铸造硬币,然后使用 public_transfer 函数将硬币发送给接收者。

更新硬币元数据

/// Update name of the coin in `CoinMetadata`
public entry fun update_name&lt;T>(
    treasury: &TreasuryCap&lt;T>,
    metadata: &mut CoinMetadata&lt;T>,
    name: string::String,
) {
    metadata.name = name;
}

这个入口点函数用于更新 CoinMetadata 中的硬币名称。

/// Update the symbol of the coin in `CoinMetadata`
public entry fun update_symbol&lt;T>(
    treasury: &TreasuryCap&lt;T>,
    metadata: &mut CoinMetadata&lt;T>,
    symbol: ascii::String,
) {
    metadata.symbol = symbol;
}

这个入口点函数用于更新 CoinMetadata 中的硬币符号。

/// Update the description of the coin in `CoinMetadata`
public entry fun update_description&lt;T>(
    treasury: &TreasuryCap&lt;T>,
    metadata: &mut CoinMetadata&lt;T>,
    description: string::String,
) {
    metadata.description = description;
}

这个入口点函数用于更新 CoinMetadata 中的硬币描述。

/// Update the url of the coin in `CoinMetadata`
public entry fun update_icon_url&lt;T>(
    treasury: &TreasuryCap&lt;T>,
    metadata: &mut CoinMetadata&lt;T>,
    url: ascii::String,
) {
    metadata.icon_url = option::some(url::new_unsafe(url));
}

这个入口点函数用于更新 CoinMetadata 中的硬币图标 URL。

获取硬币元数据字段

public fun get_decimals&lt;T>(metadata: &CoinMetadata&lt;T>): u8 {
    metadata.decimals
}

这个函数用于获取 CoinMetadata 中的硬币小数位数。

public fun get_name&lt;T>(metadata: &CoinMetadata&lt;T>): string::String {
    metadata.name
}

这个函数用于获取 CoinMetadata 中的硬币名称。

public fun get_symbol&lt;T>(metadata: &CoinMetadata&lt;T>): ascii::String {
    metadata.symbol
}

这个函数用于获取 CoinMetadata 中的硬币符号。

public fun get_description&lt;T>(metadata: &CoinMetadata&lt;T>): string::String {
    metadata.description
}

这个函数用于获取 CoinMetadata 中的硬币描述。

public fun get_icon_url&lt;T>(metadata: &CoinMetadata&lt;T>): Option&lt;Url> {
    metadata.icon_url
}

这个函数用于获取 CoinMetadata 中的硬币图标 URL。

测试专用代码

#[test_only]
/// Mint coins of any type for (obviously!) testing purposes only
public fun mint_for_testing&lt;T>(value: u64, ctx: &mut TxContext): Coin&lt;T> {
    Coin { id: object::new(ctx), balance: balance::create_for_testing(value) }
}

这个测试专用函数用于铸造任意类型的硬币,仅用于测试目的。

#[test_only]
/// Burn coins of any type for testing purposes only
public fun burn_for_testing&lt;T>(coin: Coin&lt;T>): u64 {
    let Coin { id, balance } = coin;
    id.delete();
    balance.destroy_for_testing()
}

这个测试专用函数用于销毁任意类型的硬币,仅用于测试目的。

#[test_only]
/// Create a `TreasuryCap` for any `Coin` for testing purposes.
public fun create_treasury_cap_for_testing&lt;T>(ctx: &mut TxContext): TreasuryCap&lt;T> {
    TreasuryCap {
        id: object::new(ctx),
        total_supply: balance::create_supply_for_testing(),
    }
}

这个测试专用函数用于为任意类型的硬币创建 TreasuryCap,仅用于测试目的。

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
aimotee
aimotee
江湖只有他的大名,没有他的介绍。