-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Add HD/Bip32 support #6265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add HD/Bip32 support #6265
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be based on sendmany (not sendtoaddress) and take the chain to use for change as a parameter. The existing RPCs and GUI should use the hdsetchain-configured default - no need for random keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @luke-jr. The hd'ness should be used by default in future. But maybe to give a save transition, a first version would keep the hd functions separated. Users could decide where they want to use hd and where not. Maybe not everyone likes to use hd change keys for current non-hd inputs.
But right, this PR would slightly mix hd and non-hdness anyway. Unspents and balance would be shared.
|
One warning while compiling hdgetaddress doesn't seem to work? |
src/wallet/hdkeystore.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/acctual/actual
|
@fanquake: thanks for the tests. Will have a look at it. Before calling |
|
can this be used to import master seeds? If not, would this require much additional work? |
src/wallet/rpcwallet.cpp
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this not read HelpExampleCli("hdaddchain", "") ? Since by providing "set" as an argument, you must also provide a seed ... I believe the intention was to provide a example run without providing a seed, which should just run as hdaddchain without arguments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. Will fix this.
|
@rebroad: right. This PR would enabled HD features in the main bitcoin-core wallet. It won't affect the current ways of generating keys and sending coins. It's totally independent form the rest of the wallet features. So it is relatively save to use/test this. You can import hd seeds, but only in raw hex. There is no support for Bip39 word lists. I'm pretty sure you'll find a tool to convert bip39 wordlists into 32byte master seed represented in hex. |
|
I haven't gotten to testing this yet, but why did you not decide to accept a base58 encoded key? The first reason against accepting raw hex is there's no way to validate the key without visually comparing. And extended keys can often look similar at the start. xpub/xprv's include a checksum, so the user can be sure they entered the right thing. The other reason is extensibility, since adding watch-only chains implies there won't be any master hex around to use. |
|
@afk11: The lack of base58check encoded master keys is only because it's not implemented yet (didn't find time to do it). But it's very trivial to add. I decided to export the master seed hex to potentially allow to create a bip39 mnemonic (there could be a tool hex-seed->bip39mnemonic). IIRC, you can't create a bip39 mnemonic from the master private key (not sure). Somehow i feel to store a hd chains of keys in the very root, the seed and not in the first derivation, the master private key. But right. Especially for watch-only and HDM wallets, base58check encoded public key importing and usage as external chain root is extremely helpful. I also wrote that in the PR description (see "whats next"). |
3555883 to
41f6c1c
Compare
|
Rebased and added the base58check encoded master pub/priv key to the |
f7de7e2 to
e902fa2
Compare
|
Added some commits on top to address nits and add a feature for creating a hd chain of keys with a existing base58check encoded extended master private key ( |
|
Most of the bip32 work is also included in CoreWallet (https://github.com/jonasschnelli/bitcoin/tree/2015/05/corewallet), which aims to be a replacement/twin for the current wallet with the option of completely split it of, of the bitcoin-core repository. The PR is an option for quicker adding bip32 supporting to bitcoin-core (for the ones who can compile bitcoin-core by them self) or for the case where CoreWallet could fail to reach a stable level. |
|
concept ACK |
99340d4 to
a4ce300
Compare
|
@jonasschnelli oops, missed the notification on this.. You're right you can't go from hex to bip39 mnemonic, as mnemonics have pbkdf2 applied to them. +1 on base58 also. I noticed you have a hard limit of 32 bytes of hex for the provided seed. This isn't correct as BIP32 doesn't specify a size, but rather states the binary seed may be short, or as long as 512 bits (128-256 recommended), since it's hashed with HMAC. Small PR against your branch for this: jonasschnelli#8 Also, chalk it up to not reading the docs carefully, but I didn't expect hdaddchain to create a random key when I started testing. Maybe explicitly mention this will happen if no hex seed / master private key is provided? |
|
@afk11: Meh. Right. I see your point. So you are saying once you have created a bip32 chain with a entropy over This would definitively mean using base58c for the seed output, or even better, just the master private key in base58c. Or do you see any reason to keep the seed? Maybe it should also support importing a bip39 wordlist to create a bip32 chain. |
a4ce300 to
7e4471a
Compare
|
Yes, that is correct - the entropy used to produce the bip39 mnemonic is different to the seed that is produced. I would suggest only displaying the base58 master key. It would keep the API consistent, since in certain situations the initial seed used to yield the master key won't be available, and in all other There isn't much reason to keep the hex seed - the same can be said for BIP39 mnemonics (and their passphrases) I guess. You could have separate RPC methods to create a new master via both methods. I'm not sure if anything is lost in doing this. If someone dumps their master xprv, they can import it using |
|
Could you point me at some background on the concerns about BIP 39 and security please? Seed interoperability with other wallets would seem like one of the major advantages to HD wallet support, although being about to import is IMHO the most important part of that use case, so reference client can be used to recover where another wallet fails. |
|
@rnicoll: Mostly because Bip39 can harm your security:
The 2048 kdf rounds might be okay for embedded USB hardware wallet. But IMO nothing that i'd like to have on my full-node wallet. But i'm pretty sure you can export/convert a bip39 memonic into a master xpriv key (maybe on bip32.org)? |
|
something to keep in mind with BIP39 is that because |
|
@rubensayshi, at least, not without transferring all the BTC. |
|
Needs rebase |
CExtPubKey should be serializable like CPubKey
- master seed can now be stored encrypted - refactor hdkeystore.cpp/wallet.cpp - add CHDPubKey which represents a deriven child key with some metdata for adding to a persistant store
… creation with base58c encoded ext priv key
5f8cfe6 to
3327d29
Compare
|
Rebased and updated.
This PR is relatively complex and are meant for user who are seeking full control over their hd structure. I have plans to also open a smaller, simpler HD patch. |
This will add basic bip32 support for the current wallet. I testes the PR in serval environments, but, still needs more testing.
Feedback of any type is highly welcome.
Concept
m/44'/0'/0'/corm/0'/chdaddchain add <chainpath> <masterseed>), the rpc command will add the generated master seed as hex to the response (user can store it and use it as backup).Instead of bip39 i'd like to use @maaku base-32 error correction encoding (https://gist.github.com/maaku/8996338). Users could write down the used master seed (or print if we would add a such option to the GUI).(not sure about that but i think users should create a print of the seeds 32byte hex representation. Brainwallets tend to have weak security and are social-conceptual a bad idea).activeHDChain) which is somehow unavoidable (change addresses, etc.).Persistance
RPC
This adds 5 new rpc commands
hdaddchainallows to add a new hd chain of keyshdgetaddressget next available external keyhdsetchainset the active chain of keys (enables basic chain rotation)hdsendtoaddresscopy of sendtoaddress but uses a hd pub key for the change addresshdgetinfolist the available chains of keysGUI
The UI still uses normal key operation. Switch to HD would be trivial, but, i'd like to extend the "first start wizard" to allow selecting a chain and encrypt before writing unencrypted data to the database.
What's next
hdaddchainRPC. Signing would fail in a such case.hdgetaddresscall [as well as change output keys]).