Rust StarkNet交互库starknet-providers的使用,支持与StarkNet区块链网络的高效通信和智能合约操作
Rust StarkNet交互库starknet-providers的使用
starknet-providers
是一个Rust库,用于与StarkNet节点和排序器进行交互,支持与StarkNet区块链网络的高效通信和智能合约操作。
安装
在你的项目目录中运行以下Cargo命令:
cargo add starknet-providers
或者在Cargo.toml中添加以下行:
starknet-providers = "0.15.0"
示例代码
以下是一个使用starknet-providers
与StarkNet网络交互的基本示例:
use starknet_providers::{Provider, JsonRpcProvider};
use starknet_core::types::FieldElement;
#[tokio::main]
async fn main() {
// 创建一个JSON-RPC provider连接到StarkNet测试网
let provider = JsonRpcProvider::new("https://starknet-testnet.public.blastapi.io");
// 获取最新的区块号
match provider.block_number().await {
Ok(block_number) => println!("Latest block number: {}", block_number),
Err(e) => eprintln!("Error getting block number: {}", e),
}
// 获取指定合约的存储值
let contract_address = FieldElement::from_hex_be("0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef").unwrap();
let key = FieldElement::from_hex_be("0x0").unwrap();
match provider.get_storage_at(contract_address, key).await {
Ok(value) => println!("Storage value: {}", value),
Err(e) => eprintln!("Error getting storage value: {}", e),
}
}
完整示例代码
以下是一个更完整的示例,展示如何使用starknet-providers
进行多种操作:
use starknet_providers::{Provider, JsonRpcProvider};
use starknet_core::types::{FieldElement, BlockId, BlockTag};
use std::str::FromStr;
#[tokio::main]
async fn main() {
// 初始化JSON-RPC provider
let provider = JsonRpcProvider::new("https://starknet-testnet.public.blastapi.io");
// 1. 获取链ID
match provider.chain_id().await {
Ok(chain_id) => println!("Chain ID: {}", chain_id),
Err(e) => eprintln!("Error getting chain ID: {}", e),
}
// 2. 获取最新区块信息
match provider.get_block_with_txs(BlockId::Tag(BlockTag::Latest)).await {
Ok(block) => println!("Latest block hash: {:?}", block.block_hash),
Err(e) => eprintln!("Error getting latest block: {}", e),
}
// 3. 查询合约存储
let contract_address = FieldElement::from_hex_be(
"0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
).unwrap();
let key = FieldElement::from_hex_be("0x0").unwrap();
match provider.get_storage_at(contract_address, key).await {
Ok(value) => println!("Storage value: {}", value),
Err(e) => eprintln!("Error getting storage value: {}", e),
}
// 4. 获取合约代码
match provider.get_class_hash_at(contract_address).await {
Ok(class_hash) => println!("Contract class hash: {}", class_hash),
Err(e) => eprintln!("Error getting contract class hash: {}", e),
}
// 5. 获取交易状态
let tx_hash = FieldElement::from_str("0x123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef").unwrap();
match provider.get_transaction_status(tx_hash).await {
Ok(status) => println!("Transaction status: {:?}", status),
Err(e) => eprintln!("Error getting transaction status: {}", e),
}
}
特性
- 支持JSON-RPC协议与StarkNet节点通信
- 提供基本的区块链操作如查询区块、交易和合约状态
- 支持智能合约交互
- 类型安全的API设计
许可证
该库采用MIT或Apache-2.0双许可证。
1 回复
Rust StarkNet交互库starknet-providers使用指南
starknet-providers
是一个用于与StarkNet区块链网络交互的Rust库,它提供了高效通信和智能合约操作的功能。
主要特性
- 支持与StarkNet节点的JSON-RPC通信
- 提供同步和异步API
- 支持智能合约部署和调用
- 支持账户抽象操作
- 提供交易状态查询功能
安装方法
在Cargo.toml中添加依赖:
[dependencies]
starknet-providers = "0.3"
tokio = { version = "1.0", features = ["full"] } # 如果需要异步支持
基本使用方法
1. 创建Provider
use starknet_providers::{JsonRpcClient, Provider};
// 连接到本地StarkNet节点
let provider = JsonRpcClient::new("http://localhost:9545");
2. 查询链信息
use starknet_providers::Provider;
let chain_id = provider.chain_id().await?;
println!("Chain ID: {}", chain_id);
let block_number = provider.block_number().await?;
println!("Current block number: {}", block_number);
3. 查询账户余额
use starknet_providers::Provider;
use starknet_core::types::FieldElement;
let account_address = FieldElement::from_hex_be("0x123...").unwrap();
let balance = provider.get_balance(account_address).await?;
println!("Account balance: {}", balance);
4. 调用智能合约
use starknet_providers::Provider;
use starknet_core::types::{FunctionCall, FieldElement};
let contract_address = FieldElement::from_hex_be("0x456...").unwrap();
let entry_point_selector = FieldElement::from_hex_be("0x789...").unwrap();
let call = FunctionCall {
contract_address,
entry_point_selector,
calldata: vec![], // 根据合约ABI填充
};
let result = provider.call(call, None).await?;
println!("Call result: {:?}", result);
5. 发送交易
use starknet_providers::Provider;
use starknet_core::types::{
BroadcastedInvokeTransaction, InvokeTransactionV1, FieldElement
};
let tx = BroadcastedInvokeTransaction::V1(InvokeTransactionV1 {
sender_address: FieldElement::from_hex_be("0xabc...").unwrap(),
calldata: vec![], // 根据交易内容填充
max_fee: FieldElement::from_dec_str("1000000").unwrap(),
signature: vec![], // 签名数据
nonce: FieldElement::ZERO,
});
let tx_hash = provider.add_invoke_transaction(tx).await?;
println!("Transaction hash: 0x{:x}", tx_hash);
异步API示例
use starknet_providers::{JsonRpcClient, Provider};
use starknet_core::types::FieldElement;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let provider = JsonRpcClient::new("https://starknet-mainnet.infura.io/v3/YOUR_API_KEY");
let block = provider.get_block_with_txs(BlockId::Number(12345)).await?;
println!("Block transactions: {:?}", block.transactions);
Ok(())
}
错误处理
match provider.get_block_with_txs(BlockId::Number(12345)).await {
Ok(block) => println!("Got block: {:?}", block),
Err(starknet_providers::ProviderError::StarknetError(error)) => {
eprintln!("StarkNet error: {}", error.message);
}
Err(e) => eprintln!("Other error: {}", e),
}
高级功能
批量请求
use starknet_providers::{Provider, JsonRpcClient};
use starknet_core::types::{BlockId, BlockTag};
let provider = JsonRpcClient::new("http://localhost:9545");
let batch = vec![
provider.get_block_with_txs(BlockId::Tag(BlockTag::Latest)),
provider.chain_id(),
provider.syncing(),
];
let results = futures::future::join_all(batch).await;
自定义HTTP客户端
use starknet_providers::{JsonRpcClient, Provider};
use reqwest::Client;
let http_client = Client::builder()
.timeout(std::time::Duration::from_secs(30))
.build()?;
let provider = JsonRpcClient::with_client(
"http://localhost:9545",
http_client,
);
注意事项
- 确保StarkNet节点版本与库兼容
- 处理交易时注意gas费用和nonce管理
- 生产环境建议使用重试机制处理暂时性错误
- 敏感操作(如私钥签名)应在安全环境中进行
完整示例代码
use starknet_providers::{JsonRpcClient, Provider};
use starknet_core::types::{
BlockId, BlockTag, FieldElement, FunctionCall,
BroadcastedInvokeTransaction, InvokeTransactionV1
};
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// 1. 初始化Provider
let provider = JsonRpcClient::new("http://localhost:9545");
// 2. 查询链信息
let chain_id = provider.chain_id().await?;
println!("Chain ID: {}", chain_id);
let block_number = provider.block_number().await?;
println!("Current block number: {}", block_number);
// 3. 查询账户余额
let account_address = FieldElement::from_hex_be("0x123...").unwrap();
let balance = provider.get_balance(account_address).await?;
println!("Account balance: {}", balance);
// 4. 调用智能合约
let contract_address = FieldElement::from_hex_be("0x456...").unwrap();
let entry_point_selector = FieldElement::from_hex_be("0x789...").unwrap();
let call = FunctionCall {
contract_address,
entry_point_selector,
calldata: vec![], // 根据合约ABI填充
};
let result = provider.call(call, None).await?;
println!("Call result: {:?}", result);
// 5. 发送交易
let tx = BroadcastedInvokeTransaction::V1(InvokeTransactionV1 {
sender_address: FieldElement::from_hex_be("0xabc...").unwrap(),
calldata: vec![], // 根据交易内容填充
max_fee: FieldElement::from_dec_str("1000000").unwrap(),
signature: vec![], // 签名数据
nonce: FieldElement::ZERO,
});
let tx_hash = provider.add_invoke_transaction(tx).await?;
println!("Transaction hash: 0x{:x}", tx_hash);
// 批量请求示例
let batch = vec![
provider.get_block_with_txs(BlockId::Tag(BlockTag::Latest)),
provider.chain_id(),
provider.syncing(),
];
let results = futures::future::join_all(batch).await;
println!("Batch results: {:?}", results);
Ok(())
}
这个库为Rust开发者提供了与StarkNet交互的完整工具集,可以方便地构建StarkNet上的去中心化应用。