Browse Source

Encapsulate public keys in CPubKey

0.8
Pieter Wuille 13 years ago
parent
commit
fd61d6f506
  1. 6
      src/base58.h
  2. 20
      src/bitcoinrpc.cpp
  3. 2
      src/init.cpp
  4. 12
      src/key.cpp
  5. 39
      src/key.h
  6. 22
      src/keystore.cpp
  7. 8
      src/keystore.h
  8. 2
      src/main.cpp
  9. 2
      src/qt/addresstablemodel.cpp
  10. 2
      src/script.cpp
  11. 6
      src/script.h
  12. 14
      src/test/multisig_tests.cpp
  13. 32
      src/wallet.cpp
  14. 24
      src/wallet.h
  15. 2
      src/walletdb.cpp
  16. 20
      src/walletdb.h

6
src/base58.h

@ -275,9 +275,9 @@ public:
return true; return true;
} }
void SetPubKey(const std::vector<unsigned char>& vchPubKey) void SetPubKey(const CPubKey& vchPubKey)
{ {
SetHash160(Hash160(vchPubKey)); SetHash160(vchPubKey.GetID());
} }
bool SetScriptHash160(const uint160& hash160) bool SetScriptHash160(const uint160& hash160)
@ -333,7 +333,7 @@ public:
SetHash160(hash160In); SetHash160(hash160In);
} }
CBitcoinAddress(const std::vector<unsigned char>& vchPubKey) CBitcoinAddress(const CPubKey& vchPubKey)
{ {
SetPubKey(vchPubKey); SetPubKey(vchPubKey);
} }

20
src/bitcoinrpc.cpp

