# 用 Rust 开发 Solana：解锁 Web3 交易费用计算


By [Paxon](https://paragraph.com/@paxon-2) · 2025-05-17

---

用 Rust 开发 Solana：解锁 Web3 交易费用计算
===============================

Web3 时代，Solana 以高性能低成本引领区块链开发！本文用 Rust 带你从零构建交易费用计算工具，连接本地节点、创建钱包、发送交易，快速掌握 Solana 开发。无论新手还是 Rust 爱好者，都能解锁 Web3 无限可能！

本文通过一个 Rust 开发的 Solana 客户端示例，展示如何快速构建 Web3 应用。内容包括项目初始化、依赖配置、连接本地 Solana 节点、创建钱包、请求空投 SOL，以及构造、模拟和发送含 Memo 的交易。代码简洁易懂，结合详细步骤和输出结果，助你快速估算交易费用和计算单元。适合想用 Rust 探索 Solana 和 Web3 开发的初学者与开发者。

交易费用计算原理
--------

在 Solana 区块链上，每笔交易都会消耗计算单元（Compute Units）并需支付以 lamports 为单位的手续费。交易费用的基础部分由交易包含的签名数量决定，每增加一个签名需支付 5000 lamports 的费用。了解这一机制，有助于开发者使用 Rust 高效构建 Web3 应用，优化交易成本并提升 Solana 网络的开发体验。

实操
--

### 创建项目

    cargo new solfeecalc
    
        Creating binary (application) `solfeecalc` package
    note: see more `Cargo.toml` keys and their definitions at *******************************************************
    cd solfeecalc
    
    ls
    Cargo.toml src
    cargo run
       Compiling solfeecalc v0.1.0 (/Users/qiaopengjun/Code/Solana/SolanaSandbox/solfeecalc)
        Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.56s
         Running `target/debug/solfeecalc`
    Hello, world!
    

### 安装项目依赖

    SolanaSandbox/solfeecalc on  main [?] is 📦 0.1.0 via 🦀 1.86.0 took 3.6s 
    ➜ cargo add anyhow  
    
    SolanaSandbox/solfeecalc on  main [?] is 📦 0.1.0 via 🦀 1.86.0 took 6.4s 
    ➜ cargo add tokio --features full
    
    SolanaSandbox/solfeecalc on  main [?] is 📦 0.1.0 via 🦀 1.86.0 
    ➜ cargo add solana-sdk
    
    SolanaSandbox/solfeecalc on  main [?] is 📦 0.1.0 via 🦀 1.86.0 took 6.5s 
    ➜ cargo add solana-client
    
    SolanaSandbox/solfeecalc on  main [?] is 📦 0.1.0 via 🦀 1.86.0 took 11.6s 
    ➜ cargo add spl-memo
    

### 查看项目目录结构

    SolanaSandbox/solfeecalc on  main [?] is 📦 0.1.0 via 🦀 1.86.0 
    ➜ tree . -L 6 -I "target|test-ledger"
    .
    ├── Cargo.lock
    ├── Cargo.toml
    └── src
        └── main.rs
    
    2 directories, 3 files
    

### 代码实现

    use solana_client::nonblocking::rpc_client::RpcClient;
    use solana_sdk::{
        commitment_config::CommitmentConfig, native_token::LAMPORTS_PER_SOL, signature::Keypair,
        signer::Signer, transaction::Transaction,
    };
    use spl_memo::build_memo;
    
    #[tokio::main]
    async fn main() -> anyhow::Result<()> {
        let client = RpcClient::new_with_commitment(
            String::from("http://127.0.0.1:8899"),
            CommitmentConfig::confirmed(),
        );
    
        let signer_keypair = Keypair::new();
        let memo = String::from("Memo message to be logged in this transaction");
    
        let memo_ix = build_memo(memo.as_bytes(), &[&signer_keypair.pubkey()]);
    
        let mut transaction = Transaction::new_with_payer(&[memo_ix], Some(&signer_keypair.pubkey()));
        transaction.sign(&[&signer_keypair], client.get_latest_blockhash().await?);
    
        let transaction_signature = client
            .request_airdrop(&signer_keypair.pubkey(), 5 * LAMPORTS_PER_SOL)
            .await?;
        loop {
            if client.confirm_transaction(&transaction_signature).await? {
                break;
            }
        }
    
        let estimated_units = estimate_cu_used(&client, &transaction).await?;
        println!("Transaction estimated to consumed {estimated_units} compute units");
    
        let tx_cost = client.get_fee_for_message(transaction.message()).await?;
        println!("Transaction signatures length: {}", transaction.signatures.len());
        println!("Transaction is estimated to cost {tx_cost} lamports");
    
        match client.send_and_confirm_transaction(&transaction).await {
            Ok(signature) => println!("Transaction Signature: {}", signature),
            Err(err) => eprintln!("Error sending transaction: {}", err),
        }
        Ok(())
    }
    
    async fn estimate_cu_used(client: &RpcClient, tx: &Transaction) -> anyhow::Result<u64> {
        let sim_res = client.simulate_transaction(tx).await?;
    
        let units_consumed = sim_res
            .value
            .units_consumed
            .expect("couldn't estimate CUs used");
    
        Ok(units_consumed)
    }
    

这段代码是一个用 Rust 编写的 Solana 客户端示例，主要功能是：

*   连接本地 Solana 节点
    
*   创建一个新钱包（Keypair）
    
*   请求空投 5 SOL 到该钱包
    
*   构造并模拟一笔带有 Memo 的交易，估算其消耗的计算单元（compute units）和手续费
    
*   发送并确认该交易
    

下面详细解释每一部分：

#### 1\. 依赖导入

    use solana_client::nonblocking::rpc_client::RpcClient;
    use solana_sdk::{
        commitment_config::CommitmentConfig, native_token::LAMPORTS_PER_SOL, signature::Keypair,
        signer::Signer, transaction::Transaction,
    };
    use spl_memo::build_memo;
    

*   引入了 Solana 客户端、SDK 相关模块，以及 SPL Memo 工具。
    

* * *

#### 2\. 主函数

    #[tokio::main]
    async fn main() -> anyhow::Result<()> {
        // 1. 创建 RPC 客户端，连接本地节点
        let client = RpcClient::new_with_commitment(
            String::from("http://127.0.0.1:8899"),
            CommitmentConfig::confirmed(),
        );
    
        // 2. 生成一个新的钱包密钥对
        let signer_keypair = Keypair::new();
    
        // 3. 构造 Memo 指令
        let memo = String::from("Memo message to be logged in this transaction");
        let memo_ix = build_memo(memo.as_bytes(), &[&signer_keypair.pubkey()]);
    
        // 4. 构造交易（只包含 Memo 指令），设置付款人
        let mut transaction = Transaction::new_with_payer(&[memo_ix], Some(&signer_keypair.pubkey()));
    
        // 5. 签名交易
        transaction.sign(&[&signer_keypair], client.get_latest_blockhash().await?);
    
        // 6. 请求空投 5 SOL 到新钱包
        let transaction_signature = client
            .request_airdrop(&signer_keypair.pubkey(), 5 * LAMPORTS_PER_SOL)
            .await?;
    
        // 7. 等待空投交易确认
        loop {
            if client.confirm_transaction(&transaction_signature).await? {
                break;
            }
        }
    
        // 8. 估算交易消耗的计算单元
        let estimated_units = estimate_cu_used(&client, &transaction).await?;
        println!("Transaction estimated to consumed {estimated_units} compute units");
    
        // 9. 查询交易手续费
        let tx_cost = client.get_fee_for_message(transaction.message()).await?;
        println!("Transaction is estimated to cost {tx_cost} lamports");
    
        // 10. 发送并确认交易
        match client.send_and_confirm_transaction(&transaction).await {
            Ok(signature) => println!("Transaction Signature: {}", signature),
            Err(err) => eprintln!("Error sending transaction: {}", err),
        }
        Ok(())
    }
    

#### 3\. 估算计算单元的辅助函数

    async fn estimate_cu_used(client: &RpcClient, tx: &Transaction) -> anyhow::Result<u64> {
        let sim_res = client.simulate_transaction(tx).await?;
    
        let units_consumed = sim_res
            .value
            .units_consumed
            .expect("couldn't estimate CUs used");
    
        Ok(units_consumed)
    }
    

*   用于模拟交易，返回消耗的计算单元（compute units）。
    

#### 总结

这段代码的主要流程是：

1.  连接本地 Solana 节点。
    
2.  创建新钱包并请求空投。
    
3.  构造带 Memo 的交易，模拟并估算其资源消耗和手续费。
    
4.  发送并确认交易，输出交易签名。
    

### 启动本地节点

    SolanaSandbox/solfeecalc on  main [?] is 📦 0.1.0 via 🦀 1.86.0 took 5.2s 
    ➜ solana-test-validator
    Ledger location: test-ledger
    Log: test-ledger/validator.log
    ⠤ Initializing...                                                                                                        Waiting for fees to stabilize 1...
    Identity: pjzkQFXWQg6YuiowupiWZYtTQDb62ypyYAwCVZ9kgLS
    Genesis Hash: 82cxWMZD15FZWY6CBgSc4k5wpdwPu81jD4ALKYDqVngY
    Version: 2.1.21
    Shred Version: 32306
    Gossip Address: 127.0.0.1:1024
    TPU Address: 127.0.0.1:1027
    JSON RPC URL: http://127.0.0.1:8899
    WebSocket PubSub URL: ws://127.0.0.1:8900
    ⠚ 00:00:16 | Processed Slot: 32 | Confirmed Slot: 32 | Finalized Slot: 1 | Full Snapshot Slot: - | Incremental Snapshot Slo
    

### 构建项目

    SolanaSandbox/solfeecalc on  main [?] is 📦 0.1.0 via 🦀 1.86.0 took 3.7s 
    ➜ cargo build
        Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.66s
    

### 运行项目

    SolanaSandbox/solfeecalc on  main [?] is 📦 0.1.0 via 🦀 1.86.0 
    ➜ cargo run  
        Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.20s
         Running `target/debug/solfeecalc`
    Transaction estimated to consumed 31276 compute units
    Transaction signatures length: 1
    Transaction is estimated to cost 5000 lamports
    Transaction Signature: EZUcNbzKmwp7UkVUETmoy2CSXkV6y1SQvvMsy6QCycs69UutV4WvyZwG4T6vS1xc8KN645GGnqH7ab2FfHUQWrR
    

总结
--

通过 Rust 和 Solana SDK，本文展示了一个简单却实用的 Web3 交易费用计算工具的开发全流程。从搭建本地节点到发送交易，你不仅学会了 Solana 的核心开发技能，还能为更复杂的去中心化应用奠定基础。无论你是想探索 Web3 的新手，还是追求高效开发的 Rust 开发者，这篇实战指南都能让你快速上手 Solana，解锁区块链开发的无限可能！快来动手试试，打造你的第一个 Solana 应用吧！

参考
--

*   [https://solana.com/zh/developers/cookbook/transactions/calculate-cost](https://solana.com/zh/developers/cookbook/transactions/calculate-cost)
    
*   [https://docs.rs/spl-memo/latest/spl\_memo/](https://docs.rs/spl-memo/latest/spl_memo/)
    
*   [https://crates.io/crates/spl-memo](https://crates.io/crates/spl-memo)
    
*   [https://github.com/solana-labs/solana-program-library](https://github.com/solana-labs/solana-program-library)

---

*Originally published on [Paxon](https://paragraph.com/@paxon-2/rust-solana-web3)*
