diff -uNr a/bitcoin/src/base58.h b/bitcoin/src/base58.h
--- a/bitcoin/src/base58.h e4fa4700d17d7da955e3ee980c4a4315e44655dafdec0a4657278e174fa92a187de81c121d30b85a86fd0fe4334867ca73090142c58a3d51083f4ebe7dd4b35c
+++ b/bitcoin/src/base58.h 1f4664b4c9784cc26df8a5cdcbff6523e4e3cc5e0baf7940896f757d8d88f1d82110bd6e5cde43c17d989bdf8fb48500d4fb1706e87f5dca29b7dc9a0c0585f7
@@ -18,6 +18,7 @@
 #include <string>
 #include <vector>
 #include "bignum.h"
+#include "key.h"
 
 static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
 
@@ -315,4 +316,32 @@
     }
 };
 
+/** A base58-encoded secret key */
+class CBitcoinSecret : public CBase58Data
+{
+public:
+    void SetSecret(const CSecret& vchSecret)
+    { 
+        assert(vchSecret.size() == 32);
+        SetData(128, &vchSecret[0], vchSecret.size());
+    }
+
+    CSecret GetSecret()
+    {
+        CSecret vchSecret;
+        vchSecret.resize(32);
+        memcpy(&vchSecret[0], &vchData[0], 32);
+        return vchSecret;
+    }
+
+    CBitcoinSecret(const CSecret& vchSecret)
+    {
+        SetSecret(vchSecret);
+    }
+
+    CBitcoinSecret()
+    {
+    }
+};
+
 #endif
diff -uNr a/bitcoin/src/bitcoinrpc.cpp b/bitcoin/src/bitcoinrpc.cpp
--- a/bitcoin/src/bitcoinrpc.cpp ede2e19dd0ce3d03f54689cbeda30b4b36152f7e532b3d34f0f8c55bb292f7d25c149b88162d96a8208997237a32566d0e555aa7105bfed8175983d80ad892e6
+++ b/bitcoin/src/bitcoinrpc.cpp 7a2e0923be3e44c746a463b71649fb4ca12729a3aa0dd9e0e8ac83ed47dd240fa22dbb4fc0c6220e7beab25df3540220accdca04544f77992212c178f31f2131
@@ -7,6 +7,7 @@
 #include "db.h"
 #include "net.h"
 #include "init.h"
+#include "util.h"
 #undef printf
 #include <boost/asio.hpp>
 #include <boost/iostreams/concepts.hpp>
@@ -584,7 +585,7 @@
     if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig))
         return false;
 
-    return (key.GetAddress() == addr);
+    return (CBitcoinAddress(key.GetPubKey()) == addr);
 }
 
 
@@ -1838,6 +1839,60 @@
 } // ... but will return 'false' if we already have the block.
 
 
+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;
+    CSecret secret = vchSecret.GetSecret();
+    key.SetSecret(secret);
+    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();
+    }
+
+    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();
+}
+
 
 //
 // Call Table
@@ -1887,6 +1942,8 @@
     make_pair("listsinceblock",        &listsinceblock),
     make_pair("dumpblock",              &dumpblock),
     make_pair("eatblock",               &eatblock),
+    make_pair("importprivkey",          &importprivkey),
+    make_pair("dumpprivkey",            &dumpprivkey),
 };
 map<string, rpcfn_type> mapCallTable(pCallTable, pCallTable + sizeof(pCallTable)/sizeof(pCallTable[0]));
 
diff -uNr a/bitcoin/src/key.h b/bitcoin/src/key.h
--- a/bitcoin/src/key.h afe71ade56fae65b970ff3dfb3f14edacee0af497ae57e2d2502c9a4b4f49f3336f9d3794b72a87d185b92fc01f1a5077e1ccd63a61ac4fa9c4464c6224fd1e4
+++ b/bitcoin/src/key.h 6c895cb293f5a285f55bd313d7df2020be08f1792b0c6ec649a359661f38fbc6b8045de847a44cd9fd8429cdc2e960364d2eed6346ee042f32bb46798bcdb189
@@ -14,7 +14,6 @@
 
 #include "serialize.h"
 #include "uint256.h"
