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.

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