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.
1251tx_create.vout.emplace_back(0, CScript{});1252tx_spend.vin.emplace_back(Txid{}, 0);1253std::vector<std::vector<uint8_t>> sol_dummy;1255// CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash,1256// WitnessV1Taproot, PayToAnchor, WitnessUnknown.1257static_assert(std::variant_size_v<CTxDestination> == 9);1259// Go through all defined output types and sanity check SpendsNonAnchorWitnessProg.1261// P2PK1262tx_create.vout[0].scriptPubKey = GetScriptForDestination(PubKeyDestination{pubkey});1263BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::PUBKEY);1264tx_spend.vin[0].prevout.hash = tx_create.GetHash();1265AddCoins(coins, CTransaction{tx_create}, 0, false);1266BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1268// P2PKH1269tx_create.vout[0].scriptPubKey = GetScriptForDestination(PKHash{pubkey});1270BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::PUBKEYHASH);1271tx_spend.vin[0].prevout.hash = tx_create.GetHash();1272AddCoins(coins, CTransaction{tx_create}, 0, false);1273BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1275// P2SH1276auto redeem_script{CScript{} << OP_1 << OP_CHECKSIG};1277tx_create.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash{redeem_script});1278BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::SCRIPTHASH);1279tx_spend.vin[0].prevout.hash = tx_create.GetHash();1280tx_spend.vin[0].scriptSig = CScript{} << OP_0 << ToByteVector(redeem_script);1281AddCoins(coins, CTransaction{tx_create}, 0, false);1282BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1283tx_spend.vin[0].scriptSig.clear();1285// native P2WSH1286const auto witness_script{CScript{} << OP_12 << OP_HASH160 << OP_DUP << OP_EQUAL};1287tx_create.vout[0].scriptPubKey = GetScriptForDestination(WitnessV0ScriptHash{witness_script});1288BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::WITNESS_V0_SCRIPTHASH);1289tx_spend.vin[0].prevout.hash = tx_create.GetHash();1290AddCoins(coins, CTransaction{tx_create}, 0, false);1291BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1293// P2SH-wrapped P2WSH1294redeem_script = tx_create.vout[0].scriptPubKey;1295tx_create.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(redeem_script));1296BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::SCRIPTHASH);1297tx_spend.vin[0].prevout.hash = tx_create.GetHash();1298tx_spend.vin[0].scriptSig = CScript{} << ToByteVector(redeem_script);1299AddCoins(coins, CTransaction{tx_create}, 0, false);1300BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1301tx_spend.vin[0].scriptSig.clear();1302BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1304// native P2WPKH1305tx_create.vout[0].scriptPubKey = GetScriptForDestination(WitnessV0KeyHash{pubkey});1306BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::WITNESS_V0_KEYHASH);1307tx_spend.vin[0].prevout.hash = tx_create.GetHash();1308AddCoins(coins, CTransaction{tx_create}, 0, false);1309BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1311// P2SH-wrapped P2WPKH1312redeem_script = tx_create.vout[0].scriptPubKey;1313tx_create.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(redeem_script));1314BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::SCRIPTHASH);1315tx_spend.vin[0].prevout.hash = tx_create.GetHash();1316tx_spend.vin[0].scriptSig = CScript{} << ToByteVector(redeem_script);1317AddCoins(coins, CTransaction{tx_create}, 0, false);1318BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1319tx_spend.vin[0].scriptSig.clear();1320BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1322// P2TR1323tx_create.vout[0].scriptPubKey = GetScriptForDestination(WitnessV1Taproot{XOnlyPubKey{pubkey}});1324BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::WITNESS_V1_TAPROOT);1325tx_spend.vin[0].prevout.hash = tx_create.GetHash();1326AddCoins(coins, CTransaction{tx_create}, 0, false);1327BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1329// P2SH-wrapped P2TR (undefined, non-standard)1330redeem_script = tx_create.vout[0].scriptPubKey;1331tx_create.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(redeem_script));1332BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::SCRIPTHASH);1333tx_spend.vin[0].prevout.hash = tx_create.GetHash();1334tx_spend.vin[0].scriptSig = CScript{} << ToByteVector(redeem_script);1335AddCoins(coins, CTransaction{tx_create}, 0, false);1336BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1337tx_spend.vin[0].scriptSig.clear();1338BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1340// P2A1341tx_create.vout[0].scriptPubKey = GetScriptForDestination(PayToAnchor{});1342BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::ANCHOR);1343tx_spend.vin[0].prevout.hash = tx_create.GetHash();1344AddCoins(coins, CTransaction{tx_create}, 0, false);1345BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1347// P2SH-wrapped P2A (undefined, non-standard)1348redeem_script = tx_create.vout[0].scriptPubKey;1349tx_create.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(redeem_script));1350BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::SCRIPTHASH);1351tx_spend.vin[0].prevout.hash = tx_create.GetHash();1352tx_spend.vin[0].scriptSig = CScript{} << ToByteVector(redeem_script);1353AddCoins(coins, CTransaction{tx_create}, 0, false);1354BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1355tx_spend.vin[0].scriptSig.clear();1357// Undefined version 1 witness program1358tx_create.vout[0].scriptPubKey = GetScriptForDestination(WitnessUnknown{1, {0x42, 0x42}});1359BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::WITNESS_UNKNOWN);1360tx_spend.vin[0].prevout.hash = tx_create.GetHash();1361AddCoins(coins, CTransaction{tx_create}, 0, false);1362BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1364// P2SH-wrapped undefined version 1 witness program1365redeem_script = tx_create.vout[0].scriptPubKey;1366tx_create.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(redeem_script));1367BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::SCRIPTHASH);1368tx_spend.vin[0].prevout.hash = tx_create.GetHash();1369tx_spend.vin[0].scriptSig = CScript{} << ToByteVector(redeem_script);1370AddCoins(coins, CTransaction{tx_create}, 0, false);1371BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1372tx_spend.vin[0].scriptSig.clear();1373BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1375// Various undefined version >1 32-byte witness programs.1376const auto program{ToByteVector(XOnlyPubKey{pubkey})};1377for (int i{2}; i <= 16; ++i) {1378tx_create.vout[0].scriptPubKey = GetScriptForDestination(WitnessUnknown{i, program});1379BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::WITNESS_UNKNOWN);1380tx_spend.vin[0].prevout.hash = tx_create.GetHash();1381AddCoins(coins, CTransaction{tx_create}, 0, false);1382BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1384// It's also detected within P2SH.1385redeem_script = tx_create.vout[0].scriptPubKey;1386tx_create.vout[0].scriptPubKey = GetScriptForDestination(ScriptHash(redeem_script));1387BOOST_CHECK_EQUAL(Solver(tx_create.vout[0].scriptPubKey, sol_dummy), TxoutType::SCRIPTHASH);1388tx_spend.vin[0].prevout.hash = tx_create.GetHash();1389tx_spend.vin[0].scriptSig = CScript{} << ToByteVector(redeem_script);1390AddCoins(coins, CTransaction{tx_create}, 0, false);1391BOOST_CHECK(::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1392tx_spend.vin[0].scriptSig.clear();1393BOOST_CHECK(!::SpendsNonAnchorWitnessProg(CTransaction{tx_spend}, coins));1394}1395}1397BOOST_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.