BIP-bip-84 Final
BIP-84: Native SegWit Derivation
Derivation scheme for Native SegWit (P2WPKH) addresses. Standard path for bc1q addresses.
| Type | Bitcoin Improvement Proposal |
| Number | bip-84 |
| Status | Final |
| Authors | Pavol Rusnak |
| Original | https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki |
| Requires |
BIP-84: Derivation Scheme for P2WPKH
BIP-84 defines the standard derivation path for Native SegWit (P2WPKH) addresses, producing addresses that start with bc1q.
Purpose
Before BIP-84:
- BIP-44 defined
m/44'/0'/...for legacy addresses - BIP-49 defined
m/49'/0'/...for wrapped SegWit (P2SH-P2WPKH)
BIP-84 extends this:
m/84'/0'/...for native SegWit (P2WPKH)
This allows wallets to:
- Manage multiple address types from one seed
- Know which address type to generate from the path
- Maintain compatibility with existing HD infrastructure
Derivation Path
m / 84' / coin_type' / account' / change / address_index
| Level | Hardened | Value | Description |
|---|---|---|---|
| Purpose | Yes | 84’ | BIP-84 (native SegWit) |
| Coin Type | Yes | 0’ | Bitcoin mainnet |
| Account | Yes | 0’ to n’ | User accounts |
| Change | No | 0 or 1 | 0 = receiving, 1 = change |
| Address Index | No | 0 to n | Sequential addresses |
Example Paths
m/84'/0'/0'/0/0 First receiving address, account 0
m/84'/0'/0'/0/1 Second receiving address, account 0
m/84'/0'/0'/1/0 First change address, account 0
m/84'/0'/1'/0/0 First receiving address, account 1
Extended Key Versions
BIP-84 introduces new version bytes for serialized extended keys:
| Network | Key Type | Version | Prefix |
|---|---|---|---|
| Mainnet | Private | 0x04b2430c | zprv |
| Mainnet | Public | 0x04b24746 | zpub |
| Testnet | Private | 0x045f18bc | vprv |
| Testnet | Public | 0x045f1cf6 | vpub |
This allows wallets to distinguish SegWit extended keys from legacy.
Address Generation
From derived public key to P2WPKH address:
Public Key (33 bytes, compressed)
↓
SHA256
↓
RIPEMD160
↓
Witness Program (20 bytes)
↓
Bech32 Encode (witness version 0)
↓
bc1q... address
Implementation
const bitcoin = require('bitcoinjs-lib');
const { BIP32Factory } = require('bip32');
const ecc = require('tiny-secp256k1');
const bip39 = require('bip39');
const bip32 = BIP32Factory(ecc);
// From mnemonic to seed
const mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
const seed = bip39.mnemonicToSeedSync(mnemonic);
// Derive BIP-84 account
const root = bip32.fromSeed(seed);
const account = root.derivePath("m/84'/0'/0'");
// Generate receiving addresses
for (let i = 0; i < 5; i++) {
const child = account.derivePath(`0/${i}`);
const { address } = bitcoin.payments.p2wpkh({
pubkey: child.publicKey,
network: bitcoin.networks.bitcoin
});
console.log(`m/84'/0'/0'/0/${i}: ${address}`);
}
Output:
m/84'/0'/0'/0/0: bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu
m/84'/0'/0'/0/1: bc1qnjg0jd8228aq7ez7e7n38hvkmjm8wqh6ek4zv3
m/84'/0'/0'/0/2: bc1qp59yckz4ae5c4efgw2s5njs68r8dp6k2xzqpjk
m/84'/0'/0'/0/3: bc1qgl5vlg0zdl7yvprgxj9fevsc6q6x5dmcyk3cn3
m/84'/0'/0'/0/4: bc1qm97vqzgj934vnaq9s53ynkyf9dgr05rargr04n
Python Implementation
from bip_utils import Bip39SeedGenerator, Bip84, Bip84Coins
# Generate seed from mnemonic
mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
seed = Bip39SeedGenerator(mnemonic).Generate()
# Create BIP-84 wallet
bip84_ctx = Bip84.FromSeed(seed, Bip84Coins.BITCOIN)
account = bip84_ctx.Purpose().Coin().Account(0)
# Generate addresses
for i in range(5):
addr = account.Change(0).AddressIndex(i)
print(f"m/84'/0'/0'/0/{i}: {addr.PublicKey().ToAddress()}")
Extended Public Key (zpub)
The zpub at account level enables watch-only wallets:
// Export zpub
const zpub = account.neutered().toBase58();
// zpub6rFR7y4Q2AijBEqTUquhVz398htDFrtymD9xYYfG1m4wAcvPhXNfE3EfH1r1ADqtfSdVCToUG868RvUUkgDKf31mGDtKsAYz2oz2AGutZYs
// Import zpub for watch-only
const watchOnly = bip32.fromBase58(zpub);
const address = bitcoin.payments.p2wpkh({
pubkey: watchOnly.derivePath('0/0').publicKey
}).address;
Comparison with Other BIPs
| BIP | Purpose | Path | Address Prefix | Output Type |
|---|---|---|---|---|
| 44 | Legacy | m/44’/0’/… | 1… | P2PKH |
| 49 | Wrapped SegWit | m/49’/0’/… | 3… | P2SH-P2WPKH |
| 84 | Native SegWit | m/84’/0’/… | bc1q… | P2WPKH |
| 86 | Taproot | m/86’/0’/… | bc1p… | P2TR |
Fee Savings
Native SegWit (BIP-84) provides significant fee savings:
| Transaction Type | Virtual Size | Savings vs Legacy |
|---|---|---|
| P2PKH (legacy) | ~226 vB | baseline |
| P2SH-P2WPKH (BIP-49) | ~167 vB | ~26% |
| P2WPKH (BIP-84) | ~141 vB | ~38% |
Test Vector
Mnemonic:
abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about
| Path | Address |
|---|---|
| m/84’/0’/0’/0/0 | bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu |
| m/84’/0’/0’/0/1 | bc1qnjg0jd8228aq7ece2l8nh6acv5v62d9d5qujka |
| m/84’/0’/0’/1/0 | bc1q8c6fshw2dlwun7ekn9qwf37cu2rn755upcp6el |
Account xpub:
zpub6rFR7y4Q2AijBEqTUquhVz398htDFrtymD9xYYfG1m4wAcvPhXNfE3EfH1r1ADqtfSdVCToUG868RvUUkgDKf31mGDtKsAYz2oz2AGutZYs
Agent Recommendations
- Use BIP-84 as default for new wallets
- Generate zpub for watch-only monitoring
- Implement gap limit (20 addresses)
- Support address reuse detection for privacy
- Consider BIP-86 (Taproot) for newer deployments
Related BIPs
- BIP-32: HD wallet derivation
- BIP-39: Mnemonic seeds
- BIP-43: Purpose field definition
- BIP-44: Multi-account hierarchy
- BIP-141: SegWit consensus rules
- BIP-173: Bech32 addresses
Machine-Readable Summary
{
"bip": 84,
"title": "Derivation Scheme for P2WPKH",
"status": "final",
"purpose_value": 84,
"path_template": "m/84'/coin'/account'/change/index",
"address_type": "P2WPKH",
"address_prefix": "bc1q",
"extended_key_prefixes": {
"mainnet_private": "zprv",
"mainnet_public": "zpub",
"testnet_private": "vprv",
"testnet_public": "vpub"
}
}