Rename xpub and xpriv types
The BIP-32 extended public key and extended private key exist in the Bitcoin vernacular as xpub and xpriv. We can use these terms with no loss of clarity. Rename our current BIP-32 types - `ExtendedPubKey` to `Xpub` - `ExtendedPrivKey` to `Xpriv` This patch is a mechanical search-and-replace, followed by running the formatter, no other manual changes.
This commit is contained in:
parent
5bf2117dc4
commit
be05f9d852
|
@ -4,7 +4,7 @@ use std::str::FromStr;
|
||||||
use std::{env, process};
|
use std::{env, process};
|
||||||
|
|
||||||
use bitcoin::address::Address;
|
use bitcoin::address::Address;
|
||||||
use bitcoin::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey};
|
use bitcoin::bip32::{ChildNumber, DerivationPath, Xpriv, Xpub};
|
||||||
use bitcoin::hex::FromHex;
|
use bitcoin::hex::FromHex;
|
||||||
use bitcoin::secp256k1::ffi::types::AlignedType;
|
use bitcoin::secp256k1::ffi::types::AlignedType;
|
||||||
use bitcoin::secp256k1::Secp256k1;
|
use bitcoin::secp256k1::Secp256k1;
|
||||||
|
@ -39,14 +39,14 @@ fn main() {
|
||||||
let secp = Secp256k1::preallocated_new(buf.as_mut_slice()).unwrap();
|
let secp = Secp256k1::preallocated_new(buf.as_mut_slice()).unwrap();
|
||||||
|
|
||||||
// calculate root key from seed
|
// calculate root key from seed
|
||||||
let root = ExtendedPrivKey::new_master(network, &seed).unwrap();
|
let root = Xpriv::new_master(network, &seed).unwrap();
|
||||||
println!("Root key: {}", root);
|
println!("Root key: {}", root);
|
||||||
|
|
||||||
// derive child xpub
|
// derive child xpub
|
||||||
let path = DerivationPath::from_str("m/84h/0h/0h").unwrap();
|
let path = DerivationPath::from_str("m/84h/0h/0h").unwrap();
|
||||||
let child = root.derive_priv(&secp, &path).unwrap();
|
let child = root.derive_priv(&secp, &path).unwrap();
|
||||||
println!("Child at {}: {}", path, child);
|
println!("Child at {}: {}", path, child);
|
||||||
let xpub = ExtendedPubKey::from_priv(&secp, &child);
|
let xpub = Xpub::from_priv(&secp, &child);
|
||||||
println!("Public key at {}: {}", path, xpub);
|
println!("Public key at {}: {}", path, xpub);
|
||||||
|
|
||||||
// generate first receiving address at m/0/0
|
// generate first receiving address at m/0/0
|
||||||
|
|
|
@ -33,9 +33,7 @@ use std::collections::BTreeMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use bitcoin::bip32::{
|
use bitcoin::bip32::{ChildNumber, DerivationPath, Fingerprint, IntoDerivationPath, Xpriv, Xpub};
|
||||||
ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey, Fingerprint, IntoDerivationPath,
|
|
||||||
};
|
|
||||||
use bitcoin::consensus::encode;
|
use bitcoin::consensus::encode;
|
||||||
use bitcoin::locktime::absolute;
|
use bitcoin::locktime::absolute;
|
||||||
use bitcoin::psbt::{self, Input, Psbt, PsbtSighashType};
|
use bitcoin::psbt::{self, Input, Psbt, PsbtSighashType};
|
||||||
|
@ -97,14 +95,14 @@ fn main() -> Result<()> {
|
||||||
/// An example of an offline signer i.e., a cold-storage device.
|
/// An example of an offline signer i.e., a cold-storage device.
|
||||||
struct ColdStorage {
|
struct ColdStorage {
|
||||||
/// The master extended private key.
|
/// The master extended private key.
|
||||||
master_xpriv: ExtendedPrivKey,
|
master_xpriv: Xpriv,
|
||||||
/// The master extended public key.
|
/// The master extended public key.
|
||||||
master_xpub: ExtendedPubKey,
|
master_xpub: Xpub,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The data exported from an offline wallet to enable creation of a watch-only online wallet.
|
/// The data exported from an offline wallet to enable creation of a watch-only online wallet.
|
||||||
/// (wallet, fingerprint, account_0_xpub, input_utxo_xpub)
|
/// (wallet, fingerprint, account_0_xpub, input_utxo_xpub)
|
||||||
type ExportData = (ColdStorage, Fingerprint, ExtendedPubKey, ExtendedPubKey);
|
type ExportData = (ColdStorage, Fingerprint, Xpub, Xpub);
|
||||||
|
|
||||||
impl ColdStorage {
|
impl ColdStorage {
|
||||||
/// Constructs a new `ColdStorage` signer.
|
/// Constructs a new `ColdStorage` signer.
|
||||||
|
@ -113,18 +111,18 @@ impl ColdStorage {
|
||||||
///
|
///
|
||||||
/// The newly created signer along with the data needed to configure a watch-only wallet.
|
/// The newly created signer along with the data needed to configure a watch-only wallet.
|
||||||
fn new<C: Signing>(secp: &Secp256k1<C>, xpriv: &str) -> Result<ExportData> {
|
fn new<C: Signing>(secp: &Secp256k1<C>, xpriv: &str) -> Result<ExportData> {
|
||||||
let master_xpriv = ExtendedPrivKey::from_str(xpriv)?;
|
let master_xpriv = Xpriv::from_str(xpriv)?;
|
||||||
let master_xpub = ExtendedPubKey::from_priv(secp, &master_xpriv);
|
let master_xpub = Xpub::from_priv(secp, &master_xpriv);
|
||||||
|
|
||||||
// Hardened children require secret data to derive.
|
// Hardened children require secret data to derive.
|
||||||
|
|
||||||
let path = "m/84h/0h/0h".into_derivation_path()?;
|
let path = "m/84h/0h/0h".into_derivation_path()?;
|
||||||
let account_0_xpriv = master_xpriv.derive_priv(secp, &path)?;
|
let account_0_xpriv = master_xpriv.derive_priv(secp, &path)?;
|
||||||
let account_0_xpub = ExtendedPubKey::from_priv(secp, &account_0_xpriv);
|
let account_0_xpub = Xpub::from_priv(secp, &account_0_xpriv);
|
||||||
|
|
||||||
let path = INPUT_UTXO_DERIVATION_PATH.into_derivation_path()?;
|
let path = INPUT_UTXO_DERIVATION_PATH.into_derivation_path()?;
|
||||||
let input_xpriv = master_xpriv.derive_priv(secp, &path)?;
|
let input_xpriv = master_xpriv.derive_priv(secp, &path)?;
|
||||||
let input_xpub = ExtendedPubKey::from_priv(secp, &input_xpriv);
|
let input_xpub = Xpub::from_priv(secp, &input_xpriv);
|
||||||
|
|
||||||
let wallet = ColdStorage { master_xpriv, master_xpub };
|
let wallet = ColdStorage { master_xpriv, master_xpub };
|
||||||
let fingerprint = wallet.master_fingerprint();
|
let fingerprint = wallet.master_fingerprint();
|
||||||
|
@ -151,9 +149,9 @@ impl ColdStorage {
|
||||||
/// An example of an watch-only online wallet.
|
/// An example of an watch-only online wallet.
|
||||||
struct WatchOnly {
|
struct WatchOnly {
|
||||||
/// The xpub for account 0 derived from derivation path "m/84h/0h/0h".
|
/// The xpub for account 0 derived from derivation path "m/84h/0h/0h".
|
||||||
account_0_xpub: ExtendedPubKey,
|
account_0_xpub: Xpub,
|
||||||
/// The xpub derived from `INPUT_UTXO_DERIVATION_PATH`.
|
/// The xpub derived from `INPUT_UTXO_DERIVATION_PATH`.
|
||||||
input_xpub: ExtendedPubKey,
|
input_xpub: Xpub,
|
||||||
/// The master extended pubkey fingerprint.
|
/// The master extended pubkey fingerprint.
|
||||||
master_fingerprint: Fingerprint,
|
master_fingerprint: Fingerprint,
|
||||||
}
|
}
|
||||||
|
@ -166,11 +164,7 @@ impl WatchOnly {
|
||||||
///
|
///
|
||||||
/// The reason for importing the `input_xpub` is so one can use bitcoind to grab a valid input
|
/// The reason for importing the `input_xpub` is so one can use bitcoind to grab a valid input
|
||||||
/// to verify the workflow presented in this file.
|
/// to verify the workflow presented in this file.
|
||||||
fn new(
|
fn new(account_0_xpub: Xpub, input_xpub: Xpub, master_fingerprint: Fingerprint) -> Self {
|
||||||
account_0_xpub: ExtendedPubKey,
|
|
||||||
input_xpub: ExtendedPubKey,
|
|
||||||
master_fingerprint: Fingerprint,
|
|
||||||
) -> Self {
|
|
||||||
WatchOnly { account_0_xpub, input_xpub, master_fingerprint }
|
WatchOnly { account_0_xpub, input_xpub, master_fingerprint }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ const UTXO_3: P2trUtxo = P2trUtxo {
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use bitcoin::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey, Fingerprint};
|
use bitcoin::bip32::{ChildNumber, DerivationPath, Fingerprint, Xpriv, Xpub};
|
||||||
use bitcoin::consensus::encode;
|
use bitcoin::consensus::encode;
|
||||||
use bitcoin::key::{TapTweak, XOnlyPublicKey};
|
use bitcoin::key::{TapTweak, XOnlyPublicKey};
|
||||||
use bitcoin::opcodes::all::{OP_CHECKSIG, OP_CLTV, OP_DROP};
|
use bitcoin::opcodes::all::{OP_CHECKSIG, OP_CLTV, OP_DROP};
|
||||||
|
@ -114,7 +114,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let tx_hex_string = encode::serialize_hex(&generate_bip86_key_spend_tx(
|
let tx_hex_string = encode::serialize_hex(&generate_bip86_key_spend_tx(
|
||||||
&secp,
|
&secp,
|
||||||
// The master extended private key from the descriptor in step 4
|
// The master extended private key from the descriptor in step 4
|
||||||
ExtendedPrivKey::from_str(BENEFACTOR_XPRIV_STR)?,
|
Xpriv::from_str(BENEFACTOR_XPRIV_STR)?,
|
||||||
// Set these fields with valid data for the UTXO from step 5 above
|
// Set these fields with valid data for the UTXO from step 5 above
|
||||||
UTXO_1,
|
UTXO_1,
|
||||||
vec![
|
vec![
|
||||||
|
@ -133,11 +133,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
println!("START EXAMPLE 2 - Script path spending of inheritance UTXO\n");
|
println!("START EXAMPLE 2 - Script path spending of inheritance UTXO\n");
|
||||||
|
|
||||||
{
|
{
|
||||||
let beneficiary =
|
let beneficiary = BeneficiaryWallet::new(Xpriv::from_str(BENEFICIARY_XPRIV_STR)?)?;
|
||||||
BeneficiaryWallet::new(ExtendedPrivKey::from_str(BENEFICIARY_XPRIV_STR)?)?;
|
|
||||||
|
|
||||||
let mut benefactor = BenefactorWallet::new(
|
let mut benefactor = BenefactorWallet::new(
|
||||||
ExtendedPrivKey::from_str(BENEFACTOR_XPRIV_STR)?,
|
Xpriv::from_str(BENEFACTOR_XPRIV_STR)?,
|
||||||
beneficiary.master_xpub(),
|
beneficiary.master_xpub(),
|
||||||
)?;
|
)?;
|
||||||
let (tx, psbt) = benefactor.create_inheritance_funding_tx(
|
let (tx, psbt) = benefactor.create_inheritance_funding_tx(
|
||||||
|
@ -172,11 +171,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
println!("START EXAMPLE 3 - Key path spending of inheritance UTXO\n");
|
println!("START EXAMPLE 3 - Key path spending of inheritance UTXO\n");
|
||||||
|
|
||||||
{
|
{
|
||||||
let beneficiary =
|
let beneficiary = BeneficiaryWallet::new(Xpriv::from_str(BENEFICIARY_XPRIV_STR)?)?;
|
||||||
BeneficiaryWallet::new(ExtendedPrivKey::from_str(BENEFICIARY_XPRIV_STR)?)?;
|
|
||||||
|
|
||||||
let mut benefactor = BenefactorWallet::new(
|
let mut benefactor = BenefactorWallet::new(
|
||||||
ExtendedPrivKey::from_str(BENEFACTOR_XPRIV_STR)?,
|
Xpriv::from_str(BENEFACTOR_XPRIV_STR)?,
|
||||||
beneficiary.master_xpub(),
|
beneficiary.master_xpub(),
|
||||||
)?;
|
)?;
|
||||||
let (tx, _) = benefactor.create_inheritance_funding_tx(
|
let (tx, _) = benefactor.create_inheritance_funding_tx(
|
||||||
|
@ -221,7 +219,7 @@ struct P2trUtxo<'a> {
|
||||||
|
|
||||||
fn generate_bip86_key_spend_tx(
|
fn generate_bip86_key_spend_tx(
|
||||||
secp: &secp256k1::Secp256k1<secp256k1::All>,
|
secp: &secp256k1::Secp256k1<secp256k1::All>,
|
||||||
master_xpriv: ExtendedPrivKey,
|
master_xpriv: Xpriv,
|
||||||
input_utxo: P2trUtxo,
|
input_utxo: P2trUtxo,
|
||||||
outputs: Vec<TxOut>,
|
outputs: Vec<TxOut>,
|
||||||
) -> Result<Transaction, Box<dyn std::error::Error>> {
|
) -> Result<Transaction, Box<dyn std::error::Error>> {
|
||||||
|
@ -335,8 +333,8 @@ fn generate_bip86_key_spend_tx(
|
||||||
/// A wallet that allows creating and spending from an inheritance directly via the key path for purposes
|
/// A wallet that allows creating and spending from an inheritance directly via the key path for purposes
|
||||||
/// of refreshing the inheritance timelock or changing other spending conditions.
|
/// of refreshing the inheritance timelock or changing other spending conditions.
|
||||||
struct BenefactorWallet {
|
struct BenefactorWallet {
|
||||||
master_xpriv: ExtendedPrivKey,
|
master_xpriv: Xpriv,
|
||||||
beneficiary_xpub: ExtendedPubKey,
|
beneficiary_xpub: Xpub,
|
||||||
current_spend_info: Option<TaprootSpendInfo>,
|
current_spend_info: Option<TaprootSpendInfo>,
|
||||||
next_psbt: Option<Psbt>,
|
next_psbt: Option<Psbt>,
|
||||||
secp: Secp256k1<secp256k1::All>,
|
secp: Secp256k1<secp256k1::All>,
|
||||||
|
@ -345,8 +343,8 @@ struct BenefactorWallet {
|
||||||
|
|
||||||
impl BenefactorWallet {
|
impl BenefactorWallet {
|
||||||
fn new(
|
fn new(
|
||||||
master_xpriv: ExtendedPrivKey,
|
master_xpriv: Xpriv,
|
||||||
beneficiary_xpub: ExtendedPubKey,
|
beneficiary_xpub: Xpub,
|
||||||
) -> Result<Self, Box<dyn std::error::Error>> {
|
) -> Result<Self, Box<dyn std::error::Error>> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
master_xpriv,
|
master_xpriv,
|
||||||
|
@ -615,18 +613,16 @@ impl BenefactorWallet {
|
||||||
/// A wallet that allows spending from an inheritance locked to a P2TR UTXO via a script path
|
/// A wallet that allows spending from an inheritance locked to a P2TR UTXO via a script path
|
||||||
/// after some expiry using CLTV.
|
/// after some expiry using CLTV.
|
||||||
struct BeneficiaryWallet {
|
struct BeneficiaryWallet {
|
||||||
master_xpriv: ExtendedPrivKey,
|
master_xpriv: Xpriv,
|
||||||
secp: secp256k1::Secp256k1<secp256k1::All>,
|
secp: secp256k1::Secp256k1<secp256k1::All>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BeneficiaryWallet {
|
impl BeneficiaryWallet {
|
||||||
fn new(master_xpriv: ExtendedPrivKey) -> Result<Self, Box<dyn std::error::Error>> {
|
fn new(master_xpriv: Xpriv) -> Result<Self, Box<dyn std::error::Error>> {
|
||||||
Ok(Self { master_xpriv, secp: Secp256k1::new() })
|
Ok(Self { master_xpriv, secp: Secp256k1::new() })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn master_xpub(&self) -> ExtendedPubKey {
|
fn master_xpub(&self) -> Xpub { Xpub::from_priv(&self.secp, &self.master_xpriv) }
|
||||||
ExtendedPubKey::from_priv(&self.secp, &self.master_xpriv)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn spend_inheritance(
|
fn spend_inheritance(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -47,7 +47,7 @@ impl_bytes_newtype!(Fingerprint, 4);
|
||||||
/// Extended private key
|
/// Extended private key
|
||||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "std", derive(Debug))]
|
#[cfg_attr(feature = "std", derive(Debug))]
|
||||||
pub struct ExtendedPrivKey {
|
pub struct Xpriv {
|
||||||
/// The network this key is to be used on
|
/// The network this key is to be used on
|
||||||
pub network: Network,
|
pub network: Network,
|
||||||
/// How many derivations this key is from the master (which is 0)
|
/// How many derivations this key is from the master (which is 0)
|
||||||
|
@ -62,12 +62,12 @@ pub struct ExtendedPrivKey {
|
||||||
pub chain_code: ChainCode,
|
pub chain_code: ChainCode,
|
||||||
}
|
}
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
crate::serde_utils::serde_string_impl!(ExtendedPrivKey, "a BIP-32 extended private key");
|
crate::serde_utils::serde_string_impl!(Xpriv, "a BIP-32 extended private key");
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
impl fmt::Debug for ExtendedPrivKey {
|
impl fmt::Debug for Xpriv {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("ExtendedPrivKey")
|
f.debug_struct("Xpriv")
|
||||||
.field("network", &self.network)
|
.field("network", &self.network)
|
||||||
.field("depth", &self.depth)
|
.field("depth", &self.depth)
|
||||||
.field("parent_fingerprint", &self.parent_fingerprint)
|
.field("parent_fingerprint", &self.parent_fingerprint)
|
||||||
|
@ -80,7 +80,7 @@ impl fmt::Debug for ExtendedPrivKey {
|
||||||
|
|
||||||
/// Extended public key
|
/// Extended public key
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
|
||||||
pub struct ExtendedPubKey {
|
pub struct Xpub {
|
||||||
/// The network this key is to be used on
|
/// The network this key is to be used on
|
||||||
pub network: Network,
|
pub network: Network,
|
||||||
/// How many derivations this key is from the master (which is 0)
|
/// How many derivations this key is from the master (which is 0)
|
||||||
|
@ -95,7 +95,7 @@ pub struct ExtendedPubKey {
|
||||||
pub chain_code: ChainCode,
|
pub chain_code: ChainCode,
|
||||||
}
|
}
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
crate::serde_utils::serde_string_impl!(ExtendedPubKey, "a BIP-32 extended public key");
|
crate::serde_utils::serde_string_impl!(Xpub, "a BIP-32 extended public key");
|
||||||
|
|
||||||
/// A child number for a derived key
|
/// A child number for a derived key
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
|
||||||
|
@ -535,14 +535,14 @@ impl From<base58::Error> for Error {
|
||||||
fn from(err: base58::Error) -> Self { Error::Base58(err) }
|
fn from(err: base58::Error) -> Self { Error::Base58(err) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtendedPrivKey {
|
impl Xpriv {
|
||||||
/// Construct a new master key from a seed value
|
/// Construct a new master key from a seed value
|
||||||
pub fn new_master(network: Network, seed: &[u8]) -> Result<ExtendedPrivKey, Error> {
|
pub fn new_master(network: Network, seed: &[u8]) -> Result<Xpriv, Error> {
|
||||||
let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(b"Bitcoin seed");
|
let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(b"Bitcoin seed");
|
||||||
hmac_engine.input(seed);
|
hmac_engine.input(seed);
|
||||||
let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine);
|
let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine);
|
||||||
|
|
||||||
Ok(ExtendedPrivKey {
|
Ok(Xpriv {
|
||||||
network,
|
network,
|
||||||
depth: 0,
|
depth: 0,
|
||||||
parent_fingerprint: Default::default(),
|
parent_fingerprint: Default::default(),
|
||||||
|
@ -571,8 +571,8 @@ impl ExtendedPrivKey {
|
||||||
&self,
|
&self,
|
||||||
secp: &Secp256k1<C>,
|
secp: &Secp256k1<C>,
|
||||||
path: &P,
|
path: &P,
|
||||||
) -> Result<ExtendedPrivKey, Error> {
|
) -> Result<Xpriv, Error> {
|
||||||
let mut sk: ExtendedPrivKey = *self;
|
let mut sk: Xpriv = *self;
|
||||||
for cnum in path.as_ref() {
|
for cnum in path.as_ref() {
|
||||||
sk = sk.ckd_priv(secp, *cnum)?;
|
sk = sk.ckd_priv(secp, *cnum)?;
|
||||||
}
|
}
|
||||||
|
@ -584,7 +584,7 @@ impl ExtendedPrivKey {
|
||||||
&self,
|
&self,
|
||||||
secp: &Secp256k1<C>,
|
secp: &Secp256k1<C>,
|
||||||
i: ChildNumber,
|
i: ChildNumber,
|
||||||
) -> Result<ExtendedPrivKey, Error> {
|
) -> Result<Xpriv, Error> {
|
||||||
let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(&self.chain_code[..]);
|
let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(&self.chain_code[..]);
|
||||||
match i {
|
match i {
|
||||||
ChildNumber::Normal { .. } => {
|
ChildNumber::Normal { .. } => {
|
||||||
|
@ -607,7 +607,7 @@ impl ExtendedPrivKey {
|
||||||
let tweaked =
|
let tweaked =
|
||||||
sk.add_tweak(&self.private_key.into()).expect("statistically impossible to hit");
|
sk.add_tweak(&self.private_key.into()).expect("statistically impossible to hit");
|
||||||
|
|
||||||
Ok(ExtendedPrivKey {
|
Ok(Xpriv {
|
||||||
network: self.network,
|
network: self.network,
|
||||||
depth: self.depth + 1,
|
depth: self.depth + 1,
|
||||||
parent_fingerprint: self.fingerprint(secp),
|
parent_fingerprint: self.fingerprint(secp),
|
||||||
|
@ -618,7 +618,7 @@ impl ExtendedPrivKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decoding extended private key from binary data according to BIP 32
|
/// Decoding extended private key from binary data according to BIP 32
|
||||||
pub fn decode(data: &[u8]) -> Result<ExtendedPrivKey, Error> {
|
pub fn decode(data: &[u8]) -> Result<Xpriv, Error> {
|
||||||
if data.len() != 78 {
|
if data.len() != 78 {
|
||||||
return Err(Error::WrongExtendedKeyLength(data.len()));
|
return Err(Error::WrongExtendedKeyLength(data.len()));
|
||||||
}
|
}
|
||||||
|
@ -630,7 +630,7 @@ impl ExtendedPrivKey {
|
||||||
_ => unreachable!("length checked above"),
|
_ => unreachable!("length checked above"),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(ExtendedPrivKey {
|
Ok(Xpriv {
|
||||||
network,
|
network,
|
||||||
depth: data[4],
|
depth: data[4],
|
||||||
parent_fingerprint: data[5..9]
|
parent_fingerprint: data[5..9]
|
||||||
|
@ -664,7 +664,7 @@ impl ExtendedPrivKey {
|
||||||
|
|
||||||
/// Returns the HASH160 of the public key belonging to the xpriv
|
/// Returns the HASH160 of the public key belonging to the xpriv
|
||||||
pub fn identifier<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> XpubIdentifier {
|
pub fn identifier<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> XpubIdentifier {
|
||||||
ExtendedPubKey::from_priv(secp, self).identifier()
|
Xpub::from_priv(secp, self).identifier()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the first four bytes of the identifier
|
/// Returns the first four bytes of the identifier
|
||||||
|
@ -673,13 +673,10 @@ impl ExtendedPrivKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtendedPubKey {
|
impl Xpub {
|
||||||
/// Derives a public key from a private key
|
/// Derives a public key from a private key
|
||||||
pub fn from_priv<C: secp256k1::Signing>(
|
pub fn from_priv<C: secp256k1::Signing>(secp: &Secp256k1<C>, sk: &Xpriv) -> Xpub {
|
||||||
secp: &Secp256k1<C>,
|
Xpub {
|
||||||
sk: &ExtendedPrivKey,
|
|
||||||
) -> ExtendedPubKey {
|
|
||||||
ExtendedPubKey {
|
|
||||||
network: sk.network,
|
network: sk.network,
|
||||||
depth: sk.depth,
|
depth: sk.depth,
|
||||||
parent_fingerprint: sk.parent_fingerprint,
|
parent_fingerprint: sk.parent_fingerprint,
|
||||||
|
@ -703,8 +700,8 @@ impl ExtendedPubKey {
|
||||||
&self,
|
&self,
|
||||||
secp: &Secp256k1<C>,
|
secp: &Secp256k1<C>,
|
||||||
path: &P,
|
path: &P,
|
||||||
) -> Result<ExtendedPubKey, Error> {
|
) -> Result<Xpub, Error> {
|
||||||
let mut pk: ExtendedPubKey = *self;
|
let mut pk: Xpub = *self;
|
||||||
for cnum in path.as_ref() {
|
for cnum in path.as_ref() {
|
||||||
pk = pk.ckd_pub(secp, *cnum)?
|
pk = pk.ckd_pub(secp, *cnum)?
|
||||||
}
|
}
|
||||||
|
@ -738,11 +735,11 @@ impl ExtendedPubKey {
|
||||||
&self,
|
&self,
|
||||||
secp: &Secp256k1<C>,
|
secp: &Secp256k1<C>,
|
||||||
i: ChildNumber,
|
i: ChildNumber,
|
||||||
) -> Result<ExtendedPubKey, Error> {
|
) -> Result<Xpub, Error> {
|
||||||
let (sk, chain_code) = self.ckd_pub_tweak(i)?;
|
let (sk, chain_code) = self.ckd_pub_tweak(i)?;
|
||||||
let tweaked = self.public_key.add_exp_tweak(secp, &sk.into())?;
|
let tweaked = self.public_key.add_exp_tweak(secp, &sk.into())?;
|
||||||
|
|
||||||
Ok(ExtendedPubKey {
|
Ok(Xpub {
|
||||||
network: self.network,
|
network: self.network,
|
||||||
depth: self.depth + 1,
|
depth: self.depth + 1,
|
||||||
parent_fingerprint: self.fingerprint(),
|
parent_fingerprint: self.fingerprint(),
|
||||||
|
@ -753,7 +750,7 @@ impl ExtendedPubKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Decoding extended public key from binary data according to BIP 32
|
/// Decoding extended public key from binary data according to BIP 32
|
||||||
pub fn decode(data: &[u8]) -> Result<ExtendedPubKey, Error> {
|
pub fn decode(data: &[u8]) -> Result<Xpub, Error> {
|
||||||
if data.len() != 78 {
|
if data.len() != 78 {
|
||||||
return Err(Error::WrongExtendedKeyLength(data.len()));
|
return Err(Error::WrongExtendedKeyLength(data.len()));
|
||||||
}
|
}
|
||||||
|
@ -765,7 +762,7 @@ impl ExtendedPubKey {
|
||||||
_ => unreachable!("length checked above"),
|
_ => unreachable!("length checked above"),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(ExtendedPubKey {
|
Ok(Xpub {
|
||||||
network,
|
network,
|
||||||
depth: data[4],
|
depth: data[4],
|
||||||
parent_fingerprint: data[5..9]
|
parent_fingerprint: data[5..9]
|
||||||
|
@ -809,52 +806,52 @@ impl ExtendedPubKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ExtendedPrivKey {
|
impl fmt::Display for Xpriv {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
base58::encode_check_to_fmt(fmt, &self.encode()[..])
|
base58::encode_check_to_fmt(fmt, &self.encode()[..])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for ExtendedPrivKey {
|
impl FromStr for Xpriv {
|
||||||
type Err = Error;
|
type Err = Error;
|
||||||
|
|
||||||
fn from_str(inp: &str) -> Result<ExtendedPrivKey, Error> {
|
fn from_str(inp: &str) -> Result<Xpriv, Error> {
|
||||||
let data = base58::decode_check(inp)?;
|
let data = base58::decode_check(inp)?;
|
||||||
|
|
||||||
if data.len() != 78 {
|
if data.len() != 78 {
|
||||||
return Err(base58::Error::InvalidLength(data.len()).into());
|
return Err(base58::Error::InvalidLength(data.len()).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtendedPrivKey::decode(&data)
|
Xpriv::decode(&data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ExtendedPubKey {
|
impl fmt::Display for Xpub {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||||
base58::encode_check_to_fmt(fmt, &self.encode()[..])
|
base58::encode_check_to_fmt(fmt, &self.encode()[..])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for ExtendedPubKey {
|
impl FromStr for Xpub {
|
||||||
type Err = Error;
|
type Err = Error;
|
||||||
|
|
||||||
fn from_str(inp: &str) -> Result<ExtendedPubKey, Error> {
|
fn from_str(inp: &str) -> Result<Xpub, Error> {
|
||||||
let data = base58::decode_check(inp)?;
|
let data = base58::decode_check(inp)?;
|
||||||
|
|
||||||
if data.len() != 78 {
|
if data.len() != 78 {
|
||||||
return Err(base58::Error::InvalidLength(data.len()).into());
|
return Err(base58::Error::InvalidLength(data.len()).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtendedPubKey::decode(&data)
|
Xpub::decode(&data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ExtendedPubKey> for XpubIdentifier {
|
impl From<Xpub> for XpubIdentifier {
|
||||||
fn from(key: ExtendedPubKey) -> XpubIdentifier { key.identifier() }
|
fn from(key: Xpub) -> XpubIdentifier { key.identifier() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&ExtendedPubKey> for XpubIdentifier {
|
impl From<&Xpub> for XpubIdentifier {
|
||||||
fn from(key: &ExtendedPubKey) -> XpubIdentifier { key.identifier() }
|
fn from(key: &Xpub) -> XpubIdentifier { key.identifier() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -953,13 +950,13 @@ mod tests {
|
||||||
expected_sk: &str,
|
expected_sk: &str,
|
||||||
expected_pk: &str,
|
expected_pk: &str,
|
||||||
) {
|
) {
|
||||||
let mut sk = ExtendedPrivKey::new_master(network, seed).unwrap();
|
let mut sk = Xpriv::new_master(network, seed).unwrap();
|
||||||
let mut pk = ExtendedPubKey::from_priv(secp, &sk);
|
let mut pk = Xpub::from_priv(secp, &sk);
|
||||||
|
|
||||||
// Check derivation convenience method for ExtendedPrivKey
|
// Check derivation convenience method for Xpriv
|
||||||
assert_eq!(&sk.derive_priv(secp, &path).unwrap().to_string()[..], expected_sk);
|
assert_eq!(&sk.derive_priv(secp, &path).unwrap().to_string()[..], expected_sk);
|
||||||
|
|
||||||
// Check derivation convenience method for ExtendedPubKey, should error
|
// Check derivation convenience method for Xpub, should error
|
||||||
// appropriately if any ChildNumber is hardened
|
// appropriately if any ChildNumber is hardened
|
||||||
if path.0.iter().any(|cnum| cnum.is_hardened()) {
|
if path.0.iter().any(|cnum| cnum.is_hardened()) {
|
||||||
assert_eq!(pk.derive_pub(secp, &path), Err(Error::CannotDeriveFromHardenedKey));
|
assert_eq!(pk.derive_pub(secp, &path), Err(Error::CannotDeriveFromHardenedKey));
|
||||||
|
@ -973,12 +970,12 @@ mod tests {
|
||||||
match num {
|
match num {
|
||||||
Normal { .. } => {
|
Normal { .. } => {
|
||||||
let pk2 = pk.ckd_pub(secp, num).unwrap();
|
let pk2 = pk.ckd_pub(secp, num).unwrap();
|
||||||
pk = ExtendedPubKey::from_priv(secp, &sk);
|
pk = Xpub::from_priv(secp, &sk);
|
||||||
assert_eq!(pk, pk2);
|
assert_eq!(pk, pk2);
|
||||||
}
|
}
|
||||||
Hardened { .. } => {
|
Hardened { .. } => {
|
||||||
assert_eq!(pk.ckd_pub(secp, num), Err(Error::CannotDeriveFromHardenedKey));
|
assert_eq!(pk.ckd_pub(secp, num), Err(Error::CannotDeriveFromHardenedKey));
|
||||||
pk = ExtendedPubKey::from_priv(secp, &sk);
|
pk = Xpub::from_priv(secp, &sk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -987,8 +984,8 @@ mod tests {
|
||||||
assert_eq!(&sk.to_string()[..], expected_sk);
|
assert_eq!(&sk.to_string()[..], expected_sk);
|
||||||
assert_eq!(&pk.to_string()[..], expected_pk);
|
assert_eq!(&pk.to_string()[..], expected_pk);
|
||||||
// Check decoded base58 against result
|
// Check decoded base58 against result
|
||||||
let decoded_sk = ExtendedPrivKey::from_str(expected_sk);
|
let decoded_sk = Xpriv::from_str(expected_sk);
|
||||||
let decoded_pk = ExtendedPubKey::from_str(expected_pk);
|
let decoded_pk = Xpub::from_str(expected_pk);
|
||||||
assert_eq!(Ok(sk), decoded_sk);
|
assert_eq!(Ok(sk), decoded_sk);
|
||||||
assert_eq!(Ok(pk), decoded_pk);
|
assert_eq!(Ok(pk), decoded_pk);
|
||||||
}
|
}
|
||||||
|
@ -1181,7 +1178,7 @@ mod tests {
|
||||||
sk.as_mut_ptr().copy_from(zeros.as_ptr(), 32);
|
sk.as_mut_ptr().copy_from(zeros.as_ptr(), 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
let xpriv = ExtendedPrivKey {
|
let xpriv = Xpriv {
|
||||||
network: Network::Bitcoin,
|
network: Network::Bitcoin,
|
||||||
depth: 0,
|
depth: 0,
|
||||||
parent_fingerprint: Default::default(),
|
parent_fingerprint: Default::default(),
|
||||||
|
@ -1195,7 +1192,7 @@ mod tests {
|
||||||
|
|
||||||
// Xpriv having secret key set to all zeros
|
// Xpriv having secret key set to all zeros
|
||||||
let xpriv_str = "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzF93Y5wvzdUayhgkkFoicQZcP3y52uPPxFnfoLZB21Teqt1VvEHx";
|
let xpriv_str = "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzF93Y5wvzdUayhgkkFoicQZcP3y52uPPxFnfoLZB21Teqt1VvEHx";
|
||||||
ExtendedPrivKey::from_str(xpriv_str).unwrap();
|
Xpriv::from_str(xpriv_str).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1203,6 +1200,6 @@ mod tests {
|
||||||
fn schnorr_broken_privkey_ffs() {
|
fn schnorr_broken_privkey_ffs() {
|
||||||
// Xpriv having secret key set to all 0xFF's
|
// Xpriv having secret key set to all 0xFF's
|
||||||
let xpriv_str = "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD9y5gkZ6Eq3Rjuahrv17fENZ3QzxW";
|
let xpriv_str = "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD9y5gkZ6Eq3Rjuahrv17fENZ3QzxW";
|
||||||
ExtendedPrivKey::from_str(xpriv_str).unwrap();
|
Xpriv::from_str(xpriv_str).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use core::fmt;
|
||||||
|
|
||||||
use internals::write_err;
|
use internals::write_err;
|
||||||
|
|
||||||
use crate::bip32::ExtendedPubKey;
|
use crate::bip32::Xpub;
|
||||||
use crate::blockdata::transaction::Transaction;
|
use crate::blockdata::transaction::Transaction;
|
||||||
use crate::consensus::encode;
|
use crate::consensus::encode;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
@ -69,7 +69,7 @@ pub enum Error {
|
||||||
},
|
},
|
||||||
/// Conflicting data during combine procedure:
|
/// Conflicting data during combine procedure:
|
||||||
/// global extended public key has inconsistent key sources
|
/// global extended public key has inconsistent key sources
|
||||||
CombineInconsistentKeySources(Box<ExtendedPubKey>),
|
CombineInconsistentKeySources(Box<Xpub>),
|
||||||
/// Serialization error in bitcoin consensus-encoded structures
|
/// Serialization error in bitcoin consensus-encoded structures
|
||||||
ConsensusEncoding(encode::Error),
|
ConsensusEncoding(encode::Error),
|
||||||
/// Negative fee
|
/// Negative fee
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use core::convert::TryFrom;
|
use core::convert::TryFrom;
|
||||||
|
|
||||||
use crate::bip32::{ChildNumber, DerivationPath, ExtendedPubKey, Fingerprint};
|
use crate::bip32::{ChildNumber, DerivationPath, Fingerprint, Xpub};
|
||||||
use crate::blockdata::transaction::Transaction;
|
use crate::blockdata::transaction::Transaction;
|
||||||
use crate::consensus::encode::MAX_VEC_SIZE;
|
use crate::consensus::encode::MAX_VEC_SIZE;
|
||||||
use crate::consensus::{encode, Decodable};
|
use crate::consensus::{encode, Decodable};
|
||||||
|
@ -76,8 +76,7 @@ impl Psbt {
|
||||||
let mut tx: Option<Transaction> = None;
|
let mut tx: Option<Transaction> = None;
|
||||||
let mut version: Option<u32> = None;
|
let mut version: Option<u32> = None;
|
||||||
let mut unknowns: BTreeMap<raw::Key, Vec<u8>> = Default::default();
|
let mut unknowns: BTreeMap<raw::Key, Vec<u8>> = Default::default();
|
||||||
let mut xpub_map: BTreeMap<ExtendedPubKey, (Fingerprint, DerivationPath)> =
|
let mut xpub_map: BTreeMap<Xpub, (Fingerprint, DerivationPath)> = Default::default();
|
||||||
Default::default();
|
|
||||||
let mut proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>> = Default::default();
|
let mut proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>> = Default::default();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
@ -114,7 +113,7 @@ impl Psbt {
|
||||||
}
|
}
|
||||||
PSBT_GLOBAL_XPUB => {
|
PSBT_GLOBAL_XPUB => {
|
||||||
if !pair.key.key.is_empty() {
|
if !pair.key.key.is_empty() {
|
||||||
let xpub = ExtendedPubKey::decode(&pair.key.key)
|
let xpub = Xpub::decode(&pair.key.key)
|
||||||
.map_err(|_| Error::XPubKey(
|
.map_err(|_| Error::XPubKey(
|
||||||
"Can't deserialize ExtendedPublicKey from global XPUB key data"
|
"Can't deserialize ExtendedPublicKey from global XPUB key data"
|
||||||
))?;
|
))?;
|
||||||
|
|
|
@ -14,7 +14,7 @@ use std::collections::{HashMap, HashSet};
|
||||||
use internals::write_err;
|
use internals::write_err;
|
||||||
use secp256k1::{Message, Secp256k1, Signing};
|
use secp256k1::{Message, Secp256k1, Signing};
|
||||||
|
|
||||||
use crate::bip32::{self, ExtendedPrivKey, ExtendedPubKey, KeySource};
|
use crate::bip32::{self, KeySource, Xpriv, Xpub};
|
||||||
use crate::blockdata::transaction::{Transaction, TxOut};
|
use crate::blockdata::transaction::{Transaction, TxOut};
|
||||||
use crate::crypto::ecdsa;
|
use crate::crypto::ecdsa;
|
||||||
use crate::crypto::key::{PrivateKey, PublicKey};
|
use crate::crypto::key::{PrivateKey, PublicKey};
|
||||||
|
@ -44,7 +44,7 @@ pub struct Psbt {
|
||||||
pub version: u32,
|
pub version: u32,
|
||||||
/// A global map from extended public keys to the used key fingerprint and
|
/// A global map from extended public keys to the used key fingerprint and
|
||||||
/// derivation path as defined by BIP 32.
|
/// derivation path as defined by BIP 32.
|
||||||
pub xpub: BTreeMap<ExtendedPubKey, KeySource>,
|
pub xpub: BTreeMap<Xpub, KeySource>,
|
||||||
/// Global proprietary key-value pairs.
|
/// Global proprietary key-value pairs.
|
||||||
#[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
|
#[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
|
||||||
pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
|
pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
|
||||||
|
@ -487,7 +487,7 @@ pub trait GetKey {
|
||||||
) -> Result<Option<PrivateKey>, Self::Error>;
|
) -> Result<Option<PrivateKey>, Self::Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GetKey for ExtendedPrivKey {
|
impl GetKey for Xpriv {
|
||||||
type Error = GetKeyError;
|
type Error = GetKeyError;
|
||||||
|
|
||||||
fn get_key<C: Signing>(
|
fn get_key<C: Signing>(
|
||||||
|
@ -520,7 +520,7 @@ pub type SigningErrors = BTreeMap<usize, SignError>;
|
||||||
macro_rules! impl_get_key_for_set {
|
macro_rules! impl_get_key_for_set {
|
||||||
($set:ident) => {
|
($set:ident) => {
|
||||||
|
|
||||||
impl GetKey for $set<ExtendedPrivKey> {
|
impl GetKey for $set<Xpriv> {
|
||||||
type Error = GetKeyError;
|
type Error = GetKeyError;
|
||||||
|
|
||||||
fn get_key<C: Signing>(
|
fn get_key<C: Signing>(
|
||||||
|
@ -810,7 +810,7 @@ mod tests {
|
||||||
use secp256k1::{All, SecretKey};
|
use secp256k1::{All, SecretKey};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::bip32::{ChildNumber, ExtendedPrivKey, ExtendedPubKey, KeySource};
|
use crate::bip32::{ChildNumber, KeySource, Xpriv, Xpub};
|
||||||
use crate::blockdata::locktime::absolute;
|
use crate::blockdata::locktime::absolute;
|
||||||
use crate::blockdata::script::ScriptBuf;
|
use crate::blockdata::script::ScriptBuf;
|
||||||
use crate::blockdata::transaction::{OutPoint, Sequence, Transaction, TxIn, TxOut};
|
use crate::blockdata::transaction::{OutPoint, Sequence, Transaction, TxIn, TxOut};
|
||||||
|
@ -857,7 +857,7 @@ mod tests {
|
||||||
|
|
||||||
let mut hd_keypaths: BTreeMap<secp256k1::PublicKey, KeySource> = Default::default();
|
let mut hd_keypaths: BTreeMap<secp256k1::PublicKey, KeySource> = Default::default();
|
||||||
|
|
||||||
let mut sk: ExtendedPrivKey = ExtendedPrivKey::new_master(Bitcoin, &seed).unwrap();
|
let mut sk: Xpriv = Xpriv::new_master(Bitcoin, &seed).unwrap();
|
||||||
|
|
||||||
let fprint = sk.fingerprint(secp);
|
let fprint = sk.fingerprint(secp);
|
||||||
|
|
||||||
|
@ -874,7 +874,7 @@ mod tests {
|
||||||
|
|
||||||
sk = sk.derive_priv(secp, &dpath).unwrap();
|
sk = sk.derive_priv(secp, &dpath).unwrap();
|
||||||
|
|
||||||
let pk = ExtendedPubKey::from_priv(secp, &sk);
|
let pk = Xpub::from_priv(secp, &sk);
|
||||||
|
|
||||||
hd_keypaths.insert(pk.public_key, (fprint, dpath.into()));
|
hd_keypaths.insert(pk.public_key, (fprint, dpath.into()));
|
||||||
|
|
||||||
|
@ -1019,7 +1019,7 @@ mod tests {
|
||||||
let psbt = Psbt {
|
let psbt = Psbt {
|
||||||
version: 0,
|
version: 0,
|
||||||
xpub: {
|
xpub: {
|
||||||
let xpub: ExtendedPubKey =
|
let xpub: Xpub =
|
||||||
"xpub661MyMwAqRbcGoRVtwfvzZsq2VBJR1LAHfQstHUoxqDorV89vRoMxUZ27kLrraAj6MPi\
|
"xpub661MyMwAqRbcGoRVtwfvzZsq2VBJR1LAHfQstHUoxqDorV89vRoMxUZ27kLrraAj6MPi\
|
||||||
QfrDb27gigC1VS1dBXi5jGpxmMeBXEkKkcXUTg4".parse().unwrap();
|
QfrDb27gigC1VS1dBXi5jGpxmMeBXEkKkcXUTg4".parse().unwrap();
|
||||||
vec![(xpub, key_source)].into_iter().collect()
|
vec![(xpub, key_source)].into_iter().collect()
|
||||||
|
|
|
@ -5,7 +5,7 @@ use core::convert::TryFrom;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use bitcoin::bip32::{ExtendedPrivKey, ExtendedPubKey, Fingerprint, IntoDerivationPath, KeySource};
|
use bitcoin::bip32::{Fingerprint, IntoDerivationPath, KeySource, Xpriv, Xpub};
|
||||||
use bitcoin::blockdata::opcodes::OP_0;
|
use bitcoin::blockdata::opcodes::OP_0;
|
||||||
use bitcoin::blockdata::script;
|
use bitcoin::blockdata::script;
|
||||||
use bitcoin::consensus::encode::{deserialize, serialize_hex};
|
use bitcoin::consensus::encode::{deserialize, serialize_hex};
|
||||||
|
@ -41,7 +41,7 @@ fn bip174_psbt_workflow() {
|
||||||
//
|
//
|
||||||
|
|
||||||
let ext_priv = build_extended_private_key();
|
let ext_priv = build_extended_private_key();
|
||||||
let ext_pub = ExtendedPubKey::from_priv(&secp, &ext_priv);
|
let ext_pub = Xpub::from_priv(&secp, &ext_priv);
|
||||||
let parent_fingerprint = ext_pub.fingerprint();
|
let parent_fingerprint = ext_pub.fingerprint();
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -120,15 +120,15 @@ fn bip174_psbt_workflow() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to build an extended private key from seed and also directly from a string.
|
/// Attempts to build an extended private key from seed and also directly from a string.
|
||||||
fn build_extended_private_key() -> ExtendedPrivKey {
|
fn build_extended_private_key() -> Xpriv {
|
||||||
// Strings from BIP 174 test vector.
|
// Strings from BIP 174 test vector.
|
||||||
let extended_private_key = "tprv8ZgxMBicQKsPd9TeAdPADNnSyH9SSUUbTVeFszDE23Ki6TBB5nCefAdHkK8Fm3qMQR6sHwA56zqRmKmxnHk37JkiFzvncDqoKmPWubu7hDF";
|
let extended_private_key = "tprv8ZgxMBicQKsPd9TeAdPADNnSyH9SSUUbTVeFszDE23Ki6TBB5nCefAdHkK8Fm3qMQR6sHwA56zqRmKmxnHk37JkiFzvncDqoKmPWubu7hDF";
|
||||||
let seed = "cUkG8i1RFfWGWy5ziR11zJ5V4U4W3viSFCfyJmZnvQaUsd1xuF3T";
|
let seed = "cUkG8i1RFfWGWy5ziR11zJ5V4U4W3viSFCfyJmZnvQaUsd1xuF3T";
|
||||||
|
|
||||||
let xpriv = ExtendedPrivKey::from_str(extended_private_key).unwrap();
|
let xpriv = Xpriv::from_str(extended_private_key).unwrap();
|
||||||
|
|
||||||
let sk = PrivateKey::from_wif(seed).unwrap();
|
let sk = PrivateKey::from_wif(seed).unwrap();
|
||||||
let seeded = ExtendedPrivKey::new_master(NETWORK, &sk.inner.secret_bytes()).unwrap();
|
let seeded = Xpriv::new_master(NETWORK, &sk.inner.secret_bytes()).unwrap();
|
||||||
assert_eq!(xpriv, seeded);
|
assert_eq!(xpriv, seeded);
|
||||||
|
|
||||||
xpriv
|
xpriv
|
||||||
|
@ -224,7 +224,7 @@ fn update_psbt(mut psbt: Psbt, fingerprint: Fingerprint) -> Psbt {
|
||||||
let redeem_script_1 = "00208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903";
|
let redeem_script_1 = "00208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903";
|
||||||
let witness_script = "522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae";
|
let witness_script = "522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae";
|
||||||
|
|
||||||
// Public key and its derivation path (these are the child pubkeys for our `ExtendedPrivKey`,
|
// Public key and its derivation path (these are the child pubkeys for our `Xpriv`,
|
||||||
// can be verified by deriving the key using this derivation path).
|
// can be verified by deriving the key using this derivation path).
|
||||||
let pk_path = vec![
|
let pk_path = vec![
|
||||||
("029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f", "m/0h/0h/0h"),
|
("029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f", "m/0h/0h/0h"),
|
||||||
|
@ -310,7 +310,7 @@ fn update_psbt_with_sighash_all(mut psbt: Psbt) -> Psbt {
|
||||||
|
|
||||||
/// Verifies the keys in the test vector are valid for the extended private key and derivation path.
|
/// Verifies the keys in the test vector are valid for the extended private key and derivation path.
|
||||||
fn parse_and_verify_keys(
|
fn parse_and_verify_keys(
|
||||||
ext_priv: &ExtendedPrivKey,
|
ext_priv: &Xpriv,
|
||||||
sk_path: &[(&str, &str)],
|
sk_path: &[(&str, &str)],
|
||||||
) -> BTreeMap<PublicKey, PrivateKey> {
|
) -> BTreeMap<PublicKey, PrivateKey> {
|
||||||
let secp = &Secp256k1::new();
|
let secp = &Secp256k1::new();
|
||||||
|
|
|
@ -27,7 +27,7 @@ use std::convert::TryFrom;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use bincode::serialize;
|
use bincode::serialize;
|
||||||
use bitcoin::bip32::{ChildNumber, ExtendedPrivKey, ExtendedPubKey, KeySource};
|
use bitcoin::bip32::{ChildNumber, KeySource, Xpriv, Xpub};
|
||||||
use bitcoin::blockdata::locktime::{absolute, relative};
|
use bitcoin::blockdata::locktime::{absolute, relative};
|
||||||
use bitcoin::blockdata::witness::Witness;
|
use bitcoin::blockdata::witness::Witness;
|
||||||
use bitcoin::consensus::encode::deserialize;
|
use bitcoin::consensus::encode::deserialize;
|
||||||
|
@ -155,7 +155,7 @@ fn serde_regression_address() {
|
||||||
#[test]
|
#[test]
|
||||||
fn serde_regression_extended_priv_key() {
|
fn serde_regression_extended_priv_key() {
|
||||||
let s = include_str!("data/serde/extended_priv_key");
|
let s = include_str!("data/serde/extended_priv_key");
|
||||||
let key = ExtendedPrivKey::from_str(s.trim()).unwrap();
|
let key = Xpriv::from_str(s.trim()).unwrap();
|
||||||
let got = serialize(&key).unwrap();
|
let got = serialize(&key).unwrap();
|
||||||
let want = include_bytes!("data/serde/extended_priv_key_bincode") as &[_];
|
let want = include_bytes!("data/serde/extended_priv_key_bincode") as &[_];
|
||||||
assert_eq!(got, want)
|
assert_eq!(got, want)
|
||||||
|
@ -164,7 +164,7 @@ fn serde_regression_extended_priv_key() {
|
||||||
#[test]
|
#[test]
|
||||||
fn serde_regression_extended_pub_key() {
|
fn serde_regression_extended_pub_key() {
|
||||||
let s = include_str!("data/serde/extended_pub_key");
|
let s = include_str!("data/serde/extended_pub_key");
|
||||||
let key = ExtendedPubKey::from_str(s.trim()).unwrap();
|
let key = Xpub::from_str(s.trim()).unwrap();
|
||||||
let got = serialize(&key).unwrap();
|
let got = serialize(&key).unwrap();
|
||||||
let want = include_bytes!("data/serde/extended_pub_key_bincode") as &[_];
|
let want = include_bytes!("data/serde/extended_pub_key_bincode") as &[_];
|
||||||
assert_eq!(got, want)
|
assert_eq!(got, want)
|
||||||
|
@ -269,7 +269,7 @@ fn serde_regression_psbt() {
|
||||||
version: 0,
|
version: 0,
|
||||||
xpub: {
|
xpub: {
|
||||||
let s = include_str!("data/serde/extended_pub_key");
|
let s = include_str!("data/serde/extended_pub_key");
|
||||||
let xpub = ExtendedPubKey::from_str(s.trim()).unwrap();
|
let xpub = Xpub::from_str(s.trim()).unwrap();
|
||||||
vec![(xpub, key_source)].into_iter().collect()
|
vec![(xpub, key_source)].into_iter().collect()
|
||||||
},
|
},
|
||||||
unsigned_tx: {
|
unsigned_tx: {
|
||||||
|
|
Loading…
Reference in New Issue