PIVX Core  5.6.99
P2P Digital Currency
ismine.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Copyright (c) 2016-2021 The PIVX Core developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include "ismine.h"
8 
9 #include "keystore.h"
10 #include "script/script.h"
11 #include "script/sign.h"
12 #include "util/system.h"
13 
14 
15 
16 typedef std::vector<unsigned char> valtype;
17 
18 unsigned int HaveKeys(const std::vector<valtype>& pubkeys, const CKeyStore& keystore)
19 {
20  unsigned int nResult = 0;
21  for (const valtype& pubkey : pubkeys) {
22  CKeyID keyID = CPubKey(pubkey).GetID();
23  if(keystore.HaveKey(keyID))
24  ++nResult;
25  }
26  return nResult;
27 }
28 
29 isminetype IsMine(const CKeyStore& keystore, const CTxDestination& dest)
30 {
31  CScript script = GetScriptForDestination(dest);
32  return IsMine(keystore, script);
33 }
34 
36 {
39  if (keystore.GetSaplingIncomingViewingKey(pa, ivk) &&
40  keystore.GetSaplingFullViewingKey(ivk, exfvk) &&
41  keystore.HaveSaplingSpendingKey(exfvk)) {
43  } else if (!ivk.IsNull()) {
45  } else {
46  return ISMINE_NO;
47  }
48 }
49 
50 namespace
51 {
52  class CWDestinationVisitor : public boost::static_visitor<isminetype>
53  {
54  private:
55  const CKeyStore& keystore;
56  public:
57  explicit CWDestinationVisitor(const CKeyStore& _keystore) : keystore(_keystore) {}
58 
59  isminetype operator()(const CTxDestination& dest) const {
60  return ::IsMine(keystore, dest);
61  }
62 
63  isminetype operator()(const libzcash::SaplingPaymentAddress& pa) const {
64  return ::IsMine(keystore, pa);
65  }
66  };
67 }
68 
69 isminetype IsMine(const CKeyStore& keystore, const CWDestination& dest)
70 {
71  return boost::apply_visitor(CWDestinationVisitor(keystore), dest);
72 }
73 
74 isminetype IsMine(const CKeyStore& keystore, const CScript& scriptPubKey)
75 {
76  std::vector<valtype> vSolutions;
77  txnouttype whichType;
78  if(!Solver(scriptPubKey, whichType, vSolutions)) {
79  if(keystore.HaveWatchOnly(scriptPubKey)) {
80  return ISMINE_WATCH_ONLY;
81  }
82 
83  return ISMINE_NO;
84  }
85 
86  CKeyID keyID;
87  switch (whichType) {
88  case TX_NONSTANDARD:
89  case TX_NULL_DATA:
90  break;
91  case TX_PUBKEY:
92  keyID = CPubKey(vSolutions[0]).GetID();
93  if(keystore.HaveKey(keyID))
94  return ISMINE_SPENDABLE;
95  break;
96  case TX_PUBKEYHASH:
97  case TX_EXCHANGEADDR:
98  keyID = CKeyID(uint160(vSolutions[0]));
99  if(keystore.HaveKey(keyID))
100  return ISMINE_SPENDABLE;
101  break;
102  case TX_SCRIPTHASH: {
103  CScriptID scriptID = CScriptID(uint160(vSolutions[0]));
104  CScript subscript;
105  if(keystore.GetCScript(scriptID, subscript)) {
106  isminetype ret = IsMine(keystore, subscript);
107  if(ret != ISMINE_NO)
108  return ret;
109  }
110  break;
111  }
112  case TX_COLDSTAKE: {
113  CKeyID stakeKeyID = CKeyID(uint160(vSolutions[0]));
114  bool stakeKeyIsMine = keystore.HaveKey(stakeKeyID);
115  CKeyID ownerKeyID = CKeyID(uint160(vSolutions[1]));
116  bool spendKeyIsMine = keystore.HaveKey(ownerKeyID);
117 
118  if (spendKeyIsMine) {
119  // If the wallet has both keys, ISMINE_SPENDABLE_DELEGATED
120  // takes precedence over ISMINE_COLD
122  } else if (stakeKeyIsMine) {
123  return ISMINE_COLD;
124  } else {
125  // todo: Include watch only..
126  }
127  break;
128  }
129  case TX_MULTISIG: {
130  // Only consider transactions "mine" if we own ALL the
131  // keys involved. multi-signature transactions that are
132  // partially owned (somebody else has a key that can spend
133  // them) enable spend-out-from-under-you attacks, especially
134  // in shared-wallet situations.
135  std::vector<valtype> keys(vSolutions.begin() + 1, vSolutions.begin() + vSolutions.size() - 1);
136  if(HaveKeys(keys, keystore) == keys.size())
137  return ISMINE_SPENDABLE;
138  break;
139  }
140  }
141 
142  if (keystore.HaveWatchOnly(scriptPubKey)) {
143  return ISMINE_WATCH_ONLY;
144  }
145 
146  return ISMINE_NO;
147 }
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:21
A virtual base class for key stores.
Definition: keystore.h:23
virtual bool HaveWatchOnly(const CScript &dest) const =0
virtual bool GetSaplingIncomingViewingKey(const libzcash::SaplingPaymentAddress &addr, libzcash::SaplingIncomingViewingKey &ivkOut) const =0
virtual bool HaveSaplingSpendingKey(const libzcash::SaplingExtendedFullViewingKey &extfvk) const =0
virtual bool HaveKey(const CKeyID &address) const =0
Check whether a key corresponding to a given address is present in the store.
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const =0
virtual bool GetSaplingFullViewingKey(const libzcash::SaplingIncomingViewingKey &ivk, libzcash::SaplingExtendedFullViewingKey &extfvkOut) const =0
An encapsulated public key.
Definition: pubkey.h:44
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:167
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:381
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:24
bool IsNull() const
Definition: uint256.h:36
Sapling functions.
Definition: address.h:30
160-bit opaque blob.
Definition: uint256.h:127
boost::variant< CTxDestination, libzcash::SaplingPaymentAddress > CWDestination
std::vector< unsigned char > valtype
Definition: interpreter.cpp:17
std::vector< unsigned char > valtype
Definition: ismine.cpp:16
unsigned int HaveKeys(const std::vector< valtype > &pubkeys, const CKeyStore &keystore)
Definition: ismine.cpp:18
isminetype IsMine(const CKeyStore &keystore, const CTxDestination &dest)
Definition: ismine.cpp:29
isminetype
IsMine() return codes.
Definition: ismine.h:19
@ ISMINE_COLD
Indicates that we have the staking key of a P2CS.
Definition: ismine.h:24
@ ISMINE_SPENDABLE_SHIELDED
Indicates that we have the spending key of a shielded spend/output.
Definition: ismine.h:30
@ ISMINE_WATCH_ONLY_SHIELDED
Indicates that we don't have the spending key of a shielded spend/output.
Definition: ismine.h:28
@ ISMINE_SPENDABLE
Definition: ismine.h:22
@ ISMINE_NO
Definition: ismine.h:20
@ ISMINE_WATCH_ONLY
Definition: ismine.h:21
@ ISMINE_SPENDABLE_DELEGATED
Indicates that we have the spending key of a P2CS.
Definition: ismine.h:26
bool Solver(const CScript &scriptPubKey, txnouttype &typeRet, std::vector< std::vector< unsigned char > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition: standard.cpp:90
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a PIVX scriptPubKey for the given CTxDestination.
Definition: standard.cpp:278
boost::variant< CNoDestination, CKeyID, CScriptID, CExchangeKeyID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:72
txnouttype
Definition: standard.h:46
@ TX_PUBKEYHASH
Definition: standard.h:50
@ TX_PUBKEY
Definition: standard.h:49
@ TX_NULL_DATA
Definition: standard.h:53
@ TX_COLDSTAKE
Definition: standard.h:54
@ TX_SCRIPTHASH
Definition: standard.h:51
@ TX_NONSTANDARD
Definition: standard.h:47
@ TX_MULTISIG
Definition: standard.h:52
@ TX_EXCHANGEADDR
Definition: standard.h:55