(三)Let's Move共学,sui move 发币

  • aimotee
  • 更新于 2024-11-21 11:12
  • 阅读 475

首先感谢Let'sMove共学,感谢HOH社区我会把详细的过程和注意的点都写上,适合和我一样的小白开始学习move一.项目文件结构详细官方文档地址:https://move-book.com/本期文章使用文献:https://docs

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

<!--EndFragment-->

一.项目文件结构

详细官方文档地址:https://move-book.com/ 本期文章使用文献:https://docs.sui.io/guides/developer/coin

1.文件结构

我们在上一节已经学会如何创建一个sui的项目文件sui move new &lt;你的项目名称>,整个目录结构如下

sources/
    my_module.move
    another_module.move
    ...
tests/
    ...
examples/
    using_my_module.move
Move.toml

<!--StartFragment-->

放入tests目录中的代码不会在链上发布,并且仅在测试中可用。目录可以是用于代码示例,也不在链上发布。tests``tests``examples

<!--EndFragment-->

2.Move.toml简单解释

[package]
name = "my_project"
version = "0.0.0"
edition = "2024"

[dependencies]
Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "framework/testnet" }

[addresses]
std =  "0x1"
alice = "0xA11CE"

[dev-addresses]
alice = "0xB0B"

<!--StartFragment--> <!--StartFragment-->

[package]

<!--EndFragment-->

  • name- 导入包时包的名称;
  • version- 包的版本,可用于 Release Management;
  • edition- Move 语言的版本

<!--EndFragment-->

<!--StartFragment-->

[dependencies]

<!--EndFragment-->

<!--StartFragment-->

该部分用于指定项目的依赖关系。每个依赖项都是 指定为键值对。

依赖项规范可以是 git 存储库 URL 或 local 目录

<!--EndFragment-->

<!--StartFragment-->

[addresses]

<!--EndFragment--> <!--StartFragment-->

该部分用于为地址添加别名。任何地址都可以在这个部分 <!--StartFragment-->

alice = "0xA11CE"``alice``0xA11CE

<!--EndFragment-->

<!--EndFragment--> <!--StartFragment-->

[dev-addresses]

<!--EndFragment--> <!--StartFragment-->

该部分与address相同,但仅适用于 test 和 dev 模式

<!--EndFragment-->

二. Coin合约与Faucet_coin合约

我们这里直接以我自己最简单的coin代码,然后对代码进行简单的解析

module aimotee::my_coin {
    use sui::coin::{Self, TreasuryCap};

    public struct MY_COIN has drop {}

    fun init(witness: MY_COIN, ctx: &mut TxContext) {
        let (treasury, metadata) = coin::create_currency(witness, 6, b"Ai", b"Aimotee", b"a coin", option::none(), ctx);
        transfer::public_freeze_object(metadata);
        transfer::public_transfer(treasury, ctx.sender())
    }

    public fun mint(
        treasury_cap: &mut TreasuryCap&lt;MY_COIN>,
        amount: u64,
        recipient: address,
        ctx: &mut TxContext,
    ) {
        let coin = coin::mint(treasury_cap, amount, ctx);
        transfer::public_transfer(coin, recipient)
    }
}
}
module aimotee_faucet_coin::my_coin {
    use sui::coin::{Self, TreasuryCap};

    public struct MY_COIN has drop {}

    fun init(witness: MY_COIN, ctx: &mut TxContext) {
        let (treasury, metadata) = coin::create_currency(witness, 6, b"Ai", b"Aimotee_faucet", b"a coin", option::none(), ctx);
        transfer::public_freeze_object(metadata);
        transfer::public_share_object(treasury)
    }

    public fun mint(
        treasury_cap: &mut TreasuryCap&lt;MY_COIN>,
        amount: u64,
        recipient: address,
        ctx: &mut TxContext,
    ) {
        let coin = coin::mint(treasury_cap, amount, ctx);
        transfer::public_transfer(coin, recipient)
    }
}

这段代码是用Move语言编写的,旨在在Sui区块链平台上定义并操作一种名为MY_COIN的自定义货币。下面是对这段代码的详细分析和解释:

模块定义

module aimotee::my_coin {

这行代码定义了一个新的模块my_coin,它位于aimotee命名空间下。模块是Move语言中组织代码的基本单元,类似于其他编程语言中的类或包。

导入外部模块

use sui::coin::{Self, TreasuryCap};

这行代码导入了Sui标准库中的coin模块及其内部的TreasuryCap类型。Self关键字表示从coin模块中导入所有同名的类型和函数。

定义结构体

public struct MY_COIN has drop {}

这行代码定义了一个公开的结构体MY_COIN,并且声明它具有drop属性。drop属性意味着当对象不再需要时,会自动调用特定的清理逻辑(如果定义了的话)。对于货币对象来说,这个属性通常不是必需的,因为货币对象应该总是保持存在,除非它们被销毁或转移。

初始化货币

fun init(witness: MY_COIN, ctx: &mut TxContext) {
    let (treasury, metadata) = coin::create_currency(witness, 6, b"Ai", b"Aimotee", b"a coin", option::none(), ctx);
    transfer::public_freeze_object(metadata);
    transfer::public_transfer(treasury, ctx.sender())
}
  • 函数签名init函数用于初始化新的货币。它接受两个参数:

