MOVE入门|第二节:move学习之模块及脚本

Move开发的程序有 Modules(模块) 和 Scripts(脚本)两种类型:模块是定义结构类型以及对这些类型进行操作的函数的库。结构类型定义Move全局存储的模式,模块函数定义了更新存储的规则。模块本身也存储在全局存储中。脚本是类似于传统语言中main函数,是执行程序的入口点。脚本通常调用已发布模块的函数来更新全局存储,且脚本不会发布到全局存储中。

模块(Module)

Modules(模块)定义了结构体以及一组对结构体操作的函数。结构体主要用于定义全局存储的资源,而函数定义的是更新资源的规则。 有点像面向对象编程语言中类的概念,如在move中可以定义一个名为Math的模块(类),在其中定义加减乘除等函数(类中的方法)来完成这些运算。

语法

module <address>::<identifier> {

    (<use> | <friend> | <type> | <function> | <constant>)*
}
  • module <address>::<identifier>:module为模块声明关键字, <address>为模块发布在全局存储上的地址,可以是命名地址或文字地址 <identifier>为模块名
  • <use>:可以使用use关键字导入需要的模块
  • <constant>:在module中可以使用const关键字声明常量
  • <function>:可以定义函数
  • <type>:指在module中可以定义结构体
  • <friend>:指可以使用friend关键字在moudle中指定一个可信模块列表

例子

module 0x01::Test{
    struct Example has copy,drop {i:u64}

    use std::debug;

    const ONE :u64 =1;

    public fun print(x:u64){
        let sum =x+ONE;
        let example = Example{i:sum};
        debug::print(&example);
    }
}

下面详细解释一下以上代码:

  • struct Example has copy,drop {i:u64}:定义了一个结构体Example,有copy和drop的能力(能力我们在后面章节会具体介绍),结构体中定义了一个u64变量i。
  • module 0x01::Test :指模块 Test 会通过 publish 发布到全局存储中地址0x01下。所以可以使用0x01::Test::函数名这种形式进行调用
  • use std::debug:使用use关键字导入debug模块。std为标准库地址,他也是一个命名地址(即对数值地址命名)。
  • const ONE :u64 =1:使用const关键字声明一个常量ONE
  • public fun print(x:u64):定义了一个打印函数
  • let example = Example{i:sum}:实例了一个结构体变量example。
  • debug::print(&example):调用debug模块下的print函数来打印example的值

注意:发布模块不会执行任何函数。要使用模块就得使用脚本。

此时我们先编译发布一下模块

1.move build编译sources下的move代码
move build 
2.在沙盒环境使用move sandbox publish -v发布字节码到0x01名下。
move sandbox publish -v 
3.检查0x01地址下是否保存Test模块。
ls storage/0x00000000000000000000000000000001/modules |grep Test

如果想要使用此模块中的函数,可以使用脚本调用,也可以使用单元测试来测试。这里我们先介绍使用脚本调用

script {

//引入Test模块
use 0x1::Test;

fun test_T(i:u64){

//调用Test模块中的print函数
    Test::print(i);
    }
}

运行脚本:

move sandbox run sources/scripts/test_script.move --args 1 

脚本(script)

在move中,Script是链下执行程序的入口点,不需要部署到链上,主要用于调用模块中函数去更新资源。

注意:一个脚本文件中有且只能有一个函数,函数名可以任意起。

语法

script文件中,通常包括:

  • use声明:声明需要引入的模块。语法为:use 模块发布地址::模块名
  • 常量:script中可以包含常量。语法为:const 常量名:类型 = 常量的值
  • 主函数:script中唯一的函数,可以有任意数量的参数,但不能有返回值
script {
//1.使用use来引入需要使用的模块
    <use>*
//2.常量
    <constants>*
//3.主函数
    fun <identifier><[type parameters: constraint]*>([identifier: type]*) <function_body>
}

例子

script{
    //导入标准库中的debug模块 (语法:use address::模块名)
    use std::debug;

//声明常量ONE
    const ONE:u64 =1;

//主函数
    fun main(x:u64){
    //声明一个变量sum,值为x+ONE
        let sum =x +ONE;
    //调用debug模块的print函数,打印出sum的值
        debug::print(&sum);
    }

}

沙盒环境执行script脚本

通过使用--args向脚本main函数传参

move sandbox run sources/scripts/test_script.move --args 1 

总结

这一讲介绍了模块与脚本,模块是发布代码供他人访问的唯一方法,而发布模块不会执行任何函数,要使用模块就得使用脚本,即调用关系为:user->script->module。

评论