Wallet Architecture
The Bitcoin Core wallet is responsible for everything a user cares about: managing keys, knowing their balance, and sending bitcoin. It sits on top of the validation layer, watching the blockchain for relevant transactions.
CWallet
The main wallet class. Owns keys, tracks transactions, initiates sends.
ScriptPubKeyMan
Manages specific groups of keys/scripts. Multiple SPKMs per wallet.
CWalletTx
Wallet's view of a transaction, includes metadata like confirmation count, labels.
Key Design Decisions
- Separation of concerns:
CWallethandles general wallet logic, whileScriptPubKeyManhandles key-related operations. This allows multiple key management strategies. - Watch-only support: a wallet can track addresses without having private keys (for cold storage setups).
- Multiple wallets: a single node can load multiple wallet files simultaneously.
Key Management
Modern Bitcoin Core wallets use HD key derivation (BIP 32) to generate all keys from a single master seed:
Key Pool
The wallet pre-generates a pool of keys (default: 1,000) so that backups remain valid for future addresses. When a key is used, a new one is generated to refill the pool.
Descriptor Wallets
Since Bitcoin Core v0.21, wallets use output descriptors: a compact language that describes exactly how to derive scriptPubKeys:
Descriptors solve the backup problem. Instead of backing up every key, you back up one descriptor string (containing the xpub/xprv and derivation path). This single string can regenerate every address the wallet will ever use.
Tracking Funds
The wallet needs to know which UTXOs belong to it. Here's how:
- IsMine check: when a new transaction/block arrives, the wallet checks every output's scriptPubKey against its ScriptPubKeyMans. If a SPKM recognizes the script, the output is "ours."
- CWalletTx: matched transactions are stored as CWalletTx objects with additional metadata (which outputs are ours, confirmation depth, time received).
- Balance calculation: the wallet iterates over all CWalletTx entries, summing spendable UTXOs based on confirmation status.
Balance Types
Coin Selection
When creating a transaction, the wallet must choose which UTXOs to spend as inputs. This matters for fees, privacy, and UTXO set management.
Available Algorithms
The wallet runs all applicable algorithms and picks the solution with the lowest waste metric: a score that accounts for current fees, long-term fee predictions, and the cost of creating change.
Waste = input cost at current rate โ input cost at long-term rate + excess amount (change cost or overpayment). A negative waste score means the current selection is beneficial at today's fee rates.
Creating a Transaction
The CreateTransaction function orchestrates the full spending flow:
Change Output
If the selected inputs exceed the payment + fee, the wallet creates a change output back to itself. The change address is derived from the wallet's key pool. If the change amount would be below the dust threshold, it's added to the fee instead.
Transaction Signing
Signing proves ownership of the UTXOs being spent. The wallet signs each input based on its script type:
Sighash Types
The sighash type controls what parts of the transaction the signature commits to:
- SIGHASH_ALL (default): signs all inputs and outputs. Most restrictive.
- SIGHASH_NONE: signs inputs but no outputs. Anyone can redirect the payment.
- SIGHASH_SINGLE: signs the output at the same index as the input.
- SIGHASH_ANYONECANPAY: modifier: only sign your own input (others can add more inputs).
Fee Estimation
Bitcoin Core estimates the fee rate needed for confirmation within a target number of blocks:
- Tracks how long transactions at various fee rates took to confirm historically
- Maintains fee rate buckets and confirmation statistics
- Returns a conservative (uses a longer confirmation window) or economical estimate
- The
estimatesmartfeeRPC exposes this to users and wallets
Fee estimation only works well when the node has been running long enough to observe fee patterns. On a freshly started or rarely-used node, estimates may be unreliable. A fallback fee rate is used when no estimate is available.
Partially Signed Bitcoin Transactions (PSBT)
PSBT (BIP 174) is a format for passing unsigned or partially signed transactions between wallets, signers, and tools:
PSBT Use Cases
- Hardware wallets: watch-only wallet creates unsigned PSBT โ hardware signer signs โ broadcast
- Multisig: each cosigner adds their signature to the PSBT in sequence
- CoinJoin / PayJoin: multiple parties contribute inputs and sign
- Offline signing: create on online machine, sign on air-gapped machine
Wallet Storage
The wallet database stores keys, transactions, and metadata:
Wallet files are stored in the data directory under wallets/. Each wallet has its own subdirectory containing the database and any lock files.