RPC 示例
使用 curl 和 Savitri SDK 的实际示例。
curl 示例
健康检查
curl -s -X POST http://localhost:8545/rpc \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"savitri_health","params":[],"id":1}'
获取区块高度
curl -s -X POST http://localhost:8545/rpc \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"savitri_blockNumber","params":[],"id":1}'
按高度获取区块
curl -s -X POST http://localhost:8545/rpc \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"savitri_getBlockByHeight","params":[42],"id":1}'
获取账户
curl -s -X POST http://localhost:8545/rpc \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"savitri_getAccount","params":["aabbccdd...64hexchars"],"id":1}'
提交交易
curl -s -X POST http://localhost:8545/rpc \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"savitri_sendRawTransaction","params":["signed_tx_hex"],"id":1}'
水龙头领取
curl -s -X POST http://localhost:8545/rpc \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"savitri_faucetClaim","params":["your_address_hex"],"id":1}'
PoU 状态
# 本地分数
curl -s -X POST http://localhost:8545/rpc \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"savitri_pouLocal","params":[],"id":1}'
# 所有节点
curl -s -X POST http://localhost:8545/rpc \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"savitri_pouPeers","params":[],"id":1}'
批量请求
curl -s -X POST http://localhost:8545/rpc \
-H "Content-Type: application/json" \
-d '[
{"jsonrpc":"2.0","method":"savitri_blockNumber","params":[],"id":1},
{"jsonrpc":"2.0","method":"savitri_health","params":[],"id":2},
{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":3}
]'
SDK 示例
监控区块生产
use savitri_sdk::RpcClient;
use std::time::Duration;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = RpcClient::from_url("http://localhost:8545")?;
let mut last_height = 0u64;
loop {
let height = client.get_block_number().await?;
if height > last_height {
let block = client.get_block_by_height(height).await?;
println!(
"Block #{}: {} TXs, proposer: {}...{}",
height,
block.transaction_count,
&block.proposer[..8],
&block.proposer[56..]
);
last_height = height;
}
tokio::time::sleep(Duration::from_secs(1)).await;
}
}
余额检查后转账
use savitri_sdk::{RpcClient, Wallet, TransactionBuilder};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = RpcClient::from_url("http://localhost:8545")?;
let wallet = Wallet::from_private_key_hex("your_key")?;
// 先检查余额
let account = client.get_account(wallet.address()).await?;
let balance: u128 = account.balance.parse()?;
let transfer_amount: u128 = 1_000_000_000_000_000_000; // 1 SAVT
let fee: u128 = 1_000_000_000_000_000; // 0.001 SAVT
if balance < transfer_amount + fee {
println!("Insufficient balance: {} < {}", balance, transfer_amount + fee);
return Ok(());
}
let tx = TransactionBuilder::new()
.to("recipient_address_64hex")
.value(transfer_amount)
.nonce(account.nonce)
.fee(fee)
.build_and_sign(&wallet)?;
// Serialize and send (simplified)
println!("Transaction built, nonce: {}", account.nonce);
Ok(())
}
多节点健康仪表板
use savitri_sdk::RpcClient;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let nodes = vec![
("MN-1", "http://localhost:5021"),
("MN-2", "http://localhost:5022"),
("LN-1", "http://localhost:5001"),
("LN-2", "http://localhost:5002"),
];
for (name, url) in &nodes {
match RpcClient::from_url(*url) {
Ok(client) => {
match client.health().await {
Ok(h) => println!("{}: {} ({})", name, h.status, h.mode),
Err(e) => println!("{}: OFFLINE ({})", name, e),
}
}
Err(e) => println!("{}: ERROR ({})", name, e),
}
}
Ok(())
}
追踪 PoU 分数
use savitri_sdk::RpcClient;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let client = RpcClient::from_url("http://localhost:8545")?;
let pou = client.pou_local().await?;
println!("My PoU score: {:?}", pou.local_score);
println!("Leader: {:?}", pou.leader);
println!("Am I leader: {}", pou.local_is_leader);
let peers = client.pou_peers().await?;
let mut scores: Vec<_> = peers.peers.iter().collect();
scores.sort_by(|a, b| b.1.cmp(a.1));
println!("\nPeer Rankings:");
for (i, (peer, score)) in scores.iter().enumerate() {
println!(" {}. {} (score: {})", i + 1, &peer[..16], score);
}
Ok(())
}