Fix up TransparentAddresses
This commit is contained in:
parent
16ee53a909
commit
9887b7c8b7
|
@ -191,6 +191,12 @@ dependencies = [
|
|||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bs58"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b170cd256a3f9fa6b9edae3e44a7dfdfc77e8124dbc3e2612d75f9c3e2396dae"
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.3.1"
|
||||
|
@ -2036,6 +2042,7 @@ dependencies = [
|
|||
name = "zebra-chain"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
"byteorder",
|
||||
"chrono",
|
||||
"ed25519-zebra",
|
||||
|
|
|
@ -8,6 +8,7 @@ edition = "2018"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
bs58 = "0.3.0"
|
||||
byteorder = "1.3"
|
||||
chrono = "0.4"
|
||||
futures = "0.3"
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
//! Address types.
|
||||
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use ripemd160::Ripdemd160;
|
||||
use std::{fmt, io};
|
||||
|
||||
use bs58;
|
||||
use ripemd160::{Digest, Ripemd160};
|
||||
use secp256k1::PublicKey;
|
||||
use sha2::Sha256;
|
||||
|
||||
use crate::serialization::{
|
||||
ReadZcashExt, SerializationError, WriteZcashExt, ZcashDeserialize, ZcashSerialize,
|
||||
};
|
||||
#[cfg(test)]
|
||||
use proptest_derive::Arbitrary;
|
||||
|
||||
use crate::serialization::{SerializationError, ZcashDeserialize, ZcashSerialize};
|
||||
|
||||
use crate::types::Script;
|
||||
|
||||
|
@ -19,11 +22,15 @@ use crate::types::Script;
|
|||
/// https://en.bitcoin.it/Base58Check_encoding#Encoding_a_Bitcoin_address
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
#[cfg_attr(test, derive(Arbitrary))]
|
||||
struct AddressPayloadHash(pub [u8; 20]);
|
||||
pub struct AddressPayloadHash(pub [u8; 20]);
|
||||
|
||||
impl<'a> From<&'a [u8]> for AddressPayloadHash {
|
||||
fn from(bytes: &'a [u8]) -> Self {
|
||||
Self(Ripdemd160::digest(Sha256::digest(bytes)))
|
||||
let sha_hash = Sha256::digest(bytes);
|
||||
let ripe_hash = Ripemd160::digest(&sha_hash);
|
||||
let mut payload = [0u8; 20];
|
||||
payload[..].copy_from_slice(&ripe_hash[..]);
|
||||
Self(payload)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +44,7 @@ impl fmt::Debug for AddressPayloadHash {
|
|||
|
||||
/// An enum describing the possible network choices.
|
||||
// XXX Stolen from zebra-network for now.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub enum Network {
|
||||
/// The production mainnet.
|
||||
Mainnet,
|
||||
|
@ -57,42 +64,89 @@ pub enum Network {
|
|||
///
|
||||
/// https://zips.z.cash/protocol/protocol.pdf#transparentaddrencoding
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
#[cfg_attr(test, derive(Arbitrary))]
|
||||
// #[cfg_attr(test, derive(Arbitrary))]
|
||||
pub enum TransparentAddress {
|
||||
/// P2SH (Pay to Script Hash) addresses
|
||||
PayToScriptHash {
|
||||
/// Production, test, or other network
|
||||
network: Network,
|
||||
script: AddressPayloadHash,
|
||||
/// 20 bytes specifying a script hash.
|
||||
script_hash: AddressPayloadHash,
|
||||
},
|
||||
/// P2PKH (Pay to Public Key Hash) addresses
|
||||
PayToPublicKeyHash {
|
||||
/// Production, test, or other network
|
||||
network: Network,
|
||||
pub_key: AddressPayloadHash,
|
||||
/// 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: AddressPayloadHash,
|
||||
},
|
||||
}
|
||||
|
||||
impl From<Script> for TransparentAddress {
|
||||
fn from(script: Script) -> Self {
|
||||
TransparentAddress::PayToScriptHash {
|
||||
network: Network::Mainnet,
|
||||
script_hash: AddressPayloadHash::from(&script.0[..]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PublicKey> for TransparentAddress {
|
||||
fn from(pub_key: PublicKey) -> Self {
|
||||
TransparentAddress::PayToPublicKeyHash {
|
||||
network: Network::Mainnet,
|
||||
pub_key_hash: AddressPayloadHash::from(&pub_key.serialize()[..]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug 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.debug_tuple("TransparentAddress")
|
||||
.field(&bs58::encode(bytes.get_ref()).into_vec())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl ZcashSerialize for TransparentAddress {
|
||||
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
|
||||
match self {
|
||||
TransparentAddress::PayToScriptHash { network, script_hash } => {
|
||||
if network == Network::Mainnet {
|
||||
TransparentAddress::PayToScriptHash {
|
||||
network,
|
||||
script_hash,
|
||||
} => {
|
||||
if *network == Network::Mainnet {
|
||||
writer.write_all(&[0x1C, 0xBD][..])?
|
||||
} else {
|
||||
// Dev network doesn't have a recommendation so we
|
||||
// default to testnet bytes.
|
||||
writer.write_all(&[0x1C, 0xBA][..])?
|
||||
}
|
||||
writer.write_all::<BigEndian>(script_hash[..])?
|
||||
// XXX I'm asuming this is BigEndian because we're not
|
||||
// explicitly making it LittleEndian?
|
||||
writer.write_all(&script_hash.0)?
|
||||
}
|
||||
TransparentAddress::PayToPublicKeyHash{network, pub_key_hash) => {
|
||||
if network == Network::Mainnet {
|
||||
TransparentAddress::PayToPublicKeyHash {
|
||||
network,
|
||||
pub_key_hash,
|
||||
} => {
|
||||
if *network == Network::Mainnet {
|
||||
writer.write_all(&[0x1C, 0xB8][..])?
|
||||
} else {
|
||||
// Dev network doesn't have a recommendation so we
|
||||
// default to testnet bytes.
|
||||
writer.write_all(&[0x1D, 0x25][..])?
|
||||
}
|
||||
writer.write_all::<BigEndian>(hash[..])?
|
||||
// XXX I'm asuming this is BigEndian because we're not
|
||||
// explicitly making it LittleEndian?
|
||||
writer.write_all(&pub_key_hash.0)?
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,32 +159,25 @@ impl ZcashDeserialize for TransparentAddress {
|
|||
reader.read_exact(&mut hash_bytes)?;
|
||||
|
||||
match version_bytes {
|
||||
[0x1c, 0xbd] => {
|
||||
Ok(TransparentAddress::PayToScriptHash {
|
||||
network: Network::Mainnet,
|
||||
script: AddressPayloadHash(hash_bytes)
|
||||
})
|
||||
},
|
||||
[0x1c, 0xbd] => Ok(TransparentAddress::PayToScriptHash {
|
||||
network: Network::Mainnet,
|
||||
script_hash: AddressPayloadHash(hash_bytes),
|
||||
}),
|
||||
// Currently only reading !mainnet versions as testnet.
|
||||
[0x1c, 0xba] => {
|
||||
Ok(TransparentAddress::PayToScriptHash {
|
||||
network: Network::Testnet,
|
||||
script: AddressPayloadHash(hash_bytes)
|
||||
})
|
||||
},
|
||||
[0x1c, 0xb8] => {
|
||||
Ok(TransparentAddress::PayToPublicKeyHash {
|
||||
network: Network::Mainnet,
|
||||
pub_key: AddressPayloadHash(hash_bytes)
|
||||
})
|
||||
},
|
||||
[0x1c, 0xba] => Ok(TransparentAddress::PayToScriptHash {
|
||||
network: Network::Testnet,
|
||||
script_hash: AddressPayloadHash(hash_bytes),
|
||||
}),
|
||||
[0x1c, 0xb8] => Ok(TransparentAddress::PayToPublicKeyHash {
|
||||
network: Network::Mainnet,
|
||||
pub_key_hash: AddressPayloadHash(hash_bytes),
|
||||
}),
|
||||
// Currently only reading !mainnet versions as testnet.
|
||||
[0x1d, 0x25] => {
|
||||
Ok(TransparentAddress::PayToPublicKeyHash {
|
||||
network: Network::Testnet,
|
||||
pub_key: AddressPayloadHash(hash_bytes)
|
||||
})
|
||||
}
|
||||
[0x1d, 0x25] => Ok(TransparentAddress::PayToPublicKeyHash {
|
||||
network: Network::Testnet,
|
||||
pub_key_hash: AddressPayloadHash(hash_bytes),
|
||||
}),
|
||||
_ => Err(SerializationError::Parse("bad t-addr version/type")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
#![doc(html_logo_url = "https://www.zfnd.org/images/zebra-icon.png")]
|
||||
#![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_chain")]
|
||||
|
||||
#![deny(missing_docs)]
|
||||
|
||||
mod merkle_tree;
|
||||
mod sha256d_writer;
|
||||
|
||||
pub mod addresses;
|
||||
pub mod block;
|
||||
pub mod equihash_solution;
|
||||
pub mod keys;
|
||||
|
|
Loading…
Reference in New Issue