@ -590,7 +590,7 @@ Value getnewaddress(const Array& params, bool fHelp)
pwalletMain->TopUpKeyPool(); pwalletMain->TopUpKeyPool();
// Generate a new key that is added to wallet // Generate a new key that is added to wallet
std::vector<unsigned char> newKey; CPubKey newKey;
if (!pwalletMain->GetKeyFromPool(newKey, false)) if (!pwalletMain->GetKeyFromPool(newKey, false))
throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first"); throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
CBitcoinAddress address(newKey); CBitcoinAddress address(newKey);
@ -611,12 +611,12 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
bool bKeyUsed = false; bool bKeyUsed = false;
// Check if the current key has been used // Check if the current key has been used
if (!account.vchPubKey.empty()) if (account.vchPubKey.IsValid())
{ {
CScript scriptPubKey; CScript scriptPubKey;
scriptPubKey.SetBitcoinAddress(account.vchPubKey); scriptPubKey.SetBitcoinAddress(account.vchPubKey);
for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin(); for (map<uint256, CWalletTx>::iterator it = pwalletMain->mapWallet.begin();
it != pwalletMain->mapWallet.end() && !account.vchPubKey.empty(); it != pwalletMain->mapWallet.end() && account.vchPubKey.IsValid();
++it) ++it)
{ {
const CWalletTx& wtx = (*it).second; const CWalletTx& wtx = (*it).second;
@ -627,7 +627,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
} }
// Generate a new key // Generate a new key
if (account.vchPubKey.empty() || bForceNew || bKeyUsed) if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed)
{ {
if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false)) if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first"); throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
@ -1203,19 +1203,19 @@ Value addmultisigaddress(const Array& params, bool fHelp)
if (address.IsScript()) if (address.IsScript())
throw runtime_error( throw runtime_error(
strprintf("%s is a pay-to-script address",ks.c_str())); strprintf("%s is a pay-to-script address",ks.c_str()));
std::vector<unsigned char> vchPubKey; CPubKey vchPubKey;
if (!pwalletMain->GetPubKey(address, vchPubKey)) if (!pwalletMain->GetPubKey(address, vchPubKey))
throw runtime_error( throw runtime_error(
strprintf("no full public key for address %s",ks.c_str())); strprintf("no full public key for address %s",ks.c_str()));
if (vchPubKey.empty() || !pubkeys[i].SetPubKey(vchPubKey)) if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey))
throw runtime_error(" Invalid public key: "+ks); throw runtime_error(" Invalid public key: "+ks);
} }
// Case 2: hex public key // Case 2: hex public key
else if (IsHex(ks)) else if (IsHex(ks))
{ {
vector<unsigned char> vchPubKey = ParseHex(ks); CPubKey vchPubKey(ParseHex(ks));
if (vchPubKey.empty() || !pubkeys[i].SetPubKey(vchPubKey)) if (!vchPubKey.IsValid() || !pubkeys[i].SetPubKey(vchPubKey))
throw runtime_error(" Invalid public key: "+ks); throw runtime_error(" Invalid public key: "+ks);
} }
else else
@ -1954,9 +1954,9 @@ Value validateaddress(const Array& params, bool fHelp)
if (pwalletMain->HaveKey(address)) if (pwalletMain->HaveKey(address))
{ {
ret.push_back(Pair("ismine", true)); ret.push_back(Pair("ismine", true));
std::vector<unsigned char> vchPubKey; CPubKey vchPubKey;
pwalletMain->GetPubKey(address, vchPubKey); pwalletMain->GetPubKey(address, vchPubKey);
ret.push_back(Pair("pubkey", HexStr(vchPubKey))); ret.push_back(Pair("pubkey", HexStr(vchPubKey.Raw())));
CKey key; CKey key;
key.SetPubKey(vchPubKey); key.SetPubKey(vchPubKey);
ret.push_back(Pair("iscompressed", key.IsCompressed())); ret.push_back(Pair("iscompressed", key.IsCompressed()));

2
src/init.cpp

@ -604,7 +604,7 @@ bool AppInit2()
// Create new keyUser and set as default key // Create new keyUser and set as default key
RandAddSeedPerfmon(); RandAddSeedPerfmon();
std::vector<unsigned char> newDefaultKey; CPubKey newDefaultKey;
if (!pwalletMain->GetKeyFromPool(newDefaultKey, false)) if (!pwalletMain->GetKeyFromPool(newDefaultKey, false))
strErrors << _("Cannot initialize keypool") << "\n"; strErrors << _("Cannot initialize keypool") << "\n";
pwalletMain->SetDefaultKey(newDefaultKey); pwalletMain->SetDefaultKey(newDefaultKey);

12
src/key.cpp

@ -239,18 +239,18 @@ CPrivKey CKey::GetPrivKey() const
return vchPrivKey; return vchPrivKey;
} }
bool CKey::SetPubKey(const std::vector<unsigned char>& vchPubKey) bool CKey::SetPubKey(const CPubKey& vchPubKey)
{ {
const unsigned char* pbegin = &vchPubKey[0]; const unsigned char* pbegin = &vchPubKey.vchPubKey[0];
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size())) if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.vchPubKey.size()))
return false; return false;
fSet = true; fSet = true;
if (vchPubKey.size() == 33) if (vchPubKey.vchPubKey.size() == 33)
SetCompressedPubKey(); SetCompressedPubKey();
return true; return true;
} }
std::vector<unsigned char> CKey::GetPubKey() const CPubKey CKey::GetPubKey() const
{ {
int nSize = i2o_ECPublicKey(pkey, NULL); int nSize = i2o_ECPublicKey(pkey, NULL);
if (!nSize) if (!nSize)
@ -259,7 +259,7 @@ std::vector<unsigned char> CKey::GetPubKey() const
unsigned char* pbegin = &vchPubKey[0]; unsigned char* pbegin = &vchPubKey[0];
if (i2o_ECPublicKey(pkey, &pbegin) != nSize) if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size"); throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
return vchPubKey; return CPubKey(vchPubKey);
} }
bool CKey::Sign(uint256 hash, std::vector<unsigned char>& vchSig) bool CKey::Sign(uint256 hash, std::vector<unsigned char>& vchSig)

39
src/key.h

