1 // Copyright (c) 2012-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 "consensus/tx_verify.h"
9 #include "validation.h"
10 #include "policy/policy.h"
11 #include "script/script.h"
12 #include "script/script_error.h"
13 #include "script/sign.h"
14 #include "script/ismine.h"
15 #include "test/test_bitcoin.h"
19 #include <boost/test/unit_test.hpp>
22 static std::vector
<unsigned char>
23 Serialize(const CScript
& s
)
25 std::vector
<unsigned char> sSerialized(s
.begin(), s
.end());
30 Verify(const CScript
& scriptSig
, const CScript
& scriptPubKey
, bool fStrict
, ScriptError
& err
)
32 // Create dummy to/from transactions:
33 CMutableTransaction txFrom
;
34 txFrom
.vout
.resize(1);
35 txFrom
.vout
[0].scriptPubKey
= scriptPubKey
;
37 CMutableTransaction txTo
;
40 txTo
.vin
[0].prevout
.n
= 0;
41 txTo
.vin
[0].prevout
.hash
= txFrom
.GetHash();
42 txTo
.vin
[0].scriptSig
= scriptSig
;
43 txTo
.vout
[0].nValue
= 1;
45 return VerifyScript(scriptSig
, scriptPubKey
, nullptr, fStrict
? SCRIPT_VERIFY_P2SH
: SCRIPT_VERIFY_NONE
, MutableTransactionSignatureChecker(&txTo
, 0, txFrom
.vout
[0].nValue
), &err
);
49 BOOST_FIXTURE_TEST_SUITE(script_P2SH_tests
, BasicTestingSetup
)
51 BOOST_AUTO_TEST_CASE(sign
)
54 // Pay-to-script-hash looks like this:
55 // scriptSig: <sig> <sig...> <serialized_script>
56 // scriptPubKey: HASH160 <hash> EQUAL
58 // Test SignSignature() (and therefore the version of Solver() that signs transactions)
59 CBasicKeyStore keystore
;
61 for (int i
= 0; i
< 4; i
++)
63 key
[i
].MakeNewKey(true);
64 keystore
.AddKey(key
[i
]);
67 // 8 Scripts: checking all combinations of
68 // different keys, straight/P2SH, pubkey/pubkeyhash
69 CScript standardScripts
[4];
70 standardScripts
[0] << ToByteVector(key
[0].GetPubKey()) << OP_CHECKSIG
;
71 standardScripts
[1] = GetScriptForDestination(key
[1].GetPubKey().GetID());
72 standardScripts
[2] << ToByteVector(key
[1].GetPubKey()) << OP_CHECKSIG
;
73 standardScripts
[3] = GetScriptForDestination(key
[2].GetPubKey().GetID());
74 CScript evalScripts
[4];
75 for (int i
= 0; i
< 4; i
++)
77 keystore
.AddCScript(standardScripts
[i
]);
78 evalScripts
[i
] = GetScriptForDestination(CScriptID(standardScripts
[i
]));
81 CMutableTransaction txFrom
; // Funding transaction:
83 txFrom
.vout
.resize(8);
84 for (int i
= 0; i
< 4; i
++)
86 txFrom
.vout
[i
].scriptPubKey
= evalScripts
[i
];
87 txFrom
.vout
[i
].nValue
= COIN
;
88 txFrom
.vout
[i
+4].scriptPubKey
= standardScripts
[i
];
89 txFrom
.vout
[i
+4].nValue
= COIN
;
91 BOOST_CHECK(IsStandardTx(txFrom
, reason
));
93 CMutableTransaction txTo
[8]; // Spending transactions
94 for (int i
= 0; i
< 8; i
++)
96 txTo
[i
].vin
.resize(1);
97 txTo
[i
].vout
.resize(1);
98 txTo
[i
].vin
[0].prevout
.n
= i
;
99 txTo
[i
].vin
[0].prevout
.hash
= txFrom
.GetHash();
100 txTo
[i
].vout
[0].nValue
= 1;
101 BOOST_CHECK_MESSAGE(IsMine(keystore
, txFrom
.vout
[i
].scriptPubKey
), strprintf("IsMine %d", i
));
103 for (int i
= 0; i
< 8; i
++)
105 BOOST_CHECK_MESSAGE(SignSignature(keystore
, txFrom
, txTo
[i
], 0, SIGHASH_ALL
), strprintf("SignSignature %d", i
));
107 // All of the above should be OK, and the txTos have valid signatures
108 // Check to make sure signature verification fails if we use the wrong ScriptSig:
109 for (int i
= 0; i
< 8; i
++) {
110 PrecomputedTransactionData
txdata(txTo
[i
]);
111 for (int j
= 0; j
< 8; j
++)
113 CScript sigSave
= txTo
[i
].vin
[0].scriptSig
;
114 txTo
[i
].vin
[0].scriptSig
= txTo
[j
].vin
[0].scriptSig
;
115 const CTxOut
& output
= txFrom
.vout
[txTo
[i
].vin
[0].prevout
.n
];
116 bool sigOK
= CScriptCheck(output
.scriptPubKey
, output
.nValue
, txTo
[i
], 0, SCRIPT_VERIFY_P2SH
| SCRIPT_VERIFY_STRICTENC
, false, &txdata
)();
118 BOOST_CHECK_MESSAGE(sigOK
, strprintf("VerifySignature %d %d", i
, j
));
120 BOOST_CHECK_MESSAGE(!sigOK
, strprintf("VerifySignature %d %d", i
, j
));
121 txTo
[i
].vin
[0].scriptSig
= sigSave
;
126 BOOST_AUTO_TEST_CASE(norecurse
)
129 // Make sure only the outer pay-to-script-hash does the
130 // extra-validation thing:
131 CScript invalidAsScript
;
132 invalidAsScript
<< OP_INVALIDOPCODE
<< OP_INVALIDOPCODE
;
134 CScript p2sh
= GetScriptForDestination(CScriptID(invalidAsScript
));
137 scriptSig
<< Serialize(invalidAsScript
);
139 // Should not verify, because it will try to execute OP_INVALIDOPCODE
140 BOOST_CHECK(!Verify(scriptSig
, p2sh
, true, err
));
141 BOOST_CHECK_MESSAGE(err
== SCRIPT_ERR_BAD_OPCODE
, ScriptErrorString(err
));
143 // Try to recur, and verification should succeed because
144 // the inner HASH160 <> EQUAL should only check the hash:
145 CScript p2sh2
= GetScriptForDestination(CScriptID(p2sh
));
147 scriptSig2
<< Serialize(invalidAsScript
) << Serialize(p2sh
);
149 BOOST_CHECK(Verify(scriptSig2
, p2sh2
, true, err
));
150 BOOST_CHECK_MESSAGE(err
== SCRIPT_ERR_OK
, ScriptErrorString(err
));
153 BOOST_AUTO_TEST_CASE(set
)
156 // Test the CScript::Set* methods
157 CBasicKeyStore keystore
;
159 std::vector
<CPubKey
> keys
;
160 for (int i
= 0; i
< 4; i
++)
162 key
[i
].MakeNewKey(true);
163 keystore
.AddKey(key
[i
]);
164 keys
.push_back(key
[i
].GetPubKey());
168 inner
[0] = GetScriptForDestination(key
[0].GetPubKey().GetID());
169 inner
[1] = GetScriptForMultisig(2, std::vector
<CPubKey
>(keys
.begin(), keys
.begin()+2));
170 inner
[2] = GetScriptForMultisig(1, std::vector
<CPubKey
>(keys
.begin(), keys
.begin()+2));
171 inner
[3] = GetScriptForMultisig(2, std::vector
<CPubKey
>(keys
.begin(), keys
.begin()+3));
174 for (int i
= 0; i
< 4; i
++)
176 outer
[i
] = GetScriptForDestination(CScriptID(inner
[i
]));
177 keystore
.AddCScript(inner
[i
]);
180 CMutableTransaction txFrom
; // Funding transaction:
182 txFrom
.vout
.resize(4);
183 for (int i
= 0; i
< 4; i
++)
185 txFrom
.vout
[i
].scriptPubKey
= outer
[i
];
186 txFrom
.vout
[i
].nValue
= CENT
;
188 BOOST_CHECK(IsStandardTx(txFrom
, reason
));
190 CMutableTransaction txTo
[4]; // Spending transactions
191 for (int i
= 0; i
< 4; i
++)
193 txTo
[i
].vin
.resize(1);
194 txTo
[i
].vout
.resize(1);
195 txTo
[i
].vin
[0].prevout
.n
= i
;
196 txTo
[i
].vin
[0].prevout
.hash
= txFrom
.GetHash();
197 txTo
[i
].vout
[0].nValue
= 1*CENT
;
198 txTo
[i
].vout
[0].scriptPubKey
= inner
[i
];
199 BOOST_CHECK_MESSAGE(IsMine(keystore
, txFrom
.vout
[i
].scriptPubKey
), strprintf("IsMine %d", i
));
201 for (int i
= 0; i
< 4; i
++)
203 BOOST_CHECK_MESSAGE(SignSignature(keystore
, txFrom
, txTo
[i
], 0, SIGHASH_ALL
), strprintf("SignSignature %d", i
));
204 BOOST_CHECK_MESSAGE(IsStandardTx(txTo
[i
], reason
), strprintf("txTo[%d].IsStandard", i
));
208 BOOST_AUTO_TEST_CASE(is
)
210 // Test CScript::IsPayToScriptHash()
213 p2sh
<< OP_HASH160
<< ToByteVector(dummy
) << OP_EQUAL
;
214 BOOST_CHECK(p2sh
.IsPayToScriptHash());
216 // Not considered pay-to-script-hash if using one of the OP_PUSHDATA opcodes:
217 static const unsigned char direct
[] = { OP_HASH160
, 20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL
};
218 BOOST_CHECK(CScript(direct
, direct
+sizeof(direct
)).IsPayToScriptHash());
219 static const unsigned char pushdata1
[] = { OP_HASH160
, OP_PUSHDATA1
, 20, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL
};
220 BOOST_CHECK(!CScript(pushdata1
, pushdata1
+sizeof(pushdata1
)).IsPayToScriptHash());
221 static const unsigned char pushdata2
[] = { OP_HASH160
, OP_PUSHDATA2
, 20,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL
};
222 BOOST_CHECK(!CScript(pushdata2
, pushdata2
+sizeof(pushdata2
)).IsPayToScriptHash());
223 static const unsigned char pushdata4
[] = { OP_HASH160
, OP_PUSHDATA4
, 20,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, OP_EQUAL
};
224 BOOST_CHECK(!CScript(pushdata4
, pushdata4
+sizeof(pushdata4
)).IsPayToScriptHash());
227 BOOST_CHECK(!not_p2sh
.IsPayToScriptHash());
229 not_p2sh
.clear(); not_p2sh
<< OP_HASH160
<< ToByteVector(dummy
) << ToByteVector(dummy
) << OP_EQUAL
;
230 BOOST_CHECK(!not_p2sh
.IsPayToScriptHash());
232 not_p2sh
.clear(); not_p2sh
<< OP_NOP
<< ToByteVector(dummy
) << OP_EQUAL
;
233 BOOST_CHECK(!not_p2sh
.IsPayToScriptHash());
235 not_p2sh
.clear(); not_p2sh
<< OP_HASH160
<< ToByteVector(dummy
) << OP_CHECKSIG
;
236 BOOST_CHECK(!not_p2sh
.IsPayToScriptHash());
239 BOOST_AUTO_TEST_CASE(switchover
)
241 // Test switch over code
244 notValid
<< OP_11
<< OP_12
<< OP_EQUALVERIFY
;
246 scriptSig
<< Serialize(notValid
);
248 CScript fund
= GetScriptForDestination(CScriptID(notValid
));
251 // Validation should succeed under old rules (hash is correct):
252 BOOST_CHECK(Verify(scriptSig
, fund
, false, err
));
253 BOOST_CHECK_MESSAGE(err
== SCRIPT_ERR_OK
, ScriptErrorString(err
));
255 BOOST_CHECK(!Verify(scriptSig
, fund
, true, err
));
256 BOOST_CHECK_MESSAGE(err
== SCRIPT_ERR_EQUALVERIFY
, ScriptErrorString(err
));
259 BOOST_AUTO_TEST_CASE(AreInputsStandard
)
262 CCoinsView coinsDummy
;
263 CCoinsViewCache
coins(&coinsDummy
);
264 CBasicKeyStore keystore
;
266 std::vector
<CPubKey
> keys
;
267 for (int i
= 0; i
< 6; i
++)
269 key
[i
].MakeNewKey(true);
270 keystore
.AddKey(key
[i
]);
272 for (int i
= 0; i
< 3; i
++)
273 keys
.push_back(key
[i
].GetPubKey());
275 CMutableTransaction txFrom
;
276 txFrom
.vout
.resize(7);
278 // First three are standard:
279 CScript pay1
= GetScriptForDestination(key
[0].GetPubKey().GetID());
280 keystore
.AddCScript(pay1
);
281 CScript pay1of3
= GetScriptForMultisig(1, keys
);
283 txFrom
.vout
[0].scriptPubKey
= GetScriptForDestination(CScriptID(pay1
)); // P2SH (OP_CHECKSIG)
284 txFrom
.vout
[0].nValue
= 1000;
285 txFrom
.vout
[1].scriptPubKey
= pay1
; // ordinary OP_CHECKSIG
286 txFrom
.vout
[1].nValue
= 2000;
287 txFrom
.vout
[2].scriptPubKey
= pay1of3
; // ordinary OP_CHECKMULTISIG
288 txFrom
.vout
[2].nValue
= 3000;
290 // vout[3] is complicated 1-of-3 AND 2-of-3
291 // ... that is OK if wrapped in P2SH:
293 oneAndTwo
<< OP_1
<< ToByteVector(key
[0].GetPubKey()) << ToByteVector(key
[1].GetPubKey()) << ToByteVector(key
[2].GetPubKey());
294 oneAndTwo
<< OP_3
<< OP_CHECKMULTISIGVERIFY
;
295 oneAndTwo
<< OP_2
<< ToByteVector(key
[3].GetPubKey()) << ToByteVector(key
[4].GetPubKey()) << ToByteVector(key
[5].GetPubKey());
296 oneAndTwo
<< OP_3
<< OP_CHECKMULTISIG
;
297 keystore
.AddCScript(oneAndTwo
);
298 txFrom
.vout
[3].scriptPubKey
= GetScriptForDestination(CScriptID(oneAndTwo
));
299 txFrom
.vout
[3].nValue
= 4000;
301 // vout[4] is max sigops:
302 CScript fifteenSigops
; fifteenSigops
<< OP_1
;
303 for (unsigned i
= 0; i
< MAX_P2SH_SIGOPS
; i
++)
304 fifteenSigops
<< ToByteVector(key
[i
%3].GetPubKey());
305 fifteenSigops
<< OP_15
<< OP_CHECKMULTISIG
;
306 keystore
.AddCScript(fifteenSigops
);
307 txFrom
.vout
[4].scriptPubKey
= GetScriptForDestination(CScriptID(fifteenSigops
));
308 txFrom
.vout
[4].nValue
= 5000;
310 // vout[5/6] are non-standard because they exceed MAX_P2SH_SIGOPS
311 CScript sixteenSigops
; sixteenSigops
<< OP_16
<< OP_CHECKMULTISIG
;
312 keystore
.AddCScript(sixteenSigops
);
313 txFrom
.vout
[5].scriptPubKey
= GetScriptForDestination(CScriptID(fifteenSigops
));
314 txFrom
.vout
[5].nValue
= 5000;
315 CScript twentySigops
; twentySigops
<< OP_CHECKMULTISIG
;
316 keystore
.AddCScript(twentySigops
);
317 txFrom
.vout
[6].scriptPubKey
= GetScriptForDestination(CScriptID(twentySigops
));
318 txFrom
.vout
[6].nValue
= 6000;
320 AddCoins(coins
, txFrom
, 0);
322 CMutableTransaction txTo
;
324 txTo
.vout
[0].scriptPubKey
= GetScriptForDestination(key
[1].GetPubKey().GetID());
327 for (int i
= 0; i
< 5; i
++)
329 txTo
.vin
[i
].prevout
.n
= i
;
330 txTo
.vin
[i
].prevout
.hash
= txFrom
.GetHash();
332 BOOST_CHECK(SignSignature(keystore
, txFrom
, txTo
, 0, SIGHASH_ALL
));
333 BOOST_CHECK(SignSignature(keystore
, txFrom
, txTo
, 1, SIGHASH_ALL
));
334 BOOST_CHECK(SignSignature(keystore
, txFrom
, txTo
, 2, SIGHASH_ALL
));
335 // SignSignature doesn't know how to sign these. We're
336 // not testing validating signatures, so just create
337 // dummy signatures that DO include the correct P2SH scripts:
338 txTo
.vin
[3].scriptSig
<< OP_11
<< OP_11
<< std::vector
<unsigned char>(oneAndTwo
.begin(), oneAndTwo
.end());
339 txTo
.vin
[4].scriptSig
<< std::vector
<unsigned char>(fifteenSigops
.begin(), fifteenSigops
.end());
341 BOOST_CHECK(::AreInputsStandard(txTo
, coins
));
342 // 22 P2SH sigops for all inputs (1 for vin[0], 6 for vin[3], 15 for vin[4]
343 BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txTo
, coins
), 22U);
345 CMutableTransaction txToNonStd1
;
346 txToNonStd1
.vout
.resize(1);
347 txToNonStd1
.vout
[0].scriptPubKey
= GetScriptForDestination(key
[1].GetPubKey().GetID());
348 txToNonStd1
.vout
[0].nValue
= 1000;
349 txToNonStd1
.vin
.resize(1);
350 txToNonStd1
.vin
[0].prevout
.n
= 5;
351 txToNonStd1
.vin
[0].prevout
.hash
= txFrom
.GetHash();
352 txToNonStd1
.vin
[0].scriptSig
<< std::vector
<unsigned char>(sixteenSigops
.begin(), sixteenSigops
.end());
354 BOOST_CHECK(!::AreInputsStandard(txToNonStd1
, coins
));
355 BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd1
, coins
), 16U);
357 CMutableTransaction txToNonStd2
;
358 txToNonStd2
.vout
.resize(1);
359 txToNonStd2
.vout
[0].scriptPubKey
= GetScriptForDestination(key
[1].GetPubKey().GetID());
360 txToNonStd2
.vout
[0].nValue
= 1000;
361 txToNonStd2
.vin
.resize(1);
362 txToNonStd2
.vin
[0].prevout
.n
= 6;
363 txToNonStd2
.vin
[0].prevout
.hash
= txFrom
.GetHash();
364 txToNonStd2
.vin
[0].scriptSig
<< std::vector
<unsigned char>(twentySigops
.begin(), twentySigops
.end());
366 BOOST_CHECK(!::AreInputsStandard(txToNonStd2
, coins
));
367 BOOST_CHECK_EQUAL(GetP2SHSigOpCount(txToNonStd2
, coins
), 20U);
370 BOOST_AUTO_TEST_SUITE_END()