//! Transparent Address types. use std::{fmt, io}; use ripemd160::{Digest, Ripemd160}; use secp256k1::PublicKey; use sha2::Sha256; #[cfg(test)] use proptest::{arbitrary::Arbitrary, collection::vec, prelude::*}; use crate::{ serialization::{SerializationError, ZcashDeserialize, ZcashSerialize}, types::Script, Network, }; /// Magic numbers used to identify what networks Transparent Addresses /// are associated with. mod magics { pub mod p2sh { pub const MAINNET: [u8; 2] = [0x1C, 0xBD]; pub const TESTNET: [u8; 2] = [0x1C, 0xBA]; } pub mod p2pkh { pub const MAINNET: [u8; 2] = [0x1C, 0xB8]; pub const TESTNET: [u8; 2] = [0x1D, 0x25]; } } /// Transparent Zcash Addresses /// /// In Bitcoin a single byte is used for the version field identifying /// the address type. In Zcash two bytes are used. For addresses on /// the production network, this and the encoded length cause the first /// two characters of the Base58Check encoding to be fixed as “t3” for /// P2SH addresses, and as “t1” for P2PKH addresses. (This does not /// imply that a transparent Zcash address can be parsed identically /// to a Bitcoin address just by removing the “t”.) /// /// https://zips.z.cash/protocol/protocol.pdf#transparentaddrencoding #[derive(Copy, Clone, Eq, PartialEq)] pub enum TransparentAddress { /// P2SH (Pay to Script Hash) addresses PayToScriptHash { /// Production, test, or other network network: Network, /// 20 bytes specifying a script hash. script_hash: [u8; 20], }, /// P2PKH (Pay to Public Key Hash) addresses PayToPublicKeyHash { /// Production, test, or other network network: Network, /// 20 bytes specifying a public key hash, which is a RIPEMD-160 /// hash of a SHA-256 hash of a compressed ECDSA key encoding. pub_key_hash: [u8; 20], }, } impl fmt::Debug for TransparentAddress { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut debug_struct = f.debug_struct("TransparentAddress"); match self { TransparentAddress::PayToScriptHash { network, script_hash, } => debug_struct .field("network", network) .field("script_hash", &hex::encode(script_hash)) .finish(), TransparentAddress::PayToPublicKeyHash { network, pub_key_hash, } => debug_struct .field("network", network) .field("pub_key_hash", &hex::encode(pub_key_hash)) .finish(), } } } impl fmt::Display for TransparentAddress { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let mut bytes = io::Cursor::new(Vec::new()); let _ = self.zcash_serialize(&mut bytes); f.write_str(&bs58::encode(bytes.get_ref()).with_check().into_string()) } } impl From