Derive transparent (t-addr) keys from the HD seed and add BIP39 mnemonic seed phrases that are byte-for-byte compatible with SilentDragonXLite, so the same 24 words recover the same shielded and transparent addresses in either wallet. HD transparent keys: - Derive t-keys from the seed at m/44'/coin'/0'/0/i (were random CKeys). - CHDChain gains a version-gated transparent counter; existing wallets load unchanged. GenerateNewKey routes through DeriveNewChildKey when enabled (-hdtransparent, default on). - Restore from a seed hex via -hdseed with gap-limit pre-derivation; birthday pinned to genesis so the rescan is not clipped. BIP39 seed phrases: - Wire the vendored trezor BIP39 lib (src/crypto/bip39) into the build, fix its BIP39_WORDS guard, and disable the insecure mnemonic cache. - Match SDXLite exactly: English wordlist, empty passphrase, PBKDF2 64-byte seed, coin type 141, ZIP-32 m/32'/141'/i' and BIP44 m/44'/141'/0'/0/i. Store the 32-byte entropy and expand to the 64-byte seed on demand. - Restore via -mnemonic, create via -usemnemonic, reveal via z_exportmnemonic. Verified by gtests including a known-answer BIP39 seed vector and z/t address derivation checks (src/gtest/test_hdtransparent.cpp, test_mnemonic_compat.cpp). Docs in doc/hd-transparent-keys.md and doc/seed-phrase.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3.8 KiB
HD transparent keys
DragonX derives transparent (t-address) keys deterministically from the wallet's HD seed, so they can be recovered from the seed alone — the same way Sapling (shielded) keys already are.
Derivation
Transparent keys are derived over secp256k1 using BIP32/BIP44:
m / 44' / coin_type' / 0' / 0 / i
coin_typeisParams().BIP44CoinType()— 141 on mainnet, 1 on test/regtest.- Account is fixed at
0'and the chain at0(external). The internal/change chain (1) is not used: on thisac_private=1chain a non-coinbase transparent output is consensus-invalid, so transparent change can never carry value. iisCHDChain.transparentChildCounter, a monotonic index persisted in the wallet so the same addresses regenerate after a seed-only restore.
Each derived key records its hdKeypath and the seed fingerprint (seedFp) in
its CKeyMetadata, matching the Sapling scheme.
Why this matters on a private chain
On DragonX (ac_private=1 from genesis) a normal user can never receive to a
transparent address — inbound t-payments are rejected by consensus. The only
thing that legitimately lands spendable value on a t-address is a mining
coinbase (plus notary/burn special cases). There is no "coinbase must be
shielded" rule, so mature coinbase is directly spendable.
So HD transparent keys exist to let a miner recover coinbase rewards that were paid to wallet-derived t-addresses, using only the seed.
Enabling / disabling
Controlled by -hdtransparent (default on). When on and the wallet has an
HD seed, every newly generated transparent key (receive address, change,
coinbase payout drawn from the keypool) is HD-derived.
-hdtransparent=0 # keep the legacy behaviour (random transparent keys)
Backing up and restoring
-
Back up the seed.
z_exportwallet <file>writes the 32-byte HD seed as a# HDSeed=<hex>line. Guard this value like a private key. -
Restore into a fresh/empty wallet by starting the node with:
-hdseed=<64-hex-character seed> -hdtransparentgaplimit=<n> # HD transparent keys to pre-derive (default 1000)On restore the node injects the seed, pre-derives
ntransparent keys with a genesis birthday, and the normal startup rescan finds any coinbase paid to them. Raise-hdtransparentgaplimitif the wallet minted more thanndistinct coinbase addresses.Warning: passing
-hdseedon the command line exposes the seed to your shell history and the process list. Prefer putting it inDRAGONX.confwith tight file permissions, and remove it after the restore completes.
Limitations (read before relying on recovery)
- Legacy random keys are not recoverable. Any transparent key created before
this feature (or with
-hdtransparent=0) came from the CSPRNG, not the seed, and the phrase/seed will not regenerate it. Keepwallet.dat/dumpwalletbackups for those. A wallet that predates the feature and then enables it becomes a mix of random (old) and HD (new) keys. - Gap limit. A rescan only discovers keys already present in the wallet.
Restore pre-derives
-hdtransparentgaplimitkeys; coinbase paid to an index beyond that window is not found until you derive further and rescan again. - Scope. Recovers transparent coinbase value only, per the consensus rules above. Shielded funds are recovered separately via the Sapling HD keys.
On-disk compatibility
The transparent counter is stored in CHDChain under a new serialization
version (VERSION_HD_TRANSPARENT = 2). Existing v1 wallet.dat records load
unchanged (the counter defaults to 0); the record is rewritten as v2 the first
time an HD transparent key is derived. Downgrading a v2 wallet to an older
binary is not supported.