Aptos: 第一个 Move 智能合约
昨天刚刚上手 Aptos,部署一个 move 合约测试测试,结果调用合约时总不成功,今天晚上再次测试成功调用,记录一下详细过程。
-
首先安装 aptos-cli,预编译二进制 下载地址 ✈️
-
创建新账号,选择
devnet
(默认)会自动领取水龙头aptos init
-
创建项目文件夹
mkdir -p learn-move/sources && cd learn-move
-
在文件夹中创建文件
Move.toml
,文件内容如下[package] name = "TestCoin" version = "0.0.1" [dependencies] AptosFramework = { git = "https://github.com/aptos-labs/aptos-core.git", subdir = "aptos-move/framework/aptos-framework/", rev = "devnet" } MoveStdlib = { git = "https://github.com/aptos-labs/aptos-core.git", subdir = "aptos-move/framework/move-stdlib", rev = "devnet" } [addresses] NBCOIN = '_'
-
在
sources
文件夹中创建智能合约文件TestCoin.move
,内容如下module NBCOIN::TestCoin{ use std::signer; use std::string; struct Coin has store { value : u128, } struct CoinStore has key { coin : Coin, } struct CoinInfo has key { // name name: string::String, // symbol symbol: string::String, // decimals decimals: u8, // suppley supply: u128, // capcity cap: u128, } /// Address of the owner of this module const MODULE_OWNER: address = @NBCOIN; const THE_ACCOUNT_HAS_BEEN_REGISTERED : u64 = 1; const INVALID_TOKEN_OWNER : u64 = 2; const THE_ACCOUNT_IS_NOT_REGISTERED : u64 = 3; const INSUFFICIENT_BALANCE : u64 = 4; const ECOIN_INFO_ALREADY_PUBLISHED : u64 = 5; const EXCEEDING_THE_TOTAL_SUPPLY : u64 = 6; public fun getBalance(owner: address) : u128 acquires CoinStore{ assert!(is_account_registered(owner), THE_ACCOUNT_IS_NOT_REGISTERED); borrow_global<CoinStore>(owner).coin.value } public fun is_account_registered(account_addr : address) : bool{ exists<CoinStore>(account_addr) } fun deposit(account_addr : address, coin : Coin) acquires CoinStore { assert!(is_account_registered(account_addr), THE_ACCOUNT_IS_NOT_REGISTERED); let balance = getBalance(account_addr); let balance_ref = &mut borrow_global_mut<CoinStore>(account_addr).coin.value; *balance_ref = balance + coin.value; let Coin { value:_ } = coin; } fun withdraw(account_addr : address, amount : u128) : Coin acquires CoinStore { assert!(is_account_registered(account_addr), THE_ACCOUNT_IS_NOT_REGISTERED); let balance = getBalance(account_addr); assert!(balance >= amount, INSUFFICIENT_BALANCE); let balance_ref = &mut borrow_global_mut<CoinStore>(account_addr).coin.value; *balance_ref = balance - amount; Coin { value: amount } } public entry fun initialize(address : &signer, name : string::String, symbol : string::String, decimals : u8, supply : u128) { assert!(signer::address_of(address) == MODULE_OWNER, INVALID_TOKEN_OWNER); assert!(!exists<CoinInfo>(MODULE_OWNER), ECOIN_INFO_ALREADY_PUBLISHED); move_to(address, CoinInfo{name : name, symbol : symbol, decimals, supply, cap : 0}); } public entry fun register(address : &signer) { let account = signer::address_of(address); assert!(!exists<CoinStore>(account), THE_ACCOUNT_HAS_BEEN_REGISTERED); move_to(address, CoinStore{ coin : Coin{ value : 0 } }); } public entry fun mint(owner : &signer,to : address,amount : u128) acquires CoinStore,CoinInfo{ assert!(signer::address_of(owner) == MODULE_OWNER, INVALID_TOKEN_OWNER); assert!(borrow_global<CoinInfo>(MODULE_OWNER).cap + amount <= borrow_global<CoinInfo>(MODULE_OWNER).supply,EXCEEDING_THE_TOTAL_SUPPLY); deposit(to, Coin { value : amount }); let cap = &mut borrow_global_mut<CoinInfo>(MODULE_OWNER).cap; *cap = *cap + amount; } public entry fun transfer(from : &signer, to : address, amount : u128) acquires CoinStore { let coin = withdraw(signer::address_of(from), amount); deposit(to, coin); } public entry fun burn(owner : &signer, amount : u128) acquires CoinStore,CoinInfo { assert!(signer::address_of(owner) == MODULE_OWNER, INVALID_TOKEN_OWNER); let coin = withdraw(signer::address_of(owner), amount); let Coin { value: amount } = coin; let cap = &mut borrow_global_mut<CoinInfo>(MODULE_OWNER).cap; *cap = *cap - amount; let supply = &mut borrow_global_mut<CoinInfo>(MODULE_OWNER).supply; *supply = *supply - amount; } }
-
编译合约
aptos move compile --named-addresses NBCOIN=default
-
部署合约
aptos move publish --named-addresses NBCOIN=default
-
初始化 TestCoin
aptos move run \ --function-id 'default::TestCoin::initialize' \ --args 'string:NBCOIN' 'string:NBC' u8:8 u128:1000000
-
将默认账户注册到 TestCoin
aptos move run \ --function-id 'default::TestCoin::register'
-
为默认账户 mint 一些代币
aptos move run \ --function-id 'default::TestCoin::mint' \ --args address:default u128:1000000
-
创建新账户
a2
(使用devnet
,会自动领水龙头)aptos init --profile a2
-
给
a2
账户注册aptos move run \ --profile a2 \ --function-id 'default::TestCoin::register'
-
使用
default
账户给a2
转账aptos move run \ --function-id 'default::TestCoin::transfer' \ --args address:a2 u128:10000
全流程结束 ~