Move训练营-task1学习笔记

  • 四尾
  • 发布于 5天前
  • 阅读 65

Sui生态概念入门Sui是从零开始设计的区块链平台,在2023年5月份完成主网的上线,使用Move编程语言进行应用开发。而本次训练营里会教大家使用Move的基础语法帮助完成Sui上的应用开发。训练营分为8个task,每个task里都能学到Sui平台上的一部分知识点,全部知识点都学完了以后,对于小

Sui 生态概念入门

Sui是从零开始设计的区块链平台,在2023年5月份完成主网的上线,使用Move编程语言进行应用开发。而本次训练营里会教大家使用Move的基础语法帮助完成Sui上的应用开发。训练营分为8个task,每个task里都能学到Sui平台上的一部分知识点,全部知识点都学完了以后,对于小白来说,直接进行应用开发还有点难度,但是也算是踏进了Sui平台的门槛。

task1的目标是向Sui测试网上发布自己的包,并在包里面打印出自己的github id,我的github id是 coachafei

Move语言介绍

Move起源于Facebook(现在的Meta)的明星项目Diem(前身为Libra,https://github.com/diem/diem)。Move诞生自Diem, Diem最开始是想做一个跨全球的区块链支付系统,但是Diem的开发者调研了目前存在的区块链编程语言和通用的编程语言后,认为通用的语言里没有包含区块链所需的特性,而现有的区块链编程语言又太过复杂,不太适用于这样一个系统。又或者特性满足,但是性能和安全性不能满足,于是大佬们就从通用语言中选择了Rust作为基础样本。

因为Rust里的很多安全概念可以很好的满足这样一个系统的要求,例如所有权机制,可以避免资产的双花诞生。因此就借鉴Rust的特性和语法习惯,简化出一些只和资产处理有关的特性。于是面向资产编程的Move语言就诞生了。

Move语言的特点:

  • 面向资产
  • 安全
  • 适用于大规模系统
  • 借鉴Rust安全语法和特性;
  • 内核从0设计,不是基于Rust。

Move的官方仓库是https://github.com/move-language/move-sui,对于开发能力强的大佬,可以去直接看Move语言的源码。

智能合约

Move是一门编程语言的同时,还是面向资产编程的特定语言,业界称为智能合约编程语言。智能合约是一种运行在区块链上的计算机程序,类比现实生活中,智能合约就像是程序世界的法律,规定了程序必须如何执行,双方都要遵守这个约定,并且都不能违反这个合约,目前对于智能合约还只有初步的模糊印象。

智能合约的用途

智能合约编程语言可以实现:

  • 资产的定义,例如定义USD、NFT等;
  • 操作资产,对资产的信息进行增删改查;
  • 权限控制,可以限制用户对资产的访问,限制转移权限等。

Move编程语言和其他编程语言的差别

  • 每次运行程序都是一个完整的事务,要么全部成功,要么全部失败,没有中间情况。
  • 不用考虑并发资源的处理,底层会自动处理并发资源的排序;
  • 和链的结合屏蔽了数据层的概念,语言本身的操作就是数据的操作,极大地简化了需要学习的数据层知识。

上面的内容主要都是Move语言的一些基本概念介绍,下面才是 task1 完成的基本流程。

Move语言示例

下面是一个简单的move语言编程示例:

public struct Hello has key {
    id: UID,
    say: String
}

fun init(ctx: &mut TxContext) {
    let hello_move = Hello {
        id: object::new(ctx),
        say: string(b"move"),    
    };
    transfer(hello_move, sender(ctx));
}

上面就是我们用来完成task1的文件模板,在训练营仓库的完整文件路径是:

https://github.com/move-cn/letsmove/tutorial/bootcamp/01_hello/hello_move/sources/hello.move

要完成task1,我们需要先在github上把训练营仓库fork到自己的名称空间中,github的fork操作这里就不过多赘述了。fork完成后,在自己的开发电脑上执行命令:

git clone https://github.com:coachafei/letsmove.git 

把训练营仓库克隆到本地,供后面的流程使用。因为已经有大量用户向这个仓库里提交pr并且合入了,因此这个项目会比较大,最好是通过科学上网才能够顺利克隆到本地。

安装 Move 开发环境

主要有下面3个目标:

  • 安装IDE,Move开发一般使用vscode或者rustover,因为目前这两个IDE上对Sui的插件支持的比较好;
  • 安装Sui命令,不同的操作系统上使用不同的命令来安装,例如macos上使用brew install sui命令直接安装
  • 安装chrome浏览器钱包(这一步需要科学上网),基本步骤是:

    • 打开chrome浏览器,点击右上角头像旁边的3个点,然后点击extensions,在打开的菜单里点击Visit Chrome Web Store,如下所示:

      image.png

    • 在打开的Chrome 插件商店中间的搜索框里输入 Sui wallet,然后在搜索结果中点击 Slush - A Sui wallet,如下所示,这个是改版后的Sui插件钱包:

      image.png

    • 在搜索结果中找到Slush Sui walllet,并点击它,进入Slush Sui Wallet界面后,点击右边的添加到Chrome按钮安装,

    image.png

    • 安装好了以后,会自动弹开Slush钱包的配置页面,点击页面下面的More Option,然后选择Create a passphrase account

      image.png

    • 会自动打开助记词页面,助记词是为了帮助你恢复钱包账户,因此一定要像密码一样严格保管。点击copy按钮复制助记词保存下来。

      image.png

    • 确认保存好以后,点击next进入下一步,为你的钱包设置一个密码,确保密码有足够的强度,确认完毕后点击next:

      image.png

    • 为钱包设置一个不用锁定的时间,超过这个时间点击浏览器上的钱包插件图标时,会要求你输入密码,同时记得勾选下面的 Confirm Transaction,表示通过钱包进行事务交易的时候要输入密码,为了安全起见新手一定要勾选,最后点击next:

      image.png

    • 到这里Chrome浏览器上的插件钱包就安装完毕,点击钱包图标后,看到的钱包界面如下所示:

      image.png

      左上角以0x开头的就是我们的账户地址,这里需要注意区分一个概念,钱包里可以存多个账户地址,就和每个人可以有多个银行账户一样。然后可以在一个手机上管理多个银行账户。交易的时候一般用的是账户地址,而不是钱包,钱包只是为了方便账户管理而开发的一个工具。

到这里,我们的基本环境就差不多准备好了。

创建task1的 Hello Move 项目

使用vscode或者rustover打开我们克隆到本地的letmove项目,我这里用的是vscode。打开vscode的终端页面,执行下面的命令切换到mover子目录,然后复制社区提供的模板文件并重命名为github id同名用户目录,

cd mover/
cp 001 coachafei

创建存放任务代码的task1子目录,然后切换到这个目录下创建新的项目hellomove

mkdir coachafei/code/task1
cd coachafei/code/task1
sui move new hellomove

把项目根目录开始的tutorial/bootcamp/01_hello/sources/hello.move 文件里的内容复制并粘贴到我们task1里的hellomove/sources/hellomove.move文件中。

复制的时候需要注意,示例文件里的模块名称叫hello_move,我们上面命令里使用的是hellomove,因此需要把复制的文件内容里的hello_move修改为hellomove

复制完成后,把hellomove.move文件中的b"move"修改为b"coachafei",即你自己的github id。那么task1的配置就完成了,下面需要把它发布到区块链的测试网上。

发布上链

在vscode的终端窗口执行下面的内容把我们自己的项目发布上链

sui client publish

这个命令必须在项目目录下执行,后续会下载sui代码库,需要科学上网。

image.png

在这个命令执行过程中会有几个操作,分别是:

  • 是否链接到Sui全节点,选择y;
  • Sui全节点的地址,如果不输入则默认使用Sui的测试网。直接回车;
  • 选择密钥对的加密算法,输入0然后回车;
  • 会自动生成新的密钥对和密钥对的助记词,把生成的密钥对助记词保存下来。(这里相当于生成一个本地的钱包账户,助记词是这个本地账户的主机词,如果泄露了也可能会导致你后续在这个钱包里获取的资金被盗走)。

它在编译完成上链的时候可能会因为没有足够的gas费用导致上链失败,每一次区块链交易都需要支付一定的gas费用,而gas费用则来自于区块链网络上的币(Coin),如果没有足够的币就会出现下面的报错:

image.png

出现这种错误时,需要通过下面两步来处理:

  1. 通过水龙头获取测试网络上用的Sui 币
    sui client faucet

    新版本在执行这个命令后,可能会出现下面的提示:

image.png

要求你到这个地址上去请求测试网络的Sui币,打开这个地址后,如下所示:

image.png

在页面中输入你之前执行sui client publish命令时创建的本地账户地址,然后点击下面的按钮来申请测试网络Sui 币。

  1. 查看自己有没有Sui 币,执行下面的命令:
    sui client gas

    正常情况下如果获取到了测试网上的Sui 币,就会出现下面的显示:

    [warn] Client/Server api version mismatch, client api version : 1.37.1, server api version : 1.44.2
    ╭────────────────────────────────────────────────────────────────────┬────────────────────┬──────────────────╮
    │ gasCoinId                                                          │ mistBalance (MIST) │ suiBalance (SUI) │
    ├────────────────────────────────────────────────────────────────────┼────────────────────┼──────────────────┤
    │ 0xddc8864c968c04067b00692ec9fca7e71af321b3aea85b85b2b21fd9a1645416 │ 982111440          │ 0.98             │
    ╰────────────────────────────────────────────────────────────────────┴────────────────────┴──────────────────╯

    对于测试网络,通过这两个命令确认拿到了测试Sui 币后,再执行publish子命令才能正常发布。发布成功后,会出现大量输出的内容,在输出内容中找到package_id,类似下面这样:

    package id: 0xcbb694013c7c846a30899d7882b770b193d461f14266239bce04f1d4172cce3d

区块链网络和币的一些概念

Sui目前有4套网络,分别是:

  • MainNet,主网,个人理解实际有价值的网络,Sui币资产主要就在这个网络上;
  • TestNet,测试网络,测试合约代码使用,提供了水龙头供你获取测试币;
  • DevNet,开发网络,给用户测试部署合约代码使用,提供了水龙头供你获取测试币;
  • Local,本地网络,自己部署在本地电脑上,供本地开发代码使用。

除了本地部署的local网络你可以自己获取测试币以后,devnet和testnet都需要通过水龙头来获取测试币,我们上面发布hellomove包时获取的就是测试网络的Sui币。而主网上币则是可以换到钱的币,因此需要购买或者通过参加活动由其他拥有币的开发者转给你。

可以通过命令 sui client envs 查看本地的网络配置,示例输出如下:

╭─────────┬─────────────────────────────────────┬────────╮
│ alias   │ url                                 │ active │
├─────────┼─────────────────────────────────────┼────────┤
│ testnet │ https://fullnode.testnet.sui.io:443 │        │
│ mainnet │ https://fullnode.mainnet.sui.io:443 │        │
│ devnet  │ https://fullnode.devnet.sui.io:443  │        │
│ local   │ http://127.0.0.1:9000               │ *      │
╰─────────┴─────────────────────────────────────┴────────╯

网络后面的*号表示是正在使用的网络。可以使用命令 sui client switch --env netname命令切换到不同的网络,例如切换到主网就是 sui client switch --env mainnet

事务信息解析

执行 sui client publish 命令后,就相当于执行了一次事务,每次执行事务都需要支付一次交易的gas费用。发布事务时会输出大量的数据信息。信息解析如下。

事务摘要

事务摘要是本次事务的唯一性标识,可以在链上通过这个唯一性标识来查询事务的详细信息。

Transaction Digest: VTZGbGrd2MVuP1sqVRgCYAnhwrw7VkW9DD45Yex9V4N

事务数据

事务数据里包含本次事务的详细信息,包括

  • Gas费用的明细,例如谁来支付(sender,gas owner),支付的数量(gas budget),支付的方式等。
  • 事务类型,
  • 签名信息

等等,如下所示:

╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Data                                                                                             │
├──────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Sender: 0xd95ac7e46d610afd67d3862ca3db7ef8afc7c753c7b963e2a385bf5e2d638635                                   │
│ Gas Owner: 0xd95ac7e46d610afd67d3862ca3db7ef8afc7c753c7b963e2a385bf5e2d638635                                │
│ Gas Budget: 10253600 MIST                                                                                    │
│ Gas Price: 1000 MIST                                                                                         │
│ Gas Payment:                                                                                                 │
│  ┌──                                                                                                         │
│  │ ID: 0x32ac5c34019e37774fce9977978c033211f9eca1b86494aac051403f87255fa5                                    │
│  │ Version: 349174470                                                                                        │
│  │ Digest: A94DtyGCtuVBWrirWikxgj6ayY1JdzfNB95p98ptBbr7                                                      │
│  └──                                                                                                         │
│                                                                                                              │
│ Transaction Kind: Programmable                                                                               │
│ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │
│ │ Input Objects                                                                                            │ │
│ ├──────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │
│ │ 0   Pure Arg: Type: address, Value: "0xd95ac7e46d610afd67d3862ca3db7ef8afc7c753c7b963e2a385bf5e2d638635" │ │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│ ╭─────────────────────────────────────────────────────────────────────────╮                                  │
│ │ Commands                                                                │                                  │
│ ├─────────────────────────────────────────────────────────────────────────┤                                  │
│ │ 0  Publish:                                                             │                                  │
│ │  ┌                                                                      │                                  │
│ │  │ Dependencies:                                                        │                                  │
│ │  │   0x0000000000000000000000000000000000000000000000000000000000000001 │                                  │
│ │  │   0x0000000000000000000000000000000000000000000000000000000000000002 │                                  │
│ │  └                                                                      │                                  │
│ │                                                                         │                                  │
│ │ 1  TransferObjects:                                                     │                                  │
│ │  ┌                                                                      │                                  │
│ │  │ Arguments:                                                           │                                  │
│ │  │   Result 0                                                           │                                  │
│ │  │ Address: Input  0                                                    │                                  │
│ │  └                                                                      │                                  │
│ ╰─────────────────────────────────────────────────────────────────────────╯                                  │
│                                                                                                              │
│ Signatures:                                                                                                  │
│    grPQYvgfutC5zJTUvtgqixVtTM7Uklqnva6UsJD8XT/dB5LhzugPRrhiAeEcVo/jb8WJnPpebG/r5czMOJVGBA==                  │
│                                                                                                              │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

交易影响

这部分内容包含了交易的状态,交易对网络状态所做的更改,以及交易所涉及的对象。

╭───────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Transaction Effects                                                                               │
├───────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Digest: VTZGbGrd2MVuP1sqVRgCYAnhwrw7VkW9DD45Yex9V4N                                               │
│ Status: Success                                                                                   │
│ Executed Epoch: 679                                                                               │
│                                                                                                   │
│ Created Objects:                                                                                  │
│  ┌──                                                                                              │
│  │ ID: 0x50d2ae11dba3be2e4fa0088530a6c6f3637183e0818f7b0b423453070e16b8c3                         │
│  │ Owner: Account Address ( 0xd95ac7e46d610afd67d3862ca3db7ef8afc7c753c7b963e2a385bf5e2d638635 )  │
│  │ Version: 349174471                                                                             │
│  │ Digest: 83xSwgve3E6himz8K6qsqDD7PMoxDFuqPoyiHhuPxdA                                            │
│  └──                                                                                              │
│  ┌──                                                                                              │
│  │ ID: 0x9f02ee0c66dbd5dcdf7a7f4f89499a4203bf49a2230b280e394b5bf54795617f                         │
│  │ Owner: Immutable                                                                               │
│  │ Version: 1                                                                                     │
│  │ Digest: Eqr4zwM8PtPVmKGuRzbPSR52D5zdqGnBPueoEtRqYbeS                                           │
│  └──                                                                                              │
│ Mutated Objects:                                                                                  │
│  ┌──                                                                                              │
│  │ ID: 0x32ac5c34019e37774fce9977978c033211f9eca1b86494aac051403f87255fa5                         │
│  │ Owner: Account Address ( 0xd95ac7e46d610afd67d3862ca3db7ef8afc7c753c7b963e2a385bf5e2d638635 )  │
│  │ Version: 349174471                                                                             │
│  │ Digest: CKvkXMoxmnviZRV2579sCdMh6Bt8vjNA7bv8gedsPm1Y                                           │
│  └──                                                                                              │
│ Gas Object:                                                                                       │
│  ┌──                                                                                              │
│  │ ID: 0x32ac5c34019e37774fce9977978c033211f9eca1b86494aac051403f87255fa5                         │
│  │ Owner: Account Address ( 0xd95ac7e46d610afd67d3862ca3db7ef8afc7c753c7b963e2a385bf5e2d638635 )  │
│  │ Version: 349174471                                                                             │
│  │ Digest: CKvkXMoxmnviZRV2579sCdMh6Bt8vjNA7bv8gedsPm1Y                                           │
│  └──                                                                                              │
│ Gas Cost Summary:                                                                                 │
│    Storage Cost: 8253600 MIST                                                                     │
│    Computation Cost: 1000000 MIST                                                                 │
│    Storage Rebate: 978120 MIST                                                                    │
│    Non-refundable Storage Fee: 9880 MIST                                                          │
│                                                                                                   │
│ Transaction Dependencies:                                                                         │
│    5MBY2WgzpjRKma7TGK46GoszzwssZKaXZgW5DBe3PY5z                                                   │
│    5XvhL1EeEbZcMfKaGHzkiVvbkVk1DM7Adp4cMbku4gQ4                                                   │
│    J4Uru4JqPRC4PpFmVDfMBKqvcaiNdfkpHewqGdnfJMPZ                                                   │
╰───────────────────────────────────────────────────────────────────────────────────────────────────╯

事件(Events)

如果触发了任何事件,会在这个部分被看到,但是我们的示例里没有使用任何包,所以这里看不到相关的内容,如下所示:

╭─────────────────────────────╮
│ No transaction block events │
╰─────────────────────────────╯

后面会学习怎么主动触发事件。

对象变更

这部分记录了本次交易里变更的对象,在本次交易里

╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Object Changes                                                                                   │
├──────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects:                                                                                 │
│  ┌──                                                                                             │
│  │ ObjectID: 0x50d2ae11dba3be2e4fa0088530a6c6f3637183e0818f7b0b423453070e16b8c3                  │
│  │ Sender: 0xd95ac7e46d610afd67d3862ca3db7ef8afc7c753c7b963e2a385bf5e2d638635                    │
│  │ Owner: Account Address ( 0xd95ac7e46d610afd67d3862ca3db7ef8afc7c753c7b963e2a385bf5e2d638635 ) │
│  │ ObjectType: 0x2::package::UpgradeCap                                                          │
│  │ Version: 349174471                                                                            │
│  │ Digest: 83xSwgve3E6himz8K6qsqDD7PMoxDFuqPoyiHhuPxdA                                           │
│  └──                                                                                             │
│ Mutated Objects:                                                                                 │
│  ┌──                                                                                             │
│  │ ObjectID: 0x32ac5c34019e37774fce9977978c033211f9eca1b86494aac051403f87255fa5                  │
│  │ Sender: 0xd95ac7e46d610afd67d3862ca3db7ef8afc7c753c7b963e2a385bf5e2d638635                    │
│  │ Owner: Account Address ( 0xd95ac7e46d610afd67d3862ca3db7ef8afc7c753c7b963e2a385bf5e2d638635 ) │
│  │ ObjectType: 0x2::coin::Coin<0x2::sui::SUI>                                                    │
│  │ Version: 349174471                                                                            │
│  │ Digest: CKvkXMoxmnviZRV2579sCdMh6Bt8vjNA7bv8gedsPm1Y                                          │
│  └──                                                                                             │
│ Published Objects:                                                                               │
│  ┌──                                                                                             │
│  │ PackageID: 0x9f02ee0c66dbd5dcdf7a7f4f89499a4203bf49a2230b280e394b5bf54795617f                 │
│  │ Version: 1                                                                                    │
│  │ Digest: Eqr4zwM8PtPVmKGuRzbPSR52D5zdqGnBPueoEtRqYbeS                                          │
│  │ Modules: todo_list                                                                            │
│  └──                                                                                             │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯

余额变更

这部分记录了账号上的SUI代币变化情况,如下所示:

╭───────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Balance Changes                                                                                   │
├───────────────────────────────────────────────────────────────────────────────────────────────────┤
│  ┌──                                                                                              │
│  │ Owner: Account Address ( 0xd95ac7e46d610afd67d3862ca3db7ef8afc7c753c7b963e2a385bf5e2d638635 )  │
│  │ CoinType: 0x2::sui::SUI                                                                        │
│  │ Amount: -8275480                                                                               │
│  └──                                                                                              │
╰───────────────────────────────────────────────────────────────────────────────────────────────────╯

例如本次交易话费了8275480MISTs,约等于0.083 SUI币。

区块链浏览器

除了命令行里的输出外,我们还可以通过区块链浏览器到Sui的区块链网络上去查看我们发布上链的内容详细信息。常用的区块链浏览器有:

打开以后就可以看到Sui区块链网络,默认打开的是Sui区块链的主网,如下所示。

image.png

这个时候点击右上角的Mainnet图标,就可以看到下面的内容:

image.png

在这里可以切换主网Mainet、测试网Testnet和开发网Devnet,我们刚才测试上链的是测试网,因此要点击第三个Testnet进行网络切换。

在切换完成后,在页面中间的搜索框中输入发布成功时记录下来的那一串哈希值Package id,就能搜索到你上链的内容,如下所示:

image.png

要在页面上能看到输出你的github id信息,例如图中的coachafei,表示我第一个任务就完成了。然后需要记录3个信息:

  • Chrome钱包截图
  • package id
  • package id在suiscan区块链浏览器上的截图

记录下来以后,把这3个内容填写到个人目录下的README.md文件中,截图保存在个人目录下的images子目录中。保存好以后执行命令:

git add . 
git commit -m '完成task1'
git push

把第一次任务的内容推送到自己的仓库中,然后到github页面上提交第一次任务的PR,等待小管家的合入。合入成功后,小管家就会向你的钱包账户里转入本次任务的奖励。

和链上对象进行交互

在上面的示例中,我们向链上发布了一个hello_move包。下面是另一个演示向链上发布包todoList的示例,和链上的对象进行交互,主要流程包括: 1.创建todoList项目并发布; 2.通过CLI命令调用发布的对象并构建交易 3.把对象传递给函数 4.链式调用

1. 创建todoList项目并发布

首先执行命令

sui move new todo_list

创建todo_list包,然后打开包里的sources/todo_list.move文件,内容如下:

module todo_list::todo_list {
    use std::string::String;

    // List of todos, Can be managed by the owner and shared with others
    public struct TodoList has key, store {
        id: UID,
        items: vector<String>
    }

    // Create a new todo list.
    public fun new(ctx: &mut TxContext): TodoList {
        let list = TodoList {
            id: object::new(ctx),
            items: vector[],
        };
        (list)
    }

    // Add a new todo item to the list.
    public fun add(list: &mut TodoList, item: String) {
        list.items.push_back(item)
    }

    // Remove a todo item from the list.
    public fun remove(list: &mut TodoList, index: u64): String {
        list.items.remove(index)
    }

    // Delete the list and the capability to manage it.
    public fun delete(list: TodoList) {
        let TodoList {id, items: _} = list;
        id.delete();
    }

    // Get the number of items in the list.
    public fun length(list: &TodoList): u64 {
        list.items.length()
    }
}

在模块todo_list里定义了TodoList对象,以及和它交互的5个方法。方法的作用分别是:

  • 创建todoList对象
  • 添加todo项到列表中;
  • 从列表中移除todo项
  • 删除列表
  • 获取列表的长度

然后执行命令

sui client publish

把这个todo_list包发布到测试网上,发布完成后,在事务数据中能够找到创建的todo_list包的PackageId,如下所示:

│ Published Objects:                                                                               │
│  ┌──                                                                                             │
│  │ PackageID: 0x9f02ee0c66dbd5dcdf7a7f4f89499a4203bf49a2230b280e394b5bf54795617f                 │
│  │ Version: 1                                                                                    │
│  │ Digest: Eqr4zwM8PtPVmKGuRzbPSR52D5zdqGnBPueoEtRqYbeS                                          │
│  │ Modules: todo_list                                                                            │
│  └──                                                                                             │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯

我们记下这个PackageID的值。

2. 通过CLI命令构建交易

为了演示和todo_list包的交互,会使用CLI命令来构建一个交易,调用包里的new方法在链上创建一个TodoList列表对象,并向列表里添加一个项目。

准备变量

首先需要使用export命令把两个值保存在环境变量里:

export PACKAGE_ID=0x9f02ee0c66dbd5dcdf7a7f4f89499a4203bf49a2230b280e394b5bf54795617f
export MY_ADDRESS=$(sui client active-address)

第一个变量是todo_list包在链上的对象地址,第二个变量是本地账户地址。

使用CLI构建交易信息

构建交易会使用sui clint ptb命令,详细的交易命令如下所示:

sui client ptb \
--gas-budget 100000000 \
--assign sender @$MY_ADDRESS \
--move-call $PACKAGE_ID::todo_list::new \
--assign list \
--transfer-objects "[list]" sender

参数说明:

  • --gas-budget,交易费用预算;
  • --assign sender $MY_ADDRESS,指定发送者。
  • --move-call $PACKAGE_ID::tod_list::new,表示是一个调用操作,调用链上$PACKGE_ID对象里的todo_list模块中的new方法
  • --assign list,表示把这个方法的返回结果分配给list变量。
  • --transfer-objects "[list]" sender,表示把[list]对象所有权转移给sender对象,即本地账户。

这个命令执行完成后,会看到类似之前sui client publish命令的输出。我们需要关注的是信息里面的Created Objects内容,即我们新建的对象,它包含了新建的TodoList的对象ID、类型和版本信息,如下所示:

├─────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Created Objects:                                                                                        │
│  ┌──                                                                                                    │
│  │ ObjectID: 0x433b2981e439c1e3eaef42a12736b72322ef9e3bc6996ff122526660d0743ca8                         │
│  │ Sender: 0xd95ac7e46d610afd67d3862ca3db7ef8afc7c753c7b963e2a385bf5e2d638635                           │
│  │ Owner: Account Address ( 0xd95ac7e46d610afd67d3862ca3db7ef8afc7c753c7b963e2a385bf5e2d638635 )        │
│  │ ObjectType: 0x9f02ee0c66dbd5dcdf7a7f4f89499a4203bf49a2230b280e394b5bf54795617f::todo_list::TodoList  │
│  │ Version: 349174472                                                                                   │
│  │ Digest: HgrsygxErokz9JEDJAXT7gaXvRUSHjYWnhJNnvzgQ2gt   
│  └──                                                                                                    │                                              │

从输出信息中可以看到新建的对象ID是:0x433b2981e439c1e3eaef42a12736b72322ef9e3bc6996ff122526660d0743ca8,发送者是我们本地账户的地址。所有者也是我们本地账户地址。还可以通过命令:

sui client objects

来确认,在输出信息中能找到类似如下所示的内容:

│ ╭────────────┬──────────────────────────────────────────────────────────────────────╮ │
│ │ objectId   │  0x433b2981e439c1e3eaef42a12736b72322ef9e3bc6996ff122526660d0743ca8  │ │
│ │ version    │  349174472                                                           │ │
│ │ digest     │  9/EKaBhcvkj8qbE+uHtAZATouVfKmfrwvWD5sD2haJU=                        │ │
│ │ objectType │  0x9f02..617f::todo_list::TodoList                                   │ │
│ ╰────────────┴──────────────────────────────────────────────────────────────────────╯ │

3. 传递对象给函数

上一步创建了TodoList对象列表,我们作为它的所有者,也可以和它进行交互。可以在它上面调用todo_list模块里的函数并获取返回结果。首先我们向它里面添加一个项目。

定义变量

定义一个环境变量关联到创建好的列表对象:

export LIST_ID=0x433b2981e439c1e3eaef42a12736b72322ef9e3bc6996ff122526660d0743ca8

构建交易

交易的命令是:

sui client ptb \
--gas-budget 10000000 \
--move-call $PACKAGE_ID::todo_list::add @$LIST_ID "'Finish the Hello, Sui chapter'"

上面的命令中调用了todo_list模块里的add函数,并向他传递了两个参数,分别是 @LIST_ID和后面的项目,项目是一个字符串。

这个命令调用只对现有对象进行操作,并没有生成新的对象,因此在实际的输出结果中不会有Created Objects信息,只有Mutable Objects信息。

通过命令 sui client object $LIST_ID,可以看到变化后的TodoList对象内容如下:

╭───────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ objectId      │  0x433b2981e439c1e3eaef42a12736b72322ef9e3bc6996ff122526660d0743ca8                                               │
│ version       │  349174473                                                                                                        │
│ digest        │  6AQ8i83Sx7QKD6Xkq1QjQfymCEnC3rZvpXbyQczLZ97z                                                                     │
│ objType       │  0x9f02ee0c66dbd5dcdf7a7f4f89499a4203bf49a2230b280e394b5bf54795617f::todo_list::TodoList                          │
│ owner         │ ╭──────────────┬──────────────────────────────────────────────────────────────────────╮                           │
│               │ │ AddressOwner │  0xd95ac7e46d610afd67d3862ca3db7ef8afc7c753c7b963e2a385bf5e2d638635  │                           │
│               │ ╰──────────────┴──────────────────────────────────────────────────────────────────────╯                           │
│ prevTx        │  HSZyJxA1oLo9fFzer8qouJp8iQmAntjooNTrSHQ81bZ3                                                                     │
│ storageRebate │  1558000                                                                                                          │
│ content       │ ╭───────────────────┬───────────────────────────────────────────────────────────────────────────────────────────╮ │
│               │ │ dataType          │  moveObject                                                                               │ │
│               │ │ type              │  0x9f02ee0c66dbd5dcdf7a7f4f89499a4203bf49a2230b280e394b5bf54795617f::todo_list::TodoList  │ │
│               │ │ hasPublicTransfer │  true                                                                                     │ │
│               │ │ fields            │ ╭───────┬───────────────────────────────────────────────────────────────────────────────╮ │ │
│               │ │                   │ │ id    │ ╭────┬──────────────────────────────────────────────────────────────────────╮ │ │ │
│               │ │                   │ │       │ │ id │  0x433b2981e439c1e3eaef42a12736b72322ef9e3bc6996ff122526660d0743ca8  │ │ │ │
│               │ │                   │ │       │ ╰────┴──────────────────────────────────────────────────────────────────────╯ │ │ │
│               │ │                   │ │ items │ ╭─────────────────────────────────╮                                           │ │ │
│               │ │                   │ │       │ │  Finish the Hello, Sui chapter  │                                           │ │ │
│               │ │                   │ │       │ ╰─────────────────────────────────╯                                           │ │ │
│               │ │                   │ ╰───────┴───────────────────────────────────────────────────────────────────────────────╯ │ │
│               │ ╰───────────────────┴───────────────────────────────────────────────────────────────────────────────────────────╯ │
╰───────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

从输出中可以看到,这个TodoList对象里有我们新添加进去的字符串Finish the Hello, Sui chapter

4. 链式调用

链式调用指的是,我们在ptb子命令构建的单个交易里可以同时跟上多次函数调用,对同一个对象进行多次操作。例如下面的示例交易命令,对上面的列表对象添加3个项目并删除1个项目:

sui client ptb \
--gas-budget 100000000 \
--move-call $PACKAGE_ID::todo_list::add @$LIST_ID "'Finish Concepts chapter'" \
--move-call $PACKAGE_ID::todo_list::add @$LIST_ID "'Read the Move Basics chapter'" \
--move-call $PACKAGE_ID::todo_list::add @$LIST_ID "'Learn about Object Model'" \
--move-call $PACKAGE_ID::todo_list::remove @$LIST_ID 0

命令执行成功后,再使用命令sui client object $LIST_ID,看到的列表对象内容如下:

╭───────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ objectId      │  0x433b2981e439c1e3eaef42a12736b72322ef9e3bc6996ff122526660d0743ca8                                               │
│ version       │  349174474                                                                                                        │
│ digest        │  26BYuhizgqWKFWaaAZQ3w1CCzNPLK36U9Mvgf7AirNJU                                                                     │
│ objType       │  0x9f02ee0c66dbd5dcdf7a7f4f89499a4203bf49a2230b280e394b5bf54795617f::todo_list::TodoList                          │
│ owner         │ ╭──────────────┬──────────────────────────────────────────────────────────────────────╮                           │
│               │ │ AddressOwner │  0xd95ac7e46d610afd67d3862ca3db7ef8afc7c753c7b963e2a385bf5e2d638635  │                           │
│               │ ╰──────────────┴──────────────────────────────────────────────────────────────────────╯                           │
│ prevTx        │  EhQ44T89qEUz7DvNuavsk3vefgvC3o2zJ9TtYvkmGjCb                                                                     │
│ storageRebate │  1922800                                                                                                          │
│ content       │ ╭───────────────────┬───────────────────────────────────────────────────────────────────────────────────────────╮ │
│               │ │ dataType          │  moveObject                                                                               │ │
│               │ │ type              │  0x9f02ee0c66dbd5dcdf7a7f4f89499a4203bf49a2230b280e394b5bf54795617f::todo_list::TodoList  │ │
│               │ │ hasPublicTransfer │  true                                                                                     │ │
│               │ │ fields            │ ╭───────┬───────────────────────────────────────────────────────────────────────────────╮ │ │
│               │ │                   │ │ id    │ ╭────┬──────────────────────────────────────────────────────────────────────╮ │ │ │
│               │ │                   │ │       │ │ id │  0x433b2981e439c1e3eaef42a12736b72322ef9e3bc6996ff122526660d0743ca8  │ │ │ │
│               │ │                   │ │       │ ╰────┴──────────────────────────────────────────────────────────────────────╯ │ │ │
│               │ │                   │ │ items │ ╭────────────────────────────────╮                                            │ │ │
│               │ │                   │ │       │ │  Finish Concepts chapter       │                                            │ │ │
│               │ │                   │ │       │ │  Read the Move Basics chapter  │                                            │ │ │
│               │ │                   │ │       │ │  Learn about Object Model      │                                            │ │ │
│               │ │                   │ │       │ ╰────────────────────────────────╯                                            │ │ │
│               │ │                   │ ╰───────┴───────────────────────────────────────────────────────────────────────────────╯ │ │
│               │ ╰───────────────────┴───────────────────────────────────────────────────────────────────────────────────────────╯ │
╰───────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

从结果中可以看到,新增了3个新的字符串,并且上一步添加的字符串通过索引0把它删除了,因此TodoList对象中还剩下新增的3个字符串。

总结

task1里涉及到的知识点包括:

  • 开发环境配置;
  • 钱包的创建,钱包和账户的区别;
  • Sui区块链网络的介绍
  • 发布上链的基本流程;
  • 查看本地账户拥有的对象;
  • ptb子命令调用链上对象;
  • 原创
  • 学分: 2
  • 分类: Sui
  • 标签:
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
四尾
四尾
0x4e7B...a876
web3小白,刚进入web3不久,希望在这里和大家一同成长。