move背景
move 是由 Diem 项目 专门为区块链开发的一种安全可靠的智能合约编程语言 ,目前主要使用move语言开发智能合约的链有 Sui ,Aptos ,Starcoin
move对比solidity
存储模型
1 | struct GlobalStorage { |
1 | contract Alpha{ |
面向资源
move 使用drop store key copy这样一些关键字赋予资源各种能力(ability),实现了数据的资源属性,使其不再是单纯的一个uint,一个struct
key代表可以作为全局存储中的索引,一般和address组合查询
drop代表该数据可以在未转移的情况下丢弃
store 代表存储结构
copy 赋予资源快速拷贝的能力,比如权限之类的
1 | // @see module aptos_framework::coin |
ERC20部分代码
1 | function _transfer( |
一句话来讲move 提供的 ability ,限定了资源必须被处理 这样的一个语境
泛型
逻辑复用
安全复用
真正的协议标准复用,但是丢失了一定的灵活性
1 | struct Aranoverse {} |
1 | contract Aranoverse is ERC20{ |
形式化验证
简单来说可以认为是运行前断言以及运行后断言,可以保证运行的正确性。
1 | module hello_aptos::counter { |
自带测试框架
1 | #[test(signer = @hello_aptos)] |
move on Aptos 简要开发示例
环境准备
rust 环境
1
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
aptos cli
1
cargo install --git https://github.com/aptos-labs/aptos-core.git aptos --tag aptos-cli-v1.0.0
move 开发
1
2创建项目
mkdir hello-aptos && cd hello-aptos && aptos move init --name hello-aptos1
2初始化 rpc 以及 account
aptos init1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46// sources/hello_aptos.move
module hello_aptos::message3 {
use std::error;
use std::signer;
use std::string;
use aptos_framework::account;
use aptos_framework::event;
struct MessageHolder has key {
message: string::String,
message_change_events: event::EventHandle<MessageChangeEvent>,
}
//<:!:resource
struct MessageChangeEvent has drop, store {
from_message: string::String,
to_message: string::String,
}
const ENO_MESSAGE: u64 = 0;
public fun get_message(addr: address): string::String acquires MessageHolder {
assert!(exists<MessageHolder>(addr), error::not_found(ENO_MESSAGE));
*&borrow_global<MessageHolder>(addr).message
}
public entry fun set_message(account: signer, message: string::String)
acquires MessageHolder {
let account_addr = signer::address_of(&account);
if (!exists<MessageHolder>(account_addr)) {
move_to(&account, MessageHolder {
message,
message_change_events: account::new_event_handle<MessageChangeEvent>(&account),
})
} else {
let old_message_holder = borrow_global_mut<MessageHolder>(account_addr);
let from_message = *&old_message_holder.message;
event::emit_event(&mut old_message_holder.message_change_events, MessageChangeEvent {
from_message,
to_message: copy message,
});
old_message_holder.message = message;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27// tests/hello_aptos_test.move
#[test_only]
module hello_aptos::message_tests {
use std::signer;
use std::unit_test;
use std::vector;
use std::string;
use hello_aptos::message3;
fun get_account(): signer {
vector::pop_back(&mut unit_test::create_signers_for_testing(1))
}
#[test]
public entry fun sender_can_set_message() {
let account = get_account();
let addr = signer::address_of(&account);
aptos_framework::account::create_account_for_test(addr);
message3::set_message(account, string::utf8(b"Hello, Aptos"));
assert!(
message3::get_message(addr) == string::utf8(b"Hello, Aptos"),
0
);
}
}1
2
3
4
5
6
7
8
9
10
11
12[package]
name = 'hello-aptos'
version = '1.0.0'
[dependencies.AptosFramework]
git = 'https://github.com/aptos-labs/aptos-core.git'
rev = 'main'
subdir = 'aptos-move/framework/aptos-framework'
[addresses]
hello_aptos = "0x000b2e79cbfbf4bb872769c53fae1827f460016893aafb678c90fa2437ae6c96"
aptos_framwork= "0x1"1
aptos move test
1
aptos move publish --named-addresses hello_aptos=0x000b2e79cbfbf4bb872769c53fae1827f460016893aafb678c90fa2437ae6c96
1
2
3aptos move run \
--function-id 'default::message3::set_message' \
--args 'string:hello, atptos'1
curl --location --request GET 'https://fullnode.devnet.aptoslabs.com/v1/accounts/{YOUR_ACCOUNT}/resource/{YOUR_ACCOUNT}::message3::MessageHolder'
文献与代码
move/spec-lang.md at main · move-language/move · GitHub
GitHub - aptos-labs/aptos-core: A layer 1 for everyone!