Repository: bitcoin/bitcoin
File: src/kernel/bitcoinkernel.cpp (C++)

Code before:
}

void btck_transaction_output_destroy(btck_TransactionOutput* output)
{
    delete output;
}

int btck_script_pubkey_verify(const btck_ScriptPubkey* script_pubkey,
                              const int64_t amount,
                              const btck_Transaction* tx_to,
                              const btck_TransactionOutput** spent_outputs_, size_t spent_outputs_len,
                              const unsigned int input_index,
                              const btck_ScriptVerificationFlags flags,
                              btck_ScriptVerifyStatus* status)
{
    // Assert that all specified flags are part of the interface before continuing
    assert((flags & ~btck_ScriptVerificationFlags_ALL) == 0);

    if (!is_valid_flag_combination(script_verify_flags::from_int(flags))) {
        if (status) *status = btck_ScriptVerifyStatus_ERROR_INVALID_FLAGS_COMBINATION;
        return 0;
    }

    if (flags & btck_ScriptVerificationFlags_TAPROOT && spent_outputs_ == nullptr) {
        if (status) *status = btck_ScriptVerifyStatus_ERROR_SPENT_OUTPUTS_REQUIRED;
        return 0;
    }

    if (status) *status = btck_ScriptVerifyStatus_OK;

    const CTransaction& tx{*btck_Transaction::get(tx_to)};
    std::vector<CTxOut> spent_outputs;
    if (spent_outputs_ != nullptr) {
        assert(spent_outputs_len == tx.vin.size());
        spent_outputs.reserve(spent_outputs_len);
        for (size_t i = 0; i < spent_outputs_len; i++) {
            const CTxOut& tx_out{btck_TransactionOutput::get(spent_outputs_[i])};
            spent_outputs.push_back(tx_out);
        }
    }

    assert(input_index < tx.vin.size());
    PrecomputedTransactionData txdata{tx};

    if (spent_outputs_ != nullptr && flags & btck_ScriptVerificationFlags_TAPROOT) {
        txdata.Init(tx, std::move(spent_outputs));
    }

    bool result = VerifyScript(tx.vin[input_index].scriptSig,
                               btck_ScriptPubkey::get(script_pubkey),
                               &tx.vin[input_index].scriptWitness,

Review comment (suggestion):
I realize you are immitating my own patterns here, but I think it would be better to not rely too heaviliy on the move constructor here, and instead do the following:
```diff
diff --git a/src/kernel/bitcoinkernel.cpp b/src/kernel/bitcoinkernel.cpp
index 4102ee9305..2e86c3d8df 100644
--- a/src/kernel/bitcoinkernel.cpp
+++ b/src/kernel/bitcoinkernel.cpp
@@ -617 +617 @@ btck_PrecomputedTransactionData* btck_precomputed_transaction_data_create(
-        PrecomputedTransactionData txdata{tx};
+        auto txdata{btck_PrecomputedTransactionData::create(tx)};
@@ -626 +626 @@ btck_PrecomputedTransactionData* btck_precomputed_transaction_data_create(
-            txdata.Init(tx, std::move(spent_outputs));
+            btck_PrecomputedTransactionData::get(txdata).Init(tx, std::move(spent_outputs));
@@ -629 +629 @@ btck_PrecomputedTransactionData* btck_precomputed_transaction_data_create(
-        return btck_PrecomputedTransactionData::create(std::move(txdata));
+        return txdata;
``` 
There some other cases in this file where this pattern might be better, but I don't think it is worth fixing here.

Code after:
}

void btck_transaction_output_destroy(btck_TransactionOutput* output)
{
    delete output;
}

btck_PrecomputedTransactionData* btck_precomputed_transaction_data_create(
    const btck_Transaction* tx_to,
    const btck_TransactionOutput** spent_outputs_, size_t spent_outputs_len)
{
    try {
        const CTransaction& tx{*btck_Transaction::get(tx_to)};
        auto txdata{btck_PrecomputedTransactionData::create()};
        if (spent_outputs_ != nullptr && spent_outputs_len > 0) {
            assert(spent_outputs_len == tx.vin.size());
            std::vector<CTxOut> spent_outputs;
            spent_outputs.reserve(spent_outputs_len);
            for (size_t i = 0; i < spent_outputs_len; i++) {
                const CTxOut& tx_out{btck_TransactionOutput::get(spent_outputs_[i])};
                spent_outputs.push_back(tx_out);
            }
            btck_PrecomputedTransactionData::get(txdata).Init(tx, std::move(spent_outputs));
        } else {
            btck_PrecomputedTransactionData::get(txdata).Init(tx, {});
        }

        return txdata;
    } catch (...) {
        return nullptr;
    }
}

btck_PrecomputedTransactionData* btck_precomputed_transaction_data_copy(const btck_PrecomputedTransactionData* precomputed_txdata)
{
    return btck_PrecomputedTransactionData::copy(precomputed_txdata);
}

void btck_precomputed_transaction_data_destroy(btck_PrecomputedTransactionData* precomputed_txdata)
{
    delete precomputed_txdata;
}

int btck_script_pubkey_verify(const btck_ScriptPubkey* script_pubkey,
                              const int64_t amount,
                              const btck_Transaction* tx_to,
                              const btck_PrecomputedTransactionData* precomputed_txdata,
                              const unsigned int input_index,
                              const btck_ScriptVerificationFlags flags,
                              btck_ScriptVerifyStatus* status)
{