3 #include <boost/assert.hpp>
4 #include <boost/assign/list_of.hpp>
5 #include <boost/assign/list_inserter.hpp>
6 #include <boost/assign/std/vector.hpp>
7 #include <boost/test/unit_test.hpp>
8 #include <boost/foreach.hpp>
11 #include "../script.h"
12 #include "../wallet.h"
16 // Test routines internal to script.cpp:
17 extern uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
18 extern bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, int& nSigOps,
19 int nHashType, bool fStrictOpEval);
21 BOOST_AUTO_TEST_SUITE(script_op_eval_tests)
23 BOOST_AUTO_TEST_CASE(script_op_eval1)
25 // OP_EVAL looks like this:
26 // scriptSig: <sig> <sig...> <serialized_script>
27 // scriptPubKey: DUP HASH160 <hash> EQUALVERIFY EVAL
29 // Test SignSignature() (and therefore the version of Solver() that signs transactions)
30 CBasicKeyStore keystore;
32 for (int i = 0; i < 4; i++)
35 keystore.AddKey(key[i]);
38 // 8 Scripts: checking all combinations of
39 // different keys, straight/EVAL, pubkey/pubkeyhash
40 CScript standardScripts[4];
41 standardScripts[0] << key[0].GetPubKey() << OP_CHECKSIG;
42 standardScripts[1].SetBitcoinAddress(key[1].GetPubKey());
43 standardScripts[2] << key[1].GetPubKey() << OP_CHECKSIG;
44 standardScripts[3].SetBitcoinAddress(key[2].GetPubKey());
45 CScript evalScripts[4];
46 uint160 sigScriptHashes[4];
47 for (int i = 0; i < 4; i++)
49 sigScriptHashes[i] = Hash160(standardScripts[i]);
50 keystore.AddCScript(sigScriptHashes[i], standardScripts[i]);
51 evalScripts[i] << OP_DUP << OP_HASH160 << sigScriptHashes[i] << OP_EQUALVERIFY << OP_EVAL;
54 CTransaction txFrom; // Funding transaction:
55 txFrom.vout.resize(8);
56 for (int i = 0; i < 4; i++)
58 txFrom.vout[i].scriptPubKey = evalScripts[i];
59 txFrom.vout[i+4].scriptPubKey = standardScripts[i];
61 BOOST_CHECK(txFrom.IsStandard());
63 CTransaction txTo[8]; // Spending transactions
64 for (int i = 0; i < 8; 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;
71 BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i));
73 for (int i = 0; i < 8; i++)
75 BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i));
77 // All of the above should be OK, and the txTos have valid signatures
78 // Check to make sure signature verification fails if we use the wrong ScriptSig:
79 for (int i = 0; i < 8; i++)
80 for (int j = 0; j < 8; j++)
82 CScript sigSave = txTo[i].vin[0].scriptSig;
83 txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig;
85 bool sigOK = VerifySignature(txFrom, txTo[i], 0, nUnused);
87 BOOST_CHECK_MESSAGE(sigOK, strprintf("VerifySignature %d %d", i, j));
89 BOOST_CHECK_MESSAGE(!sigOK, strprintf("VerifySignature %d %d", i, j));
90 txTo[i].vin[0].scriptSig = sigSave;
94 BOOST_AUTO_TEST_CASE(script_op_eval2)
96 // Test OP_EVAL edge cases
99 recurse << OP_DUP << OP_EVAL;
101 uint160 recurseHash = Hash160(recurse);
104 fund << OP_DUP << OP_HASH160 << recurseHash << OP_EQUALVERIFY << OP_EVAL;
106 CTransaction txFrom; // Funding transaction:
107 txFrom.vout.resize(1);
108 txFrom.vout[0].scriptPubKey = fund;
110 BOOST_CHECK(txFrom.IsStandard()); // Looks like a standard transaction until you try to spend it
115 txTo.vin[0].prevout.n = 0;
116 txTo.vin[0].prevout.hash = txFrom.GetHash();
117 txTo.vin[0].scriptSig = CScript() << static_cast<std::vector<unsigned char> >(recurse);
118 txTo.vout[0].nValue = 1;
121 BOOST_CHECK(!VerifyScript(txTo.vin[0].scriptSig, txFrom.vout[0].scriptPubKey, txTo, 0, nUnused, 0, true));
122 BOOST_CHECK(!VerifySignature(txFrom, txTo, 0, nUnused, true));
125 BOOST_AUTO_TEST_CASE(script_op_eval3)
127 // Test the CScript::Set* methods
128 CBasicKeyStore keystore;
130 std::vector<CKey> keys;
131 for (int i = 0; i < 4; i++)
134 keystore.AddKey(key[i]);
135 keys.push_back(key[i]);
139 inner[0].SetBitcoinAddress(key[0].GetPubKey());
140 inner[1].SetMultisig(2, std::vector<CKey>(keys.begin(), keys.begin()+2));
141 inner[2].SetMultisig(1, std::vector<CKey>(keys.begin(), keys.begin()+2));
142 inner[3].SetMultisig(2, std::vector<CKey>(keys.begin(), keys.begin()+3));
145 for (int i = 0; i < 4; i++)
147 outer[i].SetEval(inner[i]);
148 keystore.AddCScript(Hash160(inner[i]), inner[i]);
151 CTransaction txFrom; // Funding transaction:
152 txFrom.vout.resize(4);
153 for (int i = 0; i < 4; i++)
155 txFrom.vout[i].scriptPubKey = outer[i];
157 BOOST_CHECK(txFrom.IsStandard());
159 CTransaction txTo[4]; // Spending transactions
160 for (int i = 0; i < 4; i++)
162 txTo[i].vin.resize(1);
163 txTo[i].vout.resize(1);
164 txTo[i].vin[0].prevout.n = i;
165 txTo[i].vin[0].prevout.hash = txFrom.GetHash();
166 txTo[i].vout[0].nValue = 1;
167 txTo[i].vout[0].scriptPubKey = inner[i];
168 BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i));
170 for (int i = 0; i < 4; i++)
172 BOOST_CHECK_MESSAGE(SignSignature(keystore, txFrom, txTo[i], 0), strprintf("SignSignature %d", i));
173 BOOST_CHECK_MESSAGE(txTo[i].IsStandard(), strprintf("txTo[%d].IsStandard", i));
177 BOOST_AUTO_TEST_CASE(script_op_eval_backcompat1)
179 // Check backwards-incompatibility-testing code
180 CScript returnsEleven;
181 returnsEleven << OP_11;
183 // This should validate on new clients, but will
184 // be invalid on old clients (that interpret OP_EVAL as a no-op)
185 // ... except there's a special rule that makes new clients reject
188 fund << OP_EVAL << OP_11 << OP_EQUAL;
190 CTransaction txFrom; // Funding transaction:
191 txFrom.vout.resize(1);
192 txFrom.vout[0].scriptPubKey = fund;
197 txTo.vin[0].prevout.n = 0;
198 txTo.vin[0].prevout.hash = txFrom.GetHash();
199 txTo.vin[0].scriptSig = CScript() << static_cast<std::vector<unsigned char> >(returnsEleven);
200 txTo.vout[0].nValue = 1;
203 BOOST_CHECK(!VerifyScript(txTo.vin[0].scriptSig, txFrom.vout[0].scriptPubKey, txTo, 0, nUnused, 0, true));
204 BOOST_CHECK(!VerifySignature(txFrom, txTo, 0, nUnused, true));
207 BOOST_AUTO_TEST_CASE(script_op_eval_switchover)
209 // Test OP_EVAL switchover code
211 notValid << OP_11 << OP_12 << OP_EQUALVERIFY;
213 // This will be valid under old rules, invalid under new:
217 CTransaction txFrom; // Funding transaction:
218 txFrom.vout.resize(1);
219 txFrom.vout[0].scriptPubKey = fund;
224 txTo.vin[0].prevout.n = 0;
225 txTo.vin[0].prevout.hash = txFrom.GetHash();
226 txTo.vin[0].scriptSig = CScript() << static_cast<std::vector<unsigned char> >(notValid);
227 txTo.vout[0].nValue = 1;
230 BOOST_CHECK(VerifyScript(txTo.vin[0].scriptSig, txFrom.vout[0].scriptPubKey, txTo, 0, nUnused, 0, false));
232 // Under strict op_eval switchover, it should be considered invalid:
233 BOOST_CHECK(!VerifyScript(txTo.vin[0].scriptSig, txFrom.vout[0].scriptPubKey, txTo, 0, nUnused, 0, true));
236 BOOST_AUTO_TEST_SUITE_END()