Line data Source code
1 : // Copyright (c) 2017-2021 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 :
5 : #include <key.h>
6 : #include <script/script.h>
7 : #include <script/signingprovider.h>
8 : #include <script/standard.h>
9 : #include <test/util/setup_common.h>
10 :
11 : #include <boost/test/unit_test.hpp>
12 :
13 146 : BOOST_FIXTURE_TEST_SUITE(script_standard_tests, BasicTestingSetup)
14 :
15 149 : BOOST_AUTO_TEST_CASE(dest_default_is_no_dest)
16 : {
17 1 : CTxDestination dest;
18 1 : BOOST_CHECK(!IsValidDestination(dest));
19 1 : }
20 :
21 149 : BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
22 : {
23 1 : CKey keys[3];
24 3 : CPubKey pubkeys[3];
25 4 : for (int i = 0; i < 3; i++) {
26 3 : keys[i].MakeNewKey(true);
27 3 : pubkeys[i] = keys[i].GetPubKey();
28 3 : }
29 :
30 1 : CScript s;
31 1 : std::vector<std::vector<unsigned char> > solutions;
32 :
33 : // TxoutType::PUBKEY
34 1 : s.clear();
35 1 : s << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
36 1 : BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::PUBKEY);
37 1 : BOOST_CHECK_EQUAL(solutions.size(), 1U);
38 1 : BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0]));
39 :
40 : // TxoutType::PUBKEYHASH
41 1 : s.clear();
42 1 : s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
43 1 : BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::PUBKEYHASH);
44 1 : BOOST_CHECK_EQUAL(solutions.size(), 1U);
45 1 : BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));
46 :
47 : // TxoutType::SCRIPTHASH
48 1 : CScript redeemScript(s); // initialize with leftover P2PKH script
49 1 : s.clear();
50 1 : s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
51 1 : BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::SCRIPTHASH);
52 1 : BOOST_CHECK_EQUAL(solutions.size(), 1U);
53 1 : BOOST_CHECK(solutions[0] == ToByteVector(CScriptID(redeemScript)));
54 :
55 : // TxoutType::MULTISIG
56 1 : s.clear();
57 3 : s << OP_1 <<
58 2 : ToByteVector(pubkeys[0]) <<
59 2 : ToByteVector(pubkeys[1]) <<
60 1 : OP_2 << OP_CHECKMULTISIG;
61 1 : BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::MULTISIG);
62 1 : BOOST_CHECK_EQUAL(solutions.size(), 4U);
63 1 : BOOST_CHECK(solutions[0] == std::vector<unsigned char>({1}));
64 1 : BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
65 1 : BOOST_CHECK(solutions[2] == ToByteVector(pubkeys[1]));
66 1 : BOOST_CHECK(solutions[3] == std::vector<unsigned char>({2}));
67 :
68 1 : s.clear();
69 3 : s << OP_2 <<
70 2 : ToByteVector(pubkeys[0]) <<
71 2 : ToByteVector(pubkeys[1]) <<
72 2 : ToByteVector(pubkeys[2]) <<
73 1 : OP_3 << OP_CHECKMULTISIG;
74 1 : BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::MULTISIG);
75 1 : BOOST_CHECK_EQUAL(solutions.size(), 5U);
76 1 : BOOST_CHECK(solutions[0] == std::vector<unsigned char>({2}));
77 1 : BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
78 1 : BOOST_CHECK(solutions[2] == ToByteVector(pubkeys[1]));
79 1 : BOOST_CHECK(solutions[3] == ToByteVector(pubkeys[2]));
80 1 : BOOST_CHECK(solutions[4] == std::vector<unsigned char>({3}));
81 :
82 : // TxoutType::NULL_DATA
83 1 : s.clear();
84 3 : s << OP_RETURN <<
85 2 : std::vector<unsigned char>({0}) <<
86 2 : std::vector<unsigned char>({75}) <<
87 1 : std::vector<unsigned char>({255});
88 1 : BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NULL_DATA);
89 1 : BOOST_CHECK_EQUAL(solutions.size(), 0U);
90 :
91 : // TxoutType::NONSTANDARD
92 1 : s.clear();
93 1 : s << OP_9 << OP_ADD << OP_11 << OP_EQUAL;
94 1 : BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
95 1 : }
96 :
97 149 : BOOST_AUTO_TEST_CASE(script_standard_Solver_failure)
98 : {
99 1 : CKey key = GenerateRandomKey();
100 1 : CPubKey pubkey = key.GetPubKey();
101 :
102 1 : CScript s;
103 1 : std::vector<std::vector<unsigned char> > solutions;
104 :
105 : // TxoutType::PUBKEY with incorrectly sized pubkey
106 1 : s.clear();
107 1 : s << std::vector<unsigned char>(30, 0x01) << OP_CHECKSIG;
108 1 : BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
109 :
110 : // TxoutType::PUBKEYHASH with incorrectly sized key hash
111 1 : s.clear();
112 1 : s << OP_DUP << OP_HASH160 << ToByteVector(pubkey) << OP_EQUALVERIFY << OP_CHECKSIG;
113 1 : BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
114 :
115 : // TxoutType::SCRIPTHASH with incorrectly sized script hash
116 1 : s.clear();
117 1 : s << OP_HASH160 << std::vector<unsigned char>(21, 0x01) << OP_EQUAL;
118 1 : BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
119 :
120 : // TxoutType::MULTISIG 0/2
121 1 : s.clear();
122 1 : s << OP_0 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
123 1 : BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
124 :
125 : // TxoutType::MULTISIG 2/1
126 1 : s.clear();
127 1 : s << OP_2 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
128 1 : BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
129 :
130 : // TxoutType::MULTISIG n = 2 with 1 pubkey
131 1 : s.clear();
132 1 : s << OP_1 << ToByteVector(pubkey) << OP_2 << OP_CHECKMULTISIG;
133 1 : BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
134 :
135 : // TxoutType::MULTISIG n = 1 with 0 pubkeys
136 1 : s.clear();
137 1 : s << OP_1 << OP_1 << OP_CHECKMULTISIG;
138 1 : BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
139 :
140 : // TxoutType::NULL_DATA with other opcodes
141 1 : s.clear();
142 1 : s << OP_RETURN << std::vector<unsigned char>({75}) << OP_ADD;
143 1 : BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
144 1 : }
145 :
146 149 : BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
147 : {
148 1 : CKey key = GenerateRandomKey();
149 1 : CPubKey pubkey = key.GetPubKey();
150 :
151 1 : CScript s;
152 1 : CTxDestination address;
153 :
154 : // TxoutType::PUBKEY
155 1 : s.clear();
156 1 : s << ToByteVector(pubkey) << OP_CHECKSIG;
157 1 : BOOST_CHECK(ExtractDestination(s, address));
158 1 : BOOST_CHECK(std::get<PKHash>(address) == PKHash(pubkey));
159 :
160 : // TxoutType::PUBKEYHASH
161 1 : s.clear();
162 1 : s << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
163 1 : BOOST_CHECK(ExtractDestination(s, address));
164 1 : BOOST_CHECK(std::get<PKHash>(address) == PKHash(pubkey));
165 :
166 : // TxoutType::SCRIPTHASH
167 1 : CScript redeemScript(s); // initialize with leftover P2PKH script
168 1 : s.clear();
169 1 : s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
170 1 : BOOST_CHECK(ExtractDestination(s, address));
171 1 : BOOST_CHECK(std::get<ScriptHash>(address) == ScriptHash(redeemScript));
172 :
173 : // TxoutType::MULTISIG
174 1 : s.clear();
175 1 : s << OP_1 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
176 1 : BOOST_CHECK(!ExtractDestination(s, address));
177 :
178 : // TxoutType::NULL_DATA
179 1 : s.clear();
180 1 : s << OP_RETURN << std::vector<unsigned char>({75});
181 1 : BOOST_CHECK(!ExtractDestination(s, address));
182 1 : }
183 :
184 149 : BOOST_AUTO_TEST_CASE(script_standard_GetScriptFor_)
185 : {
186 1 : CKey keys[3];
187 3 : CPubKey pubkeys[3];
188 4 : for (int i = 0; i < 3; i++) {
189 3 : keys[i].MakeNewKey(true);
190 3 : pubkeys[i] = keys[i].GetPubKey();
191 3 : }
192 :
193 1 : CScript expected, result;
194 :
195 : // PKHash
196 1 : expected.clear();
197 1 : expected << OP_DUP << OP_HASH160 << ToByteVector(PKHash(pubkeys[0])) << OP_EQUALVERIFY << OP_CHECKSIG;
198 1 : result = GetScriptForDestination(PKHash(pubkeys[0]));
199 1 : BOOST_CHECK(result == expected);
200 :
201 : // ScriptHash
202 1 : CScript redeemScript(result);
203 1 : expected.clear();
204 1 : expected << OP_HASH160 << ToByteVector(ScriptHash(redeemScript)) << OP_EQUAL;
205 1 : result = GetScriptForDestination(ScriptHash(redeemScript));
206 1 : BOOST_CHECK(result == expected);
207 :
208 : // CNoDestination
209 1 : expected.clear();
210 1 : result = GetScriptForDestination(CNoDestination());
211 1 : BOOST_CHECK(result == expected);
212 :
213 : // GetScriptForRawPubKey
214 1 : expected.clear();
215 1 : expected << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
216 1 : result = GetScriptForRawPubKey(pubkeys[0]);
217 1 : BOOST_CHECK(result == expected);
218 :
219 : // GetScriptForMultisig
220 1 : expected.clear();
221 3 : expected << OP_2 <<
222 2 : ToByteVector(pubkeys[0]) <<
223 2 : ToByteVector(pubkeys[1]) <<
224 2 : ToByteVector(pubkeys[2]) <<
225 1 : OP_3 << OP_CHECKMULTISIG;
226 1 : result = GetScriptForMultisig(2, std::vector<CPubKey>(pubkeys, pubkeys + 3));
227 1 : BOOST_CHECK(result == expected);
228 1 : }
229 :
230 146 : BOOST_AUTO_TEST_SUITE_END()
|