@ -9,7 +9,9 @@
#include <vector> #include <vector>
#include "allocators.h" #include "allocators.h"
#include "serialize.h"
#include "uint256.h" #include "uint256.h"
#include "util.h"
#include <openssl/ec.h> // for EC_KEY definition #include <openssl/ec.h> // for EC_KEY definition
@ -42,6 +44,39 @@ public:
explicit key_error(const std::string& str) : std::runtime_error(str) {} explicit key_error(const std::string& str) : std::runtime_error(str) {}
}; };
class CPubKey {
private:
std::vector<unsigned char> vchPubKey;
friend class CKey;
public:
CPubKey() { }
CPubKey(const std::vector<unsigned char> &vchPubKeyIn) : vchPubKey(vchPubKeyIn) { }
friend bool operator==(const CPubKey &a, const CPubKey &b) { return a.vchPubKey == b.vchPubKey; }
friend bool operator!=(const CPubKey &a, const CPubKey &b) { return a.vchPubKey != b.vchPubKey; }
friend bool operator<(const CPubKey &a, const CPubKey &b) { return a.vchPubKey < b.vchPubKey; }
IMPLEMENT_SERIALIZE(
READWRITE(vchPubKey);
)
uint160 GetID() const {
return Hash160(vchPubKey);
}
uint256 GetHash() const {
return Hash(vchPubKey.begin(), vchPubKey.end());
}
bool IsValid() const {
return vchPubKey.size() == 33 || vchPubKey.size() == 65;
}
std::vector<unsigned char> Raw() const {
return vchPubKey;
}
};
// secure_allocator is defined in serialize.h // secure_allocator is defined in serialize.h
// CPrivKey is a serialized private key, with all parameters included (279 bytes) // CPrivKey is a serialized private key, with all parameters included (279 bytes)
@ -78,8 +113,8 @@ public:
bool SetSecret(const CSecret& vchSecret, bool fCompressed = false); bool SetSecret(const CSecret& vchSecret, bool fCompressed = false);
CSecret GetSecret(bool &fCompressed) const; CSecret GetSecret(bool &fCompressed) const;
CPrivKey GetPrivKey() const; CPrivKey GetPrivKey() const;
bool SetPubKey(const std::vector<unsigned char>& vchPubKey); bool SetPubKey(const CPubKey& vchPubKey);
std::vector<unsigned char> GetPubKey() const; CPubKey GetPubKey() const;
bool Sign(uint256 hash, std::vector<unsigned char>& vchSig); bool Sign(uint256 hash, std::vector<unsigned char>& vchSig);

22
src/keystore.cpp

