Rust区块链开发库starknet-signers的使用,StarkNet签名工具库提供安全的以太坊账户签名功能

Rust区块链开发库starknet-signers的使用

安装

在您的项目目录中运行以下Cargo命令:

cargo add starknet-signers

或者在Cargo.toml中添加:

starknet-signers = "0.13.0"

基本使用示例

use starknet_signers::{LocalWallet, Signer};
use starknet_core::types::FieldElement;

#[tokio::main]
async fn main() {
    // 创建本地钱包
    let private_key = FieldElement::from_hex_be("YOUR_PRIVATE_KEY_HEX").unwrap();
    let wallet = LocalWallet::from(private_key);
    
    // 准备要签名的消息
    let message = FieldElement::from_hex_be("MESSAGE_HEX").unwrap();
    
    // 签名
    let signature = wallet.sign(&message).await.unwrap();
    
    println!("Signature: {:?}", signature);
}

完整示例

use starknet_signers::{LocalWallet, Signer};
use starknet_core::types::{FieldElement, transaction::DeclareTransaction};
use starknet_providers::Provider;

#[tokio::main]
async fn main() {
    // 1. 设置私钥和钱包
    let private_key = FieldElement::from_hex_be("0x123...").unwrap();
    let wallet = LocalWallet::from(private_key);
    
    // 2. 创建交易
    let declare_transaction = DeclareTransaction {
        class_hash: FieldElement::from_hex_be("0x456...").unwrap(),
        sender_address: FieldElement::from_hex_be("0x789...").unwrap(),
        nonce: FieldElement::ZERO,
        max_fee: FieldElement::from_hex_be("0xDEADBEEF").unwrap(),
        signature: vec![], // 签名将在后面添加
        compiled_class_hash: None,
        contract_class: None,
    };
    
    // 3. 计算交易哈希
    let chain_id = FieldElement::from_hex_be("SN_MAIN").unwrap();
    let transaction_hash = declare_transaction.calculate_hash(&chain_id);
    
    // 4. 签名交易
    let signature = wallet.sign(&transaction_hash).await.unwrap();
    
    // 5. 添加签名到交易
    let signed_transaction = DeclareTransaction {
        signature: signature.to_vec(),
        ..declare_transaction
    };
    
    // 6. 发送交易到StarkNet网络
    // let provider = /* 初始化Provider */;
    // let result = provider.add_declare_transaction(&signed_transaction).await.unwrap();
    
    println!("Signed transaction with hash: 0x{:x}", transaction_hash);
}

完整示例demo

下面是一个更完善的示例,展示如何完整使用starknet-signers进行交易签名和发送:

use starknet_signers::{LocalWallet, Signer};
use starknet_core::types::{
    FieldElement, 
    transaction::{DeclareTransaction, BroadcastedDeclareTransaction}
};
use starknet_providers::{
    Provider, 
    jsonrpc::{HttpTransport, JsonRpcClient}
};
use url::Url;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 初始化钱包
    let private_key = FieldElement::from_hex_be("0x123...")?;
    let wallet = LocalWallet::from(private_key);
    
    // 2. 准备交易参数
    let class_hash = FieldElement::from_hex_be("0x456...")?;
    let sender_address = FieldElement::from_hex_be("0x789...")?;
    let max_fee = FieldElement::from_hex_be("0x100000")?;
    
    // 3. 创建声明交易
    let declare_transaction = DeclareTransaction {
        class_hash,
        sender_address,
        nonce: FieldElement::ZERO,
        max_fee,
        signature: vec![],
        compiled_class_hash: None,
        contract_class: None,
    };
    
    // 4. 计算交易哈希并签名
    let chain_id = FieldElement::from_hex_be("SN_MAIN")?;
    let transaction_hash = declare_transaction.calculate_hash(&chain_id);
    let signature = wallet.sign(&transaction_hash).await?;
    
    // 5. 构建已签名的交易
    let signed_transaction = DeclareTransaction {
        signature: signature.to_vec(),
        ..declare_transaction
    };
    
    // 6. 准备广播交易
    let broadcasted_tx = BroadcastedDeclareTransaction {
        sender_address: signed_transaction.sender_address,
        max_fee: signed_transaction.max_fee,
        signature: signed_transaction.signature,
        nonce: signed_transaction.nonce,
        contract_class: None, // 实际使用时需要提供
        compiled_class_hash: None, // 实际使用时需要提供
    };
    
    // 7. 初始化Provider并发送交易
    let rpc_url = Url::parse("https://starknet-mainnet.infura.io/v3/YOUR_API_KEY")?;
    let provider = JsonRpcClient::new(HttpTransport::new(rpc_url));
    
    // 8. 发送交易 (实际使用时取消注释)
    // let result = provider.add_declare_transaction(&broadcasted_tx).await?;
    // println!("Transaction result: {:?}", result);
    
    println!("Successfully signed transaction with hash: 0x{:x}", transaction_hash);
    Ok(())
}

