aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2011-07-13 11:56:38 +0200
committerPieter Wuille <sipa@ulyssis.org>2011-12-17 21:49:48 +0100
commit95d888a6d1f659a5cb81124e0d97966b9de1f139 (patch)
treedb17f76d0517ddbf12fd9144948816e930439eef
parent30ab2c9c46ce38197017ce6a6e13869617e692c7 (diff)
downloadbitcoin-95d888a6d1f659a5cb81124e0d97966b9de1f139.tar.xz
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.pro1
-rw-r--r--src/bitcoinrpc.cpp12
-rw-r--r--src/makefile.mingw1
-rw-r--r--src/makefile.osx1
-rw-r--r--src/makefile.unix1
-rw-r--r--src/rpcdump.cpp101
-rw-r--r--src/wallet.cpp10
-rw-r--r--src/wallet.h1
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);