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.

multisig_tests.cpp 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. // Copyright (c) 2011-2013 The Bitcoin Core developers
  2. // Distributed under the MIT software license, see the accompanying
  3. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4. #include "key.h"
  5. #include "keystore.h"
  6. #include "main.h"
  7. #include "script/script.h"
  8. #include "script/script_error.h"
  9. #include "script/interpreter.h"
  10. #include "script/sign.h"
  11. #include "uint256.h"
  12. #include "test/test_bitcoin.h"
  13. #ifdef ENABLE_WALLET
  14. #include "wallet/wallet_ismine.h"
  15. #endif
  16. #include <boost/foreach.hpp>
  17. #include <boost/test/unit_test.hpp>
  18. using namespace std;
  19. typedef vector<unsigned char> valtype;
  20. BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup)
  21. CScript
  22. sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction, int whichIn)
  23. {
  24. uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL);
  25. CScript result;
  26. result << OP_0; // CHECKMULTISIG bug workaround
  27. BOOST_FOREACH(const CKey &key, keys)
  28. {
  29. vector<unsigned char> vchSig;
  30. BOOST_CHECK(key.Sign(hash, vchSig));
  31. vchSig.push_back((unsigned char)SIGHASH_ALL);
  32. result << vchSig;
  33. }
  34. return result;
  35. }
  36. BOOST_AUTO_TEST_CASE(multisig_verify)
  37. {
  38. unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
  39. ScriptError err;
  40. CKey key[4];
  41. for (int i = 0; i < 4; i++)
  42. key[i].MakeNewKey(true);
  43. CScript a_and_b;
  44. a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
  45. CScript a_or_b;
  46. a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
  47. CScript escrow;
  48. escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
  49. CMutableTransaction txFrom; // Funding transaction
  50. txFrom.vout.resize(3);
  51. txFrom.vout[0].scriptPubKey = a_and_b;
  52. txFrom.vout[1].scriptPubKey = a_or_b;
  53. txFrom.vout[2].scriptPubKey = escrow;
  54. CMutableTransaction txTo[3]; // Spending transaction
  55. for (int i = 0; i < 3; i++)
  56. {
  57. txTo[i].vin.resize(1);
  58. txTo[i].vout.resize(1);
  59. txTo[i].vin[0].prevout.n = i;
  60. txTo[i].vin[0].prevout.hash = txFrom.GetHash();
  61. txTo[i].vout[0].nValue = 1;
  62. }
  63. vector<CKey> keys;
  64. CScript s;
  65. // Test a AND b:
  66. keys.assign(1,key[0]);
  67. keys.push_back(key[1]);
  68. s = sign_multisig(a_and_b, keys, txTo[0], 0);
  69. BOOST_CHECK(VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err));
  70. BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
  71. for (int i = 0; i < 4; i++)
  72. {
  73. keys.assign(1,key[i]);
  74. s = sign_multisig(a_and_b, keys, txTo[0], 0);
  75. BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 1: %d", i));
  76. BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
  77. keys.assign(1,key[1]);
  78. keys.push_back(key[i]);
  79. s = sign_multisig(a_and_b, keys, txTo[0], 0);
  80. BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, MutableTransactionSignatureChecker(&txTo[0], 0), &err), strprintf("a&b 2: %d", i));
  81. BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
  82. }
  83. // Test a OR b:
  84. for (int i = 0; i < 4; i++)
  85. {
  86. keys.assign(1,key[i]);
  87. s = sign_multisig(a_or_b, keys, txTo[1], 0);
  88. if (i == 0 || i == 1)
  89. {
  90. BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i));
  91. BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
  92. }
  93. else
  94. {
  95. BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err), strprintf("a|b: %d", i));
  96. BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
  97. }
  98. }
  99. s.clear();
  100. s << OP_0 << OP_1;
  101. BOOST_CHECK(!VerifyScript(s, a_or_b, flags, MutableTransactionSignatureChecker(&txTo[1], 0), &err));
  102. BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
  103. for (int i = 0; i < 4; i++)
  104. for (int j = 0; j < 4; j++)
  105. {
  106. keys.assign(1,key[i]);
  107. keys.push_back(key[j]);
  108. s = sign_multisig(escrow, keys, txTo[2], 0);
  109. if (i < j && i < 3 && j < 3)
  110. {
  111. BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 1: %d %d", i, j));
  112. BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
  113. }
  114. else
  115. {
  116. BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, MutableTransactionSignatureChecker(&txTo[2], 0), &err), strprintf("escrow 2: %d %d", i, j));
  117. BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
  118. }
  119. }
  120. }
  121. BOOST_AUTO_TEST_CASE(multisig_IsStandard)
  122. {
  123. CKey key[4];
  124. for (int i = 0; i < 4; i++)
  125. key[i].MakeNewKey(true);
  126. txnouttype whichType;
  127. CScript a_and_b;
  128. a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
  129. BOOST_CHECK(::IsStandard(a_and_b, whichType));
  130. CScript a_or_b;
  131. a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
  132. BOOST_CHECK(::IsStandard(a_or_b, whichType));
  133. CScript escrow;
  134. escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
  135. BOOST_CHECK(::IsStandard(escrow, whichType));
  136. CScript one_of_four;
  137. one_of_four << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << ToByteVector(key[3].GetPubKey()) << OP_4 << OP_CHECKMULTISIG;
  138. BOOST_CHECK(!::IsStandard(one_of_four, whichType));
  139. CScript malformed[6];
  140. malformed[0] << OP_3 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
  141. malformed[1] << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
  142. malformed[2] << OP_0 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
  143. malformed[3] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_0 << OP_CHECKMULTISIG;
  144. malformed[4] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_CHECKMULTISIG;
  145. malformed[5] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey());
  146. for (int i = 0; i < 6; i++)
  147. BOOST_CHECK(!::IsStandard(malformed[i], whichType));
  148. }
  149. BOOST_AUTO_TEST_CASE(multisig_Solver1)
  150. {
  151. // Tests Solver() that returns lists of keys that are
  152. // required to satisfy a ScriptPubKey
  153. //
  154. // Also tests IsMine() and ExtractDestination()
  155. //
  156. // Note: ExtractDestination for the multisignature transactions
  157. // always returns false for this release, even if you have
  158. // one key that would satisfy an (a|b) or 2-of-3 keys needed
  159. // to spend an escrow transaction.
  160. //
  161. CBasicKeyStore keystore, emptykeystore, partialkeystore;
  162. CKey key[3];
  163. CTxDestination keyaddr[3];
  164. for (int i = 0; i < 3; i++)
  165. {
  166. key[i].MakeNewKey(true);
  167. keystore.AddKey(key[i]);
  168. keyaddr[i] = key[i].GetPubKey().GetID();
  169. }
  170. partialkeystore.AddKey(key[0]);
  171. {
  172. vector<valtype> solutions;
  173. txnouttype whichType;
  174. CScript s;
  175. s << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG;
  176. BOOST_CHECK(Solver(s, whichType, solutions));
  177. BOOST_CHECK(solutions.size() == 1);
  178. CTxDestination addr;
  179. BOOST_CHECK(ExtractDestination(s, addr));
  180. BOOST_CHECK(addr == keyaddr[0]);
  181. #ifdef ENABLE_WALLET
  182. BOOST_CHECK(IsMine(keystore, s));
  183. BOOST_CHECK(!IsMine(emptykeystore, s));
  184. #endif
  185. }
  186. {
  187. vector<valtype> solutions;
  188. txnouttype whichType;
  189. CScript s;
  190. s << OP_DUP << OP_HASH160 << ToByteVector(key[0].GetPubKey().GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
  191. BOOST_CHECK(Solver(s, whichType, solutions));
  192. BOOST_CHECK(solutions.size() == 1);
  193. CTxDestination addr;
  194. BOOST_CHECK(ExtractDestination(s, addr));
  195. BOOST_CHECK(addr == keyaddr[0]);
  196. #ifdef ENABLE_WALLET
  197. BOOST_CHECK(IsMine(keystore, s));
  198. BOOST_CHECK(!IsMine(emptykeystore, s));
  199. #endif
  200. }
  201. {
  202. vector<valtype> solutions;
  203. txnouttype whichType;
  204. CScript s;
  205. s << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
  206. BOOST_CHECK(Solver(s, whichType, solutions));
  207. BOOST_CHECK_EQUAL(solutions.size(), 4U);
  208. CTxDestination addr;
  209. BOOST_CHECK(!ExtractDestination(s, addr));
  210. #ifdef ENABLE_WALLET
  211. BOOST_CHECK(IsMine(keystore, s));
  212. BOOST_CHECK(!IsMine(emptykeystore, s));
  213. BOOST_CHECK(!IsMine(partialkeystore, s));
  214. #endif
  215. }
  216. {
  217. vector<valtype> solutions;
  218. txnouttype whichType;
  219. CScript s;
  220. s << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
  221. BOOST_CHECK(Solver(s, whichType, solutions));
  222. BOOST_CHECK_EQUAL(solutions.size(), 4U);
  223. vector<CTxDestination> addrs;
  224. int nRequired;
  225. BOOST_CHECK(ExtractDestinations(s, whichType, addrs, nRequired));
  226. BOOST_CHECK(addrs[0] == keyaddr[0]);
  227. BOOST_CHECK(addrs[1] == keyaddr[1]);
  228. BOOST_CHECK(nRequired == 1);
  229. #ifdef ENABLE_WALLET
  230. BOOST_CHECK(IsMine(keystore, s));
  231. BOOST_CHECK(!IsMine(emptykeystore, s));
  232. BOOST_CHECK(!IsMine(partialkeystore, s));
  233. #endif
  234. }
  235. {
  236. vector<valtype> solutions;
  237. txnouttype whichType;
  238. CScript s;
  239. s << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
  240. BOOST_CHECK(Solver(s, whichType, solutions));
  241. BOOST_CHECK(solutions.size() == 5);
  242. }
  243. }
  244. BOOST_AUTO_TEST_CASE(multisig_Sign)
  245. {
  246. // Test SignSignature() (and therefore the version of Solver() that signs transactions)
  247. CBasicKeyStore keystore;
  248. CKey key[4];
  249. for (int i = 0; i < 4; i++)
  250. {
  251. key[i].MakeNewKey(true);
  252. keystore.AddKey(key[i]);
  253. }
  254. CScript a_and_b;
  255. a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
  256. CScript a_or_b;
  257. a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
  258. CScript escrow;
  259. escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
  260. CMutableTransaction txFrom; // Funding transaction
  261. txFrom.vout.resize(3);
  262. txFrom.vout[0].scriptPubKey = a_and_b;
  263. txFrom.vout[1].scriptPubKey = a_or_b;
  264. txFrom.vout[2].scriptPubKey = escrow;
  265. CMutableTransaction txTo[3]; // Spending transaction
  266. for (int i = 0; i < 3; i++)
  267. {
  268. txTo[i].vin.resize(1);
  269. txTo[i].vout.resize(1);
  270. txTo[i].vin[0].prevout.n = i;
  271. txTo[i].vin[0].prevout.hash = txFrom.GetHash();
  272. txTo[i].vout[0].nValue = 1;
  273. }
  274. for (int i = 0; i < 3; i++)
  275. {
  276. BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i));
  277. }
  278. }
  279. BOOST_AUTO_TEST_SUITE_END()