8个版本 (4个重大更改)

新功能 0.4.0 2024年8月20日
0.3.2 2024年3月6日
0.3.1 2024年1月12日
0.3.0 2023年6月6日
0.0.0 2021年3月7日

#68魔法豆

Download history 3811/week @ 2024-05-01 2468/week @ 2024-05-08 6648/week @ 2024-05-15 7596/week @ 2024-05-22 6649/week @ 2024-05-29 1983/week @ 2024-06-05 2409/week @ 2024-06-12 2049/week @ 2024-06-19 1423/week @ 2024-06-26 833/week @ 2024-07-03 1623/week @ 2024-07-10 2206/week @ 2024-07-17 2454/week @ 2024-07-24 2403/week @ 2024-07-31 2133/week @ 2024-08-07 1570/week @ 2024-08-14

8,973 每月下载量
用于 19 个crate(9个直接使用)

MIT/Apache

775KB
10K SLoC

zcash_address

Zcash地址解析和序列化。这个库允许用户轻松识别和为新Zcash地址类型提供良好的错误消息。

许可证

许可协议为以下之一

供您选择。

贡献

除非您明确声明,否则任何有意提交以包含在您的工作中的贡献,如Apache-2.0许可证中定义的,应如上双许可,不附加任何额外条款或条件。


lib.rs:

所有定义的Zcash地址类型的解析器。

这个crate实现地址解析为一个两阶段过程,围绕不透明的 ZcashAddress 类型构建。

        s.parse()              .convert()
        -------->              --------->
Strings           ZcashAddress            Custom types
        <--------              <---------
        .encode()              ToAddress

需要注意的是,此包不依赖于任何 Zcash 协议包(例如 sapling-cryptoorchard)。此包的设计目标是具有最少的依赖;它专注于解析和处理这些关注点,同时暴露 API,使您能够将解析的数据转换为想要使用的 Rust 类型。

使用此包

我只需要验证 Zcash 地址

fn is_valid_zcash_address(addr_string: &str) -> bool {
    addr_string.parse::<ZcashAddress>().is_ok()
}

我想在使用的 zcash_primitives 交易构建器的 Rust 钱包应用程序中解析 Zcash 地址

使用 zcash_client_backend::address::RecipientAddress,它实现了此包中的特性和解析地址字符串到与 zcash_primitives 包中的交易构建器以及 zcash_client_backend 包本身中的钱包功能一起工作的协议类型。

我们打算将 zcash_client_backendzcash_primitives 包中的密钥和地址类型重构到一个专注于处理 Zcash 密钥材料的独立包中。那个包将成为您应该使用的包。

我想解析统一地址

请参阅 unified::Address 文档中的示例。

虽然 unified::Address 类型确实有解析方法,但您仍然应该使用 ZcashAddress 解析您的地址字符串,然后进行转换;这将确保对于其他 Zcash 地址类型,您获得一个 ConversionError::Unsupported,这是一个更好的错误,对您的用户来说更好。

我想用支持 C FFI 的语言解析主网 Zcash 地址

例如,您可以使用静态函数从解析的数据创建目标语言的地址类型。

use std::ffi::{CStr, c_char, c_void};
use std::ptr;

use zcash_address::{ConversionError, Network, TryFromRawAddress, ZcashAddress};

// Functions that return a pointer to a heap-allocated address of the given kind in
// the target language. These should be augmented to return any relevant errors.
extern {
    fn addr_from_sapling(data: *const u8) -> *mut c_void;
    fn addr_from_transparent_p2pkh(data: *const u8) -> *mut c_void;
}

struct ParsedAddress(*mut c_void);

impl TryFromRawAddress for ParsedAddress {
    type Error = &'static str;

    fn try_from_raw_sapling(
        data: [u8; 43],
    ) -> Result<Self, ConversionError<Self::Error>> {
        let parsed = unsafe { addr_from_sapling(data[..].as_ptr()) };
        if parsed.is_null() {
            Err("Reason for the failure".into())
        } else {
            Ok(Self(parsed))
        }
    }

    fn try_from_raw_transparent_p2pkh(
        data: [u8; 20],
    ) -> Result<Self, ConversionError<Self::Error>> {
        let parsed = unsafe { addr_from_transparent_p2pkh(data[..].as_ptr()) };
        if parsed.is_null() {
            Err("Reason for the failure".into())
        } else {
            Ok(Self(parsed))
        }
    }
}

pub extern "C" fn parse_zcash_address(encoded: *const c_char) -> *mut c_void {
    let encoded = unsafe { CStr::from_ptr(encoded) }.to_str().expect("valid");

    let addr = match ZcashAddress::try_from_encoded(encoded) {
        Ok(addr) => addr,
        Err(e) => {
            // This was either an invalid address encoding, or not a Zcash address.
            // You should pass this error back across the FFI.
            return ptr::null_mut();
        }
    };

    match addr.convert_if_network::<ParsedAddress>(Network::Main) {
        Ok(parsed) => parsed.0,
        Err(e) => {
            // We didn't implement all of the methods of `TryFromRawAddress`, so if an
            // address with one of those kinds is parsed, it will result in an error
            // here that should be passed back across the FFI.
            ptr::null_mut()
        }
    }
}

依赖关系

~1.1–1.9MB
~37K SLoC