Simplified Payment Verification

Instant payment, signature validity, and the importance of integrity

Wei Zhang
nChain
8 min readAug 25, 2020

--

Photo by SkillScouter on Unsplash

The concept of Simplified Payment Verification (SPV) can be traced back to the Bitcoin white paper in 2008. It provides a scalable mechanism for verifying whether a transaction has appeared in a block. However, there are some subtle but important aspects of SPV that are often overlooked. This article will explore the role that SPV plays in enabling instant payments, data ownership, and legal compliance.

Proof of publication in a block

Section 8 of the Bitcoin white paper introduces SPV as the process of verifying whether a payment has been accepted by the Bitcoin network. The verifier is assumed to have access to a list of block headers, and it takes an input consisting of a Bitcoin transaction and its Merkle proof. If the Merkle proof leads to a Merkle root which appears in one of the block headers, it means that the transaction has indeed been published in that block. The process is considered as simplified because it only requires three pieces of information:

1. a list of block headers (under 52 MB at the time of writing),

2. a transaction (under 400 bytes for a simple Pay-to-Public-Key-Hash transaction¹), and

3. a Merkle proof (928 bytes assuming the block containing 1 billion transactions).

Consider a merchant, say Bob, who maintains a list of block headers. When he receives a payment transaction from his customer, say Alice, he can verify that the payment has appeared in a block as soon as its Merkle proof is obtained. If a BIP-270 process is implemented, it is Bob himself (or a receiver in general) who is responsible for sending the transaction to the Bitcoin network and obtaining a Merkle proof. This process works very well with an SPV client because the merchant has all three pieces of information required to carry out the verification.

The cost for Bob to run this system is much lower than the cost of maintaining a full copy of the blockchain. Given the lightweight nature of this mechanism in terms of storage and bandwidth, it is not difficult to see that this can be scaled up easily.

Instant Payments

Somewhat counter-intuitively, SPV may also be used for payments that are effectively instant. In this case, the customer, Alice, provides two transactions and one Merkle proof to the merchant, Bob. One is a payment transaction. The other is the transaction whose output is referenced by the payment transaction. Let us call it the previous transaction from now on. The Merkle proof is for the previous transaction. (The number of previous transactions required depends on the number of inputs in the payment transaction. For simplicity, we assume only one transaction is referenced in the payment transaction as an input.) Note that the payment transaction does not have a Merkle proof at this point.

One motivation for the simplified payment verification on the previous transaction is to have a fail-fast mechanism to allow Bob to detect invalid payment transactions quickly before it is sent to the Bitcoin nodes. This is because the proof that the previous transaction exists on the global ledger provides some assurance that Alice did indeed have the necessary funds at some point in the past.

In fact, there is a much more fundamental motivation to conduct this simplified payment verification on the previous transaction: to prove the integrity of a transaction.

The simplified payment verification on the previous transaction is to ensure the data in the previous transaction provided by the customer has not been tampered with. Before we explain this in detail, we would like to make a reasonable assumption that digital signatures are legally binding. Note that this has been the case in the UK since 2000.

Digital signature validity

Consider once again our favourite characters, Alice and Bob. Suppose Alice would like to purchase a games console from Bob. She sends a payment transaction to Bob.

Payment Transaction, TX_payment

Looking at this payment transaction, Bob can determine that it spends an output from transaction TX_previous, and assigns x amount to him as he has asked for. To be convinced of its validity, he could send this transaction to the Bitcoin nodes and wait for a response, but it would take a while. To serve his customers better, Bob realises that there is a digital signature in the payment transaction, (Sig_A,PK_A). If he can verify the digital signature and ensure it is coming from Alice, he would be happy to complete the trade as Alice would be legally responsible for her actions due to the presence of her signature. As an analogy, one can think of paying by a credit card and a signature is required to confirm the payment, where the verification of the signature is to check whether it is the same as the one on the back of the card. When the purchase is for a high value item, a photo ID may be required to assist the verification.

One implicit assumption we have made is that Bob is able to link Alice’s identity to the public key. This assumption might not hold in some cases, for example if the value of the transaction is sufficiently low. However, given the benefits of effectively instant payments and the need for auditing and national taxation, the assumption can be justified and realised via loyalty programs, certified public keys², or any other incentive or enforcing schemes. It is not unreasonable to expect that soon a provable link to identity may be a legal requirement for purchases over a certain threshold.

