Vara 入门实战

Vara 入门实战

安装

curl https://get.gear.rs/gear-v1.4.1-aarch64-apple-darwin.tar.xz | tar xJ
gear --version
gear 1.4.1-a25a431f157

入口函数

函数 作用 支持的操作
init 初始化状态 load, send, reply
handle 处理收到的消息 load, send, reply
handle_reply 处理收到的回复 load, send
state 查询状态(只读) load, reply

init

static mut STATE: Option<HashMap<ActorId, u128>> = None;

#[no_mangle]
extern fn init() {
    unsafe { STATE = Some(Default::default()) }
}

handle

#[no_mangle]
extern fn handle() {
    let payload = msg::load().expect("Failed to load payload");

    if let PingPong::Ping = payload {
        let pingers = unsafe { STATE.as_mut().expect("State isn't initialized") };

        pingers
            .entry(msg::source())
            .and_modify(|ping_count| *ping_count = ping_count.saturating_add(1))
            .or_insert(1);

        msg::reply(PingPong::Pong, 0).expect("Failed to reply from `handle()`");
    }
}

state

#[no_mangle]
extern fn state() {
    let state = unsafe { STATE.take().expect("State isn't initialized") };
    msg::reply(State::from_iter(state), 0).expect("Failed to reply from `state()`");
}

合约间的请求与回复

alt text

请求: A 发送消息 (init, handle) => B 接收消息 (handle)

回复: A 获取回复 (handle_reply) <= B 回复消息 (handle)

debug 合约

打印 debug 信息

  • gstd::debug!()
  • gstd::dbg!()

构建时启用 debug

cargo build

cargo build --release --features=debug

查看 debug 信息:

  • RUST_LOG="gwasm=debug" 启动本地节点
  • gtest 单元测试

参考

gtest 单元测试

gtest

是一个轻量级的测试框架,在链下环境模拟:

  • 合约
  • 用户
  • 余额
  • Mailbox
  • ...

引入 gtest 库

[dev-dependencies]
gtest = { version = "1.4.1" }

gtest 语法介绍

  • 初始化系统环境
  • 程序初始化
  • 发送消息
  • 处理执行结果
  • 日志 (Log) 处理
  • 时间控制
  • 余额管理

初始化系统环境

let sys = System::new();

程序初始化

let program = Program::from_file(
    &sys,
    "./target/wasm32-unknown-unknown/release/demo_ping.wasm",
);
let program_id = program.id();

发送消息

let res = program.send_bytes(100001, "INIT MESSAGE");

处理执行结果

assert!(res.log().is_empty());
assert!(!res.main_failed());

发送消息

let res = program.send_bytes(100001, "INIT MESSAGE");

处理执行结果

assert!(res.log().is_empty());
assert!(!res.main_failed());

日志 (Log) 处理

let expected_log = Log::builder()
    .source(ping_pong_id)
    .dest(100001)
    .payload_bytes("PONG");
assert!(res.contains(&expected_log));

assert!(!res.main_failed());

时间控制

sys.spend_blocks(150);

余额管理

sys.mint_to(42, 5000);
let prog = Program::current(&sys);
prog.mint(1000);

时间控制

sys.spend_blocks(150);

余额管理

sys.mint_to(42, 5000);
let prog = Program::current(&sys);
prog.mint(1000);

gclient 集成测试

gclient

gclient 是一个支持在链上对合约进行端到端测试的工具

  • 事件订阅
  • Gas 计算
  • 交易处理
  • 异步支持
  • ...

引入 gclient 库

[dev-dependencies]
gclient = { version = "1.4.1" }
tokio = { version = "1", features = ["full"] }

安装节点

# 检查节点版本与 gclient 一致
./gear --version

gclient 语法介绍

  • 创建 API 实例
  • 订阅事件
  • Gas 计算
  • 上传和初始化程序
  • 发送消息
  • 验证合约状态

创建 API 实例

// Create API instance
let api = GearApi::dev().await?;

订阅事件

let mut listener = api.subscribe().await?;
// Check that blocks are still running
assert!(listener.blocks_running().await?);

Gas 计算

// Calculate gas amount needed for initialization
let gas_info = api
    .calculate_upload_gas(
        None,
        gclient::code_from_os(WASM_PATH)?,
        vec![],
        0,
        true,
    )
    .await?;

let payload = b"inc".to_vec();

// Calculate gas amount needed for handling the message
let gas_info = api
    .calculate_handle_gas(None, program_id, payload.clone(), 0, true)
    .await?;

上传和初始化程序

// Upload and init the program
let (message_id, program_id, _hash) = api
    .upload_program_bytes_by_path(
        WASM_PATH,
        gclient::now_micros().to_le_bytes(),
        vec![],
        gas_info.min_limit,
        0,
    )
    .await?;
assert!(listener.message_processed(message_id).await?.succeed());

发送消息

// Send the inc message
let (message_id, _hash) = api
    .send_message_bytes(program_id, payload, gas_info.min_limit, 0)
    .await?;
assert!(listener.message_processed(message_id).await?.succeed());

验证合约状态

// Listen and verify the returned message
if let (message_id, result, value) = listener.reply_bytes_on(message_id).await? {
    if let Ok(data) = result {
        println!("Data: {:?}", data);
        assert_eq!(data, b"1");
    } else if let Err(error) = result {
        println!("Error: {:?}", error);
    }
}

开发环境搭建

安装

使用示例

# Vara Network Testnet
gear

# Vara Network Mainnet
gear --chain vara

# 生成地址
gear key generate

# 检查地址
gear key inspect

gear --help

Usage: gear [OPTIONS]
       gear &lt;COMMAND>

Commands:
  key            Key management cli utilities
  build-spec     Build a chain specification
  check-block    Validate blocks
  export-blocks  Export blocks
  export-state   Export the state of a given block into a chain spec
  import-blocks  Import blocks
  purge-chain    Remove the whole chain
  revert         Revert the chain to a previous state
  try-runtime    Try-runtime has migrated to a standalone CLI (&lt;https://github.com/paritytech/try-runtime-cli>). The subcommand exists as a stub and deprecation notice. It will be removed entirely some time after January 2024
  chain-info     Db meta columns information
  gcli           Run gear program cli.
  help           Print this message or the help of the given subcommand(s)

Options:
      --validator

编译构建模版合约

image-20240702104821464.png

查看build后的metadata和优化后的合约二进制并启动本地节点

image-20240702104931237.png

https://idea.gear-tech.io/programs?node=ws://localhost:9944

使用公共测试网

image-20240705164627458.png

使用Gear IDEA 部署合约

image-20240705165042491.png

计算交易gas费用

image-20240705165430062.png

点击上传合约

image-20240705165538230.png

查看部署后的合约

image-20240705165744557.png

查询合约详情

image-20240705170154810.png

开发者资源

参考

点赞 1
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
寻月隐君
寻月隐君
0x750E...B6f5
不要放弃,如果你喜欢这件事,就不要放弃。如果你不喜欢,那这也不好,因为一个人不应该做自己不喜欢的事。