diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2011-07-13 11:56:38 +0200 |
---|---|---|
committer | Pieter Wuille <sipa@ulyssis.org> | 2011-12-17 21:49:48 +0100 |
commit | 95d888a6d1f659a5cb81124e0d97966b9de1f139 (patch) | |
tree | db17f76d0517ddbf12fd9144948816e930439eef | |
parent | 30ab2c9c46ce38197017ce6a6e13869617e692c7 (diff) |
Key import and export
Introduces two new RPC calls:
* dumpprivkey: retrieve the private key corresponding to an address
* importprivkey: add a private key to your wallet
The private key format is analoguous to the address format. It is
a 51-character base58-encoded string, that includes a version number
and a checksum.
Includes patch by mhanne:
* add optional account parameter for importprivkey, if omitted use default
-rw-r--r-- | bitcoin-qt.pro | 1 | ||||
-rw-r--r-- | src/bitcoinrpc.cpp | 12 | ||||
-rw-r--r-- | src/makefile.mingw | 1 | ||||
-rw-r--r-- | src/makefile.osx | 1 | ||||
-rw-r--r-- | src/makefile.unix | 1 | ||||
-rw-r--r-- | src/rpcdump.cpp | 101 | ||||
-rw-r--r-- | src/wallet.cpp | 10 | ||||
-rw-r--r-- | src/wallet.h | 1 |
8 files changed, 124 insertions, 4 deletions
diff --git a/bitcoin-qt.pro b/bitcoin-qt.pro index 0989fe8b04..853f2faf93 100644 --- a/bitcoin-qt.pro +++ b/bitcoin-qt.pro @@ -174,6 +174,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/qt/transactionview.cpp \ src/qt/walletmodel.cpp \ src/bitcoinrpc.cpp \ + src/rpcdump.cpp \ src/qt/overviewpage.cpp \ src/qt/csvmodelwriter.cpp \ src/crypter.cpp \ diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index fcf2482ee0..e3378782c0 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -9,6 +9,7 @@ #include "init.h" #undef printf #include <boost/asio.hpp> +#include <boost/filesystem.hpp> #include <boost/iostreams/concepts.hpp> #include <boost/iostreams/stream.hpp> #include <boost/algorithm/string.hpp> @@ -42,6 +43,8 @@ static std::string strRPCUserColonPass; static int64 nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; +extern Value dumpprivkey(const Array& params, bool fHelp); +extern Value importprivkey(const Array& params, bool fHelp); Object JSONRPCError(int code, const string& message) { @@ -1599,7 +1602,6 @@ Value validateaddress(const Array& params, bool fHelp) return ret; } - Value getwork(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) @@ -1840,13 +1842,15 @@ pair<string, rpcfn_type> pCallTable[] = make_pair("sendmany", &sendmany), make_pair("gettransaction", &gettransaction), make_pair("listtransactions", &listtransactions), - make_pair("signmessage", &signmessage), - make_pair("verifymessage", &verifymessage), + make_pair("signmessage", &signmessage), + make_pair("verifymessage", &verifymessage), make_pair("getwork", &getwork), make_pair("listaccounts", &listaccounts), make_pair("settxfee", &settxfee), make_pair("getmemorypool", &getmemorypool), - make_pair("listsinceblock", &listsinceblock), + make_pair("listsinceblock", &listsinceblock), + make_pair("dumpprivkey", &dumpprivkey), + make_pair("importprivkey", &importprivkey) }; map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0])); diff --git a/src/makefile.mingw b/src/makefile.mingw index ce3da062ec..ed718b89ea 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -70,6 +70,7 @@ OBJS= \ obj/net.o \ obj/protocol.o \ obj/bitcoinrpc.o \ + obj/rpcdump.o \ obj/script.o \ obj/util.o \ obj/wallet.o diff --git a/src/makefile.osx b/src/makefile.osx index 690e35a3e7..4b0b521a33 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -81,6 +81,7 @@ OBJS= \ obj/net.o \ obj/protocol.o \ obj/bitcoinrpc.o \ + obj/rpcdump.o \ obj/script.o \ obj/util.o \ obj/wallet.o diff --git a/src/makefile.unix b/src/makefile.unix index a8b6837c8a..a436f968bc 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -119,6 +119,7 @@ OBJS= \ obj/net.o \ obj/protocol.o \ obj/bitcoinrpc.o \ + obj/rpcdump.o \ obj/script.o \ obj/util.o \ obj/wallet.o diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp new file mode 100644 index 0000000000..f3978fbce8 --- /dev/null +++ b/src/rpcdump.cpp @@ -0,0 +1,101 @@ +// Copyright (c) 2011 Bitcoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include "headers.h" +#include "init.h" // for pwalletMain +#include "bitcoinrpc.h" + +// #include <boost/asio.hpp> +// #include <boost/iostreams/concepts.hpp> +// #include <boost/iostreams/stream.hpp> +#include <boost/lexical_cast.hpp> +// #ifdef USE_SSL +// #include <boost/asio/ssl.hpp> +// typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream; +// #endif +// #include <boost/xpressive/xpressive_dynamic.hpp> +#include "json/json_spirit_reader_template.h" +#include "json/json_spirit_writer_template.h" +#include "json/json_spirit_utils.h" + +#define printf OutputDebugStringF + +// using namespace boost::asio; +using namespace json_spirit; +using namespace std; + +extern Object JSONRPCError(int code, const string& message); + +class CTxDump +{ +public: + CBlockIndex *pindex; + int64 nValue; + bool fSpent; + CWalletTx* ptx; + int nOut; + CTxDump(CWalletTx* ptx = NULL, int nOut = -1) + { + pindex = NULL; + nValue = 0; + fSpent = false; + this->ptx = ptx; + this->nOut = nOut; + } +}; + +Value importprivkey(const Array& params, bool fHelp) +{ + if (fHelp || params.size() < 1 || params.size() > 2) + throw runtime_error( + "importprivkey <bitcoinprivkey> [label]\n" + "Adds a private key (as returned by dumpprivkey) to your wallet."); + + string strSecret = params[0].get_str(); + string strLabel = ""; + if (params.size() > 1) + strLabel = params[1].get_str(); + CBitcoinSecret vchSecret; + bool fGood = vchSecret.SetString(strSecret); + + if (!fGood) throw JSONRPCError(-5,"Invalid private key"); + + CKey key; + key.SetSecret(vchSecret.GetSecret()); + CBitcoinAddress vchAddress = CBitcoinAddress(key.GetPubKey()); + + CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(pwalletMain->cs_wallet) + { + pwalletMain->MarkDirty(); + pwalletMain->SetAddressBookName(vchAddress, strLabel); + + if (!pwalletMain->AddKey(key)) + throw JSONRPCError(-4,"Error adding key to wallet"); + + pwalletMain->ScanForWalletTransactions(pindexGenesisBlock, true); + pwalletMain->ReacceptWalletTransactions(); + } + + MainFrameRepaint(); + + return Value::null; +} + +Value dumpprivkey(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 1) + throw runtime_error( + "dumpprivkey <bitcoinaddress>\n" + "Reveals the private key corresponding to <bitcoinaddress>."); + + string strAddress = params[0].get_str(); + CBitcoinAddress address; + if (!address.SetString(strAddress)) + throw JSONRPCError(-5, "Invalid bitcoin address"); + CSecret vchSecret; + if (!pwalletMain->GetSecret(address, vchSecret)) + throw JSONRPCError(-4,"Private key for address " + strAddress + " is not known"); + return CBitcoinSecret(vchSecret).ToString(); +} diff --git a/src/wallet.cpp b/src/wallet.cpp index f9157e01d5..87f5dfd659 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -224,6 +224,15 @@ void CWallet::WalletUpdateSpent(const CTransaction &tx) } } +void CWallet::MarkDirty() +{ + CRITICAL_BLOCK(cs_wallet) + { + BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet) + item.second.MarkDirty(); + } +} + bool CWallet::AddToWallet(const CWalletTx& wtxIn) { uint256 hash = wtxIn.GetHash(); @@ -1445,6 +1454,7 @@ void CWallet::GetAllReserveAddresses(set<CBitcoinAddress>& setAddress) CWalletDB walletdb(strWalletFile); CRITICAL_BLOCK(cs_main) + CRITICAL_BLOCK(cs_wallet) BOOST_FOREACH(const int64& id, setKeyPool) { CKeyPool keypool; diff --git a/src/wallet.h b/src/wallet.h index 95537be63e..78f055a604 100644 --- a/src/wallet.h +++ b/src/wallet.h @@ -74,6 +74,7 @@ public: bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase); bool EncryptWallet(const SecureString& strWalletPassphrase); + void MarkDirty(); bool AddToWallet(const CWalletTx& wtxIn); bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false, bool fFindBlock = false); bool EraseFromWallet(uint256 hash); |