diff --git a/examples/bip32.rs b/examples/bip32.rs new file mode 100644 index 00000000..04816f49 --- /dev/null +++ b/examples/bip32.rs @@ -0,0 +1,61 @@ +extern crate bitcoin; + +use std::{env, process}; +use std::str::FromStr; + +use bitcoin::secp256k1::Secp256k1; +use bitcoin::util::key::PrivateKey; +use bitcoin::util::bip32::ExtendedPrivKey; +use bitcoin::util::bip32::ExtendedPubKey; +use bitcoin::util::bip32::DerivationPath; +use bitcoin::util::bip32::ChildNumber; +use bitcoin::util::address::Address; + +fn main() { + // This example derives root xprv + // from a 32-byte secret of the input WIF string, + // derives the child xprv with path m/84h/0h/0h, + // prints out corresponding xpub, + // calculates and prints out the first receiving segwit address. + // Run this example with cargo and WIF argument: + // cargo run --example bip32 L1HKVVLHXiUhecWnwFYF6L3shkf1E12HUmuZTESvBXUdx3yqVP1D + + let args: Vec = env::args().collect(); + if args.len() < 2 { + eprintln!("not enough arguments. usage: {} ", &args[0]); + process::exit(1); + } + + let wif = PrivateKey::from_wif(&args[1]).unwrap(); + println!("Seed WIF: {}", wif); + + // use the network from WIF key + let network = wif.network; + println!("Network: {:?}", network); + // seed is a 32-byte secret in WIF + let seed = wif.to_bytes(); + + // we need secp256k1 context for key derivation + let secp = Secp256k1::new(); + + // calculate root key from seed + let root = ExtendedPrivKey::new_master(network, &seed).unwrap(); + println!("Root key: {}", root); + + // derive child xpub + let path = DerivationPath::from_str("m/84h/0h/0h").unwrap(); + let child = root.derive_priv(&secp, &path).unwrap(); + println!("Child at {}: {}", path, child); + let xpub = ExtendedPubKey::from_private(&secp, &child); + println!("Public key at {}: {}", path, xpub); + + // generate first receiving address at m/0/0 + // manually creating indexes this time + let zero = ChildNumber::from_normal_idx(0).unwrap(); + let public_key = xpub.derive_pub(&secp, &vec![zero, zero]) + .unwrap() + .public_key; + let address = Address::p2wpkh(&public_key, network).unwrap(); + println!("First receiving address: {}", address); + +}