Move on Sui入门 004-在sui链上发布Coin合约和Faucet Coin合约

一、知识点

  1. 一次性见证(One Time Witness)设计模式
  2. coin模块的使用
  3. transfer模块 public_transfer 和 public_share_object 的用法和理解
  4. 发行代币的理解

二、代码

1、发行一个Coin合约
  1. 创建项目
  • 运行命令:sui move new privatecoin
  • 修改项目依赖,Move.toml文件中的git地址,将github替换为gitee
  • 删除privatecoin.move中的注释部分
  1. 创建一次性见证结构体
  • 只有drop能力

  • 没有字段

  • 不是泛型字段

  • 以module名称的大写字母命名

    // 一次性见证结构体,one-time-witness,要有drop能力
    public struct PRIVATECOIN has drop {}

  1. 初始化init函数
  • 使用coin::create_currency()方法创建代币

  • 使用transfer::public_transfer()方法转移铸币的权限凭证给合约部署者

    // 初始化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());
    }

  1. 实现铸币方法
  • 第一种方法:使用coin::mint()方法铸币,使用transfer::public_transfer()方法转移代币

  • 第二种方法:使用coin::mint_and_transfer()方法铸造并转移代币

  • 以上两种方法都要传入铸币权限、铸币数量、接收者地址和 TxContext交易上下文对象

    // 铸造代币函数,需要参数:铸币权限、铸币数量、接收代币地址、交易上下文
    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)
    }

  1. 实现销毁代币方法
  • 使用coin::burn()方法销毁代币

    // 销毁代币,使用coin::burn()方法
    public entry fun burn(treasuryCap: &mut coin::TreasuryCap<PRIVATECOIN>, coin: Coin<PRIVATECOIN>) {
    coin::burn(treasuryCap, coin);
    }

  1. 完整代码

    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);
    }

2、发行一个Faucet Coin合约
  1. 创建项目
  • 运行命令:sui move new publiccoin
  • 修改项目依赖,Move.toml文件中的git地址,将github替换为gitee
  • 删除publiccoin.move中的注释部分
  1. 创建一次性见证结构体
  • 只有drop能力

  • 没有字段

  • 不是泛型字段

  • 以module名称的大写字母命名

    // 一次性见证结构体,one-time-witness,要有drop能力
    public struct PUBLICCOIN has drop {}

  1. 初始化init函数
  • 使用coin::create_currency()方法创建代币

  • 使用transfer::public_share_object()方法共享铸币权

    // 初始化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);

  1. 实现铸币方法
  • 第一种方法:使用coin::mint()方法铸币,使用transfer::public_transfer()方法转移代币

  • 第二种方法:使用coin::mint_and_transfer()方法铸造并转移代币

  • 以上两种方法都要传入铸币权限、铸币数量、接收者地址和 TxContext交易上下文对象

    // 铸造代币函数,需要参数:铸币权限、铸币数量、接收代币地址、交易上下文
    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)
    }

  1. 实现销毁代币方法
  • 使用coin::burn()方法销毁代币

    // 销毁代币,使用coin::burn()方法
    public entry fun burn(treasuryCap: &mut coin::TreasuryCap<PUBLICCOIN>, coin: Coin<PUBLICCOIN>) {
    coin::burn(treasuryCap, coin);
    }

  1. 完整代码

    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);
    }

3、两个Coin合约对比

通过代码对比可以看到,两个项目的代码差别只有一处,就是关于铸币权限凭证 treasuryCap 的处理,privatecoin项目将铸币权限凭证 treasuryCap 转移给了合约部署者,publiccoin项目将铸币权限凭证 treasuryCap 共享给了所有用户。

三、调用

两个合约的调用方法基本一致

  • 编译合约:sui move build
  • 发布合约:sui client publish
    • 发布成功,找到项目 Transaction Digest,在sui浏览器输入打开
    • 找到合约相关object ID,提供给mint和burn方法
  • 调用mint方法:

    sui client call --package <package ID> --module <module> --function <function> --args <args1 args2 ...>

    • 铸币成功后,找到 Transaction Digest,在sui浏览器输入打开
    • 找到代币object ID,提供给burn方法使用
  • 调用burn方法:

    sui client call --package <package ID> --module <module> --function <function> --args <args1 args2 ...>

四、结论

通过不同合约的方法调用我们可以得出以下结论

  • privatecoin合约:合约发布者拥有铸币凭证权限,可以给不同地址铸造代币,但是合约发布者只能销毁自己拥有的代币;其他地址既不能铸造代币,也不能销毁代币
  • publiccoin合约:所用地址都拥有铸币凭证权限,可以给不同地址铸造代币,但只能销毁自己拥有的代币
  • 不管有没有权限凭证,每个地址拥有的资产只能由该地址销毁

至此结束,更多信息请,,,https://t.me/gtokentool

相关推荐
程亦寻5 小时前
物联网与前沿技术融合分析
人工智能·物联网·区块链·量子计算
卓琢11 小时前
前沿技术趋势洞察与分析:探寻科技变革的多维密码
人工智能·区块链·量子计算
小志biubiu12 小时前
技术洞察:C++在后端开发中的前沿趋势与社会影响
开发语言·c++·笔记·学习·区块链·c11
资讯分享周17 小时前
万泽时代:以“数智”之力,驱动榆林能源集团碳管理数字化转型
人工智能·区块链·能源
我要学脑机1 天前
加密货币的基本交易技术指标
区块链
qiquandongkh1 天前
期权懂|期权的溢价率和杠杆率有什么区别?
大数据·区块链
BTColdman11 天前
Plume :RWAfi 叙事引领者,全新加密时代的新蓝筹生态
人工智能·区块链
焗猪扒饭3 天前
加密货币安全基石: 分布式密钥生成协议(GG18, 币安tss-lib keygen部分)
web3·区块链·数字货币
艾思科蓝 AiScholar3 天前
【江西新能源科技职业学院主办 | JPCS(ISSN: 1742-6588)出版,快速见刊检索】2025年可再生能源与节能国际会议(REEC 2025)
数据库·人工智能·科技·神经网络·数据分析·区块链·信息与通信
dingzd954 天前
Web3如何赋能元宇宙中的数字身份与隐私保护
web3·去中心化·区块链·数据安全