代码解析Rust Bitcoin library

660 阅读3分钟

这是一个支持比特币网络协议和相关原语的库。它专为与比特币网络协同工作的 Rust 程序设计。

它也完全用 Rust 编写,以展示强类型安全(包括所有权和生命周期)对金融和/或加密软件的好处。

下面进行解析的是 rust-bitcoin\bitcoin\embedded\src下的main.rs代码。 这段代码是一个使用 Rust 编写的嵌入式程序,它使用比特币库来生成比特币地址。下面是对这段代码的逐行注释:

// 启用编译器特性,以便使用自定义分配错误处理程序
#![feature(alloc_error_handler)]
// 启用编译器特性,以便在 panic 时获取更多信息
#![feature(panic_info_message)]
// 禁用标准库,因为这是一个嵌入式程序
#![no_std]
// 禁用默认的入口点,因为我们将使用 cortex_m_rt 提供的入口点
#![no_main]

// 引入 alloc 库,以便使用动态内存分配
extern crate alloc;
// 引入比特币库
extern crate bitcoin;

// 引入一些类型和 trait,以便在程序中使用它们
use alloc::string::ToString;
use alloc::vec;
use core::panic::PanicInfo;

// 引入 CortexMHeap 类型,以便在程序中使用它作为全局分配器
use alloc_cortex_m::CortexMHeap;
// 使用 panic_halt 作为默认的 panic 处理程序
// use panic_halt as _;
// 引入比特币库中的一些类型和 trait,以便在程序中使用它们
use bitcoin::{Address, Network, PrivateKey};
use bitcoin::secp256k1::ffi::types::AlignedType;
use bitcoin::secp256k1::Secp256k1;

// 引入 cortex_m_rt 库中的 entry 属性,以便定义程序的入口点
use cortex_m_rt::entry;
// 引入 cortex_m_semihosting 库中的一些函数,以便在程序中使用它们进行调试和打印
use cortex_m_semihosting::{debug, hprintln};

// 定义全局分配器
#[global_allocator]
static ALLOCATOR: CortexMHeap = CortexMHeap::empty();

// 定义堆大小
const HEAP_SIZE: usize = 1024 * 256; // 256 KB

// 定义程序的入口点
#[entry]
fn main() -> ! {
 // 打印堆大小
 hprintln!("heap size {}", HEAP_SIZE).unwrap();

 // 初始化全局分配器
 unsafe { ALLOCATOR.init(cortex_m_rt::heap_start() as usize, HEAP_SIZE) }

 // 获取 secp256k1 上下文对象所需的缓冲区大小
 let size = Secp256k1::preallocate_size();
 // 打印缓冲区大小
 hprintln!("secp buf size {}", size*16).unwrap();

 // 从 WIF 格式的私钥字符串加载私钥
 let raw = "L1HKVVLHXiUhecWnwFYF6L3shkf1E12HUmuZTESvBXUdx3yqVP1D";
 let pk = PrivateKey::from_wif(raw).unwrap();
 // 打印私钥信息
 hprintln!("Seed WIF: {}", pk).unwrap();

 // 创建 secp256k1 上下文对象所需的缓冲区
 let mut buf_ful = vec![AlignedType::zeroed(); size];
 // 使用预分配的缓冲区创建 secp256k1 上下文对象
 let secp = Secp256k1::preallocated_new(&mut buf_ful).unwrap();

 // 使用私钥派生公钥
 let pubkey = pk.public_key(&secp);
 // 使用公钥派生比特币地址(P2WPKH 格式)
 let address = Address::p2wpkh(&pubkey, Network::Bitcoin).unwrap();
 // 打印比特币地址信息
 hprintln!("Address: {}", address).unwrap();

 // 检查派生的比特币地址是否与预期相同
 assert_eq!(address.to_string(), "bc1qpx9t9pzzl4qsydmhyt6ctrxxjd4ep549np9993".to_string());
 // 退出 QEMU(仅适用于 QEMU 模拟器)
 // 注意:不要在硬件上运行此代码;它可能会破坏 OpenOCD 状态
 debug::exit(debug::EXIT_SUCCESS);

 // 主循环(永远不会退出)
 loop {}
}

// 定义 panic 处理程序(当程序发生 panic 时调用)
#[inline(never)]
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
 // 打印 panic 信息并退出 QEMU(仅适用于 QEMU 模拟器)
 hprintln!("panic {:?}", info.message()).unwrap();
 debug::exit(debug::EXIT_FAILURE);
 loop {}
}

这段代码定义了一个嵌入式程序,该程序使用 cortex_m_rt 库作为运行时支持,并使用 alloc_cortex_m 库作为全局分配器。该程序从 WIF 格式的私钥字符串加载私钥,然后使用比特币库中的 Secp256k1 类型派生公钥并生成 P2WPKH 格式的比特币地址。