-#include "base58.h"
 
 // secp160k1
 // const unsigned int PRIVATE_KEY_SIZE = 192;
@@ -419,12 +418,6 @@
         return true;
     }
 
-    // Get the address corresponding to this key
-    CBitcoinAddress GetAddress() const
-    {
-        return CBitcoinAddress(GetPubKey());
-    }
-
     bool IsValid()
     {
         if (!fSet)
diff -uNr a/bitcoin/src/keystore.cpp b/bitcoin/src/keystore.cpp
--- a/bitcoin/src/keystore.cpp d11a428a6fd4d8431cce1195406dff39b0a585a0f44c6156a07a33e02c61d711220747b25bf9c341e88deae60719c1ddeb03df016f7374b966b3a0b830e6f98a
+++ b/bitcoin/src/keystore.cpp 86eca03a230c96ee276a1269c8f53b60e6d12b104d2805b09227eac556fd40b76ea817001f0991c3c8929bcbd8281af4fcb62513059a5b1a18986147d2905dfe
@@ -29,7 +29,7 @@
 bool CBasicKeyStore::AddKey(const CKey& key)
 {
     CRITICAL_BLOCK(cs_KeyStore)
-        mapKeys[key.GetAddress()] = key.GetSecret();
+        mapKeys[CBitcoinAddress(key.GetPubKey())] = key.GetSecret();
     return true;
 }
 
diff -uNr a/bitcoin/src/keystore.h b/bitcoin/src/keystore.h
--- a/bitcoin/src/keystore.h 247c94ea309f95ddc3b90dcd41dd9212bd5269e8772816bb272a1152422cc1c50bead6370495043a9abc924e119c926d55ecd7f39d1022c7d4eb50718188a641
+++ b/bitcoin/src/keystore.h ed95d6650ae506d0883462041d5035216fdb08534e179ea59deabf5226ce23b6922b0a5ff005202f7732265fbb6b5a4612bdbc7d950d6fb921babbf6bba83c77
@@ -28,6 +28,15 @@
     // This may succeed even if GetKey fails (e.g., encrypted wallets)
     virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
 
+    virtual bool GetSecret(const CBitcoinAddress &address, CSecret& vchSecret) const
+    {
+        CKey key;
+        if (!GetKey(address, key))
+            return false;
+        vchSecret = key.GetSecret();
+        return true;
+    }
+
     // Generate a new key, and add it to the store
     virtual std::vector<unsigned char> GenerateNewKey();
 };
diff -uNr a/bitcoin/src/wallet.cpp b/bitcoin/src/wallet.cpp
--- a/bitcoin/src/wallet.cpp bdc4fc472be4a86fb91fa69368faace04414fdeee5b8c82795e31d37e21581b973caf7f3e9ccc27d487944a5782e3b59615180eab87c8b3e81242901f3039e4d
+++ b/bitcoin/src/wallet.cpp 5215203ab6bf6d76003d6e82b3c54145fb5f59b41af5b88d72d315e0723fea8e1313894707ec159d2303a22109b1d8961aa822ae2dd45416bd00e440832f6ee3
@@ -224,6 +224,15 @@
     }
 }
 
+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();
diff -uNr a/bitcoin/src/wallet.h b/bitcoin/src/wallet.h
--- a/bitcoin/src/wallet.h 86f5e1ca584e6aa01b956278ea06eff4f79b58ca386c490fe605384923f90fcc710fd6bf2f14926d5dfd43e17fc5655a0150b32bc750f05506baf439255c8e30
+++ b/bitcoin/src/wallet.h e99f1c98e8619088d9ec26e6334e58316381f55fa449a510a6595d850302f2c3c250853e2637e4c28c223fcb73e13f7bf74ca2d5c866aff849d6bda6d601483f
@@ -73,6 +73,7 @@
     bool Unlock(const SecureString& strWalletPassphrase);
     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);