跳到主要内容

钱包

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 时,私钥材料会被清零(通过 zeroize crate 实现 Drop trait)。
  • 克隆行为:克隆的钱包不继承 RPC 连接(初始为未连接状态)。
  • 不持久化:钱包不会将密钥保存到磁盘。请使用自己的安全存储方案。
{
let wallet = Wallet::new();
// ... use wallet ...
} // wallet dropped here — private key bytes are zeroed in memory