Rust比特币开发工具包bdk_esplora的使用,与Esplora区块链API无缝集成实现高效交易查询和同步

Rust比特币开发工具包bdk_esplora的使用,与Esplora区块链API无缝集成实现高效交易查询和同步

BDK Esplora 概述

BDK Esplora扩展了esplora-client(通过扩展特性:EsploraExtEsploraAsyncExt)来从Esplora服务器更新bdk_chain结构。

这些扩展特性主要用于通过sync满足SyncRequest和通过full_scan满足FullScanRequest

使用方式

仅使用阻塞模式

bdk_esplora = { version = "0.19", features = ["blocking"] }

仅使用异步模式

bdk_esplora = { version = "0.19", features = ["async"] }

仅使用异步模式(带HTTPS)

可以额外指定使用rustls或native-tls,例如async-https-native,这适用于异步和阻塞特性。

bdk_esplora = { version = "0.19", features = ["async-https"] }

仅使用异步模式(带tokio)

bdk_esplora = { version = "0.19", features = ["async", "tokio"] }

使用扩展特性

// 用于阻塞模式
#[cfg(feature = "blocking")]
use bdk_esplora::EsploraExt;

// 用于异步模式
#[cfg(feature = "async")]
use bdk_esplora::EsploraAsyncExt;

完整示例代码

阻塞模式示例

use bdk_esplora::EsploraExt;
use bdk_chain::{Keychain, SpkClient};
use bitcoin::Network;

// 设置Esplora客户端
let client = esplora_client::Builder::new("https://blockstream.info/api")
    .build_blocking()
    .unwrap();

// 创建钱包
let mut wallet = Keychain::new(Network::Testnet);
let descriptor = "wpkh(tprv8ZgxMBicQKsPe.../0/*)";

// 同步钱包
let sync_request = wallet.sync_request();
client.sync(&sync_request).unwrap();

// 查询余额
let balance = wallet.balance();
println!("当前余额: {}", balance);

异步模式示例

use bdk_esplora::EsploraAsyncExt;
use bdk_chain::{Keychain, SpkClient};
use bitcoin::Network;

#[tokio::main]
async fn main() {
    // 设置Esplora客户端
    let client = esplora_client::Builder::new("https://blockstream.info/api")
        .build_async()
        .unwrap();

    // 创建钱包
    let mut wallet = Keychain::new(Network::Testnet);
    let descriptor = "wpkh(tprv8ZgxMBicQKsPe.../0/*)";

    // 同步钱包
    let sync_request = wallet.sync_request();
    client.sync(&sync_request).await.unwrap();

    // 查询余额
    let balance = wallet.balance();
    println!("当前余额: {}", balance);
}

完整Demo示例

以下是一个更完整的BDK Esplora使用示例,包含钱包创建、地址生成、交易查询等功能:

阻塞模式完整示例

use bdk_esplora::EsploraExt;
use bdk_chain::{Keychain, SpkClient, local_chain};
use bitcoin::{Network, Address};
use std::str::FromStr;

fn main() {
    // 1. 初始化Esplora客户端(使用测试网)
    let client = esplora_client::Builder::new("https://blockstream.info/testnet/api")
        .build_blocking()
        .expect("创建Esplora客户端失败");
    
    // 2. 创建钱包和密钥链
    let mut wallet = Keychain::new(Network::Testnet);
    let descriptor = "wpkh(tprv8ZgxMBicQKsPe.../0/*)"; // 替换为你的实际描述符
    
    // 3. 生成新地址
    let new_address = wallet.next_unused_spk().address();
    println!("新生成的接收地址: {}", new_address);
    
    // 4. 同步钱包状态
    let sync_request = wallet.sync_request();
    client.sync(&sync_request).expect("同步钱包失败");
    
    // 5. 查询余额和交易
    let balance = wallet.balance();
    println!("钱包余额: {} satoshis", balance.total());
    
    // 6. 查询特定地址的交易历史
    let address = Address::from_str("tb1q...").unwrap(); // 替换为你想查询的地址
    let transactions = client.get_address_txs(&address).expect("获取交易失败");
    println!("地址交易历史: {:?}", transactions);
    
    // 7. 广播交易(示例)
    let raw_tx = "0200000001..."; // 替换为你的原始交易数据
    client.broadcast(raw_tx).expect("广播交易失败");
}

异步模式完整示例

use bdk_esplora::EsploraAsyncExt;
use bdk_chain::{Keychain, SpkClient, local_chain};
use bitcoin::{Network, Address};
use std::str::FromStr;

