Seed Phrases, Key Pairs, and Addresses
Key pairs have taken a vital role in technology since the dawn of asymmetric cryptography and an even more important role in cryptoassets. A key pair consists of a public key for receiving information and a private key for sending it. With cryptoassets we actually don’t use our public key for receiving, but for verification. I found a really cool python package for generating seed phrases, private keys, and payment addresses. Built by Github user meherett, it is called python-hdwallet. Hdwallet stands for Hierarchical Deterministic Wallet. In short, HD wallets generate a seed phrase (usually 12 or 24 words). They then run this phrase through a process to create everything you need to access your coins.
The process usually goes like this:
- Create seed phrase
- Run seed phrase through a one-way function to create a private key
- Run private key through a one-way function to create a public key
- Run public key through a one-way function to create a receiving address
This package does all of that and so much more. If you would like to code along with me, simply click on the “python-hdwallet” link above and follow the README instructions. We should start with a script that looks like this:

Run the script:

And you’ll get an output like this:

As you can see above, we get a TON of information from this script. The only ones you really need to pay attention to here are “mnemonic”, “wif”, “public_key” and “addresses”. “Mnemonic” is the seed phrase from which the private key is generated. “Wif” is the format of private key that we need to hang on to. When importing a private key to a wallet, we import the key in wif format. If you back up your private key (which you definitely should) the wallet gives you the key in wif. The public key is used at the protocol level for verification. Since it is generated from the private key, when we submit a transaction, the node checks our unique signature against this unique public key in order to validate it. Just like our digital signature, our public key is unique to the private key that it was generated from.
In our addresses section, first you will see “p2pkh” (pay to pubkey hash). A payment address is a hash of the public key. If you are interested in this transaction format, I have another piece about it here where I use Julia to create raw transactions.
Next up we have the “p2sh” format or “pay to script hash”. As I mentioned earlier, a payment address is simply a hash. Because it is generated through a hashing function, we can actually take a script, run it through this function, and output a payment address directly to the script. This is most commonly used for multisignature addresses.
The other addresses are “p2wpkh” (pay to witness pubkey hash), “p2wpk_in_p2sh” (pay to witness pubkey hash in pay to script hash), “p2wsh” (pay to witness script hash) and “p2wsh_in_p2sh” (pay to witness script hash in pay to script hash). These are essentially just the p2pkh and p2sh formats for the Bitcoin Segwit protocol. Since this piece is not about the Segwit (segregated witness) Upgrade, I’m not going into anymore detail about them.
Now you know a bit more about key pairs and where they come from. Thanks for reading, I hope you enjoyed the article!
