Use the variable name _ for unused return values
[bitcoinplatinum.git] / src / test / multisig_tests.cpp
blob5e89ef60d2113d143dd546116833e74296c8880d
1 // Copyright (c) 2011-2016 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.
5 #include "key.h"
6 #include "keystore.h"
7 #include "policy/policy.h"
8 #include "script/script.h"
9 #include "script/script_error.h"
10 #include "script/interpreter.h"
11 #include "script/sign.h"
12 #include "script/ismine.h"
13 #include "uint256.h"
14 #include "test/test_bitcoin.h"
17 #include <boost/test/unit_test.hpp>
19 typedef std::vector<unsigned char> valtype;
21 BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup)
23 CScript
24 sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transaction, int whichIn)
26 uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL, 0, SIGVERSION_BASE);
28 CScript result;
29 result << OP_0; // CHECKMULTISIG bug workaround
30 for (const CKey &key : keys)
32 std::vector<unsigned char> vchSig;
33 BOOST_CHECK(key.Sign(hash, vchSig));
34 vchSig.push_back((unsigned char)SIGHASH_ALL);
35 result << vchSig;
37 return result;
40 BOOST_AUTO_TEST_CASE(multisig_verify)
42 unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
44 ScriptError err;
45 CKey key[4];
46 CAmount amount = 0;
47 for (int i = 0; i < 4; i++)
48 key[i].MakeNewKey(true);
50 CScript a_and_b;
51 a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
53 CScript a_or_b;
54 a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
56 CScript escrow;
57 escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
59 CMutableTransaction txFrom; // Funding transaction
60 txFrom.vout.resize(3);
61 txFrom.vout[0].scriptPubKey = a_and_b;
62 txFrom.vout[1].scriptPubKey = a_or_b;
63 txFrom.vout[2].scriptPubKey = escrow;
65 CMutableTransaction txTo[3]; // Spending transaction
66 for (int i = 0; i < 3; i++)
68 txTo[i].vin.resize(1);
69 txTo[i].vout.resize(1);
70 txTo[i].vin[0].prevout.n = i;
71 txTo[i].vin[0].prevout.hash = txFrom.GetHash();
72 txTo[i].vout[0].nValue = 1;
75 std::vector<CKey> keys;
76 CScript s;
78 // Test a AND b:
79 keys.assign(1,key[0]);
80 keys.push_back(key[1]);
81 s = sign_multisig(a_and_b, keys, txTo[0], 0);
82 BOOST_CHECK(VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err));
83 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
85 for (int i = 0; i < 4; i++)
87 keys.assign(1,key[i]);
88 s = sign_multisig(a_and_b, keys, txTo[0], 0);
89 BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 1: %d", i));
90 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
92 keys.assign(1,key[1]);
93 keys.push_back(key[i]);
94 s = sign_multisig(a_and_b, keys, txTo[0], 0);
95 BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 2: %d", i));
96 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
99 // Test a OR b:
100 for (int i = 0; i < 4; i++)
102 keys.assign(1,key[i]);
103 s = sign_multisig(a_or_b, keys, txTo[1], 0);
104 if (i == 0 || i == 1)
106 BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i));
107 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
109 else
111 BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i));
112 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
115 s.clear();
116 s << OP_0 << OP_1;
117 BOOST_CHECK(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err));
118 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
121 for (int i = 0; i < 4; i++)
122 for (int j = 0; j < 4; j++)
124 keys.assign(1,key[i]);
125 keys.push_back(key[j]);
126 s = sign_multisig(escrow, keys, txTo[2], 0);
127 if (i < j && i < 3 && j < 3)
129 BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 1: %d %d", i, j));
130 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
132 else
134 BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 2: %d %d", i, j));
135 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
140 BOOST_AUTO_TEST_CASE(multisig_IsStandard)
142 CKey key[4];
143 for (int i = 0; i < 4; i++)
144 key[i].MakeNewKey(true);
146 txnouttype whichType;
148 CScript a_and_b;
149 a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
150 BOOST_CHECK(::IsStandard(a_and_b, whichType));
152 CScript a_or_b;
153 a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
154 BOOST_CHECK(::IsStandard(a_or_b, whichType));
156 CScript escrow;
157 escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
158 BOOST_CHECK(::IsStandard(escrow, whichType));
160 CScript one_of_four;
161 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;
162 BOOST_CHECK(!::IsStandard(one_of_four, whichType));
164 CScript malformed[6];
165 malformed[0] << OP_3 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
166 malformed[1] << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
167 malformed[2] << OP_0 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
168 malformed[3] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_0 << OP_CHECKMULTISIG;
169 malformed[4] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_CHECKMULTISIG;
170 malformed[5] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey());
172 for (int i = 0; i < 6; i++)
173 BOOST_CHECK(!::IsStandard(malformed[i], whichType));
176 BOOST_AUTO_TEST_CASE(multisig_Solver1)
178 // Tests Solver() that returns lists of keys that are
179 // required to satisfy a ScriptPubKey
181 // Also tests IsMine() and ExtractDestination()
183 // Note: ExtractDestination for the multisignature transactions
184 // always returns false for this release, even if you have
185 // one key that would satisfy an (a|b) or 2-of-3 keys needed
186 // to spend an escrow transaction.
188 CBasicKeyStore keystore, emptykeystore, partialkeystore;
189 CKey key[3];
190 CTxDestination keyaddr[3];
191 for (int i = 0; i < 3; i++)
193 key[i].MakeNewKey(true);
194 keystore.AddKey(key[i]);
195 keyaddr[i] = key[i].GetPubKey().GetID();
197 partialkeystore.AddKey(key[0]);
200 std::vector<valtype> solutions;
201 txnouttype whichType;
202 CScript s;
203 s << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG;
204 BOOST_CHECK(Solver(s, whichType, solutions));
205 BOOST_CHECK(solutions.size() == 1);
206 CTxDestination addr;
207 BOOST_CHECK(ExtractDestination(s, addr));
208 BOOST_CHECK(addr == keyaddr[0]);
209 BOOST_CHECK(IsMine(keystore, s));
210 BOOST_CHECK(!IsMine(emptykeystore, s));
213 std::vector<valtype> solutions;
214 txnouttype whichType;
215 CScript s;
216 s << OP_DUP << OP_HASH160 << ToByteVector(key[0].GetPubKey().GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
217 BOOST_CHECK(Solver(s, whichType, solutions));
218 BOOST_CHECK(solutions.size() == 1);
219 CTxDestination addr;
220 BOOST_CHECK(ExtractDestination(s, addr));
221 BOOST_CHECK(addr == keyaddr[0]);
222 BOOST_CHECK(IsMine(keystore, s));
223 BOOST_CHECK(!IsMine(emptykeystore, s));
226 std::vector<valtype> solutions;
227 txnouttype whichType;
228 CScript s;
229 s << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
230 BOOST_CHECK(Solver(s, whichType, solutions));
231 BOOST_CHECK_EQUAL(solutions.size(), 4U);
232 CTxDestination addr;
233 BOOST_CHECK(!ExtractDestination(s, addr));
234 BOOST_CHECK(IsMine(keystore, s));
235 BOOST_CHECK(!IsMine(emptykeystore, s));
236 BOOST_CHECK(!IsMine(partialkeystore, s));
239 std::vector<valtype> solutions;
240 txnouttype whichType;
241 CScript s;
242 s << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
243 BOOST_CHECK(Solver(s, whichType, solutions));
244 BOOST_CHECK_EQUAL(solutions.size(), 4U);
245 std::vector<CTxDestination> addrs;
246 int nRequired;
247 BOOST_CHECK(ExtractDestinations(s, whichType, addrs, nRequired));
248 BOOST_CHECK(addrs[0] == keyaddr[0]);
249 BOOST_CHECK(addrs[1] == keyaddr[1]);
250 BOOST_CHECK(nRequired == 1);
251 BOOST_CHECK(IsMine(keystore, s));
252 BOOST_CHECK(!IsMine(emptykeystore, s));
253 BOOST_CHECK(!IsMine(partialkeystore, s));
256 std::vector<valtype> solutions;
257 txnouttype whichType;
258 CScript s;
259 s << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
260 BOOST_CHECK(Solver(s, whichType, solutions));
261 BOOST_CHECK(solutions.size() == 5);
265 BOOST_AUTO_TEST_CASE(multisig_Sign)
267 // Test SignSignature() (and therefore the version of Solver() that signs transactions)
268 CBasicKeyStore keystore;
269 CKey key[4];
270 for (int i = 0; i < 4; i++)
272 key[i].MakeNewKey(true);
273 keystore.AddKey(key[i]);
276 CScript a_and_b;
277 a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
279 CScript a_or_b;
280 a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
282 CScript escrow;
283 escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
285 CMutableTransaction txFrom; // Funding transaction
286 txFrom.vout.resize(3);
287 txFrom.vout[0].scriptPubKey = a_and_b;
288 txFrom.vout[1].scriptPubKey = a_or_b;
289 txFrom.vout[2].scriptPubKey = escrow;
291 CMutableTransaction txTo[3]; // Spending transaction
292 for (int i = 0; i < 3; i++)
294 txTo[i].vin.resize(1);
295 txTo[i].vout.resize(1);
296 txTo[i].vin[0].prevout.n = i;
297 txTo[i].vin[0].prevout.hash = txFrom.GetHash();
298 txTo[i].vout[0].nValue = 1;
301 for (int i = 0; i < 3; i++)
303 BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL), strprintf("SignSignature %d", i));
308 BOOST_AUTO_TEST_SUITE_END()