diff --git a/bitcoin/examples/bip32.rs b/bitcoin/examples/bip32.rs index 98f19673..de027003 100644 --- a/bitcoin/examples/bip32.rs +++ b/bitcoin/examples/bip32.rs @@ -8,7 +8,7 @@ use bitcoin::bip32::{ChildNumber, DerivationPath, Xpriv, Xpub}; use bitcoin::hex::FromHex; use bitcoin::secp256k1::ffi::types::AlignedType; use bitcoin::secp256k1::Secp256k1; -use bitcoin::CompressedPublicKey; +use bitcoin::{Network, NetworkKind, CompressedPublicKey}; fn main() { // This example derives root xprv from a 32-byte seed, @@ -26,10 +26,7 @@ fn main() { let seed_hex = &args[1]; println!("Seed: {}", seed_hex); - - // default network as mainnet - let network = bitcoin::Network::Bitcoin; - println!("Network: {:?}", network); + println!("Using mainnet network"); let seed = Vec::from_hex(seed_hex).unwrap(); @@ -39,7 +36,7 @@ fn main() { let secp = Secp256k1::preallocated_new(buf.as_mut_slice()).unwrap(); // calculate root key from seed - let root = Xpriv::new_master(network, &seed).unwrap(); + let root = Xpriv::new_master(NetworkKind::Main, &seed).unwrap(); println!("Root key: {}", root); // derive child xpub @@ -53,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); + let address = Address::p2wpkh(&CompressedPublicKey(public_key), Network::Bitcoin); println!("First receiving address: {}", address); } diff --git a/bitcoin/src/address/mod.rs b/bitcoin/src/address/mod.rs index 336f63b3..b1843824 100644 --- a/bitcoin/src/address/mod.rs +++ b/bitcoin/src/address/mod.rs @@ -46,7 +46,7 @@ use crate::blockdata::script::witness_program::WitnessProgram; use crate::blockdata::script::witness_version::WitnessVersion; use crate::blockdata::script::{self, PushBytesBuf, Script, ScriptBuf, ScriptHash}; use crate::crypto::key::{PubkeyHash, PublicKey, CompressedPublicKey, TweakedPublicKey, UntweakedPublicKey}; -use crate::network::Network; +use crate::network::{Network, NetworkKind}; use crate::prelude::*; use crate::taproot::TapNodeHash; @@ -135,8 +135,8 @@ impl NetworkValidation for NetworkUnchecked { /// addresses are used only on the appropriate network. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] enum AddressInner { - P2pkh { hash: PubkeyHash, prefix: LegacyP2pkhPrefix }, - P2sh { hash: ScriptHash, prefix: LegacyP2shPrefix }, + P2pkh { hash: PubkeyHash, network: NetworkKind }, + P2sh { hash: ScriptHash, network: NetworkKind }, Segwit { program: WitnessProgram, hrp: KnownHrp }, } @@ -145,15 +145,21 @@ impl fmt::Display for AddressInner { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { use AddressInner::*; match self { - P2pkh { hash, prefix } => { + P2pkh { hash, network } => { let mut prefixed = [0; 21]; - prefixed[0] = prefix.to_u8(); + prefixed[0] = match network { + NetworkKind::Main => PUBKEY_ADDRESS_PREFIX_MAIN, + NetworkKind::Test => PUBKEY_ADDRESS_PREFIX_TEST, + }; prefixed[1..].copy_from_slice(&hash[..]); base58::encode_check_to_fmt(fmt, &prefixed[..]) } - P2sh { hash, prefix } => { + P2sh { hash, network } => { let mut prefixed = [0; 21]; - prefixed[0] = prefix.to_u8(); + prefixed[0] = match network { + NetworkKind::Main => SCRIPT_ADDRESS_PREFIX_MAIN, + NetworkKind::Test => SCRIPT_ADDRESS_PREFIX_TEST, + }; prefixed[1..].copy_from_slice(&hash[..]); base58::encode_check_to_fmt(fmt, &prefixed[..]) } @@ -172,64 +178,6 @@ impl fmt::Display for AddressInner { } } -/// Prefix byte used for legacy P2PKH addresses. -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -enum LegacyP2pkhPrefix { - /// Prefix used for legacy addresses on the main Bitcoin network. - Mainnet, - /// Prefix used for legacy addresses on all other test networks (testnet, signet, regtest). - AllTestnets, -} - -impl LegacyP2pkhPrefix { - /// Creates a legacy prefix from the associated `network`. - fn from_network(network: Network) -> Self { - use Network::*; - - match network { - Bitcoin => Self::Mainnet, - Signet | Testnet | Regtest => Self::AllTestnets, - } - } - - /// Converts this prefix enum to the respective byte value. - fn to_u8(self) -> u8 { - match self { - Self::Mainnet => PUBKEY_ADDRESS_PREFIX_MAIN, - Self::AllTestnets => PUBKEY_ADDRESS_PREFIX_TEST, - } - } -} - -/// Prefix byte used for legacy P2SH addresses. -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -enum LegacyP2shPrefix { - /// Prefix used for legacy addresses on the main Bitcoin network. - Mainnet, - /// Prefix used for legacy addresses on all other test networks (testnet, signet, regtest). - AllTestnets, -} - -impl LegacyP2shPrefix { - /// Creates a legacy prefix from the associated `network`. - fn from_network(network: Network) -> Self { - use Network::*; - - match network { - Bitcoin => Self::Mainnet, - Signet | Testnet | Regtest => Self::AllTestnets, - } - } - - /// Converts this prefix enum to the respective byte value. - fn to_u8(self) -> u8 { - match self { - Self::Mainnet => SCRIPT_ADDRESS_PREFIX_MAIN, - Self::AllTestnets => SCRIPT_ADDRESS_PREFIX_TEST, - } - } -} - /// Known bech32 human-readable parts. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[non_exhaustive] @@ -277,6 +225,10 @@ impl KnownHrp { } } +impl From for KnownHrp { + fn from(n: Network) -> Self { Self::from_network(n) } +} + /// A Bitcoin address. /// /// ### Parsing addresses @@ -412,10 +364,9 @@ impl Address { /// /// This is the preferred non-witness type address. #[inline] - pub fn p2pkh(pk: impl Into, network: Network) -> Address { + pub fn p2pkh(pk: impl Into, network: impl Into) -> Address { let hash = pk.into(); - let prefix = LegacyP2pkhPrefix::from_network(network); - Self(AddressInner::P2pkh { hash, prefix }, PhantomData) + Self(AddressInner::P2pkh { hash, network: network.into() }, PhantomData) } /// Creates a pay to script hash P2SH address from a script. @@ -423,7 +374,7 @@ impl Address { /// This address type was introduced with BIP16 and is the popular type to implement multi-sig /// these days. #[inline] - pub fn p2sh(script: &Script, network: Network) -> Result { + pub fn p2sh(script: &Script, network: impl Into) -> Result { if script.len() > MAX_SCRIPT_ELEMENT_SIZE { return Err(Error::ExcessiveScriptSize); } @@ -432,9 +383,8 @@ impl Address { } // This is intentionally not public so we enforce script length checks. - fn p2sh_from_hash(hash: ScriptHash, network: Network) -> Address { - let prefix = LegacyP2shPrefix::from_network(network); - Self(AddressInner::P2sh { hash, prefix }, PhantomData) + fn p2sh_from_hash(hash: ScriptHash, network: impl Into) -> Address { + Self(AddressInner::P2sh { hash, network: network.into() }, PhantomData) } /// Creates a witness pay to public key address from a public key. @@ -453,8 +403,8 @@ impl Address { /// This is a segwit address type that looks familiar (as p2sh) to legacy clients. pub fn p2shwpkh( pk: &CompressedPublicKey, - network: Network, - ) -> Self { + network: impl Into, + ) -> Address { let builder = script::Builder::new().push_int(0).push_slice(pk.wpubkey_hash()); let script_hash = builder.as_script().script_hash(); Address::p2sh_from_hash(script_hash, network) @@ -469,7 +419,7 @@ impl Address { /// Creates a pay to script address that embeds a witness pay to script hash address. /// /// This is a segwit address type that looks familiar (as p2sh) to legacy clients. - pub fn p2shwsh(script: &Script, network: Network) -> Address { + pub fn p2shwsh(script: &Script, network: impl Into) -> Address { let builder = script::Builder::new().push_int(0).push_slice(script.wscript_hash()); let script_hash = builder.as_script().script_hash(); Address::p2sh_from_hash(script_hash, network) @@ -496,6 +446,7 @@ impl Address { /// /// 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 }; @@ -530,7 +481,7 @@ impl Address { use AddressInner::*; match self.0 { - P2pkh { ref hash, prefix: _ } => Some(*hash), + P2pkh { ref hash, network: _ } => Some(*hash), _ => None, } } @@ -540,7 +491,7 @@ impl Address { use AddressInner::*; match self.0 { - P2sh { ref hash, prefix: _ } => Some(*hash), + P2sh { ref hash, network: _ } => Some(*hash), _ => None, } } @@ -587,9 +538,13 @@ impl Address { pub fn script_pubkey(&self) -> ScriptBuf { use AddressInner::*; match self.0 { - P2pkh { ref hash, prefix: _ } => ScriptBuf::new_p2pkh(hash), - P2sh { ref hash, prefix: _ } => ScriptBuf::new_p2sh(hash), - Segwit { ref program, hrp: _ } => ScriptBuf::new_witness_program(program), + P2pkh { ref hash, network: _ } => ScriptBuf::new_p2pkh(hash), + P2sh { ref hash, network: _ } => ScriptBuf::new_p2sh(hash), + Segwit { ref program, hrp: _ } => { + let prog = program.program(); + let version = program.version(); + ScriptBuf::new_witness_program_unchecked(version, prog) + } } } @@ -650,9 +605,9 @@ impl Address { pub fn matches_script_pubkey(&self, script: &Script) -> bool { use AddressInner::*; match self.0 { - P2pkh { ref hash, prefix: _ } if script.is_p2pkh() => + P2pkh { ref hash, network: _ } if script.is_p2pkh() => &script.as_bytes()[3..23] == >::as_ref(hash), - P2sh { ref hash, prefix: _ } if script.is_p2sh() => + P2sh { ref hash, network: _ } if script.is_p2sh() => &script.as_bytes()[2..22] == >::as_ref(hash), Segwit { ref program, hrp: _ } if script.is_witness_program() => &script.as_bytes()[2..] == program.program().as_bytes(), @@ -671,8 +626,8 @@ impl Address { fn payload_as_bytes(&self) -> &[u8] { use AddressInner::*; match self.0 { - P2sh { ref hash, prefix: _ } => hash.as_ref(), - P2pkh { ref hash, prefix: _ } => hash.as_ref(), + P2sh { ref hash, network: _ } => hash.as_ref(), + P2pkh { ref hash, network: _ } => hash.as_ref(), Segwit { ref program, hrp: _ } => program.program().as_bytes(), } } @@ -706,12 +661,12 @@ impl Address { /// assert!(address.is_valid_for_network(Network::Bitcoin)); /// assert_eq!(address.is_valid_for_network(Network::Testnet), false); /// ``` - pub fn is_valid_for_network(&self, network: Network) -> bool { + pub fn is_valid_for_network(&self, n: Network) -> bool { use AddressInner::*; match self.0 { - P2pkh { hash: _, ref prefix } => *prefix == LegacyP2pkhPrefix::from_network(network), - P2sh { hash: _, ref prefix } => *prefix == LegacyP2shPrefix::from_network(network), - Segwit { program: _, ref hrp } => *hrp == KnownHrp::from_network(network), + P2pkh { hash: _, ref network } => *network == NetworkKind::from(n), + P2sh { hash: _, ref network } => *network == NetworkKind::from(n), + Segwit { program: _, ref hrp } => *hrp == KnownHrp::from_network(n), } } @@ -739,8 +694,8 @@ impl Address { use AddressInner::*; let inner = match self.0 { - P2pkh { hash, prefix } => P2pkh { hash, prefix }, - P2sh { hash, prefix } => P2sh { hash, prefix }, + P2pkh { hash, network } => P2pkh { hash, network }, + P2sh { hash, network } => P2sh { hash, network }, Segwit { program, hrp } => Segwit { program, hrp }, }; Address(inner, PhantomData) @@ -801,19 +756,19 @@ impl FromStr for Address { let inner = match *prefix { PUBKEY_ADDRESS_PREFIX_MAIN => { let hash = PubkeyHash::from_byte_array(data); - AddressInner::P2pkh { hash, prefix: LegacyP2pkhPrefix::Mainnet } + AddressInner::P2pkh { hash, network: NetworkKind::Main } } PUBKEY_ADDRESS_PREFIX_TEST => { let hash = PubkeyHash::from_byte_array(data); - AddressInner::P2pkh { hash, prefix: LegacyP2pkhPrefix::AllTestnets } + AddressInner::P2pkh { hash, network: NetworkKind::Test } } SCRIPT_ADDRESS_PREFIX_MAIN => { let hash = ScriptHash::from_byte_array(data); - AddressInner::P2sh { hash, prefix: LegacyP2shPrefix::Mainnet } + AddressInner::P2sh { hash, network: NetworkKind::Main } } SCRIPT_ADDRESS_PREFIX_TEST => { let hash = ScriptHash::from_byte_array(data); - AddressInner::P2sh { hash, prefix: LegacyP2shPrefix::AllTestnets } + AddressInner::P2sh { hash, network: NetworkKind::Test } } x => return Err(ParseError::Base58(base58::Error::InvalidAddressVersion(x))), }; @@ -868,7 +823,7 @@ mod tests { #[test] fn test_p2pkh_address_58() { let hash = "162c5ea71c0b23f5b9022ef047c4a86470a5b070".parse::().unwrap(); - let addr = Address::p2pkh(hash, Bitcoin); + let addr = Address::p2pkh(hash, NetworkKind::Main); assert_eq!( addr.script_pubkey(), @@ -882,13 +837,13 @@ mod tests { #[test] fn test_p2pkh_from_key() { let key = "048d5141948c1702e8c95f438815794b87f706a8d4cd2bffad1dc1570971032c9b6042a0431ded2478b5c9cf2d81c124a5e57347a3c63ef0e7716cf54d613ba183".parse::().unwrap(); - let addr = Address::p2pkh(key, Bitcoin); + let addr = Address::p2pkh(key, NetworkKind::Main); assert_eq!(&addr.to_string(), "1QJVDzdqb1VpbDK7uDeyVXy9mR27CJiyhY"); let key = "03df154ebfcf29d29cc10d5c2565018bce2d9edbab267c31d2caf44a63056cf99f" .parse::() .unwrap(); - let addr = Address::p2pkh(key, Testnet); + let addr = Address::p2pkh(key, NetworkKind::Test); assert_eq!(&addr.to_string(), "mqkhEMH6NCeYjFybv7pvFC22MFeaNT9AQC"); assert_eq!(addr.address_type(), Some(AddressType::P2pkh)); roundtrips(&addr, Testnet); @@ -897,7 +852,7 @@ mod tests { #[test] fn test_p2sh_address_58() { let hash = "162c5ea71c0b23f5b9022ef047c4a86470a5b070".parse::().unwrap(); - let addr = Address::p2sh_from_hash(hash, Bitcoin); + let addr = Address::p2sh_from_hash(hash, NetworkKind::Main); assert_eq!( addr.script_pubkey(), @@ -911,7 +866,7 @@ mod tests { #[test] fn test_p2sh_parse() { let script = ScriptBuf::from_hex("552103a765fc35b3f210b95223846b36ef62a4e53e34e2925270c2c7906b92c9f718eb2103c327511374246759ec8d0b89fa6c6b23b33e11f92c5bc155409d86de0c79180121038cae7406af1f12f4786d820a1466eec7bc5785a1b5e4a387eca6d797753ef6db2103252bfb9dcaab0cd00353f2ac328954d791270203d66c2be8b430f115f451b8a12103e79412d42372c55dd336f2eb6eb639ef9d74a22041ba79382c74da2338fe58ad21035049459a4ebc00e876a9eef02e72a3e70202d3d1f591fc0dd542f93f642021f82102016f682920d9723c61b27f562eb530c926c00106004798b6471e8c52c60ee02057ae").unwrap(); - let addr = Address::p2sh(&script, Testnet).unwrap(); + let addr = Address::p2sh(&script, NetworkKind::Test).unwrap(); assert_eq!(&addr.to_string(), "2N3zXjbwdTcPsJiy8sUK9FhWJhqQCxA8Jjr"); assert_eq!(addr.address_type(), Some(AddressType::P2sh)); roundtrips(&addr, Testnet); @@ -920,7 +875,7 @@ mod tests { #[test] fn test_p2sh_parse_for_large_script() { let script = ScriptBuf::from_hex("552103a765fc35b3f210b95223846b36ef62a4e53e34e2925270c2c7906b92c9f718eb2103c327511374246759ec8d0b89fa6c6b23b33e11f92c5bc155409d86de0c79180121038cae7406af1f12f4786d820a1466eec7bc5785a1b5e4a387eca6d797753ef6db2103252bfb9dcaab0cd00353f2ac328954d791270203d66c2be8b430f115f451b8a12103e79412d42372c55dd336f2eb6eb639ef9d74a22041ba79382c74da2338fe58ad21035049459a4ebc00e876a9eef02e72a3e70202d3d1f591fc0dd542f93f642021f82102016f682920d9723c61b27f562eb530c926c00106004798b6471e8c52c60ee02057ae12123122313123123ac1231231231231313123131231231231313212313213123123552103a765fc35b3f210b95223846b36ef62a4e53e34e2925270c2c7906b92c9f718eb2103c327511374246759ec8d0b89fa6c6b23b33e11f92c5bc155409d86de0c79180121038cae7406af1f12f4786d820a1466eec7bc5785a1b5e4a387eca6d797753ef6db2103252bfb9dcaab0cd00353f2ac328954d791270203d66c2be8b430f115f451b8a12103e79412d42372c55dd336f2eb6eb639ef9d74a22041ba79382c74da2338fe58ad21035049459a4ebc00e876a9eef02e72a3e70202d3d1f591fc0dd542f93f642021f82102016f682920d9723c61b27f562eb530c926c00106004798b6471e8c52c60ee02057ae12123122313123123ac1231231231231313123131231231231313212313213123123552103a765fc35b3f210b95223846b36ef62a4e53e34e2925270c2c7906b92c9f718eb2103c327511374246759ec8d0b89fa6c6b23b33e11f92c5bc155409d86de0c79180121038cae7406af1f12f4786d820a1466eec7bc5785a1b5e4a387eca6d797753ef6db2103252bfb9dcaab0cd00353f2ac328954d791270203d66c2be8b430f115f451b8a12103e79412d42372c55dd336f2eb6eb639ef9d74a22041ba79382c74da2338fe58ad21035049459a4ebc00e876a9eef02e72a3e70202d3d1f591fc0dd542f93f642021f82102016f682920d9723c61b27f562eb530c926c00106004798b6471e8c52c60ee02057ae12123122313123123ac1231231231231313123131231231231313212313213123123").unwrap(); - assert_eq!(Address::p2sh(&script, Testnet), Err(Error::ExcessiveScriptSize)); + assert_eq!(Address::p2sh(&script, NetworkKind::Test), Err(Error::ExcessiveScriptSize)); } #[test] @@ -954,7 +909,7 @@ mod tests { let key = "026c468be64d22761c30cd2f12cbc7de255d592d7904b1bab07236897cc4c2e766" .parse::() .unwrap(); - let addr = Address::p2shwpkh(&key, Bitcoin); + let addr = Address::p2shwpkh(&key, NetworkKind::Main); assert_eq!(&addr.to_string(), "3QBRmWNqqBGme9er7fMkGqtZtp4gjMFxhE"); assert_eq!(addr.address_type(), Some(AddressType::P2sh)); roundtrips(&addr, Bitcoin); @@ -964,7 +919,7 @@ mod tests { fn test_p2shwsh() { // stolen from Bitcoin transaction f9ee2be4df05041d0e0a35d7caa3157495ca4f93b233234c9967b6901dacf7a9 let script = ScriptBuf::from_hex("522103e5529d8eaa3d559903adb2e881eb06c86ac2574ffa503c45f4e942e2a693b33e2102e5f10fcdcdbab211e0af6a481f5532536ec61a5fdbf7183770cf8680fe729d8152ae").unwrap(); - let addr = Address::p2shwsh(&script, Bitcoin); + let addr = Address::p2shwsh(&script, NetworkKind::Main); assert_eq!(&addr.to_string(), "36EqgNnsWW94SreZgBWc1ANC6wpFZwirHr"); assert_eq!(addr.address_type(), Some(AddressType::P2sh)); roundtrips(&addr, Bitcoin); diff --git a/bitcoin/src/bip32.rs b/bitcoin/src/bip32.rs index ad4dfcf9..5bda3575 100644 --- a/bitcoin/src/bip32.rs +++ b/bitcoin/src/bip32.rs @@ -21,7 +21,7 @@ use serde; use crate::base58; use crate::crypto::key::{self, Keypair, PrivateKey, CompressedPublicKey}; use crate::internal_macros::impl_bytes_newtype; -use crate::network::Network; +use crate::network::NetworkKind; use crate::prelude::*; /// Version bytes for extended public keys on the Bitcoin network. @@ -69,7 +69,7 @@ hash_newtype! { #[cfg_attr(feature = "std", derive(Debug))] pub struct Xpriv { /// The network this key is to be used on - pub network: Network, + pub network: NetworkKind, /// How many derivations this key is from the master (which is 0) pub depth: u8, /// Fingerprint of the parent key (0 for master) @@ -101,8 +101,8 @@ impl fmt::Debug for Xpriv { /// Extended public key #[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)] pub struct Xpub { - /// The network this key is to be used on - pub network: Network, + /// The network kind this key is to be used on + pub network: NetworkKind, /// How many derivations this key is from the master (which is 0) pub depth: u8, /// Fingerprint of the parent key @@ -558,13 +558,13 @@ impl From for Error { impl Xpriv { /// Construct a new master key from a seed value - pub fn new_master(network: Network, seed: &[u8]) -> Result { + pub fn new_master(network: impl Into, seed: &[u8]) -> Result { let mut hmac_engine: HmacEngine = HmacEngine::new(b"Bitcoin seed"); hmac_engine.input(seed); let hmac_result: Hmac = Hmac::from_engine(hmac_engine); Ok(Xpriv { - network, + network: network.into(), depth: 0, parent_fingerprint: Default::default(), child_number: ChildNumber::from_normal_idx(0)?, @@ -645,9 +645,9 @@ impl Xpriv { } let network = if data.starts_with(&VERSION_BYTES_MAINNET_PRIVATE) { - Network::Bitcoin + NetworkKind::Main } else if data.starts_with(&VERSION_BYTES_TESTNETS_PRIVATE) { - Network::Testnet + NetworkKind::Test } else { let (b0, b1, b2, b3) = (data[0], data[1], data[2], data[3]); return Err(Error::UnknownVersion([b0, b1, b2, b3])); @@ -671,8 +671,8 @@ impl Xpriv { pub fn encode(&self) -> [u8; 78] { let mut ret = [0; 78]; ret[0..4].copy_from_slice(&match self.network { - Network::Bitcoin => VERSION_BYTES_MAINNET_PRIVATE, - Network::Testnet | Network::Signet | Network::Regtest => VERSION_BYTES_TESTNETS_PRIVATE, + NetworkKind::Main => VERSION_BYTES_MAINNET_PRIVATE, + NetworkKind::Test => VERSION_BYTES_TESTNETS_PRIVATE, }); ret[4] = self.depth; ret[5..9].copy_from_slice(&self.parent_fingerprint[..]); @@ -777,9 +777,9 @@ impl Xpub { } let network = if data.starts_with(&VERSION_BYTES_MAINNET_PUBLIC) { - Network::Bitcoin + NetworkKind::Main } else if data.starts_with(&VERSION_BYTES_TESTNETS_PUBLIC) { - Network::Testnet + NetworkKind::Test } else { let (b0, b1, b2, b3) = (data[0], data[1], data[2], data[3]); return Err(Error::UnknownVersion([b0, b1, b2, b3])); @@ -803,8 +803,8 @@ impl Xpub { pub fn encode(&self) -> [u8; 78] { let mut ret = [0; 78]; ret[0..4].copy_from_slice(&match self.network { - Network::Bitcoin => VERSION_BYTES_MAINNET_PUBLIC, - Network::Testnet | Network::Signet | Network::Regtest => VERSION_BYTES_TESTNETS_PUBLIC, + NetworkKind::Main => VERSION_BYTES_MAINNET_PUBLIC, + NetworkKind::Test => VERSION_BYTES_TESTNETS_PUBLIC, }); ret[4] = self.depth; ret[5..9].copy_from_slice(&self.parent_fingerprint[..]); @@ -884,7 +884,6 @@ mod tests { use super::ChildNumber::{Hardened, Normal}; use super::*; - use crate::network::Network::{self, Bitcoin}; #[test] fn test_parse_derivation_path() { @@ -965,7 +964,7 @@ mod tests { fn test_path( secp: &Secp256k1, - network: Network, + network: NetworkKind, seed: &[u8], path: DerivationPath, expected_sk: &str, @@ -1060,32 +1059,32 @@ mod tests { let seed = hex!("000102030405060708090a0b0c0d0e0f"); // m - test_path(&secp, Bitcoin, &seed, "m".parse().unwrap(), + test_path(&secp, NetworkKind::Main, &seed, "m".parse().unwrap(), "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi", "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"); // m/0h - test_path(&secp, Bitcoin, &seed, "m/0h".parse().unwrap(), + test_path(&secp, NetworkKind::Main, &seed, "m/0h".parse().unwrap(), "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7", "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw"); // m/0h/1 - test_path(&secp, Bitcoin, &seed, "m/0h/1".parse().unwrap(), + test_path(&secp, NetworkKind::Main, &seed, "m/0h/1".parse().unwrap(), "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs", "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ"); // m/0h/1/2h - test_path(&secp, Bitcoin, &seed, "m/0h/1/2h".parse().unwrap(), + test_path(&secp, NetworkKind::Main, &seed, "m/0h/1/2h".parse().unwrap(), "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM", "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5"); // m/0h/1/2h/2 - test_path(&secp, Bitcoin, &seed, "m/0h/1/2h/2".parse().unwrap(), + test_path(&secp, NetworkKind::Main, &seed, "m/0h/1/2h/2".parse().unwrap(), "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334", "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV"); // m/0h/1/2h/2/1000000000 - test_path(&secp, Bitcoin, &seed, "m/0h/1/2h/2/1000000000".parse().unwrap(), + test_path(&secp, NetworkKind::Main, &seed, "m/0h/1/2h/2/1000000000".parse().unwrap(), "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76", "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy"); } @@ -1096,32 +1095,32 @@ mod tests { let seed = hex!("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542"); // m - test_path(&secp, Bitcoin, &seed, "m".parse().unwrap(), + test_path(&secp, NetworkKind::Main, &seed, "m".parse().unwrap(), "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U", "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB"); // m/0 - test_path(&secp, Bitcoin, &seed, "m/0".parse().unwrap(), + test_path(&secp, NetworkKind::Main, &seed, "m/0".parse().unwrap(), "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt", "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH"); // m/0/2147483647h - test_path(&secp, Bitcoin, &seed, "m/0/2147483647h".parse().unwrap(), + test_path(&secp, NetworkKind::Main, &seed, "m/0/2147483647h".parse().unwrap(), "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9", "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a"); // m/0/2147483647h/1 - test_path(&secp, Bitcoin, &seed, "m/0/2147483647h/1".parse().unwrap(), + test_path(&secp, NetworkKind::Main, &seed, "m/0/2147483647h/1".parse().unwrap(), "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef", "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon"); // m/0/2147483647h/1/2147483646h - test_path(&secp, Bitcoin, &seed, "m/0/2147483647h/1/2147483646h".parse().unwrap(), + test_path(&secp, NetworkKind::Main, &seed, "m/0/2147483647h/1/2147483646h".parse().unwrap(), "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc", "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL"); // m/0/2147483647h/1/2147483646h/2 - test_path(&secp, Bitcoin, &seed, "m/0/2147483647h/1/2147483646h/2".parse().unwrap(), + test_path(&secp, NetworkKind::Main, &seed, "m/0/2147483647h/1/2147483646h/2".parse().unwrap(), "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j", "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt"); } @@ -1132,12 +1131,12 @@ mod tests { let seed = hex!("4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be"); // m - test_path(&secp, Bitcoin, &seed, "m".parse().unwrap(), + test_path(&secp, NetworkKind::Main, &seed, "m".parse().unwrap(), "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6", "xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13"); // m/0h - test_path(&secp, Bitcoin, &seed, "m/0h".parse().unwrap(), + test_path(&secp, NetworkKind::Main, &seed, "m/0h".parse().unwrap(), "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L", "xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y"); } @@ -1200,7 +1199,7 @@ mod tests { } let xpriv = Xpriv { - network: Network::Bitcoin, + network: NetworkKind::Main, depth: 0, parent_fingerprint: Default::default(), child_number: ChildNumber::Normal { index: 0 }, diff --git a/bitcoin/src/crypto/key.rs b/bitcoin/src/crypto/key.rs index ba7cf541..97e0014e 100644 --- a/bitcoin/src/crypto/key.rs +++ b/bitcoin/src/crypto/key.rs @@ -16,7 +16,7 @@ use io::{Read, Write}; use crate::crypto::ecdsa; use crate::internal_macros::impl_asref_push_bytes; -use crate::network::Network; +use crate::network::NetworkKind; use crate::prelude::*; use crate::taproot::{TapNodeHash, TapTweakHash}; use crate::{base58, io}; @@ -390,8 +390,8 @@ impl From<&CompressedPublicKey> for WPubkeyHash { pub struct PrivateKey { /// Whether this private key should be serialized as compressed pub compressed: bool, - /// The network on which this key should be used - pub network: Network, + /// The network kind on which this key should be used + pub network: NetworkKind, /// The actual ECDSA key pub inner: secp256k1::SecretKey, } @@ -400,20 +400,23 @@ impl PrivateKey { /// Constructs new compressed ECDSA private key using the secp256k1 algorithm and /// a secure random number generator. #[cfg(feature = "rand-std")] - pub fn generate(network: Network) -> PrivateKey { + pub fn generate(network: impl Into) -> PrivateKey { let secret_key = secp256k1::SecretKey::new(&mut rand::thread_rng()); - PrivateKey::new(secret_key, network) + PrivateKey::new(secret_key, network.into()) } /// Constructs compressed ECDSA private key from the provided generic Secp256k1 private key /// and the specified network - pub fn new(key: secp256k1::SecretKey, network: Network) -> PrivateKey { - PrivateKey { compressed: true, network, inner: key } + pub fn new(key: secp256k1::SecretKey, network: impl Into) -> PrivateKey { + PrivateKey { compressed: true, network: network.into(), inner: key } } /// Constructs uncompressed (legacy) ECDSA private key from the provided generic Secp256k1 /// private key and the specified network - pub fn new_uncompressed(key: secp256k1::SecretKey, network: Network) -> PrivateKey { - PrivateKey { compressed: false, network, inner: key } + pub fn new_uncompressed( + key: secp256k1::SecretKey, + network: impl Into, + ) -> PrivateKey { + PrivateKey { compressed: false, network: network.into(), inner: key } } /// Creates a public key from this private key @@ -428,17 +431,16 @@ impl PrivateKey { pub fn to_bytes(self) -> Vec { self.inner[..].to_vec() } /// Deserialize a private key from a slice - pub fn from_slice(data: &[u8], network: Network) -> Result { + pub fn from_slice(data: &[u8], network: impl Into) -> Result { Ok(PrivateKey::new(secp256k1::SecretKey::from_slice(data)?, network)) } /// Format the private key to WIF format. + #[rustfmt::skip] pub fn fmt_wif(&self, fmt: &mut dyn fmt::Write) -> fmt::Result { let mut ret = [0; 34]; - ret[0] = match self.network { - Network::Bitcoin => 128, - Network::Testnet | Network::Signet | Network::Regtest => 239, - }; + ret[0] = if self.network.is_mainnet() { 128 } else { 239 }; + ret[1..33].copy_from_slice(&self.inner[..]); let privkey = if self.compressed { ret[33] = 1; @@ -470,8 +472,8 @@ impl PrivateKey { }; let network = match data[0] { - 128 => Network::Bitcoin, - 239 => Network::Testnet, + 128 => NetworkKind::Main, + 239 => NetworkKind::Test, x => { return Err(Error::Base58(base58::Error::InvalidAddressVersion(x))); } @@ -953,14 +955,14 @@ mod tests { use super::*; use crate::address::Address; - use crate::network::Network::{Bitcoin, Testnet}; + use crate::network::NetworkKind; #[test] fn test_key_derivation() { // testnet compressed let sk = PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy").unwrap(); - assert_eq!(sk.network, Testnet); + assert_eq!(sk.network, NetworkKind::Test); assert!(sk.compressed); assert_eq!(&sk.to_wif(), "cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy"); @@ -977,7 +979,7 @@ mod tests { // mainnet uncompressed let sk = PrivateKey::from_wif("5JYkZjmN7PVMjJUfJWfRFwtuXTGB439XV6faajeHPAM9Z2PT2R3").unwrap(); - assert_eq!(sk.network, Bitcoin); + assert_eq!(sk.network, NetworkKind::Main); assert!(!sk.compressed); assert_eq!(&sk.to_wif(), "5JYkZjmN7PVMjJUfJWfRFwtuXTGB439XV6faajeHPAM9Z2PT2R3"); @@ -1295,7 +1297,7 @@ mod tests { fn private_key_debug_is_obfuscated() { let sk = PrivateKey::from_str("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy").unwrap(); - let want = "PrivateKey { compressed: true, network: Testnet, inner: SecretKey(#32014e414fdce702) }"; + let want = "PrivateKey { compressed: true, network: Test, inner: SecretKey(#32014e414fdce702) }"; let got = format!("{:?}", sk); assert_eq!(got, want) } diff --git a/bitcoin/src/lib.rs b/bitcoin/src/lib.rs index 53b94258..0ebbe5a2 100644 --- a/bitcoin/src/lib.rs +++ b/bitcoin/src/lib.rs @@ -129,7 +129,7 @@ pub use crate::{ crypto::key::{self, PrivateKey, PubkeyHash, PublicKey, CompressedPublicKey, WPubkeyHash, XOnlyPublicKey}, crypto::sighash::{self, LegacySighash, SegwitV0Sighash, TapSighash, TapSighashTag}, merkle_tree::MerkleBlock, - network::Network, + network::{Network, NetworkKind}, pow::{CompactTarget, Target, Work}, psbt::Psbt, sighash::{EcdsaSighashType, TapSighashType}, diff --git a/bitcoin/src/network.rs b/bitcoin/src/network.rs index 32102715..9c76d70f 100644 --- a/bitcoin/src/network.rs +++ b/bitcoin/src/network.rs @@ -31,6 +31,33 @@ use crate::constants::ChainHash; use crate::p2p::Magic; use crate::prelude::{String, ToOwned}; +/// What kind of network we are on. +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum NetworkKind { + /// The Bitcoin mainnet network. + Main, + /// Some kind of testnet network. + Test, +} + +// We explicitly do not provide `is_testnet`, using `!network.is_mainnet()` is less +// ambiguous due to confusion caused by signet/testnet/regtest. +impl NetworkKind { + /// Returns true if this is real mainnet bitcoin. + pub fn is_mainnet(&self) -> bool { *self == NetworkKind::Main } +} + +impl From for NetworkKind { + fn from(n: Network) -> Self { + use Network::*; + + match n { + Bitcoin => NetworkKind::Main, + Testnet | Signet | Regtest => NetworkKind::Test, + } + } +} + /// The cryptocurrency network to act on. #[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] diff --git a/bitcoin/src/psbt/mod.rs b/bitcoin/src/psbt/mod.rs index 925ea413..4581e770 100644 --- a/bitcoin/src/psbt/mod.rs +++ b/bitcoin/src/psbt/mod.rs @@ -1014,7 +1014,7 @@ mod tests { use crate::blockdata::script::ScriptBuf; use crate::blockdata::transaction::{self, OutPoint, Sequence, Transaction, TxIn, TxOut}; use crate::blockdata::witness::Witness; - use crate::network::Network::Bitcoin; + use crate::network::NetworkKind; use crate::psbt::map::{Input, Output}; use crate::psbt::raw; use crate::psbt::serialize::{Deserialize, Serialize}; @@ -1151,7 +1151,7 @@ mod tests { let mut hd_keypaths: BTreeMap = Default::default(); - let mut sk: Xpriv = Xpriv::new_master(Bitcoin, &seed).unwrap(); + let mut sk: Xpriv = Xpriv::new_master(NetworkKind::Main, &seed).unwrap(); let fprint = sk.fingerprint(secp); @@ -1926,7 +1926,7 @@ mod tests { let secp = Secp256k1::new(); let sk = SecretKey::new(&mut thread_rng()); - let priv_key = PrivateKey::new(sk, crate::Network::Regtest); + let priv_key = PrivateKey::new(sk, NetworkKind::Test); let pk = PublicKey::from_private_key(&secp, &priv_key); (priv_key, pk, secp) diff --git a/bitcoin/src/sign_message.rs b/bitcoin/src/sign_message.rs index c543c4ff..c16bc810 100644 --- a/bitcoin/src/sign_message.rs +++ b/bitcoin/src/sign_message.rs @@ -226,7 +226,7 @@ mod tests { use secp256k1; - use crate::{Address, AddressType, Network}; + use crate::{Address, AddressType, Network, NetworkKind}; let secp = secp256k1::Secp256k1::new(); let message = "rust-bitcoin MessageSignature test"; @@ -243,12 +243,14 @@ mod tests { .try_into() .expect("compressed was set to true"); + let p2pkh = Address::p2pkh(pubkey, NetworkKind::Main); + assert_eq!(signature2.is_signed_by_address(&secp, &p2pkh, msg_hash), Ok(true)); let p2wpkh = Address::p2wpkh(&pubkey, Network::Bitcoin); assert_eq!( signature2.is_signed_by_address(&secp, &p2wpkh, msg_hash), Err(MessageSignatureError::UnsupportedAddressType(AddressType::P2wpkh)) ); - let p2shwpkh = Address::p2shwpkh(&pubkey, Network::Bitcoin); + let p2shwpkh = Address::p2shwpkh(&pubkey, NetworkKind::Main); assert_eq!( signature2.is_signed_by_address(&secp, &p2shwpkh, msg_hash), Err(MessageSignatureError::UnsupportedAddressType(AddressType::P2sh)) @@ -266,7 +268,7 @@ mod tests { use secp256k1; use crate::crypto::key::PublicKey; - use crate::{Address, Network}; + use crate::{Address, NetworkKind}; let secp = secp256k1::Secp256k1::new(); let message = "a different message from what was signed"; @@ -283,7 +285,7 @@ mod tests { PublicKey::from_slice(&BASE64_STANDARD.decode(pubkey_base64).expect("base64 string")) .expect("pubkey slice"); - let p2pkh = Address::p2pkh(pubkey, Network::Bitcoin); + let p2pkh = Address::p2pkh(pubkey, NetworkKind::Main); assert_eq!(signature.is_signed_by_address(&secp, &p2pkh, msg_hash), Ok(false)); } } diff --git a/bitcoin/tests/psbt.rs b/bitcoin/tests/psbt.rs index 7ad4bda5..f8d51b13 100644 --- a/bitcoin/tests/psbt.rs +++ b/bitcoin/tests/psbt.rs @@ -13,12 +13,10 @@ use bitcoin::psbt::{Psbt, PsbtSighashType}; use bitcoin::script::PushBytes; use bitcoin::secp256k1::{self, Secp256k1}; use bitcoin::{ - absolute, Amount, Denomination, Network, OutPoint, PrivateKey, PublicKey, ScriptBuf, Sequence, - Transaction, TxIn, TxOut, Witness, + absolute, Amount, Denomination, NetworkKind, OutPoint, PrivateKey, PublicKey, ScriptBuf, + Sequence, Transaction, TxIn, TxOut, Witness, }; -const NETWORK: Network = Network::Testnet; - #[track_caller] fn hex_psbt(s: &str) -> Psbt { let v: Vec = Vec::from_hex(s).expect("valid hex digits"); @@ -124,7 +122,7 @@ fn build_extended_private_key() -> Xpriv { let xpriv = Xpriv::from_str(extended_private_key).unwrap(); let sk = PrivateKey::from_wif(seed).unwrap(); - let seeded = Xpriv::new_master(NETWORK, &sk.inner.secret_bytes()).unwrap(); + let seeded = Xpriv::new_master(NetworkKind::Test, &sk.inner.secret_bytes()).unwrap(); assert_eq!(xpriv, seeded); xpriv diff --git a/bitcoin/tests/serde.rs b/bitcoin/tests/serde.rs index 430e9b6c..04686a7c 100644 --- a/bitcoin/tests/serde.rs +++ b/bitcoin/tests/serde.rs @@ -38,7 +38,7 @@ use bitcoin::psbt::{Input, Output, Psbt, PsbtSighashType}; use bitcoin::sighash::{EcdsaSighashType, TapSighashType}; use bitcoin::taproot::{self, ControlBlock, LeafVersion, TapTree, TaprootBuilder}; use bitcoin::{ - ecdsa, transaction, Address, Amount, Block, Network, OutPoint, PrivateKey, PublicKey, + ecdsa, transaction, Address, Amount, Block, NetworkKind, OutPoint, PrivateKey, PublicKey, ScriptBuf, Sequence, Target, Transaction, TxIn, TxOut, Txid, Work, }; @@ -145,7 +145,7 @@ fn serde_regression_witness() { fn serde_regression_address() { let s = include_str!("data/serde/public_key_hex"); let pk = PublicKey::from_str(s.trim()).unwrap(); - let addr = Address::p2pkh(pk, Network::Bitcoin); + let addr = Address::p2pkh(pk, NetworkKind::Main); let got = serialize(&addr).unwrap(); let want = include_bytes!("data/serde/address_bincode") as &[_];