下载 Move Cli
Move 运行需要 Move CLI 客户端,就像运行 Java 代码需要下载配置 JDK。
// 下载 move cli 文件$ cargo install --git https://github.com/diem/move move-cli --branch main// 在环境变量中配置PATH,如果安装了oh-my-zsh,在~/.zshrc中配置$ vim ~/.bash_profile// 添加move,保存并退出MOVE_HOME=/Users/{...}/.cargo/binexport PATH={...}:${MOVE_HOME}// 使配置文件生效$ source ~/.bash_profile
初始化Move项目
// 初始化$ move package new toycoin// 初始化后的目录结构toycoin-- sources-- Move.toml// 在sources下创建 module 和 scripts 目录$ cd toycoin$ mkdir -p sources/modules$ mkdir -p sources/scripts
创建代币
1.编写模块文件
首先创建一个 module 文件,并把她发布在 0x1 address上,(Move 的标准库在是 Std address 上 ),在source/modules/Coin.move文件定义。
address 0x1 {module Coin {// 默认情况下,move中的结构体是不能被复制和直接销毁的// has drop: 表示Coin结构体可以被直接销毁struct Coin has drop {value: u64,}public fun mint(value: u64): Coin {Coin { value }}}}
然后使用 Move Cli 发布 Modules。
// -v 打印发布信息$ move sandbox publish -vFound 1 modulesPublishing a new module 00000000000000000000000000000001::Coin (wrote 119 bytes)
发布完成后,会自动生成 build 和 storage 目录,先跳过。
2.运行可执行文件
首先创建一个 scripts 文件,在sources/scripts/Test.move文件定义。
script {use 0x1::Coin;fun main() {let _coin = Coin::mint(100);}}
然后使用 Move Cli 执行。
$ move sandbox run sources/scripts/Test.move
3.注意
address 0x1 {module Coin {struct Coin has drop {value: u64,}public fun mint(value: u64): Coin {Coin { value }}}}
以上代码可以正常运行,但是这样实现的 Coin 不是很有用。如果 Coin 赋予了一个值,必须要确保她被使用掉了,例如:传递到其他函数体。否则,此 Coin 可能会丢失。
Move中,一个 resource 的值 (如Coin或者Asset),不能复制只能传递出去。
销毁代币
1.修改模块文件
只有 module 里面可以定义对 resource (如Coin或者Asset) 进行销毁。在source/modules/Coin.move添加以下定义。
public fun value(coin: &Coin): u64 {coin.value}public fun burn(coin: Coin): u64 {let Coin { value } = coin;value}
以上代码中,value方法参数是传入了一个Coin的引用,这里只是读一下Coin的值,并不是传递到value函数体中了。而burn方法参数是将Coin结构体传递进来,在调用burn方法的时候,Coin结构体就传入了此方法作用域中。
然后使用 Move Cli 重新发布 Modules。
$ move sandbox publish -vUpdating an existing module 00000000000000000000000000000001::Coin (wrote 170 bytes)Wrote 170 bytes of module ID's and code
2.编写可执行文件
再创建一个 scripts 文件,在sources/scripts/Burn.move文件定义。
script {// move 原生依赖提供的打印方法use Std::Debug;use 0x1::Coin;fun main() {let coin = Coin::mint(100);Debug::print(&Coin::value(&coin));Coin::burn(coin);}}
因为上面使用了move的原生依赖,所以需要在Move.toml中添加依赖,最终为:
[package]name = "toycoin"version = "0.0.0"[addresses]Std = "0x1" # Specify and assign 0x1 to the named address "Std"[dependencies]MoveNursery = { git = "https://github.com/diem/move.git", subdir = "language/move-stdlib/nursery", rev = "7e593a2" }
然后使用 Move Cli 执行。
$ move sandbox run sources/scripts/Burn.move[debug] 100
3.补充
通过”&”来传递 Coin 结构体的引用,这里只是读取了一下值;当没有”&”的 Coin 传递到 burn函数后,Coin 结构体就不在我们 script 的作用域中了,因为 move 要确保一个 resource (Coin或asset) 不会意外走丢。
