Rust StarkNet插件库的使用:零知识证明与Layer2区块链开发的强大工具
Rust StarkNet插件库的使用:零知识证明与Layer2区块链开发的强大工具
简介
starknet-rs是一个完整的Rust语言Starknet库,提供了与Starknet Layer2区块链交互所需的各种功能。
注意:目前starknet-rs仍处于实验阶段,在第一个稳定版本发布前可能会有破坏性更改。该库目前也未经过安全审计,请谨慎使用。
功能特性
- ✅ Sequencer网关/feeder网关客户端
- ✅ 全节点JSON-RPC API客户端
- ✅ HTTP传输
- ✅ WebSocket传输(仅订阅)
- ✅ 智能合约部署
- ✅ 支持使用IAccount账户合约的签名器
- ✅ Ledger硬件钱包支持
安装
在项目中添加starknet-rs依赖:
[dependencies]
starknet = "0.15.1"
或者直接从GitHub获取最新版本:
[dependencies]
starknet = { git = "https://github.com/xJonathanLEI/starknet-rs" }
示例代码
示例1:从alpha-sepolia测试网获取最新区块
use starknet::providers::{Provider, JsonRpcClient};
use url::Url;
#[tokio::main]
async fn main() {
// 创建JSON-RPC客户端
let provider = JsonRpcClient::new(
Url::parse("https://alpha-sepolia.starknet.io").unwrap()
);
// 获取最新区块
let block = provider.get_block("latest").await.unwrap();
println!("Latest block: {:?}", block);
}
示例2:部署合约到alpha-sepolia测试网
use starknet::{
core::types::FieldElement,
providers::{Provider, JsonRpcClient},
signers::{LocalWallet, SigningKey},
contract::ContractFactory,
};
use url::Url;
#[tokio::main]
async fn main() {
// 创建JSON-RPC客户端
let provider = JsonRpcClient::new(
Url::parse("https://alpha-sepolia.starknet.io").unwrap()
);
// 创建钱包签名器
let signer = LocalWallet::from(SigningKey::from_hex("YOUR_PRIVATE_KEY").unwrap());
// 合约class hash和构造函数参数
let class_hash = FieldElement::from_hex_be("YOUR_CLASS_HASH").unwrap();
let constructor_args = vec![FieldElement::ONE];
// 创建合约工厂并部署
let factory = ContractFactory::new(class_hash, provider, signer);
let deployment = factory.deploy(&constructor_args).await.unwrap();
println!("Contract deployed at: 0x{:x}", deployment.address);
}
示例3:在alpha-sepolia上铸造1,000 TST代币
use starknet::{
core::types::FieldElement,
providers::{Provider, JsonRpcClient},
signers::{LocalWallet, SigningKey},
};
use url::Url;
#[tokio::main]
async fn main() {
// 创建JSON-RPC客户端
let provider = JsonRpcClient::new(
Url::parse("https://alpha-sepolia.starknet.io").unwrap()
);
// 创建钱包签名器
let signer = LocalWallet::from(SigningKey::from_hex("YOUR_PRIVATE_KEY").unwrap());
// TST代币合约地址和ABI
let token_address = FieldElement::from_hex_be("0xYOUR_TOKEN_ADDRESS").unwrap();
// 调用mint函数
let calldata = vec![
FieldElement::from_hex_be("YOUR_ACCOUNT_ADDRESS").unwrap(), // recipient
FieldElement::from_dec_str("1000000000000000000000").unwrap(), // amount (1,000 * 10^18)
FieldElement::ZERO // data
];
let result = provider
.execute(
token_address,
"mint", // function name
&calldata,
&signer
)
.await
.unwrap();
println!("Mint transaction hash: 0x{:x}", result.transaction_hash);
}
完整示例:完整的StarkNet合约交互流程
use starknet::{
core::types::{BlockId, BlockTag, FieldElement},
providers::{jsonrpc::HttpTransport, JsonRpcClient, Provider},
signers::{LocalWallet, SigningKey},
};
use url::Url;
#[tokio::main]
async fn main() {
// 1. 初始化JSON-RPC客户端
let rpc_url = Url::parse("https://alpha-sepolia.starknet.io").unwrap();
let provider = JsonRpcClient::new(HttpTransport::new(rpc_url));
// 2. 创建签名器
let private_key = "0x123456789abcdef..."; // 替换为你的私钥
let signer = LocalWallet::from(SigningKey::from_hex(private_key).unwrap());
// 3. 查询链上数据
let latest_block = provider
.get_block_with_txs(BlockId::Tag(BlockTag::Latest))
.await
.unwrap();
println!("Latest block number: {}", latest_block.block_number);
// 4. 与合约交互
let contract_address = FieldElement::from_hex_be("0x...").unwrap(); // 替换为合约地址
// 调用合约的balanceOf函数
let calldata = vec![
FieldElement::from_hex_be("0x...").unwrap(), // 查询的地址
];
let balance = provider
.call(
starknet::core::types::FunctionCall {
contract_address,
entry_point_selector: FieldElement::from_hex_be(
"0x02e4263afad30923c891518314c3c95dbe830a168f2d698e51a6a790a5e8c4d8",
)
.unwrap(), // balanceOf的选择器
calldata,
},
BlockId::Tag(BlockTag::Latest),
)
.await
.unwrap();
println!("Balance: {:?}", balance);
// 5. 发送交易
let transfer_calldata = vec![
FieldElement::from_hex_be("0x...").unwrap(), // 接收地址
FieldElement::from_dec_str("1000000000000000000").unwrap(), // 转账金额 (1 * 10^18)
FieldElement::ZERO,
];
let transfer_result = provider
.execute(
contract_address,
"transfer", // 函数名
&transfer_calldata,
&signer,
)
.await
.unwrap();
println!("Transfer tx hash: 0x{:x}", transfer_result.transaction_hash);
}
使用场景
starknet-rs非常适合以下开发场景:
- 构建Starknet Layer2 DApps
- 开发零知识证明相关应用
- 创建智能合约部署工具
- 开发钱包和签名服务
- 构建区块链数据分析工具
许可证
starknet-rs采用双许可证:
- Apache License 2.0
- MIT license
开发者可以根据需要选择其中一种。
1 回复
Rust StarkNet插件库的使用:零知识证明与Layer2区块链开发的强大工具
介绍
StarkNet是一个基于零知识证明的Layer2扩容解决方案,而Rust StarkNet插件库为开发者提供了在Rust环境中与StarkNet交互的强大工具集。这个库特别适合需要在StarkNet上构建去中心化应用(DApps)、智能合约或需要零知识证明功能的开发者。
主要特性
- 完整的StarkNet JSON-RPC API支持
- 零知识证明工具集成
- 合约部署和交互功能
- 交易签名和发送
- 账户管理
- 事件监听和处理
安装方法
在Cargo.toml中添加依赖:
[dependencies]
starknet = "0.1.0" # 请使用最新版本
基本使用方法
1. 连接到StarkNet网络
use starknet::providers::{Provider, JsonRpcProvider};
use url::Url;
async fn connect_to_starknet() {
let provider_url = Url::parse("https://starknet-mainnet.infura.io/v3/YOUR_API_KEY").unwrap();
let provider = JsonRpcProvider::new(provider_url);
// 获取当前区块号
let block_number = provider.block_number().await.unwrap();
println!("Current StarkNet block number: {}", block_number);
}
2. 部署智能合约
use starknet::contract::ContractFactory;
use starknet::accounts::SingleOwnerAccount;
use starknet::signers::LocalWallet;
async fn deploy_contract() {
let provider = JsonRpcProvider::new(/* 你的provider URL */);
let signer = LocalWallet::from_private_key("0x123...").unwrap();
let account = SingleOwnerAccount::new(provider, signer, "0xYourAddress".parse().unwrap());
let contract_artifact = /* 加载你的合约artifact */;
let factory = ContractFactory::new(contract_artifact, account);
let deployment = factory.deploy(vec![]).unwrap(); // 传入构造函数参数
let deployed_contract = deployment.send().await.unwrap();
println!("Contract deployed at: {}", deployed_contract.address());
}
3. 与合约交互
use starknet::contract::Contract;
use starknet::core::types::FieldElement;
async fn call_contract() {
let provider = JsonRpcProvider::new(/* 你的provider URL */);
let contract_address = "0xContractAddress".parse().unwrap();
let contract_abi = /* 加载你的合约ABI */;
let contract = Contract::new(contract_address, contract_abi, provider);
// 调用view函数
let result: FieldElement = contract.call("get_balance", vec![]).await.unwrap();
println!("Balance: {}", result);
// 执行交易
let signer = LocalWallet::from_private_key("0x123...").unwrap();
let account = SingleOwnerAccount::new(provider, signer, "0xYourAddress".parse().unwrap());
let contract = contract.with_account(account);
let tx = contract.invoke("transfer", vec![recipient, amount]).await.unwrap();
println!("Transaction hash: {}", tx.transaction_hash);
}
4. 使用零知识证明
use starknet::crypto::pedersen_hash;
use starknet::types::FieldElement;
fn zkp_example() {
// 计算Pedersen哈希 - StarkNet中常用的哈希函数
let a = FieldElement::from_hex_be("0x123").unwrap();
let b = FieldElement::from_hex_be("0x456").unwrap();
let hash = pedersen_hash(&a, &b);
println!("Pedersen hash: 0x{:x}", hash);
}
高级功能
事件监听
use starknet::core::types::{BlockId, EventFilter};
use futures::StreamExt;
async fn listen_to_events() {
let provider = JsonRpcProvider::new(/* 你的provider URL */);
let contract_address = "0xContractAddress".parse().unwrap();
let filter = EventFilter {
from_block: BlockId::Number(1000),
to_block: BlockId::Latest,
address: Some(contract_address),
keys: Some(vec![vec!["0xEventKey"].parse().unwrap()]]),
};
let mut event_stream = provider.get_events(filter).unwrap();
while let Some(event) = event_stream.next().await {
println!("New event: {:?}", event);
}
}
批量交易
use starknet::account::Execution;
async fn batch_transactions() {
let provider = /* 初始化provider */;
let account = /* 初始化account */;
let contract = Contract::new(/* 合约地址 */, /* ABI */, &account);
let execution = account
.execute(vec![
Execution::new("contract_method1", vec!["0x1".parse().unwrap()]),
Execution::new("contract_method2", vec!["0x2".parse().unwrap()]),
])
.unwrap();
let result = execution.send().await.unwrap();
println!("Batch transaction hash: {}", result.transaction_hash);
}
最佳实践
- 错误处理:始终正确处理可能出现的错误,StarkNet操作可能会因为网络问题或合约状态而失败
- Gas估算:在执行交易前估算gas,避免交易失败
- 测试网先行:先在测试网测试你的代码,再部署到主网
- 缓存结果:对频繁查询的数据考虑实现缓存机制
- 事件驱动:利用事件监听而不是轮询来构建响应式应用
完整示例代码
// 完整StarkNet交互示例
use starknet::{
providers::{JsonRpcProvider, Provider},
contract::{Contract, ContractFactory},
accounts::SingleOwnerAccount,
signers::LocalWallet,
core::types::{FieldElement, BlockId, EventFilter},
crypto::pedersen_hash,
};
use url::Url;
use futures::StreamExt;
#[tokio::main]
async fn main() {
// 1. 连接到StarkNet网络
let provider_url = Url::parse("https://starknet-mainnet.infura.io/v3/YOUR_API_KEY").unwrap();
let provider = JsonRpcProvider::new(provider_url);
// 获取网络状态
let block_number = provider.block_number().await.unwrap();
println!("Current StarkNet block number: {}", block_number);
// 2. 部署合约示例
let signer = LocalWallet::from_private_key("0x123...").unwrap();
let account = SingleOwnerAccount::new(
provider.clone(),
signer,
"0xYourAddress".parse().unwrap()
);
// 假设这是你的合约artifact
let contract_artifact = load_contract_artifact();
let factory = ContractFactory::new(contract_artifact, account.clone());
match factory.deploy(vec![]).unwrap().send().await {
Ok(deployed_contract) => {
println!("Contract deployed at: {}", deployed_contract.address());
// 3. 与合约交互
let contract = Contract::new(
deployed_contract.address(),
load_contract_abi(),
account.clone()
);
// 调用view函数
if let Ok(balance) = contract.call("get_balance", vec![]).await {
println!("Contract balance: {}", balance);
}
// 执行交易
let recipient = FieldElement::from_hex_be("0xabc").unwrap();
let amount = FieldElement::from_dec_str("100").unwrap();
if let Ok(tx) = contract.invoke("transfer", vec![recipient, amount]).await {
println!("Transfer transaction hash: {}", tx.transaction_hash);
}
// 4. 使用零知识证明功能
let a = FieldElement::from_hex_be("0x123").unwrap();
let b = FieldElement::from_hex_be("0x456").unwrap();
println!("Pedersen hash: 0x{:x}", pedersen_hash(&a, &b));
// 5. 监听事件
let filter = EventFilter {
from_block: BlockId::Number(block_number),
to_block: BlockId::Latest,
address: Some(deployed_contract.address()),
keys: Some(vec![vec!["0xEventKey".parse().unwrap()]]),
};
tokio::spawn(async move {
let mut events = provider.get_events(filter).unwrap();
while let Some(event) = events.next().await {
println!("New contract event: {:?}", event);
}
});
// 6. 批量交易示例
let execution = account.execute(vec![
Execution::new("method1", vec!["0x1".parse().unwrap()]),
Execution::new("method2", vec!["0x2".parse().unwrap()]),
]).unwrap();
if let Ok(result) = execution.send().await {
println!("Batch execution hash: {}", result.transaction_hash);
}
}
Err(e) => eprintln!("Contract deployment failed: {:?}", e),
}
}
// 辅助函数 - 实际项目中需要实现
fn load_contract_artifact() -> serde_json::Value {
unimplemented!()
}
fn load_contract_abi() -> starknet::core::abi::Abi {
unimplemented!()
}
这个完整示例展示了如何使用Rust StarkNet插件库进行完整的区块链交互流程,包括网络连接、合约部署、交互、事件监听和批量交易等功能。