-
Notifications
You must be signed in to change notification settings - Fork 385
Examples from Addresses and HD Wallets
JamesC edited this page Apr 17, 2018
·
1 revision
All examples from the Bitcoin addresses and HD wallets documentation chapter are shown here in full. The specific examples referenced in the subsections are wrapped in the functions listed below.
Addresses, WIF format, Wallets
- create_address_wif_wallet();
Mnemonic Word Lists
- create_mnemonic_from_entropy();
HD Children
- create_hd_children();
Extended Keys, Hardened Children
- create_extended_hardened_keys();
Libbitcoin API: Version 3. Libbitcoin must be compiled with ICU (International Components for Unicode) to work with the optional mnemonic secret passphrase.
Script below is ready-to-compile: g++ -std=c++11 -o addresses_hd_wallets addresses_hd_wallets_examples.cpp $(pkg-config --cflags libbitcoin --libs libbitcoin)
#include <bitcoin/bitcoin.hpp>
#include <string.h>
#include <iostream>
using namespace bc;
using namespace wallet;
void create_address_wif_wallet() {
// ******* part 1 *******
// Begin with a private key
auto my_secret = base16_literal(
"f3c8f9a6198cca98f481edde13bcc031b1470a81e367b838fe9e0a9db0f5993d");
// Derive pubkey point
ec_compressed my_pubkey;
secret_to_public(my_pubkey, my_secret);
// Pubkeyhash: sha256 + hash160
auto my_pubkeyhash = bitcoin_short_hash(my_pubkey);
// Prefix for mainnet = 0x00
one_byte addr_prefix = { { 0x00 } }; //Testnet 0x6f
// Byte sequence = prefix + pubkey + checksum(4-bytes)
data_chunk prefix_pubkey_checksum(to_chunk(addr_prefix));
extend_data(prefix_pubkey_checksum, my_pubkeyhash);
append_checksum(prefix_pubkey_checksum);
// Base58 encode byte sequence -> Bitcoin Address
std::cout << encode_base58(prefix_pubkey_checksum) << std::endl;
// You can directly generate Bitcoin addresses
// with Libbitcoin wallet types: ec_private/ec_public
// described in the following section
//******* part 2 *******
// WIF encoded private key
// Additional Information: Mainnet, PubKey compression
one_byte secret_prefix = { { 0x80 } }; //Testnet Prefix: 0xEF
one_byte secret_compressed = { { 0x01} }; //Omitted if uncompressed
// Apply prefix, suffix & append checksum
auto prefix_secret_comp_checksum = to_chunk(secret_prefix);
extend_data(prefix_secret_comp_checksum, my_secret);
extend_data(prefix_secret_comp_checksum, secret_compressed);
append_checksum(prefix_secret_comp_checksum);
// WIF (mainnet/compressed)
std::cout << encode_base58(prefix_secret_comp_checksum) << std::endl;
// ******* part 3 *******
// Instantiate ec_private object
// ec_private::mainnet = 0x8000 (Mainnet Prefixes 0x80,0x00)
// ec_private::testnet = 0xEF6F (Testnet Prefixes 0xEF,0x6F)
ec_private my_private(my_secret, ec_private::mainnet, true);
std::cout << my_private.to_payment_address() << std::endl;
std::cout << my_private.encoded() << std::endl; //WIF private key
// ******* part 4 *******
// ec_public from ec_private
// (compression implied from ec_private input)
ec_public my_public(my_private);
// ec_public from point
// (compression not implied, supplied as arguments)
ec_public my_public2(my_pubkey, true); //compression = true
// Payment addresses:
// Will always default to mainnet if no argument supplied
// regardless of version in ec_private constructor argument
payment_address my_addr = my_public.to_payment_address();
payment_address my_addr2 = my_public2.to_payment_address(); //0x00, 0x6f
std::cout << (my_addr.encoded() == my_addr2.encoded()) << std::endl;
}
void create_mnemonic_from_entropy() {
// ******* part 1 *******
// 128, 160, 192, 224, 256 bits of Entropy are valid
// We generate 128 bits of Entropy
data_chunk my_entropy_128(16); //16 bytes = 128 bits
pseudo_random_fill(my_entropy_128);
// Instantiate mnemonic word_list
word_list my_word_list = create_mnemonic(my_entropy_128);
std::cout << join(my_word_list) << std::endl; //join to a single string with spaces
}
void create_hd_children() {
// ******* part 1 *******
// Load mnemonic sentence into word list
std::string my_sentence = "market parent marriage drive umbrella custom leisure fury recipe steak have enable";
auto my_word_list = split(my_sentence, " ", true);
// Create an optional secret passphrase
std::string my_passphrase = "my secret passphrase";
// Create 512bit seed (without optional secret passphrase)
auto hd_seed = decode_mnemonic(my_word_list);
// Create 512bit seed (with optional secret passphrase)
// Requires: Libbitcoin compiled with ICU.
// auto hd_seed = decode_mnemonic(my_word_list, my_passphrase);
// ******* part 2 *******
// We reuse 512 bit hd_seed from the previous example
// Derivation of master private key m
data_chunk seed_chunk(to_chunk(hd_seed));
hd_private m(seed_chunk, hd_private::mainnet);
// Derivation of master public key M
hd_public M = m.to_public();
// ******* part 3 *******
// Derive children of master key m
auto m0 = m.derive_private(0);
auto m1 = m.derive_private(1);
auto m2 = m.derive_private(2);
// Derive grandchild private keys
auto m10 = m1.derive_private(0); //Depth 2, Index 0
auto m11 = m1.derive_private(1); //Depth 2, Index 1
auto m12 = m1.derive_private(2); //Depth 2, Index 2
auto m100 = m10.derive_private(0); //Depth 3, Index 0
auto m101 = m10.derive_private(1); //Depth 3, Index 1
auto m102 = m10.derive_private(2); //Depth 3, Index 1
// Derive grandchild public keys
auto M00 = m0.derive_public(0); //Depth 2, Index 0
auto M01 = m0.derive_public(1); //Depth 2, Index 1
auto M02 = m0.derive_public(2); //Depth 2, Index 2
// ...
// Derive hd_public of any hd_private object
// of same depth & index
auto M102 = m102.to_public();
// ******* part 4 *******
// Derive public children of master key M
auto M0 = M.derive_public(0); //Depth 1, Index 0
auto M1 = M.derive_public(1); //Depth 1, Index 1
auto M2 = M.derive_public(2); //Depth 1, Index 2
// Derive further public children
auto M10 = M1.derive_public(0); //Depth 2, Index 0
auto M11 = M1.derive_public(1); //Depth 2, Index 1
auto M12 = M1.derive_public(2); //Depth 2, Index 2
auto M100 = M10.derive_public(0); //Depth 3, Index 0
auto M101 = M10.derive_public(1); //Depth 3, Index 1
// ...
// No private children can be derived
// from child public keys!
}
void create_extended_hardened_keys() {
// Load mnemonic sentence into word list
std::string my_sentence = "market parent marriage drive umbrella custom leisure fury recipe steak have enable";
auto my_word_list = split(my_sentence, " ", true);
// Create an optional secret passphrase
std::string my_passphrase = "my secret passphrase";
// Create 512bit seed
auto hd_seed = decode_mnemonic(my_word_list); //2nd argument: my_passphrase
data_chunk seed_chunk(to_chunk(hd_seed));
// ******* part 1 *******
// Generate master private key
// hd_private::mainnet = 0x0488ADE40488B21E
// Versions for both private and public keys
hd_private m(seed_chunk, hd_private::mainnet);
auto m1 = m.derive_private(1);
// Public key mainnet prefix 0488B21E
// is implicitly passed on to M
hd_public M = m1.to_public();
// Extended Private Key:
// m1 serialised in extended private key format
auto m1_xprv = m.to_hd_key();
// 4 Bytes: Version in hex
auto m1_xprv_ver = slice<0,4>(m1_xprv);
std::cout << encode_base16(m1_xprv_ver) << std::endl;
// 1-Byte: Depth
auto m1_xprv_depth = slice<4,5>(m1_xprv);
std::cout << encode_base16(m1_xprv_depth) << std::endl;
// 4-Bytes: Parent Fingerprint
auto m1_xprv_parent = slice<5,9>(m1_xprv);
std::cout << encode_base16(m1_xprv_parent) << std::endl;
// 4-Bytes: Index Number
auto m1_xprv_index = slice<9,13>(m1_xprv);
std::cout << encode_base16(m1_xprv_index) << std::endl;
// 32-Bytes: Chain Code
auto m1_xprv_chaincode = slice<13,45>(m1_xprv);
std::cout << encode_base16(m1_xprv_chaincode) << std::endl;
// 34-Bytes: Private Key (with 0x00 prefix)
auto m1_xprv_private = slice<45,78>(m1_xprv);
std::cout << encode_base16(m1_xprv_private) << std::endl;
// 4-Bytes: double sha256 checksum
auto m1_xprv_checksum = slice<78,82>(m1_xprv);
std::cout << encode_base16(m1_xprv_checksum) << std::endl;
// //checksum test
// auto checksum_test = slice<0,78>(m1_xprv);
// auto checksum_test_slice = to_chunk(checksum_test);
// append_checksum(checksum_test_slice);
// auto rest = slice<78,82>(to_array<82>(checksum_test_slice));
// std::cout << encode_base16(rest) << std::endl;
// ******* part 2 *******
// Hardened private key derivation with index >= 1 << 31
auto m0 = m.derive_private(0);
auto m00h = m.derive_private(hd_first_hardened_key);
auto m01h = m.derive_private(1 + hd_first_hardened_key);
auto m02h = m.derive_private(2 + hd_first_hardened_key);
// Hardened public key can only be derived from private key
auto M00h = m00h.to_public();
// or from parent private key
auto M00h_ = m.derive_public(hd_first_hardened_key);
// Above keys are equivalent
std::cout << (M00h == M00h_) << std::endl;
}
int main() {
std::cout << "Address, WIF, Wallets: " << "\n";
create_address_wif_wallet();
std::cout << "\n";
std::cout << "Mnemonic Word Lists: " << "\n";
create_mnemonic_from_entropy();
std::cout << "\n";
create_hd_children();
std::cout << "Extended & Hardened Keys: " << "\n";
create_extended_hardened_keys();
std::cout << "\n";
return 0;
}
Users | Developers | License | Copyright © 2011-2024 libbitcoin developers
- Home
- manifesto
- libbitcoin.info
- Libbitcoin Institute
- Freenode (IRC)
- Mailing List
- Slack Channel
- Build Libbitcoin
- Comprehensive Overview
- Developer Documentation
- Tutorials (aaronjaramillo)
- Bitcoin Unraveled
-
Cryptoeconomics
- Foreword by Amir Taaki
- Value Proposition
- Axiom of Resistance
- Money Taxonomy
- Pure Bank
- Production and Consumption
- Labor and Leisure
- Custodial Risk Principle
- Dedicated Cost Principle
- Depreciation Principle
- Expression Principle
- Inflation Principle
- Other Means Principle
- Patent Resistance Principle
- Risk Sharing Principle
- Reservation Principle
- Scalability Principle
- Subjective Inflation Principle
- Consolidation Principle
- Fragmentation Principle
- Permissionless Principle
- Public Data Principle
- Social Network Principle
- State Banking Principle
- Substitution Principle
- Cryptodynamic Principles
- Censorship Resistance Property
- Consensus Property
- Stability Property
- Utility Threshold Property
- Zero Sum Property
- Threat Level Paradox
- Miner Business Model
- Qualitative Security Model
- Proximity Premium Flaw
- Variance Discount Flaw
- Centralization Risk
- Pooling Pressure Risk
- ASIC Monopoly Fallacy
- Auditability Fallacy
- Balance of Power Fallacy
- Blockchain Fallacy
- Byproduct Mining Fallacy
- Causation Fallacy
- Cockroach Fallacy
- Credit Expansion Fallacy
- Debt Loop Fallacy
- Decoupled Mining Fallacy
- Dumping Fallacy
- Empty Block Fallacy
- Energy Exhaustion Fallacy
- Energy Store Fallacy
- Energy Waste Fallacy
- Fee Recovery Fallacy
- Genetic Purity Fallacy
- Full Reserve Fallacy
- Halving Fallacy
- Hoarding Fallacy
- Hybrid Mining Fallacy
- Ideal Money Fallacy
- Impotent Mining Fallacy
- Inflation Fallacy
- Inflationary Quality Fallacy
- Jurisdictional Arbitrage Fallacy
- Lunar Fallacy
- Network Effect Fallacy
- Prisoner's Dilemma Fallacy
- Private Key Fallacy
- Proof of Cost Fallacy
- Proof of Memory Façade
- Proof of Stake Fallacy
- Proof of Work Fallacy
- Regression Fallacy
- Relay Fallacy
- Replay Protection Fallacy
- Reserve Currency Fallacy
- Risk Free Return Fallacy
- Scarcity Fallacy
- Selfish Mining Fallacy
- Side Fee Fallacy
- Split Credit Expansion Fallacy
- Stock to Flow Fallacy
- Thin Air Fallacy
- Time Preference Fallacy
- Unlendable Money Fallacy
- Fedcoin Objectives
- Hearn Error
- Collectible Tautology
- Price Estimation
- Savings Relation
- Speculative Consumption
- Spam Misnomer
- Efficiency Paradox
- Split Speculator Dilemma
- Bitcoin Labels
- Brand Arrogation
- Reserve Definition
- Maximalism Definition
- Shitcoin Definition
- Glossary
- Console Applications
- Development Libraries
- Maintainer Information
- Miscellaneous Articles