一、知识点一次性见证(OneTimeWitness)设计模式coin模块的使用transfer模块public_transfer和public_share_object的用法和理解发行代币的理解二、代码1、发行一个Coin合约创建项目运行命令:suimove
创建项目
创建一次性见证结构体
// 一次性见证结构体,one-time-witness,要有drop能力
public struct PRIVATECOIN has drop {}
// 初始化init函数
// witness:一次性证明,用于验证代币的唯一性和创造者的权限。
// ctx:交易上下文,用于处理交易中的各种状态和信息。
fun init(otw: PRIVATECOIN, ctx: &mut TxContext) {
// 使用 coin 模块的 create_currency 函数来创建代币
// treasuryCap:权限凭证,持有此凭证者有权铸造代币,coinMetadata:代币的元数据,如名称、符号、描述等信息。
let (treasuryCap, coinMetadata) = coin::create_currency(
otw, // 一次性证明,用于确认铸币操作的合法性
6, // 代币的小数位数
b"private coin", // 代币的符号
b"private coin", // 代币的名称
b"this is a private coin", // 代币的信息描述
option::some(url::new_unsafe_from_bytes(b"https://himg.bdimg.com/sys/portraitn/item/public.1.e9f8c73.BSHSEfneCaeAXqEhmsNv0A")), // 代币的图标
ctx // 交易上下文对象
);
// 冻结代币元数据,阻止后续的修改,把对象变成不可变对象
transfer::public_freeze_object(coinMetadata);
// treasury 是一个特殊的对象,它控制着代币的铸造权限。只有拥有 TreasuryCap 的实体才能铸造新的代币
// 将铸币的权限凭证转移到合约部署者,拥有铸币权才能铸造代币
transfer::public_transfer(treasuryCap, ctx.sender());
}
// 铸造代币函数,需要参数:铸币权限、铸币数量、接收代币地址、交易上下文
public entry fun mint(treasuryCap: &mut coin::TreasuryCap<PRIVATECOIN>, amount: u64, recipient: address, ctx: &mut TxContext) {
// 方法一:使用coin::mint()函数铸币,使用transfer::public_transfer()方法转移代币
let coin = coin::mint(treasuryCap, amount, ctx);
transfer::public_transfer(coin, recipient);
// 方法二:使用coin::mint_and_transfer()完成铸币和转移
// coin::mint_and_transfer(treasuryCap, amount, recipient, ctx)
}
// 销毁代币,使用coin::burn()方法
public entry fun burn(treasuryCap: &mut coin::TreasuryCap<PRIVATECOIN>, coin: Coin<PRIVATECOIN>) {
coin::burn(treasuryCap, coin);
}
module privatecoin::privatecoin;
use std::option;
use sui::coin;
use sui::coin::Coin;
use sui::transfer;
use sui::url;
// 一次性见证结构体,one-time-witness,要有drop能力
public struct PRIVATECOIN has drop {}
// 初始化init函数
// witness:一次性证明,用于验证代币的唯一性和创造者的权限。
// ctx:交易上下文,用于处理交易中的各种状态和信息。
fun init(otw: PRIVATECOIN, ctx: &mut TxContext) {
// 使用 coin 模块的 create_currency 函数来创建代币
// treasuryCap:权限凭证,持有此凭证者有权铸造代币,coinMetadata:代币的元数据,如名称、符号、描述等信息。
let (treasuryCap, coinMetadata) = coin::create_currency(
otw, // 一次性证明,用于确认铸币操作的合法性
6, // 代币的小数位数
b"private coin", // 代币的符号
b"private coin", // 代币的名称
b"this is a private coin", // 代币的信息描述
option::some(url::new_unsafe_from_bytes(b"https://himg.bdimg.com/sys/portraitn/item/public.1.e9f8c73.BSHSEfneCaeAXqEhmsNv0A")), // 代币的图标
ctx // 交易上下文对象
);
// 冻结代币元数据,阻止后续的修改,把对象变成不可变对象
transfer::public_freeze_object(coinMetadata);
// treasury 是一个特殊的对象,它控制着代币的铸造权限。只有拥有 TreasuryCap 的实体才能铸造新的代币
// 将铸币的权限凭证转移到合约部署者,拥有铸币权才能铸造代币
transfer::public_transfer(treasuryCap, ctx.sender());
}
// 铸造代币函数,需要参数:铸币权限、铸币数量、接收代币地址、交易上下文
public entry fun mint(treasuryCap: &mut coin::TreasuryCap<PRIVATECOIN>, amount: u64, recipient: address, ctx: &mut TxContext) {
// 方法一:使用coin::mint()函数铸币,使用transfer::public_transfer()方法转移代币
let coin = coin::mint(treasuryCap, amount, ctx);
transfer::public_transfer(coin, recipient);
// 方法二:使用coin::mint_and_transfer()完成铸币和转移
// coin::mint_and_transfer(treasuryCap, amount, recipient, ctx)
}
// 销毁代币,使用coin::burn()方法
public entry fun burn(treasuryCap: &mut coin::TreasuryCap<PRIVATECOIN>, coin: Coin<PRIVATECOIN>) {
coin::burn(treasuryCap, coin);
}
创建项目
创建一次性见证结构体
// 一次性见证结构体,one-time-witness,要有drop能力
public struct PUBLICCOIN has drop {}
// 初始化init函数
// witness:一次性证明,用于验证代币的唯一性和创造者的权限。
// ctx:交易上下文,用于处理交易中的各种状态和信息。
fun init(otw: PUBLICCOIN, ctx: &mut TxContext) {
// 使用 coin 模块的 create_currency 函数来创建代币
// treasuryCap:权限凭证,持有此凭证者有权铸造代币,coinMetadata:代币的元数据,如名称、符号、描述等信息。
let (treasuryCap, coinMetadata) = coin::create_currency(
otw, // 一次性证明,用于确认铸币操作的合法性
6, // 代币的小数位数
b"public coin", // 代币的符号
b"public coin", // 代币的名称
b"this is a public coin", // 代币的信息描述
option::some(url::new_unsafe_from_bytes(b"https://himg.bdimg.com/sys/portraitn/item/public.1.e9f8c73.BSHSEfneCaeAXqEhmsNv0A")), // 代币的图标
ctx // 交易上下文对象
);
// 冻结代币元数据,阻止后续的修改,把对象变成不可变对象
transfer::public_freeze_object(coinMetadata);
// treasury 是一个特殊的对象,它控制着代币的铸造权限。只有拥有 TreasuryCap 的实体才能铸造新的代币
// 共享铸币权
transfer::public_share_object(treasuryCap);
// 铸造代币函数,需要参数:铸币权限、铸币数量、接收代币地址、交易上下文
public entry fun mint(treasuryCap: &mut coin::TreasuryCap<PUBLICCOIN>, amount: u64, recipient: address, ctx: &mut TxContext) {
// 方法一:使用coin::mint()函数铸币,使用transfer::public_transfer()方法转移代币
let coin = coin::mint(treasuryCap, amount, ctx);
transfer::public_transfer(coin, recipient);
// 方法二:使用coin::mint_and_transfer()完成铸币和转移
// coin::mint_and_transfer(treasuryCap, amount, recipient, ctx)
}
// 销毁代币,使用coin::burn()方法
public entry fun burn(treasuryCap: &mut coin::TreasuryCap<PUBLICCOIN>, coin: Coin<PUBLICCOIN>) {
coin::burn(treasuryCap, coin);
}
module publiccoin::publiccoin;
use std::option;
use sui::coin;
use sui::coin::Coin;
use sui::transfer;
use sui::url;
// 一次性见证结构体,one-time-witness,要有drop能力
public struct PUBLICCOIN has drop {}
// 初始化init函数
// witness:一次性证明,用于验证代币的唯一性和创造者的权限。
// ctx:交易上下文,用于处理交易中的各种状态和信息。
fun init(otw: PUBLICCOIN, ctx: &mut TxContext) {
// 使用 coin 模块的 create_currency 函数来创建代币
// treasuryCap:权限凭证,持有此凭证者有权铸造代币,coinMetadata:代币的元数据,如名称、符号、描述等信息。
let (treasuryCap, coinMetadata) = coin::create_currency(
otw, // 一次性证明,用于确认铸币操作的合法性
6, // 代币的小数位数
b"public coin", // 代币的符号
b"public coin", // 代币的名称
b"this is a public coin", // 代币的信息描述
option::some(url::new_unsafe_from_bytes(b"https://himg.bdimg.com/sys/portraitn/item/public.1.e9f8c73.BSHSEfneCaeAXqEhmsNv0A")), // 代币的图标
ctx // 交易上下文对象
);
// 冻结代币元数据,阻止后续的修改,把对象变成不可变对象
transfer::public_freeze_object(coinMetadata);
// treasury 是一个特殊的对象,它控制着代币的铸造权限。只有拥有 TreasuryCap 的实体才能铸造新的代币
// 共享铸币权
transfer::public_share_object(treasuryCap);
}
// 铸造代币函数,需要参数:铸币权限、铸币数量、接收代币地址、交易上下文
public entry fun mint(treasuryCap: &mut coin::TreasuryCap<PUBLICCOIN>, amount: u64, recipient: address, ctx: &mut TxContext) {
// 方法一:使用coin::mint()函数铸币,使用transfer::public_transfer()方法转移代币
let coin = coin::mint(treasuryCap, amount, ctx);
transfer::public_transfer(coin, recipient);
// 方法二:使用coin::mint_and_transfer()完成铸币和转移
// coin::mint_and_transfer(treasuryCap, amount, recipient, ctx)
}
// 销毁代币,使用coin::burn()方法
public entry fun burn(treasuryCap: &mut coin::TreasuryCap<PUBLICCOIN>, coin: Coin<PUBLICCOIN>) {
coin::burn(treasuryCap, coin);
}
通过代码对比可以看到,两个项目的代码差别只有一处,就是关于铸币权限凭证 treasuryCap 的处理,privatecoin项目将铸币权限凭证 treasuryCap 转移给了合约部署者,publiccoin项目将铸币权限凭证 treasuryCap 共享给了所有用户。
两个合约的调用方法基本一致
sui client call --package <package ID> --module <module> --function <function> --args <args1 args2 ...>
调用burn方法:
sui client call --package <package ID> --module <module> --function <function> --args <args1 args2 ...>
通过不同合约的方法调用我们可以得出以下结论
privatecoin合约:合约发布者拥有铸币凭证权限,可以给不同地址铸造代币,但是合约发布者只能销毁自己拥有的代币;其他地址既不能铸造代币,也不能销毁代币
publiccoin合约:所用地址都拥有铸币凭证权限,可以给不同地址铸造代币,但只能销毁自己拥有的代币
不管有没有权限凭证,每个地址拥有的资产只能由该地址销毁
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!