-
Notifications
You must be signed in to change notification settings - Fork 941
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
312608b
commit 07b22a6
Showing
4 changed files
with
597 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
# move入门之基础概念 | ||
🧑💻作者:gracecampo | ||
## 重要性 | ||
对于刚入门的开发人员来说,必然需要对sui和move的基本概念有了解,才能更好的理解以及开发应用。 | ||
|
||
本节将对sui和move中的基础概念进行讲解,希望可以带来一定的帮助。 | ||
|
||
### package-包 | ||
在一个项目中,一个包是包含了move.toml文件,以及source目录的文件夹,move.toml中定义了一个该项目的各项配置信息,source则用于储存项目源码。 | ||
|
||
 | ||
如图所示: source文件夹是存放源码的目录,move.toml文件是存放项目相关信息及依赖的文件,test文件夹是防止测试文件的目录 | ||
|
||
在move中一个项目通常被组织为一个包(package),包将被发布在区块链上,并生成一个地址用于识别,通过将包发布到区块链上,我们可以通过与区块链的交互进行调用。 | ||
|
||
创建包可以使用: | ||
```shell | ||
sui move new 你的项目名称 | ||
``` | ||
一个包可以有多个模块,每个模块可以有单独的作用域,变量,结构体,函数组成。 | ||
```sui move | ||
//clidemo是包名,mycoin为模块名 | ||
module packagedemo::demo { | ||
//定义一个结构体 | ||
public struct DEMO has drop {} | ||
//定义函数 | ||
public fun fun1(){ | ||
//定义变量 | ||
let A:u8 = 13; | ||
} | ||
//定义函数 | ||
public fun fun2(){ | ||
//定义变量 | ||
let B:u8 = 13; | ||
} | ||
} | ||
``` | ||
发布包: | ||
```shell | ||
sui move publish | ||
``` | ||
发布后的包将会在链上生成不可变更的唯一地址,其中包含了该包下的模块源码,我们可以通过使用链上交互工具(例如钱包)进行交互。 | ||
|
||
### Manifest-包清单 | ||
Move.toml 是描述 包 及其依赖关系的清单文件,采用 TOML 格式,包含多个部分,其中最重要的是 [package]、[dependencies] 和 [addresses]。 | ||
|
||
下图是一个基础的包清单配置 | ||
```toml | ||
[package] | ||
name = "packagedemo" | ||
edition = "2024.beta" # edition = "legacy" to use legacy (pre-2024) Move | ||
# license = "" # e.g., "MIT", "GPL", "Apache 2.0" | ||
# authors = ["..."] # e.g., ["Joe Smith ([email protected])", "John Snow ([email protected])"] | ||
|
||
[dependencies] | ||
Sui = { git = "https://gitee.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "framework/testnet" } | ||
|
||
# For remote import, use the `{ git = "...", subdir = "...", rev = "..." }`. | ||
# Revision can be a branch, a tag, and a commit hash. | ||
# MyRemotePackage = { git = "https://some.remote/host.git", subdir = "remote/path", rev = "main" } | ||
|
||
# For local dependencies use `local = path`. Path is relative to the package root | ||
# Local = { local = "../path/to" } | ||
|
||
# To resolve a version conflict and force a specific version for dependency | ||
# override use `override = true` | ||
# Override = { local = "../conflicting/version", override = true } | ||
|
||
[addresses] | ||
packagedemo = "0x0" | ||
|
||
# Named addresses will be accessible in Move as `@name`. They're also exported: | ||
# for example, `std = "0x1"` is exported by the Standard Library. | ||
# alice = "0xA11CE" | ||
|
||
[dev-dependencies] | ||
# The dev-dependencies section allows overriding dependencies for `--test` and | ||
# `--dev` modes. You can introduce test-only dependencies here. | ||
# Local = { local = "../path/to/dev-build" } | ||
|
||
[dev-addresses] | ||
# The dev-addresses section allows overwriting named addresses for the `--test` | ||
# and `--dev` modes. | ||
# alice = "0xB0B" | ||
``` | ||
[package] 部分用于描述包。该部分的字段不会被发布到链上,但会用于工具和版本管理;它还指定了编译器使用的 Move 版本。 | ||
|
||
[dependencies] 部分用于指定项目的依赖关系。每个依赖关系都以键值对的形式指定,键是依赖的名称,值是依赖的规范。依赖规范可以是 git 仓库的 URL 或本地目录的路径。 | ||
|
||
[dev-dependencies] 部分,用于在开发和测试模式下覆盖依赖关系。 | ||
|
||
[addresses] 部分用于为地址添加别名。 | ||
|
||
[dev-addresses] 部分与 [addresses] 类似,但仅在测试和开发模式下有效。 | ||
|
||
|
||
### address 地址 | ||
地址是区块链上位置的唯一标识符。它用于标识包 (package)、账户 (account)和对象 (object)。地址的固定大小为32字节,通常表示为以 0x 开头的十六进制字符串。地址不区分大小写。 | ||
|
||
sui预留了一部分地址,用于底层依赖包,例如以下几个: | ||
|
||
0x1 - Sui 标准库的地址(别名 std) | ||
|
||
0x2 - Sui 框架的地址(别名 sui) | ||
|
||
0x6 - 系统 Clock 对象的地址 | ||
|
||
### account 账户 | ||
账户 (account) 是识别用户的一种方式。账户由私钥生成,并通过地址来识别。账户可以拥有对象,并且可以发送交易。每个交易都有一个发送者,发送者通过地址来识别。 | ||
|
||
Sui 支持多种加密算法用于生成账户。支持的曲线有 ed25519、secp256k1。Sui 的加密灵活性使得账户生成具有灵活性和多样性。 | ||
|
||
我们可以通过第三方钱包进行地址生成,例如sui Wallet | ||
|
||
也可以使用sui-cli进行本地生成,命令如下: | ||
|
||
```shell | ||
sui client new-address ed25519 | ||
``` | ||
|
||
### transaction 交易 | ||
transaction(交易)是区块链系统中一个重要概念,它与现实中的交易不同,在区块链系统中,transaction是与链上交互中,任何改变区块链系统状态的变动都可视为交易。 | ||
|
||
此类活动可以是转账,调用函数,部署合约,升级合约等操作。 | ||
|
||
用户通过调用程序中的公开函数与区块链上的智能合约进行交互。这些公开函数定义了可以在交易中执行的操作。交易是由账户发起的,账户发送交易时指定它要操作的对象。 | ||
|
||
我们可以通过区块浏览器,查看对应的transaction信息 | ||
|
||
 | ||
