Simplified Payment Verification

Abstract

Defining Simplified Payment Verification (SPV) without external reference for sake of clarity.

Motivation

Bitcoin's security model is built upon the idea of widespread distribution of blockheaders, where applications run SPV. This ensures that anyone can easily identify any attempt to commit fraud using tampered data. To ascertain the validity of data received from peers, any client on the network can employ Simplified Payment Verification. We require a clear and definitive reference that outlines the specific criteria. This way, implementations with variations in finer details can always refer back to the fundamental principles that remain constant over time.

Certain checks that are unique to each implementation, such as detecting encoding errors or malformed transactions, are not covered here. Although these checks are essential, they vary according to the implementation and are not included in the definitive list presented below.

Verification Steps

Checks made on receipt of a transaction from a counterparty:

  1. Script evaluation of each unlocking script results in TRUE.

  2. The sum of the satoshis-in must be greater than the sum of the satoshis-out.

  3. Each input must be associated with a Merkle path to a block.

  4. nLocktime, and nSequence of each input are set to the expected values.

Script Evaluation

Often this is referred to as "check the signatures" which is indeed usually the case but it is possible to have transactions which do not require signatures so for the sake of technical exactitude - running script evaluation is really what is happening here. The interpretation requires that each input unlocking script is concatenated with the previous locking script and the interpreter runs given that input. The result should be a truthy value left on the stack after execution, otherwise the predicate has failed and the utxo has not been unlocked.

Check Fees

Each input is a pointer to a previous output, each output has a satoshi value. Therefore to calculate the input satoshis we must have details of the previous transactions from which we are spending utxos. We use this information to determine the fees paid by the transaction. We compare these fees with the size of the Tx in bytes to arrive at a rate: sats/byte. The acceptable rate is well known, various services publish this information. At the time of publishing this rate is equivalent to 1 satoshi for a standard transaction, therefore the check could simply be:

sumInputAmounts > sumOutputAmounts

Merkle Path

If all inputs come from Transactions which are mined in a block, then the associated Merkle path is one which leads that txid to a Merkle root. If some inputs are not in a block then we must include previous transaction data, and follow the history of all inputs until we arrive at a point where all inputs are associated with previous inputs which appear in a mined block. Various formats will handle this differently, but the universal rule is that SPV requires that we prove that all inputs come from legitimate transactions.

In a long chain of transactions conducted while not connected to the internet, each new transaction is appended to the end of the SPV data such that all prior transaction ancestry is propagated to all counterparties, until they are broadcasted. So we would expect large SPV data payloads only when many transactions happen offline, which in today's age will be extremely rare.

Locktime and Sequence

The nLocktime default is 00000000, and nSequence default is FFFFFFFF. If these values are not default then there is a naunced condition to the transaction which is explained here.

Last updated