Rust比特币Electrum服务器库electrsd的使用,高效支持Electrum协议与区块链数据查询

Rust比特币Electrum服务器库electrsd的使用,高效支持Electrum协议与区块链数据查询

MIT license Crates

Electrsd简介

Electrsd是一个用于运行regtest模式electrs进程的工具,可以连接到指定的bitcoind实例,在集成测试环境中非常有用。

基础使用示例

// 初始化bitcoind实例
let bitcoind = bitcoind::BitcoinD::new("/usr/local/bin/bitcoind").unwrap();
// 初始化electrsd实例
let electrsd = electrsd::ElectrsD::new("/usr/local/bin/electrs", bitcoind).unwrap();
// 订阅区块头信息
let header = electrsd.client.block_headers_subscribe().unwrap();
// 验证初始区块高度为0
assert_eq!(header.height, 0);

自动下载二进制文件

在项目的Cargo.toml中启用以下特性:

electrsd = { version= "0.23", features = ["corepc-node_23_1", "electrs_0_9_1"] }

然后使用自动下载功能:

// 自动下载bitcoind可执行文件
let bitcoind_exe = bitcoind::downloaded_exe_path().expect("bitcoind version feature must be enabled");
let bitcoind = bitcoind::BitcoinD::new(bitcoind_exe).unwrap();

// 自动下载electrs可执行文件
let electrs_exe = electrsd::downloaded_exe_path().expect("electrs version feature must be enabled");
let electrsd = electrsd::ElectrsD::new(electrs_exe, bitcoind).unwrap();

可以通过设置环境变量ELECTRSD_DOWNLOAD_ENDPOINTBITCOIND_DOWNLOAD_ENDPOINT来自定义下载端点。

如果不使用自动下载功能,有以下选项:

  • 在系统PATH中配置electrs可执行文件
  • 通过ELECTRS_EXEC环境变量指定electrs可执行文件路径
// 使用环境变量或PATH中的electrs可执行文件
if let Ok(exe_path) = electrsd::exe_path() {
  let electrsd = electrsd::electrsD::new(exe_path).unwrap();
}

可以通过Conf结构体配置启动选项:

let conf = electrsd::Conf {
    http_addr: "127.0.0.1:3000".to_string(),
    ..Default::default()
};
let electrsd = electrsd::ElectrsD::with_conf(electrs_exe, bitcoind, conf).unwrap();

完整示例代码

use electrsd::{ElectrsD, Conf};
use bitcoind::BitcoinD;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 方法1:手动指定二进制路径
    let bitcoind = BitcoinD::new("/usr/local/bin/bitcoind")?;
    let electrsd = ElectrsD::new("/usr/local/bin/electrs", bitcoind)?;
    
    // 订阅区块头
    let header = electrsd.client.block_headers_subscribe()?;
    println!("当前区块高度: {}", header.height);
    
    // 生成一个测试交易
    let address = "bcrt1qxxxxxx".to_string();
    let txid = bitcoind.client.send_to_address(&address, 1.0)?;
    println!("生成的测试交易ID: {}", txid);
    
    // 等待交易确认
    bitcoind.client.generate(1)?;
    
    // 方法2:自动下载二进制文件
    let bitcoind_exe = bitcoind::downloaded_exe_path()?;
    let bitcoind = BitcoinD::new(bitcoind_exe)?;
    
    let electrs_exe = electrsd::downloaded_exe_path()?;
    let conf = Conf::default();
    let electrsd = ElectrsD::with_conf(electrs_exe, bitcoind, conf)?;
    
    // 查询交易详情
    let tx = electrsd.client.transaction_get(&txid)?;
    println!("交易详情: {:#?}", tx);
    
    // 查询交易所在区块
    let block_hash = electrsd.client.block_header(header.height)?;
    println!("区块哈希: {}", block_hash);
    
    // 方法3:使用环境变量指定的路径
    if let Ok(exe_path) = electrsd::exe_path() {
        let electrsd = ElectrsD::new(exe_path, bitcoind)?;
        // 其他操作...
    }
    
    Ok(())
}

