Bitcoin for Builders Protocol

Keys, addresses and descriptors

From a secret number to a bc1 address: how keys, HD wallets and output descriptors fit together, explored with your regtest wallet.

45 minBeginner3 / 8

Draft: this lesson is still waiting for review.

What you'll learn

  • Explain how a private key, public key and address relate
  • Recognise the main address types by their prefix
  • Read a wallet descriptor and derive addresses from it

Key terms

private key (ufunguo binafsi)
A secret number that signs your payments. Never give it to anyone.
public key (ufunguo wa umma)
A number derived from your private key. Others use it to check your signature without learning your secret.
address (anwani)
A string you give someone so they can send you bitcoin, like an M-Pesa phone number.
seed phrase (maneno ya siri)
12 or 24 words that can restore every key in your wallet. Whoever knows them owns the money.
descriptor
A short description of which addresses a wallet owns and how to spend them.

Every Bitcoin address you have ever seen started life as a random number. This lesson follows that number all the way to a bc1 string, then shows how one seed phrase produces millions of addresses that a wallet can always find again.

Step 1: Key terms

TermWhat it means
Private keyA 256-bit secret number
Public keyA point on the secp256k1 curve, computed from the private key; you can't reverse it
AddressAn encoding of a locking script, usually built from a hash of the public key
HD wallet (BIP32)Derives a whole tree of keys from one master key
Seed phrase (BIP39)Words that encode the master seed
DescriptorA string that says exactly which scripts a wallet watches and how to spend them

Step 2: Address types by prefix

Prefix (mainnet)RegtestTypeNotes
1...m... / n...P2PKH (legacy)Oldest, largest fees
3...2...P2SHOften wraps multisig or SegWit
bc1q...bcrt1q...P2WPKH (SegWit v0)Common default
bc1p...bcrt1p...P2TR (Taproot)Newest; Schnorr signatures
bitcoin-cli -regtest -rpcwallet=alice getnewaddress "" bech32
bitcoin-cli -regtest -rpcwallet=alice getnewaddress "" bech32m

Done when: you can say which type each of your two new addresses is from its prefix alone.

Step 3: Read your wallet's descriptors

Modern Bitcoin Core wallets are descriptor wallets.

bitcoin-cli -regtest -rpcwallet=alice listdescriptors

You'll see entries like:

wpkh([d34db33f/84h/1h/0h]tpubDC.../0/*)#checksum

Read it left to right:

  • wpkh(...): pay-to-witness-public-key-hash, so bcrt1q addresses.
  • [d34db33f/84h/1h/0h]: the master key fingerprint and the BIP84 derivation path (purpose 84, coin type 1 for test networks, account 0).
  • tpubDC...: the extended public key for that account.
  • /0/*: the receive branch, every index. /1/* is the change branch.

Step 4: Derive addresses yourself

Copy one wpkh(...) descriptor including its checksum, then:

bitcoin-cli -regtest deriveaddresses "wpkh([...]tpub.../0/*)#checksum" "[0,2]"
bitcoin-cli -regtest -rpcwallet=alice getaddressinfo "<first address>"

Expected: the first derived address matches one your wallet already handed out, and getaddressinfo shows the same hdkeypath.

Lab evidence

  • Two addresses of different types, labelled by type.
  • One descriptor with each part annotated.
  • deriveaddresses output matching an address from getnewaddress.

Reflect

Write your answer down, or talk it over with a friend or your chama.

  1. Why can a wallet restored from a seed phrase find all its old addresses?
  2. What does a descriptor tell a watch-only wallet that a list of addresses doesn't?

Check yourself

Question 1 of 4Which can be computed from which?

Further reading

An original Bitsacco Jifunze lesson. Licence: CC BY-SA 4.0.