https://github.com/aptos-labs/aptos-core/

github代码参考:https://github.com/aptos-labs/aptos-core/

模块交互与发布

发布

生成账户地址:aptos init

领水:aptos account fund-with-faucet –account de fault

编译:aptos move compile

测试: aptos move test

发布:aptos move publish

交互

Aptos 区块链浏览器:https://explorer.aptoslabs.com/

生成的sender来搜索(记得切换对应网络)

点击 Modules-run 实施交互,进行基本调试

Vector 向量解析

特性:vector 可以理解为其他语言的数组

查询功能

语法 描述
vector::is_empty(): bool 查询是否是空数组
vector::length(v: &vector): u64 查询数组长度
vector::borrow(v: &vector, i: u64): &T 返回数组第n项的数据
vector::borrow_mut(v: &mut vector, i: u64): &mut T 返回数组第n项的可变引用
vector::contains(v: &vector, e: &T): bool 如果元素e在数组中,则返回true
vector::index_of(v: &vector, e: &T): (bool, u64) 如果元素e在数组中,则返回true和索引位置

增删改

语法 描述
vector::push_back(v: &mut vector, t: T) 添加尾部1个元素
vector::append(v1: &mut vector, v2: vector) 添加尾部1个数组
vector::reverse_append(lhs: &mut vector, other: vector) 添加尾部1个数组,并进行排序
vector::pop_back(v: &mut vector): T 删掉尾部1个元素
vector::destroy_empty(v: vector) 删除数组
vector::swap(v: &mut vector, i: u64, j: u64) 交换数组中两个元素的位置
vector::reverse(v: &mut vector) 反转数组中元素的顺序
vector::insert(v: &mut vector, i: u64, e: T) 在长度为i-1处插入一个元素
vector::remove(v: &mut vector, i: u64): T 删除索引为i处的元素

代码示例

module 0x42::lesson4{
use std::debug;
use std::vector;
//create a vector of u64
const ARR:vector<u64> = vector[1,2,3,4,5,6];

#[test]
fun test_vector(){
debug::print(&ARR);
}

#[test]
fun test_empty_vector(){
let bools:bool = vector::is_empty(&ARR);
debug::print(&bools);

}
#[test]
fun test_vector_length(){
let len:u64 = vector::length(&ARR);
debug::print(&len);
}

#[test]
fun test_vector_borrow(){
let val = vector::borrow(&ARR,3);
debug::print(val);
}

#[test]
fun test_vector_borrow_mut(){
//change vector value
let arr:vector<u64> = vector[1,2,3,4,5];
let val = vector::borrow_mut(&mut arr,3);
*val = 100;
debug::print(&arr);
}
#[test]
fun test_vector_contains(){
let n2:u64 = 11;
let n:u64 = 3;
let bools:bool = vector::contains(&ARR,&n);
let bools2:bool = vector::contains(&ARR,&n2);
debug::print(&bools);
debug::print(&bools2);
}
#[test]
fun test_vector_index_of(){
let n2:u64 = 11;
let n:u64 = 3;
let (isIndex,index) = vector::index_of(&ARR,&n);
let (isIndex2,index2) = vector::index_of(&ARR,&n2);
debug::print(&index);
debug::print(&index2);
debug::print(&isIndex);
debug::print(&isIndex2);
}
}

函数修饰符

核心概念

函数修饰符是用来赋予函数特殊能力的一组关键字。

主要有以下几类

可见性

  • 无public,私有函数,仅限module内部调用

  • friend (public),模块内部函数,同包模块之间可以调用

  • public,模块公开函数,所有模块都可以调用

全局存储引用

  • acquires,当需要使用move_fromborrow_globalborrow_global_mut 访问地址下的资源的时候,需要用其修饰

链下

  • entry,修饰后,该方法可由链下脚本调用

    代码示例1

    address 0x42{
    module m{
    friend 0x42::m3;

    fun f1() : u64{
    1
    }
    //public 可以被外部访问
    public fun f2() : u64{
    2
    }
    //外部模块无法直接调用,需要声明friend
    public(friend) fun f3() : u64{
    3
    }
    }
    module m2{
    fun f1() : u64{
    0x42::m::f2()
    }
    }
    //view f2 f3
    module m3{
    fun f1() : u64{
    0x42::m::f3()
    }
    }
    }

    代码示例2

    module 0x42::Demo{
    use std::debug;
    // 每个账户在 move 中都有一个唯一的 Signer,它通常是账户的创建者或者拥有者。
    use std::signer;

    struct Coin has key{
    value:u64
    }

    //可以被链下调用
    public entry fun mint(account: &signer, value: u64){
    //将Coin移动到用户的地址中去
    move_to(account, Coin{value});
    }

    #[test(account = @0x42)]
    //acquires
    public fun test_mint(account: &signer)acquires Coin{

    //获取account的地址
    let addr = signer::address_of(account);
    mint(account, 10);

    //从全局资源中借用指定地址addr处的Coin类型资源,并获取其value
    let coin = borrow_global<Coin>(addr).value;
    debug::print(&coin)
    }

    }

