Rust NEAR协议开发库near-workspaces的使用:简化NEAR区块链智能合约测试与交互
Rust NEAR协议开发库near-workspaces的使用:简化NEAR区块链智能合约测试与交互
NEAR Workspaces (Rust版本)
这是一个用于自动化NEAR智能合约工作流程和编写测试的Rust库。该软件尚未最终完成,可能会发生变化。
简单测试案例
一个简单的测试示例,帮助我们熟悉near-workspaces
框架。我们将通过NFT合约来展示如何使用near-workspaces-rs
进行测试。
设置 - 导入
首先,我们需要声明一些方便的导入:
// 允许我们将参数转换为合约可读取的JSON字节的宏
use serde_json::json;
我们需要预编译WASM合约并知道其路径。在这个示例中,我们将指向NFT合约示例:
const NFT_WASM_FILEPATH: &str = "./examples/res/non_fungible_token.wasm";
设置 - 启动Sandbox并部署NFT合约
这包括启动我们的sandbox,加载wasm文件并将该wasm文件部署到sandbox环境中。
#[tokio::test]
async fn test_nft_contract() -> anyhow::Result<()> {
let worker = near_workspaces::sandbox().await?;
let wasm = std::fs::read(NFT_WASM_FILEPATH)?;
let contract = worker.dev_deploy(&wasm).await?;
其中:
anyhow
- 处理错误处理的crate,使开发人员的错误处理更加健壮worker
- 我们与sandbox环境交互的网关contract
- 开发人员与之交互的部署在sandbox上的合约
初始化合约 & 测试输出
然后我们将直接调用合约,初始化NFT合约的元数据:
let outcome = contract
.call("new_default_meta")
.args_json(json!({
"owner_id": contract.id(),
}))
.transact() // 注意:我们在这里使用合约的密钥来签署交易
.await?;
// outcome包含日志、收据和交易结果等数据
println!("new_default_meta outcome: {:#?}", outcome);
接下来,让我们通过nft_mint
铸造一个NFT。这展示了一些我们可以提供的额外参数,如存款和gas:
use near_gas::NearGas;
use near_workspaces::types::NearToken;
let deposit = NearToken::from_near(100);
let outcome = contract
.call("nft_mint")
.args_json(json!({
"token_id": "0",
"token_owner_id": contract.id(),
"token_metadata": {
"title": "Olympus Mons",
"description": "Tallest mountain in charted solar system",
"copies": 1,
},
}))
.deposit(deposit)
// nft_mint可能消耗比默认gas更多的gas,所以提供我们自己的gas值:
.gas(NearGas::from_tgas(300))
.transact()
.await?;
println!("nft_mint outcome: {:#?}", outcome);
然后我们可以通过view
调用nft_metadata
来查看我们铸造的NFT的元数据:
let result: serde_json::Value = contract
.call("nft_metadata")
.view()
.await?
.json()?;
println!("--------------\n{}", result);
println!("Dev Account ID: {}", contract.id());
Ok(())
}
完整示例代码
以下是完整的NFT测试示例:
use serde_json::json;
use near_workspaces::types::NearToken;
use near_gas::NearGas;
const NFT_WASM_FILEPATH: &str = "./examples/res/non_fungible_token.wasm";
#[tokio::test]
async fn test_nft_contract() -> anyhow::Result<()> {
// 设置sandbox环境并部署合约
let worker = near_workspaces::sandbox().await?;
let wasm = std::fs::read(NFT_WASM_FILEPATH)?;
let contract = worker.dev_deploy(&wasm).await?;
// 初始化NFT合约
let outcome = contract
.call("new_default_meta")
.args_json(json!({
"owner_id": contract.id(),
}))
.transact()
.await?;
println!("new_default_meta outcome: {:#?}", outcome);
// 铸造NFT
let deposit = NearToken::from_near(100);
let outcome = contract
.call("nft_mint")
.args_json(json!({
"token_id": "0",
"token_owner_id": contract.id(),
"token_metadata": {
"title": "Olympus Mons",
"description": "Tallest mountain in charted solar system",
"copies": 1,
},
}))
.deposit(deposit)
.gas(NearGas::from_tgas(300))
.transact()
.await?;
println!("nft_mint outcome: {:#?}", outcome);
// 查看NFT元数据
let result: serde_json::Value = contract
.call("nft_metadata")
.view()
.await?
.json()?;
println!("--------------\n{}", result);
println!("Dev Account ID: {}", contract.id());
Ok(())
}
要运行上述NFT示例,执行:
cargo run --example nft
1 回复
Rust NEAR协议开发库near-workspaces使用指南
near-workspaces
是一个用于简化NEAR区块链智能合约测试与交互的Rust库,它提供了一套方便的API来与NEAR协议进行交互。
主要特性
- 简化本地测试环境设置
- 提供沙盒环境进行合约测试
- 支持与测试网和主网交互
- 方便的账户和合约管理
安装方法
在Cargo.toml中添加依赖:
[dependencies]
near-workspaces = "0.5"
tokio = { version = "1", features = ["full"] }
基本使用方法
1. 初始化工作区
use near_workspaces::Workspace;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 创建沙盒环境
let worker = near_workspaces::sandbox().await?;
// 或者连接测试网
// let worker = near_workspaces::testnet().await?;
Ok(())
}
2. 创建账户
let account = worker.dev_create_account().await?;
println!("Account ID: {}", account.id());
3. 部署合约
// 编译后的wasm合约路径
let wasm = std::path::PathBuf:: from("res/my_contract.wasm");
let contract = worker.dev_deploy(&std::fs::read(wasm)?).await?;
println!("Contract deployed at: {}", contract.id());
4. 调用合约方法
// 调用view方法
let result: String = contract
.view("get_greeting")
.args_json(serde_json::json!({}))
.await?
.json()?;
println!("Greeting: {}", result);
// 调用change方法
let outcome = contract
.call("set_greeting")
.args_json(serde_json::json!({"message": "Hello from workspaces!"}))
.transact()
.await?;
println!("Transaction outcome: {:?}", outcome);
高级功能
1. 批量交易
let outcome = contract
.batch(&worker)
.call(
"method1",
serde_json::json!({"param": "value"}),
)
.call(
"method2",
serde_json::json!({"param": 42}),
)
.transact()
.await?;
2. 模拟主网环境
let worker = near_workspaces::sandbox()
.rpc_addr("https://rpc.mainnet.near.org")
.await?;
3. 测试错误处理
let result = contract
.call("failing_method")
.args_json(serde_json::json!({}))
.transact()
.await;
assert!(result.is_err());
完整示例
use near_workspaces::Workspace;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 1. 初始化沙盒环境
let worker = near_workspaces::sandbox().await?;
// 2. 创建测试账户
let account = worker.dev_create_account().await?;
// 3. 部署合约
let wasm = std::path::PathBuf::from("res/hello_near.wasm");
let contract = worker.dev_deploy(&std::fs::read(wasm)?).await?;
// 4. 调用合约方法
let greeting: String = contract
.view("get_greeting")
.args_json(serde_json::json!({}))
.await?
.json()?;
println!("Initial greeting: {}", greeting);
// 5. 修改状态
let outcome = contract
.call("set_greeting")
.args_json(serde_json::json!({"message": "Hello Workspaces!"}))
.transact()
.await?;
println!("Transaction result: {:?}", outcome);
// 6. 验证修改
let new_greeting: String = contract
.view("get_greeting")
.args_json(serde_json::json!({}))
.await?
.json()?;
println!("Updated greeting: {}", new_greeting);
Ok(())
}
注意事项
- 需要Tokio运行时支持异步操作
- 测试时建议使用沙盒环境,速度快且无需真实代币
- 与主网交互时需要配置正确的RPC地址和账户凭据
- 合约方法调用时注意参数类型匹配
near-workspaces
大大简化了NEAR智能合约的测试流程,是开发NEAR DApp不可或缺的工具。