    • witness: MY_COIN:这是一个证明,表明调用者有权创建这种货币。
    • ctx: &mut TxContext:这是对当前交易上下文的可变引用,用于获取交易信息。
  • 创建货币

    let (treasury, metadata) = coin::create_currency(witness, 6, b"Ai", b"Aimotee", b"a coin", option::none(), ctx);

    这行代码调用了coin::create_currency函数来创建新的货币,并返回一个TreasuryCap(财政库)对象和货币元数据。参数说明如下:

    • witness:证明对象。
    • 6:货币的小数位数。
    • b"Ai":货币的符号。
    • b"Aimotee":货币的全名。
    • b"a coin":货币的描述。
    • option::none():可选的图标URL,这里没有提供。
    • ctx:交易上下文。
  • 冻结元数据

    transfer::public_freeze_object(metadata);

    这行代码冻结了货币元数据对象,这意味着一旦货币被创建,其元数据就不能再被修改。

  • 转移财政库对象

    transfer::public_transfer(treasury, ctx.sender());

    这行代码将财政库对象转移到发起者的地址上。财政库对象允许持有者铸造新的货币单位。

铸造新币

public fun mint(
    treasury_cap: &mut TreasuryCap&lt;MY_COIN>,
    amount: u64,
    recipient: address,
    ctx: &mut TxContext,
) {
    let coin = coin::mint(treasury_cap, amount, ctx);
    transfer::public_transfer(coin, recipient);
}
  • 函数签名mint是一个公开函数,允许持有人通过提供财政库对象来铸造指定数量的新币。它接受四个参数:

    • treasury_cap: &mut TreasuryCap&lt;MY_COIN>:对财政库对象的可变引用。
    • amount: u64:要铸造的新币数量。
    • recipient: address:接收新币的地址。
    • ctx: &mut TxContext:对当前交易上下文的可变引用。
  • 铸造新币

    let coin = coin::mint(treasury_cap, amount, ctx);

    这行代码调用了coin::mint函数来创建指定数量的新币。

  • 转移新币

    transfer::public_transfer(coin, recipient);

    这行代码将新创建的货币对象发送给指定的接收者地址。

细心的人已经发现了,这两个代码的唯一区别就是在init函数中的

transfer::public_transfer(treasury, ctx.sender()); transfer::public_share_object(treasury); <!--StartFragment-->

下面这行代码这意味着任何人都可以访问和使用财政库对象,从而允许任何人调用mint函数来铸造新币 我们将在下期对coin进行更详细的分析 <!--EndFragment-->

调用函数

我们先看看cli的原文

Call Move function

Usage: sui client call [OPTIONS] --package &lt;PACKAGE> --module &lt;MODULE> --function &lt;FUNCTION> --gas-budget &lt;GAS_BUDGET>

Options:
    --package &lt;PACKAGE>              Object ID of the package, which contains the module
    --module &lt;MODULE>                The name of the module in the package
    --function &lt;FUNCTION>            Function name in module
    --type-args &lt;TYPE_ARGS>...       Type arguments to the generic function being called. All must be specified, or the call will fail
    --args &lt;ARGS>...                 Simplified ordered args like in the function syntax ObjectIDs, Addresses must be hex strings
    --gas &lt;GAS>                      ID of the gas object for gas payment, in 20 bytes Hex string If not provided, a gas object with at least gas_budget value will be selected
    --gas-budget &lt;GAS_BUDGET>        Gas budget for this call
    --serialize-unsigned-transaction  Instead of executing the transaction, serialize the bcs bytes of the unsigned transaction data (TransactionData) using base64 encoding, and print out
                                        the string &lt;TX_BYTES>. The string can be used to execute transaction with `sui client execute-signed-tx --tx-bytes &lt;TX_BYTES>`.
    --serialize-signed-transaction  Instead of executing the transaction, serialize the bcs bytes of the signed transaction data (SenderSignedData) using base64 encoding, and print out the
                                        string &lt;SIGNED_TX_BYTES>. The string can be used to execute transaction with `sui client execute-combined-signed-tx --signed-tx-bytes &lt;SIGNED_TX_BYTES>`.
    --json                          Return command outputs in json format
  -h, --help                            Print help

<!--StartFragment-->

<!--EndFragment--> 这样我们就可以调用mint函数来给我们地址生成代币了,注意两个函数一个只能合约创建者铸币,一个是所有人都可以铸币

sui client call --function mint --module my_coin --package &lt;PACKAGE-ID> --args &lt;TREASURY-CAP-ID> &lt;COIN-AMOUNT> &lt;RECIPIENT-ADDRESS> --gas-budget &lt;GAS-AMOUNT>

在最新版的sui cli中,--gas-budget <GAS-AMOUNT>不是必要的 注意: &lt;TREASURY-CAP-ID> 可以去区块链浏览器上查看

image.png 可以把Type都复制下来看看 带TreasuryCap的是这样的0x2::coin::TreasuryCap&lt;0x818cd47a2f8cf720b65456469d82fc4ab7ba7f7774540f1d7d82ac1438c473::my_coin::MY_COIN> 再把前面的objectid复制下来就是 &lt;TREASURY-CAP-ID>

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

0 条评论

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