Bitcoin Core 28.0.0
P2P Digital Currency
Loading...
Searching...
No Matches
script_p2sh_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2012-2022 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
6#include <key.h>
7#include <policy/policy.h>
8#include <policy/settings.h>
9#include <script/script.h>
10#include <script/script_error.h>
11#include <script/sign.h>
14#include <validation.h>
15
16#include <vector>
17
18#include <boost/test/unit_test.hpp>
19
20// Helpers:
21static bool IsStandardTx(const CTransaction& tx, bool permit_bare_multisig, std::string& reason)
22{
23 return IsStandardTx(tx, std::nullopt, permit_bare_multisig, CFeeRate{DUST_RELAY_TX_FEE}, reason);
24}
25
26static bool IsStandardTx(const CTransaction& tx, std::string& reason)
27{
28 return IsStandardTx(tx, std::nullopt, /*permit_bare_multisig=*/true, CFeeRate{DUST_RELAY_TX_FEE}, reason) &&
29 IsStandardTx(tx, std::nullopt, /*permit_bare_multisig=*/false, CFeeRate{DUST_RELAY_TX_FEE}, reason);
30}
31
32static std::vector<unsigned char> Serialize(const CScript& s)
33{
34 std::vector<unsigned char> sSerialized(s.begin(), s.end());
35 return sSerialized;
36}
37
38static bool Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict, ScriptError& err)
39{
40 // Create dummy to/from transactions:
42 txFrom.vout.resize(1);
43 txFrom.vout[0].scriptPubKey = scriptPubKey;
44
46 txTo.vin.resize(1);
47 txTo.vout.resize(1);
48 txTo.vin[0].prevout.n = 0;
49 txTo.vin[0].prevout.hash = txFrom.GetHash();
50 txTo.vin[0].scriptSig = scriptSig;
51 txTo.vout[0].nValue = 1;
52
53 return VerifyScript(scriptSig, scriptPubKey, nullptr, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, MutableTransactionSignatureChecker(&txTo, 0, txFrom.vout[0].nValue, MissingDataBehavior::ASSERT_FAIL), &err);
54}
55
56
57BOOST_FIXTURE_TEST_SUITE(script_p2sh_tests, BasicTestingSetup)
58
60{
61 // Pay-to-script-hash looks like this:
62 // scriptSig: <sig> <sig...> <serialized_script>
63 // scriptPubKey: HASH160 <hash> EQUAL
64
65 // Test SignSignature() (and therefore the version of Solver() that signs transactions)
67 CKey key[4];
68 for (int i = 0; i < 4; i++)
69 {
70 key[i].MakeNewKey(true);
71 BOOST_CHECK(keystore.AddKey(key[i]));
72 }
73
74 // 8 Scripts: checking all combinations of
75 // different keys, straight/P2SH, pubkey/pubkeyhash
76 CScript standardScripts[4];
77 standardScripts[0] << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG;
78 standardScripts[1] = GetScriptForDestination(PKHash(key[1].GetPubKey()));
79 standardScripts[2] << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG;
80 standardScripts[3] = GetScriptForDestination(PKHash(key[2].GetPubKey()));
81 CScript evalScripts[4];
82 for (int i = 0; i < 4; i++)
83 {
84 BOOST_CHECK(keystore.AddCScript(standardScripts[i]));
85 evalScripts[i] = GetScriptForDestination(ScriptHash(standardScripts[i]));
86 }
87
88 CMutableTransaction txFrom; // Funding transaction:
89 std::string reason;
90 txFrom.vout.resize(8);
91 for (int i = 0; i < 4; i++)
92 {
93 txFrom.vout[i].scriptPubKey = evalScripts[i];
94 txFrom.vout[i].nValue = COIN;
95 txFrom.vout[i+4].scriptPubKey = standardScripts[i];
96 txFrom.vout[i+4].nValue = COIN;
97 }
98 BOOST_CHECK(IsStandardTx(CTransaction(txFrom), reason));
99
100 CMutableTransaction txTo[8]; // Spending transactions
101 for (int i = 0; i < 8; i++)
102 {
103 txTo[i].vin.resize(1);
104 txTo[i].vout.resize(1);
105 txTo[i].vin[0].prevout.n = i;
106 txTo[i].vin[0].prevout.hash = txFrom.GetHash();
107 txTo[i].vout[0].nValue = 1;
108 }
109 for (int i = 0; i < 8; i++)
110 {
111 SignatureData empty;
112 BOOST_CHECK_MESSAGE(SignSignature(keystore, CTransaction(txFrom), txTo[i], 0, SIGHASH_ALL, empty), strprintf("SignSignature %d", i));
113 }
114 // All of the above should be OK, and the txTos have valid signatures
115 // Check to make sure signature verification fails if we use the wrong ScriptSig:
117 for (int i = 0; i < 8; i++) {
118 PrecomputedTransactionData txdata(txTo[i]);
119 for (int j = 0; j < 8; j++)
120 {
121 CScript sigSave = txTo[i].vin[0].scriptSig;
122 txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig;
123 bool sigOK = CScriptCheck(txFrom.vout[txTo[i].vin[0].prevout.n], CTransaction(txTo[i]), signature_cache, 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, false, &txdata)();
124 if (i == j)
125 BOOST_CHECK_MESSAGE(sigOK, strprintf("VerifySignature %d %d", i, j));
126 else
127 BOOST_CHECK_MESSAGE(!sigOK, strprintf("VerifySignature %d %d", i, j));
128 txTo[i].vin[0].scriptSig = sigSave;
129 }
130 }
131}
132
134{
135 ScriptError err;
136 // Make sure only the outer pay-to-script-hash does the
137 // extra-validation thing:
138 CScript invalidAsScript;
139 invalidAsScript << OP_INVALIDOPCODE << OP_INVALIDOPCODE;
140
141 CScript p2sh = GetScriptForDestination(ScriptHash(invalidAsScript));
142
143 CScript scriptSig;
144 scriptSig << Serialize(invalidAsScript);
145
146 // Should not verify, because it will try to execute OP_INVALIDOPCODE
147 BOOST_CHECK(!Verify(scriptSig, p2sh, true, err));
148 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_BAD_OPCODE, ScriptErrorString(err));
149
150 // Try to recur, and verification should succeed because
151 // the inner HASH160 <> EQUAL should only check the hash:
153 CScript scriptSig2;
154 scriptSig2 << Serialize(invalidAsScript) << Serialize(p2sh);
155
156 BOOST_CHECK(Verify(scriptSig2, p2sh2, true, err));
157 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
158}
159
161{
162 // Test the CScript::Set* methods
164 CKey key[4];
165 std::vector<CPubKey> keys;
166 keys.reserve(4);
167 for (int i = 0; i < 4; i++)
168 {
169 key[i].MakeNewKey(true);
170 BOOST_CHECK(keystore.AddKey(key[i]));
171 keys.push_back(key[i].GetPubKey());
172 }
173
174 CScript inner[4];
175 inner[0] = GetScriptForDestination(PKHash(key[0].GetPubKey()));
176 inner[1] = GetScriptForMultisig(2, std::vector<CPubKey>(keys.begin(), keys.begin()+2));
177 inner[2] = GetScriptForMultisig(1, std::vector<CPubKey>(keys.begin(), keys.begin()+2));
178 inner[3] = GetScriptForMultisig(2, std::vector<CPubKey>(keys.begin(), keys.begin()+3));
179
180 CScript outer[4];
181 for (int i = 0; i < 4; i++)
182 {
183 outer[i] = GetScriptForDestination(ScriptHash(inner[i]));
184 BOOST_CHECK(keystore.AddCScript(inner[i]));
185 }
186
187 CMutableTransaction txFrom; // Funding transaction:
188 std::string reason;
189 txFrom.vout.resize(4);
190 for (int i = 0; i < 4; i++)
191 {
192 txFrom.vout[i].scriptPubKey = outer[i];
193 txFrom.vout[i].nValue = CENT;
194 }
195 BOOST_CHECK(IsStandardTx(CTransaction(txFrom), reason));
196
197 CMutableTransaction txTo[4]; // Spending transactions
198 for (int i = 0; i < 4; i++)
199 {
200 txTo[i].vin.resize(1);
201 txTo[i].vout.resize(1);
202 txTo[i].vin[0].prevout.n = i;
203 txTo[i].vin[0].prevout.hash = txFrom.GetHash();
204 txTo[i].vout[0].nValue = 1*CENT;
205 txTo[i].vout[0].scriptPubKey = inner[i];
206 }
207 for (int i = 0; i < 4; i++)
208 {
209 SignatureData empty;
210 BOOST_CHECK_MESSAGE(SignSignature(keystore, CTransaction(txFrom), txTo[i], 0, SIGHASH_ALL, empty), strprintf("SignSignature %d", i));
211 BOOST_CHECK_MESSAGE(IsStandardTx(CTransaction(txTo[i]), /*permit_bare_multisig=*/true, reason), strprintf("txTo[%d].IsStandard", i));
212 bool no_pbms_is_std = IsStandardTx(CTransaction(txTo[i]), /*permit_bare_multisig=*/false, reason);
213 BOOST_CHECK_MESSAGE((i == 0 ? no_pbms_is_std : !no_pbms_is_std), strprintf("txTo[%d].IsStandard(permbaremulti=false)", i));
214 }
215}
216
218{
219 // Test CScript::IsPayToScriptHash()
220 uint160 dummy;
221 CScript p2sh;
222 p2sh << OP_HASH160 << ToByteVector(dummy) << OP_EQUAL;
224
225 std::vector<unsigned char> direct = {OP_HASH160, 20};
226 direct.insert(direct.end(), 20, 0);
227 direct.push_back(OP_EQUAL);
228 BOOST_CHECK(CScript(direct.begin(), direct.end()).IsPayToScriptHash());
229
230 // Not considered pay-to-script-hash if using one of the OP_PUSHDATA opcodes:
231 std::vector<unsigned char> pushdata1 = {OP_HASH160, OP_PUSHDATA1, 20};
232 pushdata1.insert(pushdata1.end(), 20, 0);
233 pushdata1.push_back(OP_EQUAL);
234 BOOST_CHECK(!CScript(pushdata1.begin(), pushdata1.end()).IsPayToScriptHash());
235 std::vector<unsigned char> pushdata2 = {OP_HASH160, OP_PUSHDATA2, 20, 0};
236 pushdata2.insert(pushdata2.end(), 20, 0);
237 pushdata2.push_back(OP_EQUAL);
238 BOOST_CHECK(!CScript(pushdata2.begin(), pushdata2.end()).IsPayToScriptHash());
239 std::vector<unsigned char> pushdata4 = {OP_HASH160, OP_PUSHDATA4, 20, 0, 0, 0};
240 pushdata4.insert(pushdata4.end(), 20, 0);
241 pushdata4.push_back(OP_EQUAL);
242 BOOST_CHECK(!CScript(pushdata4.begin(), pushdata4.end()).IsPayToScriptHash());
243
244 CScript not_p2sh;
245 BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
246
247 not_p2sh.clear(); not_p2sh << OP_HASH160 << ToByteVector(dummy) << ToByteVector(dummy) << OP_EQUAL;
248 BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
249
250 not_p2sh.clear(); not_p2sh << OP_NOP << ToByteVector(dummy) << OP_EQUAL;
251 BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
252
253 not_p2sh.clear(); not_p2sh << OP_HASH160 << ToByteVector(dummy) << OP_CHECKSIG;
254 BOOST_CHECK(!not_p2sh.IsPayToScriptHash());
255}
256
258{
259 // Test switch over code
260 CScript notValid;
261 ScriptError err;
262 notValid << OP_11 << OP_12 << OP_EQUALVERIFY;
263 CScript scriptSig;
264 scriptSig << Serialize(notValid);
265
267
268
269 // Validation should succeed under old rules (hash is correct):
270 BOOST_CHECK(Verify(scriptSig, fund, false, err));
271 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
272 // Fail under new:
273 BOOST_CHECK(!Verify(scriptSig, fund, true, err));
274 BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EQUALVERIFY, ScriptErrorString(err));
275}
276
278{
279 CCoinsView coinsDummy;
280 CCoinsViewCache coins(&coinsDummy);
282 CKey key[6];
283 for (int i = 0; i < 6; i++)
284 {
285 key[i].MakeNewKey(true);
286 BOOST_CHECK(keystore.AddKey(key[i]));
287 }
288 std::vector<CPubKey> keys;
289 keys.reserve(3);
290 for (int i = 0; i < 3; i++)
291 keys.push_back(key[i].GetPubKey());
292
293 CMutableTransaction txFrom;
294 txFrom.vout.resize(7);
295
296 // First three are standard:
298 BOOST_CHECK(keystore.AddCScript(pay1));
299 CScript pay1of3 = GetScriptForMultisig(1, keys);
300
301 txFrom.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(pay1)); // P2SH (OP_CHECKSIG)
302 txFrom.vout[0].nValue = 1000;
303 txFrom.vout[1].scriptPubKey = pay1; // ordinary OP_CHECKSIG
304 txFrom.vout[1].nValue = 2000;
305 txFrom.vout[2].scriptPubKey = pay1of3; // ordinary OP_CHECKMULTISIG
306 txFrom.vout[2].nValue = 3000;
307
308 // vout[3] is complicated 1-of-3 AND 2-of-3
309 // ... that is OK if wrapped in P2SH:
310 CScript oneAndTwo;
311 oneAndTwo << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey());
312 oneAndTwo << OP_3 << OP_CHECKMULTISIGVERIFY;
313 oneAndTwo << OP_2 << ToByteVector(key[3].GetPubKey()) << ToByteVector(key[4].GetPubKey()) << ToByteVector(key[5].GetPubKey());
314 oneAndTwo << OP_3 << OP_CHECKMULTISIG;
315 BOOST_CHECK(keystore.AddCScript(oneAndTwo));
316 txFrom.vout[3].scriptPubKey = GetScriptForDestination(ScriptHash(oneAndTwo));
317 txFrom.vout[3].nValue = 4000;
318
319 // vout[4] is max sigops:
320 CScript fifteenSigops; fifteenSigops << OP_1;
321 for (unsigned i = 0; i < MAX_P2SH_SIGOPS; i++)
322 fifteenSigops << ToByteVector(key[i%3].GetPubKey());
323 fifteenSigops << OP_15 << OP_CHECKMULTISIG;
324 BOOST_CHECK(keystore.AddCScript(fifteenSigops));
325 txFrom.vout[4].scriptPubKey = GetScriptForDestination(ScriptHash(fifteenSigops));
326 txFrom.vout[4].nValue = 5000;
327
328 // vout[5/6] are non-standard because they exceed MAX_P2SH_SIGOPS
329 CScript sixteenSigops; sixteenSigops << OP_16 << OP_CHECKMULTISIG;
330 BOOST_CHECK(keystore.AddCScript(sixteenSigops));
331 txFrom.vout[5].scriptPubKey = GetScriptForDestination(ScriptHash(sixteenSigops));
332 txFrom.vout[5].nValue = 5000;
333 CScript twentySigops; twentySigops << OP_CHECKMULTISIG;
334 BOOST_CHECK(keystore.AddCScript(twentySigops));
335 txFrom.vout[6].scriptPubKey = GetScriptForDestination(ScriptHash(twentySigops));
336 txFrom.vout[6].nValue = 6000;
337
338 AddCoins(coins, CTransaction(txFrom), 0);
339
341 txTo.vout.resize(1);
342 txTo.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key[1].GetPubKey()));
343
344 txTo.vin.resize(5);
345 for (int i = 0; i < 5; i++)
346 {
347 txTo.vin[i].prevout.n = i;
348 txTo.vin[i].prevout.hash = txFrom.GetHash();
349 }
350 SignatureData empty;
351 BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL, empty));
352 SignatureData empty_b;
353 BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 1, SIGHASH_ALL, empty_b));
354 SignatureData empty_c;
355 BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 2, SIGHASH_ALL, empty_c));
356 // SignSignature doesn't know how to sign these. We're
357 // not testing validating signatures, so just create
358 // dummy signatures that DO include the correct P2SH scripts:
359 txTo.vin[3].scriptSig << OP_11 << OP_11 << std::vector<unsigned char>(oneAndTwo.begin(), oneAndTwo.end());
360 txTo.vin[4].scriptSig << std::vector<unsigned char>(fifteenSigops.begin(), fifteenSigops.end());
361
363 // 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4]
365
366 CMutableTransaction txToNonStd1;
367 txToNonStd1.vout.resize(1);
368 txToNonStd1.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key[1].GetPubKey()));
369 txToNonStd1.vout[0].nValue = 1000;
370 txToNonStd1.vin.resize(1);
371 txToNonStd1.vin[0].prevout.n = 5;
372 txToNonStd1.vin[0].prevout.hash = txFrom.GetHash();
373 txToNonStd1.vin[0].scriptSig << std::vector<unsigned char>(sixteenSigops.begin(), sixteenSigops.end());
374
375 BOOST_CHECK(!::AreInputsStandard(CTransaction(txToNonStd1), coins));
376 BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(txToNonStd1), coins), 16U);
377
378 CMutableTransaction txToNonStd2;
379 txToNonStd2.vout.resize(1);
380 txToNonStd2.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key[1].GetPubKey()));
381 txToNonStd2.vout[0].nValue = 1000;
382 txToNonStd2.vin.resize(1);
383 txToNonStd2.vin[0].prevout.n = 6;
384 txToNonStd2.vin[0].prevout.hash = txFrom.GetHash();
385 txToNonStd2.vin[0].scriptSig << std::vector<unsigned char>(twentySigops.begin(), twentySigops.end());
386
387 BOOST_CHECK(!::AreInputsStandard(CTransaction(txToNonStd2), coins));
388 BOOST_CHECK_EQUAL(GetP2SHSigOpCount(CTransaction(txToNonStd2), coins), 20U);
389}
390
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
static constexpr CAmount COIN
The amount of satoshis in one BTC.
Definition amount.h:15
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition coins.h:360
Abstract view on the open txout dataset.
Definition coins.h:304
Fee rate in satoshis per kilovirtualbyte: CAmount / kvB.
Definition feerate.h:33
An encapsulated private key.
Definition key.h:35
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition key.cpp:161
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition key.cpp:182
Closure representing one script verification Note that this stores references to the spending transac...
Definition validation.h:336
Serialized script, used inside transaction inputs and outputs.
Definition script.h:414
bool IsPayToScriptHash() const
Definition script.cpp:224
void clear()
Definition script.h:565
The basic transaction that is broadcasted on the network and contained in blocks.
Fillable signing provider that keeps keys in an address->secret map.
virtual bool AddCScript(const CScript &redeemScript)
virtual bool AddKey(const CKey &key)
Valid signature cache, to avoid doing expensive ECDSA signature checking twice for every transaction ...
Definition sigcache.h:39
iterator begin()
Definition prevector.h:304
iterator end()
Definition prevector.h:306
160-bit opaque blob.
Definition uint256.h:166
void AddCoins(CCoinsViewCache &cache, const CTransaction &tx, int nHeight, bool check_for_overwrite)
Utility function to add all of a transaction's outputs to a cache.
Definition coins.cpp:121
BOOST_AUTO_TEST_SUITE_END()
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
GenericTransactionSignatureChecker< CMutableTransaction > MutableTransactionSignatureChecker
@ SCRIPT_VERIFY_P2SH
Definition interpreter.h:49
@ SCRIPT_VERIFY_STRICTENC
Definition interpreter.h:54
@ SCRIPT_VERIFY_NONE
Definition interpreter.h:46
@ SIGHASH_ALL
Definition interpreter.h:30
@ ASSERT_FAIL
Abort execution through assertion failure (for consensus code)
#define BOOST_CHECK_EQUAL(v1, v2)
Definition object.cpp:18
#define BOOST_CHECK(expr)
Definition object.cpp:17
bool AreInputsStandard(const CTransaction &tx, const CCoinsViewCache &mapInputs)
Check transaction inputs to mitigate two potential denial-of-service attacks:
Definition policy.cpp:177
static constexpr unsigned int DUST_RELAY_TX_FEE
Min feerate for defining dust.
Definition policy.h:55
static constexpr unsigned int MAX_P2SH_SIGOPS
Maximum number of signature check operations in an IsStandard() P2SH script.
Definition policy.h:31
@ OP_2
Definition script.h:84
@ OP_PUSHDATA4
Definition script.h:79
@ OP_CHECKMULTISIG
Definition script.h:191
@ OP_CHECKSIG
Definition script.h:189
@ OP_16
Definition script.h:98
@ OP_INVALIDOPCODE
Definition script.h:211
@ OP_EQUAL
Definition script.h:145
@ OP_NOP
Definition script.h:101
@ OP_HASH160
Definition script.h:186
@ OP_1
Definition script.h:82
@ OP_12
Definition script.h:94
@ OP_CHECKMULTISIGVERIFY
Definition script.h:192
@ OP_15
Definition script.h:97
@ OP_PUSHDATA1
Definition script.h:77
@ OP_3
Definition script.h:85
@ OP_11
Definition script.h:93
@ OP_PUSHDATA2
Definition script.h:78
@ OP_EQUALVERIFY
Definition script.h:146
std::vector< unsigned char > ToByteVector(const T &in)
Definition script.h:66
std::string ScriptErrorString(const ScriptError serror)
enum ScriptError_t ScriptError
@ SCRIPT_ERR_EQUALVERIFY
@ SCRIPT_ERR_OK
@ SCRIPT_ERR_BAD_OPCODE
static bool Verify(const CScript &scriptSig, const CScript &scriptPubKey, bool fStrict, ScriptError &err)
BOOST_AUTO_TEST_CASE(sign)
static std::vector< unsigned char > Serialize(const CScript &s)
static bool IsStandardTx(const CTransaction &tx, bool permit_bare_multisig, std::string &reason)
static constexpr CAmount CENT
static constexpr size_t DEFAULT_SIGNATURE_CACHE_BYTES
Definition sigcache.h:29
static bool GetPubKey(const SigningProvider &provider, const SignatureData &sigdata, const CKeyID &address, CPubKey &pubkey)
Definition sign.cpp:109
bool SignSignature(const SigningProvider &provider, const CScript &fromPubKey, CMutableTransaction &txTo, unsigned int nIn, const CAmount &amount, int nHashType, SignatureData &sig_data)
Produce a satisfying script (scriptSig or witness).
Definition sign.cpp:697
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
Definition solver.cpp:218
Basic testing setup.
A mutable version of CTransaction.
std::vector< CTxOut > vout
Txid GetHash() const
Compute the hash of this CMutableTransaction.
std::vector< CTxIn > vin
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
unsigned int GetP2SHSigOpCount(const CTransaction &tx, const CCoinsViewCache &inputs)
Count ECDSA signature operations in pay-to-script-hash inputs.