diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2012-05-14 23:44:52 +0200 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2012-05-24 20:26:19 +0200 |
commit | 1025440184ef100a22d07c7bb543ee45cf169d64 (patch) | |
tree | cd85ae7d981820189e506167e518adaf820aa638 /src/base58.h | |
parent | fd61d6f5068cf92d34569862b4225f177049a4f0 (diff) |
Refactor: split CKeyID/CScriptID/CTxDestination from CBitcoinAddress
This introduces internal types:
* CKeyID: reference (hash160) of a key
* CScriptID: reference (hash160) of a script
* CTxDestination: a boost::variant of the former two
CBitcoinAddress is retrofitted to be a Base58 encoding of a
CTxDestination. This allows all internal code to only use the
internal types, and only have RPC and GUI depend on the base58 code.
Furthermore, the header dependencies are a lot saner now. base58.h is
at the top (right below rpc and gui) instead of at the bottom. For the
rest: wallet -> script -> keystore -> key. Only keystore still requires
a forward declaration of CScript. Solving that would require splitting
script into two layers.
Diffstat (limited to 'src/base58.h')
-rw-r--r-- | src/base58.h | 101 |
1 files changed, 71 insertions, 30 deletions
diff --git a/src/base58.h b/src/base58.h index 26d8c5f9ed..b492cd683c 100644 --- a/src/base58.h +++ b/src/base58.h @@ -19,6 +19,7 @@ #include <vector> #include "bignum.h" #include "key.h" +#include "script.h" static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; @@ -258,6 +259,18 @@ public: * Script-hash-addresses have version 5 (or 196 testnet). * The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script. */ +class CBitcoinAddress; +class CBitcoinAddressVisitor : public boost::static_visitor<bool> +{ +private: + CBitcoinAddress *addr; +public: + CBitcoinAddressVisitor(CBitcoinAddress *addrIn) : addr(addrIn) { } + bool operator()(const CKeyID &id) const; + bool operator()(const CScriptID &id) const; + bool operator()(const CNoDestination &no) const; +}; + class CBitcoinAddress : public CBase58Data { public: @@ -269,21 +282,19 @@ public: SCRIPT_ADDRESS_TEST = 196, }; - bool SetHash160(const uint160& hash160) - { - SetData(fTestNet ? PUBKEY_ADDRESS_TEST : PUBKEY_ADDRESS, &hash160, 20); + bool Set(const CKeyID &id) { + SetData(fTestNet ? PUBKEY_ADDRESS_TEST : PUBKEY_ADDRESS, &id, 20); return true; } - void SetPubKey(const CPubKey& vchPubKey) - { - SetHash160(vchPubKey.GetID()); + bool Set(const CScriptID &id) { + SetData(fTestNet ? SCRIPT_ADDRESS_TEST : SCRIPT_ADDRESS, &id, 20); + return true; } - bool SetScriptHash160(const uint160& hash160) + bool Set(const CTxDestination &dest) { - SetData(fTestNet ? SCRIPT_ADDRESS_TEST : SCRIPT_ADDRESS, &hash160, 20); - return true; + return boost::apply_visitor(CBitcoinAddressVisitor(this), dest); } bool IsValid() const @@ -315,27 +326,14 @@ public: } return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize; } - bool IsScript() const - { - if (!IsValid()) - return false; - if (fTestNet) - return nVersion == SCRIPT_ADDRESS_TEST; - return nVersion == SCRIPT_ADDRESS; - } CBitcoinAddress() { } - CBitcoinAddress(uint160 hash160In) - { - SetHash160(hash160In); - } - - CBitcoinAddress(const CPubKey& vchPubKey) + CBitcoinAddress(const CTxDestination &dest) { - SetPubKey(vchPubKey); + Set(dest); } CBitcoinAddress(const std::string& strAddress) @@ -348,15 +346,58 @@ public: SetString(pszAddress); } - uint160 GetHash160() const - { - assert(vchData.size() == 20); - uint160 hash160; - memcpy(&hash160, &vchData[0], 20); - return hash160; + CTxDestination Get() const { + if (!IsValid()) + return CNoDestination(); + switch (nVersion) { + case PUBKEY_ADDRESS: + case PUBKEY_ADDRESS_TEST: { + uint160 id; + memcpy(&id, &vchData[0], 20); + return CKeyID(id); + } + case SCRIPT_ADDRESS: + case SCRIPT_ADDRESS_TEST: { + uint160 id; + memcpy(&id, &vchData[0], 20); + return CScriptID(id); + } + } + return CNoDestination(); + } + + bool GetKeyID(CKeyID &keyID) const { + if (!IsValid()) + return false; + switch (nVersion) { + case PUBKEY_ADDRESS: + case PUBKEY_ADDRESS_TEST: { + uint160 id; + memcpy(&id, &vchData[0], 20); + keyID = CKeyID(id); + return true; + } + default: return false; + } + } + + bool IsScript() const { + if (!IsValid()) + return false; + switch (nVersion) { + case SCRIPT_ADDRESS: + case SCRIPT_ADDRESS_TEST: { + return true; + } + default: return false; + } } }; +bool inline CBitcoinAddressVisitor::operator()(const CKeyID &id) const { return addr->Set(id); } +bool inline CBitcoinAddressVisitor::operator()(const CScriptID &id) const { return addr->Set(id); } +bool inline CBitcoinAddressVisitor::operator()(const CNoDestination &id) const { return false; } + /** A base58-encoded secret key */ class CBitcoinSecret : public CBase58Data { |