struct 结构体

核心概念

Struct 结构体,用来存储具有结构化的数据,sturct可以相互嵌套(不能递归)可存储地址下作为资源,默认情况下,结构声明是线性且短暂的(也就是没办法引用)

  1. 命名必须以大写字母开头
  2. 可以通过has 关键词赋与能力

修饰符

-Copy 值能够被复制
-Drop 值可以在作用域结束时删除
-Key 值可以用作全局存储操作的key,可以索引到相关结构体
-Store 值可以被全局存储,结合key使用,实现嵌套

除struct类型外,其他的类型默认具备 store,drop,copy 的能力,sturct 最终是存储在用户的地址上(或者被销毁),不存在aptos合约里,aptos合约是一个全纯的函数(相较于Solidity)

Object 对象

  1. 对象是单个地址的资源容器,用于储存资源;
  2. 对象提供了一种集中式资源控制与所有权管理的方法;

创建并转移对象案例

module my_addr::object_playgoud{
use std::signer;
use aptos_framework::object::{self,ObjectCore};

entry fun create_and_transfer(caller:&signer,destination:address){
//接受拥有者地址
let caller_adsress = signer::address_of(caller);
//绑定地址和对象
let constructor_ref = object::create_object(caller_address);

//Set up the object

//transfer to destination
//转移所有权
let object = object::object_from_constructor_ref<ObjectCore>(
&constructor_ref
);
object::transfer(caller,object,destination);
}

三种对象类型

  • 普通对象可删除,且具有随机地址object::create_object(owner_address: address)
  • 命名对象。不可删除,通过固定的signer和特定的seed生成唯一地址的对象,1个地址只能生成1个,具有确定性地址object::create_named_object(creator: &signer, seed: vector<u8>)
  • 粘性对象。不可删除,通过signer生成的对象,1个地址可以生成多个,具有随机地址object::create_sticky_object(owner_address: address)

示例代码:

module 0x42::demo{
use std::debug::print;
use aptos_framework::object;
use aptos_framework::object::{Object, ConstructorRef, ObjectCore};

use std::signer;

const NAME:vector<u8> = b"myObject";
//can_delet
public fun createDeleteableObject(caller: &signer):ConstructorRef{
let caller_addr = signer::address_of(caller);
let obj = object::create_object(caller_addr);
obj
}



//aptos-labs/examples

//cannt
public fun createNamedObject(caller: &signer):ConstructorRef{
let obj = object::create_named_object(caller, NAME);
obj
}
public fun createStickyObject(caller: &signer):ConstructorRef{
let caller_addr = signer::address_of(caller);
let obj = object::create_sticky_object(caller_addr);
obj
}
#[test(caller = @0x88)]
fun test2(caller: &signer){
let obj = createNamedObject(caller);
print(&obj);
}


#[test(caller = @0x88)]
fun test(caller: &signer){
let obj = createDeleteableObject(caller);
print(&obj);
}

#[test(caller = @0x88)]
fun test3(caller: &signer){
let obj = createStickyObject(caller);
print(&obj);
}

}

Object 配置

一旦您创建了对象,您将收到一个ConstructorRef可用于生成其他Refs 。Refs可在将来用于启用/禁用/执行某些对象功能,例如传输资源、传输对象本身或删除对象。

  1. 允许删除对象 ( DeleteRef)

    对于使用默认方法(允许删除)创建的对象,您可以生成一个DeleteRef稍后可以使用的对象。这可以帮助消除混乱并获得存储退款。DeleteRef您不能为不可删除的对象创建。

  2. 一次性转账 ( LinearTransferRef)

    此外,如果创建者想要控制所有传输,以提供一次性使用的传输功能。这可用于通过从对象创建者到接收者的一次性传输来创建“灵魂绑定”对象。必须LinearTransferRef由对象的所有者使用。

  3. 禁用/切换传输 ( TransferRef)

    默认情况下,所有对象都是可转让的。这可以通过 来更改,TransferRef来生成object::generate_transfer_ref

  4. 添加可扩展性(ExtendRef)

将对象变成可动态配置的,可以往里面添置新的 struct 资源。生成一个ExtendRefobject::generate_extend_ref。此引用可用于为该对象生成签名者。

  1. 添加资源

    使用ConstructorRefobject::generate_signer创建一个签名者,允许您将资源转移到对象上。这使用move_to,与将资源添加到帐户的功能相同