You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

wallet_ismine.cpp 2.6KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Copyright (c) 2009-2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2014 The Bitcoin developers
  3. // Distributed under the MIT software license, see the accompanying
  4. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5. #include "wallet_ismine.h"
  6. #include "key.h"
  7. #include "keystore.h"
  8. #include "script/script.h"
  9. #include "script/standard.h"
  10. #include <boost/foreach.hpp>
  11. using namespace std;
  12. typedef vector<unsigned char> valtype;
  13. unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore)
  14. {
  15. unsigned int nResult = 0;
  16. BOOST_FOREACH(const valtype& pubkey, pubkeys)
  17. {
  18. CKeyID keyID = CPubKey(pubkey).GetID();
  19. if (keystore.HaveKey(keyID))
  20. ++nResult;
  21. }
  22. return nResult;
  23. }
  24. isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest)
  25. {
  26. CScript script = GetScriptForDestination(dest);
  27. return IsMine(keystore, script);
  28. }
  29. isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey)
  30. {
  31. vector<valtype> vSolutions;
  32. txnouttype whichType;
  33. if (!Solver(scriptPubKey, whichType, vSolutions)) {
  34. if (keystore.HaveWatchOnly(scriptPubKey))
  35. return ISMINE_WATCH_ONLY;
  36. return ISMINE_NO;
  37. }
  38. CKeyID keyID;
  39. switch (whichType)
  40. {
  41. case TX_NONSTANDARD:
  42. case TX_NULL_DATA:
  43. break;
  44. case TX_PUBKEY:
  45. keyID = CPubKey(vSolutions[0]).GetID();
  46. if (keystore.HaveKey(keyID))
  47. return ISMINE_SPENDABLE;
  48. break;
  49. case TX_PUBKEYHASH:
  50. keyID = CKeyID(uint160(vSolutions[0]));
  51. if (keystore.HaveKey(keyID))
  52. return ISMINE_SPENDABLE;
  53. break;
  54. case TX_SCRIPTHASH:
  55. {
  56. CScriptID scriptID = CScriptID(uint160(vSolutions[0]));
  57. CScript subscript;
  58. if (keystore.GetCScript(scriptID, subscript)) {
  59. isminetype ret = IsMine(keystore, subscript);
  60. if (ret == ISMINE_SPENDABLE)
  61. return ret;
  62. }
  63. break;
  64. }
  65. case TX_MULTISIG:
  66. {
  67. // Only consider transactions "mine" if we own ALL the
  68. // keys involved. Multi-signature transactions that are
  69. // partially owned (somebody else has a key that can spend
  70. // them) enable spend-out-from-under-you attacks, especially
  71. // in shared-wallet situations.
  72. vector<valtype> keys(vSolutions.begin()+1, vSolutions.begin()+vSolutions.size()-1);
  73. if (HaveKeys(keys, keystore) == keys.size())
  74. return ISMINE_SPENDABLE;
  75. break;
  76. }
  77. }
  78. if (keystore.HaveWatchOnly(scriptPubKey))
  79. return ISMINE_WATCH_ONLY;
  80. return ISMINE_NO;
  81. }