|
||
💧 [HOH水分子公众号](https://mp.weixin.qq.com/s/d0brr-ao6cZ5t8Z5OO1Mog) | ||
|
||
🌊 [HOH水分子X账号](https://x.com/0xHOH) | ||
|
||
📹 [课程B站账号](https://space.bilibili.com/3493269495352098) | ||
|
||
💻 Github仓库 https://github.com/move-cn/letsmove |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
# move入门之结构体的四大能力 | ||
🧑💻作者:gracecampo | ||
本文将介绍在move中很重要的的结构体知识点,以及结构体的四大能力。 | ||
就像人有运动,说话,思考的能力一样,一个结构体我们也可以赋予它一定的能力。 | ||
## 结构体定义 | ||
结构体是面向结构体编程思想的重要体现,我们将现实事物抽象成代码,必然需要一个载体,而这个载体在move编程中的体现就是结构体,将现实事物的一些特征, | ||
用结构体属性来表示出来。 | ||
|
||
比如我们要抽象出一个人,而这个人具备三种基本属性:姓名,性别,年龄,我们在代码中可以这样定义 | ||
```sui move | ||
//定义人的结构体,存在姓名,年龄,性别三个属性 | ||
module person::person{ | ||
use std::string::String; | ||
public struct Person{ | ||
name: String, | ||
age: u8, | ||
sex: String | ||
} | ||
} | ||
``` | ||
### 结构体限制: | ||
结构体模式是私有的,只能模块内部访问,但是我们可以通过可见性声明,比如添加public或者public(package),来提高它的可见性。 | ||
|
||
public :公共可见,凡是导入该模块的,都可以使用 | ||
|
||
public(package): 包内可用,只能在包内访问及使用,相比public要更严格。 | ||
|
||
## copy能力 | ||
move是用于表示数字资产或者资源的,而数字资产或者资源在某种程度上是不允许复制的。 | ||
而在一些业务场景下,是需要一些资源或者数字资产具备copy能力。 | ||
copy能力表示该类型的实例或者值可以被复制,在move中自定义类型如果不加说明,默认是不具备copy能力的。此能力作用于结构体上。 | ||
举例说明: | ||
```sui move | ||
module person::person { | ||
use std::string::String; | ||
public struct Person has copy{ | ||
name: String, | ||
age: u8, | ||
sex: String | ||
} | ||
} | ||
``` | ||
在上面的例子中,我们添加has copy,使得person结构体拥有被复制的能力,但在常识中,人是不能被复制的,但是通过copy能力我们可以让person这个结构体 | ||
被复制。 | ||
接下来,我们来看代码: | ||
```sui move | ||
module person::person { | ||
use std::string::String; | ||
public struct Person has copy,drop{ | ||
name: vector<u8>, | ||
age: u8, | ||
sex: vector<u8>, | ||
} | ||
public fun copy_persion(){ | ||
let personA = Person{name: b"zhangsan",age:18,sex:b"男"}; | ||
//可以复制到personB | ||
let personB = personA; | ||
//通过解引用,复制到personC | ||
let personC = *&personB; | ||
} | ||
} | ||
``` | ||
在上述代码中personA被隐性的复制到personB,personB通过解引用操作符复制到personC。 | ||
在上述代码中,如果Person没有copy能力,编译将失败。 | ||
在编译上述代码时,Person不仅需要声明copy,也应当具有drop能力,否则编译会失败。 | ||
drop能力会在下面的drop能力介绍。 | ||
## drop能力 | ||
定义: | ||
在move中,为了是所有资源或者资产得到正确处理,是不允许声明结构体后不使用它忽略的,否则会导致编译失败。 | ||
而拥有drop能力允许对结构体进行忽略或者丢弃。 | ||
```sui move | ||
module book::drop_ability { | ||
/// | ||
public struct PersonHasDrop has drop{ | ||
name: vector<u8>, | ||
age: u8, | ||
sex: vector<u8>, | ||
} | ||
public struct NoDropPerson{ | ||
} | ||
#[test] | ||
fun test_drop() { | ||
//声明一个无drop能力的结构体 | ||
let no_drop = NoDropPerson {}; | ||
//声明拥有drop能力的结构体,但是可以忽略它 | ||
let _ = PersonHasDrop{name:b"zhangsan",age:19,sex:b"nan"}; | ||
//无drop能力的我们必须解包结构体,才能通过编译 | ||
let NoDropPerson {name:_,age:_,sex:_} = no_drop; | ||
} | ||
} | ||
``` | ||
drop能力通常在自定义的结构体上使用,以防在不需要的时候,可以或略它。 | ||
例如,vector 类型具有 drop 能力,这使得在不再需要时可以忽略该向量。 | ||
sui提供的标准库中,很多原生类型是已经声明drop能力的,此项设计,极大减轻了我们对于对于结构体属性的管理。 | ||
## key能力 | ||
在move的设计中,drop和copy是针对结构体的,他们主要影响的是结构体行为,而key和store能力主要影响的是结构体的储存。 | ||
key通常是标识一个对象的唯一性,用于标识该对象在区块链系统中的储存位置。 | ||
sui验证器要求结构体的第一个字段必须明明为id,并且类型是UID. | ||
```sui move | ||
module book::key_ability { | ||
use sui::object::{Self, ID, UID}; | ||
public struct Person has key{ | ||
id: UID, | ||
name: vector<u8>, | ||
age: u8, | ||
sex: vector<u8>, | ||
} | ||
public fun copy_persion(ctx: &mut TxContext): Person{ | ||
Person{ | ||
id:object::new(ctx),name: b"zhangsan",age:18,sex:b"男" | ||
} | ||
} | ||
} | ||
``` | ||
当我们需要对象进行链上转移的时候,必须使结构体拥有key的能力。否则将无法转移。 | ||
故而具备key能力的对象是不可复制以及丢弃的,故而它是不能被赋予copy,drop能力的。 | ||
## store能力 | ||
store能力是一种特殊的能力,允许将结构体作为另一个结构体的字段来使用。 | ||
如果不声明store能力,源码将无法编译成功。 | ||
```sui move | ||
module book::store_ability { | ||
use sui::object::{Self, ID, UID}; | ||
public struct Currency has store{ | ||
currency_type: vector<u8>, | ||
} | ||
public struct PersonWallet has key,store{ | ||
id: UID, | ||
money: Currency | ||
} | ||
public struct Person has key{ | ||
id: UID, | ||
name: vector<u8>, | ||
age: u8, | ||
sex: vector<u8>, | ||
wallet: PersonWallet | ||
} | ||
public fun copy_persion(ctx: &mut TxContext): Person{ | ||
let currency = Currency{ | ||
currency_type:b"usd" | ||
}; | ||
let person_wallet = PersonWallet{ | ||
id: object::new(ctx),money:currency | ||
}; | ||
Person{ | ||
id:object::new(ctx),name: b"zhangsan",age:18,sex:b"男",wallet:person_wallet | ||
} | ||
} | ||
} | ||
``` | ||
在例子中,我们声明了一个拥有store的结构体Currency,而钱包结构体(PersonWallet)将Currency类型作为对象的一个字段, | ||
钱包结构体(PersonWallet)同样拥有store,它同样可以被Person作为一部分来使用。 | ||
|
||
在move中,除了引用之外,所有原生类型都具有store能力,比如address,vector等。 | ||
|
||
💧 [HOH水分子公众号](https://mp.weixin.qq.com/s/d0brr-ao6cZ5t8Z5OO1Mog) | ||
|
||
🌊 [HOH水分子X账号](https://x.com/0xHOH) | ||
|
||
📹 [课程B站账号](https://space.bilibili.com/3493269495352098) | ||
|
||
💻 Github仓库 https://github.com/move-cn/letsmove |
Oops, something went wrong.