Skip to content

Commit

Permalink
Use CBitcoinAddress instead of string/uint160
Browse files Browse the repository at this point in the history
Instead of conversion functions between pubkey/uint160/address in
base58.h, have a fully fledged class CBitcoinAddress (CAddress was
already taken) to represent addresses.
  • Loading branch information
sipa committed Jul 17, 2011
1 parent 03fbd79 commit 2ffba73
Show file tree
Hide file tree
Showing 10 changed files with 278 additions and 250 deletions.
145 changes: 107 additions & 38 deletions src/base58.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,52 +159,121 @@ inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>



#define ADDRESSVERSION ((unsigned char)(fTestNet ? 111 : 0))

inline std::string Hash160ToAddress(uint160 hash160)
class CBitcoinAddress
{
// add 1-byte version number to the front
std::vector<unsigned char> vch(1, ADDRESSVERSION);
vch.insert(vch.end(), UBEGIN(hash160), UEND(hash160));
return EncodeBase58Check(vch);
}
protected:
unsigned char nVersion;
std::vector<unsigned char> vchData;

inline bool AddressToHash160(const char* psz, uint160& hash160Ret)
{
std::vector<unsigned char> vch;
if (!DecodeBase58Check(psz, vch))
return false;
if (vch.empty())
return false;
unsigned char nVersion = vch[0];
if (vch.size() != sizeof(hash160Ret) + 1)
return false;
memcpy(&hash160Ret, &vch[1], sizeof(hash160Ret));
return (nVersion <= ADDRESSVERSION);
}
public:
bool SetAddress(const uint160& hash160)
{
nVersion = fTestNet ? 111 : 0;
vchData.resize(20);
memcpy(&vchData[0], &hash160, 20);
return true;
}

inline bool AddressToHash160(const std::string& str, uint160& hash160Ret)
{
return AddressToHash160(str.c_str(), hash160Ret);
}
bool SetAddress(const char* pszAddress)
{
std::vector<unsigned char> vchTemp;
DecodeBase58Check(pszAddress, vchTemp);
if (vchTemp.empty())
{
vchData.clear();
nVersion = 0;
return false;
}
nVersion = vchTemp[0];
vchData.resize(vchTemp.size() - 1);
memcpy(&vchData[0], &vchTemp[1], vchData.size());
return true;
}

inline bool IsValidBitcoinAddress(const char* psz)
{
uint160 hash160;
return AddressToHash160(psz, hash160);
}
bool SetAddress(const std::string& strAddress)
{
return SetAddress(strAddress.c_str());
}

inline bool IsValidBitcoinAddress(const std::string& str)
{
return IsValidBitcoinAddress(str.c_str());
}
bool SetAddress(const std::vector<unsigned char>& vchPubKey)
{
return SetAddress(Hash160(vchPubKey));
}

bool IsValid() const
{
int nExpectedSize = 20;
bool fExpectTestNet = false;
switch(nVersion)
{
case 0:
break;

case 111:
fExpectTestNet = true;
break;

default:
return false;
}
return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize;
}

CBitcoinAddress()
{
nVersion = 0;
vchData.clear();
}

CBitcoinAddress(uint160 hash160In)
{
SetAddress(hash160In);
}

CBitcoinAddress(const std::vector<unsigned char>& vchPubKey)
{
SetAddress(vchPubKey);
}

inline std::string PubKeyToAddress(const std::vector<unsigned char>& vchPubKey)
{
return Hash160ToAddress(Hash160(vchPubKey));
}
CBitcoinAddress(const std::string& strAddress)
{
SetAddress(strAddress);
}

CBitcoinAddress(const char* pszAddress)
{
SetAddress(pszAddress);
}

std::string ToString() const
{
std::vector<unsigned char> vch(1, nVersion);
vch.insert(vch.end(), vchData.begin(), vchData.end());
return EncodeBase58Check(vch);
}

uint160 GetHash160() const
{
assert(vchData.size() == 20);
uint160 hash160;
memcpy(&hash160, &vchData[0], 20);
return hash160;
}

int CompareTo(const CBitcoinAddress& address) const
{
if (nVersion < address.nVersion) return -1;
if (nVersion < address.nVersion) return 1;
if (vchData < address.vchData) return -1;
if (vchData > address.vchData) return 1;
return 0;
}

bool operator==(const CBitcoinAddress& address) const { return CompareTo(address) == 0; }
bool operator<=(const CBitcoinAddress& address) const { return CompareTo(address) <= 0; }
bool operator>=(const CBitcoinAddress& address) const { return CompareTo(address) >= 0; }
bool operator< (const CBitcoinAddress& address) const { return CompareTo(address) < 0; }
bool operator> (const CBitcoinAddress& address) const { return CompareTo(address) > 0; }
};

#endif
5 changes: 5 additions & 0 deletions src/key.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ class CKey
return false;
return true;
}

CBitcoinAddress GetAddress() const
{
return CBitcoinAddress(GetPubKey());
}
};

#endif
20 changes: 10 additions & 10 deletions src/keystore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ std::vector<unsigned char> CKeyStore::GenerateNewKey()
return key.GetPubKey();
}

