From 20a5f1f35f9b5955059b698204fa88ec7d8612bf Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 23 Jan 2024 16:51:44 +1100 Subject: [PATCH] Use KnowHrp instead of Network We have a bunch of functions that take `Network` when what they really want is something that can be converted to a `KnownHrp`. Make `KnownHrp` public and accept `impl Into`. --- bitcoin/examples/bip32.rs | 6 +++--- bitcoin/src/address/mod.rs | 39 +++++++++++++++++++------------------- bitcoin/src/lib.rs | 2 +- bitcoin/src/taproot/mod.rs | 4 ++-- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/bitcoin/examples/bip32.rs b/bitcoin/examples/bip32.rs index 98642870..9d8efbc7 100644 --- a/bitcoin/examples/bip32.rs +++ b/bitcoin/examples/bip32.rs @@ -3,12 +3,12 @@ extern crate bitcoin; use std::str::FromStr; use std::{env, process}; -use bitcoin::address::Address; +use bitcoin::address::{Address, KnownHrp}; use bitcoin::bip32::{ChildNumber, DerivationPath, Xpriv, Xpub}; use bitcoin::hex::FromHex; use bitcoin::secp256k1::ffi::types::AlignedType; use bitcoin::secp256k1::Secp256k1; -use bitcoin::{CompressedPublicKey, Network, NetworkKind}; +use bitcoin::{CompressedPublicKey, NetworkKind}; fn main() { // This example derives root xprv from a 32-byte seed, @@ -50,6 +50,6 @@ fn main() { // manually creating indexes this time let zero = ChildNumber::from_normal_idx(0).unwrap(); let public_key = xpub.derive_pub(&secp, &[zero, zero]).unwrap().public_key; - let address = Address::p2wpkh(&CompressedPublicKey(public_key), Network::Bitcoin); + let address = Address::p2wpkh(&CompressedPublicKey(public_key), KnownHrp::Mainnet); println!("First receiving address: {}", address); } diff --git a/bitcoin/src/address/mod.rs b/bitcoin/src/address/mod.rs index d1d8175e..aeca55ab 100644 --- a/bitcoin/src/address/mod.rs +++ b/bitcoin/src/address/mod.rs @@ -180,9 +180,12 @@ impl fmt::Display for AddressInner { } /// Known bech32 human-readable parts. +/// +/// This is the human-readable part before the separator (`1`) in a bech32 encoded address e.g., +/// the "bc" in "bc1p2wsldez5mud2yam29q22wgfh9439spgduvct83k3pm50fcxa5dps59h4z5". #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[non_exhaustive] -enum KnownHrp { +pub enum KnownHrp { /// The main Bitcoin network. Mainnet, /// The test networks, testnet and signet. @@ -387,9 +390,9 @@ impl Address { /// Creates a witness pay to public key address from a public key. /// /// This is the native segwit address type for an output redeemable with a single signature. - pub fn p2wpkh(pk: &CompressedPublicKey, network: Network) -> Self { + pub fn p2wpkh(pk: &CompressedPublicKey, hrp: impl Into) -> Self { let program = WitnessProgram::p2wpkh(pk); - Address::from_witness_program(program, network) + Address::from_witness_program(program, hrp) } /// Creates a pay to script address that embeds a witness pay to public key. @@ -402,9 +405,9 @@ impl Address { } /// Creates a witness pay to script hash address. - pub fn p2wsh(script: &Script, network: Network) -> Address { + pub fn p2wsh(script: &Script, hrp: impl Into) -> Address { let program = WitnessProgram::p2wsh(script); - Address::from_witness_program(program, network) + Address::from_witness_program(program, hrp) } /// Creates a pay to script address that embeds a witness pay to script hash address. @@ -421,26 +424,24 @@ impl Address { secp: &Secp256k1, internal_key: UntweakedPublicKey, merkle_root: Option, - network: Network, + hrp: impl Into, ) -> Address { let program = WitnessProgram::p2tr(secp, internal_key, merkle_root); - Address::from_witness_program(program, network) + Address::from_witness_program(program, hrp) } /// Creates a pay to taproot address from a pre-tweaked output key. - pub fn p2tr_tweaked(output_key: TweakedPublicKey, network: Network) -> Address { + pub fn p2tr_tweaked(output_key: TweakedPublicKey, hrp: impl Into) -> Address { let program = WitnessProgram::p2tr_tweaked(output_key); - Address::from_witness_program(program, network) + Address::from_witness_program(program, hrp) } /// Creates an address from an arbitrary witness program. /// /// This only exists to support future witness versions. If you are doing normal mainnet things /// then you likely do not need this constructor. - // TODO: This is still arguably wrong, could take a KnownHrp/Hrp instead of Network. - pub fn from_witness_program(program: WitnessProgram, network: Network) -> Address { - let hrp = KnownHrp::from_network(network); - let inner = AddressInner::Segwit { program, hrp }; + pub fn from_witness_program(program: WitnessProgram, hrp: impl Into) -> Address { + let inner = AddressInner::Segwit { program, hrp: hrp.into() }; Address(inner, PhantomData) } @@ -874,7 +875,7 @@ mod tests { let key = "033bc8c83c52df5712229a2f72206d90192366c36428cb0c12b6af98324d97bfbc" .parse::() .unwrap(); - let addr = Address::p2wpkh(&key, Bitcoin); + let addr = Address::p2wpkh(&key, KnownHrp::Mainnet); assert_eq!(&addr.to_string(), "bc1qvzvkjn4q3nszqxrv3nraga2r822xjty3ykvkuw"); assert_eq!(addr.address_type(), Some(AddressType::P2wpkh)); roundtrips(&addr, Bitcoin); @@ -884,7 +885,7 @@ mod tests { fn test_p2wsh() { // stolen from Bitcoin transaction 5df912fda4becb1c29e928bec8d64d93e9ba8efa9b5b405bd683c86fd2c65667 let script = ScriptBuf::from_hex("52210375e00eb72e29da82b89367947f29ef34afb75e8654f6ea368e0acdfd92976b7c2103a1b26313f430c4b15bb1fdce663207659d8cac749a0e53d70eff01874496feff2103c96d495bfdd5ba4145e3e046fee45e84a8a48ad05bd8dbb395c011a32cf9f88053ae").unwrap(); - let addr = Address::p2wsh(&script, Bitcoin); + let addr = Address::p2wsh(&script, KnownHrp::Mainnet); assert_eq!( &addr.to_string(), "bc1qwqdg6squsna38e46795at95yu9atm8azzmyvckulcc7kytlcckxswvvzej" @@ -923,7 +924,7 @@ mod tests { ); let program = WitnessProgram::new(WitnessVersion::V13, &program).expect("valid program"); - let addr = Address::from_witness_program(program, Bitcoin); + let addr = Address::from_witness_program(program, KnownHrp::Mainnet); roundtrips(&addr, Bitcoin); } @@ -1090,7 +1091,7 @@ mod tests { ) .unwrap(); let secp = Secp256k1::verification_only(); - let address = Address::p2tr(&secp, internal_key, None, Network::Bitcoin); + let address = Address::p2tr(&secp, internal_key, None, KnownHrp::Mainnet); assert_eq!( address.to_string(), "bc1p5cyxnuxmeuwuvkwfem96lqzszd02n6xdcjrs20cac6yqjjwudpxqkedrcr" @@ -1189,7 +1190,7 @@ mod tests { let pubkey = PublicKey::from_str(pubkey_string).expect("pubkey"); let xonly_pubkey = XOnlyPublicKey::from(pubkey.inner); let tweaked_pubkey = TweakedPublicKey::dangerous_assume_tweaked(xonly_pubkey); - let address = Address::p2tr_tweaked(tweaked_pubkey, Network::Bitcoin); + let address = Address::p2tr_tweaked(tweaked_pubkey, KnownHrp::Mainnet); assert_eq!( address, @@ -1215,7 +1216,7 @@ mod tests { let pubkey = PublicKey::from_str(pubkey_string).expect("pubkey"); let xonly_pubkey = XOnlyPublicKey::from(pubkey.inner); let tweaked_pubkey = TweakedPublicKey::dangerous_assume_tweaked(xonly_pubkey); - let address = Address::p2tr_tweaked(tweaked_pubkey, Network::Bitcoin); + let address = Address::p2tr_tweaked(tweaked_pubkey, KnownHrp::Mainnet); assert_eq!( address, diff --git a/bitcoin/src/lib.rs b/bitcoin/src/lib.rs index f7a4c82e..df95a919 100644 --- a/bitcoin/src/lib.rs +++ b/bitcoin/src/lib.rs @@ -116,7 +116,7 @@ pub mod taproot; #[rustfmt::skip] // Keep public re-exports separate. #[doc(inline)] pub use crate::{ - address::{Address, AddressType}, + address::{Address, AddressType, KnownHrp}, amount::{Amount, Denomination, SignedAmount}, bip158::{FilterHash, FilterHeader}, bip32::XKeyIdentifier, diff --git a/bitcoin/src/taproot/mod.rs b/bitcoin/src/taproot/mod.rs index 32271bf2..203ac314 100644 --- a/bitcoin/src/taproot/mod.rs +++ b/bitcoin/src/taproot/mod.rs @@ -1436,7 +1436,7 @@ mod test { use super::*; use crate::sighash::{TapSighash, TapSighashTag}; - use crate::{Address, Network}; + use crate::{Address, KnownHrp}; extern crate serde_json; #[cfg(feature = "serde")] @@ -1828,7 +1828,7 @@ mod test { let tweak = TapTweakHash::from_key_and_tweak(internal_key, merkle_root); let (output_key, _parity) = internal_key.tap_tweak(secp, merkle_root); - let addr = Address::p2tr(secp, internal_key, merkle_root, Network::Bitcoin); + let addr = Address::p2tr(secp, internal_key, merkle_root, KnownHrp::Mainnet); let spk = addr.script_pubkey(); assert_eq!(expected_output_key, output_key.to_inner());