Implement TransparentAddress encoding and decoding
This commit is contained in:
parent
97c21e0c1a
commit
932f1c9737
|
@ -13,6 +13,7 @@ edition = "2018"
|
|||
|
||||
[dependencies]
|
||||
bech32 = "0.7"
|
||||
bs58 = { version = "0.3", features = ["check"] }
|
||||
ff = { version = "0.6", path = "../ff" }
|
||||
hex = "0.3"
|
||||
pairing = { version = "0.16", path = "../pairing" }
|
||||
|
|
|
@ -28,3 +28,13 @@ pub const HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY: &str = "zxviews";
|
|||
/// [`PaymentAddress`]: zcash_primitives::primitives::PaymentAddress
|
||||
/// [Zcash Protocol Specification]: https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
|
||||
pub const HRP_SAPLING_PAYMENT_ADDRESS: &str = "zs";
|
||||
|
||||
/// The prefix for a Base58Check-encoded mainnet [`TransparentAddress::PublicKey`].
|
||||
///
|
||||
/// [`TransparentAddress::PublicKey`]: zcash_primitives::legacy::TransparentAddress::PublicKey
|
||||
pub const B58_PUBKEY_ADDRESS_PREFIX: [u8; 2] = [0x1c, 0xb8];
|
||||
|
||||
/// The prefix for a Base58Check-encoded mainnet [`TransparentAddress::Script`].
|
||||
///
|
||||
/// [`TransparentAddress::Script`]: zcash_primitives::legacy::TransparentAddress::Script
|
||||
pub const B58_SCRIPT_ADDRESS_PREFIX: [u8; 2] = [0x1c, 0xbd];
|
||||
|
|
|
@ -28,3 +28,13 @@ pub const HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY: &str = "zxviewtestsapling";
|
|||
/// [`PaymentAddress`]: zcash_primitives::primitives::PaymentAddress
|
||||
/// [Zcash Protocol Specification]: https://github.com/zcash/zips/blob/master/protocol/protocol.pdf
|
||||
pub const HRP_SAPLING_PAYMENT_ADDRESS: &str = "ztestsapling";
|
||||
|
||||
/// The prefix for a Base58Check-encoded testnet [`TransparentAddress::PublicKey`].
|
||||
///
|
||||
/// [`TransparentAddress::PublicKey`]: zcash_primitives::legacy::TransparentAddress::PublicKey
|
||||
pub const B58_PUBKEY_ADDRESS_PREFIX: [u8; 2] = [0x1d, 0x25];
|
||||
|
||||
/// The prefix for a Base58Check-encoded testnet [`TransparentAddress::Script`].
|
||||
///
|
||||
/// [`TransparentAddress::Script`]: zcash_primitives::legacy::TransparentAddress::Script
|
||||
pub const B58_SCRIPT_ADDRESS_PREFIX: [u8; 2] = [0x1c, 0xba];
|
||||
|
|
|
@ -6,9 +6,12 @@
|
|||
//! [`constants`]: crate::constants
|
||||
|
||||
use bech32::{self, Error, FromBase32, ToBase32};
|
||||
use bs58::{self, decode::Error as Bs58Error};
|
||||
use pairing::bls12_381::Bls12;
|
||||
use std::convert::TryInto;
|
||||
use std::io::{self, Write};
|
||||
use zcash_primitives::{
|
||||
legacy::TransparentAddress,
|
||||
primitives::PaymentAddress,
|
||||
zip32::{ExtendedFullViewingKey, ExtendedSpendingKey},
|
||||
JUBJUB,
|
||||
|
@ -176,6 +179,108 @@ pub fn decode_payment_address(hrp: &str, s: &str) -> Result<Option<PaymentAddres
|
|||
})
|
||||
}
|
||||
|
||||
/// Writes a [`TransparentAddress`] as a Base58Check-encoded string.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use zcash_client_backend::{
|
||||
/// constants::testnet::{B58_PUBKEY_ADDRESS_PREFIX, B58_SCRIPT_ADDRESS_PREFIX},
|
||||
/// encoding::encode_transparent_address,
|
||||
/// };
|
||||
/// use zcash_primitives::legacy::TransparentAddress;
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// encode_transparent_address(
|
||||
/// &B58_PUBKEY_ADDRESS_PREFIX,
|
||||
/// &B58_SCRIPT_ADDRESS_PREFIX,
|
||||
/// &TransparentAddress::PublicKey([0; 20]),
|
||||
/// ),
|
||||
/// "tm9iMLAuYMzJ6jtFLcA7rzUmfreGuKvr7Ma",
|
||||
/// );
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// encode_transparent_address(
|
||||
/// &B58_PUBKEY_ADDRESS_PREFIX,
|
||||
/// &B58_SCRIPT_ADDRESS_PREFIX,
|
||||
/// &TransparentAddress::Script([0; 20]),
|
||||
/// ),
|
||||
/// "t26YoyZ1iPgiMEWL4zGUm74eVWfhyDMXzY2",
|
||||
/// );
|
||||
/// ```
|
||||
pub fn encode_transparent_address(
|
||||
pubkey_version: &[u8],
|
||||
script_version: &[u8],
|
||||
addr: &TransparentAddress,
|
||||
) -> String {
|
||||
let decoded = match addr {
|
||||
TransparentAddress::PublicKey(key_id) => {
|
||||
let mut decoded = vec![0; pubkey_version.len() + 20];
|
||||
decoded[..pubkey_version.len()].copy_from_slice(pubkey_version);
|
||||
decoded[pubkey_version.len()..].copy_from_slice(key_id);
|
||||
decoded
|
||||
}
|
||||
TransparentAddress::Script(script_id) => {
|
||||
let mut decoded = vec![0; script_version.len() + 20];
|
||||
decoded[..script_version.len()].copy_from_slice(script_version);
|
||||
decoded[script_version.len()..].copy_from_slice(script_id);
|
||||
decoded
|
||||
}
|
||||
};
|
||||
bs58::encode(decoded).with_check().into_string()
|
||||
}
|
||||
|
||||
/// Decodes a [`TransparentAddress`] from a Base58Check-encoded string.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use zcash_client_backend::{
|
||||
/// constants::testnet::{B58_PUBKEY_ADDRESS_PREFIX, B58_SCRIPT_ADDRESS_PREFIX},
|
||||
/// encoding::decode_transparent_address,
|
||||
/// };
|
||||
/// use zcash_primitives::legacy::TransparentAddress;
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// decode_transparent_address(
|
||||
/// &B58_PUBKEY_ADDRESS_PREFIX,
|
||||
/// &B58_SCRIPT_ADDRESS_PREFIX,
|
||||
/// "tm9iMLAuYMzJ6jtFLcA7rzUmfreGuKvr7Ma",
|
||||
/// ),
|
||||
/// Ok(Some(TransparentAddress::PublicKey([0; 20]))),
|
||||
/// );
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// decode_transparent_address(
|
||||
/// &B58_PUBKEY_ADDRESS_PREFIX,
|
||||
/// &B58_SCRIPT_ADDRESS_PREFIX,
|
||||
/// "t26YoyZ1iPgiMEWL4zGUm74eVWfhyDMXzY2",
|
||||
/// ),
|
||||
/// Ok(Some(TransparentAddress::Script([0; 20]))),
|
||||
/// );
|
||||
/// ```
|
||||
pub fn decode_transparent_address(
|
||||
pubkey_version: &[u8],
|
||||
script_version: &[u8],
|
||||
s: &str,
|
||||
) -> Result<Option<TransparentAddress>, Bs58Error> {
|
||||
bs58::decode(s).with_check(None).into_vec().map(|decoded| {
|
||||
if decoded.starts_with(pubkey_version) {
|
||||
decoded[pubkey_version.len()..]
|
||||
.try_into()
|
||||
.ok()
|
||||
.map(TransparentAddress::PublicKey)
|
||||
} else if decoded.starts_with(script_version) {
|
||||
decoded[script_version.len()..]
|
||||
.try_into()
|
||||
.ok()
|
||||
.map(TransparentAddress::Script)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pairing::bls12_381::Bls12;
|
||||
|
|
Loading…
Reference in New Issue