sui move笔记

2024-02-05 16:52
文章标签 笔记 sui move

本文主要是介绍sui move笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

一些疑问:

  • sui 和move是什么关系?

基础

基本数据类型

Move 的基本数据类型包括: 整型 (u8, u32,u64, u128,u258)、布尔型 boolean 和地址 address。

Move 不支持字符串和浮点数。

_u8:代表8位无符号整数类型,范围是0~255。占用内存8位
_u16:代表16位无符号整数类型,范围是0~65535。占用内存16位
_u32:代表32位无符号整数类型,范围是0~4294967295。占用内存32位
_u64:代表64位无符号整数类型,范围是0~18446744073709551615。占用内64位
以此类推

整型

module ch02::int {fun main() {// define empty variable, set value laterlet a: u8;a = 10;let a = 1u32;// define variable, set typelet a: u64 = 10;// finally simple assignmentlet a = 10;// simple assignment with defined value typelet a = 10u64;// in function calls or expressions you can use ints as constant valuesif (a < 10) {};// or like this, with typeif (a < 10u64) {}; // usually you don't need to specify typelet b = 1u256;// or like this, with typeif (b < 10u256) {}; // usually you don't need to specify type}
}

let a = 10 默认不手动标记类型的整型是 u64 类型,也就是等同于 let a:u64 = 10 或者 let a = 10u64

布尔型

布尔类型就像编程语言那样,包含false和true两个值。

module book::boolean {fun main() {// these are all the ways to do itlet b : bool; b = true;let b : bool = true;let b = true;let b = false; // here's an example with false}
}

地址

地址是区块链中交易发送者的标识符,转账和导入模块这些基本操作都离不开地址。

module book::addr {fun main() {let addr: address; // type identifieraddr = @ch02;}
}

模块

模块是发布在特定地址下的打包在一起的一组函数和结构体。
模块以module关键字开头,后面跟随地址::模块名称和大括号,大括号中放置模块内容。

module book::math {public fun sum(a: u64, b: u64): u64 {a + b}
}

注意:

  • 模块在发布者的地址下发布。标准库在 0x1 地址下发布。
  • 发布模块时,不会执行任何函数。要使用模块就得使用脚本。
  • 模块名推荐使用小写
  • 模块是发布代码供他人访问的唯一方法。新的类型和 Resource 也只能在模块中定义。默认情况下,模块将在发布者的地址下进行编译和发布

导入

Move 在默认上下文中只能使用基本类型,也就是整型、布尔型和地址,可以执行的有意义或有用的操作也就是操作这些基本类型,或者基于基本类型定义新的类型。

除此之外还可以导入已发布的模块(或标准库)。

