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.

standard.cpp 9.3KB

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