split off CBase58Data from CBitcoinAddress
[novacoin.git] / src / script.cpp
index bd1b5b3..652240f 100644 (file)
@@ -580,6 +580,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
                     case OP_ABS:        if (bn < bnZero) bn = -bn; break;
                     case OP_NOT:        bn = (bn == bnZero); break;
                     case OP_0NOTEQUAL:  bn = (bn != bnZero); break;
+                    default:            assert(!"invalid opcode"); break;
                     }
                     popstack(stack);
                     stack.push_back(bn.getvch());
@@ -659,6 +660,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
                     case OP_GREATERTHANOREQUAL:  bn = (bn1 >= bn2); break;
                     case OP_MIN:                 bn = (bn1 < bn2 ? bn1 : bn2); break;
                     case OP_MAX:                 bn = (bn1 > bn2 ? bn1 : bn2); break;
+                    default:                     assert(!"invalid opcode"); break;
                     }
                     popstack(stack);
                     popstack(stack);
@@ -1030,7 +1032,7 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash
         return false;
 
     // Compile solution
-    CRITICAL_BLOCK(keystore.cs_mapKeys)
+    CRITICAL_BLOCK(keystore.cs_KeyStore)
     {
         BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
         {
@@ -1038,13 +1040,15 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash
             {
                 // Sign
                 const valtype& vchPubKey = item.second;
-                CPrivKey privkey;
-                if (!keystore.GetPrivKey(vchPubKey, privkey))
+                CKey key;
+                if (!keystore.GetKey(Hash160(vchPubKey), key))
+                    return false;
+                if (key.GetPubKey() != vchPubKey)
                     return false;
                 if (hash != 0)
                 {
                     vector<unsigned char> vchSig;
-                    if (!CKey::Sign(privkey, hash, vchSig))
+                    if (!key.Sign(hash, vchSig))
                         return false;
                     vchSig.push_back((unsigned char)nHashType);
                     scriptSigRet << vchSig;
@@ -1053,20 +1057,16 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, uint256 hash
             else if (item.first == OP_PUBKEYHASH)
             {
                 // Sign and give pubkey
-                map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second));
-                if (mi == mapPubKeys.end())
-                    return false;
-                const vector<unsigned char>& vchPubKey = (*mi).second;
-                CPrivKey privkey;
-                if (!keystore.GetPrivKey(vchPubKey, privkey))
+                CKey key;
+                if (!keystore.GetKey(uint160(item.second), key))
                     return false;
                 if (hash != 0)
                 {
                     vector<unsigned char> vchSig;
-                    if (!CKey::Sign(privkey, hash, vchSig))
+                    if (!key.Sign(hash, vchSig))
                         return false;
                     vchSig.push_back((unsigned char)nHashType);
-                    scriptSigRet << vchSig << vchPubKey;
+                    scriptSigRet << vchSig << key.GetPubKey();
                 }
             }
             else
@@ -1089,60 +1089,57 @@ bool IsStandard(const CScript& scriptPubKey)
 
 bool IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
 {
-    CScript scriptSig;
-    return Solver(keystore, scriptPubKey, 0, 0, scriptSig);
-}
-
-
-bool ExtractPubKey(const CScript& scriptPubKey, const CKeyStore* keystore, vector<unsigned char>& vchPubKeyRet)
-{
-    vchPubKeyRet.clear();
-
     vector<pair<opcodetype, valtype> > vSolution;
     if (!Solver(scriptPubKey, vSolution))
         return false;
 
-    CRITICAL_BLOCK(cs_mapPubKeys)
+    // Compile solution
+    CRITICAL_BLOCK(keystore.cs_KeyStore)
     {
         BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
         {
-            valtype vchPubKey;
             if (item.first == OP_PUBKEY)
             {
-                vchPubKey = item.second;
+                const valtype& vchPubKey = item.second;
+                vector<unsigned char> vchPubKeyFound;
+                if (!keystore.GetPubKey(Hash160(vchPubKey), vchPubKeyFound))
+                    return false;
+                if (vchPubKeyFound != vchPubKey)
+                    return false;
             }
             else if (item.first == OP_PUBKEYHASH)
             {
-                map<uint160, valtype>::iterator mi = mapPubKeys.find(uint160(item.second));
-                if (mi == mapPubKeys.end())
-                    continue;
-                vchPubKey = (*mi).second;
+                if (!keystore.HaveKey(uint160(item.second)))
+                    return false;
             }
-            if (keystore == NULL || keystore->HaveKey(vchPubKey))
+            else
             {
-                vchPubKeyRet = vchPubKey;
-                return true;
+                return false;
             }
         }
     }
-    return false;
+
+    return true;
 }
 
 
-bool ExtractHash160(const CScript& scriptPubKey, uint160& hash160Ret)
+bool ExtractAddress(const CScript& scriptPubKey, const CKeyStore* keystore, CBitcoinAddress& addressRet)
 {
-    hash160Ret = 0;
-
     vector<pair<opcodetype, valtype> > vSolution;
     if (!Solver(scriptPubKey, vSolution))
         return false;
 
-    BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
+    CRITICAL_BLOCK(keystore->cs_KeyStore)
     {
-        if (item.first == OP_PUBKEYHASH)
+        BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution)
         {
-            hash160Ret = uint160(item.second);
-            return true;
+            uint160 hash160;
+            if (item.first == OP_PUBKEY)
+                addressRet.SetPubKey(item.second);
+            else if (item.first == OP_PUBKEYHASH)
+                addressRet.SetHash160((uint160)item.second);
+            if (keystore == NULL || keystore->HaveKey(addressRet))
+                return true;
         }
     }
     return false;