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

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

用 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 应用吧!

参考

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
寻月隐君
寻月隐君
0xE91e...6bE5
不要放弃,如果你喜欢这件事,就不要放弃。如果你不喜欢,那这也不好,因为一个人不应该做自己不喜欢的事。