PageRenderTime 25ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/src/script/standard.cpp

https://gitlab.com/Ltaimao/bitcoin
C++ | 318 lines | 253 code | 39 blank | 26 comment | 78 complexity | e563e9953dc3fc56635a86af669092a3 MD5 | raw file
  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 "script/standard.h"
  6. #include "pubkey.h"
  7. #include "script/script.h"
  8. #include "util.h"
  9. #include "utilstrencodings.h"
  10. #include <boost/foreach.hpp>
  11. using namespace std;
  12. typedef vector<unsigned char> valtype;
  13. unsigned nMaxDatacarrierBytes = MAX_OP_RETURN_RELAY;
  14. CScriptID::CScriptID(const CScript& in) : uint160(in.size() ? Hash160(in.begin(), in.end()) : 0) {}
  15. const char* GetTxnOutputType(txnouttype t)
  16. {
  17. switch (t)
  18. {
  19. case TX_NONSTANDARD: return "nonstandard";
  20. case TX_PUBKEY: return "pubkey";
  21. case TX_PUBKEYHASH: return "pubkeyhash";
  22. case TX_SCRIPTHASH: return "scripthash";
  23. case TX_MULTISIG: return "multisig";
  24. case TX_NULL_DATA: return "nulldata";
  25. }
  26. return NULL;
  27. }
  28. /**
  29. * Return public keys or hashes from scriptPubKey, for 'standard' transaction types.
  30. */
  31. bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsigned char> >& vSolutionsRet)
  32. {
  33. // Templates
  34. static multimap<txnouttype, CScript> mTemplates;
  35. if (mTemplates.empty())
  36. {
  37. // Standard tx, sender provides pubkey, receiver adds signature
  38. mTemplates.insert(make_pair(TX_PUBKEY, CScript() << OP_PUBKEY << OP_CHECKSIG));
  39. // Bitcoin address tx, sender provides hash of pubkey, receiver provides signature and pubkey
  40. mTemplates.insert(make_pair(TX_PUBKEYHASH, CScript() << OP_DUP << OP_HASH160 << OP_PUBKEYHASH << OP_EQUALVERIFY << OP_CHECKSIG));
  41. // Sender provides N pubkeys, receivers provides M signatures
  42. mTemplates.insert(make_pair(TX_MULTISIG, CScript() << OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIG));
  43. // Empty, provably prunable, data-carrying output
  44. if (GetBoolArg("-datacarrier", true))
  45. mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN << OP_SMALLDATA));
  46. mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN));
  47. }
  48. // Shortcut for pay-to-script-hash, which are more constrained than the other types:
  49. // it is always OP_HASH160 20 [20 byte hash] OP_EQUAL
  50. if (scriptPubKey.IsPayToScriptHash())
  51. {
  52. typeRet = TX_SCRIPTHASH;
  53. vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22);
  54. vSolutionsRet.push_back(hashBytes);
  55. return true;
  56. }
  57. // Scan templates
  58. const CScript& script1 = scriptPubKey;
  59. BOOST_FOREACH(const PAIRTYPE(txnouttype, CScript)& tplate, mTemplates)
  60. {
  61. const CScript& script2 = tplate.second;
  62. vSolutionsRet.clear();
  63. opcodetype opcode1, opcode2;
  64. vector<unsigned char> vch1, vch2;
  65. // Compare
  66. CScript::const_iterator pc1 = script1.begin();
  67. CScript::const_iterator pc2 = script2.begin();
  68. while (true)
  69. {
  70. if (pc1 == script1.end() && pc2 == script2.end())
  71. {
  72. // Found a match
  73. typeRet = tplate.first;
  74. if (typeRet == TX_MULTISIG)
  75. {
  76. // Additional checks for TX_MULTISIG:
  77. unsigned char m = vSolutionsRet.front()[0];
  78. unsigned char n = vSolutionsRet.back()[0];
  79. if (m < 1 || n < 1 || m > n || vSolutionsRet.size()-2 != n)
  80. return false;
  81. }
  82. return true;
  83. }
  84. if (!script1.GetOp(pc1, opcode1, vch1))
  85. break;
  86. if (!script2.GetOp(pc2, opcode2, vch2))
  87. break;
  88. // Template matching opcodes:
  89. if (opcode2 == OP_PUBKEYS)
  90. {
  91. while (vch1.size() >= 33 && vch1.size() <= 65)
  92. {
  93. vSolutionsRet.push_back(vch1);
  94. if (!script1.GetOp(pc1, opcode1, vch1))
  95. break;
  96. }
  97. if (!script2.GetOp(pc2, opcode2, vch2))
  98. break;
  99. // Normal situation is to fall through
  100. // to other if/else statements
  101. }
  102. if (opcode2 == OP_PUBKEY)
  103. {
  104. if (vch1.size() < 33 || vch1.size() > 65)
  105. break;
  106. vSolutionsRet.push_back(vch1);
  107. }
  108. else if (opcode2 == OP_PUBKEYHASH)
  109. {
  110. if (vch1.size() != sizeof(uint160))
  111. break;
  112. vSolutionsRet.push_back(vch1);
  113. }
  114. else if (opcode2 == OP_SMALLINTEGER)
  115. { // Single-byte small integer pushed onto vSolutions
  116. if (opcode1 == OP_0 ||
  117. (opcode1 >= OP_1 && opcode1 <= OP_16))
  118. {
  119. char n = (char)CScript::DecodeOP_N(opcode1);
  120. vSolutionsRet.push_back(valtype(1, n));
  121. }
  122. else
  123. break;
  124. }
  125. else if (opcode2 == OP_SMALLDATA)
  126. {
  127. // small pushdata, <= nMaxDatacarrierBytes
  128. if (vch1.size() > nMaxDatacarrierBytes)
  129. break;
  130. }
  131. else if (opcode1 != opcode2 || vch1 != vch2)
  132. {
  133. // Others must match exactly
  134. break;
  135. }
  136. }
  137. }
  138. vSolutionsRet.clear();
  139. typeRet = TX_NONSTANDARD;
  140. return false;
  141. }
  142. int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions)
  143. {
  144. switch (t)
  145. {
  146. case TX_NONSTANDARD:
  147. case TX_NULL_DATA:
  148. return -1;
  149. case TX_PUBKEY:
  150. return 1;
  151. case TX_PUBKEYHASH:
  152. return 2;
  153. case TX_MULTISIG:
  154. if (vSolutions.size() < 1 || vSolutions[0].size() < 1)
  155. return -1;
  156. return vSolutions[0][0] + 1;
  157. case TX_SCRIPTHASH:
  158. return 1; // doesn't include args needed by the script
  159. }
  160. return -1;
  161. }
  162. bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType)
  163. {
  164. vector<valtype> vSolutions;
  165. if (!Solver(scriptPubKey, whichType, vSolutions))
  166. return false;
  167. if (whichType == TX_MULTISIG)
  168. {
  169. unsigned char m = vSolutions.front()[0];
  170. unsigned char n = vSolutions.back()[0];
  171. // Support up to x-of-3 multisig txns as standard
  172. if (n < 1 || n > 3)
  173. return false;
  174. if (m < 1 || m > n)
  175. return false;
  176. }
  177. return whichType != TX_NONSTANDARD;
  178. }
  179. bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
  180. {
  181. vector<valtype> vSolutions;
  182. txnouttype whichType;
  183. if (!Solver(scriptPubKey, whichType, vSolutions))
  184. return false;
  185. if (whichType == TX_PUBKEY)
  186. {
  187. CPubKey pubKey(vSolutions[0]);
  188. if (!pubKey.IsValid())
  189. return false;
  190. addressRet = pubKey.GetID();
  191. return true;
  192. }
  193. else if (whichType == TX_PUBKEYHASH)
  194. {
  195. addressRet = CKeyID(uint160(vSolutions[0]));
  196. return true;
  197. }
  198. else if (whichType == TX_SCRIPTHASH)
  199. {
  200. addressRet = CScriptID(uint160(vSolutions[0]));
  201. return true;
  202. }
  203. // Multisig txns have more than one address...
  204. return false;
  205. }
  206. bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vector<CTxDestination>& addressRet, int& nRequiredRet)
  207. {
  208. addressRet.clear();
  209. typeRet = TX_NONSTANDARD;
  210. vector<valtype> vSolutions;
  211. if (!Solver(scriptPubKey, typeRet, vSolutions))
  212. return false;
  213. if (typeRet == TX_NULL_DATA){
  214. // This is data, not addresses
  215. return false;
  216. }
  217. if (typeRet == TX_MULTISIG)
  218. {
  219. nRequiredRet = vSolutions.front()[0];
  220. for (unsigned int i = 1; i < vSolutions.size()-1; i++)
  221. {
  222. CPubKey pubKey(vSolutions[i]);
  223. if (!pubKey.IsValid())
  224. continue;
  225. CTxDestination address = pubKey.GetID();
  226. addressRet.push_back(address);
  227. }
  228. if (addressRet.empty())
  229. return false;
  230. }
  231. else
  232. {
  233. nRequiredRet = 1;
  234. CTxDestination address;
  235. if (!ExtractDestination(scriptPubKey, address))
  236. return false;
  237. addressRet.push_back(address);
  238. }
  239. return true;
  240. }
  241. namespace
  242. {
  243. class CScriptVisitor : public boost::static_visitor<bool>
  244. {
  245. private:
  246. CScript *script;
  247. public:
  248. CScriptVisitor(CScript *scriptin) { script = scriptin; }
  249. bool operator()(const CNoDestination &dest) const {
  250. script->clear();
  251. return false;
  252. }
  253. bool operator()(const CKeyID &keyID) const {
  254. script->clear();
  255. *script << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
  256. return true;
  257. }
  258. bool operator()(const CScriptID &scriptID) const {
  259. script->clear();
  260. *script << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
  261. return true;
  262. }
  263. };
  264. }
  265. CScript GetScriptForDestination(const CTxDestination& dest)
  266. {
  267. CScript script;
  268. boost::apply_visitor(CScriptVisitor(&script), dest);
  269. return script;
  270. }
  271. CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys)
  272. {
  273. CScript script;
  274. script << CScript::EncodeOP_N(nRequired);
  275. BOOST_FOREACH(const CPubKey& key, keys)
  276. script << ToByteVector(key);
  277. script << CScript::EncodeOP_N(keys.size()) << OP_CHECKMULTISIG;
  278. return script;
  279. }