  • 直接导入
module book::m {fun main(a: u8) {std::debug::print(&a);}
}

在此示例中,我们从地址0x1(标准库)导入了 debug 模块,并使用了它的 print 方法

use关键字

要使代码更简洁(注意,0x1 是特殊的地址,实际地址是很长的),可以使用关键字use:

use <address>::<ModuleName>;

这里 </address/> 是模块发布object的地址, 是模块的名字。非常简单,例如,我们可以像下面这样从 0x1 地址导入 vector 模块。

use 0x1::vector;
  • 访问模块的内容

要访问导入的模块的方法(或类型),需要使用::符号。非常简单,模块中定义的所有公开成员都可以通过双冒号进行访问。

module book::m_use {use  std::debug::print;fun main(a: u8) {print(&a);}
}

在模块中导入
在模块中导入模块必须在 module {} 块内进行:

module book::math {use std::vector;// you are free to import any number of modulespublic fun empty_vec(): vector<u64> {let v = vector::empty<u64>();v}
}

成员导入
导入语句还可以进一步被扩展,可以直接导入模块的成员:

module book::m_use2 {// single member importuse sui::tx_context::TxContext;use sui::tx_context::sender;// multi member import (mind braces)use std::vector::{empty,push_back};fun main(ctx: &mut TxContext) {// use functions without module accesslet vec = empty<u8>();push_back(&mut vec, 10);let _ = sender(ctx);}
}

使用 Self 来同时导入模块和模块成员
导入语句还可以进一步扩展,通过使用 Self 来同时导入模块和模块成员,这里 Self 代表模块自己。

module book::m_self {use 0x1::vector::{Self, // Self == Imported moduleempty};fun main() {// `empty` imported as `empty`let vec = empty<u8>();// Self means vectorvector::push_back(&mut vec, 10);}
}

使用 use as
当两个或多个模块具有相同的名称时,可以使用关键字as更改导入的模块的名称,这样可以在解决命名冲突的同时缩短代码长度。

语法:

use <address>::<ModuleName> as <Alias>;
module ch04::m_as1 {use 0x1::vector::{Self as v,empty as empty_vec};fun main() {// `empty` imported as `empty_vec`let vec = empty_vec<u8>();// Self as V = vectorv::push_back(&mut vec, 10);}
}

函数

Move 中代码的执行是通过调用函数实现的。函数以 fun 关键字开头,后跟函数名称、扩在括号中的参数,以及扩在花括号中的函数体。

module book::f01 {fun function_name(arg1: u64, arg2: bool): u64 {// function body10}
}
  • 注意:Move 函数使用snake_case命名规则,也就是小写字母以及下划线作为单词分隔符。

返回值:

module book::math {fun zero(): u8 {0}
}

第一步:我们定义一个 math 模块,它有一个函数:zero(),该函数返回 u8 类型的值 0。0 之后没有分号,因为它是函数的返回值

return关键字:

module book::m {public fun conditional_return(a: u8): bool {if (a == 10) {return true // semi is not put!};if (a < 10) {true} else {false}}
}

多个返回值及解构:

要指定多个返回值,需要使用括号:

module book::math {// ...public fun max(a: u8, b: u8): (u8, bool) {if (a > b) {(a, false)} else if (a < b) {(b, false)} else {(a, true)}}
}

在另一个模块中使用该函数的返回值。

module book::math_use {use book::math::sum;use book::math::max;fun use_max(){let (a,b)= max(1u8,2u8);}
}

上面例子中,我们解构了一个二元组,用函数 max 的返回值创建了两个新变量。

公有、私有方法、friend方法、native本地方法:

默认情况下,模块中定义的每个函数都是私有的,无法在其它模块或脚本中访问。可能你已经注意到了,我们在 Math 模块中定义的某些函数前有关键字 public:

  • 关键字 public 将更改函数的默认可见性并使其公开,即可以从外部访问。
  • 默认情况下函数是私有函数只能在定义它们的模块中访问。
  • 私有函数只能在定义它们的模块中访问。
module book::math {public fun sum(a: u64, b: u64): u64 {a + b}fun zero(): u8 {0}
}

friend 方法:
friend 方法可以指定指定的模板能调用,目前只能在同一个包内生效

module book::friends {friend book::m;public(friend) fun a_less_10(a: u8): bool {if(a < 10u) return true;false}
}

本地方法:
有一种特殊的函数叫做"本地方法"。本地方法实现的功能超出了 Move 的能力,它可以提供了额外的功能。本地方法由 VM 本身定义,并且在不同的VM实现中可能会有所不同。这意味着它们没有用 Move 语法实现,没有函数体,直接以分号结尾。关键字 native 用于标记本地函数,它和函数可见性修饰符不冲突,native 和 public 可以同时使用。

module book::m {native public fun borrow_address(s: &signer): &address;// ... some other functions ...
}

运算符

as

as 在move 中有两个用法:
1.给包取别名

module book::m_as1 {use 0x1::vector::{Self as v,empty as empty_vec};fun main() {// `empty` imported as `empty_vec`let vec = empty_vec<u8>();// Self as V = vectorv::push_back(&mut vec, 10);}
}

2.整型类型转换 语法 (整型A as 整型 B) 当需要比较值的大小或者当函数需要输入不同大小的整型参数时,你可以使用as运算符将一种整型转换成另外一种整型 注意就是括号是一定不能省的

module book::op_as {fun main(){let _a:u64 = (10u8 as u64);let _b:u8 = (a as u8);}
}

+ - * /

注意:

  • 负数做减法一定要检查是否产生负数
  • 做加法乘法注意 溢出报错
  • 除法小心精度丢失问题
  • 得益于Move的安全设计,溢出和负数不会让合约产生安全问题,因为程序会终止运行,但是程序终止会给用户带来不好的体验,代码不是很好调试,建议还是做好溢出边界判断
module book::op_arith {fun main(){let _add_op = 1 + 1;let _mut_op = 1*1;let _minu_op = 100 -1;let _div_op = 100/1;}}

常量

Move 支持模块级常量。常量一旦定义,就无法更改,所以可以使用常量为特定模块或脚本定义一些不变量,例如角色、标识符等。

常量可以定义为基本类型(比如整数,布尔值和地址),也可以定义为数组。我们可以通过名称访问常量,但是要注意,常量对于定义它们的模块来说是本地可见的。

module book::consts {use std::debug;const RECEIVER: address = 0x999;const ErrO1: u64 = 1000fun main(account: &signer) {debug::print<address>(&RECEIVER);let _ = RECEIVER;let _ = ErrO1;}
}

注意:

