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.
751out_sigdata->missing_sigs = sigdata.missing_sigs;752out_sigdata->missing_redeem_script = sigdata.missing_redeem_script;753out_sigdata->missing_witness_script = sigdata.missing_witness_script;754}756if (!sig_complete) return util::Unexpected{PSBTError::INCOMPLETE};757return {};758}760void RemoveUnnecessaryTransactions(PartiallySignedTransaction& psbtx)761{762// Figure out if any non_witness_utxos should be dropped763std::vector<unsigned int> to_drop;764for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {765const auto& input = psbtx.inputs.at(i);766int wit_ver;767std::vector<unsigned char> wit_prog;768if (input.witness_utxo.IsNull() || !input.witness_utxo.scriptPubKey.IsWitnessProgram(wit_ver, wit_prog)) {769// There's a non-segwit input, so we cannot drop any non_witness_utxos770to_drop.clear();771break;772}773if (wit_ver == 0) {774// Segwit v0, so we cannot drop any non_witness_utxos775to_drop.clear();776break;777}778// non_witness_utxos cannot be dropped if the sighash type includes SIGHASH_ANYONECANPAY779// Since callers should have called SignPSBTInput which updates the sighash type in the PSBT, we only780// need to look at that field. If it is not present, then we can assume SIGHASH_DEFAULT or SIGHASH_ALL.781if (input.sighash_type != std::nullopt && (*input.sighash_type & 0x80) == SIGHASH_ANYONECANPAY) {782to_drop.clear();783break;784}786if (input.non_witness_utxo) {787to_drop.push_back(i);788}789}791// Drop the non_witness_utxos that we can drop792for (unsigned int i : to_drop) {793psbtx.inputs.at(i).non_witness_utxo = nullptr;794}795}797bool FinalizePSBT(PartiallySignedTransaction& psbtx)798{799// Finalize input signatures -- in case we have partial signatures that add up to a complete800// signature, but have not combined them yet (e.g. because the combiner that created this801// PartiallySignedTransaction did not understand them), this will combine them into a final802// script.803bool complete = true;804std::optional<PrecomputedTransactionData> txdata_res = PrecomputePSBTData(psbtx);805if (!txdata_res) {806return false;807}808const PrecomputedTransactionData& txdata = *txdata_res;809for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {810PSBTInput& input = psbtx.inputs.at(i);811const auto sign_result = SignPSBTInput(DUMMY_SIGNING_PROVIDER, psbtx, i, &txdata, {.sighash_type = input.sighash_type, .finalize = true}, /*out_sigdata=*/nullptr);812complete &= sign_result.has_value();813}815return complete;816}818bool FinalizeAndExtractPSBT(PartiallySignedTransaction& psbtx, CMutableTransaction& result)819{820// It's not safe to extract a PSBT that isn't finalized, and there's no easy way to check821// whether a PSBT is finalized without finalizing it, so we just do this.822if (!FinalizePSBT(psbtx)) {823return false;824}826std::optional<CMutableTransaction> unsigned_tx = psbtx.GetUnsignedTx();827if (!unsigned_tx) {828return false;829}830result = *unsigned_tx;831for (unsigned int i = 0; i < result.vin.size(); ++i) {832result.vin[i].scriptSig = psbtx.inputs[i].final_script_sig;833result.vin[i].scriptWitness = psbtx.inputs[i].final_script_witness;834}835return true;836}838std::optional<PartiallySignedTransaction> CombinePSBTs(const std::vector<PartiallySignedTransaction>& psbtxs)839{840PartiallySignedTransaction out = psbtxs[0]; // Copy the first one842// Merge843for (auto it = std::next(psbtxs.begin()); it != psbtxs.end(); ++it) {844if (!out.Merge(*it)) {845return std::nullopt;846}847}848return out;849}851std::string PSBTRoleName(PSBTRole role) {852switch (role) {853case PSBTRole::CREATOR: return "creator";854case PSBTRole::UPDATER: return "updater";855case PSBTRole::SIGNER: return "signer";856case PSBTRole::FINALIZER: return "finalizer";857case PSBTRole::EXTRACTOR: return "extractor";858} // no default case, so the compiler can warn about missing cases859assert(false);860}862util::Result<PartiallySignedTransaction> DecodeBase64PSBT(const std::string& base64_tx)863{864auto tx_data = DecodeBase64(base64_tx);865if (!tx_data) {866return util::Error{Untranslated("invalid base64")};867}868return DecodeRawPSBT(MakeByteSpan(*tx_data));869}871util::Result<PartiallySignedTransaction> DecodeRawPSBT(std::span<const std::byte> tx_data)872{873SpanReader ss_data{tx_data};874try {875PartiallySignedTransaction psbt(deserialize, ss_data);876if (!ss_data.empty()) {877return util::Error{Untranslated("extra data after PSBT")};878}879return psbt;880} catch (const std::exception& e) {881return util::Error{Untranslated(e.what())};882}883}885uint32_t PartiallySignedTransaction::GetVersion() const886{887if (m_version != std::nullopt) {888return *m_version;889}890return 0;891}
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.