1 #include <boost/assert.hpp>
2 #include <boost/assign/list_of.hpp>
3 #include <boost/assign/list_inserter.hpp>
4 #include <boost/assign/std/vector.hpp>
5 #include <boost/test/unit_test.hpp>
6 #include <boost/foreach.hpp>
7 #include <boost/tuple/tuple.hpp>
9 #include <openssl/ec.h>
10 #include <openssl/err.h>
18 using namespace boost::assign;
20 typedef vector<unsigned char> valtype;
22 extern uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
23 extern bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn,
24 bool fValidatePayToScriptHash, int nHashType);
26 BOOST_AUTO_TEST_SUITE(multisig_tests)
29 sign_multisig(CScript scriptPubKey, vector<CKey> keys, CTransaction transaction, int whichIn)
31 uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL);
34 result << OP_0; // CHECKMULTISIG bug workaround
35 BOOST_FOREACH(CKey key, keys)
37 vector<unsigned char> vchSig;
38 BOOST_CHECK(key.Sign(hash, vchSig));
39 vchSig.push_back((unsigned char)SIGHASH_ALL);
45 BOOST_AUTO_TEST_CASE(multisig_verify)
48 for (int i = 0; i < 4; i++)
49 key[i].MakeNewKey(true);
52 a_and_b << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
55 a_or_b << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
58 escrow << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG;
60 CTransaction txFrom; // Funding transaction
61 txFrom.vout.resize(3);
62 txFrom.vout[0].scriptPubKey = a_and_b;
63 txFrom.vout[1].scriptPubKey = a_or_b;
64 txFrom.vout[2].scriptPubKey = escrow;
66 CTransaction txTo[3]; // Spending transaction
67 for (int i = 0; i < 3; i++)
69 txTo[i].vin.resize(1);
70 txTo[i].vout.resize(1);
71 txTo[i].vin[0].prevout.n = i;
72 txTo[i].vin[0].prevout.hash = txFrom.GetHash();
73 txTo[i].vout[0].nValue = 1;
81 keys += key[0],key[1]; // magic operator+= from boost.assign
82 s = sign_multisig(a_and_b, keys, txTo[0], 0);
83 BOOST_CHECK(VerifyScript(s, a_and_b, txTo[0], 0, true, 0));
85 for (int i = 0; i < 4; i++)
89 s = sign_multisig(a_and_b, keys, txTo[0], 0);
90 BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, true, 0), strprintf("a&b 1: %d", i));
93 keys += key[1],key[i];
94 s = sign_multisig(a_and_b, keys, txTo[0], 0);
95 BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, true, 0), strprintf("a&b 2: %d", i));
99 for (int i = 0; i < 4; i++)
103 s = sign_multisig(a_or_b, keys, txTo[1], 0);
104 if (i == 0 || i == 1)
105 BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, txTo[1], 0, true, 0), strprintf("a|b: %d", i));
107 BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, txTo[1], 0, true, 0), strprintf("a|b: %d", i));
111 BOOST_CHECK(!VerifyScript(s, a_or_b, txTo[1], 0, true, 0));
114 BOOST_CHECK(!VerifyScript(s, a_or_b, txTo[1], 0, true, 0));
117 for (int i = 0; i < 4; i++)
118 for (int j = 0; j < 4; j++)
121 keys += key[i],key[j];
122 s = sign_multisig(escrow, keys, txTo[2], 0);
123 if (i < j && i < 3 && j < 3)
124 BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, txTo[2], 0, true, 0), strprintf("escrow 1: %d %d", i, j));
126 BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, txTo[2], 0, true, 0), strprintf("escrow 2: %d %d", i, j));
130 BOOST_AUTO_TEST_CASE(multisig_IsStandard)
133 for (int i = 0; i < 4; i++)
134 key[i].MakeNewKey(true);
136 txnouttype whichType;
139 a_and_b << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
140 BOOST_CHECK(::IsStandard(a_and_b, whichType));
143 a_or_b << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
144 BOOST_CHECK(::IsStandard(a_or_b, whichType));
147 escrow << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG;
148 BOOST_CHECK(::IsStandard(escrow, whichType));
151 one_of_four << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << key[3].GetPubKey() << OP_4 << OP_CHECKMULTISIG;
152 BOOST_CHECK(!::IsStandard(one_of_four, whichType));
154 CScript malformed[6];
155 malformed[0] << OP_3 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
156 malformed[1] << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_3 << OP_CHECKMULTISIG;
157 malformed[2] << OP_0 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
158 malformed[3] << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_0 << OP_CHECKMULTISIG;
159 malformed[4] << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_CHECKMULTISIG;
160 malformed[5] << OP_1 << key[0].GetPubKey() << key[1].GetPubKey();
162 for (int i = 0; i < 6; i++)
163 BOOST_CHECK(!::IsStandard(malformed[i], whichType));
166 BOOST_AUTO_TEST_CASE(multisig_Solver1)
168 // Tests Solver() that returns lists of keys that are
169 // required to satisfy a ScriptPubKey
171 // Also tests IsMine() and ExtractAddress()
173 // Note: ExtractAddress for the multisignature transactions
174 // always returns false for this release, even if you have
175 // one key that would satisfy an (a|b) or 2-of-3 keys needed
176 // to spend an escrow transaction.
178 CBasicKeyStore keystore, emptykeystore, partialkeystore;
180 CTxDestination keyaddr[3];
181 for (int i = 0; i < 3; i++)
183 key[i].MakeNewKey(true);
184 keystore.AddKey(key[i]);
185 keyaddr[i] = key[i].GetPubKey().GetID();
187 partialkeystore.AddKey(key[0]);
190 vector<valtype> solutions;
191 txnouttype whichType;
193 s << key[0].GetPubKey() << OP_CHECKSIG;
194 BOOST_CHECK(Solver(s, whichType, solutions));
195 BOOST_CHECK(solutions.size() == 1);
197 BOOST_CHECK(ExtractDestination(s, addr));
198 BOOST_CHECK(addr == keyaddr[0]);
199 BOOST_CHECK(IsMine(keystore, s));
200 BOOST_CHECK(!IsMine(emptykeystore, s));
203 vector<valtype> solutions;
204 txnouttype whichType;
206 s << OP_DUP << OP_HASH160 << key[0].GetPubKey().GetID() << OP_EQUALVERIFY << OP_CHECKSIG;
207 BOOST_CHECK(Solver(s, whichType, solutions));
208 BOOST_CHECK(solutions.size() == 1);
210 BOOST_CHECK(ExtractDestination(s, addr));
211 BOOST_CHECK(addr == keyaddr[0]);
212 BOOST_CHECK(IsMine(keystore, s));
213 BOOST_CHECK(!IsMine(emptykeystore, s));
216 vector<valtype> solutions;
217 txnouttype whichType;
219 s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
220 BOOST_CHECK(Solver(s, whichType, solutions));
221 BOOST_CHECK_EQUAL(solutions.size(), 4);
223 BOOST_CHECK(!ExtractDestination(s, addr));
224 BOOST_CHECK(IsMine(keystore, s));
225 BOOST_CHECK(!IsMine(emptykeystore, s));
226 BOOST_CHECK(!IsMine(partialkeystore, s));
229 vector<valtype> solutions;
230 txnouttype whichType;
232 s << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
233 BOOST_CHECK(Solver(s, whichType, solutions));
234 BOOST_CHECK_EQUAL(solutions.size(), 4);
235 vector<CTxDestination> addrs;
237 BOOST_CHECK(ExtractDestinations(s, whichType, addrs, nRequired));
238 BOOST_CHECK(addrs[0] == keyaddr[0]);
239 BOOST_CHECK(addrs[1] == keyaddr[1]);
240 BOOST_CHECK(nRequired == 1);
241 BOOST_CHECK(IsMine(keystore, s));
242 BOOST_CHECK(!IsMine(emptykeystore, s));
243 BOOST_CHECK(!IsMine(partialkeystore, s));
246 vector<valtype> solutions;
247 txnouttype whichType;
249 s << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG;
250 BOOST_CHECK(Solver(s, whichType, solutions));
251 BOOST_CHECK(solutions.size() == 5);
255 BOOST_AUTO_TEST_CASE(multisig_Sign)
257 // Test SignSignature() (and therefore the version of Solver() that signs transactions)
258 CBasicKeyStore keystore;
260 for (int i = 0; i < 4; i++)
262 key[i].MakeNewKey(true);
263 keystore.AddKey(key[i]);
267 a_and_b << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
270 a_or_b << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
273 escrow << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG;
275 CTransaction txFrom; // Funding transaction
276 txFrom.vout.resize(3);
277 txFrom.vout[0].scriptPubKey = a_and_b;
278 txFrom.vout[1].scriptPubKey = a_or_b;
279 txFrom.vout[2].scriptPubKey = escrow;
281 CTransaction txTo[3]; // Spending transaction
282 for (int i = 0; i < 3; i++)
284 txTo[i].vin.resize(1);
285 txTo[i].vout.resize(1);
286 txTo[i].vin[0].prevout.n = i;
287 txTo[i].vin[0].prevout.hash = txFrom.GetHash();
288 txTo[i].vout[0].nValue = 1;
291 for (int i = 0; i < 3; i++)
293 BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i));
298 BOOST_AUTO_TEST_SUITE_END()