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.
501CScript scriptPubKey = CScript() << OP_0 << std::vector<unsigned char>(hash.begin(), hash.end());503std::vector<int> sigHashes;504sigHashes.push_back(SIGHASH_NONE | SIGHASH_ANYONECANPAY);505sigHashes.push_back(SIGHASH_SINGLE | SIGHASH_ANYONECANPAY);506sigHashes.push_back(SIGHASH_ALL | SIGHASH_ANYONECANPAY);507sigHashes.push_back(SIGHASH_NONE);508sigHashes.push_back(SIGHASH_SINGLE);509sigHashes.push_back(SIGHASH_ALL);511// create a big transaction of 4500 inputs signed by the same key512for(uint32_t ij = 0; ij < 4500; ij++) {513uint32_t i = mtx.vin.size();514COutPoint outpoint{Txid{"0000000000000000000000000000000000000000000000000000000000000100"}, i};516mtx.vin.resize(mtx.vin.size() + 1);517mtx.vin[i].prevout = outpoint;518mtx.vin[i].scriptSig = CScript();520mtx.vout.resize(mtx.vout.size() + 1);521mtx.vout[i].nValue = 1000;522mtx.vout[i].scriptPubKey = CScript() << OP_1;523}525// sign all inputs526for(uint32_t i = 0; i < mtx.vin.size(); i++) {527SignatureData empty;528bool hashSigned = SignSignature(keystore, scriptPubKey, mtx, i, 1000, sigHashes.at(i % sigHashes.size()), empty);529assert(hashSigned);530}532DataStream ssout;533ssout << TX_WITH_WITNESS(mtx);534CTransaction tx(deserialize, TX_WITH_WITNESS, ssout);536// check all inputs concurrently, with the cache537PrecomputedTransactionData txdata(tx);538CCheckQueue<CScriptCheck> scriptcheckqueue(/*batch_size=*/128, /*worker_threads_num=*/20);539CCheckQueueControl<CScriptCheck> control(scriptcheckqueue);541std::vector<Coin> coins;542for(uint32_t i = 0; i < mtx.vin.size(); i++) {543Coin coin;544coin.nHeight = 1;545coin.fCoinBase = false;546coin.out.nValue = 1000;547coin.out.scriptPubKey = scriptPubKey;548coins.emplace_back(std::move(coin));549}551SignatureCache signature_cache{DEFAULT_SIGNATURE_CACHE_BYTES};553for(uint32_t i = 0; i < mtx.vin.size(); i++) {554std::vector<CScriptCheck> vChecks;555vChecks.emplace_back(coins[tx.vin[i].prevout.n].out, tx, signature_cache, i, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false, &txdata);556control.Add(std::move(vChecks));557}559bool controlCheck = !control.Complete().has_value();560assert(controlCheck);561}563SignatureData CombineSignatures(const CMutableTransaction& input1, const CMutableTransaction& input2, const CTransactionRef tx)564{565SignatureData sigdata;566sigdata = DataFromTransaction(input1, 0, tx->vout[0]);567sigdata.MergeSignatureData(DataFromTransaction(input2, 0, tx->vout[0]));568ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(input1, 0, tx->vout[0].nValue, {.sighash_type = SIGHASH_DEFAULT}), tx->vout[0].scriptPubKey, sigdata);569return sigdata;570}572BOOST_AUTO_TEST_CASE(test_witness)573{574FillableSigningProvider keystore, keystore2;575CKey key1 = GenerateRandomKey();576CKey key2 = GenerateRandomKey();577CKey key3 = GenerateRandomKey();578CKey key1L = GenerateRandomKey(/*compressed=*/false);579CKey key2L = GenerateRandomKey(/*compressed=*/false);580CPubKey pubkey1 = key1.GetPubKey();581CPubKey pubkey2 = key2.GetPubKey();582CPubKey pubkey3 = key3.GetPubKey();583CPubKey pubkey1L = key1L.GetPubKey();584CPubKey pubkey2L = key2L.GetPubKey();585BOOST_CHECK(keystore.AddKeyPubKey(key1, pubkey1));586BOOST_CHECK(keystore.AddKeyPubKey(key2, pubkey2));587BOOST_CHECK(keystore.AddKeyPubKey(key1L, pubkey1L));588BOOST_CHECK(keystore.AddKeyPubKey(key2L, pubkey2L));589CScript scriptPubkey1, scriptPubkey2, scriptPubkey1L, scriptPubkey2L, scriptMulti;590scriptPubkey1 << ToByteVector(pubkey1) << OP_CHECKSIG;591scriptPubkey2 << ToByteVector(pubkey2) << OP_CHECKSIG;592scriptPubkey1L << ToByteVector(pubkey1L) << OP_CHECKSIG;593scriptPubkey2L << ToByteVector(pubkey2L) << OP_CHECKSIG;594std::vector<CPubKey> oneandthree;595oneandthree.push_back(pubkey1);596oneandthree.push_back(pubkey3);597scriptMulti = GetScriptForMultisig(2, oneandthree);598BOOST_CHECK(keystore.AddCScript(scriptPubkey1));599BOOST_CHECK(keystore.AddCScript(scriptPubkey2));600BOOST_CHECK(keystore.AddCScript(scriptPubkey1L));601BOOST_CHECK(keystore.AddCScript(scriptPubkey2L));602BOOST_CHECK(keystore.AddCScript(scriptMulti));603CScript destination_script_1, destination_script_2, destination_script_1L, destination_script_2L, destination_script_multi;604destination_script_1 = GetScriptForDestination(WitnessV0KeyHash(pubkey1));605destination_script_2 = GetScriptForDestination(WitnessV0KeyHash(pubkey2));606destination_script_1L = GetScriptForDestination(WitnessV0KeyHash(pubkey1L));607destination_script_2L = GetScriptForDestination(WitnessV0KeyHash(pubkey2L));608destination_script_multi = GetScriptForDestination(WitnessV0ScriptHash(scriptMulti));609BOOST_CHECK(keystore.AddCScript(destination_script_1));610BOOST_CHECK(keystore.AddCScript(destination_script_2));611BOOST_CHECK(keystore.AddCScript(destination_script_1L));612BOOST_CHECK(keystore.AddCScript(destination_script_2L));613BOOST_CHECK(keystore.AddCScript(destination_script_multi));614BOOST_CHECK(keystore2.AddCScript(scriptMulti));615BOOST_CHECK(keystore2.AddCScript(destination_script_multi));616BOOST_CHECK(keystore2.AddKeyPubKey(key3, pubkey3));618CTransactionRef output1, output2;619CMutableTransaction input1, input2;621// Normal pay-to-compressed-pubkey.622CreateCreditAndSpend(keystore, scriptPubkey1, output1, input1);623CreateCreditAndSpend(keystore, scriptPubkey2, output2, input2);624CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, true);625CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);626CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);627CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);628CheckWithFlag(output1, input2, SCRIPT_VERIFY_NONE, false);629CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);630CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);631CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);633// P2SH pay-to-compressed-pubkey.634CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(scriptPubkey1)), output1, input1);635CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(scriptPubkey2)), output2, input2);636ReplaceRedeemScript(input2.vin[0].scriptSig, scriptPubkey1);637CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, true);638CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);639CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);640CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);641CheckWithFlag(output1, input2, SCRIPT_VERIFY_NONE, true);642CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);643CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);644CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);646// Witness pay-to-compressed-pubkey (v0).647CreateCreditAndSpend(keystore, destination_script_1, output1, input1);648CreateCreditAndSpend(keystore, destination_script_2, output2, input2);649CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, true);650CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);651CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);652CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);653CheckWithFlag(output1, input2, SCRIPT_VERIFY_NONE, true);654CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true);655CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);656CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);658// P2SH witness pay-to-compressed-pubkey (v0).659CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_1)), output1, input1);660CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_2)), output2, input2);661ReplaceRedeemScript(input2.vin[0].scriptSig, destination_script_1);662CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, true);663CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);664CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);665CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);666CheckWithFlag(output1, input2, SCRIPT_VERIFY_NONE, true);667CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, true);668CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);669CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);671// Normal pay-to-uncompressed-pubkey.672CreateCreditAndSpend(keystore, scriptPubkey1L, output1, input1);673CreateCreditAndSpend(keystore, scriptPubkey2L, output2, input2);674CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, true);675CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);676CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);677CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);678CheckWithFlag(output1, input2, SCRIPT_VERIFY_NONE, false);679CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);680CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);681CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);683// P2SH pay-to-uncompressed-pubkey.684CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(scriptPubkey1L)), output1, input1);685CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(scriptPubkey2L)), output2, input2);686ReplaceRedeemScript(input2.vin[0].scriptSig, scriptPubkey1L);687CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, true);688CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);689CheckWithFlag(output1, input1, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, true);690CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);691CheckWithFlag(output1, input2, SCRIPT_VERIFY_NONE, true);692CheckWithFlag(output1, input2, SCRIPT_VERIFY_P2SH, false);693CheckWithFlag(output1, input2, SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_P2SH, false);694CheckWithFlag(output1, input2, STANDARD_SCRIPT_VERIFY_FLAGS, false);696// Signing disabled for witness pay-to-uncompressed-pubkey (v1).697CreateCreditAndSpend(keystore, destination_script_1L, output1, input1, false);698CreateCreditAndSpend(keystore, destination_script_2L, output2, input2, false);700// Signing disabled for P2SH witness pay-to-uncompressed-pubkey (v1).701CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_1L)), output1, input1, false);702CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_2L)), output2, input2, false);704// Normal 2-of-2 multisig705CreateCreditAndSpend(keystore, scriptMulti, output1, input1, false);706CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, false);707CreateCreditAndSpend(keystore2, scriptMulti, output2, input2, false);708CheckWithFlag(output2, input2, SCRIPT_VERIFY_NONE, false);709BOOST_CHECK(output1->Equals(*output2));710UpdateInput(input1.vin[0], CombineSignatures(input1, input2, output1));711CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);713// P2SH 2-of-2 multisig714CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(scriptMulti)), output1, input1, false);715CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, true);716CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, false);717CreateCreditAndSpend(keystore2, GetScriptForDestination(ScriptHash(scriptMulti)), output2, input2, false);718CheckWithFlag(output2, input2, SCRIPT_VERIFY_NONE, true);719CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH, false);720BOOST_CHECK(output1->Equals(*output2));721UpdateInput(input1.vin[0], CombineSignatures(input1, input2, output1));722CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);723CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);725// Witness 2-of-2 multisig726CreateCreditAndSpend(keystore, destination_script_multi, output1, input1, false);727CheckWithFlag(output1, input1, SCRIPT_VERIFY_NONE, true);728CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);729CreateCreditAndSpend(keystore2, destination_script_multi, output2, input2, false);730CheckWithFlag(output2, input2, SCRIPT_VERIFY_NONE, true);731CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);732BOOST_CHECK(output1->Equals(*output2));733UpdateInput(input1.vin[0], CombineSignatures(input1, input2, output1));734CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true);735CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);737// P2SH witness 2-of-2 multisig738CreateCreditAndSpend(keystore, GetScriptForDestination(ScriptHash(destination_script_multi)), output1, input1, false);739CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true);740CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);741CreateCreditAndSpend(keystore2, GetScriptForDestination(ScriptHash(destination_script_multi)), output2, input2, false);742CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH, true);743CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, false);744BOOST_CHECK(output1->Equals(*output2));745UpdateInput(input1.vin[0], CombineSignatures(input1, input2, output1));746CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true);747CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true);748}750BOOST_AUTO_TEST_CASE(test_IsStandard)
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.