特性

  • 支持本地钱包签名
  • 与starknet-rs生态系统无缝集成
  • 提供安全的以太坊账户签名功能
  • 支持交易哈希计算和签名

许可证

starknet-signers采用双许可证:

  • MIT许可证
  • Apache-2.0许可证

您可以根据需要选择其中一种许可证。


1 回复

Rust区块链开发库starknet-signers的使用指南

完整示例demo

下面是一个完整的示例项目,展示了如何使用starknet-signers库进行密钥管理、消息签名和验证:

Cargo.toml

[package]
name = "starknet_signer_demo"
version = "0.1.0"
edition = "2021"

[dependencies]
starknet-signers = "0.2.0"
starknet-core = "0.5.0"
tokio = { version = "1.0", features = ["full"] }
dotenv = "0.15.0"

src/wallet.rs

use starknet_signers::{LocalWallet, SigningKey, VerifyingKey};
use starknet_core::types::FieldElement;
use std::env;

pub struct StarkNetWallet {
    pub wallet: LocalWallet,
    pub verifying_key: VerifyingKey,
}

impl StarkNetWallet {
    // 从环境变量加载私钥创建钱包
    pub fn from_env() -> Self {
        let private_key = env::var("PRIVATE_KEY")
            .expect("PRIVATE_KEY must be set in .env file");
        let private_key = FieldElement::from_hex_be(&private_key)
            .expect("Invalid private key format");
        
        let signing_key = SigningKey::from_secret_scalar(private_key);
        let wallet = LocalWallet::from(signing_key);
        let verifying_key = wallet.get_verifying_key();
        
        StarkNetWallet { wallet, verifying_key }
    }

    // 生成新的随机钱包
    pub fn generate_random() -> Self {
        let signing_key = SigningKey::from_random();
        let wallet = LocalWallet::from(signing_key);
        let verifying_key = wallet.get_verifying_key();
        
        StarkNetWallet { wallet, verifying_key }
    }

    // 获取公钥
    pub fn get_public_key(&self) -> FieldElement {
        self.wallet.get_public_key()
    }

    // 签名消息
    pub async fn sign_message(&self, message: &FieldElement) -> (FieldElement, FieldElement) {
        self.wallet.sign_message(message).await.unwrap()
    }

    // 验证签名
    pub fn verify_signature(
        &self,
        message: &FieldElement,
        signature: &(FieldElement, FieldElement)
    ) -> bool {
        self.verifying_key.verify(message, signature).unwrap()
    }
}

src/main.rs

mod wallet;

use wallet::StarkNetWallet;
use starknet_core::types::FieldElement;
use dotenv::dotenv;

#[tokio::main]
async fn main() {
    // 加载.env文件
    dotenv().ok();

    println!("=== StarkNet 签名器演示 ===");
    
    // 示例1: 从环境变量创建钱包
    println!("\n1. 从环境变量创建钱包:");
    let env_wallet = StarkNetWallet::from_env();
    let public_key = env_wallet.get_public_key();
    println!("公钥: 0x{}", hex::encode(public_key.to_bytes_be()));

    // 示例2: 生成随机钱包
    println!("\n2. 生成随机钱包:");
    let random_wallet = StarkNetWallet::generate_random();
    println!("新钱包公钥: 0x{}", hex::encode(random_wallet.get_public_key().to_bytes_be()));

    // 示例3: 签名和验证消息
    println!("\n3. 签名和验证消息:");
    let message = FieldElement::from_hex_be("0x123456789abcdef").unwrap();
    println!("原始消息: 0x{}", hex::encode(message.to_bytes_be()));
    
    let signature = env_wallet.sign_message(&message).await;
    println!("签名结果: (0x{}, 0x{})", 
        hex::encode(signature.0.to_bytes_be()),
        hex::encode(signature.1.to_bytes_be()));
    
    let is_valid = env_wallet.verify_signature(&message, &signature);
    println!("签名验证结果: {}", is_valid);
    
    // 示例4: 验证错误签名
    println!("\n4. 验证错误签名:");
    let fake_signature = (FieldElement::from(1u64), FieldElement::from(1u64));
    let is_valid = env_wallet.verify_signature(&message, &fake_signature);
    println!("错误签名验证结果: {}", is_valid);
}

.env 文件示例

PRIVATE_KEY=0x123456789abcdef123456789abcdef123456789abcdef123456789abcdef

项目结构说明

starknet_signer_demo/
├── .env                 # 存储私钥的环境变量文件
├── Cargo.toml          # 项目依赖配置
└── src/
    ├── main.rs         # 主程序入口
    └── wallet.rs       # 钱包管理模块

使用说明

  1. 创建.env文件并设置你的私钥
  2. 运行cargo run执行示例程序
  3. 程序将演示:
    • 从环境变量加载私钥创建钱包
    • 生成随机钱包
    • 消息签名和验证
    • 错误签名验证

这个完整示例展示了starknet-signers库的核心功能,包括密钥管理、消息签名和验证,可以作为你StarkNet应用开发的起点。

回到顶部