rust: Add address inspection to `zcash-inspect`

This commit is contained in:
Jack Grigg 2022-08-01 21:23:51 +00:00
parent a125180a50
commit b0bf639760
2 changed files with 130 additions and 1 deletions

View File

@ -0,0 +1,125 @@
use zcash_address::{
unified::{self, Container, Encoding},
Network, ToAddress, UnsupportedAddress, ZcashAddress,
};
enum AddressKind {
Sprout([u8; 64]),
Sapling([u8; 43]),
Unified(unified::Address),
P2pkh([u8; 20]),
P2sh([u8; 20]),
}
struct Address {
net: Network,
kind: AddressKind,
}
impl zcash_address::FromAddress for Address {
fn from_sprout(net: Network, data: [u8; 64]) -> Result<Self, UnsupportedAddress> {
Ok(Address {
net,
kind: AddressKind::Sprout(data),
})
}
fn from_sapling(net: Network, data: [u8; 43]) -> Result<Self, UnsupportedAddress> {
Ok(Address {
net,
kind: AddressKind::Sapling(data),
})
}
fn from_unified(net: Network, data: unified::Address) -> Result<Self, UnsupportedAddress> {
Ok(Address {
net,
kind: AddressKind::Unified(data),
})
}
fn from_transparent_p2pkh(net: Network, data: [u8; 20]) -> Result<Self, UnsupportedAddress> {
Ok(Address {
net,
kind: AddressKind::P2pkh(data),
})
}
fn from_transparent_p2sh(net: Network, data: [u8; 20]) -> Result<Self, UnsupportedAddress> {
Ok(Address {
net,
kind: AddressKind::P2sh(data),
})
}
}
pub(crate) fn inspect(addr: ZcashAddress) {
eprintln!("Zcash address");
match addr.convert::<Address>() {
// TODO: Check for valid internals once we have migrated to a newer zcash_address
// version with custom errors.
Err(_) => unreachable!(),
Ok(addr) => {
eprintln!(
" - Network: {}",
match addr.net {
Network::Main => "main",
Network::Test => "testnet",
Network::Regtest => "regtest",
}
);
eprintln!(
" - Kind: {}",
match addr.kind {
AddressKind::Sprout(_) => "Sprout",
AddressKind::Sapling(_) => "Sapling",
AddressKind::Unified(_) => "Unified Address",
AddressKind::P2pkh(_) => "Transparent P2PKH",
AddressKind::P2sh(_) => "Transparent P2SH",
}
);
if let AddressKind::Unified(ua) = addr.kind {
eprintln!(" - Receivers:");
for receiver in ua.items() {
match receiver {
unified::Receiver::Orchard(data) => {
eprintln!(
" - Orchard ({})",
unified::Address::try_from_items(vec![unified::Receiver::Orchard(
data
)])
.unwrap()
.encode(&addr.net)
);
}
unified::Receiver::Sapling(data) => {
eprintln!(
" - Sapling ({})",
ZcashAddress::from_sapling(addr.net, data)
);
}
unified::Receiver::P2pkh(data) => {
eprintln!(
" - Transparent P2PKH ({})",
ZcashAddress::from_transparent_p2pkh(addr.net, data)
);
}
unified::Receiver::P2sh(data) => {
eprintln!(
" - Transparent P2SH ({})",
ZcashAddress::from_transparent_p2sh(addr.net, data)
);
}
unified::Receiver::Unknown { typecode, data } => {
eprintln!(" - Unknown");
eprintln!(" - Typecode: {}", typecode);
eprintln!(" - Payload: {}", hex::encode(data));
}
}
}
}
}
}
}

View File

@ -5,12 +5,14 @@ use std::process;
use gumdrop::{Options, ParsingStyle};
use lazy_static::lazy_static;
use zcash_address::ZcashAddress;
use zcash_primitives::{block::BlockHeader, consensus::BranchId, transaction::Transaction};
use zcash_proofs::{default_params_folder, load_parameters, ZcashParameters};
mod context;
use context::{Context, ZUint256};
mod address;
mod block;
mod transaction;
@ -55,8 +57,10 @@ fn main() {
return;
}
if let Ok(bytes) = hex::decode(opts.data) {
if let Ok(bytes) = hex::decode(&opts.data) {
inspect_bytes(bytes, opts.context);
} else if let Ok(addr) = ZcashAddress::try_from_encoded(&opts.data) {
address::inspect(addr);
} else {
// Unknown data format.
eprintln!("String does not match known Zcash data formats.");