5 #if defined(HAVE_CONFIG_H)
9 #include <test/data/script_tests.json.h>
10 #include <test/data/bip341_wallet_vectors.json.h>
30 #if defined(HAVE_CONSENSUS_LIB)
39 #include <boost/test/unit_test.hpp>
108 BOOST_ERROR(
"Unknown scripterror enumeration value, update script_errors in script_tests.cpp.");
117 BOOST_ERROR(
"Unknown scripterror \"" <<
name <<
"\" in test description");
138 for (
int i = 0; i < 16; ++i) {
140 uint32_t combined_flags{
expect ? (
flags & ~extra_flags) : (
flags | extra_flags)};
144 BOOST_CHECK_MESSAGE(
VerifyScript(scriptSig, scriptPubKey, &scriptWitness, combined_flags,
MutableTransactionSignatureChecker(&tx, 0, txCredit.
vout[0].nValue,
MissingDataBehavior::ASSERT_FAIL), &err) ==
expect, message +
strprintf(
" (with flags %x)", combined_flags));
147 #if defined(HAVE_CONSENSUS_LIB)
151 if (libconsensus_flags ==
flags) {
152 int expectedSuccessCode =
expect ? 1 : 0;
165 std::vector<unsigned char> r, s;
166 r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]);
167 s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
170 static const unsigned char order[33] = {
172 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
173 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
174 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
175 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41
177 while (s.size() < 33) {
178 s.insert(s.begin(), 0x00);
181 for (
int p = 32; p >= 1; p--) {
182 int n = (int)order[p] - s[p] - carry;
183 s[p] = (n + 256) & 0xFF;
187 if (s.size() > 1 && s[0] == 0 && s[1] < 0x80) {
193 vchSig.push_back(0x30);
194 vchSig.push_back(4 + r.size() + s.size());
195 vchSig.push_back(0x02);
196 vchSig.push_back(r.size());
197 vchSig.insert(vchSig.end(), r.begin(), r.end());
198 vchSig.push_back(0x02);
199 vchSig.push_back(s.size());
200 vchSig.insert(vchSig.end(), s.begin(), s.end());
205 const unsigned char vchKey0[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
206 const unsigned char vchKey1[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0};
207 const unsigned char vchKey2[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0};
211 CKey key0, key0C, key1, key1C, key2, key2C;
212 CPubKey pubkey0, pubkey0C, pubkey0H;
218 key0.
Set(vchKey0, vchKey0 + 32,
false);
219 key0C.
Set(vchKey0, vchKey0 + 32,
true);
223 *
const_cast<unsigned char*
>(pubkey0H.
data()) = 0x06 | (pubkey0H[64] & 1);
225 key1.
Set(vchKey1, vchKey1 + 32,
false);
226 key1C.
Set(vchKey1, vchKey1 + 32,
true);
230 key2.
Set(vchKey2, vchKey2 + 32,
false);
231 key2C.
Set(vchKey2, vchKey2 + 32,
true);
237 enum class WitnessMode {
255 bool havePush{
false};
256 std::vector<unsigned char> push;
265 spendTx.
vin[0].scriptSig << push;
270 void DoPush(
const std::vector<unsigned char>& data)
278 TestBuilder(
const CScript& script_,
const std::string& comment_, uint32_t flags_,
bool P2SH =
false, WitnessMode wm =
WitnessMode::NONE,
int witnessversion = 0,
CAmount nValue_ = 0) : script(script_), comment(comment_),
flags(flags_), nValue(nValue_)
281 if (wm == WitnessMode::PKH) {
286 }
else if (wm == WitnessMode::SH) {
287 witscript = scriptPubKey;
293 redeemscript = scriptPubKey;
309 spendTx.
vin[0].scriptSig << _op;
313 TestBuilder&
Num(
int num)
316 spendTx.
vin[0].scriptSig << num;
320 TestBuilder& Push(
const std::string& hex)
326 TestBuilder& Push(
const CScript& _script)
328 DoPush(std::vector<unsigned char>(_script.
begin(), _script.
end()));
335 std::vector<unsigned char> vchSig, r, s;
338 key.
Sign(hash, vchSig,
false, iter++);
339 if ((lenS == 33) != (vchSig[5 + vchSig[3]] == 33)) {
342 r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]);
343 s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
344 }
while (lenR != r.size() || lenS != s.size());
345 vchSig.push_back(
static_cast<unsigned char>(nHashType));
354 return PushSig(key, nHashType, lenR, lenS, sigversion, amount).AsWit();
357 TestBuilder& Push(
const CPubKey& pubkey)
359 DoPush(std::vector<unsigned char>(pubkey.
begin(), pubkey.
end()));
363 TestBuilder& PushRedeem()
365 DoPush(std::vector<unsigned char>(redeemscript.
begin(), redeemscript.
end()));
369 TestBuilder& PushWitRedeem()
371 DoPush(std::vector<unsigned char>(witscript.
begin(), witscript.
end()));
375 TestBuilder& EditPush(
unsigned int pos,
const std::string& hexin,
const std::string& hexout)
378 std::vector<unsigned char> datain =
ParseHex(hexin);
379 std::vector<unsigned char> dataout =
ParseHex(hexout);
380 assert(pos + datain.size() <= push.size());
381 BOOST_CHECK_MESSAGE(std::vector<unsigned char>(push.begin() + pos, push.begin() + pos + datain.size()) == datain, comment);
382 push.erase(push.begin() + pos, push.begin() + pos + datain.size());
383 push.insert(push.begin() + pos, dataout.begin(), dataout.end());
387 TestBuilder& DamagePush(
unsigned int pos)
390 assert(pos < push.size());
397 TestBuilder copy = *
this;
399 DoTest(creditTx->vout[0].scriptPubKey, spendTx.
vin[0].scriptSig, scriptWitness,
flags, comment, scriptError, nValue);
407 scriptWitness.
stack.push_back(push);
416 if (!scriptWitness.
stack.empty()) {
418 for (
unsigned i = 0; i < scriptWitness.
stack.size(); i++) {
422 array.push_back(wit);
425 array.push_back(
FormatScript(creditTx->vout[0].scriptPubKey));
428 array.push_back(comment);
432 std::string GetComment()
const
438 std::string JSONPrettyPrint(
const UniValue& univalue)
440 std::string
ret = univalue.
write(4);
443 while ((pos =
ret.find(
" \n", pos)) != std::string::npos) {
444 ret.replace(pos, 2,
"\n");
455 std::vector<TestBuilder> tests;
459 ).PushSig(keys.key0));
466 ).PushSig(keys.key1).Push(keys.pubkey1C));
468 "P2PKH, bad pubkey", 0
472 "P2PK anyonecanpay", 0
475 "P2PK anyonecanpay marked with normal hashtype", 0
480 ).PushSig(keys.key0).PushRedeem());
487 ).PushSig(keys.key0).Push(keys.pubkey0).PushRedeem());
489 "P2SH(P2PKH), bad sig but no VERIFY_P2SH", 0,
true
490 ).PushSig(keys.key0).DamagePush(10).PushRedeem());
497 ).Num(0).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
504 ).Num(0).PushSig(keys.key1).PushSig(keys.key2).PushRedeem());
510 "P2PK with too much R padding but no DERSIG", 0
511 ).PushSig(keys.key1,
SIGHASH_ALL, 31, 32).EditPush(1,
"43021F",
"44022000"));
516 "P2PK with too much S padding but no DERSIG", 0
517 ).PushSig(keys.key1,
SIGHASH_ALL).EditPush(1,
"44",
"45").EditPush(37,
"20",
"2100"));
522 "P2PK with too little R padding but no DERSIG", 0
523 ).PushSig(keys.key1,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220"));
528 "P2PK NOT with bad sig with too much R padding but no DERSIG", 0
529 ).PushSig(keys.key2,
SIGHASH_ALL, 31, 32).EditPush(1,
"43021F",
"44022000").DamagePush(10));
534 "P2PK NOT with too much R padding but no DERSIG", 0
541 "BIP66 example 1, without DERSIG", 0
542 ).PushSig(keys.key1,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220"));
547 "BIP66 example 2, without DERSIG", 0
553 "BIP66 example 3, without DERSIG", 0
559 "BIP66 example 4, without DERSIG", 0
565 "BIP66 example 5, without DERSIG", 0
571 "BIP66 example 6, without DERSIG", 0
577 "BIP66 example 7, without DERSIG", 0
578 ).Num(0).PushSig(keys.key1,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220").PushSig(keys.key2));
583 "BIP66 example 8, without DERSIG", 0
589 "BIP66 example 9, without DERSIG", 0
595 "BIP66 example 10, without DERSIG", 0
596 ).Num(0).Num(0).PushSig(keys.key2,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220"));
601 "BIP66 example 11, without DERSIG", 0
607 "BIP66 example 12, without DERSIG", 0
608 ).Num(0).PushSig(keys.key1,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220").Num(0));
611 ).Num(0).PushSig(keys.key1,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220").Num(0));
613 "P2PK with multi-byte hashtype, without DERSIG", 0
614 ).PushSig(keys.key2,
SIGHASH_ALL).EditPush(70,
"01",
"0101"));
620 "P2PK with high S but no LOW_S", 0
627 "P2PK with hybrid pubkey but no STRICTENC", 0
633 "P2PK NOT with hybrid pubkey but no STRICTENC", 0
639 "P2PK NOT with invalid hybrid pubkey but no STRICTENC", 0
645 "1-of-2 with the second 1 hybrid pubkey and no STRICTENC", 0
655 "P2PK with undefined hashtype but no STRICTENC", 0
656 ).PushSig(keys.key1, 5));
661 "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC", 0
662 ).PushSig(keys.key1, 5).DamagePush(10));
668 "3-of-3 with nonzero dummy but no NULLDUMMY", 0
669 ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
674 "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY", 0
675 ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10));
678 ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10).ScriptError(
SCRIPT_ERR_SIG_NULLDUMMY));
681 "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY", 0
682 ).Num(0).PushSig(keys.key1).Opcode(
OP_DUP));
687 "P2SH(P2PK) with non-push scriptSig but no P2SH or SIGPUSHONLY", 0,
true
688 ).PushSig(keys.key2).Opcode(
OP_NOP8).PushRedeem());
690 "P2PK with non-push scriptSig but with P2SH validation", 0
691 ).PushSig(keys.key2).Opcode(
OP_NOP8));
700 ).Num(0).PushSig(keys.key1).PushSig(keys.key1));
703 ).Num(11).PushSig(keys.key0));
709 ).Num(11).PushSig(keys.key0).PushRedeem());
715 ).PushSig(keys.key0).PushRedeem());
719 0, 1).PushWitSig(keys.key0).PushWitRedeem());
722 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit());
725 0, 1).PushWitSig(keys.key0).PushWitRedeem().PushRedeem());
728 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().PushRedeem());
742 "Basic P2WSH with the wrong key but no WITNESS",
SCRIPT_VERIFY_P2SH,
false, WitnessMode::SH
743 ).PushWitSig(keys.key0).PushWitRedeem());
745 "Basic P2WPKH with the wrong key but no WITNESS",
SCRIPT_VERIFY_P2SH,
false, WitnessMode::PKH
746 ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit());
748 "Basic P2SH(P2WSH) with the wrong key but no WITNESS",
SCRIPT_VERIFY_P2SH,
true, WitnessMode::SH
749 ).PushWitSig(keys.key0).PushWitRedeem().PushRedeem());
751 "Basic P2SH(P2WPKH) with the wrong key but no WITNESS",
SCRIPT_VERIFY_P2SH,
true, WitnessMode::PKH
752 ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().PushRedeem());
764 0, 0).PushWitSig(keys.key0, 1).Push(keys.pubkey0).AsWit().PushRedeem().ScriptError(
SCRIPT_ERR_EVAL_FALSE));
774 std::vector<unsigned char> hashBytes =
ToByteVector(hash);
775 hashBytes.pop_back();
776 tests.push_back(TestBuilder(
CScript() <<
OP_0 << hashBytes,
785 tests.push_back(TestBuilder(witscript,
805 0, 1).PushWitSig(keys.key0C).PushWitRedeem());
808 0, 1).PushWitSig(keys.key0C).Push(keys.pubkey0C).AsWit());
811 0, 1).PushWitSig(keys.key0C).PushWitRedeem().PushRedeem());
814 0, 1).PushWitSig(keys.key0C).Push(keys.pubkey0C).AsWit().PushRedeem());
833 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem());
836 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem());
839 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem());
842 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem());
847 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem());
850 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().PushRedeem());
859 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem());
862 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem());
872 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem());
875 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem());
878 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem());
881 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem());
884 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem());
887 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().PushRedeem());
895 std::set<std::string> tests_set;
900 for (
unsigned int idx = 0; idx < json_tests.
size(); idx++) {
901 const UniValue& tv = json_tests[idx];
902 tests_set.insert(JSONPrettyPrint(tv.
get_array()));
906 #ifdef UPDATE_JSON_TESTS
909 for (TestBuilder& test : tests) {
911 std::string str = JSONPrettyPrint(test.GetJSON());
912 #ifdef UPDATE_JSON_TESTS
913 strGen += str +
",\n";
915 if (tests_set.count(str) == 0) {
916 BOOST_CHECK_MESSAGE(
false,
"Missing auto script_valid test: " + test.GetComment());
921 #ifdef UPDATE_JSON_TESTS
923 fputs(strGen.c_str(), file);
939 for (
unsigned int idx = 0; idx < tests.
size(); idx++) {
941 std::string strTest = test.
write();
944 unsigned int pos = 0;
947 for (i = 0; i < test[pos].
size()-1; i++) {
953 if (test.
size() < 4 + pos)
955 if (test.
size() != 1) {
956 BOOST_ERROR(
"Bad test: " << strTest);
960 std::string scriptSigString = test[pos++].
get_str();
962 std::string scriptPubKeyString = test[pos++].
get_str();
967 DoTest(scriptPubKey, scriptSig, witness, scriptflags, strTest, scriptError, nValue);
975 static const unsigned char direct[] = { 1, 0x5a };
976 static const unsigned char pushdata1[] = {
OP_PUSHDATA1, 1, 0x5a };
977 static const unsigned char pushdata2[] = {
OP_PUSHDATA2, 1, 0, 0x5a };
978 static const unsigned char pushdata4[] = {
OP_PUSHDATA4, 1, 0, 0, 0, 0x5a };
981 std::vector<std::vector<unsigned char> > directStack;
985 std::vector<std::vector<unsigned char> > pushdata1Stack;
990 std::vector<std::vector<unsigned char> > pushdata2Stack;
995 std::vector<std::vector<unsigned char> > pushdata4Stack;
1000 const std::vector<unsigned char> pushdata1_trunc{
OP_PUSHDATA1, 1};
1001 const std::vector<unsigned char> pushdata2_trunc{
OP_PUSHDATA2, 1, 0};
1002 const std::vector<unsigned char> pushdata4_trunc{
OP_PUSHDATA4, 1, 0, 0, 0};
1004 std::vector<std::vector<unsigned char>> stack_ignore;
1017 std::vector<std::vector<unsigned char>> stack_ignore;
1038 for (
const CKey &key : keys)
1040 std::vector<unsigned char> vchSig;
1050 std::vector<CKey> keys;
1071 txTo12.
vout[0].nValue = 2;
1098 std::vector<CKey> keys;
1099 keys.push_back(key1); keys.push_back(key2);
1105 keys.push_back(key1); keys.push_back(key3);
1111 keys.push_back(key2); keys.push_back(key3);
1117 keys.push_back(key2); keys.push_back(key2);
1123 keys.push_back(key2); keys.push_back(key1);
1129 keys.push_back(key3); keys.push_back(key2);
1135 keys.push_back(key4); keys.push_back(key2);
1141 keys.push_back(key1); keys.push_back(key4);
1166 std::vector<CKey> keys;
1167 std::vector<CPubKey> pubkeys;
1168 for (
int i = 0; i < 3; i++)
1171 keys.push_back(key);
1178 CScript& scriptPubKey = txFrom.
vout[0].scriptPubKey;
1212 scriptSigCopy = scriptSig;
1231 std::vector<unsigned char> sig1;
1235 std::vector<unsigned char> sig2;
1239 std::vector<unsigned char> sig3;
1283 for (
int i=0; i<67000; i++) {
1286 BOOST_CHECK_MESSAGE(script.
IsPushOnly(),
"Number " << i <<
" is not pure push.");
1292 std::vector<unsigned char> data(i,
'\111');
1295 BOOST_CHECK_MESSAGE(script.
IsPushOnly(),
"Length " << i <<
" is not pure push.");
1308 static const unsigned char direct[] = { 1 };
1319 std::string derSig(
"304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090");
1320 std::string pubKey(
"03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2");
1344 std::vector<unsigned char> data =
ParseHex(str);
1345 return CScript(data.begin(), data.end());
1461 script =
ScriptFromHex(
"76a9141234567890abcdefa1a2a3a4a5a6a7a8a9a0aaab88ac");
1463 script =
ScriptFromHex(
"76a914ff34567890abcdefa1a2a3a4a5a6a7a8a9a0aaab88ac");
1481 std::vector<CTxOut> prevouts;
1482 for (
size_t i = 0; i < univalue.
size(); ++i) {
1485 prevouts.push_back(std::move(txout));
1494 for (
size_t i = 0; i < univalue.
size(); ++i) {
1495 auto bytes =
ParseHex(univalue[i].get_str());
1496 scriptwitness.
stack.push_back(std::move(bytes));
1498 return scriptwitness;
1501 #if defined(HAVE_CONSENSUS_LIB)
1506 unsigned int libconsensus_flags = 0;
1513 scriptPubKey <<
OP_1;
1529 unsigned int libconsensus_flags = 0;
1552 unsigned int libconsensus_flags = 0;
1575 unsigned int libconsensus_flags = 0;
1587 stream << 0xffffffff;
1621 unsigned int libconsensus_flags = 1 << 3;
1676 std::vector<unsigned int>
ret;
1678 for (
unsigned int i = 0; i < 128; ++i) {
1679 unsigned int flag = 0;
1693 ret.push_back(flag);
1707 const std::vector<CTxOut> prevouts =
TxOutsFromJSON(test[
"prevouts"]);
1709 size_t idx = test[
"index"].
getInt<int64_t>();
1713 if (test.
exists(
"success")) {
1714 mtx.
vin[idx].scriptSig =
ScriptFromHex(test[
"success"][
"scriptSig"].get_str());
1718 txdata.
Init(tx, std::vector<CTxOut>(prevouts));
1721 #if defined(HAVE_CONSENSUS_LIB)
1724 std::vector<UTXO> utxos;
1725 utxos.resize(prevouts.size());
1726 for (
size_t i = 0; i < prevouts.size(); i++) {
1727 utxos[i].scriptPubKey = prevouts[i].scriptPubKey.data();
1728 utxos[i].scriptPubKeySize = prevouts[i].scriptPubKey.size();
1729 utxos[i].value = prevouts[i].nValue;
1736 if (fin || ((
flags & test_flags) ==
flags)) {
1737 bool ret =
VerifyScript(tx.
vin[idx].scriptSig, prevouts[idx].scriptPubKey, &tx.
vin[idx].scriptWitness,
flags, txcheck,
nullptr);
1739 #if defined(HAVE_CONSENSUS_LIB)
1747 if (test.
exists(
"failure")) {
1748 mtx.
vin[idx].scriptSig =
ScriptFromHex(test[
"failure"][
"scriptSig"].get_str());
1752 txdata.
Init(tx, std::vector<CTxOut>(prevouts));
1755 #if defined(HAVE_CONSENSUS_LIB)
1758 std::vector<UTXO> utxos;
1759 utxos.resize(prevouts.size());
1760 for (
size_t i = 0; i < prevouts.size(); i++) {
1761 utxos[i].scriptPubKey = prevouts[i].scriptPubKey.data();
1762 utxos[i].scriptPubKeySize = prevouts[i].scriptPubKey.size();
1763 utxos[i].value = prevouts[i].nValue;
1769 if ((
flags & test_flags) == test_flags) {
1770 bool ret =
VerifyScript(tx.
vin[idx].scriptSig, prevouts[idx].scriptPubKey, &tx.
vin[idx].scriptWitness,
flags, txcheck,
nullptr);
1772 #if defined(HAVE_CONSENSUS_LIB)
1786 const char* dir = std::getenv(
"DIR_UNIT_TEST_DATA");
1787 BOOST_WARN_MESSAGE(dir !=
nullptr,
"Variable DIR_UNIT_TEST_DATA unset, skipping script_assets_test");
1788 if (dir ==
nullptr)
return;
1789 auto path =
fs::path(dir) /
"script_assets_test.json";
1791 BOOST_WARN_MESSAGE(
exists,
"File $DIR_UNIT_TEST_DATA/script_assets_test.json not found, skipping script_assets_test");
1793 std::ifstream file{path};
1795 file.seekg(0, std::ios::end);
1796 size_t length = file.tellg();
1797 file.seekg(0, std::ios::beg);
1798 std::string data(length,
'\0');
1799 file.read(data.data(), data.size());
1804 for (
size_t i = 0; i < tests.
size(); i++) {
1813 tests.
read(json_tests::bip341_wallet_vectors);
1815 const auto& vectors = tests[
"keyPathSpending"];
1817 for (
const auto& vec : vectors.getValues()) {
1818 auto txhex =
ParseHex(vec[
"given"][
"rawUnsignedTx"].get_str());
1821 std::vector<CTxOut> utxos;
1822 for (
const auto& utxo_spent : vec[
"given"][
"utxosSpent"].getValues()) {
1823 auto script_bytes =
ParseHex(utxo_spent[
"scriptPubKey"].get_str());
1824 CScript script{script_bytes.
begin(), script_bytes.end()};
1825 CAmount amount{utxo_spent[
"amountSats"].getInt<
int>()};
1826 utxos.emplace_back(amount, script);
1830 txdata.
Init(tx, std::vector<CTxOut>{utxos},
true);
1839 for (
const auto& input : vec[
"inputSpending"].getValues()) {
1840 int txinpos = input[
"given"][
"txinIndex"].getInt<
int>();
1841 int hashtype = input[
"given"][
"hashType"].getInt<
int>();
1844 auto privkey =
ParseHex(input[
"given"][
"internalPrivkey"].get_str());
1846 key.
Set(privkey.begin(), privkey.end(),
true);
1850 if (!input[
"given"][
"merkleRoot"].isNull()) {
1851 merkle_root =
uint256{
ParseHex(input[
"given"][
"merkleRoot"].get_str())};
1862 std::vector<unsigned char> signature;
1867 BOOST_CHECK_EQUAL(
HexStr(pubkey.ComputeTapTweakHash(merkle_root.
IsNull() ?
nullptr : &merkle_root)), input[
"intermediary"][
"tweak"].get_str());
1886 uint256 hash1 =
uint256S(
"8ad69ec7cf41c2a4001fd1f738bf1e505ce2277acdcaa63fe4765192497f47a7");
1887 uint256 hash2 =
uint256S(
"f224a923cd0021ab202ab139cc56802ddb92dcfc172b9212261a539df79a112a");
1888 uint256 result =
uint256S(
"a64c5b7b943315f9b805d7a7296bedfcfd08919270a1f7a1466e98f8693d8cd9");
1894 const uint8_t script[6] = {
'f',
'o',
'o',
'b',
'a',
'r'};
1895 uint256 tlc0 =
uint256S(
"edbc10c272a1215dcdcc11d605b9027b5ad6ed97cd45521203f136767b5b9c06");
1896 uint256 tlc2 =
uint256S(
"8b5c4f90ae6bf76e259dbef5d8a59df06359c391b59263741b25eca76451b27a");
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
int64_t CAmount
Amount in satoshis (Can be negative)
static CAmount AmountFromValue(const UniValue &value)
int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, const unsigned char *txTo, unsigned int txToLen, unsigned int nIn, unsigned int flags, bitcoinconsensus_error *err)
Returns 1 if the input nIn of the serialized transaction pointed to by txTo correctly spends the scri...
int bitcoinconsensus_verify_script_with_amount(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount, const unsigned char *txTo, unsigned int txToLen, unsigned int nIn, unsigned int flags, bitcoinconsensus_error *err)
int bitcoinconsensus_verify_script_with_spent_outputs(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount, const unsigned char *txTo, unsigned int txToLen, const UTXO *spentOutputs, unsigned int spentOutputsLen, unsigned int nIn, unsigned int flags, bitcoinconsensus_error *err)
enum bitcoinconsensus_error_t bitcoinconsensus_error
@ bitcoinconsensus_ERR_OK
@ bitcoinconsensus_ERR_TX_DESERIALIZE
@ bitcoinconsensus_ERR_AMOUNT_REQUIRED
@ bitcoinconsensus_ERR_TX_INDEX
@ bitcoinconsensus_ERR_INVALID_FLAGS
@ bitcoinconsensus_ERR_TX_SIZE_MISMATCH
@ bitcoinconsensus_ERR_SPENT_OUTPUTS_REQUIRED
@ bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL
@ bitcoinconsensus_SCRIPT_FLAGS_VERIFY_TAPROOT
@ bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS
A hasher class for Bitcoin's 160-bit hash (SHA-256 + RIPEMD-160).
void Finalize(Span< unsigned char > output)
CHash160 & Write(Span< const unsigned char > input)
An encapsulated private key.
bool Sign(const uint256 &hash, std::vector< unsigned char > &vchSig, bool grind=true, uint32_t test_case=0) const
Create a DER-serialized signature.
CPubKey GetPubKey() const
Compute the public key from a private key.
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
An encapsulated public key.
const unsigned char * end() const
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
const unsigned char * begin() const
const unsigned char * data() const
A hasher class for SHA-256.
void Finalize(unsigned char hash[OUTPUT_SIZE])
CSHA256 & Write(const unsigned char *data, size_t len)
Serialized script, used inside transaction inputs and outputs.
bool IsPushOnly(const_iterator pc) const
Called by IsStandardTx and P2SH/BIP62 VerifyScript (which makes it consensus-critical).
bool HasValidOps() const
Check if the script contains valid OP_CODES.
A reference to a CScript: the Hash160 of its serialization.
The basic transaction that is broadcasted on the network and contained in blocks.
const std::vector< CTxIn > vin
An output of a transaction.
Double ended buffer combining vector and stream-like interfaces.
Fillable signing provider that keeps keys in an address->secret map.
virtual bool AddCScript(const CScript &redeemScript)
virtual bool AddKey(const CKey &key)
A writer stream (for serialization) that computes a 256-bit hash.
A signature creator for transactions.
bool CreateSchnorrSig(const SigningProvider &provider, std::vector< unsigned char > &sig, const XOnlyPubKey &pubkey, const uint256 *leaf_hash, const uint256 *merkle_root, SigVersion sigversion) const override
A Span is an object that can refer to a contiguous sequence of objects.
Minimal stream for reading from an existing byte array by Span.
const std::string & get_str() const
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
bool read(std::string_view raw)
const UniValue & get_array() const
bool exists(const std::string &key) const
constexpr bool IsNull() const
constexpr unsigned char * begin()
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
void push_back(const T &value)
CScript ParseScript(const std::string &s)
std::string FormatScript(const CScript &script)
std::string ScriptToAsmStr(const CScript &script, const bool fAttemptSighashDecode=false)
Create the assembly string representation of a CScript object.
UniValue ValueFromAmount(const CAmount amount)
BOOST_AUTO_TEST_SUITE_END()
bool SignatureHashSchnorr(uint256 &hash_out, ScriptExecutionData &execdata, const T &tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData &cache, MissingDataBehavior mdb)
int FindAndDelete(CScript &script, const CScript &b)
uint256 ComputeTapleafHash(uint8_t leaf_version, Span< const unsigned char > script)
Compute the BIP341 tapleaf hash from leaf version & script.
uint256 SignatureHash(const CScript &scriptCode, const T &txTo, unsigned int nIn, int nHashType, const CAmount &amount, SigVersion sigversion, const PrecomputedTransactionData *cache)
uint256 ComputeTapbranchHash(Span< const unsigned char > a, Span< const unsigned char > b)
Compute the BIP341 tapbranch hash from two branches.
bool EvalScript(std::vector< std::vector< unsigned char > > &stack, const CScript &script, unsigned int flags, const BaseSignatureChecker &checker, SigVersion sigversion, ScriptExecutionData &execdata, ScriptError *serror)
bool VerifyScript(const CScript &scriptSig, const CScript &scriptPubKey, const CScriptWitness *witness, unsigned int flags, const BaseSignatureChecker &checker, ScriptError *serror)
const HashWriter HASHER_TAPSIGHASH
Hasher with tag "TapSighash" pre-fed to it.
@ TAPROOT
Witness v1 with 32-byte program, not BIP16 P2SH-wrapped, key path spending; see BIP 341.
@ BASE
Bare scripts and BIP16 P2SH-wrapped redeemscripts.
@ WITNESS_V0
Witness v0 (P2WPKH and P2WSH); see BIP 141.
@ SCRIPT_VERIFY_NULLDUMMY
@ SCRIPT_VERIFY_SIGPUSHONLY
@ SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY
@ SCRIPT_VERIFY_WITNESS_PUBKEYTYPE
@ SCRIPT_VERIFY_STRICTENC
@ SCRIPT_VERIFY_CLEANSTACK
@ SCRIPT_VERIFY_MINIMALDATA
@ SCRIPT_VERIFY_CHECKSEQUENCEVERIFY
@ SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM
GenericTransactionSignatureChecker< CMutableTransaction > MutableTransactionSignatureChecker
@ SIGHASH_DEFAULT
Taproot only; implied when sighash byte is missing, and equivalent to SIGHASH_ALL.
@ ASSERT_FAIL
Abort execution through assertion failure (for consensus code)
@ FAIL
Just act as if the signature was invalid.
UniValue read_json(const std::string &jsondata)
CKey GenerateRandomKey(bool compressed) noexcept
static bool exists(const path &p)
FILE * fopen(const fs::path &p, const char *mode)
std::pair< opcodetype, std::vector< unsigned char > > Opcode
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
static constexpr TransactionSerParams TX_NO_WITNESS
static constexpr TransactionSerParams TX_WITH_WITNESS
static CTransactionRef MakeTransactionRef(Tx &&txIn)
std::shared_ptr< const CTransaction > CTransactionRef
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
std::vector< unsigned char > ToByteVector(const T &in)
opcodetype
Script opcodes.
std::string ScriptErrorString(const ScriptError serror)
enum ScriptError_t ScriptError
@ SCRIPT_ERR_OP_CODESEPARATOR
@ SCRIPT_ERR_SIG_PUSHONLY
@ SCRIPT_ERR_NUMEQUALVERIFY
@ SCRIPT_ERR_DISABLED_OPCODE
@ SCRIPT_ERR_INVALID_ALTSTACK_OPERATION
@ SCRIPT_ERR_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM
@ SCRIPT_ERR_UNKNOWN_ERROR
@ SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH
@ SCRIPT_ERR_SIG_HASHTYPE
@ SCRIPT_ERR_CHECKSIGVERIFY
@ SCRIPT_ERR_WITNESS_MALLEATED_P2SH
@ SCRIPT_ERR_WITNESS_MALLEATED
@ SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS
@ SCRIPT_ERR_INVALID_STACK_OPERATION
@ SCRIPT_ERR_WITNESS_UNEXPECTED
@ SCRIPT_ERR_NEGATIVE_LOCKTIME
@ SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH
@ SCRIPT_ERR_SIG_NULLFAIL
@ SCRIPT_ERR_SIG_NULLDUMMY
@ SCRIPT_ERR_CHECKMULTISIGVERIFY
@ SCRIPT_ERR_UNSATISFIED_LOCKTIME
@ SCRIPT_ERR_WITNESS_PUBKEYTYPE
@ SCRIPT_ERR_SIG_FINDANDDELETE
@ SCRIPT_ERR_PUBKEY_COUNT
@ SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY
@ SCRIPT_ERR_UNBALANCED_CONDITIONAL
static std::string FormatScriptError(ScriptError_t err)
static void NegateSignatureS(std::vector< unsigned char > &vchSig)
static ScriptError_t ParseScriptError(const std::string &name)
static CScript ScriptFromHex(const std::string &str)
SignatureData CombineSignatures(const CTxOut &txout, const CMutableTransaction &tx, const SignatureData &scriptSig1, const SignatureData &scriptSig2)
static ScriptErrorDesc script_errors[]
static CMutableTransaction TxFromHex(const std::string &str)
void DoTest(const CScript &scriptPubKey, const CScript &scriptSig, const CScriptWitness &scriptWitness, uint32_t flags, const std::string &message, int scriptError, CAmount nValue=0)
static void AssetTest(const UniValue &test)
static CScript sign_multisig(const CScript &scriptPubKey, const std::vector< CKey > &keys, const CTransaction &transaction)
unsigned int ParseScriptFlags(std::string strFlags)
static std::vector< unsigned int > AllConsensusFlags()
BOOST_AUTO_TEST_CASE(script_build)
std::string FormatScriptFlags(unsigned int flags)
static const unsigned int gFlags
static CScriptWitness ScriptWitnessFromJSON(const UniValue &univalue)
static std::vector< CTxOut > TxOutsFromJSON(const UniValue &univalue)
static const std::vector< unsigned int > ALL_CONSENSUS_FLAGS
Precomputed list of all valid combinations of consensus-relevant script validation flags.
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
static bool GetPubKey(const SigningProvider &provider, const SignatureData &sigdata, const CKeyID &address, CPubKey &pubkey)
SignatureData DataFromTransaction(const CMutableTransaction &tx, unsigned int nIn, const CTxOut &txout)
Extract signature data from a transaction input, and insert it.
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).
std::pair< CPubKey, std::vector< unsigned char > > SigPair
const SigningProvider & DUMMY_SIGNING_PROVIDER
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
unsigned char * UCharCast(char *c)
Span(T *, EndOrSize) -> Span< T >
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
A mutable version of CTransaction.
std::vector< CTxOut > vout
std::vector< std::vector< unsigned char > > stack
std::map< CKeyID, CKey > keys
A type to represent integers in the type system.
void Init(const T &tx, std::vector< CTxOut > &&spent_outputs, bool force=false)
Initialize this PrecomputedTransactionData with transaction data.
uint256 m_sequences_single_hash
bool m_bip341_taproot_ready
Whether the 5 fields above are initialized.
uint256 m_prevouts_single_hash
uint256 m_spent_amounts_single_hash
uint256 m_spent_scripts_single_hash
uint256 m_outputs_single_hash
bool m_annex_present
Whether an annex is present.
bool m_annex_init
Whether m_annex_present and (when needed) m_annex_hash are initialized.
void MergeSignatureData(SignatureData sigdata)
std::map< CKeyID, SigPair > signatures
BIP 174 style partial signatures for the input. May contain all signatures necessary for producing a ...
CScript scriptSig
The scriptSig of an input. Contains complete signatures or the traditional partial signatures format.
static uint64_t InsecureRandBits(int bits)
CMutableTransaction BuildSpendingTransaction(const CScript &scriptSig, const CScriptWitness &scriptWitness, const CTransaction &txCredit)
CMutableTransaction BuildCreditingTransaction(const CScript &scriptPubKey, int nValue)
uint256 uint256S(const char *str)
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.