From bd247067ae0ed7a26bec64ed05e4a848f75b082c Mon Sep 17 00:00:00 2001 From: Deirdre Connolly Date: Fri, 13 Mar 2020 14:47:47 -0400 Subject: [PATCH] Move TransparentAddress stuff to its own module --- zebra-chain/src/addresses/transparent.rs | 252 +++++++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 zebra-chain/src/addresses/transparent.rs diff --git a/zebra-chain/src/addresses/transparent.rs b/zebra-chain/src/addresses/transparent.rs new file mode 100644 index 00000000..64f1d51a --- /dev/null +++ b/zebra-chain/src/addresses/transparent.rs @@ -0,0 +1,252 @@ +//! Transparent Address types. + +use std::{fmt, io}; + +use bs58; +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, +}; + +/// 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 xed 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 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. These are big-endian. + /// 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