bool CKeyStore::GetPubKey(const uint160 &hashAddress, std::vector<unsigned char> &vchPubKeyOut) const
bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char> &vchPubKeyOut) const
{
CKey key;
if (!GetKey(hashAddress, key))
if (!GetKey(address, key))
return false;
vchPubKeyOut = key.GetPubKey();
return true;
Expand All @@ -28,7 +28,7 @@ bool CKeyStore::GetPubKey(const uint160 &hashAddress, std::vector<unsigned char>
bool CBasicKeyStore::AddKey(const CKey& key)
{
CRITICAL_BLOCK(cs_KeyStore)
mapKeys[Hash160(key.GetPubKey())] = key.GetSecret();
mapKeys[key.GetAddress()] = key.GetSecret();
return true;
}

Expand Down Expand Up @@ -98,19 +98,19 @@ bool CCryptoKeyStore::AddCryptedKey(const std::vector<unsigned char> &vchPubKey,
if (!SetCrypted())
return false;

mapCryptedKeys[Hash160(vchPubKey)] = make_pair(vchPubKey, vchCryptedSecret);
mapCryptedKeys[CBitcoinAddress(vchPubKey)] = make_pair(vchPubKey, vchCryptedSecret);
}
return true;
}

bool CCryptoKeyStore::GetKey(const uint160 &hashAddress, CKey& keyOut) const
bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
{
CRITICAL_BLOCK(cs_vMasterKey)
{
if (!IsCrypted())
return CBasicKeyStore::GetKey(hashAddress, keyOut);
return CBasicKeyStore::GetKey(address, keyOut);

CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(hashAddress);
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
if (mi != mapCryptedKeys.end())
{
const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
Expand All @@ -125,14 +125,14 @@ bool CCryptoKeyStore::GetKey(const uint160 &hashAddress, CKey& keyOut) const
return false;
}

bool CCryptoKeyStore::GetPubKey(const uint160 &hashAddress, std::vector<unsigned char>& vchPubKeyOut) const
bool CCryptoKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const
{
CRITICAL_BLOCK(cs_vMasterKey)
{
if (!IsCrypted())
return CKeyStore::GetPubKey(hashAddress, vchPubKeyOut);
return CKeyStore::GetPubKey(address, vchPubKeyOut);

CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(hashAddress);
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
if (mi != mapCryptedKeys.end())
{
vchPubKeyOut = (*mi).second.first;
Expand Down
28 changes: 14 additions & 14 deletions src/keystore.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ class CKeyStore
mutable CCriticalSection cs_KeyStore;

virtual bool AddKey(const CKey& key) =0;
virtual bool HaveKey(const uint160 &hashAddress) const =0;
virtual bool GetKey(const uint160 &hashAddress, CKey& keyOut) const =0;
virtual bool GetPubKey(const uint160 &hashAddress, std::vector<unsigned char>& vchPubKeyOut) const;
virtual bool HaveKey(const CBitcoinAddress &address) const =0;
virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0;
virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
virtual std::vector<unsigned char> GenerateNewKey();
};

typedef std::map<uint160, CSecret> KeyMap;
typedef std::map<CBitcoinAddress, CSecret> KeyMap;

class CBasicKeyStore : public CKeyStore
{
Expand All @@ -27,13 +27,13 @@ class CBasicKeyStore : public CKeyStore

public:
bool AddKey(const CKey& key);
bool HaveKey(const uint160 &hashAddress) const
bool HaveKey(const CBitcoinAddress &address) const
{
return (mapKeys.count(hashAddress) > 0);
return (mapKeys.count(address) > 0);
}
bool GetKey(const uint160 &hashAddress, CKey& keyOut) const
bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const
{
KeyMap::const_iterator mi = mapKeys.find(hashAddress);
KeyMap::const_iterator mi = mapKeys.find(address);
if (mi != mapKeys.end())
{
keyOut.SetSecret((*mi).second);
Expand All @@ -43,7 +43,7 @@ class CBasicKeyStore : public CKeyStore
}
};

typedef std::map<uint160, std::pair<std::vector<unsigned char>, std::vector<unsigned char> > > CryptedKeyMap;
typedef std::map<CBitcoinAddress, std::pair<std::vector<unsigned char>, std::vector<unsigned char> > > CryptedKeyMap;

class CCryptoKeyStore : public CBasicKeyStore
{
Expand Down Expand Up @@ -106,14 +106,14 @@ class CCryptoKeyStore : public CBasicKeyStore
virtual bool AddCryptedKey(const std::vector<unsigned char> &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
std::vector<unsigned char> GenerateNewKey();
bool AddKey(const CKey& key);
bool HaveKey(const uint160 &hashAddress) const
bool HaveKey(const CBitcoinAddress &address) const
{
if (!IsCrypted())
return CBasicKeyStore::HaveKey(hashAddress);
return mapCryptedKeys.count(hashAddress) > 0;
return CBasicKeyStore::HaveKey(address);
return mapCryptedKeys.count(address) > 0;
}
bool GetKey(const uint160 &hashAddress, CKey& keyOut) const;
bool GetPubKey(const uint160 &hashAddress, std::vector<unsigned char>& vchPubKeyOut) const;
bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const;
bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
};

#endif
Loading

0 comments on commit 2ffba73

Please sign in to comment.