1919#include < vector>
2020#include " bignum.h"
2121#include " key.h"
22+ #include " script.h"
2223
2324static const char * pszBase58 = " 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" ;
2425
@@ -258,6 +259,18 @@ class CBase58Data
258259 * Script-hash-addresses have version 5 (or 196 testnet).
259260 * The data vector contains RIPEMD160(SHA256(cscript)), where cscript is the serialized redemption script.
260261 */
262+ class CBitcoinAddress ;
263+ class CBitcoinAddressVisitor : public boost ::static_visitor<bool >
264+ {
265+ private:
266+ CBitcoinAddress *addr;
267+ public:
268+ CBitcoinAddressVisitor (CBitcoinAddress *addrIn) : addr(addrIn) { }
269+ bool operator ()(const CKeyID &id) const ;
270+ bool operator ()(const CScriptID &id) const ;
271+ bool operator ()(const CNoDestination &no) const ;
272+ };
273+
261274class CBitcoinAddress : public CBase58Data
262275{
263276public:
@@ -269,21 +282,19 @@ class CBitcoinAddress : public CBase58Data
269282 SCRIPT_ADDRESS_TEST = 196 ,
270283 };
271284
272- bool SetHash160 (const uint160& hash160)
273- {
274- SetData (fTestNet ? PUBKEY_ADDRESS_TEST : PUBKEY_ADDRESS, &hash160, 20 );
285+ bool Set (const CKeyID &id) {
286+ SetData (fTestNet ? PUBKEY_ADDRESS_TEST : PUBKEY_ADDRESS, &id, 20 );
275287 return true ;
276288 }
277289
278- void SetPubKey (const CPubKey& vchPubKey)
279- {
280- SetHash160 (vchPubKey. GetID ()) ;
290+ bool Set (const CScriptID &id) {
291+ SetData ( fTestNet ? SCRIPT_ADDRESS_TEST : SCRIPT_ADDRESS, &id, 20 );
292+ return true ;
281293 }
282294
283- bool SetScriptHash160 (const uint160& hash160 )
295+ bool Set (const CTxDestination &dest )
284296 {
285- SetData (fTestNet ? SCRIPT_ADDRESS_TEST : SCRIPT_ADDRESS, &hash160, 20 );
286- return true ;
297+ return boost::apply_visitor (CBitcoinAddressVisitor (this ), dest);
287298 }
288299
289300 bool IsValid () const
@@ -315,27 +326,14 @@ class CBitcoinAddress : public CBase58Data
315326 }
316327 return fExpectTestNet == fTestNet && vchData.size () == nExpectedSize;
317328 }
318- bool IsScript () const
319- {
320- if (!IsValid ())
321- return false ;
322- if (fTestNet )
323- return nVersion == SCRIPT_ADDRESS_TEST;
324- return nVersion == SCRIPT_ADDRESS;
325- }
326329
327330 CBitcoinAddress ()
328331 {
329332 }
330333
331- CBitcoinAddress (uint160 hash160In)
332- {
333- SetHash160 (hash160In);
334- }
335-
336- CBitcoinAddress (const CPubKey& vchPubKey)
334+ CBitcoinAddress (const CTxDestination &dest)
337335 {
338- SetPubKey (vchPubKey );
336+ Set (dest );
339337 }
340338
341339 CBitcoinAddress (const std::string& strAddress)
@@ -348,15 +346,58 @@ class CBitcoinAddress : public CBase58Data
348346 SetString (pszAddress);
349347 }
350348
351- uint160 GetHash160 () const
352- {
353- assert (vchData.size () == 20 );
354- uint160 hash160;
355- memcpy (&hash160, &vchData[0 ], 20 );
356- return hash160;
349+ CTxDestination Get () const {
350+ if (!IsValid ())
351+ return CNoDestination ();
352+ switch (nVersion) {
353+ case PUBKEY_ADDRESS:
354+ case PUBKEY_ADDRESS_TEST: {
355+ uint160 id;
356+ memcpy (&id, &vchData[0 ], 20 );
357+ return CKeyID (id);
358+ }
359+ case SCRIPT_ADDRESS:
360+ case SCRIPT_ADDRESS_TEST: {
361+ uint160 id;
362+ memcpy (&id, &vchData[0 ], 20 );
363+ return CScriptID (id);
364+ }
365+ }
366+ return CNoDestination ();
367+ }
368+
369+ bool GetKeyID (CKeyID &keyID) const {
370+ if (!IsValid ())
371+ return false ;
372+ switch (nVersion) {
373+ case PUBKEY_ADDRESS:
374+ case PUBKEY_ADDRESS_TEST: {
375+ uint160 id;
376+ memcpy (&id, &vchData[0 ], 20 );
377+ keyID = CKeyID (id);
378+ return true ;
379+ }
380+ default : return false ;
381+ }
382+ }
383+
384+ bool IsScript () const {
385+ if (!IsValid ())
386+ return false ;
387+ switch (nVersion) {
388+ case SCRIPT_ADDRESS:
389+ case SCRIPT_ADDRESS_TEST: {
390+ return true ;
391+ }
392+ default : return false ;
393+ }
357394 }
358395};
359396
397+ bool inline CBitcoinAddressVisitor::operator ()(const CKeyID &id) const { return addr->Set (id); }
398+ bool inline CBitcoinAddressVisitor::operator ()(const CScriptID &id) const { return addr->Set (id); }
399+ bool inline CBitcoinAddressVisitor::operator ()(const CNoDestination &id) const { return false ; }
400+
360401/* * A base58-encoded secret key */
361402class CBitcoinSecret : public CBase58Data
362403{
0 commit comments