mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-01-30 15:32:14 +00:00
Implement TransparentAddress encoding and decoding
This commit is contained in:
parent
601e88c633
commit
1c60a79ec1
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -130,6 +130,14 @@ dependencies = [
|
||||
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bs58"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.3.1"
|
||||
@ -650,6 +658,7 @@ name = "zcash_client_backend"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bech32 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bs58 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ff 0.4.0",
|
||||
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pairing 0.14.2",
|
||||
@ -733,6 +742,7 @@ dependencies = [
|
||||
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||
"checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774"
|
||||
"checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09"
|
||||
"checksum bs58 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0d9644ad62ff4df43da2e057febbbce576f7124cb5cd8e90e0ce7027f38aa2dd"
|
||||
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||
"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101"
|
||||
|
@ -8,6 +8,7 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
bech32 = "0.7"
|
||||
bs58 = { version = "0.2", features = ["check"] }
|
||||
ff = { path = "../ff" }
|
||||
hex = "0.3"
|
||||
pairing = { path = "../pairing" }
|
||||
|
@ -26,3 +26,13 @@ pub const HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY: &str = "zxviews";
|
||||
/// [`PaymentAddress`]: sapling_crypto::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];
|
||||
|
@ -26,3 +26,13 @@ pub const HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY: &str = "zxviewtestsapling";
|
||||
/// [`PaymentAddress`]: sapling_crypto::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];
|
||||
|
@ -4,6 +4,7 @@
|
||||
//! module.
|
||||
|
||||
use bech32::{self, Error, FromBase32, ToBase32};
|
||||
use bs58::{self, decode::DecodeError};
|
||||
use pairing::bls12_381::Bls12;
|
||||
use std::io::{self, Write};
|
||||
use zcash_primitives::{
|
||||
@ -11,6 +12,7 @@ use zcash_primitives::{
|
||||
primitives::{Diversifier, PaymentAddress},
|
||||
};
|
||||
use zcash_primitives::{
|
||||
legacy::TransparentAddress,
|
||||
zip32::{ExtendedFullViewingKey, ExtendedSpendingKey},
|
||||
JUBJUB,
|
||||
};
|
||||
@ -182,6 +184,113 @@ 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>, DecodeError> {
|
||||
let decoded = bs58::decode(s).with_check(None).into_vec()?;
|
||||
if &decoded[..pubkey_version.len()] == pubkey_version {
|
||||
if decoded.len() == pubkey_version.len() + 20 {
|
||||
let mut data = [0; 20];
|
||||
data.copy_from_slice(&decoded[pubkey_version.len()..]);
|
||||
Ok(Some(TransparentAddress::PublicKey(data)))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
} else if &decoded[..script_version.len()] == script_version {
|
||||
if decoded.len() == script_version.len() + 20 {
|
||||
let mut data = [0; 20];
|
||||
data.copy_from_slice(&decoded[script_version.len()..]);
|
||||
Ok(Some(TransparentAddress::Script(data)))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pairing::bls12_381::Bls12;
|
||||
|
Loading…
Reference in New Issue
Block a user