  • 一旦定义,常量是不可更改的。
  • 常量在模块是本地可见的,不能在外部使用。
  • 可以将常量定义为一个表达式(带有花括号),但是此表达式的语法非常有限。

表达式和作用域

这篇关于sui move笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/681563

相关文章

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

论文阅读笔记: Segment Anything

文章目录 Segment Anything摘要引言任务模型数据引擎数据集负责任的人工智能 Segment Anything Model图像编码器提示编码器mask解码器解决歧义损失和训练 Segment Anything 论文地址: https://arxiv.org/abs/2304.02643 代码地址:https://github.com/facebookresear

数学建模笔记—— 非线性规划

数学建模笔记—— 非线性规划 非线性规划1. 模型原理1.1 非线性规划的标准型1.2 非线性规划求解的Matlab函数 2. 典型例题3. matlab代码求解3.1 例1 一个简单示例3.2 例2 选址问题1. 第一问 线性规划2. 第二问 非线性规划 非线性规划 非线性规划是一种求解目标函数或约束条件中有一个或几个非线性函数的最优化问题的方法。运筹学的一个重要分支。2

【C++学习笔记 20】C++中的智能指针

智能指针的功能 在上一篇笔记提到了在栈和堆上创建变量的区别,使用new关键字创建变量时,需要搭配delete关键字销毁变量。而智能指针的作用就是调用new分配内存时,不必自己去调用delete,甚至不用调用new。 智能指针实际上就是对原始指针的包装。 unique_ptr 最简单的智能指针,是一种作用域指针,意思是当指针超出该作用域时,会自动调用delete。它名为unique的原因是这个

查看提交历史 —— Git 学习笔记 11

查看提交历史 查看提交历史 不带任何选项的git log-p选项--stat 选项--pretty=oneline选项--pretty=format选项git log常用选项列表参考资料 在提交了若干更新,又或者克隆了某个项目之后,你也许想回顾下提交历史。 完成这个任务最简单而又有效的 工具是 git log 命令。 接下来的例子会用一个用于演示的 simplegit

记录每次更新到仓库 —— Git 学习笔记 10

记录每次更新到仓库 文章目录 文件的状态三个区域检查当前文件状态跟踪新文件取消跟踪(un-tracking)文件重新跟踪(re-tracking)文件暂存已修改文件忽略某些文件查看已暂存和未暂存的修改提交更新跳过暂存区删除文件移动文件参考资料 咱们接着很多天以前的 取得Git仓库 这篇文章继续说。 文件的状态 不管是通过哪种方法,现在我们已经有了一个仓库,并从这个仓

忽略某些文件 —— Git 学习笔记 05

忽略某些文件 忽略某些文件 通过.gitignore文件其他规则源如何选择规则源参考资料 对于某些文件,我们不希望把它们纳入 Git 的管理,也不希望它们总出现在未跟踪文件列表。通常它们都是些自动生成的文件,比如日志文件、编译过程中创建的临时文件等。 通过.gitignore文件 假设我们要忽略 lib.a 文件,那我们可以在 lib.a 所在目录下创建一个名为 .gi

取得 Git 仓库 —— Git 学习笔记 04

取得 Git 仓库 —— Git 学习笔记 04 我认为, Git 的学习分为两大块:一是工作区、索引、本地版本库之间的交互;二是本地版本库和远程版本库之间的交互。第一块是基础,第二块是难点。 下面,我们就围绕着第一部分内容来学习,先不考虑远程仓库,只考虑本地仓库。 怎样取得项目的 Git 仓库? 有两种取得 Git 项目仓库的方法。第一种是在本地创建一个新的仓库,第二种是把其他地方的某个

Git 的特点—— Git 学习笔记 02

文章目录 Git 简史Git 的特点直接记录快照,而非差异比较近乎所有操作都是本地执行保证完整性一般只添加数据 参考资料 Git 简史 众所周知,Linux 内核开源项目有着为数众多的参与者。这么多人在世界各地为 Linux 编写代码,那Linux 的代码是如何管理的呢?事实是在 2002 年以前,世界各地的开发者把源代码通过 diff 的方式发给 Linus,然后由 Linus