协作头脑风暴
brainstorming
在实现前澄清需求、探索设计选择,并形成清晰的开发方向。
bitcoin-wallets-hd【开发与工程】HD wallet implementation: BIP32 derivation, BIP39 mnemonic seed (with passphrase), BIP44/49/84/86 derivation paths, account structure, gap limit, watch-only via xpub, BIP352 silent payment scan/spend derivation and BIP392 sp() descriptors. USE WHEN: building/restoring an HD wallet, choosing derivation paths, debugging address generation, importing mn…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
The standard architecture for Bitcoin wallets since 2014. One mnemonic
1. Generate 128/160/192/224/256 bits of entropy.
2. Append checksum: first ENT/32 bits of SHA256(entropy).
3. Split into 11-bit groups → indices into BIP39 wordlist.
4. Word count: 12 (128-bit), 15, 18, 21, 24 (256-bit).
Recommended: 12 words for general use, 24 words for high-value.
PBKDF2(password=mnemonic, salt="mnemonic" || passphrase,
iter=2048, hash=SHA512, len=64) → 64-byte seed
Without passphrase, salt is just "mnemonic". The passphrase
generates a completely different seed — even one character
difference = different wallet.
Critical: passphrase has no on-chain or wallet-level marker. Lose it = funds gone. Recover only if you remember exact passphrase.
HMAC-SHA512(key="Bitcoin seed", msg=seed) → 64 bytes
Left 32 → master private key
Right 32 → master chain code
See ../../cryptography/bip32/SKILL.md.
| BIP | Path | Output | Address prefix |
|---|---|---|---|
| BIP44 | m/44'/0'/account'/change/index | P2PKH | 1... |
| BIP49 | m/49'/0'/account'/change/index | P2SH-P2WPKH | 3... |
| BIP84 | m/84'/0'/account'/change/index | P2WPKH | bc1q... |
| BIP86 | m/86'/0'/account'/change/index | P2TR | bc1p... |
| BIP48 | m/48'/0'/account'/script_type'/change/index | multisig | bc1q.../bc1p... |
| BIP352 | m/352'/0'/account'/{0',1'}/0 | P2TR (silent payment) | sp1q... |
BIP352 is the odd one out: it derives two hardened branches (1' scan,
0' spend) instead of a change/index leaf, and sp1q... is a static
address string, not an output script. See below.
Coin types: 0 = mainnet, 1 = testnet, 1776 = Liquid.
change=0 for receive, change=1 for change.
account' is hardened — separates wallets logically. account=0
for primary.
When recovering from mnemonic, scan addresses sequentially until you
hit N consecutive empty addresses. Default N=20. Some wallets use
1000 for paranoid recovery.
Modern wallets use descriptors for the watch-only metadata:
wpkh([d34db33f/84h/0h/0h]xpub.../<0;1>/*)#chk
This single descriptor produces:
wpkh(.../<0;1>/0), wpkh(.../<0;1>/1), ...wpkh(.../<0;1>/0) with index 1 instead of 0.Or two separate descriptors with ;0/* and ;1/*.
Silent payments live in their own purpose tree. Two hardened branches, not one account xpub:
scan_private_key: m/352'/coin_type'/account'/1'/0
spend_private_key: m/352'/coin_type'/account'/0'/0
BIP352 requires hardened derivation for both: that is what makes it safe
to hand the scan private key to a scanning service without exposing the
master key or the spend key. The address is bech32m with HRP sp
(sp1q..., 116 chars on mainnet) or tsp on test networks, and never
appears on-chain — the outputs paid to it are ordinary BIP341 P2TR.
BIP392 (Draft; merged to the BIPs repo 2026-03-05, authored by Sparrow's
Craig Raw) puts this key material on the normal descriptor backup path
with a new top-level sp() expression:
sp([d34db33f/352h/0h/0h]spscan1q...) # watch-only: scan privkey + spend pubkey
sp([d34db33f/352h/0h/0h]spspend1q...) # full wallet: both private keys
sp(<WIF or xprv scan key>,<BIP380 spend key>) # two-key form
spscan and spspend are new bech32m key expressions (HRPs spscan
/ spspend, tspscan / tspspend on testnets), data part q for
silent payments v0 followed by ser256(b_scan) || serP(B_spend) and
ser256(b_scan) || ser256(b_spend) respectively.sp() is top level only — sh(sp(...)) and wsh(sp(...)) are
invalid.1h/0 scan, 0h/0 spend) are derived from.musig() from BIP390.sp() — BIP352 permits
only compressed pubkeys.Status as of September 2026: BIP392 is still Draft, with reference
implementation and test vectors both marked TBD. Sparrow ships the
protocol itself — sending in 2.3.0 (October 2025), BIP375 PSBT fields
and DLEQ proof verification for hardware signers in 2.4.0 (February
2026), receiving wallets in 2.5.0 (May 2026). Bitcoin Core has no
sp() descriptor: libsecp256k1 0.8.0 (August 2026) added an optional
silentpayments module, but the wallet-level PRs (#35301, #35302,
#32966) were all still open as of September 2026.
Most users have one account. Multi-account wallets:
Export the account-level xpub (e.g., m/84'/0'/0'):
account_xpub = xpub6CV2... (with [d34db33f/84h/0h/0h] origin)
Import to a wallet that knows derivation paths but never holds the seed:
bitcoin-cli importdescriptors '[
{"desc":"wpkh([d34db33f/84h/0h/0h]xpub6CV2.../<0;1>/*)#chk",
"active":true,"range":[0,999],"timestamp":"now"}
]'
This wallet can:
Math.random() or time-based
RNG for entropy → catastrophic.| Wallet | BIP44 | BIP49 | BIP84 | BIP86 | Multisig (BIP48) |
|---|---|---|---|---|---|
| Bitcoin Core (descriptor) | yes | yes | yes | yes | yes |
| Sparrow | yes | yes | yes | yes | yes |
| Specter | yes | yes | yes | yes | yes |
| Electrum | yes | yes | yes | partial | yes |
| BlueWallet | yes | yes | yes | yes | yes |
| Trezor (Suite) | yes | yes | yes | yes | yes |
| Ledger (Live) | yes | yes | yes | yes | manual |
| Coldcard (Mk4 / Q) | yes | yes | yes | yes | yes |
Silent payments (BIP352) are a separate tree rather than a column here,
and support is uneven — check per wallet. Two fixed points as of
September 2026: Sparrow does SP send and receive (2.5.x), Bitcoin Core
implements neither the BIP392 sp() descriptor nor wallet-level silent
payments.