【Aptos与Sui智能合约】 (Move长话短说) #02 - 基础数据类型和函数

本文介绍了Move语言的基础数据类型,包括整型、布尔、地址、signer特殊类型、数组和结构体。详细讨论了Move的引用和可变引用,以及Move函数的可见性和acquires关键字的使用。此外,还对比了Move与Solidity在处理区块链状态上的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0x1 Move数据类型

一般常见的基础数据类型在Move语言中都有

1.整型

整型有u8值范围2的8次方- 1, u16,u32值范围是2的32次方-1,u64,u128,u256值范围是2的256次方-1。整型数值是隐式值拷贝的,因此可以无需copy修饰。

2.布尔

布尔有:bool,太常见了,只有true或者false

3.地址类型

地址类型: address,占128-bit(16字节)大小,隐式可拷贝,无需显式声明copy。一般表达为

let a1: address = @0x1; // 全称是 0x00000000000000000000000000000001
let a2: address = @0x42; // 全称是  0x00000000000000000000000000000042
let a3: address = @0xDEADBEEF; // 全称是 0x000000000000000000000000DEADBEEF
let a4: address = @0x0000000000000000000000000000000A;
let a5: address = @std; // 把命名地址std分配给变量a5 
let a6: address = @66; // 数字表示
let a7: address = @0x42; // 十六进制表示
4.特殊类型signer

一个特殊类型signer,它是resource type也就是资源类型,它是一种特殊的address类型;signer也可以说类似于Unix系统中的UID,表示用户在Move语言代码外的一种鉴权,比如检查加密签名或者密码之类的。signer不能被copy修饰,自身也不是copyable。

5.数组类型vector

没什么特别说的,直接看例子吧

use std::vector;

let v = vector::empty<u64>();
vector::push_back(&mut v, 5);
vector::push_back(&mut v, 6);

assert!(*vector::borrow(&v, 0) == 5, 42);
assert!(*vector::borrow(&v, 1) == 6, 42);
assert!(vector::pop_back(&mut v) == 6, 42);
assert!(vector::pop_back(&mut v) == 5, 42);
6.结构体类型

结构体struct,跟Solidity类似的是,Move也有自定义结构体,
例如:

module m {
    struct Foo { x: u64 }

    public fun test1() {
        let foo = Foo { x: 100 };
        let Foo { x: _ } = foo;
        // 到这里,函数返回时,foo会被释放
    }
}

结构体可以被四种能力(Abilities)修饰,分别是:copy、drop、store、key。

  • copy 表示值可以被拷贝
  • drop 表示值可以被弹出或者删除
  • store 表示值存储在全局存储(global storage)的结构体中
  • key 允许类型作为全局存储操作的键

例如,说说copy的规则:

struct NoAbilities {}
struct S has copy, drop { f: bool }
struct Cup<T> has copy, drop, store { item: T }

fun example(c_x: Cup<u64>, c_s: Cup<S>) {
    // 允许执行!因为Cup<u64>拥有copy,并且u64隐式拥有copy能力
    let c_x2 = copy c_x;
    // 允许执行!因为Cup<S>有copy,S也有copy能力
    let c_s2 = copy c_s;
}

fun invalid(c_account: Cup<signer>, c_n: Cup<NoAbilities>) {
    // 不允许执行!因为signer没有copy,即使Cup拥有copy但是signer没有,所以会报错
    let c_account2 = copy c_account;
    // 不允许执行!因为NoAbilities没有copy能力,即使Cup有copy也不可以
    let c_n2 = copy c_n;
}

例如,说说store的规则:

struct Cup<T> has copy, drop, store { item: T }

// MyInnerResource被声明具有store,所以结构体里的字段都必须是store
struct MyInnerResource has store {
    yes: Cup<u64>, // 合法,因为Cup<u64>具有store修饰
    // no: Cup<signer>, 不合法,因为Cup<signer>不具有store修饰
}

// MyResource被声明为具有key,所以结构体里的所有字段必须具有store修饰
struct MyResource has key {
    yes: Cup<u64>, // 合法,因为Cup<u64>具有store修饰
    inner: Cup<MyInnerResource>, // 合法,因为Cup<MyInnerResource>具有store修饰
    // no: Cup<signer>, 不合法,因为Cup<signer>不具有store修饰
}

引用&和可变引用&mut

// 1.有一个结构体
let foo = Foo { x: 3, y: true };

// 2.引用访问
let foo_ref: &Foo = &foo; // 拷贝一个引用,现在有两个引用
let y: bool = foo_ref.y; // 引用访问字段y
let x_ref: &u64 = &foo.x; // 引用访问字段x

// 3.可变引用拷贝
let x_ref_mut: &mut u64 = &mut foo.x;
*x_ref_mut = 42; // 通过可变引用修改原引用的x的值

0x2 Move函数

函数分两种,一种是module function,另一种是script function。

fun <identifier><[type_parameters: constraint],*>([identifier: type],*): <return_type> <acquires [identifier],*> <function_body>

修饰符:

  • 默认是internal,也就是fun关键字前面什么也不写,就是internal的,那么外部的module和script都不可以调用
  • 使用public修饰可见性,外部module和script都可以访问
  • 使用entry修饰,一般表示入口调用函数,只是字面意义上,不能杜绝调用,因此将它修饰internal,而非public
  • 使用public(friend)修饰可见性,表示指定的module可以访问,否则拒绝。

例如public(friend)修饰可见性:

address 0x42 {
module m {
    friend 0x42::n;  // friend declaration
    public(friend) fun foo(): u64 { 0 }
    fun calls_foo(): u64 { foo() } // valid
}

module n {
    fun calls_m_foo(): u64 {
        0x42::m::foo() // 合法调用!
    }
}

module other {
    fun calls_m_foo(): u64 {
        0x42::m::foo() // 非法调用!因为 module other不是 module m 的friend
    }
}
}

script {
    fun calls_m_foo(): u64 {
        0x42::m::foo() // 非法调用!因为此 script不是 module m 的friend
    }
}
acquires关键字修饰

当一个函数需要操作resource时,则需要使用acquires关键字修饰,操作或者访问resource时,有三个针对全局存储的操作,分别是:move_from, borrow_global, borrow_global_mut

例如,减去指定地址的余额:

address 0x42 {
module example {

    struct Balance has key { value: u64 }

    public fun add_balance(s: &signer, value: u64) {
        move_to(s, Balance { value })
    }

    public fun extract_balance(addr: address): u64 acquires Balance {
        let Balance { value } = move_from(addr); // acquires needed
        value
    }
}
}

0x3 Move和Solidityb区块链状态对比图

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值