02-Starcoin – STC 部署第一个合约
合约安装环境
git clone https://github.com/starcoinorg/starcoin-framework.git
cd starcoin-framework
bash scripts/dev_setup.sh -y
要科学上网。 有时可能因为网络原因失败。多执行几次
安装完成后。会有生效一个mpm的CLI
mpm
有输出为安装成功
move 环境安装
git clone https://github.com/move-language/move.git
cd move
bash scripts/dev_setup.sh
如果失败。尝试cargo build --release
然后在./target/release/下复制move move-analyzer到path目录
move
rust-analyzer
有输出为配置成功。ctrl+c 退出
编辑器配置
VSCODE
- https://marketplace.visualstudio.com/items?itemName=starcoinorg.starcoin-ide
- move-analyzer
- move
合约编写
创建合约
mpm package new my_info
cd my_info
code .
这里使用VSCODE打开
├── Move.toml
└── sources
└── my_info.move
默认情况下sources目录是空的。我们创建一个文件名为my_info.move的模块
module 0x2fe51c3d52c20c121f38a7765993e323::MyInfo{
}
执行 mpm package build
默认一个合约只有一个module可以使用。同时一个module可以use 其他module.
这里有一个钱包地址。是合约拥有者的地址。module是部署到这个钱包地址下。
同时move有resource这个概念。move是面向资源编程。同时每一个钱包地址都可以拥有无限个资源。
这里有两个概念。
- module 拥有合约bytecode中的function
- resource 拥有合约生命的resource
简单的例子。
将Token部署到 0x2fe51c3d52c20c121f38a7765993e323 是一个module。账户将token转账给另外一个账户的时候。
是将resource 结构体Copy到另外一个账户下。但这个账户并没有其他权限。只有一个resource .当调用合约是。是由0x2fe51c3d52c20c121f38a7765993e323 中的函数调用。获取到signer的address.通过address 借用到账户余额进行操作
编写合约
module MyInfo::MyInfo{
use StarcoinFramework::Signer;
struct Info has key,store{
id:u128,
age:u8,
}
fun init(account:&signer) {
let a = Info{
id:0,
age:0,
};
move_to(account,a);
}
fun info(account:&signer) acquires Info {
let info = borrow_global_mut<Info>(Signer::address_of(account));
info.id = info.id + 1;
info.age = info.age +1;
}
public(script) fun init_info(account: signer){
Self::init(&account);
}
public(script) fun set_info(account:signer) acquires Info{
Self::info(&account);
}
}
以上是参考官方的Couner例子改了一下。
有两个可执行函数。
init_info 给当前账户初始化resource
set_info 给当前合约resource 增加1
执行
mpm release 打包 release 包
account unlock #账户.
dev deploy /home/yusong/worker/move/my_info/release/my_info.v0.0.0.blob -b #部署合约
部署完成后我们先确认钱包当前资源
state list resource 0x2FE51c3D52C20c121f38a7765993e323
{
"ok": {
"resources": {
"0x00000000000000000000000000000001::Account::Account": {
"json": {
"accept_token_events": {
"counter": 1,
"guid": "0x02000000000000002fe51c3d52c20c121f38a7765993e323"
},
"authentication_key": "0x68e22ee67b665e8c9a59c134791668132fe51c3d52c20c121f38a7765993e323",
"deposit_events": {
"counter": 8,
"guid": "0x01000000000000002fe51c3d52c20c121f38a7765993e323"
},
"key_rotation_capability": {
"vec": [
{
"account_address": "0x2fe51c3d52c20c121f38a7765993e323"
}
]
},
"sequence_number": 5,
"withdraw_events": {
"counter": 4,
"guid": "0x00000000000000002fe51c3d52c20c121f38a7765993e323"
},
"withdrawal_capability": {
"vec": [
{
"account_address": "0x2fe51c3d52c20c121f38a7765993e323"
}
]
}
},
"raw": "0x2068e22ee67b665e8c9a59c134791668132fe51c3d52c20c121f38a7765993e323012fe51c3d52c20c121f38a7765993e323012fe51c3d52c20c121f38a7765993e32304000000000000001800000000000000002fe51c3d52c20c121f38a7765993e32308000000000000001801000000000000002fe51c3d52c20c121f38a7765993e32301000000000000001802000000000000002fe51c3d52c20c121f38a7765993e3230500000000000000"
},
"0x00000000000000000000000000000001::Account::AutoAcceptToken": {
"json": {
"enable": true
},
"raw": "0x01"
},
"0x00000000000000000000000000000001::Account::Balance<0x00000000000000000000000000000001::STC::STC>": {
"json": {
"token": {
"value": 1157990203293
}
},
"raw": "0x9d3f989d0d0100000000000000000000"
},
"0x00000000000000000000000000000001::Event::EventHandleGenerator": {
"json": {
"addr": "0x2fe51c3d52c20c121f38a7765993e323",
"counter": 3
},
"raw": "0x03000000000000002fe51c3d52c20c121f38a7765993e323"
}
}
}
}
目前我的账号是没有其他资源的。只有默认的资源。
account execute-function --function 0x2FE51c3D52C20c121f38a7765993e323::MyInfo::init_info -b
执行我们的init_info函数。初始化我们的资源给sender.这里没制定就是default 账户。
再次执行账号资源查看命令。可以看到输出多了一个节点。为我们的合约存储信息。
"0x2fe51c3d52c20c121f38a7765993e323::MyInfo::Info": {
"json": {
"age": 0,
"id": 0
},
"raw": "0x0000000000000000000000000000000000"
}
接着我们尝试给我所有变量加1.
account execute-function --function 0x2FE51c3D52C20c121f38a7765993e323::MyInfo::set_info -b
执行后的resource
"0x2fe51c3d52c20c121f38a7765993e323::MyInfo::Info": {
"json": {
"age": 1,
"id": 1
},
"raw": "0x0100000000000000000000000000000001"
}
增加部分功能
module MyInfo::NewMyInfo{
use StarcoinFramework::Signer;
struct Info has key,store{
id:u128,
age:u8,
}
fun init(account:&signer) {
let a = Info{
id:0,
age:0,
};
move_to(account,a);
}
fun sub(account:&signer) acquires Info{
let info = borrow_global_mut<Info>(Signer::address_of(account));
info.id = info.id + 1;
info.age = info.age +1;
}
fun add(account:&signer) acquires Info{
let info = borrow_global_mut<Info>(Signer::address_of(account));
info.id = info.id + 1;
info.age = info.age +1;
}
fun set(account:&signer,id:u128,age:u8) acquires Info {
let info = borrow_global_mut<Info>(Signer::address_of(account));
info.id = id;
info.age = age;
}
public(script) fun init_info(account: signer){
Self::init(&account);
}
public(script) fun set_info(account:signer,id:u128,age:u8) acquires Info{
Self::set(&account,id,age);
}
public(script) fun sub_info(account:signer) acquires Info {
Self::sub(&account);
}
public(script) fun add_info(account:signer) acquires Info {
Self::sub(&account);
}
}
将合约改了以下。增加了add,sub,set,三种方式。我们部署和测试以下。
注意合约名称变了。目前没有升级需求。如需升级老合约。请看这里。
https://starcoin.org/zh/developer/blog/starcoin_stdlib_upgrade/
执行初始化
account execute-function --function 0x2FE51c3D52C20c121f38a7765993e323::NewMyInfo::init_info -b
直接增加100
account execute-function --function 0x2FE51c3D52C20c121f38a7765993e323::NewMyInfo::set_info --arg 1u128 --arg 100u8 -b
--arg 执行参数。id=1u128 age=100u8
验证下结果。
"0x2fe51c3d52c20c121f38a7765993e323::MyInfo::Info": {
"json": {
"age": 1,
"id": 1
},
"raw": "0x0100000000000000000000000000000001"
},
"0x2fe51c3d52c20c121f38a7765993e323::NewMyInfo::Info": {
"json": {
"age": 100,
"id": 1
},
"raw": "0x0100000000000000000000000000000064"
}
看到有两个资源。一个资源是老合约一个是新合约。新合约的age =100 和我们设置的是一样的。现在我们尝试用新账号初始化这个合约。
account execute-function --function 0x2FE51c3D52C20c121f38a7765993e323::NewMyInfo::init_info -b -s 0xac96380a94dceca80739826f24083c8c
account execute-function --function 0x2FE51c3D52C20c121f38a7765993e323::NewMyInfo::set_info --arg 1u128 --arg 255u8 -b -s 0xac96380a94dceca80739826f24083c8c
"0x2fe51c3d52c20c121f38a7765993e323::NewMyInfo::Info": {
"json": {
"age": 255,
"id": 1
},
"raw": "0x01000000000000000000000000000000ff"
}
可以看到结果和之前验证的一样。也就是任何人都可以初始化这个module资源给自己。下一节为我们尝试部署一个标准token。
发表回复