X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fscript.cpp;h=0909c8fa4584d51a1b2ae09209996a10e769a2b1;hb=06c7b792fed77e00e06abba85c84bd589311f315;hp=2212fe1f58bd7846cad4730c04e8971dc82ef21c;hpb=f3119076fb8c5dc4f1acd65b2f6681a6a61af92c;p=novacoin.git diff --git a/src/script.cpp b/src/script.cpp index 2212fe1..0909c8f 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -2,11 +2,6 @@ // Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include -#include - -using namespace std; -using namespace boost; #include "script.h" #include "keystore.h" @@ -16,7 +11,7 @@ using namespace boost; #include "sync.h" #include "util.h" -bool CheckSig(vector vchSig, const vector &vchPubKey, const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, int flags); +bool CheckSig(std::vector vchSig, const std::vector &vchPubKey, const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, int flags); static const valtype vchFalse(0); static const valtype vchZero(0); @@ -31,7 +26,7 @@ static const size_t nMaxNumSize = 4; CBigNum CastToBigNum(const valtype& vch) { if (vch.size() > nMaxNumSize) - throw runtime_error("CastToBigNum() : overflow"); + throw std::runtime_error("CastToBigNum() : overflow"); // Get rid of extra leading zeros return CBigNum(CBigNum(vch).getvch()); } @@ -85,10 +80,10 @@ void MakeSameSize(valtype& vch1, valtype& vch2) // #define stacktop(i) (stack.at(stack.size()+(i))) #define altstacktop(i) (altstack.at(altstack.size()+(i))) -static inline void popstack(vector& stack) +static inline void popstack(std::vector& stack) { if (stack.empty()) - throw runtime_error("popstack() : stack empty"); + throw std::runtime_error("popstack() : stack empty"); stack.pop_back(); } @@ -415,7 +410,7 @@ bool CheckSequence(const int64_t& nSequence, const CTransaction &txTo, unsigned return true; } -bool EvalScript(vector >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType) +bool EvalScript(std::vector >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType) { CAutoBN_CTX pctx; CScript::const_iterator pc = script.begin(); @@ -423,8 +418,8 @@ bool EvalScript(vector >& stack, const CScript& script, co CScript::const_iterator pbegincodehash = script.begin(); opcodetype opcode; valtype vchPushValue; - vector vfExec; - vector altstack; + std::vector vfExec; + std::vector altstack; if (script.size() > 10000) return false; int nOpCount = 0; @@ -1231,7 +1226,7 @@ class CSignatureCache { private: // sigdata_type is (signature hash, signature, public key): - typedef boost::tuple, CPubKey > sigdata_type; + typedef std::tuple, CPubKey > sigdata_type; std::set< sigdata_type> setValid; boost::shared_mutex cs_sigcache; @@ -1279,15 +1274,12 @@ public: } }; -bool CheckSig(vector vchSig, const vector &vchPubKey, const CScript &scriptCode, +bool CheckSig(std::vector vchSig, const std::vector &vchPubKey, const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType, int flags) { static CSignatureCache signatureCache; - CKey key; - if (!key.SetPubKey(vchPubKey)) - return false; - CPubKey pubkey = key.GetPubKey(); + CPubKey pubkey(vchPubKey); if (!pubkey.IsValid()) return false; @@ -1305,7 +1297,7 @@ bool CheckSig(vector vchSig, const vector &vchPubK if (signatureCache.Get(sighash, vchSig, pubkey)) return true; - if (!key.Verify(sighash, vchSig)) + if (!pubkey.Verify(sighash, vchSig)) return false; if (!(flags & SCRIPT_VERIFY_NOCACHE)) @@ -1315,29 +1307,20 @@ bool CheckSig(vector vchSig, const vector &vchPubK } - - - - - - // // Return public keys or hashes from scriptPubKey, for 'standard' transaction types. // -bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector >& vSolutionsRet) +bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector >& vSolutionsRet) { // Templates - static map mTemplates; + static std::map mTemplates; if (mTemplates.empty()) { // Standard tx, sender provides pubkey, receiver adds signature mTemplates.insert(make_pair(TX_PUBKEY, CScript() << OP_PUBKEY << OP_CHECKSIG)); - if (fTestNet || GetTime() > SMALLDATA_SWITCH_TIME) - { - // Malleable pubkey tx hack, sender provides generated pubkey combined with R parameter. The R parameter is dropped before checking a signature. - mTemplates.insert(make_pair(TX_PUBKEY_DROP, CScript() << OP_PUBKEY << OP_PUBKEY << OP_DROP << OP_CHECKSIG)); - } + // Malleable pubkey tx hack, sender provides generated pubkey combined with R parameter. The R parameter is dropped before checking a signature. + mTemplates.insert(make_pair(TX_PUBKEY_DROP, CScript() << OP_PUBKEY << OP_PUBKEY << OP_DROP << OP_CHECKSIG)); // Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey mTemplates.insert(make_pair(TX_PUBKEYHASH, CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG)); @@ -1356,7 +1339,7 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22); + std::vector hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22); vSolutionsRet.push_back(hashBytes); return true; } @@ -1373,18 +1356,18 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector vch1, vch2; + std::vector vch1, vch2; // Compare CScript::const_iterator pc1 = script1.begin(); CScript::const_iterator pc2 = script2.begin(); - while (true) + for ( ; ; ) { if (pc1 == script1.end() && pc2 == script2.end()) { @@ -1460,7 +1443,7 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector (GetTime() > SMALLDATA_SWITCH_TIME ? 1024 : 80)) + if (vch1.size() > 1024) break; } else if (opcode1 != opcode2 || vch1 != vch2) @@ -1483,7 +1466,7 @@ bool Sign1(const CKeyID& address, const CKeyStore& keystore, const uint256& hash if (!keystore.GetKey(address, key)) return false; - vector vchSig; + std::vector vchSig; if (!key.Sign(hash, vchSig)) return false; vchSig.push_back((unsigned char)nHashType); @@ -1498,7 +1481,7 @@ bool SignR(const CPubKey& pubKey, const CPubKey& R, const CKeyStore& keystore, c if (!keystore.CreatePrivKey(pubKey, R, key)) return false; - vector vchSig; + std::vector vchSig; if (!key.Sign(hash, vchSig)) return false; vchSig.push_back((unsigned char)nHashType); @@ -1507,7 +1490,7 @@ bool SignR(const CPubKey& pubKey, const CPubKey& R, const CKeyStore& keystore, c return true; } -bool SignN(const vector& multisigdata, const CKeyStore& keystore, const uint256& hash, int nHashType, CScript& scriptSigRet) +bool SignN(const std::vector& multisigdata, const CKeyStore& keystore, const uint256& hash, int nHashType, CScript& scriptSigRet) { int nSigned = 0; int nRequired = multisigdata.front()[0]; @@ -1532,7 +1515,7 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, const uint25 { scriptSigRet.clear(); - vector vSolutions; + std::vector vSolutions; if (!Solver(scriptPubKey, whichTypeRet, vSolutions)) return false; @@ -1597,7 +1580,7 @@ int ScriptSigArgsExpected(txnouttype t, const std::vector vSolutions; + std::vector vSolutions; if (!Solver(scriptPubKey, whichType, vSolutions)) return false; @@ -1616,10 +1599,10 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) } -unsigned int HaveKeys(const vector& pubkeys, const CKeyStore& keystore) +unsigned int HaveKeys(const std::vector& pubkeys, const CKeyStore& keystore) { unsigned int nResult = 0; - BOOST_FOREACH(const valtype& pubkey, pubkeys) + for (const valtype& pubkey : pubkeys) { CKeyID keyID = CPubKey(pubkey).GetID(); if (keystore.HaveKey(keyID)) @@ -1640,12 +1623,13 @@ public: bool operator()(const CScriptID &scriptID) const { return keystore->HaveCScript(scriptID); } }; +/* isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest) { CScript script; script.SetDestination(dest); return IsMine(keystore, script); -} +}*/ isminetype IsMine(const CKeyStore &keystore, const CBitcoinAddress& dest) { @@ -1656,7 +1640,7 @@ isminetype IsMine(const CKeyStore &keystore, const CBitcoinAddress& dest) isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) { - vector vSolutions; + std::vector vSolutions; txnouttype whichType; if (!Solver(scriptPubKey, whichType, vSolutions)) { if (keystore.HaveWatchOnly(scriptPubKey)) @@ -1706,7 +1690,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) // partially owned (somebody else has a key that can spend // them) enable spend-out-from-under-you attacks, especially // in shared-wallet situations. - vector keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1); + std::vector keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1); if (HaveKeys(keys, keystore) == keys.size()) return MINE_SPENDABLE; break; @@ -1720,7 +1704,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) { - vector vSolutions; + std::vector vSolutions; txnouttype whichType; if (!Solver(scriptPubKey, whichType, vSolutions)) return false; @@ -1744,6 +1728,42 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) return false; } +bool ExtractAddress(const CKeyStore &keystore, const CScript& scriptPubKey, CBitcoinAddress& addressRet) +{ + std::vector vSolutions; + txnouttype whichType; + if (!Solver(scriptPubKey, whichType, vSolutions)) + return false; + + if (whichType == TX_PUBKEY) + { + addressRet = CBitcoinAddress(CPubKey(vSolutions[0]).GetID()); + return true; + } + if (whichType == TX_PUBKEY_DROP) + { + // Pay-to-Pubkey-R + CMalleableKeyView view; + if (!keystore.CheckOwnership(CPubKey(vSolutions[0]), CPubKey(vSolutions[1]), view)) + return false; + + addressRet = CBitcoinAddress(view.GetMalleablePubKey()); + return true; + } + else if (whichType == TX_PUBKEYHASH) + { + addressRet = CBitcoinAddress(CKeyID(uint160(vSolutions[0]))); + return true; + } + else if (whichType == TX_SCRIPTHASH) + { + addressRet = CBitcoinAddress(CScriptID(uint160(vSolutions[0]))); + return true; + } + // Multisig txns have more than one address... + return false; +} + class CAffectedKeysVisitor : public boost::static_visitor { private: const CKeyStore &keystore; @@ -1758,7 +1778,7 @@ public: std::vector vDest; int nRequired; if (ExtractDestinations(script, type, vDest, nRequired)) { - BOOST_FOREACH(const CTxDestination &dest, vDest) + for (const CTxDestination &dest : vDest) boost::apply_visitor(*this, dest); } } @@ -1782,11 +1802,11 @@ void ExtractAffectedKeys(const CKeyStore &keystore, const CScript& scriptPubKey, CAffectedKeysVisitor(keystore, vKeys).Process(scriptPubKey); } -bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vector& addressRet, int& nRequiredRet) +bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector& addressRet, int& nRequiredRet) { addressRet.clear(); typeRet = TX_NONSTANDARD; - vector vSolutions; + std::vector vSolutions; if (!Solver(scriptPubKey, typeRet, vSolutions)) return false; if (typeRet == TX_NULL_DATA) @@ -1821,7 +1841,7 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vecto bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType) { - vector > stack, stackCopy; + std::vector > stack, stackCopy; if (!EvalScript(stack, scriptSig, txTo, nIn, flags, nHashType)) return false; if (flags & SCRIPT_VERIFY_P2SH) @@ -1905,26 +1925,26 @@ bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CTrans return SignSignature(keystore, txout.scriptPubKey, txTo, nIn, nHashType); } -static CScript PushAll(const vector& values) +static CScript PushAll(const std::vector& values) { CScript result; - BOOST_FOREACH(const valtype& v, values) + for (const valtype& v : values) result << v; return result; } static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, - const vector& vSolutions, - vector& sigs1, vector& sigs2) + const std::vector& vSolutions, + std::vector& sigs1, std::vector& sigs2) { // Combine all the signatures we've got: - set allsigs; - BOOST_FOREACH(const valtype& v, sigs1) + std::set allsigs; + for (const valtype& v : sigs1) { if (!v.empty()) allsigs.insert(v); } - BOOST_FOREACH(const valtype& v, sigs2) + for (const valtype& v : sigs2) { if (!v.empty()) allsigs.insert(v); @@ -1934,8 +1954,8 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction& assert(vSolutions.size() > 1); unsigned int nSigsRequired = vSolutions.front()[0]; unsigned int nPubKeys = (unsigned int)(vSolutions.size()-2); - map sigs; - BOOST_FOREACH(const valtype& sig, allsigs) + std::map sigs; + for (const valtype& sig : allsigs) { for (unsigned int i = 0; i < nPubKeys; i++) { @@ -1969,8 +1989,8 @@ static CScript CombineMultisig(const CScript& scriptPubKey, const CTransaction& } static CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, - const txnouttype txType, const vector& vSolutions, - vector& sigs1, vector& sigs2) + const txnouttype txType, const std::vector& vSolutions, + std::vector& sigs1, std::vector& sigs2) { switch (txType) { @@ -1999,7 +2019,7 @@ static CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction CScript pubKey2(spk.begin(), spk.end()); txnouttype txType2; - vector > vSolutions2; + std::vector > vSolutions2; Solver(pubKey2, txType2, vSolutions2); sigs1.pop_back(); sigs2.pop_back(); @@ -2018,12 +2038,12 @@ CScript CombineSignatures(const CScript& scriptPubKey, const CTransaction& txTo, const CScript& scriptSig1, const CScript& scriptSig2) { txnouttype txType; - vector > vSolutions; + std::vector > vSolutions; Solver(scriptPubKey, txType, vSolutions); - vector stack1; + std::vector stack1; EvalScript(stack1, scriptSig1, CTransaction(), 0, SCRIPT_VERIFY_STRICTENC, 0); - vector stack2; + std::vector stack2; EvalScript(stack2, scriptSig2, CTransaction(), 0, SCRIPT_VERIFY_STRICTENC, 0); return CombineSignatures(scriptPubKey, txTo, nIn, txType, vSolutions, stack1, stack2); @@ -2162,12 +2182,12 @@ void CScript::SetAddress(const CBitcoinAddress& dest) } } -void CScript::SetMultisig(int nRequired, const std::vector& keys) +void CScript::SetMultisig(int nRequired, const std::vector& keys) { this->clear(); *this << EncodeOP_N(nRequired); - BOOST_FOREACH(const CKey& key, keys) - *this << key.GetPubKey(); + for (const CPubKey& key : keys) + *this << key; *this << EncodeOP_N((int)(keys.size())) << OP_CHECKMULTISIG; }