commit b0942e05fb47af7a186a7c81675622419ecedb81
parent 9be1f9b1443423f9f5a0ef80988866923da596e2
Author: Shinoa-Fores <btcinfo@sdf.org>
Date: Wed, 13 Jan 2021 17:35:13 -0500
mod6_privkey_tools.vpatch
Diffstat:
7 files changed, 107 insertions(+), 9 deletions(-)
diff --git a/bitcoin/src/base58.h b/bitcoin/src/base58.h
@@ -18,6 +18,7 @@
#include <string>
#include <vector>
#include "bignum.h"
+#include "key.h"
static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
@@ -315,4 +316,32 @@ public:
}
};
+/** 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 --git a/bitcoin/src/bitcoinrpc.cpp b/bitcoin/src/bitcoinrpc.cpp
@@ -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 @@ Value verifymessage(const Array& params, bool fHelp)
if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig))
return false;
- return (key.GetAddress() == addr);
+ return (CBitcoinAddress(key.GetPubKey()) == addr);
}
@@ -1838,6 +1839,60 @@ Value eatblock(const Array& params, bool fHelp)
} // ... 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 @@ pair<string, rpcfn_type> pCallTable[] =
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 --git a/bitcoin/src/key.h b/bitcoin/src/key.h
@@ -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 @@ public:
return true;
}
- // Get the address corresponding to this key
- CBitcoinAddress GetAddress() const
- {
- return CBitcoinAddress(GetPubKey());
- }
-
bool IsValid()
{
if (!fSet)
diff --git a/bitcoin/src/keystore.cpp b/bitcoin/src/keystore.cpp
@@ -29,7 +29,7 @@ bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned c
bool CBasicKeyStore::AddKey(const CKey& key)
{
CRITICAL_BLOCK(cs_KeyStore)
- mapKeys[key.GetAddress()] = key.GetSecret();
+ mapKeys[CBitcoinAddress(key.GetPubKey())] = key.GetSecret();
return true;
}
diff --git a/bitcoin/src/keystore.h b/bitcoin/src/keystore.h
@@ -28,6 +28,15 @@ public:
// 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 --git a/bitcoin/src/wallet.cpp b/bitcoin/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();
diff --git a/bitcoin/src/wallet.h b/bitcoin/src/wallet.h
@@ -73,6 +73,7 @@ public:
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);