Tidy TransparentAddress FromStr/Display

This commit is contained in:
Deirdre Connolly 2020-04-22 01:59:28 -04:00 committed by Deirdre Connolly
parent bf371c3abc
commit 7367daef9f
2 changed files with 59 additions and 81 deletions

View File

@ -115,21 +115,18 @@ impl Arbitrary for SaplingShieldedAddress {
mod tests { mod tests {
use rand_core::OsRng; use rand_core::OsRng;
use std::str::FromStr;
use super::*; use super::*;
#[test] #[test]
fn from_str_display() { fn from_str_display() {
let zs_addr = SaplingShieldedAddress::from_str( let zs_addr: SaplingShieldedAddress =
"zs1qqqqqqqqqqqqqqqqqrjq05nyfku05msvu49mawhg6kr0wwljahypwyk2h88z6975u563j8nfaxd", "zs1qqqqqqqqqqqqqqqqqrjq05nyfku05msvu49mawhg6kr0wwljahypwyk2h88z6975u563j8nfaxd"
) .parse()
.expect("sapling z-addr string to parse"); .unwrap();
let address = zs_addr.to_string();
assert_eq!( assert_eq!(
format!("{}", address), format!("{}", zs_addr),
"zs1qqqqqqqqqqqqqqqqqrjq05nyfku05msvu49mawhg6kr0wwljahypwyk2h88z6975u563j8nfaxd" "zs1qqqqqqqqqqqqqqqqqrjq05nyfku05msvu49mawhg6kr0wwljahypwyk2h88z6975u563j8nfaxd"
); );
} }

View File

@ -60,62 +60,6 @@ pub enum TransparentAddress {
}, },
} }
impl TransparentAddress {
/// A hash of a transparent address payload, as used in
/// transparent pay-to-script-hash and pay-to-publickey-hash
/// addresses.
///
/// The resulting hash in both of these cases is always exactly 20
/// bytes.
/// https://en.bitcoin.it/Base58Check_encoding#Encoding_a_Bitcoin_address
fn hash_payload(bytes: &[u8]) -> [u8; 20] {
let sha_hash = Sha256::digest(bytes);
let ripe_hash = Ripemd160::digest(&sha_hash);
let mut payload = [0u8; 20];
payload[..].copy_from_slice(&ripe_hash[..]);
payload
}
}
impl From<Script> for TransparentAddress {
fn from(script: Script) -> Self {
TransparentAddress::PayToScriptHash {
network: Network::Mainnet,
script_hash: Self::hash_payload(&script.0[..]),
}
}
}
impl From<PublicKey> for TransparentAddress {
fn from(pub_key: PublicKey) -> Self {
TransparentAddress::PayToPublicKeyHash {
network: Network::Mainnet,
pub_key_hash: Self::hash_payload(&pub_key.serialize()[..]),
}
}
}
impl<T: ?Sized + AsRef<[u8]>> From<&T> for TransparentAddress {
fn from(s: &T) -> Self {
let bytes = &bs58::decode(s).with_check(None).into_vec().unwrap();
Self::zcash_deserialize(&bytes[..]).expect("t-addr should deserialize")
}
}
impl std::str::FromStr for TransparentAddress {
type Err = SerializationError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let result = &bs58::decode(s).with_check(None).into_vec();
match result {
Ok(bytes) => Self::zcash_deserialize(&bytes[..]),
Err(_) => Err(SerializationError::Parse("t-addr decoding error")),
}
}
}
impl fmt::Debug for TransparentAddress { impl fmt::Debug for TransparentAddress {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut debug_struct = f.debug_struct("TransparentAddress"); let mut debug_struct = f.debug_struct("TransparentAddress");
@ -144,9 +88,38 @@ impl fmt::Display for TransparentAddress {
let mut bytes = io::Cursor::new(Vec::new()); let mut bytes = io::Cursor::new(Vec::new());
let _ = self.zcash_serialize(&mut bytes); let _ = self.zcash_serialize(&mut bytes);
f.debug_tuple("TransparentAddress") f.write_str(&bs58::encode(bytes.get_ref()).with_check().into_string())
.field(&bs58::encode(bytes.get_ref()).with_check().into_string()) }
.finish() }
impl From<Script> for TransparentAddress {
fn from(script: Script) -> Self {
TransparentAddress::PayToScriptHash {
network: Network::Mainnet,
script_hash: Self::hash_payload(&script.0[..]),
}
}
}
impl From<PublicKey> for TransparentAddress {
fn from(pub_key: PublicKey) -> Self {
TransparentAddress::PayToPublicKeyHash {
network: Network::Mainnet,
pub_key_hash: Self::hash_payload(&pub_key.serialize()[..]),
}
}
}
impl std::str::FromStr for TransparentAddress {
type Err = SerializationError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let result = &bs58::decode(s).with_check(None).into_vec();
match result {
Ok(bytes) => Self::zcash_deserialize(&bytes[..]),
Err(_) => Err(SerializationError::Parse("t-addr decoding error")),
}
} }
} }
@ -213,6 +186,23 @@ impl ZcashDeserialize for TransparentAddress {
} }
} }
impl TransparentAddress {
/// A hash of a transparent address payload, as used in
/// transparent pay-to-script-hash and pay-to-publickey-hash
/// addresses.
///
/// The resulting hash in both of these cases is always exactly 20
/// bytes.
/// https://en.bitcoin.it/Base58Check_encoding#Encoding_a_Bitcoin_address
fn hash_payload(bytes: &[u8]) -> [u8; 20] {
let sha_hash = Sha256::digest(bytes);
let ripe_hash = Ripemd160::digest(&sha_hash);
let mut payload = [0u8; 20];
payload[..].copy_from_slice(&ripe_hash[..]);
payload
}
}
#[cfg(test)] #[cfg(test)]
impl TransparentAddress { impl TransparentAddress {
fn p2pkh_strategy() -> impl Strategy<Value = Self> { fn p2pkh_strategy() -> impl Strategy<Value = Self> {
@ -272,10 +262,7 @@ mod tests {
let t_addr = TransparentAddress::from(pub_key); let t_addr = TransparentAddress::from(pub_key);
assert_eq!( assert_eq!(format!("{}", t_addr), "t1bmMa1wJDFdbc2TiURQP5BbBz6jHjUBuHq");
format!("{}", t_addr),
"TransparentAddress(\"t1bmMa1wJDFdbc2TiURQP5BbBz6jHjUBuHq\")"
);
} }
#[test] #[test]
@ -284,25 +271,19 @@ mod tests {
let t_addr = TransparentAddress::from(script); let t_addr = TransparentAddress::from(script);
assert_eq!( assert_eq!(format!("{}", t_addr), "t3Y5pHwfgHbS6pDjj1HLuMFxhFFip1fcJ6g");
format!("{}", t_addr),
"TransparentAddress(\"t3Y5pHwfgHbS6pDjj1HLuMFxhFFip1fcJ6g\")"
);
} }
#[test] #[test]
fn from_string() { fn from_string() {
let t_addr = TransparentAddress::from("t3Vz22vK5z2LcKEdg16Yv4FFneEL1zg9ojd"); let t_addr: TransparentAddress = "t3Vz22vK5z2LcKEdg16Yv4FFneEL1zg9ojd".parse().unwrap();
assert_eq!( assert_eq!(format!("{}", t_addr), "t3Vz22vK5z2LcKEdg16Yv4FFneEL1zg9ojd");
format!("{}", t_addr),
"TransparentAddress(\"t3Vz22vK5z2LcKEdg16Yv4FFneEL1zg9ojd\")"
);
} }
#[test] #[test]
fn debug() { fn debug() {
let t_addr = TransparentAddress::from("t3Vz22vK5z2LcKEdg16Yv4FFneEL1zg9ojd"); let t_addr: TransparentAddress = "t3Vz22vK5z2LcKEdg16Yv4FFneEL1zg9ojd".parse().unwrap();
assert_eq!( assert_eq!(
format!("{:?}", t_addr), format!("{:?}", t_addr),