-
Notifications
You must be signed in to change notification settings - Fork 35.6k
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
Watch-Only Addresses: Separating Transaction Signing From Transaction Processing #2121
Conversation
Sorry, guys - I changed the branch names and it closed the original pull request #2117 The pull request remains open but under a new name. |
A multiple wallet version of bitcoind is underway: #2124 That branch will eventually be merged with this one. In order to distinguish spendable wallets from watch-only wallets, a new member will be added to the CWallet class as well as a new corresponding value to the database file. The CWallet methods as well as RPC calls will then be able to distinguish between the two cases and exhibit the correct behavior. |
OMG this is great! |
Automatic sanity-testing: PASSED, see http://jenkins.bluematt.me/pull-tester/89f806c1d5e171ab48b29eeea8937fb2078e917a for binaries and test log. |
Neat. I'm surprised it was this easy. |
========================================================== A major issue many have faced in using bitcoind to build applications is the lack of RPC support for tracking transactions and balances without having to know and keep associated private keys in the wallet. Oftentimes I want to watch other people's transactions or to keep my signing nodes behind tighter security while using separate relay nodes to service all nonsigning, non-key-generating application functionality such as sending payment and confirmation alerts. In order to achieve these objectives, I have had to build a bunch of custom software - much of which duplicates functionality that is already present in the Satoshi Client. This fork is an attempt at addressing some of these concerns without having to fundamentally restructure the client architecture. (Thanks, sipa!) The proposal is to add another kind of object to the wallet database - a bitcoin address sans private key - which the client treats as if it were any other wallet adddress except for when it comes to signing and privkey export operations. This means RPC calls such as getreceivedbyaddress and listtransactions can be used on arbitrary bitcoin addresses. I've added an RPC call: importaddress <bitcoinaddress> [label] [rescan=true] The address is added as a new type of serialized object in wallet.dat and loads into the key maps of the CKeyStore instances with the key set to the CKeyID and the secret set to an empty vector. Please test it out and let me know what you think. Cheers, -Eric Lombrozo
Just a remark so we don't forget (I haven't checked whether it's possible with this implementation): it'd be nice to have a way to include arbitrary P2SH addresses as watch-only |
Looks pretty good. Minor nit: "label" is deprecated in favor of "account." The help text must be changed. And if you are going to change the help text, go ahead and name the var strAccount as other, new code does. Would like to see this merged. |
Yes, please rebase. Regarding labels vs. accounts - I consider them separate things, which incidentally (and regrettably) overlap (if an address A has label L, payments to A will credit the account also called L). In this case, similarity with the existing API (importprivkey) is more important in any case, so I prefer seeing it called label. |
is it possible to download and test this modification? I'd love to try it. Can't seem to select this branch |
I would love to see this rebased and merged! I'm going to be using this functionality for an upcoming new version of Coinpunk, to support client-side encryption for private keys, so that I won't be able to release the new Coinpunk until this is released, so it would be amazing if this commit could get into the next release. I don't think it's too dangerous, just because I believe it's not handling anything that could potentially lose bitcoins, but I could be mistaken. But it would be awesome. Let me know if I can help in any way. Thanks, you guys are awesome. :-) |
I'd also love to see this make the next release. I have a project where I need to watch a large number of addresses without having the private keys on the server. I think the pull request would solve my biggest current development challenge. |
Just thinking about an alternative to this: Set a wallet passphrase so that all the private keys are encrypted and then write a separate utility to overwrite the encrypted private keys with zeros in the wallet file. Since bitcoind is not going to access the keys anyway while they're encrypted, it shouldn't matter that they're actually zeros. So that will effectively produce watch-only addresses. However, it still wouldn't be possible to add new watch-only addresses via rpc, which this patch can do. By the way, could a slightly cleaner implementation of this be to store watch-only addresses as normal keys (except where the encrypted private key is cleared) instead of adding the new "address" data type in the walletdb? |
Thanks for this, tstranex. I hadn't considered that. I might look into this as a fall back. In my case, I'm using vanity addresses so actually don't need to create addresses via RPC. |
@CodeShark Needs rebase. Although I don't think this makes sense to merge until we have HD wallets and it can be an entire read-only address-chain... |
I compiled and tested this code, and it seems to work fine. Does it collide with HD wallets? If not, I would really like to advocate for getting this in. I strongly believe that this code solves a critically urgent security problem. Without this code, I'm concerned that we may get more services that put private keys on servers simply because they have no choice, which could lead to more major thefts, which could contribute to undermining the soundness of the Bitcoin ecosystem. The last thing Bitcoin needs right now is another high profile wallet theft fiasco. This is a very important and very significant security upgrade, that I believe will dramatically lead to the improvement of security across the board, for many different types of applications. To provide analogies, this could be as important to bitcoind security as ProPolice was to buffer overflow prevention, or PBKDF2 was to password hashing. Please consider including this in the next release of bitcoind. Do it for the people that have lost a lot of money to server wallet thefts. Do it for the children. 😉 |
@kyledrake HD wallets should solve all of those issues, that's my point ;) |
@luke-jr I'm cool with HD Wallets, but HD Wallets are a long way away. This is a light, simple patch to solve a very big problem, that enables some major new infrastructure for bitcoin. I tried to rebase it and I got very close, I think someone with knowledge of the bitcoin source would very easily be able to rebase this. The biggest hurdle was the @sipa (I think?) refactor of |
So here is my rebase attempt: It fails to compile on this:
Apparently CSecret has gone away.. any ideas on how to fix this? |
I think CSecret became CKey (and the old CKey become CPubKey). HD wallets IIRC are planned for the next release. |
CKey and CSecret were merged. CPubKey is still CPubKey but inherited some of the pubkey-only functionality of the former CKey. I consider this a very useful feature, and it's orthogonal to HD wallets. Sure, BIP32 specifies a derivation that can be useful for watch-only wallets, but it still needs to be implemented. |
@sipa Do you have any free time this week to look at this? I think it's a really super easy fix for you because you are very familiar with the code (and awesome). I think I got pretty close, I just don't know any C++ and I'm completely unfamiliar with the bitcoin keystore plumbing. http://i.imgur.com/xVyoSl.jpg |
FYI this patch compiles successfully against ec0004a. I've tested |
Automatic sanity-testing: FAILED MERGE, see http://jenkins.bluematt.me/pull-tester/007a28374165f67d713a318bc37ef1286684cad5 for test log. This pull does not merge cleanly onto current master |
For those of us in the bitcoind camp using an old unstable master so we can get Since I posted on this pull request, I have gotten emails from people using this commit in production, because there is no other alternative. Which makes me excited about its potential to improve bitcoin security, but also terrified because they are using it with unstable bitcoind. It would be really great if someone was able to look at this, I really doubt it would take more than a few hours for a seasoned member of the glorious, highly talented bitcoin development team to resolve the merge conflicts on it (@sipa? @jgarzik?). |
@kyledrake Have a look at #2861. |
It would be nice to add a feature in the code to easily or automatically LOCKUNSPENT all unspent coins of the imported watch-only address. Not to mention that those coins are not spendable without privkey. In shell I run this: |
Superceded by #2861, closing. |
Perfect! |
…ut and version) (bitcoin#2121) The initial ping is sent with defaults which switch MNs to SENTINEL_PING_EXPIRED state while they should really be in PRE_ENABLED state. The fix is to split this verification in two parts - this way sentinel version is only checked after at least one ping is received from the masternode itself and not from the cold wallet.
…ut and version) (bitcoin#2121) The initial ping is sent with defaults which switch MNs to SENTINEL_PING_EXPIRED state while they should really be in PRE_ENABLED state. The fix is to split this verification in two parts - this way sentinel version is only checked after at least one ping is received from the masternode itself and not from the cold wallet.
…ut and version) (bitcoin#2121) The initial ping is sent with defaults which switch MNs to SENTINEL_PING_EXPIRED state while they should really be in PRE_ENABLED state. The fix is to split this verification in two parts - this way sentinel version is only checked after at least one ping is received from the masternode itself and not from the cold wallet.
…ut and version) (bitcoin#2121) The initial ping is sent with defaults which switch MNs to SENTINEL_PING_EXPIRED state while they should really be in PRE_ENABLED state. The fix is to split this verification in two parts - this way sentinel version is only checked after at least one ping is received from the masternode itself and not from the cold wallet.
…ut and version) (bitcoin#2121) The initial ping is sent with defaults which switch MNs to SENTINEL_PING_EXPIRED state while they should really be in PRE_ENABLED state. The fix is to split this verification in two parts - this way sentinel version is only checked after at least one ping is received from the masternode itself and not from the cold wallet.
…ut and version) (bitcoin#2121) The initial ping is sent with defaults which switch MNs to SENTINEL_PING_EXPIRED state while they should really be in PRE_ENABLED state. The fix is to split this verification in two parts - this way sentinel version is only checked after at least one ping is received from the masternode itself and not from the cold wallet.
A major issue many have faced in using bitcoind to build applications is the lack of RPC support for tracking transactions and balances without having to know and keep associated private keys in the wallet. Oftentimes one might want to watch other people's transactions or to keep signing nodes behind tighter security while using separate relay nodes to service all nonsigning, non-key-generating application functionality such as sending payment and confirmation alerts.
In order to achieve these objectives, I have had to build a bunch of custom software - much of which duplicates functionality that is already present in the Satoshi Client. This pull request is an attempt at addressing some of these concerns without having to fundamentally restructure the client architecture. (Thanks, sipa!)
The proposal is to add another kind of object to the wallet database - a bitcoin address sans private key - which the client treats as if it were any other wallet adddress except for when it comes to signing and privkey export operations. This means RPC calls such as getreceivedbyaddress and listtransactions can be used on arbitrary bitcoin addresses.
I've added an RPC call:
The address is added as a new type of serialized object in wallet.dat and loads into the key maps of the CKeyStore instances with the key set to the CKeyID and the secret set to an empty vector.
Please test it out and let me know what you think.
Cheers,
-Eric Lombrozo