@ -6,7 +6,7 @@
#include "keystore.h" #include "keystore.h"
#include "script.h" #include "script.h"
bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char> &vchPubKeyOut) const bool CKeyStore::GetPubKey(const CBitcoinAddress &address, CPubKey &vchPubKeyOut) const
{ {
CKey key; CKey key;
if (!GetKey(address, key)) if (!GetKey(address, key))
@ -97,10 +97,10 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin(); CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
for (; mi != mapCryptedKeys.end(); ++mi) for (; mi != mapCryptedKeys.end(); ++mi)
{ {
const std::vector<unsigned char> &vchPubKey = (*mi).second.first; const CPubKey &vchPubKey = (*mi).second.first;
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second; const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
CSecret vchSecret; CSecret vchSecret;
if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret)) if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
return false; return false;
if (vchSecret.size() != 32) if (vchSecret.size() != 32)
return false; return false;
@ -128,9 +128,9 @@ bool CCryptoKeyStore::AddKey(const CKey& key)
return false; return false;
std::vector<unsigned char> vchCryptedSecret; std::vector<unsigned char> vchCryptedSecret;
std::vector<unsigned char> vchPubKey = key.GetPubKey(); CPubKey vchPubKey = key.GetPubKey();
bool fCompressed; bool fCompressed;
if (!EncryptSecret(vMasterKey, key.GetSecret(fCompressed), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret)) if (!EncryptSecret(vMasterKey, key.GetSecret(fCompressed), vchPubKey.GetHash(), vchCryptedSecret))
return false; return false;
if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret)) if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret))
@ -140,7 +140,7 @@ bool CCryptoKeyStore::AddKey(const CKey& key)
} }
bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) bool CCryptoKeyStore::AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
{ {
{ {
LOCK(cs_KeyStore); LOCK(cs_KeyStore);
@ -162,10 +162,10 @@ bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address); CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
if (mi != mapCryptedKeys.end()) if (mi != mapCryptedKeys.end())
{ {
const std::vector<unsigned char> &vchPubKey = (*mi).second.first; const CPubKey &vchPubKey = (*mi).second.first;
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second; const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
CSecret vchSecret; CSecret vchSecret;
if (!DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret)) if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
return false; return false;
if (vchSecret.size() != 32) if (vchSecret.size() != 32)
return false; return false;
@ -177,7 +177,7 @@ bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
return false; return false;
} }
bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, CPubKey& vchPubKeyOut) const
{ {
{ {
LOCK(cs_KeyStore); LOCK(cs_KeyStore);
@ -207,10 +207,10 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
CKey key; CKey key;
if (!key.SetSecret(mKey.second.first, mKey.second.second)) if (!key.SetSecret(mKey.second.first, mKey.second.second))
return false; return false;
const std::vector<unsigned char> vchPubKey = key.GetPubKey(); const CPubKey vchPubKey = key.GetPubKey();
std::vector<unsigned char> vchCryptedSecret; std::vector<unsigned char> vchCryptedSecret;
bool fCompressed; bool fCompressed;
if (!EncryptSecret(vMasterKeyIn, key.GetSecret(fCompressed), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret)) if (!EncryptSecret(vMasterKeyIn, key.GetSecret(fCompressed), vchPubKey.GetHash(), vchCryptedSecret))
return false; return false;
if (!AddCryptedKey(vchPubKey, vchCryptedSecret)) if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
return false; return false;

8
src/keystore.h

@ -28,7 +28,7 @@ public:
virtual bool HaveKey(const CBitcoinAddress &address) const =0; virtual bool HaveKey(const CBitcoinAddress &address) const =0;
virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0; virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0;
virtual void GetKeys(std::set<CBitcoinAddress> &setAddress) const =0; virtual void GetKeys(std::set<CBitcoinAddress> &setAddress) const =0;
virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const; virtual bool GetPubKey(const CBitcoinAddress &address, CPubKey& vchPubKeyOut) const;
// Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013 // Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013
virtual bool AddCScript(const CScript& redeemScript) =0; virtual bool AddCScript(const CScript& redeemScript) =0;
@ -98,7 +98,7 @@ public:
virtual bool GetCScript(const uint160 &hash, CScript& redeemScriptOut) const; virtual bool GetCScript(const uint160 &hash, CScript& redeemScriptOut) const;
}; };
typedef std::map<CBitcoinAddress, std::pair<std::vector<unsigned char>, std::vector<unsigned char> > > CryptedKeyMap; typedef std::map<CBitcoinAddress, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
/** Keystore which keeps the private keys encrypted. /** Keystore which keeps the private keys encrypted.
* It derives from the basic key store, which is used if no encryption is active. * It derives from the basic key store, which is used if no encryption is active.
@ -146,7 +146,7 @@ public:
bool Lock(); bool Lock();
virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
bool AddKey(const CKey& key); bool AddKey(const CKey& key);
bool HaveKey(const CBitcoinAddress &address) const bool HaveKey(const CBitcoinAddress &address) const
{ {
@ -159,7 +159,7 @@ public:
return false; return false;
} }
bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const; bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const;
bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const; bool GetPubKey(const CBitcoinAddress &address, CPubKey& vchPubKeyOut) const;
void GetKeys(std::set<CBitcoinAddress> &setAddress) const void GetKeys(std::set<CBitcoinAddress> &setAddress) const
{ {
if (!IsCrypted()) if (!IsCrypted())

2
src/main.cpp

@ -2304,7 +2304,7 @@ unsigned char pchMessageStart[4] = { 0xf9, 0xbe, 0xb4, 0xd9 };
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
{ {
static map<CService, vector<unsigned char> > mapReuseKey; static map<CService, CPubKey> mapReuseKey;
RandAddSeedPerfmon(); RandAddSeedPerfmon();
if (fDebug) if (fDebug)
printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size()); printf("received: %s (%d bytes)\n", strCommand.c_str(), vRecv.size());

2
src/qt/addresstablemodel.cpp

@ -331,7 +331,7 @@ QString AddressTableModel::addRow(const QString &type, const QString &label, con
editStatus = WALLET_UNLOCK_FAILURE; editStatus = WALLET_UNLOCK_FAILURE;
return QString(); return QString();
} }
std::vector<unsigned char> newKey; CPubKey newKey;
if(!wallet->GetKeyFromPool(newKey, true)) if(!wallet->GetKeyFromPool(newKey, true))
{ {
editStatus = KEY_GENERATION_FAILURE; editStatus = KEY_GENERATION_FAILURE;

2
src/script.cpp

@ -1374,7 +1374,7 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash
return false; return false;
else else
{ {
valtype vch; CPubKey vch;
keystore.GetPubKey(address, vch); keystore.GetPubKey(address, vch);
scriptSigRet << vch; scriptSigRet << vch;
} }

6
src/script.h

@ -320,6 +320,12 @@ public:
return *this; return *this;
} }
CScript& operator<<(const CPubKey& key)
{
std::vector<unsigned char> vchKey = key.Raw();
return (*this) << vchKey;
}
CScript& operator<<(const CBigNum& b) CScript& operator<<(const CBigNum& b)
{ {
*this << b.getvch(); *this << b.getvch();

14
src/test/multisig_tests.cpp

@ -201,7 +201,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
vector<valtype> solutions; vector<valtype> solutions;
txnouttype whichType; txnouttype whichType;
CScript s; CScript s;
s << OP_DUP << OP_HASH160 << Hash160(key[0].GetPubKey()) << OP_EQUALVERIFY << OP_CHECKSIG; s << OP_DUP << OP_HASH160 << Hash160(key[0].GetPubKey().Raw()) << OP_EQUALVERIFY << OP_CHECKSIG;
BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK(solutions.size() == 1); BOOST_CHECK(solutions.size() == 1);
CBitcoinAddress addr; CBitcoinAddress addr;
@ -214,7 +214,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
vector<valtype> solutions; vector<valtype> solutions;
txnouttype whichType; txnouttype whichType;
CScript s; CScript s;
s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey().Raw() << OP_2 << OP_CHECKMULTISIG;
BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK_EQUAL(solutions.size(), 4); BOOST_CHECK_EQUAL(solutions.size(), 4);
CBitcoinAddress addr; CBitcoinAddress addr;
@ -227,7 +227,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
vector<valtype> solutions; vector<valtype> solutions;
txnouttype whichType; txnouttype whichType;
CScript s; CScript s;
s << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; s << OP_1 << key[0].GetPubKey().Raw() << key[1].GetPubKey().Raw() << OP_2 << OP_CHECKMULTISIG;
BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK_EQUAL(solutions.size(), 4); BOOST_CHECK_EQUAL(solutions.size(), 4);
vector<CBitcoinAddress> addrs; vector<CBitcoinAddress> addrs;
@ -244,7 +244,7 @@ BOOST_AUTO_TEST_CASE(multisig_Solver1)
vector<valtype> solutions; vector<valtype> solutions;
txnouttype whichType; txnouttype whichType;
CScript s; CScript s;
s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG; s << OP_2 << key[0].GetPubKey().Raw() << key[1].GetPubKey().Raw() << key[2].GetPubKey().Raw() << OP_3 << OP_CHECKMULTISIG;
BOOST_CHECK(Solver(s, whichType, solutions)); BOOST_CHECK(Solver(s, whichType, solutions));
BOOST_CHECK(solutions.size() == 5); BOOST_CHECK(solutions.size() == 5);
} }
@ -262,13 +262,13 @@ BOOST_AUTO_TEST_CASE(multisig_Sign)
} }
CScript a_and_b; CScript a_and_b;
a_and_b << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; a_and_b << OP_2 << key[0].GetPubKey().Raw() << key[1].GetPubKey().Raw() << OP_2 << OP_CHECKMULTISIG;
CScript a_or_b; CScript a_or_b;
a_or_b << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG; a_or_b << OP_1 << key[0].GetPubKey().Raw() << key[1].GetPubKey().Raw() << OP_2 << OP_CHECKMULTISIG;
CScript escrow; CScript escrow;
escrow << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG; escrow << OP_2 << key[0].GetPubKey().Raw() << key[1].GetPubKey().Raw() << key[2].GetPubKey().Raw() << OP_3 << OP_CHECKMULTISIG;
CTransaction txFrom; // Funding transaction CTransaction txFrom; // Funding transaction
txFrom.vout.resize(3); txFrom.vout.resize(3);

32
src/wallet.cpp

@ -16,7 +16,7 @@ using namespace std;
// mapWallet // mapWallet
// //
std::vector<unsigned char> CWallet::GenerateNewKey() CPubKey CWallet::GenerateNewKey()
{ {
bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
@ -44,7 +44,7 @@ bool CWallet::AddKey(const CKey& key)
return true; return true;
} }
bool CWallet::AddCryptedKey(const vector<unsigned char> &vchPubKey, const vector<unsigned char> &vchCryptedSecret) bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector<unsigned char> &vchCryptedSecret)
{ {
if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret)) if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
return false; return false;
@ -366,7 +366,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
{ {
if (txout.scriptPubKey == scriptDefaultKey) if (txout.scriptPubKey == scriptDefaultKey)
{ {
std::vector<unsigned char> newDefaultKey; CPubKey newDefaultKey;
if (GetKeyFromPool(newDefaultKey, false)) if (GetKeyFromPool(newDefaultKey, false))
{ {
SetDefaultKey(newDefaultKey); SetDefaultKey(newDefaultKey);
@ -1095,7 +1095,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64> >& vecSend, CW
// post-backup change. // post-backup change.
// Reserve a new key pair from key pool // Reserve a new key pair from key pool
vector<unsigned char> vchPubKey = reservekey.GetReservedKey(); CPubKey vchPubKey = reservekey.GetReservedKey();
// assert(mapKeys.count(vchPubKey)); // assert(mapKeys.count(vchPubKey));
// Fill a vout to ourself // Fill a vout to ourself
@ -1278,7 +1278,7 @@ int CWallet::LoadWallet(bool& fFirstRunRet)
if (nLoadWalletRet != DB_LOAD_OK) if (nLoadWalletRet != DB_LOAD_OK)
return nLoadWalletRet; return nLoadWalletRet;
fFirstRunRet = vchDefaultKey.empty(); fFirstRunRet = !vchDefaultKey.IsValid();
CreateThread(ThreadFlushWalletDB, &strWalletFile); CreateThread(ThreadFlushWalletDB, &strWalletFile);
return DB_LOAD_OK; return DB_LOAD_OK;
@ -1332,7 +1332,7 @@ bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
return false; return false;
} }
bool CWallet::SetDefaultKey(const std::vector<unsigned char> &vchPubKey) bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
{ {
if (fFileBacked) if (fFileBacked)
{ {
@ -1408,7 +1408,7 @@ bool CWallet::TopUpKeyPool()
void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool) void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
{ {
nIndex = -1; nIndex = -1;
keypool.vchPubKey.clear(); keypool.vchPubKey = CPubKey();
{ {
LOCK(cs_wallet); LOCK(cs_wallet);
@ -1425,9 +1425,9 @@ void CWallet::ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool)
setKeyPool.erase(setKeyPool.begin()); setKeyPool.erase(setKeyPool.begin());
if (!walletdb.ReadPool(nIndex, keypool)) if (!walletdb.ReadPool(nIndex, keypool))
throw runtime_error("ReserveKeyFromKeyPool() : read failed"); throw runtime_error("ReserveKeyFromKeyPool() : read failed");
if (!HaveKey(Hash160(keypool.vchPubKey))) if (!HaveKey(keypool.vchPubKey.GetID()))
throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool"); throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
assert(!keypool.vchPubKey.empty()); assert(keypool.vchPubKey.IsValid());
printf("keypool reserve %"PRI64d"\n", nIndex); printf("keypool reserve %"PRI64d"\n", nIndex);
} }
} }
@ -1468,7 +1468,7 @@ void CWallet::ReturnKey(int64 nIndex)
printf("keypool return %"PRI64d"\n", nIndex); printf("keypool return %"PRI64d"\n", nIndex);
} }
bool CWallet::GetKeyFromPool(vector<unsigned char>& result, bool fAllowReuse) bool CWallet::GetKeyFromPool(CPubKey& result, bool fAllowReuse)
{ {
int64 nIndex = 0; int64 nIndex = 0;
CKeyPool keypool; CKeyPool keypool;
@ -1477,7 +1477,7 @@ bool CWallet::GetKeyFromPool(vector<unsigned char>& result, bool fAllowReuse)
ReserveKeyFromKeyPool(nIndex, keypool); ReserveKeyFromKeyPool(nIndex, keypool);
if (nIndex == -1) if (nIndex == -1)
{ {
if (fAllowReuse && !vchDefaultKey.empty()) if (fAllowReuse && vchDefaultKey.IsValid())
{ {
result = vchDefaultKey; result = vchDefaultKey;
return true; return true;
@ -1503,7 +1503,7 @@ int64 CWallet::GetOldestKeyPoolTime()
return keypool.nTime; return keypool.nTime;
} }
vector<unsigned char> CReserveKey::GetReservedKey() CPubKey CReserveKey::GetReservedKey()
{ {
if (nIndex == -1) if (nIndex == -1)
{ {
@ -1517,7 +1517,7 @@ vector<unsigned char> CReserveKey::GetReservedKey()
vchPubKey = pwallet->vchDefaultKey; vchPubKey = pwallet->vchDefaultKey;
} }
} }
assert(!vchPubKey.empty()); assert(vchPubKey.IsValid());
return vchPubKey; return vchPubKey;
} }
@ -1526,7 +1526,7 @@ void CReserveKey::KeepKey()
if (nIndex != -1) if (nIndex != -1)
pwallet->KeepKey(nIndex); pwallet->KeepKey(nIndex);
nIndex = -1; nIndex = -1;
vchPubKey.clear(); vchPubKey = CPubKey();
} }
void CReserveKey::ReturnKey() void CReserveKey::ReturnKey()
@ -1534,7 +1534,7 @@ void CReserveKey::ReturnKey()
if (nIndex != -1) if (nIndex != -1)
pwallet->ReturnKey(nIndex); pwallet->ReturnKey(nIndex);
nIndex = -1; nIndex = -1;
vchPubKey.clear(); vchPubKey = CPubKey();
} }
void CWallet::GetAllReserveAddresses(set<CBitcoinAddress>& setAddress) void CWallet::GetAllReserveAddresses(set<CBitcoinAddress>& setAddress)
@ -1550,7 +1550,7 @@ void CWallet::GetAllReserveAddresses(set<CBitcoinAddress>& setAddress)
if (!walletdb.ReadPool(id, keypool)) if (!walletdb.ReadPool(id, keypool))
throw runtime_error("GetAllReserveKeyHashes() : read failed"); throw runtime_error("GetAllReserveKeyHashes() : read failed");
CBitcoinAddress address(keypool.vchPubKey); CBitcoinAddress address(keypool.vchPubKey);
assert(!keypool.vchPubKey.empty()); assert(keypool.vchPubKey.IsValid());
if (!HaveKey(address)) if (!HaveKey(address))
throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool"); throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool");
setAddress.insert(address); setAddress.insert(address);

24
src/wallet.h

@ -32,14 +32,14 @@ class CKeyPool
{ {
public: public:
int64 nTime; int64 nTime;
std::vector<unsigned char> vchPubKey; CPubKey vchPubKey;
CKeyPool() CKeyPool()
{ {
nTime = GetTime(); nTime = GetTime();
} }
CKeyPool(const std::vector<unsigned char>& vchPubKeyIn) CKeyPool(const CPubKey& vchPubKeyIn)
{ {
nTime = GetTime(); nTime = GetTime();
vchPubKey = vchPubKeyIn; vchPubKey = vchPubKeyIn;
@ -107,14 +107,14 @@ public:
std::map<CBitcoinAddress, std::string> mapAddressBook; std::map<CBitcoinAddress, std::string> mapAddressBook;
std::vector<unsigned char> vchDefaultKey; CPubKey vchDefaultKey;
// check whether we are allowed to upgrade (or already support) to the named feature // check whether we are allowed to upgrade (or already support) to the named feature
bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; } bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; }
// keystore implementation // keystore implementation
// Generate a new key // Generate a new key
std::vector<unsigned char> GenerateNewKey(); CPubKey GenerateNewKey();
// Adds a key to the store, and saves it to disk. // Adds a key to the store, and saves it to disk.
bool AddKey(const CKey& key); bool AddKey(const CKey& key);
// Adds a key to the store, without saving it to disk (used by LoadWallet) // Adds a key to the store, without saving it to disk (used by LoadWallet)
@ -123,9 +123,9 @@ public:
bool LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; } bool LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
// Adds an encrypted key to the store, and saves it to disk. // Adds an encrypted key to the store, and saves it to disk.
bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret); bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
// Adds an encrypted key to the store, without saving it to disk (used by LoadWallet) // Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
bool LoadCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { SetMinVersion(FEATURE_WALLETCRYPT); return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); } bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { SetMinVersion(FEATURE_WALLETCRYPT); return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); }
bool AddCScript(const CScript& redeemScript); bool AddCScript(const CScript& redeemScript);
bool LoadCScript(const CScript& redeemScript) { return CCryptoKeyStore::AddCScript(redeemScript); } bool LoadCScript(const CScript& redeemScript) { return CCryptoKeyStore::AddCScript(redeemScript); }
@ -156,7 +156,7 @@ public:
void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool); void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
void KeepKey(int64 nIndex); void KeepKey(int64 nIndex);
void ReturnKey(int64 nIndex); void ReturnKey(int64 nIndex);
bool GetKeyFromPool(std::vector<unsigned char> &key, bool fAllowReuse=true); bool GetKeyFromPool(CPubKey &key, bool fAllowReuse=true);
int64 GetOldestKeyPoolTime(); int64 GetOldestKeyPoolTime();
void GetAllReserveAddresses(std::set<CBitcoinAddress>& setAddress); void GetAllReserveAddresses(std::set<CBitcoinAddress>& setAddress);
@ -252,7 +252,7 @@ public:
bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx); bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx);
bool SetDefaultKey(const std::vector<unsigned char> &vchPubKey); bool SetDefaultKey(const CPubKey &vchPubKey);
// signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower // signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false); bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false);
@ -280,7 +280,7 @@ class CReserveKey
protected: protected:
CWallet* pwallet; CWallet* pwallet;
int64 nIndex; int64 nIndex;
std::vector<unsigned char> vchPubKey; CPubKey vchPubKey;
public: public:
CReserveKey(CWallet* pwalletIn) CReserveKey(CWallet* pwalletIn)
{ {
@ -295,7 +295,7 @@ public:
} }
void ReturnKey(); void ReturnKey();
std::vector<unsigned char> GetReservedKey(); CPubKey GetReservedKey();
void KeepKey(); void KeepKey();
}; };
@ -640,7 +640,7 @@ public:
class CAccount class CAccount
{ {
public: public:
std::vector<unsigned char> vchPubKey; CPubKey vchPubKey;
CAccount() CAccount()
{ {
@ -649,7 +649,7 @@ public:
void SetNull() void SetNull()
{ {
vchPubKey.clear(); vchPubKey = CPubKey();
} }
IMPLEMENT_SERIALIZE IMPLEMENT_SERIALIZE

2
src/walletdb.cpp

@ -104,7 +104,7 @@ void CWalletDB::ListAccountCreditDebit(const string& strAccount, list<CAccountin
int CWalletDB::LoadWallet(CWallet* pwallet) int CWalletDB::LoadWallet(CWallet* pwallet)
{ {
pwallet->vchDefaultKey.clear(); pwallet->vchDefaultKey = CPubKey();
int nFileVersion = 0; int nFileVersion = 0;
vector<uint256> vWalletUpgrade; vector<uint256> vWalletUpgrade;
bool fIsEncrypted = false; bool fIsEncrypted = false;

20
src/walletdb.h

@ -59,27 +59,27 @@ public:
return Erase(std::make_pair(std::string("tx"), hash)); return Erase(std::make_pair(std::string("tx"), hash));
} }
bool ReadKey(const std::vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey) bool ReadKey(const CPubKey& vchPubKey, CPrivKey& vchPrivKey)
{ {
vchPrivKey.clear(); vchPrivKey.clear();
return Read(std::make_pair(std::string("key"), vchPubKey), vchPrivKey); return Read(std::make_pair(std::string("key"), vchPubKey.Raw()), vchPrivKey);
} }
bool WriteKey(const std::vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey) bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey)
{ {
nWalletDBUpdated++; nWalletDBUpdated++;
return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false); return Write(std::make_pair(std::string("key"), vchPubKey.Raw()), vchPrivKey, false);
} }
bool WriteCryptedKey(const std::vector<unsigned char>& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, bool fEraseUnencryptedKey = true) bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, bool fEraseUnencryptedKey = true)
{ {
nWalletDBUpdated++; nWalletDBUpdated++;
if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false)) if (!Write(std::make_pair(std::string("ckey"), vchPubKey.Raw()), vchCryptedSecret, false))
return false; return false;
if (fEraseUnencryptedKey) if (fEraseUnencryptedKey)
{ {
Erase(std::make_pair(std::string("key"), vchPubKey)); Erase(std::make_pair(std::string("key"), vchPubKey.Raw()));
Erase(std::make_pair(std::string("wkey"), vchPubKey)); Erase(std::make_pair(std::string("wkey"), vchPubKey.Raw()));
} }
return true; return true;
} }
@ -120,10 +120,10 @@ public:
return Read(std::string("defaultkey"), vchPubKey); return Read(std::string("defaultkey"), vchPubKey);
} }
bool WriteDefaultKey(const std::vector<unsigned char>& vchPubKey) bool WriteDefaultKey(const CPubKey& vchPubKey)
{ {
nWalletDBUpdated++; nWalletDBUpdated++;
return Write(std::string("defaultkey"), vchPubKey); return Write(std::string("defaultkey"), vchPubKey.Raw());
} }
bool ReadPool(int64 nPool, CKeyPool& keypool) bool ReadPool(int64 nPool, CKeyPool& keypool)

Loading…
Cancel
Save