5 #include <test/data/script_tests.json.h>
6 #include <test/data/bip341_wallet_vectors.json.h>
24 #if defined(HAVE_CONSENSUS_LIB)
33 #include <boost/test/unit_test.hpp>
102 BOOST_ERROR(
"Unknown scripterror enumeration value, update script_errors in script_tests.cpp.");
111 BOOST_ERROR(
"Unknown scripterror \"" <<
name <<
"\" in test description");
132 for (
int i = 0; i < 16; ++i) {
134 uint32_t combined_flags{
expect ? (
flags & ~extra_flags) : (
flags | extra_flags)};
138 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));
141 #if defined(HAVE_CONSENSUS_LIB)
145 if (libconsensus_flags ==
flags) {
146 int expectedSuccessCode =
expect ? 1 : 0;
159 std::vector<unsigned char> r, s;
160 r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]);
161 s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
164 static const unsigned char order[33] = {
166 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
167 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
168 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
169 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41
171 while (s.size() < 33) {
172 s.insert(s.begin(), 0x00);
175 for (
int p = 32; p >= 1; p--) {
176 int n = (int)order[p] - s[p] - carry;
177 s[p] = (n + 256) & 0xFF;
181 if (s.size() > 1 && s[0] == 0 && s[1] < 0x80) {
187 vchSig.push_back(0x30);
188 vchSig.push_back(4 + r.size() + s.size());
189 vchSig.push_back(0x02);
190 vchSig.push_back(r.size());
191 vchSig.insert(vchSig.end(), r.begin(), r.end());
192 vchSig.push_back(0x02);
193 vchSig.push_back(s.size());
194 vchSig.insert(vchSig.end(), s.begin(), s.end());
199 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};
200 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};
201 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};
205 CKey key0, key0C, key1, key1C, key2, key2C;
206 CPubKey pubkey0, pubkey0C, pubkey0H;
212 key0.
Set(vchKey0, vchKey0 + 32,
false);
213 key0C.
Set(vchKey0, vchKey0 + 32,
true);
217 *
const_cast<unsigned char*
>(pubkey0H.
data()) = 0x06 | (pubkey0H[64] & 1);
219 key1.
Set(vchKey1, vchKey1 + 32,
false);
220 key1C.
Set(vchKey1, vchKey1 + 32,
true);
224 key2.
Set(vchKey2, vchKey2 + 32,
false);
225 key2C.
Set(vchKey2, vchKey2 + 32,
true);
231 enum class WitnessMode {
249 bool havePush{
false};
250 std::vector<unsigned char> push;
259 spendTx.
vin[0].scriptSig << push;
264 void DoPush(
const std::vector<unsigned char>& data)
272 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_)
275 if (wm == WitnessMode::PKH) {
280 }
else if (wm == WitnessMode::SH) {
281 witscript = scriptPubKey;
287 redeemscript = scriptPubKey;
303 spendTx.
vin[0].scriptSig << _op;
307 TestBuilder&
Num(
int num)
310 spendTx.
vin[0].scriptSig << num;
314 TestBuilder& Push(
const std::string& hex)
320 TestBuilder& Push(
const CScript& _script)
322 DoPush(std::vector<unsigned char>(_script.
begin(), _script.
end()));
329 std::vector<unsigned char> vchSig, r, s;
332 key.
Sign(hash, vchSig,
false, iter++);
333 if ((lenS == 33) != (vchSig[5 + vchSig[3]] == 33)) {
336 r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]);
337 s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
338 }
while (lenR != r.size() || lenS != s.size());
339 vchSig.push_back(
static_cast<unsigned char>(nHashType));
348 return PushSig(key, nHashType, lenR, lenS, sigversion, amount).AsWit();
351 TestBuilder& Push(
const CPubKey& pubkey)
353 DoPush(std::vector<unsigned char>(pubkey.
begin(), pubkey.
end()));
357 TestBuilder& PushRedeem()
359 DoPush(std::vector<unsigned char>(redeemscript.
begin(), redeemscript.
end()));
363 TestBuilder& PushWitRedeem()
365 DoPush(std::vector<unsigned char>(witscript.
begin(), witscript.
end()));
369 TestBuilder& EditPush(
unsigned int pos,
const std::string& hexin,
const std::string& hexout)
372 std::vector<unsigned char> datain =
ParseHex(hexin);
373 std::vector<unsigned char> dataout =
ParseHex(hexout);
374 assert(pos + datain.size() <= push.size());
375 BOOST_CHECK_MESSAGE(std::vector<unsigned char>(push.begin() + pos, push.begin() + pos + datain.size()) == datain, comment);
376 push.erase(push.begin() + pos, push.begin() + pos + datain.size());
377 push.insert(push.begin() + pos, dataout.begin(), dataout.end());
381 TestBuilder& DamagePush(
unsigned int pos)
384 assert(pos < push.size());
391 TestBuilder copy = *
this;
393 DoTest(creditTx->vout[0].scriptPubKey, spendTx.
vin[0].scriptSig, scriptWitness,
flags, comment, scriptError, nValue);
401 scriptWitness.
stack.push_back(push);
410 if (!scriptWitness.
stack.empty()) {
412 for (
unsigned i = 0; i < scriptWitness.
stack.size(); i++) {
416 array.push_back(wit);
419 array.push_back(
FormatScript(creditTx->vout[0].scriptPubKey));
422 array.push_back(comment);
426 std::string GetComment()
const
432 std::string JSONPrettyPrint(
const UniValue& univalue)
434 std::string
ret = univalue.
write(4);
437 while ((pos =
ret.find(
" \n", pos)) != std::string::npos) {
438 ret.replace(pos, 2,
"\n");
449 std::vector<TestBuilder> tests;
453 ).PushSig(keys.key0));
460 ).PushSig(keys.key1).Push(keys.pubkey1C));
462 "P2PKH, bad pubkey", 0
466 "P2PK anyonecanpay", 0
469 "P2PK anyonecanpay marked with normal hashtype", 0
474 ).PushSig(keys.key0).PushRedeem());
481 ).PushSig(keys.key0).Push(keys.pubkey0).PushRedeem());
483 "P2SH(P2PKH), bad sig but no VERIFY_P2SH", 0,
true
484 ).PushSig(keys.key0).DamagePush(10).PushRedeem());
491 ).Num(0).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
498 ).Num(0).PushSig(keys.key1).PushSig(keys.key2).PushRedeem());
504 "P2PK with too much R padding but no DERSIG", 0
505 ).PushSig(keys.key1,
SIGHASH_ALL, 31, 32).EditPush(1,
"43021F",
"44022000"));
510 "P2PK with too much S padding but no DERSIG", 0
511 ).PushSig(keys.key1,
SIGHASH_ALL).EditPush(1,
"44",
"45").EditPush(37,
"20",
"2100"));
516 "P2PK with too little R padding but no DERSIG", 0
517 ).PushSig(keys.key1,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220"));
522 "P2PK NOT with bad sig with too much R padding but no DERSIG", 0
523 ).PushSig(keys.key2,
SIGHASH_ALL, 31, 32).EditPush(1,
"43021F",
"44022000").DamagePush(10));
528 "P2PK NOT with too much R padding but no DERSIG", 0
535 "BIP66 example 1, without DERSIG", 0
536 ).PushSig(keys.key1,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220"));
541 "BIP66 example 2, without DERSIG", 0
547 "BIP66 example 3, without DERSIG", 0
553 "BIP66 example 4, without DERSIG", 0
559 "BIP66 example 5, without DERSIG", 0
565 "BIP66 example 6, without DERSIG", 0
571 "BIP66 example 7, without DERSIG", 0
572 ).Num(0).PushSig(keys.key1,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220").PushSig(keys.key2));
577 "BIP66 example 8, without DERSIG", 0
583 "BIP66 example 9, without DERSIG", 0
589 "BIP66 example 10, without DERSIG", 0
590 ).Num(0).Num(0).PushSig(keys.key2,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220"));
595 "BIP66 example 11, without DERSIG", 0
601 "BIP66 example 12, without DERSIG", 0
602 ).Num(0).PushSig(keys.key1,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220").Num(0));
605 ).Num(0).PushSig(keys.key1,
SIGHASH_ALL, 33, 32).EditPush(1,
"45022100",
"440220").Num(0));
607 "P2PK with multi-byte hashtype, without DERSIG", 0
608 ).PushSig(keys.key2,
SIGHASH_ALL).EditPush(70,
"01",
"0101"));
614 "P2PK with high S but no LOW_S", 0
621 "P2PK with hybrid pubkey but no STRICTENC", 0
627 "P2PK NOT with hybrid pubkey but no STRICTENC", 0
633 "P2PK NOT with invalid hybrid pubkey but no STRICTENC", 0
639 "1-of-2 with the second 1 hybrid pubkey and no STRICTENC", 0
649 "P2PK with undefined hashtype but no STRICTENC", 0
650 ).PushSig(keys.key1, 5));
655 "P2PK NOT with invalid sig and undefined hashtype but no STRICTENC", 0
656 ).PushSig(keys.key1, 5).DamagePush(10));
662 "3-of-3 with nonzero dummy but no NULLDUMMY", 0
663 ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2));
668 "3-of-3 NOT with invalid sig and nonzero dummy but no NULLDUMMY", 0
669 ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10));
672 ).Num(1).PushSig(keys.key0).PushSig(keys.key1).PushSig(keys.key2).DamagePush(10).ScriptError(
SCRIPT_ERR_SIG_NULLDUMMY));
675 "2-of-2 with two identical keys and sigs pushed using OP_DUP but no SIGPUSHONLY", 0
676 ).Num(0).PushSig(keys.key1).Opcode(
OP_DUP));
681 "P2SH(P2PK) with non-push scriptSig but no P2SH or SIGPUSHONLY", 0,
true
682 ).PushSig(keys.key2).Opcode(
OP_NOP8).PushRedeem());
684 "P2PK with non-push scriptSig but with P2SH validation", 0
685 ).PushSig(keys.key2).Opcode(
OP_NOP8));
694 ).Num(0).PushSig(keys.key1).PushSig(keys.key1));
697 ).Num(11).PushSig(keys.key0));
703 ).Num(11).PushSig(keys.key0).PushRedeem());
709 ).PushSig(keys.key0).PushRedeem());
713 0, 1).PushWitSig(keys.key0).PushWitRedeem());
716 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit());
719 0, 1).PushWitSig(keys.key0).PushWitRedeem().PushRedeem());
722 0, 1).PushWitSig(keys.key0).Push(keys.pubkey0).AsWit().PushRedeem());
736 "Basic P2WSH with the wrong key but no WITNESS",
SCRIPT_VERIFY_P2SH,
false, WitnessMode::SH
737 ).PushWitSig(keys.key0).PushWitRedeem());
739 "Basic P2WPKH with the wrong key but no WITNESS",
SCRIPT_VERIFY_P2SH,
false, WitnessMode::PKH
740 ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit());
742 "Basic P2SH(P2WSH) with the wrong key but no WITNESS",
SCRIPT_VERIFY_P2SH,
true, WitnessMode::SH
743 ).PushWitSig(keys.key0).PushWitRedeem().PushRedeem());
745 "Basic P2SH(P2WPKH) with the wrong key but no WITNESS",
SCRIPT_VERIFY_P2SH,
true, WitnessMode::PKH
746 ).PushWitSig(keys.key0).Push(keys.pubkey1).AsWit().PushRedeem());
758 0, 0).PushWitSig(keys.key0, 1).Push(keys.pubkey0).AsWit().PushRedeem().ScriptError(
SCRIPT_ERR_EVAL_FALSE));
768 std::vector<unsigned char> hashBytes =
ToByteVector(hash);
769 hashBytes.pop_back();
770 tests.push_back(TestBuilder(
CScript() <<
OP_0 << hashBytes,
779 tests.push_back(TestBuilder(witscript,
799 0, 1).PushWitSig(keys.key0C).PushWitRedeem());
802 0, 1).PushWitSig(keys.key0C).Push(keys.pubkey0C).AsWit());
805 0, 1).PushWitSig(keys.key0C).PushWitRedeem().PushRedeem());
808 0, 1).PushWitSig(keys.key0C).Push(keys.pubkey0C).AsWit().PushRedeem());
827 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem());
830 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem().PushRedeem());
833 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem());
836 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem());
841 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem());
844 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key0).PushWitRedeem().PushRedeem());
853 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem());
856 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key1C).PushWitRedeem().PushRedeem());
866 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key0C).PushWitRedeem());
869 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key0C).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.key1).PushWitRedeem());
881 0, 1).Push(
CScript()).AsWit().PushWitSig(keys.key1).PushWitRedeem().PushRedeem());
889 std::set<std::string> tests_set;
892 UniValue json_tests =
read_json(std::string(json_tests::script_tests, json_tests::script_tests +
sizeof(json_tests::script_tests)));
894 for (
unsigned int idx = 0; idx < json_tests.
size(); idx++) {
895 const UniValue& tv = json_tests[idx];
896 tests_set.insert(JSONPrettyPrint(tv.
get_array()));
900 #ifdef UPDATE_JSON_TESTS
903 for (TestBuilder& test : tests) {
905 std::string str = JSONPrettyPrint(test.GetJSON());
906 #ifdef UPDATE_JSON_TESTS
907 strGen += str +
",\n";
909 if (tests_set.count(str) == 0) {
910 BOOST_CHECK_MESSAGE(
false,
"Missing auto script_valid test: " + test.GetComment());
915 #ifdef UPDATE_JSON_TESTS
917 fputs(strGen.c_str(), file);
931 UniValue tests =
read_json(std::string(json_tests::script_tests, json_tests::script_tests +
sizeof(json_tests::script_tests)));
933 for (
unsigned int idx = 0; idx < tests.
size(); idx++) {
935 std::string strTest = test.
write();
938 unsigned int pos = 0;
941 for (i = 0; i < test[pos].
size()-1; i++) {
947 if (test.
size() < 4 + pos)
949 if (test.
size() != 1) {
950 BOOST_ERROR(
"Bad test: " << strTest);
954 std::string scriptSigString = test[pos++].
get_str();
956 std::string scriptPubKeyString = test[pos++].
get_str();
961 DoTest(scriptPubKey, scriptSig, witness, scriptflags, strTest, scriptError, nValue);
969 static const unsigned char direct[] = { 1, 0x5a };
970 static const unsigned char pushdata1[] = {
OP_PUSHDATA1, 1, 0x5a };
971 static const unsigned char pushdata2[] = {
OP_PUSHDATA2, 1, 0, 0x5a };
972 static const unsigned char pushdata4[] = {
OP_PUSHDATA4, 1, 0, 0, 0, 0x5a };
975 std::vector<std::vector<unsigned char> > directStack;
979 std::vector<std::vector<unsigned char> > pushdata1Stack;
984 std::vector<std::vector<unsigned char> > pushdata2Stack;
989 std::vector<std::vector<unsigned char> > pushdata4Stack;
994 const std::vector<unsigned char> pushdata1_trunc{
OP_PUSHDATA1, 1};
995 const std::vector<unsigned char> pushdata2_trunc{
OP_PUSHDATA2, 1, 0};
996 const std::vector<unsigned char> pushdata4_trunc{
OP_PUSHDATA4, 1, 0, 0, 0};
998 std::vector<std::vector<unsigned char>> stack_ignore;
1011 std::vector<std::vector<unsigned char>> stack_ignore;
1032 for (
const CKey &key : keys)
1034 std::vector<unsigned char> vchSig;
1044 std::vector<CKey> keys;
1052 CKey key1, key2, key3;
1066 txTo12.
vout[0].nValue = 2;
1082 CKey key1, key2, key3, key4;
1094 std::vector<CKey> keys;
1095 keys.push_back(key1); keys.push_back(key2);
1101 keys.push_back(key1); keys.push_back(key3);
1107 keys.push_back(key2); keys.push_back(key3);
1113 keys.push_back(key2); keys.push_back(key2);
1119 keys.push_back(key2); keys.push_back(key1);
1125 keys.push_back(key3); keys.push_back(key2);
1131 keys.push_back(key4); keys.push_back(key2);
1137 keys.push_back(key1); keys.push_back(key4);
1162 std::vector<CKey> keys;
1163 std::vector<CPubKey> pubkeys;
1164 for (
int i = 0; i < 3; i++)
1168 keys.push_back(key);
1175 CScript& scriptPubKey = txFrom.
vout[0].scriptPubKey;
1206 scriptSigCopy = scriptSig;
1223 std::vector<unsigned char> sig1;
1227 std::vector<unsigned char> sig2;
1231 std::vector<unsigned char> sig3;
1275 for (
int i=0; i<67000; i++) {
1278 BOOST_CHECK_MESSAGE(script.
IsPushOnly(),
"Number " << i <<
" is not pure push.");
1284 std::vector<unsigned char> data(i,
'\111');
1287 BOOST_CHECK_MESSAGE(script.
IsPushOnly(),
"Length " << i <<
" is not pure push.");
1300 static const unsigned char direct[] = { 1 };
1311 std::string derSig(
"304502207fa7a6d1e0ee81132a269ad84e68d695483745cde8b541e3bf630749894e342a022100c1f7ab20e13e22fb95281a870f3dcf38d782e53023ee313d741ad0cfbc0c5090");
1312 std::string pubKey(
"03b0da749730dc9b4b1f4a14d6902877a92541f5368778853d9c4a0cb7802dcfb2");
1336 std::vector<unsigned char> data =
ParseHex(str);
1337 return CScript(data.begin(), data.end());
1453 script =
ScriptFromHex(
"76a9141234567890abcdefa1a2a3a4a5a6a7a8a9a0aaab88ac");
1455 script =
ScriptFromHex(
"76a914ff34567890abcdefa1a2a3a4a5a6a7a8a9a0aaab88ac");
1473 std::vector<CTxOut> prevouts;
1474 for (
size_t i = 0; i < univalue.
size(); ++i) {
1477 prevouts.push_back(std::move(txout));
1486 for (
size_t i = 0; i < univalue.
size(); ++i) {
1487 auto bytes =
ParseHex(univalue[i].get_str());
1488 scriptwitness.
stack.push_back(std::move(bytes));
1490 return scriptwitness;
1493 #if defined(HAVE_CONSENSUS_LIB)
1498 unsigned int libconsensus_flags = 0;
1505 scriptPubKey <<
OP_1;
1521 unsigned int libconsensus_flags = 0;
1544 unsigned int libconsensus_flags = 0;
1567 unsigned int libconsensus_flags = 0;
1579 stream << 0xffffffff;
1613 unsigned int libconsensus_flags = 1 << 3;
1637 std::vector<unsigned int>
ret;
1639 for (
unsigned int i = 0; i < 128; ++i) {
1640 unsigned int flag = 0;
1654 ret.push_back(flag);
1668 const std::vector<CTxOut> prevouts =
TxOutsFromJSON(test[
"prevouts"]);
1670 size_t idx = test[
"index"].
getInt<int64_t>();
1674 if (test.
exists(
"success")) {
1675 mtx.
vin[idx].scriptSig =
ScriptFromHex(test[
"success"][
"scriptSig"].get_str());
1679 txdata.
Init(tx, std::vector<CTxOut>(prevouts));
1684 if (fin || ((
flags & test_flags) ==
flags)) {
1685 bool ret =
VerifyScript(tx.
vin[idx].scriptSig, prevouts[idx].scriptPubKey, &tx.
vin[idx].scriptWitness,
flags, txcheck,
nullptr);
1691 if (test.
exists(
"failure")) {
1692 mtx.
vin[idx].scriptSig =
ScriptFromHex(test[
"failure"][
"scriptSig"].get_str());
1696 txdata.
Init(tx, std::vector<CTxOut>(prevouts));
1700 if ((
flags & test_flags) == test_flags) {
1701 bool ret =
VerifyScript(tx.
vin[idx].scriptSig, prevouts[idx].scriptPubKey, &tx.
vin[idx].scriptWitness,
flags, txcheck,
nullptr);
1713 const char* dir = std::getenv(
"DIR_UNIT_TEST_DATA");
1714 BOOST_WARN_MESSAGE(dir !=
nullptr,
"Variable DIR_UNIT_TEST_DATA unset, skipping script_assets_test");
1715 if (dir ==
nullptr)
return;
1716 auto path =
fs::path(dir) /
"script_assets_test.json";
1718 BOOST_WARN_MESSAGE(
exists,
"File $DIR_UNIT_TEST_DATA/script_assets_test.json not found, skipping script_assets_test");
1720 std::ifstream file{path};
1722 file.seekg(0, std::ios::end);
1723 size_t length = file.tellg();
1724 file.seekg(0, std::ios::beg);
1725 std::string data(length,
'\0');
1726 file.read(data.data(), data.size());
1731 for (
size_t i = 0; i < tests.
size(); i++) {
1740 tests.
read((
const char*)json_tests::bip341_wallet_vectors,
sizeof(json_tests::bip341_wallet_vectors));
1742 const auto& vectors = tests[
"keyPathSpending"];
1744 for (
const auto& vec : vectors.getValues()) {
1745 auto txhex =
ParseHex(vec[
"given"][
"rawUnsignedTx"].get_str());
1748 std::vector<CTxOut> utxos;
1749 for (
const auto& utxo_spent : vec[
"given"][
"utxosSpent"].getValues()) {
1750 auto script_bytes =
ParseHex(utxo_spent[
"scriptPubKey"].get_str());
1751 CScript script{script_bytes.
begin(), script_bytes.end()};
1752 CAmount amount{utxo_spent[
"amountSats"].getInt<
int>()};
1753 utxos.emplace_back(amount, script);
1757 txdata.
Init(tx, std::vector<CTxOut>{utxos},
true);
1766 for (
const auto& input : vec[
"inputSpending"].getValues()) {
1767 int txinpos = input[
"given"][
"txinIndex"].getInt<
int>();
1768 int hashtype = input[
"given"][
"hashType"].getInt<
int>();
1771 auto privkey =
ParseHex(input[
"given"][
"internalPrivkey"].get_str());
1773 key.
Set(privkey.begin(), privkey.end(),
true);
1777 if (!input[
"given"][
"merkleRoot"].isNull()) {
1778 merkle_root =
uint256{
ParseHex(input[
"given"][
"merkleRoot"].get_str())};
1789 std::vector<unsigned char> signature;
1794 BOOST_CHECK_EQUAL(
HexStr(pubkey.ComputeTapTweakHash(merkle_root.
IsNull() ?
nullptr : &merkle_root)), input[
"intermediary"][
"tweak"].get_str());
1813 uint256 hash1 =
uint256S(
"8ad69ec7cf41c2a4001fd1f738bf1e505ce2277acdcaa63fe4765192497f47a7");
1814 uint256 hash2 =
uint256S(
"f224a923cd0021ab202ab139cc56802ddb92dcfc172b9212261a539df79a112a");
1815 uint256 result =
uint256S(
"a64c5b7b943315f9b805d7a7296bedfcfd08919270a1f7a1466e98f8693d8cd9");
1821 const uint8_t script[6] = {
'f',
'o',
'o',
'b',
'a',
'r'};
1822 uint256 tlc0 =
uint256S(
"edbc10c272a1215dcdcc11d605b9027b5ad6ed97cd45521203f136767b5b9c06");
1823 uint256 tlc2 =
uint256S(
"8b5c4f90ae6bf76e259dbef5d8a59df06359c391b59263741b25eca76451b27a");
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)
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_SCRIPT_FLAGS_VERIFY_ALL
@ 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.
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
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 (see script.h)
The basic transaction that is broadcasted on the network and contained in blocks.
const std::vector< CTxIn > vin
An output of a transaction.
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
const UniValue & get_array() const
bool exists(const std::string &key) const
bool read(const char *raw, size_t len)
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)
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 const int SERIALIZE_TRANSACTION_NO_WITNESS
A flag that is ORed into the protocol version to designate that a transaction should be (un)serialize...
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.
static uint64_t InsecureRandBits(int bits)
bool ProduceSignature(const SigningProvider &provider, const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
bool SignSignature(const SigningProvider &provider, const CScript &fromPubKey, CMutableTransaction &txTo, unsigned int nIn, const CAmount &amount, int nHashType)
Produce a script signature for a transaction.
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.
std::pair< CPubKey, std::vector< unsigned char > > SigPair
const SigningProvider & DUMMY_SIGNING_PROVIDER
unsigned char * UCharCast(char *c)
Span(T *, EndOrSize) -> Span< T >
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
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.
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.
std::vector< Byte > ParseHex(std::string_view str)
Parse the hex string into bytes (uint8_t or std::byte).
static const int PROTOCOL_VERSION
network protocol versioning