<p>Pubkey script alone is not enough to verify a transaction, you'll need:</p>
<ol>
<li>Pubkey script, to evaluate the scripts</li>
<li>Amount, in order to check if the sum of inputs is bigger than or equal to sum of outputs</li>
<li>Index (in <code>TxOut</code> list) and tx hash of the transaction being spent</li>
<li>Block height so that you can set the consensus rules</li>
</ol>
<p>After gathering all the above (should be found in the node's UTXO database) you can start evaluating if the provided <em>script is valid</em> which isn't limited to signature verification but running/evaluating the script that includes checking correctness of the script, OP codes, OP count, script size,...<br />
A lot of the verification can be found in <a href="https://github.com/bitcoin/bitcoin/blob/master/src/validation.cpp" rel="nofollow noreferrer">validation.cpp</a> file.<br />
This is also how I do it in <a href="https://github.com/Autarkysoft/Denovo/blob/master/Src/Autarkysoft.Bitcoin/Blockchain/TransactionVerifier.cs" rel="nofollow noreferrer">Bitcoin.Net library</a>.</p>

CC BY-SA 4.0
2020-07-01T11:27:18.290Z
Forgot about block height, which is important for nLockTime... Thank you for sharing code from your project but I would prefer using some more battle-tested code for now, Seems like this task is more easily accomplished in C derived languages (although I was trying to steer away from them), just reminded me that it might also be possible with libbitcoin: https://github.com/libbitcoin/libbitcoin-system/tree/master/include/bitcoin/system/impl/machine
Pedro
CC BY-SA 4.0
2020-07-01T10:41:59.787Z
2020-07-01T10:41:59.787Z
Coding Enthusiast
<p>Given an arbitrary signed raw transaction, how can we easily verify if all inputs are correctly signed (assuming all inputs are existent/unspent and the fee is higher than zero)? Bitcoin core's RPC command <code>testmempoolaccept</code> will check if all inputs are available to be spent in the mempool/blockchain so it's impossible to test transactions that have parents not yet broadcasted.</p>
<p>I am aware that for this kind of check, the scriptPubKeys of all inputs needs to be known and therefore only the signed raw transaction by itself is not enough for this kind of check. Still, the scriptPubKeys could be passed to the transaction instance or verify method. I was looking for some nice way to do this in python/javascript but was surprised how difficult this task is:</p>
<ul>
<li><a href="https://github.com/petertodd/python-bitcoinlib" rel="nofollow noreferrer">Peter Todd's python-bitcoinlib</a> requires each input to be validated manually <a href="https://github.com/petertodd/python-bitcoinlib/blob/master/examples/spend-p2sh-txout.py#L89" rel="nofollow noreferrer">with some flags indicating the type of ScriptPubKey</a>.</li>
<li><a href="https://github.com/1200wd/bitcoinlib" rel="nofollow noreferrer">1200wd bitcoinlib</a>, has a <a href="https://github.com/1200wd/bitcoinlib/blob/master/bitcoinlib/transactions.py#L1632" rel="nofollow noreferrer">transaction.verify()</a> method but it seems to only verify the basic transaction types: coinbase, P2PKH, P2SH(P2PKH), P2SH(multisig), ...</li>
<li>BitcoinJS has a method for this, <a href="https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/psbt.js#L286" rel="nofollow noreferrer">psbt.validateSignaturesOfAllInputs()</a> but converting a raw transaction to PSBT is <a href="https://bitcoin.stackexchange.com/questions/88227/why-is-not-possibile-to-convert-a-signed-transaction-into-psbt">not possible/easy</a>.</li>
<li>Bitcore's <a href="https://github.com/bitpay/bitcore/blob/master/packages/bitcore-lib/lib/transaction/transaction.js#L1291" rel="nofollow noreferrer">transaction.verify()</a> does mostly some basic sanity checks and doesn't verify the signatures.</li>
<li>BitcoinJ's <a href="https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/core/Transaction.java#L1673" rel="nofollow noreferrer">transaction.verify()</a> does also basic verification and the <a href="https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/script/Script.java#L766" rel="nofollow noreferrer">script execution</a>, as python-bitcoinlib, has also to be done manually with verification flags.</li>
</ul>

<transactions><signature><transaction-verification><validation>
How to verify if a transaction is signed correctly?
Pedro
# How to verify if a transaction is signed correctly?

(Asked by: username_0 on 2020-07-01)

Given an arbitrary signed raw transaction, how can we easily verify if all inputs are correctly signed (assuming all inputs are existent/unspent and the fee is higher than zero)? Bitcoin core's RPC command `testmempoolaccept` will check if all inputs are available to be spent in the mempool/blockchain so it's impossible to test transactions that have parents not yet broadcasted.

I am aware that for this kind of check, the scriptPubKeys of all inputs needs to be known and therefore only the signed raw transaction by itself is not enough for this kind of check. Still, the scriptPubKeys could be passed to the transaction instance or verify method. I was looking for some nice way to do this in python/javascript but was surprised how difficult this task is:

* [Peter Todd's python-bitcoinlib](https://github.com/petertodd/python-bitcoinlib) requires each input to be validated manually [with some flags indicating the type of ScriptPubKey](https://github.com/petertodd/python-bitcoinlib/blob/master/examples/spend-p2sh-txout.py#L89).
* [1200wd bitcoinlib](https://github.com/1200wd/bitcoinlib), has a [transaction.verify()](https://github.com/1200wd/bitcoinlib/blob/master/bitcoinlib/transactions.py#L1632) method but it seems to only verify the basic transaction types: coinbase, P2PKH, P2SH(P2PKH), P2SH(multisig), ...
* BitcoinJS has a method for this, [psbt.validateSignaturesOfAllInputs()](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/src/psbt.js#L286) but converting a raw transaction to PSBT is [not possible/easy](https://bitcoin.stackexchange.com/questions/88227/why-is-not-possibile-to-convert-a-signed-transaction-into-psbt).
* Bitcore's [transaction.verify()](https://github.com/bitpay/bitcore/blob/master/packages/bitcore-lib/lib/transaction/transaction.js#L1291) does mostly some basic sanity checks and doesn't verify the signatures.
* BitcoinJ's [transaction.verify()](https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/core/Transaction.java#L1673) does also basic verification and the [script execution](https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/script/Script.java#L766), as python-bitcoinlib, has also to be done manually with verification flags.

**Tags:** transactions, signature, transaction-verification, validation


---

## 1 answers

### Answer by username_1 on 2020-07-01. Score: 2

Pubkey script alone is not enough to verify a transaction, you'll need:

1. Pubkey script, to evaluate the scripts
2. Amount, in order to check if the sum of inputs is bigger than or equal to sum of outputs
3. Index (in `TxOut` list) and tx hash of the transaction being spent
4. Block height so that you can set the consensus rules

After gathering all the above (should be found in the node's UTXO database) you can start evaluating if the provided *script is valid* which isn't limited to signature verification but running/evaluating the script that includes checking correctness of the script, OP codes, OP count, script size,...  
A lot of the verification can be found in [validation.cpp](https://github.com/bitcoin/bitcoin/blob/master/src/validation.cpp) file.  
This is also how I do it in [Bitcoin.Net library](https://github.com/Autarkysoft/Denovo/blob/master/Src/Autarkysoft.Bitcoin/Blockchain/TransactionVerifier.cs).

> **Comments:**
> **username_0**: Forgot about block height, which is important for nLockTime... Thank you for sharing code from your project but I would prefer using some more battle-tested code for now, Seems like this task is more easily accomplished in C derived languages (although I was trying to steer away from them), just reminded me that it might also be possible with libbitcoin: https://github.com/libbitcoin/libbitcoin-system/tree/master/include/bitcoin/system/impl/machine  

---

