diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2016-04-18 15:12:46 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2016-04-18 15:14:36 +0200 |
commit | a25a4f5b04c3e045557e9e7e807b2af74ad75128 (patch) | |
tree | 5a5726a68759ab6ed0ed9e7b189dd622c6ff9b23 /src/script/ismine.cpp | |
parent | f4eae2d910d9edb3750efec4facbeab161cce593 (diff) |
wallet_ismine.h → script/ismine.h
Removes conditional dependency of `src/test` on wallet.
Makes multisig and P2SH tests complete without wallet built-in.
Diffstat (limited to 'src/script/ismine.cpp')
-rw-r--r-- | src/script/ismine.cpp | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/script/ismine.cpp b/src/script/ismine.cpp new file mode 100644 index 0000000000..535c56b57a --- /dev/null +++ b/src/script/ismine.cpp @@ -0,0 +1,95 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2015 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "ismine.h" + +#include "key.h" +#include "keystore.h" +#include "script/script.h" +#include "script/standard.h" +#include "script/sign.h" + +#include <boost/foreach.hpp> + +using namespace std; + +typedef vector<unsigned char> valtype; + +unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore) +{ + unsigned int nResult = 0; + BOOST_FOREACH(const valtype& pubkey, pubkeys) + { + CKeyID keyID = CPubKey(pubkey).GetID(); + if (keystore.HaveKey(keyID)) + ++nResult; + } + return nResult; +} + +isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest) +{ + CScript script = GetScriptForDestination(dest); + return IsMine(keystore, script); +} + +isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) +{ + vector<valtype> vSolutions; + txnouttype whichType; + if (!Solver(scriptPubKey, whichType, vSolutions)) { + if (keystore.HaveWatchOnly(scriptPubKey)) + return ISMINE_WATCH_UNSOLVABLE; + return ISMINE_NO; + } + + CKeyID keyID; + switch (whichType) + { + case TX_NONSTANDARD: + case TX_NULL_DATA: + break; + case TX_PUBKEY: + keyID = CPubKey(vSolutions[0]).GetID(); + if (keystore.HaveKey(keyID)) + return ISMINE_SPENDABLE; + break; + case TX_PUBKEYHASH: + keyID = CKeyID(uint160(vSolutions[0])); + if (keystore.HaveKey(keyID)) + return ISMINE_SPENDABLE; + break; + case TX_SCRIPTHASH: + { + CScriptID scriptID = CScriptID(uint160(vSolutions[0])); + CScript subscript; + if (keystore.GetCScript(scriptID, subscript)) { + isminetype ret = IsMine(keystore, subscript); + if (ret == ISMINE_SPENDABLE) + return ret; + } + break; + } + case TX_MULTISIG: + { + // Only consider transactions "mine" if we own ALL the + // keys involved. Multi-signature transactions that are + // partially owned (somebody else has a key that can spend + // them) enable spend-out-from-under-you attacks, especially + // in shared-wallet situations. + vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1); + if (HaveKeys(keys, keystore) == keys.size()) + return ISMINE_SPENDABLE; + break; + } + } + + if (keystore.HaveWatchOnly(scriptPubKey)) { + // TODO: This could be optimized some by doing some work after the above solver + CScript scriptSig; + return ProduceSignature(DummySignatureCreator(&keystore), scriptPubKey, scriptSig) ? ISMINE_WATCH_SOLVABLE : ISMINE_WATCH_UNSOLVABLE; + } + return ISMINE_NO; +} |