首先感谢Let'sMove共学,感谢HOH社区我会把详细的过程和注意的点都写上,适合和我一样的小白开始学习move今天我们来分析一下Coin源码github源码:https://github.com/MystenLabs/sui/blo
<!--StartFragment--> 首先感谢Let's Move共学,感谢HOH社区 \ 我会把详细的过程和注意的点都写上,适合和我一样的小白开始学习move
<!--EndFragment-->
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<u8> =
// b"Kill switch was not allowed at the creation of the DenyCapV2";
const EGlobalPauseNotAllowed: u64 = 3;
这些行定义了一些常量,它们用作错误码,以便于在函数执行过程中遇到特定错误情况时引用。
EBadWitness
: 当传递给 create_supply
函数的类型不是一次性见证(one-time witness)时,返回此错误码。一次性见证是一种确保某个操作只执行一次的机制。
EInvalidArg
: 当传递给函数的参数无效时,返回此错误码。
ENotEnough
: 当尝试分割的硬币数量超过其余额允许的次数时,返回此错误码。
EGlobalPauseNotAllowed
: 当尝试启用全局暂停功能,但在创建 DenyCapV2
时未允许此操作时,返回此错误码。这里的注释表明原本有一个错误消息的字节向量定义,但现在已被替换为一个简单的 u64
错误码。
/// A coin of type `T` worth `value`. Transferable and storable
public struct Coin<phantom T> has key, store {
id: UID,
balance: Balance<T>,
}
这里定义了一个名为 Coin
的结构体,它是一个泛型类型,其中 phantom T
表示 T
是一个不出现在结构体中的类型参数,它用于影响类型而不存储任何值。Coin
结构体有两个字段:
id
: 一个 UID
类型的字段,唯一标识一个 Coin
实例。
balance
: 一个 Balance<T>
类型的字段,表示硬币的余额。
Coin
结构体被标记为 has key
和 store
,意味着它可以在数据库中被索引和存储。
/// Each Coin type T created through `create_currency` function will have a
/// unique instance of CoinMetadata<T> that stores the metadata for this coin type.
public struct CoinMetadata<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<Url>,
}
CoinMetadata
结构体用于存储特定 Coin
类型的元数据。它也是泛型结构体,使用 phantom T
。字段包括:
id
: 一个 UID
类型的字段,唯一标识一个 CoinMetadata
实例。
decimals
: 一个 u8
类型的字段,表示硬币使用的小数位数。
name
: 一个 string::String
类型的字段,表示代币的名称。
symbol
: 一个 ascii::String
类型的字段,表示代币的符号。
description
: 一个 string::String
类型的字段,表示代币的描述。
icon_url
: 一个 Option<Url>
类型的字段,表示代币图标的 URL,可以是 None
,表示没有图标。
CoinMetadata
也被标记为 has key
和 store
,意味着它可以被索引和存储。
接下来,我们继续分析代码中的其他部分:
/// Similar to CoinMetadata, but created only for regulated coins that use the DenyList.
/// This object is always immutable.
public struct RegulatedCoinMetadata<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
(黑名单)。这个结构体是不可变的,意味着一旦创建,其内容不能被修改。
id
: 一个 UID
类型的字段,唯一标识一个 RegulatedCoinMetadata
实例。
coin_metadata_object
: 一个 ID
类型的字段,存储这个受监管硬币类型对应的 CoinMetadata
对象的 ID。
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<phantom T> has key, store {
id: UID,
total_supply: Supply<T>,
}
TreasuryCap
结构体表示一种能力,允许持有者铸造和销毁类型为 T
的硬币。它是可转移的。
id
: 一个 UID
类型的字段,唯一标识一个 TreasuryCap
实例。
total_supply
: 一个 Supply<T>
类型的字段,表示这种类型硬币的总供应量。
TreasuryCap
被标记为 has key
和 store
,意味着它可以被索引和存储。
/// 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<phantom T> has key, store {
id: UID,
allow_global_pause: bool,
}
DenyCapV2
结构体表示一种能力,允许持有者阻止地址使用特定货币的硬币,立即阻止这些地址与硬币作为交易输入的交互,并在下一个时期开始时阻止它们接收硬币。如果 allow_global_pause
为 true
,持有者可以启用全局暂停,表现得就好像所有地址都被添加到了黑名单中。
id
: 一个 UID
类型的字段,唯一标识一个 DenyCapV2
实例。
allow_global_pause
: 一个 bool
类型的字段,表示是否允许全局暂停。
DenyCapV2
被标记为 has key
和 store
,意味着它可以被索引和存储。
/// Return the total number of `T`'s in circulation.
public fun total_supply<T>(cap: &TreasuryCap<T>): u64 {
balance::supply_value(&cap.total_supply)
}
这个函数接受一个对 TreasuryCap<T>
的引用,并返回流通中的 T
类型硬币的总数。它通过调用 balance::supply_value
函数来获取 Supply<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<T>(treasury: TreasuryCap<T>): Supply<T> {
let TreasuryCap { id, total_supply } = treasury;
id.delete();
total_supply
}
这个函数将 TreasuryCap<T>
转换为 Supply<T>
,这个操作是不可逆的。一旦 TreasuryCap
被转换成 Supply
,就不能逆转,因为 TreasuryCap
只能为每种类型创建一次,这提供了不同的安全保证。
/// Get immutable reference to the treasury's `Supply`.
public fun supply_immut<T>(treasury: &TreasuryCap<T>): &Supply<T> {
&treasury.total_supply
}
这个函数返回对 TreasuryCap<T>
中 Supply<T>
的不可变引用。
/// Get mutable reference to the treasury's `Supply`.
public fun supply_mut<T>(treasury: &mut TreasuryCap<T>): &mut Supply<T> {
&mut treasury.total_supply
}
这个函数返回对 TreasuryCap<T>
中 Supply<T>
的可变引用。
/// Public getter for the coin's value
public fun value<T>(self: &Coin<T>): u64 {
self.balance.value()
}
这个函数是一个公共的访问器,用于获取 Coin<T>
的值,通过调用其 balance
的 value
方法。
/// Get immutable reference to the balance of a coin.
public fun balance<T>(coin: &Coin<T>): &Balance<T> {
&coin.balance
}
这个函数返回对 Coin<T>
中 Balance<T>
的不可变引用。
/// Get a mutable reference to the balance of a coin.
public fun balance_mut<T>(coin: &mut Coin<T>): &mut Balance<T> {
&mut coin.balance
}
这个函数返回对 Coin<T>
中 Balance<T>
的可变引用。
/// Wrap a balance into a Coin to make it transferable.
public fun from_balance<T>(balance: Balance<T>, ctx: &mut TxContext): Coin<T> {
Coin { id: object::new(ctx), balance }
}
这个函数将 Balance<T>
包装成 Coin<T>
,使其可以被转移。它接受一个 Balance<T>
和一个事务上下文 TxContext
,并返回一个新的 Coin<T>
。
/// Destruct a Coin wrapper and keep the balance.
public fun into_balance<T>(coin: Coin<T>): Balance<T> {
let Coin { id, balance } = coin;
id.delete();
balance
}
这个函数销毁 Coin<T>
包装器并保留余额。它接受一个 Coin<T>
,销毁其 id
,然后返回 Balance<T>
。
/// Take a `Coin` worth `value` from `Balance`.
/// Aborts if `value > balance.value`
public fun take<T>(balance: &mut Balance<T>, value: u64, ctx: &mut TxContext): Coin<T> {
Coin {
id: object::new(ctx),
balance: balance.split(value),
}
}
这个函数从 Balance<T>
中取出价值 value
的 Coin<T>
。如果 value
大于 balance.value
,则中止操作。它接受一个可变引用的 Balance<T>
、一个值 value
和一个事务上下文 TxContext
,并返回一个新的 Coin<T>
。
/// Put a `Coin<T>` to the `Balance<T>`.
public fun put<T>(balance: &mut Balance<T>, coin: Coin<T>) {
balance.join(into_balance(coin));
}
这个函数将 Coin<T>
放入 Balance<T>
。它接受一个可变引用的 Balance<T>
和一个 Coin<T>
,并将 Coin<T>
的余额加入到 Balance<T>
中。
继续分析代码中剩余的部分:
/// Consume the coin `c` and add its value to `self`.
/// Aborts if `c.value + self.value > U64_MAX`
public entry fun join<T>(self: &mut Coin<T>, c: Coin<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<T>(self: &mut Coin<T>, split_amount: u64, ctx: &mut TxContext): Coin<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<T>(self: &mut Coin<T>, n: u64, ctx: &mut TxContext): vector<Coin<T>> {
assert!(n > 0, EInvalidArg);
assert!(n <= value(self), ENotEnough);
let mut vec = vector[];
let mut i = 0;
let split_amount = value(self) / n;
while (i < 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<T>(ctx: &mut TxContext): Coin<T> {
Coin { id: object::new(ctx), balance: balance::zero() }
}
这个函数用于创建一个价值为零的 Coin
对象。它接受一个事务上下文 TxContext
,并返回一个新的 Coin
对象,其余额为零。这在需要占位符或预先创建空余额时非常有用。
/// Destroy a coin with value zero
public fun destroy_zero<T>(c: Coin<T>) {
let Coin { id, balance } = c;
id.delete();
balance.destroy_zero()
}
这个函数用于销毁一个价值为零的 Coin
对象。它接受一个 Coin<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<T: drop>(
witness: T,
decimals: u8,
symbol: vector<u8>,
name: vector<u8>,
description: vector<u8>,
icon_url: Option<Url>,
ctx: &mut TxContext,
): (TreasuryCap<T>, CoinMetadata<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
,并返回该货币类型的 TreasuryCap
和 CoinMetadata
。它接受一个一次性见证 witness
(确保每个货币类型只有一个 TreasuryCap
),以及其他元数据参数,如小数位数、符号、名称、描述和图标 URL。函数首先检查 witness
是否为一次性见证,然后创建 TreasuryCap
和 CoinMetadata
,并返回它们。
接下来,我们继续分析代码中的剩余部分:
/// 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<T: drop>(
witness: T,
decimals: u8,
symbol: vector<u8>,
name: vector<u8>,
description: vector<u8>,
icon_url: Option<Url>,
allow_global_pause: bool,
ctx: &mut TxContext,
): (TreasuryCap<T>, DenyCapV2<T>, CoinMetadata<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<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<T>(
deny_list: &mut DenyList,
cap: DenyCap<T>,
allow_global_pause: bool,
ctx: &mut TxContext,
): DenyCapV2<T> {
let DenyCap { id } = cap;
object::delete(id);
let ty = type_name::get_with_original_ids<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<T>(cap: &mut TreasuryCap<T>, value: u64, ctx: &mut TxContext): Coin<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<T>(cap: &mut TreasuryCap<T>, value: u64): Balance<T> {
cap.total_supply.increase_supply(value)
}
这个函数用于铸造一定数量的 Balance<T>
,并增加 TreasuryCap
中的总供应量。如果铸造后总供应量达到 u64
最大值,操作将中止。
/// Destroy the coin `c` and decrease the total supply in `cap`
/// accordingly.
public entry fun burn<T>(cap: &mut TreasuryCap<T>, c: Coin<T>): u64 {
let Coin { id, balance } = c;
id.delete();
cap.total_supply.decrease_supply(balance)
}
这个函数用于销毁 Coin<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<T>(
deny_list: &mut DenyList,
_deny_cap: &mut DenyCapV2<T>,
addr: address,
ctx: &mut TxContext,
) {
let ty = type_name::get_with_original_ids<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<T>(
deny_list: &mut DenyList,
_deny_cap: &mut DenyCapV2<T>,
addr: address,
ctx: &mut TxContext,
) {
let ty = type_name::get_with_original_ids<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<T>(
deny_list: &DenyList,
addr: address,
ctx: &TxContext,
): bool {
let ty = type_name::get_with_original_ids<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<T>(deny_list: &DenyList, addr: address): bool {
let ty = type_name::get_with_original_ids<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<T>(
deny_list: &mut DenyList,
deny_cap: &mut DenyCapV2<T>,
ctx: &mut TxContext,
) {
assert!(deny_cap.allow_global_pause, EGlobalPauseNotAllowed);
let ty = type_name::get_with_original_ids<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<T>(
deny_list: &mut DenyList,
deny_cap: &mut DenyCapV2<T>,
ctx: &mut TxContext,
) {
assert!(deny_cap.allow_global_pause, EGlobalPauseNotAllowed);
let ty = type_name::get_with_original_ids<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<T>(
deny_list: &DenyList,
ctx: &TxContext,
): bool {
let ty = type_name::get_with_original_ids<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<T>(deny_list: &DenyList): bool {
let ty = type_name::get_with_original_ids<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<T>(
c: &mut TreasuryCap<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<T>(
treasury: &TreasuryCap<T>,
metadata: &mut CoinMetadata<T>,
name: string::String,
) {
metadata.name = name;
}
这个入口点函数用于更新 CoinMetadata
中的硬币名称。
/// Update the symbol of the coin in `CoinMetadata`
public entry fun update_symbol<T>(
treasury: &TreasuryCap<T>,
metadata: &mut CoinMetadata<T>,
symbol: ascii::String,
) {
metadata.symbol = symbol;
}
这个入口点函数用于更新 CoinMetadata
中的硬币符号。
/// Update the description of the coin in `CoinMetadata`
public entry fun update_description<T>(
treasury: &TreasuryCap<T>,
metadata: &mut CoinMetadata<T>,
description: string::String,
) {
metadata.description = description;
}
这个入口点函数用于更新 CoinMetadata
中的硬币描述。
/// Update the url of the coin in `CoinMetadata`
public entry fun update_icon_url<T>(
treasury: &TreasuryCap<T>,
metadata: &mut CoinMetadata<T>,
url: ascii::String,
) {
metadata.icon_url = option::some(url::new_unsafe(url));
}
这个入口点函数用于更新 CoinMetadata
中的硬币图标 URL。
public fun get_decimals<T>(metadata: &CoinMetadata<T>): u8 {
metadata.decimals
}
这个函数用于获取 CoinMetadata
中的硬币小数位数。
public fun get_name<T>(metadata: &CoinMetadata<T>): string::String {
metadata.name
}
这个函数用于获取 CoinMetadata
中的硬币名称。
public fun get_symbol<T>(metadata: &CoinMetadata<T>): ascii::String {
metadata.symbol
}
这个函数用于获取 CoinMetadata
中的硬币符号。
public fun get_description<T>(metadata: &CoinMetadata<T>): string::String {
metadata.description
}
这个函数用于获取 CoinMetadata
中的硬币描述。
public fun get_icon_url<T>(metadata: &CoinMetadata<T>): Option<Url> {
metadata.icon_url
}
这个函数用于获取 CoinMetadata
中的硬币图标 URL。
#[test_only]
/// Mint coins of any type for (obviously!) testing purposes only
public fun mint_for_testing<T>(value: u64, ctx: &mut TxContext): Coin<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<T>(coin: Coin<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<T>(ctx: &mut TxContext): TreasuryCap<T> {
TreasuryCap {
id: object::new(ctx),
total_supply: balance::create_supply_for_testing(),
}
}
这个测试专用函数用于为任意类型的硬币创建 TreasuryCap
,仅用于测试目的。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!