Merge pull request #361 from svost/master
[novacoin.git] / src / base58.cpp
index 1842853..1c26380 100644 (file)
@@ -183,6 +183,11 @@ bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRe
         if (!vchData.empty())
             memcpy(&vchData[0], pdata, nSize);
     }
+    
+    const std::vector<unsigned char> &CBase58Data::GetData() const
+    {
+        return vchData;
+    }
 
     void CBase58Data::SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend)
     {
@@ -243,12 +248,31 @@ bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRe
         return boost::apply_visitor(CBitcoinAddressVisitor(this), dest);
     }
 
+    bool CBitcoinAddress::Set(const CMalleablePubKey &mpk) {
+        std::vector<unsigned char> vchPubkeyPair = mpk.Raw();
+        SetData(fTestNet ? PUBKEY_PAIR_ADDRESS_TEST : PUBKEY_PAIR_ADDRESS, &vchPubkeyPair[0], 68);
+        return true;
+    }
+
+    bool CBitcoinAddress::Set(const CBitcoinAddress &dest)
+    {
+        nVersion = dest.nVersion;
+        vchData = dest.vchData;
+        return true;
+    }
+
     bool CBitcoinAddress::IsValid() const
     {
         unsigned int nExpectedSize = 20;
         bool fExpectTestNet = false;
+        bool fSimple = true;
         switch(nVersion)
         {
+            case PUBKEY_PAIR_ADDRESS:
+                nExpectedSize = 68; // Serialized pair of public keys
+                fExpectTestNet = false;
+                fSimple = false;
+                break;
             case PUBKEY_ADDRESS:
                 nExpectedSize = 20; // Hash of public key
                 fExpectTestNet = false;
@@ -258,6 +282,11 @@ bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRe
                 fExpectTestNet = false;
                 break;
 
+            case PUBKEY_PAIR_ADDRESS_TEST:
+                nExpectedSize = 68;
+                fExpectTestNet = true;
+                fSimple = false;
+                break;
             case PUBKEY_ADDRESS_TEST:
                 nExpectedSize = 20;
                 fExpectTestNet = true;
@@ -270,7 +299,20 @@ bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRe
             default:
                 return false;
         }
-        return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize;
+
+        // Basic format sanity check
+        bool fSeemsSane = (fExpectTestNet == fTestNet && vchData.size() == nExpectedSize);
+
+        if (fSeemsSane && !fSimple)
+        {
+            // Perform dditional checking
+            //    for pubkey pair addresses
+            CMalleablePubKey mpk;
+            mpk.setvch(vchData);
+            return mpk.IsValid();
+        }
+        else
+            return fSeemsSane;
     }
 
     CTxDestination CBitcoinAddress::Get() const {
@@ -304,6 +346,13 @@ bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRe
             keyID = CKeyID(id);
             return true;
         }
+        case PUBKEY_PAIR_ADDRESS:
+        case PUBKEY_PAIR_ADDRESS_TEST:
+        {
+            CMalleablePubKey mPubKey;
+            mPubKey.setvch(vchData);
+            keyID = mPubKey.GetID();
+        }
         default: return false;
         }
     }
@@ -320,6 +369,30 @@ bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRe
         }
     }
 
+    bool CBitcoinAddress::IsPubKey() const {
+        if (!IsValid())
+            return false;
+        switch (nVersion) {
+        case PUBKEY_ADDRESS:
+        case PUBKEY_ADDRESS_TEST: {
+            return true;
+        }
+        default: return false;
+        }
+    }
+    
+    bool CBitcoinAddress::IsPair() const {
+        if (!IsValid())
+            return false;
+        switch (nVersion) {
+        case PUBKEY_PAIR_ADDRESS:
+        case PUBKEY_PAIR_ADDRESS_TEST: {
+            return true;
+        }
+        default: return false;
+        }
+    }
+
     void CBitcoinSecret::SetSecret(const CSecret& vchSecret, bool fCompressed)
     {
         assert(vchSecret.size() == 32);