Merge #10953: [Refactor] Combine scriptPubKey and amount as CTxOut in CScriptCheck
[bitcoinplatinum.git] / src / test / multisig_tests.cpp
blobde7f3b48f5d6fb4036905b078bb8ec320d42bbc5
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 BOOST_FIXTURE_TEST_SUITE(multisig_tests, BasicTestingSetup)
21 CScript
22 sign_multisig(CScript scriptPubKey, std::vector<CKey> keys, CTransaction transaction, int whichIn)
24 uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL, 0, SIGVERSION_BASE);
26 CScript result;
27 result << OP_0; // CHECKMULTISIG bug workaround
28 for (const CKey &key : keys)
30 std::vector<unsigned char> vchSig;
31 BOOST_CHECK(key.Sign(hash, vchSig));
32 vchSig.push_back((unsigned char)SIGHASH_ALL);
33 result << vchSig;
35 return result;
38 BOOST_AUTO_TEST_CASE(multisig_verify)
40 unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
42 ScriptError err;
43 CKey key[4];
44 CAmount amount = 0;
45 for (int i = 0; i < 4; i++)
46 key[i].MakeNewKey(true);
48 CScript a_and_b;
49 a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
51 CScript a_or_b;
52 a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
54 CScript escrow;
55 escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
57 CMutableTransaction txFrom; // Funding transaction
58 txFrom.vout.resize(3);
59 txFrom.vout[0].scriptPubKey = a_and_b;
60 txFrom.vout[1].scriptPubKey = a_or_b;
61 txFrom.vout[2].scriptPubKey = escrow;
63 CMutableTransaction txTo[3]; // Spending transaction
64 for (int i = 0; i < 3; i++)
66 txTo[i].vin.resize(1);
67 txTo[i].vout.resize(1);
68 txTo[i].vin[0].prevout.n = i;
69 txTo[i].vin[0].prevout.hash = txFrom.GetHash();
70 txTo[i].vout[0].nValue = 1;
73 std::vector<CKey> keys;
74 CScript s;
76 // Test a AND b:
77 keys.assign(1,key[0]);
78 keys.push_back(key[1]);
79 s = sign_multisig(a_and_b, keys, txTo[0], 0);
80 BOOST_CHECK(VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err));
81 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
83 for (int i = 0; i < 4; i++)
85 keys.assign(1,key[i]);
86 s = sign_multisig(a_and_b, keys, txTo[0], 0);
87 BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 1: %d", i));
88 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));
90 keys.assign(1,key[1]);
91 keys.push_back(key[i]);
92 s = sign_multisig(a_and_b, keys, txTo[0], 0);
93 BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount), &err), strprintf("a&b 2: %d", i));
94 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
97 // Test a OR b:
98 for (int i = 0; i < 4; i++)
100 keys.assign(1,key[i]);
101 s = sign_multisig(a_or_b, keys, txTo[1], 0);
102 if (i == 0 || i == 1)
104 BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i));
105 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
107 else
109 BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err), strprintf("a|b: %d", i));
110 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
113 s.clear();
114 s << OP_0 << OP_1;
115 BOOST_CHECK(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount), &err));
116 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));
119 for (int i = 0; i < 4; i++)
120 for (int j = 0; j < 4; j++)
122 keys.assign(1,key[i]);
123 keys.push_back(key[j]);
124 s = sign_multisig(escrow, keys, txTo[2], 0);
125 if (i < j && i < 3 && j < 3)
127 BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 1: %d %d", i, j));
128 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
130 else
132 BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount), &err), strprintf("escrow 2: %d %d", i, j));
133 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
138 BOOST_AUTO_TEST_CASE(multisig_IsStandard)
140 CKey key[4];
141 for (int i = 0; i < 4; i++)
142 key[i].MakeNewKey(true);
144 txnouttype whichType;
146 CScript a_and_b;
147 a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
148 BOOST_CHECK(::IsStandard(a_and_b, whichType));
150 CScript a_or_b;
151 a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
152 BOOST_CHECK(::IsStandard(a_or_b, whichType));
154 CScript escrow;
155 escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
156 BOOST_CHECK(::IsStandard(escrow, whichType));
158 CScript one_of_four;
159 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;
160 BOOST_CHECK(!::IsStandard(one_of_four, whichType));
162 CScript malformed[6];
163 malformed[0] << OP_3 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
164 malformed[1] << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
165 malformed[2] << OP_0 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
166 malformed[3] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_0 << OP_CHECKMULTISIG;
167 malformed[4] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_CHECKMULTISIG;
168 malformed[5] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey());
170 for (int i = 0; i < 6; i++)
171 BOOST_CHECK(!::IsStandard(malformed[i], whichType));
174 BOOST_AUTO_TEST_CASE(multisig_Sign)
176 // Test SignSignature() (and therefore the version of Solver() that signs transactions)
177 CBasicKeyStore keystore;
178 CKey key[4];
179 for (int i = 0; i < 4; i++)
181 key[i].MakeNewKey(true);
182 keystore.AddKey(key[i]);
185 CScript a_and_b;
186 a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
188 CScript a_or_b;
189 a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
191 CScript escrow;
192 escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
194 CMutableTransaction txFrom; // Funding transaction
195 txFrom.vout.resize(3);
196 txFrom.vout[0].scriptPubKey = a_and_b;
197 txFrom.vout[1].scriptPubKey = a_or_b;
198 txFrom.vout[2].scriptPubKey = escrow;
200 CMutableTransaction txTo[3]; // Spending transaction
201 for (int i = 0; i < 3; i++)
203 txTo[i].vin.resize(1);
204 txTo[i].vout.resize(1);
205 txTo[i].vin[0].prevout.n = i;
206 txTo[i].vin[0].prevout.hash = txFrom.GetHash();
207 txTo[i].vout[0].nValue = 1;
210 for (int i = 0; i < 3; i++)
212 BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0, SIGHASH_ALL), strprintf("SignSignature %d", i));
217 BOOST_AUTO_TEST_SUITE_END()