step0,先决条件

声明:move语言更新快,本文具有时效性,一切以官方文档为准

0.1操作系统

支持的操作系统:

macOS

windows

linux

本文以ubuntu linux为例

0.0网络环境

科学上网

特别强调:如果你没有软路由等网络层代理工具,而是用软件代理,你的终端是不走软件的代理的(大多数情况)

因此你要通过终端代理工具+软件代理工具的方式实现终端代理

介绍一个方案:**ProxyChains** + cfw

示例:假设你现在已经安装好了上述两个工具,并配置且运行了cfw

1
sudo nano /etc/proxychains.conf

在打开的文件里面最后添加一行(7890 是cfw的默认代理端口),注释掉socks

1
http 127.0.0.1 7890

然后ctrl+o保存,ctrl+x关闭

配置好以后,需要用到终端代理的命令在前面加一个proxychain即可

0.2依赖(linux)

linux平台下需要的依赖

0.2.1 系统软件

Linux 操作系统所需的先决条件包括:

cURL

Rust and Cargo

Git CLI Git

CMake

GCC

libssl-dev libssl

libclang-dev

libpq-dev libpq

build-essential

安装本节中列出的先决条件。

使用以下命令更新 apt-get

1
sudo apt-get update

运行以下命令来一次安装它们

1
sudo apt-get install curl git-all cmake gcc libssl-dev pkg-config libclang-dev libpq-dev build-essential

0.2.2 安装 cargo 和 rust

1
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

如果不成功,请确保终端已经实现科学上网

Sui 使用最新版本的 Cargo 来构建和管理依赖项。有关更多信息,请参阅 Rust 网站上的Cargo installation页面。

使用以下命令将 Rust 更新为 rustup

1
rustup update stable

step1,Install Sui move 环境

官网提供了

我建议使用“从二进制文件安装”

访问 https://github.com/MystenLabs/sui。

在右侧窗格中,找到“Releases”部分。

Sui releases in GitHub

单击标记为“Latest ”的版本以打开该版本的页面。