In general, to verify a digital signature one needs three pieces of information:

  1. the digital signature,
  2. a public key, and
  3. a message.

We can see that Bob has the first two. However, the message depends not only on the payment transaction but also some fields in the previous transaction, TX_previous.

Previous Transaction, TX_previous

The signed message contains the first output from the previous transaction, namely the value and the locking script, which is referenced in the payment transaction. One might say that it would be enough for Alice to additionally provide w and OP_DUP OP_HASH160 <H(PK_A)> OP_EQUALVERIFY OP_CHECKSIG to Bob for him to verify the signature. However, Alice cannot prove the integrity of the data that is extracted from the previous transaction unless Alice provides the previous transaction in its entirety and its Merkle proof. The Merkle proof as an integrity proof tells Bob two things

1. the locking script is indeed asking for a digital signature with respect to a specific public key (e.g., a Pay-to-Public-Key-Hash script), and

2. the locking script has not been modified.

The importance of this integrity check on the previous transaction is often underestimated. A locking script such as OP_DROP OP_DROP OP_TRUE in the previous transaction will allow Alice to put any pair of strings that look like a signature and a public key in the unlocking script. If Bob is given only the payment transaction, he cannot tell the validity of the signature or the legitimacy of the public key. Moreover, not knowing what the locking script in the previous transaction is implies that Bob cannot assume the Bitcoin nodes would verify the signature. As the example locking script shows, there is no OP_CHECKSIG and therefore there will be no signature verification when executing the script.

Note that many data applications such as Metanet applications rely on the validity of the signature and the public key in the unlocking script of a transaction to indicate data ownerships or access rights. The validity of the transaction does not imply the validity of the signature unless the previous transaction is provided and shows that a signature with respect to the given public key is required³.

If Bob asks for only the locking script and the value, then it is possible for Alice to generate a new pair of private and public keys and create a fake Pay-to-Public-Key-Hash locking script corresponding to the public key. She can then sign a message so that the resulting signature is valid when Bob verifies it on the payment transaction and the fake locking script. Therefore, it is crucial for Bob to conduct a simplified payment verification on the previous transaction as an integrity check before proceeding to a signature verification.

By verifying the digital signature successfully on the message with respect to the public key that links to Alice’s identity, Bob is convinced that Alice indeed has the rightful control over w bitcoins and approved to transfer x of them to him with her digital signature. In this case, Bob is willing to complete the trade as he knows Alice would be held legally responsible if she double spends. This is how SPV enables effectively instant payments.

Summary

When a digital signature and a public key in an unlocking script are being used meaningfully in some context, the integrity of the previous transaction, or more precisely, the integrity of the locking script from the previous transaction becomes extremely important. The proof on the integrity ensures that the digital signature in the unlocking script will be verified as a digital signature with respect to the given public key by the Bitcoin network. As described above, this can be achieved by using simplified payment verification on the previous transaction.

As in the story of Alice and Bob, the signature and the public key (linked to Alice’s identity) are regarded as a proof of Alice agreeing to pay Bob bitcoins for her purchase. Because of this interpretation, Bob needs to make sure the signature is valid and indeed from Alice. This concept also applies to data ownership or attestation in a transaction such as Metanet applications or attesting a document in an OP_RETURN payload via a transaction.

As a takeaway message, we want to stress that SPV can be used not only for proving the existence but also the integrity of a published transaction, and the integrity of the transaction implies the integrity of any data embedded in that transaction.

Footnotes

[1] If only transaction ID is provided for the verification on its existence, the verifier needs to know the depth of the Merkle tree or that the transaction ID comes from a raw transaction in order to confirm its existence. This is to ensure that the transaction ID is indeed a leaf on the Merkle tree instead of an internal node. Either piece of knowledge may require the verifier to store or have access to some additional information.

[2] To avoid re-using certified identity keys, Alice can derive a key pair from her identity key after Bob verifies her certificate. The derivation could be achieved, for example, by using a BIP32 unhardened key path, or based on a Diffie-Hellman key exchange between Alice and Bob. This is to ensure that Bob can verify the link between the public key that is used in the payment and the certified identity public key.

[3] We thank Xiaojie Tao, CTO from Volt, independently identified the importance of the previous transaction in validating a Metanet transaction: https://www.yuque.com/docs/share/0b224413-7987-4ebf-b0e3-6b268ae18f27, and motivated us to write this article.

--

--

Wei Zhang
nChain
Editor for

Quick learner, astute thinker, and effective problem-solver