#[tokio::main]
async fn main() {
    // 1. 初始化异步Esplora客户端
    let client = esplora_client::Builder::new("https://blockstream.info/testnet/api")
        .build_async()
        .expect("创建异步Esplora客户端失败");
    
    // 2. 创建钱包和密钥链
    let mut wallet = Keychain::new(Network::Testnet);
    let descriptor = "wpkh(tprv8ZgxMBicQKsPe.../0/*)"; // 替换为你的实际描述符
    
    // 3. 生成新地址
    let new_address = wallet.next_unused_spk().address();
    println!("新生成的接收地址: {}", new_address);
    
    // 4. 异步同步钱包状态
    let sync_request = wallet.sync_request();
    client.sync(&sync_request).await.expect("同步钱包失败");
    
    // 5. 查询余额
    let balance = wallet.balance();
    println!("钱包余额: {} satoshis", balance.total());
    
    // 6. 异步查询交易历史
    let address = Address::from_str("tb1q...").unwrap(); // 替换为你想查询的地址
    let transactions = client.get_address_txs(&address).await.expect("获取交易失败");
    println!("地址交易历史: {:?}", transactions);
    
    // 7. 异步广播交易
    let raw_tx = "0200000001..."; // 替换为你的原始交易数据
    client.broadcast(raw_tx).await.expect("广播交易失败");
}

这些示例展示了BDK Esplora的核心功能,包括:

  • 与Esplora区块链API的无缝集成
  • 钱包同步和状态更新
  • 地址生成和交易查询
  • 交易广播功能

根据您的应用场景选择合适的模式(阻塞或异步),并确保正确配置Cargo.toml中的依赖项。


1 回复

Rust比特币开发工具包bdk_esplora使用指南

概述

bdk_esplora是Rust比特币开发工具包(BDK)的一个模块,提供了与Esplora区块链API的无缝集成,使开发者能够高效地查询区块链数据和同步钱包状态。

Esplora是一个流行的比特币区块链浏览器和API服务,bdk_esplora模块允许Rust开发者轻松访问这些功能。

主要特性

  • 交易查询和同步
  • 余额跟踪
  • 高效的区块链数据检索
  • 支持异步操作
  • 与BDK钱包无缝集成

安装

Cargo.toml中添加依赖:

[dependencies]
bdk = { version = "0.26", features = ["esplora"] }
bdk_esplora = "0.3"
tokio = { version = "1.0", features = ["full"] }

基本使用方法

1. 初始化Esplora客户端

use bdk_esplora::esplora_client::{EsploraClient, EsploraClientConfig};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config = EsploraClientConfig {
        base_url: "https://blockstream.info/api/".to_string(),
        timeout: Some(std::time::Duration::from_secs(30)),
        concurrency: Some(5),
    };
    
    let client = EsploraClient::from_config(config)?;
    
    Ok(())
}

2. 查询交易信息

async fn get_transaction(client: &EsploraClient, txid: &str) {
    let txid = bitcoin::Txid::from_str(txid).unwrap();
    match client.get_tx(&txid).await {
        Ok(Some(tx)) => println!("Transaction found: {:?}", tx),
        Ok(None) => println!("Transaction not found"),
        Err(e) => eprintln!("Error: {}", e),
    }
}

3. 同步钱包状态

use bdk::Wallet;
use bdk::database::MemoryDatabase;

async fn sync_wallet(client: &EsploraClient) {
    let wallet = Wallet::new(
        "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4ja极佳地展示了如何构建一个完整的比特币钱包监控工具。这个示例包含了从钱包创建、地址生成、交易监控到余额查询的完整流程,以下是完整的示例代码:

```rust
use bdk::bitcoin::Network;
use bdk::wallet::AddressIndex;
use bdk::{Wallet, database::MemoryDatabase};
use bdk_esplora::esplora_client::EsploraClient;
use std::time::Duration;
use tokio::time::sleep;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 创建测试网钱包
    let wallet = Wallet::new(
        "wpkh([c258d2e4/84h/1h/0h]tpubDDYkZojQFQjht8Tm4jsS3iuEmKjTiEGjG6KnuFNKKJb5A6ZUCUZKdvLdSDWofKi4ToRCwb9poe1XdqfUnP4jaJjCB2Zwv11ZLgSbnZSNecE/0/*)",
        None,
        Network::Testnet,
        MemoryDatabase::new(),
    )?;

    // 2. 获取新接收地址
    let receive_address = wallet.get_address(AddressIndex::New)?;
    println!("新接收地址: {}", receive_address);

    // 3. 初始化Esplora客户端
    let client = EsploraClient::new("https://blockstream.info/testnet/api")?;

    // 4. 启动钱包同步
    let mut scan = client.start_scan(wallet);
    
    loop {
        // 5. 检查并处理钱包更新
        while let Some(update) = scan.next().await {
            println!("钱包更新: {:?}", update);
        }

        // 6. 获取并显示当前余额
        let balance = scan.wallet().get_balance()?;
        println!("当前余额: {} satoshis", balance);

        // 7. 等待30秒后再次检查
        sleep(Duration::from_secs(30)).await;
    }
}

这个完整示例展示了如何:

  1. 创建一个测试网HD钱包
  2. 生成新的接收地址
  3. 初始化Esplora客户端连接到测试网API
  4. 启动钱包同步过程
  5. 持续监控钱包状态变化
  6. 定期显示余额信息
  7. 实现循环监控机制

您可以根据实际需求扩展这个基础示例,比如添加交易发送功能、更详细的交易历史查询等。

回到顶部