钱包
Wallet 管理 ed25519 密钥对、对消息进行签名,并可选地连接到 RPC 节点进行链上查询。
密钥管理
创建新钱包
use savitri_sdk::Wallet;
// 随机密钥对(密码学安全)
let wallet = Wallet::new();
println!("Address: {}", wallet.address()); // 64 hex chars (32-byte pubkey)
从私钥导入
// 从原始字节
let private_key: [u8; 32] = [/* your key */];
let wallet = Wallet::from_private_key(&private_key)?;
// 从十六进制字符串
let wallet = Wallet::from_private_key_hex("aabbccdd...64hexchars")?;
// 带 0x 前缀
let wallet = Wallet::from_private_key_hex("0xaabbccdd...64hexchars")?;
导出密钥
// 公钥(可安全分享)
let pubkey = wallet.public_key();
println!("Public key: {}", hex::encode(pubkey.as_bytes()));
// 地址(从公钥派生)
println!("Address: {}", wallet.address());
// 私钥(切勿分享或记录日志)
let privkey: [u8; 32] = wallet.private_key();
签名
对消息签名
let message = b"Hello, Savitri!";
let signature: [u8; 64] = wallet.sign_message(message);
验证签名
wallet.verify_signature(message, &signature)?;
// 有效返回 Ok(()),无效返回 Err
签名方案使用 Ed25519(ed25519-dalek)。对于交易签名,消息首先进行 SHA-256 哈希:
message = from_hex || to_hex || amount_le_u64 || nonce_le_u64 || fee_le_u128
hash = SHA-256(message)
sig = Ed25519_sign(hash)
RPC 集成
将钱包连接到节点以进行链上查询:
// 创建时带 RPC 连接
let wallet = Wallet::with_rpc("http://localhost:8545")?;
// 或稍后连接
let mut wallet = Wallet::new();
wallet.connect_rpc("http://localhost:8545")?;
// 查询余额(需要 RPC)
let balance: String = wallet.get_balance().await?;
println!("Balance: {}", balance);
// 查询 nonce(需要 RPC)
let nonce: u64 = wallet.get_nonce().await?;
println!("Nonce: {}", nonce);
// 访问底层 RPC 客户端
if let Some(rpc) = wallet.rpc() {
let height = rpc.get_block_number().await?;
println!("Height: {}", height);
}
安全性
- 清零机制:钱包被 drop 时,私钥材料会被清零(通过
zeroizecrate 实现Droptrait)。 - 克隆行为:克隆的钱包不继承 RPC 连接(初始为未连接状态)。
- 不持久化:钱包不会将密钥保存到磁盘。请使用自己的安全存储方案。
{
let wallet = Wallet::new();
// ... use wallet ...
} // wallet dropped here — private key bytes are zeroed in memory