特性

  • 隔离测试环境:使用临时目录作为数据库目录,避免干扰开发环境
  • 自动端口分配:向操作系统请求空闲端口,避免端口冲突
  • 资源自动清理:当结构体超出作用域时自动杀死进程
  • 多版本支持:支持自动下载不同版本的electrs可执行文件
  • 支持的版本
    • electrs 0.10.6 (feature=electrs_0_10_6)
    • electrs 0.9.11 (feature=electrs_0_9_11)
    • electrs 0.9.1 (feature=electrs_0_9_1)
    • electrs 0.8.10 (feature=electrs_0_8_10)
    • electrs esplora (feature=esplora_a33e97e1)

传统测试方法的问题

传统基于外部bash脚本启动外部进程的集成测试方法存在许多问题:

  • 环境干扰:外部脚本可能修改或依赖本地开发环境
  • 测试粒度:通常使用单个大型测试来测试所有功能
  • 清理问题:失败的测试可能无法清理干净,导致后续测试失败
  • 跨平台支持:bash脚本难以支持不同操作系统和版本

使用项目

  • bdk - 比特币开发工具包
  • BEWallet - 比特币电子钱包
  • gdk rust - GreenAddress开发工具包
  • lwk - Lightning Wallet Kit

1 回复

Rust比特币Electrum服务器库electrsd的使用指南

介绍

electrsd是一个Rust实现的Electrum服务器库,它提供了高效的Electrum协议支持和区块链数据查询功能。这个库允许开发者轻松集成Electrum服务器功能到他们的Rust应用程序中,特别适合需要与比特币网络交互的项目。

主要特性

  • 支持Electrum协议
  • 高效的区块链数据索引和查询
  • 异步API设计
  • 可配置的服务器参数
  • 与bitcoind节点集成

安装

在Cargo.toml中添加依赖:

[dependencies]
electrsd = "0.1"
tokio = { version = "1.0", features = ["full"] }

完整示例代码

use electrsd::{ElectrsD, ElectrsConf};
use electrum_client::Client;
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. 配置并启动Electrum服务器
    let conf = ElectrsConf {
        network: "testnet".to_string(),
        electrum_port: 50001,
        ..Default::default()
    };
    
    let electrsd = ElectrsD::new(conf).await?;
    println!("Electrum服务器已启动,监听地址: {}", electrsd.electrum_url());

    // 2. 连接到Electrum服务器
    let client = Client::new(&electrsd.electrum_url())?;
    
    // 获取服务器版本信息
    let version = client.server_version("electrsd-demo", Some("1.4"))?;
    println!("服务器版本: {:?}", version);

    // 3. 查询区块链数据
    // 获取最新区块高度
    let block_height = client.block_headers_subscribe()?.height;
    println!("当前区块高度: {}", block_height);

    // 获取特定区块头
    if block_height > 100 {
        let block_header = client.block_header(block_height - 100)?;
        println!("100个区块前的头部信息: {:?}", block_header);
    }

    // 4. 批量查询示例
    let batch = client.batch();
    batch.block_headers_subscribe()?;
    batch.block_header(block_height)?;
    
    let results = batch.batch_execute()?;
    println!("批量查询结果: {:?}", results);

    // 5. 监控新区块
    println!("开始监控新区块...");
    let mut prev_height = block_height;
    loop {
        tokio::time::sleep(Duration::from_secs(30)).await;
        
        match client.block_headers_subscribe() {
            Ok(header) => {
                if header.height > prev_height {
                    println!("发现新区块! 高度: {}", header.height);
                    prev_height = header.height;
                }
            }
            Err(e) => eprintln!("监控错误: {}", e),
        }
    }
}

代码说明

  1. 服务器配置:

    • 使用ElectrsConf配置测试网环境
    • 指定Electrum服务器端口为50001
  2. 客户端连接:

    • 通过electrum_url()获取服务器URL
    • 使用server_version()进行协议版本协商
  3. 区块链查询:

    • block_headers_subscribe()获取最新区块高度
    • block_header()查询特定区块头信息
  4. 批量查询:

    • 使用batch()创建批量操作
    • 通过batch_execute()执行所有批量请求
  5. 区块监控:

    • 每30秒检查一次新区块
    • 发现新区块时打印高度信息

运行说明

  1. 确保已安装并运行bitcoind测试网节点
  2. 首次运行需要等待索引构建完成
  3. 按Ctrl+C可停止监控程序

这个完整示例展示了electrsd库的主要功能,包括服务器启动、客户端连接、基础查询、批量操作和实时监控等功能。

回到顶部