下一代智能合约编程语言Move(三)

前言

之前我们曾提到不同于其他的智能合约编程语言,Move将脚本和模块分离,之前的两篇文章主要与脚本相关,这篇文章将会主要介绍模块相关的内容。

模块

模块是开发者发布在自己地址的一系列函数,之前我们使用的脚本只能使用已经发布的模块或者标准库,标准库也就是发布在0x1地址的一系列模块。

模块是发布在发送者的地址的,标准库是发布在0x1地址的,当发布一个模块时它的函数并未执行,需要使用use script去执行模块。

模块是以module关键字开头,紧接着的是模块明,之后双括号里面就是模块的内容:

module Math {
  //模块内容
  public fun sum(a: u64, b: u64): u64 {
    a + b
  }
}

模块是唯一的向其他人开放代码的方式,新的类型和资源只能定义在模块里。

默认的你的模块会在你的地址编译和发布,然而如果需要使用本地的模块(用作测试和开发)可以在模块文件中指定地址即可。

address 0x1 {
  module Math {
  //模块内容
  public fun sum(a: u64, b: u64): u64 {
    a + b
  }
}
}

引入模块

Move中默认的上下文是空的,这意味着你只能使用基本类型如interger,bool和address,而且智能操作这些基本类型和变量,为了实现更加复杂的功能,你可以引入已经发布的模块或者标准库。

直接引入

可以直接通过地址引入模块

script {
    fun main(a: u8) {
        0x1::Offer::assert!(a == 10, 1);
    }
}

在这个例子中我们使用了地址01x(标准库)的模块Offer中的方法assert!(expr: bool, code: u8)。

使用关键字use

为了使代码更加简洁,可以使用use关键字引入模块。

use 0x1::Vector;

引入模块后需要使用模块的内容需要使用::

script {
  use 0x1::Vector;
    fun main(a: u8) {
        let _ = Vector::empty<u64>();
    }
}

与此同时还可以引入指定的内容

script {
  //引入一个成员
  use 0x1::Signer::address_of;
  //引入多个成员
  use 01x::Vector::{
    empty,
    push_back
  }
}

为了避免命名冲突,可以在引入是使用as取别名

script {
  //引入一个成员
  use 0x1::Signer::address_of as addr;
  //引入多个成员
  use 01x::Vector::{
    empty as em,
    push_back as pu
  }
}

常量

Move支持定义脚本级别和模块级别的常量,一旦定义就无法更改。

script {

    use 0x1::Debug;

    const RECEIVER : address = 0x999;

    fun main(account: &signer) {
        Debug::print<address>(&RECEIVER);

        // they can also be assigned to a variable

        let _ = RECEIVER;

        // but this code leads to compile error
        // RECEIVER = 0x800;
    }
}

函数

在Move中函数是唯一执行的地方,函数需要使用fun关键字声明,之后是函数名和参数列表,但括号内的是函数体。

fun function_name(arg1: u64, arg2: bool) {
    //函数体
  }

在Move中函数名需要都小写然后通过下划线连接。

脚本中的函数

脚本中只包含一个main函数,这个函数带有参数是用来之行一次事务,限制比较多,没有返回值,可以用来执行已经发布的模块的函数,下面的脚本就是用来检查地址是否存在。

script {
  use 0x1::Account;
  fun main(addr: address) {
    assert!(Account::exists(addr));
  }
}
模块中的函数

模块事一系列解决一个或多个任务的函数和类型(之后会详细介绍)的集合。在这一部分我们会创建一个简单的Math模块,提供一系列基本的算术能力。

module Math {
  fun zero(): u8 {
    0
  }
}

需要注意的是函数可以用return来终止函数执行并且返回一个值,以上就是返回来一个零,这是我们在表达式中提到到,没有分号可以省略return关键字。

返回多个返回值

在Move中函数是可以返回多个返回值的:

module Math {
 public fun max(a: u8, b: u8): (u8, bool) {
  if (a > b) {
    (a, false)
  } else if {
    (b, false)
  } else {
    (a, true)
  }
 }
}

我们已经返回了两个值,那么又该如何接受那两个值呢:

script {
  use 0x1::Debug;
  use 0x1::Math;

  fun main(a: u8, b: u8) {
    let (max, is_equal) = Math::max(99, 100);
    assert(is_equal, 1);
    Debug::print<u8>(&max)
  }
}
函数的可见性

Move的函数主要可以分为两类,一类事private(默认的),一类事public,如果时public则是其他模块也可以访问,但是如果时private,则只能在定义函数的地方访问。例子如下,is_zero和zero函数都是在Math模块内,但是zero是private,is_zero可以访问zero,但是其他模块不可以访问zero,而is_zero是public其他模块也可以访问。

module Math {

    public fun is_zero(a: u8): bool {
        a == zero()
    }

    fun zero(): u8 {
        0
    }
}

native函数

Move有一种特殊类型的函数native函数,native函数是实现Move没有提供的能力,实现的方式也有很多种,其室友虚拟机自己定义的,例子如下

module Signer {

    native public fun borrow_address(s: &signer): &address;

    // ... some other functions ...
}

最后

这篇文章主要讲述了Move的模块和函数,更多文章可以关注公众号QStack。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值