aboutsummaryrefslogtreecommitdiff
path: root/src/script/ismine.cpp
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2016-04-18 15:12:46 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2016-04-18 15:14:36 +0200
commita25a4f5b04c3e045557e9e7e807b2af74ad75128 (patch)
tree5a5726a68759ab6ed0ed9e7b189dd622c6ff9b23 /src/script/ismine.cpp
parentf4eae2d910d9edb3750efec4facbeab161cce593 (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.cpp95
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;
+}