-
Notifications
You must be signed in to change notification settings - Fork 38.7k
[Wallet] Add simplest BIP32/deterministic key generation implementation #8035
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
Conversation
|
Nice minimalistic PR. One question though. Why to use m/0'/0'/i instead of something more standard? BIP32 proposes m/0'/0/i for external chains (I suppose Core in current implementation does not need internal/change chain). Or even better - use m/0/i, which is forward compatible with BIP44 (maybe Core will make it somedays). m/0/i is subset of BIP44 - an account. |
src/wallet/wallet.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.
No need for strprintf. See previous line.
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.
Hmm... I have looked at walletbroadcast, there strprintf is also used. Isn't more flexible for the translation then?
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 think you want to strprintf(_(string)) the whole string and not two separate stings, as other languages might have different grammar. but consider it a nit.
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/Has only affect/Only has effect/
|
Concept ACK Nice, small, elegant 👍 |
|
What should RPC |
|
Some import path needed then. |
|
Concept ACK |
|
@slush0: One reason for the current keypath is the use hardened-only key derivation. But I agree. We could discuss the default keypath and the keypath flexibility in a such follow up PR. This PR only intent to solve the "backup problem" by using deterministic key derivation. So we could even think of using m/k'. |
ce6332e to
c3b8aa5
Compare
|
Fixed @paveljanik nits. |
@jonasschnelli It's actually quite useful feature, and it may be even for Core. I can imagine somebody who'll have Qt wallet awfully out of sync and will need to get his funds ASAP. Then loading the backup to some other software like Multibit HD will do the job. BIP44 is actually being used by most of current wallets so heading towards the same structure makes sense.
Fair point and I appreciate somebody is finally addressing it. |
src/wallet/wallet.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.
the the
c3b8aa5 to
30815d2
Compare
|
Force push fixed @paveljanik nits. Formatted some of the code with clang-format. |
src/wallet/wallet.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.
I think you should check whether the derived key already exists in the keystore, and if so, try the next chaincounter. Otheriwse you'll give out the same keys twice after a backup restore.
EDIT: nevermind, that's not going to work. we'll also need to make keypool entries be regenerated when one is encountered in the blockchain or mempool. I think we can defer that...
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 added a loop to derive the next key as long as its not known by the wallet. I think this is required otherwise we might run into an exception if someone restores a backup or has imported a derived key of a higher child index.
|
Concept ACK So as I understand this, it won't affect the keys already in the wallet, right? It just generates all new keys using the HD master key? Also there should be an RPC command to dump the master private key. |
|
@achow101:
I agree. Have a look at #6265 and #7273. |
0141792 to
cc1df8f
Compare
src/wallet/wallet.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.
external only for now? (and in the other 2 places in the PR)
src/wallet/wallet.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.
Can be simplified a bit:
else if (mapArgs.count("-usehd")) {
bool useHd = GetBoolArg("-usehd", DEFAULT_USEHD);
if (!walletInstance->hdChain.masterKeyID.IsNull() && !useHD)
return InitError(strprintf(_("Error loading %s: You can't disable HD on a already existing HD wallet"), walletFile));
if (walletInstance->hdChain.masterKeyID.IsNull() && useHD)
return InitError(strprintf(_("Error loading %s: You can't enable HD on a already existing non-HD wallet"), walletFile));
}
(also please introduce a DEFAULT_USEHD constant)
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.
Thanks. Much simpler.
Force push updated last commit.
71ff55f to
afcd77e
Compare
|
utACK afcd77e Even though this wallet change is reasonably risky, I think this has received enough review for correctness, and it should be merged now to make sure it gets more actual testing. |
… implementation afcd77e Detect -usehd mismatches when wallet.dat already exists (Jonas Schnelli) 17c0131 [Docs] Add release notes and bip update for Bip32/HD wallets (Jonas Schnelli) c022e5b [Wallet] use constant for bip32 hardened key limit (Jonas Schnelli) f190251 [Wallet] Add simplest BIP32/deterministic key generation implementation (Jonas Schnelli)
|
Post merge utACK. Will also test. |
|
Just found out about this PR. Would like to clarify the keypath: It's purpose number is I'm asking because otherwise it could be incompatible to how bitcoinj derives addresses. |
|
@schildbach: We have decided to go with a "hardened only derivation" version for the first implementation. Using On top of that, I personally think importing a xpriv into another wallet in order to "reconstruct everything" is not a very good concept. |
|
@jonasschnelli Yes that's fine. I just wanted to make sure there is no "partial overlap" with the bitcoinj impl. |
|
So, how does one import a BIP32 master key into an existing wallet? |
|
I'm switching to Core (from Electrum) after this lands in 0.13, thanks for your efforts. |
That functionality currently doesn't exist. Please read the OP: this is the smallest possible change to introduce BIP32 into Bitcoin Core. This made it realistic to get it reviewed and merged in a small timespan. More functionality can be added later. |
| // key metadata is not required | ||
| CPubKey pubkey = key.GetPubKey(); | ||
| if (!AddKeyPubKey(key, pubkey)) | ||
| throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed"); |
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.
Nit: Wrong function name
|
Post-merge review comments, sorry :/ (continued from IRC):
I think all but the first could easily be fixed even now, if we decide they are, indeed, issues. |
|
Thanks for the post-merge review Matt.
Yes. Agree. This was done after two of my former PR did not made it into the master (#6265 #7273) and I was looking for a simpler solutions.
This is to ensure we don't re-generate an already existing key (there are some cases where this would be possible otherwise). |
|
re: GenerateNewKey(): Not sure what your response was about (seems to be communication failure there), but it was pointed out to me that I missed the save line and was incorrect. |
|
I foget my sceond wallet passwor. Thats why i cant get backup. I need help |
|
@zihad944 what problem do you have specifically, what do you mean by "my second wallet password"? |
sorawee1970
left a comment
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.
src/wallet/walletdb.h
Probably most simplest HD implementation.
--usehd=0CHDChain) which contains the CKeyID for the master key together with the child key counterI'll add some tests once there are some conceptual acks (and also to keep the diff at a very minimum).