Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1501}1503BOOST_AUTO_TEST_CASE(script_byte_array_u8_vector_equivalence)1504{1505const CScript scriptPubKey1 = CScript() << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"_hex_v_u8 << OP_CHECKSIG;1506const CScript scriptPubKey2 = CScript() << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"_hex << OP_CHECKSIG;1507BOOST_CHECK(scriptPubKey1 == scriptPubKey2);1508}1510BOOST_AUTO_TEST_CASE(script_FindAndDelete)1511{1512// Exercise the FindAndDelete functionality1513CScript s;1514CScript d;1515CScript expect;1517s = CScript() << OP_1 << OP_2;1518d = CScript(); // delete nothing should be a no-op1519expect = s;1520BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0);1521BOOST_CHECK(s == expect);1523s = CScript() << OP_1 << OP_2 << OP_3;1524d = CScript() << OP_2;1525expect = CScript() << OP_1 << OP_3;1526BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);1527BOOST_CHECK(s == expect);1529s = CScript() << OP_3 << OP_1 << OP_3 << OP_3 << OP_4 << OP_3;1530d = CScript() << OP_3;1531expect = CScript() << OP_1 << OP_4;1532BOOST_CHECK_EQUAL(FindAndDelete(s, d), 4);1533BOOST_CHECK(s == expect);1535s = ToScript("0302ff03"_hex); // PUSH 0x02ff03 onto stack1536d = ToScript("0302ff03"_hex);1537expect = CScript();1538BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);1539BOOST_CHECK(s == expect);1541s = ToScript("0302ff030302ff03"_hex); // PUSH 0x02ff03 PUSH 0x02ff031542d = ToScript("0302ff03"_hex);1543expect = CScript();1544BOOST_CHECK_EQUAL(FindAndDelete(s, d), 2);1545BOOST_CHECK(s == expect);1547s = ToScript("0302ff030302ff03"_hex);1548d = ToScript("02"_hex);1549expect = s; // FindAndDelete matches entire opcodes1550BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0);1551BOOST_CHECK(s == expect);1553s = ToScript("0302ff030302ff03"_hex);1554d = ToScript("ff"_hex);1555expect = s;1556BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0);1557BOOST_CHECK(s == expect);1559// This is an odd edge case: strip of the push-three-bytes1560// prefix, leaving 02ff03 which is push-two-bytes:1561s = ToScript("0302ff030302ff03"_hex);1562d = ToScript("03"_hex);1563expect = CScript() << "ff03"_hex << "ff03"_hex;1564BOOST_CHECK_EQUAL(FindAndDelete(s, d), 2);1565BOOST_CHECK(s == expect);1567// Byte sequence that spans multiple opcodes:1568s = ToScript("02feed5169"_hex); // PUSH(0xfeed) OP_1 OP_VERIFY1569d = ToScript("feed51"_hex);1570expect = s;1571BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0); // doesn't match 'inside' opcodes1572BOOST_CHECK(s == expect);1574s = ToScript("02feed5169"_hex); // PUSH(0xfeed) OP_1 OP_VERIFY1575d = ToScript("02feed51"_hex);1576expect = ToScript("69"_hex);1577BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);1578BOOST_CHECK(s == expect);1580s = ToScript("516902feed5169"_hex);1581d = ToScript("feed51"_hex);1582expect = s;1583BOOST_CHECK_EQUAL(FindAndDelete(s, d), 0);1584BOOST_CHECK(s == expect);1586s = ToScript("516902feed5169"_hex);1587d = ToScript("02feed51"_hex);1588expect = ToScript("516969"_hex);1589BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);1590BOOST_CHECK(s == expect);1592s = CScript() << OP_0 << OP_0 << OP_1 << OP_1;1593d = CScript() << OP_0 << OP_1;1594expect = CScript() << OP_0 << OP_1; // FindAndDelete is single-pass1595BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);1596BOOST_CHECK(s == expect);1598s = CScript() << OP_0 << OP_0 << OP_1 << OP_0 << OP_1 << OP_1;1599d = CScript() << OP_0 << OP_1;1600expect = CScript() << OP_0 << OP_1; // FindAndDelete is single-pass1601BOOST_CHECK_EQUAL(FindAndDelete(s, d), 2);1602BOOST_CHECK(s == expect);1604// Another weird edge case:1605// End with invalid push (not enough data)...1606s = ToScript("0003feed"_hex);1607d = ToScript("03feed"_hex); // ... can remove the invalid push1608expect = ToScript("00"_hex);1609BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);1610BOOST_CHECK(s == expect);1612s = ToScript("0003feed"_hex);1613d = ToScript("00"_hex);1614expect = ToScript("03feed"_hex);1615BOOST_CHECK_EQUAL(FindAndDelete(s, d), 1);1616BOOST_CHECK(s == expect);1617}1619BOOST_AUTO_TEST_CASE(script_HasValidOps)1620{1621// Exercise the HasValidOps functionality1622CScript script;1623script = ToScript("76a9141234567890abcdefa1a2a3a4a5a6a7a8a9a0aaab88ac"_hex); // Normal script1624BOOST_CHECK(script.HasValidOps());1625script = ToScript("76a914ff34567890abcdefa1a2a3a4a5a6a7a8a9a0aaab88ac"_hex);1626BOOST_CHECK(script.HasValidOps());1627script = ToScript("ff88ac"_hex); // Script with OP_INVALIDOPCODE explicit1628BOOST_CHECK(!script.HasValidOps());1629script = ToScript("88acc0"_hex); // Script with undefined opcode1630BOOST_CHECK(!script.HasValidOps());1631}1633BOOST_AUTO_TEST_CASE(bip341_keypath_test_vectors)1634{1635UniValue tests;1636Assert(tests.read(json_tests::bip341_wallet_vectors));1638const auto& vectors = tests["keyPathSpending"];1640for (const auto& vec : vectors.getValues()) {1641auto txhex = ParseHex(vec["given"]["rawUnsignedTx"].get_str());1642CMutableTransaction tx;1643SpanReader{txhex} >> TX_WITH_WITNESS(tx);1644std::vector<CTxOut> utxos;1645for (const auto& utxo_spent : vec["given"]["utxosSpent"].getValues()) {1646auto script_bytes = ParseHex(utxo_spent["scriptPubKey"].get_str());1647CScript script{script_bytes.begin(), script_bytes.end()};1648CAmount amount{utxo_spent["amountSats"].getInt<int>()};1649utxos.emplace_back(amount, script);1650}1652PrecomputedTransactionData txdata;1653txdata.Init(tx, std::vector<CTxOut>{utxos}, true);1655BOOST_CHECK(txdata.m_bip341_taproot_ready);1656BOOST_CHECK_EQUAL(HexStr(txdata.m_spent_amounts_single_hash), vec["intermediary"]["hashAmounts"].get_str());1657BOOST_CHECK_EQUAL(HexStr(txdata.m_outputs_single_hash), vec["intermediary"]["hashOutputs"].get_str());1658BOOST_CHECK_EQUAL(HexStr(txdata.m_prevouts_single_hash), vec["intermediary"]["hashPrevouts"].get_str());1659BOOST_CHECK_EQUAL(HexStr(txdata.m_spent_scripts_single_hash), vec["intermediary"]["hashScriptPubkeys"].get_str());1660BOOST_CHECK_EQUAL(HexStr(txdata.m_sequences_single_hash), vec["intermediary"]["hashSequences"].get_str());1662for (const auto& input : vec["inputSpending"].getValues()) {1663int txinpos = input["given"]["txinIndex"].getInt<int>();1664int hashtype = input["given"]["hashType"].getInt<int>();1666// Load key.1667auto privkey = ParseHex(input["given"]["internalPrivkey"].get_str());1668CKey key;1669key.Set(privkey.begin(), privkey.end(), true);1671// Load Merkle root.1672uint256 merkle_root;1673if (!input["given"]["merkleRoot"].isNull()) {1674merkle_root = uint256{ParseHex(input["given"]["merkleRoot"].get_str())};1675}1677// Compute and verify (internal) public key.1678XOnlyPubKey pubkey{key.GetPubKey()};1679BOOST_CHECK_EQUAL(HexStr(pubkey), input["intermediary"]["internalPubkey"].get_str());1681// Sign and verify signature.1682FlatSigningProvider provider;1683provider.keys[key.GetPubKey().GetID()] = key;1684MutableTransactionSignatureCreator creator(tx, txinpos, utxos[txinpos].nValue, &txdata, {.sighash_type = hashtype});1685std::vector<unsigned char> signature;1686BOOST_CHECK(creator.CreateSchnorrSig(provider, signature, pubkey, nullptr, &merkle_root, SigVersion::TAPROOT));1687BOOST_CHECK_EQUAL(HexStr(signature), input["expected"]["witness"][0].get_str());1689// We can't observe the tweak used inside the signing logic, so verify by recomputing it.1690BOOST_CHECK_EQUAL(HexStr(pubkey.ComputeTapTweakHash(merkle_root.IsNull() ? nullptr : &merkle_root)), input["intermediary"]["tweak"].get_str());1692// We can't observe the sighash used inside the signing logic, so verify by recomputing it.1693ScriptExecutionData sed;1694sed.m_annex_init = true;1695sed.m_annex_present = false;1696uint256 sighash;1697BOOST_CHECK(SignatureHashSchnorr(sighash, sed, tx, txinpos, hashtype, SigVersion::TAPROOT, txdata, MissingDataBehavior::FAIL));1698BOOST_CHECK_EQUAL(HexStr(sighash), input["intermediary"]["sigHash"].get_str());1700// To verify the sigmsg, hash the expected sigmsg, and compare it with the (expected) sighash.1701BOOST_CHECK_EQUAL(HexStr((HashWriter{HASHER_TAPSIGHASH} << std::span<const uint8_t>{ParseHex(input["intermediary"]["sigMsg"].get_str())}).GetSHA256()), input["intermediary"]["sigHash"].get_str());1702}1703}1704}1706BOOST_AUTO_TEST_CASE(compute_tapbranch)1707{1708constexpr uint256 hash1{"8ad69ec7cf41c2a4001fd1f738bf1e505ce2277acdcaa63fe4765192497f47a7"};1709constexpr uint256 hash2{"f224a923cd0021ab202ab139cc56802ddb92dcfc172b9212261a539df79a112a"};1710constexpr uint256 result{"a64c5b7b943315f9b805d7a7296bedfcfd08919270a1f7a1466e98f8693d8cd9"};1711BOOST_CHECK_EQUAL(ComputeTapbranchHash(hash1, hash2), result);1712}1714BOOST_AUTO_TEST_CASE(compute_tapleaf)1715{1716constexpr uint8_t script[6] = {'f','o','o','b','a','r'};1717constexpr uint256 tlc0{"edbc10c272a1215dcdcc11d605b9027b5ad6ed97cd45521203f136767b5b9c06"};1718constexpr uint256 tlc2{"8b5c4f90ae6bf76e259dbef5d8a59df06359c391b59263741b25eca76451b27a"};1720BOOST_CHECK_EQUAL(ComputeTapleafHash(0xc0, std::span(script)), tlc0);1721BOOST_CHECK_EQUAL(ComputeTapleafHash(0xc2, std::span(script)), tlc2);1722}1724BOOST_AUTO_TEST_CASE(formatscriptflags)1725{1726// quick check that FormatScriptFlags reports any unknown/unexpected bits1727BOOST_CHECK_EQUAL(FormatScriptFlags(SCRIPT_VERIFY_P2SH), "P2SH");1728BOOST_CHECK_EQUAL(FormatScriptFlags(SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_TAPROOT), "P2SH,TAPROOT");1729BOOST_CHECK_EQUAL(FormatScriptFlags(SCRIPT_VERIFY_P2SH | script_verify_flags::from_int(1u<<31)), "P2SH,0x80000000");1730BOOST_CHECK_EQUAL(FormatScriptFlags(SCRIPT_VERIFY_TAPROOT | script_verify_flags::from_int(1u<<27)), "TAPROOT,0x08000000");1731BOOST_CHECK_EQUAL(FormatScriptFlags(SCRIPT_VERIFY_TAPROOT | script_verify_flags::from_int((1u<<28) | (1ull<<58))), "TAPROOT,0x400000010000000");1732BOOST_CHECK_EQUAL(FormatScriptFlags(script_verify_flags::from_int(1u<<26)), "0x04000000");1733}1735BOOST_AUTO_TEST_SUITE_END()
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.