]> Git Repo - VerusCoin.git/blob - src/wallet/wallet_ismine.cpp
Merge pull request #97 from miketout/dev
[VerusCoin.git] / src / wallet / wallet_ismine.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or https://www.opensource.org/licenses/mit-license.php .
5
6 #include "wallet_ismine.h"
7
8 #include "key.h"
9 #include "keystore.h"
10 #include "script/script.h"
11 #include "script/standard.h"
12 #include "cc/eval.h"
13 #include "pbaas/identity.h"
14 #include "cc/CCinclude.h"
15
16 #include <boost/foreach.hpp>
17
18 using namespace std;
19
20 typedef vector<unsigned char> valtype;
21
22 unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore)
23 {
24     unsigned int nResult = 0;
25     BOOST_FOREACH(const valtype& pubkey, pubkeys)
26     {
27         CKeyID keyID = CPubKey(pubkey).GetID();
28         if (keystore.HaveKey(keyID))
29             ++nResult;
30     }
31     return nResult;
32 }
33
34 isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest)
35 {
36     CScript script = GetScriptForDestination(dest);
37     return IsMine(keystore, script);
38 }
39
40 isminetype IsMine(const CKeyStore &keystore, const CScript& _scriptPubKey, uint32_t height)
41 {
42     vector<valtype> vSolutions;
43     txnouttype whichType;
44     CScript scriptPubKey = _scriptPubKey;
45
46     if (scriptPubKey.IsCheckLockTimeVerify())
47     {
48         uint8_t pushOp = scriptPubKey[0];
49         uint32_t scriptStart = pushOp + 3;
50
51         // continue with post CLTV script
52         scriptPubKey = CScript(scriptPubKey.size() > scriptStart ? scriptPubKey.begin() + scriptStart : scriptPubKey.end(), scriptPubKey.end());
53     }
54
55     COptCCParams p;
56     if (scriptPubKey.IsPayToCryptoCondition(p) && p.IsValid())
57     {
58         std::vector<CTxDestination> dests;
59         int minSigs;
60         bool canSign = false;
61         bool canSpend = false;
62
63         if (ExtractDestinations(scriptPubKey, whichType, dests, minSigs, &keystore, &canSign, &canSpend, height))
64         {
65             if (canSpend)
66             {
67                 return ISMINE_SPENDABLE;
68             }
69             else if (canSign)
70             {
71                 return ISMINE_WATCH_ONLY;
72             }
73             else
74             {
75                 return ISMINE_NO;
76             }
77         }
78         else
79         {
80             return ISMINE_NO;
81         }
82     }
83     else if (!Solver(scriptPubKey, whichType, vSolutions))
84     {
85         if (keystore.HaveWatchOnly(scriptPubKey))
86             return ISMINE_WATCH_ONLY;
87         return ISMINE_NO;
88     }
89
90     CKeyID keyID;
91     switch (whichType)
92     {
93     case TX_NONSTANDARD:
94     case TX_NULL_DATA:
95         break;
96     case TX_CRYPTOCONDITION:
97         {
98             // for now, default is that the first value returned will be the target address, subsequent values will be
99             // pubkeys. if we have the first in our wallet, we consider it spendable for now
100             if (vSolutions[0].size() == 33)
101             {
102                 keyID = CPubKey(vSolutions[0]).GetID();
103             }
104             else if (vSolutions[0].size() == 20)
105             {
106                 keyID = CKeyID(uint160(vSolutions[0]));
107             }
108             if (!keyID.IsNull() && keystore.HaveKey(keyID))
109             {
110                 return ISMINE_SPENDABLE;
111             }
112         }
113         break;
114     case TX_PUBKEY:
115         keyID = CPubKey(vSolutions[0]).GetID();
116         if (keystore.HaveKey(keyID))
117             return ISMINE_SPENDABLE;
118         break;
119     case TX_PUBKEYHASH:
120         keyID = CKeyID(uint160(vSolutions[0]));
121         if (keystore.HaveKey(keyID))
122             return ISMINE_SPENDABLE;
123         break;
124     case TX_SCRIPTHASH:
125     {
126         CScriptID scriptID = CScriptID(uint160(vSolutions[0]));
127         CScript subscript;
128         if (keystore.GetCScript(scriptID, subscript)) {
129             isminetype ret = IsMine(keystore, subscript);
130             if (ret == ISMINE_SPENDABLE)
131                 return ret;
132         }
133         break;
134     }
135     case TX_MULTISIG:
136     {
137         // Only consider transactions "mine" if we own ALL the
138         // keys involved. Multi-signature transactions that are
139         // partially owned (somebody else has a key that can spend
140         // them) enable spend-out-from-under-you attacks, especially
141         // in shared-wallet situations.
142         vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
143         if (HaveKeys(keys, keystore) == keys.size())
144             return ISMINE_SPENDABLE;
145         break;
146     }
147     }
148
149     if (keystore.HaveWatchOnly(scriptPubKey))
150         return ISMINE_WATCH_ONLY;
151     return ISMINE_NO;
152 }
This page took 0.031823 seconds and 4 git commands to generate.