在版本的“Assets”部分中,选择与您的操作系统对应的 .tgz 压缩文件(以ubuntu22.04为例,如果你是x86架构,选择[sui-mainnet-v1.22.0-ubuntu-x86_64.tgz](https://github.com/MystenLabs/sui/releases/download/mainnet-v1.22.0/sui-mainnet-v1.22.0-ubuntu-x86_64.tgz

1.1用命令行下载(以v1.22.0为例子,wget后面的链接以最新版本为准):

1
2
3
cd ~

wget https://github.com/MystenLabs/sui/releases/download/mainnet-v1.22.0/sui-mainnet-v1.22.0-ubuntu-x8长度6_64.tgz

1.2,解压 .tgz 文件

1
2
3
tar -zxvf sui-mainnet-v1.22.0-ubuntu-x86_64.tgz
cd target
cd release

二进制文件说明

sui-faucet- - :本地水龙头在本地网络上铸造硬币。
sui-indexer- - :本地 Sui 网络的索引器。
sui- - :主要 Sui 二进制文件。
sui-node- - :运行本地节点。
sui-test-validator- - :在本地网络上运行测试验证器以进行开发。
sui-tool- - :为 Sui 提供实用程序。

解压后出现两个文件夹:external-crates/target

move-analyzer-ubuntu-x86_64 文件在 /external-crates/move/target/release/ 里面

其他主要二进制文件在 target/releases/ 里面

1.3,直接使用二进制文件运行sui

1
./sui-ubuntu-x86_64 -V

这将显示sui的版本

1
pwd

显示当前所在目录,这在配置环境变量的环节会用到

1.4,配置环境变量

如果不想每次都在指定目录输入./sui-ubuntu-x86_64而是直接在任意文件夹用sui,可以配置一下环境变量

和传统的复杂配置思路不同,我们可以直接把二进制文件放到/usr/local/bin/,因为/usr/local/bin/是默认的环境变量值,里面的二进制文件自然也默认配置为了环境变量中的文件

(例子中的文件夹:/home/ubuntu/target/release/)替换成刚才pwd命令显示的目录,sui-ubuntu-x86_64以你下载的实际文件版本和架构为准,../是上一级目录

1
2
3
4
5
6
cd /home/ubuntu/target/
sudo mv /home/ubuntu/target/release/ /usr/local/bin/
cd /usr/local/bin/release
sudo mv * ../
cd ../
ls

重命名二进制文件,并把sui-ubuntu-x86_64重命名为sui

1
2
cd /usr/local/bin
sudo mv sui-ubuntu-x86_64 sui

授予运行权限()

1
sudo chmod +x /usr/local/bin/*

查看

1
ls

你应该能看到

image-20240411175458245

验证sui安装

1
2
cd ~
sui

你应该能看到

image-20240411175836938

证明安装成功

strp2,连接到sui网络

官方文档

Sui 拥有可用的主网、开发网和测试网网络。您可以使用测试网络(Devnet 或 Testnet)之一来试验在该网络上运行的 Sui 版本。您还可以建立本地 Sui 网络以进行本地开发。

Sui Testnet 和 Devnet 网络由 Mysten Labs 运营的四个验证器节点组成。客户端使用 JSON-RPC 通过此端点 https://fullnode.<SUI-NETWORK-VERSION>.sui.io:443 发送事务和读取请求。

例如:testnet的地址:https://fullnode.testnet.sui.io:443

2.1,配置Sui客户端

要将 Sui 客户端连接到网络,请运行以下命令:

1
sui client

第一次启动没有 client.yaml 文件的 Sui 客户端时,控制台会显示以下消息:

1
Config file ["<PATH-TO-FILE>/client.yaml"] doesn't exist, do you want to connect to a Sui Full node server [y/N]?

按 y,然后按 Enter。然后该进程请求 RPC 服务器 URL:

1
Sui Full node server URL (Defaults to Sui Devnet if not specified) :

建议:作为开发人员,常用testnet,因此这里填上https://fullnode.testnet.sui.io:443

按 Enter 键连接到 Sui Devnet。要使用自定义 RPC 服务器、Sui Testnet 或 Sui Mainnet,请输入正确的 RPC 端点的 URL,然后按 Enter。

如果您输入 URL,该过程会提示输入环境别名:

1
Environment alias for [<URL-ENTERED>] :

输入别名并按 Enter 键。(例如,如果你上面填写了testnet的url则可以写一个:testnet)

1
Select key scheme to generate keypair (0 for ed25519, 1 for secp256k1, 2 for secp256r1):

按 0、1 或 2 选择按键方案,然后按 Enter。(不知道怎么选可以选0)

Sui 返回一条类似于以下内容的消息(取决于您选择的密钥方案),其中包括地址和该地址的 12 字恢复短语:

1
2
Generated new keypair for address with scheme "ed25519" [0xb9c83a8b40d3263c9ba40d551514fbac1f8c12e98a4005a0dac072d3549c2442]
Secret Recovery Phrase : [cap wheat many line human lazy few solid bored proud speed grocery]

2.2,连接到自定义 RPC 端点(可选)

您可以使用 sui client envs 命令查看定义的环境,并使用 sui client switch 命令在它们之间切换。

如果您之前安装了连接到 Sui 网络的 Sui 客户端,或者创建了本地网络,则可以修改现有的 client.yaml 文件来更改配置的 RPC 端点。与环境相关的 sui client 命令读取和写入 client.yaml 文件。

要检查当前可用的环境别名,请运行以下命令:

1
sui client envs

该命令输出可用的环境别名,其中 (active) 表示当前活动的网络。

1
2
localnet => http://0.0.0.0:9000 (active)
devnet => https://fullnode.devnet.sui.io:443

要为自定义 RPC 端点添加新别名,请运行以下命令。将 < > 中的值替换为您的安装值:

1
sui client new-env --alias <ALIAS> --rpc <RPC-SERVER-URL>

例如:sui client new-env --alias testnet --rpc https://fullnode.testnet.sui.io:443

要切换活动网络,请运行以下命令:

1
sui client switch --env <ALIAS>

后续内容施工中

img


02_var_primitive_operator

变量的定义

1
let a: u32 = 10u32;

Move是一门强类型的编程语言,没有隐式的类型转换,定义变量也需要申明类型或者标注类型

move只有无符号的正数

Move程序使用let将变量名绑定到值:

1
2
let x = 1;
let y = x + x:

Let也可以在不将值绑定到局部的情况下使用。 然后可以为局部变量赋值。

1
2
3
4
5
6
let x;
if (cond) {
x = 1u32
} else {
x = 0u32
}

变量必须在使用前赋值

1
2
let x;
x + x // ERROR!

变量的名字

必须是 _a-zA-Z 开始 只能包含字母数字和下划线 _

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module var::var {

use sui::tx_context::{TxContext};

#[allow(unused_variable)]
fun init(_: &mut TxContext) {

let s = b"hello";

let s2 = s;

let x = 0;
let b = false;
let addr = @0x42;
let x_ref = &x;

let b2 = b;
let addr2 = @0x42;
let x_ref2 = x_ref;
}

}

整型

● Move只有6个无符号整数
● Move没负数和小数

  • u8 u16 u32 u64 u128 u256
  • + - * / %
  • = > < !=
1
2
3
4
5
6
u8 Unsigned 8-bit 0-255
u16 Unsigned 16-bit 0-65535
u32 Unsigned 32-bit 0-4294967295
u64 Unsigned 64-bit 0- 2的64次方-1
u128 Unsigned 128-bit 0- 2的128次方-1
u256 Unsigned 256-bit 0- 2的256次方-1

move没有负数,小数的定义 是 a / b , 所以只要我选择放大整数的倍数可以用来表示小数,标准库中 :
https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/packages/move-stdlib/sources/fixed_point32.move

负数 我们可以用前端展现和约定的方式来表示
比如U8 类型 的 1到127 表示负数 128到255 表示正数,这是一种约定的方式

运算符

和其他编程语言一致

as 运算符

●只有类型相同的才能做基本运算
● as 是 Move的 整数 类型转换运算符
● Move 不支持类型的隐式转换
● 语法 (1u8 as u64)

例如

1
2
3
4
5
6
fun init(ctx: &mut TxContext) {
let a : u16 = 1000;
let b : u64 = 999;
let c : u32 = 1000;
let d = b + (c as u64);
let f = a + (c as u16);

布尔型

bool是Move对布尔值true和false的基本类型。

1
2
3
&& 		ture && ture
|| ture || false = ture
! !ture= false !false = ture

地址类型

address 在Move中是一个特殊的类型用来在合约里面表示一个钱包地址

字节的长度是 32字节

1
2
3
4
5
6
7
let address1: address = @0x1;
let address2: address = @0x42;
let address3: address = @0xDEADBEEF;
let address4: address =
@0x0000000000000000000000000000000000000000
00000000000000000000000A;
let address_2 = @primitive;

@十六进制字符串,可以省略前面的0,例如:0x000000001 = 0x1

代码分析

回顾:创建一个项目

1
sui move new project_name

目录结构

image-20240414102732534

03_mod_function

什么是包

包是同一个合约地址包含的全部代码的集合,由很多模块组成

什么是模块

代码模块是代码划分访问权限和代码的组织方式

1
2
3
4
5
module mod::a {
use sui::tx_context::TxContext;
fun init(ctx: &mut TxContext) {
}
}

定义一个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
fun a(){
}

public fun b(){
}

public(friend) fun c(){}

public entry fun d(){
}

public fun f(a:u32, b:u32): bool{
a > b
}

什么是方法

方法是组织代码调用和抽象片段的最小单位

方法访问权限控制

方法签名 调用范围 返回值
fun call() 只能模块内调用 可以有
public fun call() 全部合约能调用 可以有
public entry fun call() 全部合约和Dapp(RPC)能调用
entry fun call() 只能Dapp(RPC)调用
public(package) fun call() {} 限定只能当前包调用 可以有

init方法

  • 只能是私有的
  • 会在发布合约的是自动调用一次
  • 只有两种形式
1
2
fun init(ctx: &mut TxContext){}
fun init(witness: Struct, ctx: &mut TxContext) {}

在合约发布的时候自动调用这个方法

代码分析

1
sui move new package

这里创建的package整体就是一个包,包含它里面的Move.toml(这个包的配置文件)、sources(源代码文件夹)、tests()

sources(源代码文件夹)里面的例如package.move称之为一个模块,里面有module

一般来说,模块的名字、配置文件中的名字、地址address名称都是一致的

04_comment_flow_control

mut 关键字

声明一个可修改的变量

1
2
let mut a: u32 = 32;
a = 64;

下划线开头的变量

1
let _a = 10u32;

print()

本地调试代码输出值

在标准库std::debug

1
2
3
4
5
module std::debug {
native public fun print<T>(x: &T);

native public fun print_stack_trace();
}

注释

  • 注释不支持中文等UTF-8字符 ,只支持英文,否则会报错
  • // 注释
  • /* */ 块注释
  • /// 文档注释
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/// this is mod comment
module comment::comment {

// this is comment
use sui::tx_context::TxContext;

/// this is docs comment
fun init(ctx: &mut TxContext) {
}
/**
line 1
line 2
line 3
*/
}

if

1
2
3
4
5
6
7
8
9
if (condition) true_branch // implied default: else ()
if (condition) true_branch else ()


// x and y must be u64 integers
let maximum: u64 = if (x > y) x else y;

// ERROR! branches different types
let z = if (maximum < 10) 10u8 else 100u64;

while

while结构重复语句体(unit类型的表达式),直到条件(bool类型的表达式)的计算结果为false。

下面是一个简单的while循环的例子,它计算从1到n的数字之和:

1
2
3
4
5
6
7
8
9
fun sum(n: u64): u64 {
let mut sum = 0;
let mut i = 1;
while (i <= n) {
sum = sum + i;
i = i + 1
};
sum
}

break

break表达式可用于在条件求值为false之前退出循环。例如,这个循环使用break来查找n中大于1的最小因子:

1
2
3
4
5
6
7
8
9
fun min_factor(n: u64): u64 {
let mut i = 2;
while (i <= n) {
if (n % i == 0) break;
i = i + 1
};

i
}

continue

continue表达式跳过循环的其余部分,继续进行下一次迭代。这个循环使用continue来计算1,2,…, n,除非该数能被20整除:

1
2
3
4
5
6
7
8
9
10
11
fun sum(n: u64): u64 {
let mut sum = 0;
let mut i = 0;
while (i < n) {
i = i + 1;
if (i % 20 == 0) continue;
sum = sum + i;
};

sum
}

loop

循环表达式重复循环体(类型为()的表达式),直到碰到一个break

1
2
3
4
5
6
7
8
9
10
11
fun sum(n: u64): u64 {
let mut sum = 0;
let mut i = 0;
loop {
i = i + 1;
if (i > n) break;
sum = sum + i
};

sum
}

loop{} 等价 while(true)

object

struct

结构体是自定义类型,它可以包含复杂数据, 也可以不包含任何数据。结构体由字段组成,可以简单地理解成”key-value”存储,其中 key 是字段的名称,而 value 是存储的内容。结构体使用关键字 struct 定义

info 0,说明

一、如何升级 Sui ?

如果您之前安装了 Sui 二进制文件,则可以使用与安装它们相同的命令将它们更新到最新版本

1
cargo install --locked --git https://github.com/MystenLabs/sui.git --branch testnet sui

二、用哪一个区块链浏览器

推荐:https://suivision.xyz/

devnet、testnet、mainnet的交易信息都可以很方便地查询

切换:

image-20240411191008311

三、各个网的prc端点号

1
2
3
4
5
https://sui-mainnet-endpoint.blockvision.org

https://sui-testnet-endpoint.blockvision.org

https://sui-devnet-endpoint.blockvision.org

或者

1
2
3
https://fullnode.devnet.sui.io:443

https://fullnode.testnet.sui.io:443

四、如何进行github的pr操作

一个github翻译插件:https://github.com/maboloshi/github-chinese

以一个move任务激励项目为例:https://github.com/move-cn/letsmove/pulls

现在要提交letsmove项目的pr

首先从上游链接fork项目到自己的仓库

image-20240411191325660

然后到自己仓库下面看fork的项目,用git clone下载到本地

1
git clone https://github.com/yourname/letsmove.git

在本地修改项目,改完后,更新到自己的仓库,可以通过多种方式,例如:直接上传修改的文件

image-20240411191950261

上传完毕后,点击自己仓库下面的pr,新建一个pr

image-20240411192119071