Bitcoin concept coin

Scalable peer to peer tokens on Bitcoin: Solve the back-to-Genesis problem using recursive SNARKs

This post was first published onĀ Medium.

This is an implementation ofĀ nChainā€™s solutionĀ¹.

The Back-to-Genesis Problem

Tokens on Bitcoin are typically stored in UTXOs. When a supposed token transaction is received, a user needs a way to efficiently and quickly check its authenticity. A major part is to decide if it links to certain genesis transaction, where the token is issued.

In a basic form, the Back-to-Genesis (B2G) problem boils down to: given a transaction, is it linked to certain genesis transaction in an unbroken chain of transactions?

the Back-to-Genesis (B2G)

AllĀ tokens on BitcoinĀ today have to rely on some trusted third-party to address the problem, since it becomes computationally challenging for a light-weight user to verify himself when the chain is excessively longĀ². For instance, DotWalletā€™sĀ BadgeĀ tokens use a token indexer andĀ SensibleĀ tokens use an oracle. This third-party reliance hurdles token adoption on Bitcoin, since it is not as scalable andĀ SPV-friendly as native bitcoins.

Our previous proposalĀ attempts to solve the problem without any third party. However, the size of a token transaction grows exponentially when the chain grows, severely limiting its usage in practice.

Recursive SNARKs

Recall inĀ a recursive SNARK, specifically incrementally verifiable computation (IVC), we want to prove that a function F applied n times to initial input zā‚€ yields zā‚™.

Recursive SNARKs

In each step,Ā zįµ¢Ā is the public input andĀ wįµ¢Ā the private input (i.e., witness).

the public input and wįµ¢ the private input

Each step produces a new proof. In stepĀ i, the prover algorithm computes š›‘įµ¢ that proves all steps up toĀ iĀ are correct, using only local information from the last step and current step as shown below. Crucially, it does not trace all the back to step 0, while still being able verify all steps since step 0 are correctly executed.

prover algorithm computes š›‘įµ¢
Prover algorithm: compute proof incrementally

Applying recursive SNARKs to B2G

IVC naturally leads to an elegant solution to the B2G problem.

Applying recursive SNARKs to B2G
IVC in B2G

Concretely, IVC is instantiated as follows:

  • zįµ¢: txidįµ¢, the transaction id of i-th transaction in the chain
  • wįµ¢: the rest of i-th transaction. We divide into it into two parts: prefixįµ¢ and postfixįµ¢, representing what comes before and after txidįµ¢.
  • functionĀ F: the txid of a transaction is the double SHA256 of it and the (i+1)-thĀ transaction spends theĀ i-thĀ transaction, its txid and thusĀ FĀ is calculated as below:

function F: the txid of a transaction is the double SHA256

txidĀ is the red box part,Ā prefix/postfixĀ is everything before/after it, respectively.Ā ||Ā is concatenation.

txid is the red box part, prefix/postfix is everything before/after it, respectively. || is concatenation.
A Transaction

We can now prove a transaction descents from a given transaction by verifying a single short proof regardless of the length of the transaction chain, without tracing all the way back.

A simple NFT token protocol

Let us construct a simple NFT token using the above approach. An NFT is minted in an issuance transaction, a.k.a., a genesis transaction. For simplicity, let us use only only one input and one output in each transfer transactionĀ³.

A simple NFT token protocol

When Alice transfers an NFT to Bob, she constructs a transaction with Bob as the receiver and hands it to Bob directly off chain. Thanks to the peer-to-peer nature of Bitcoin, she also sends an SNARK proof along with the transaction. Alice can generate the proof without tracing to the genesis transaction as we explained earlier.

Bob only accepts the NFT if both checks pass:

  1. he validates the transaction usingĀ SPV, similar to a regular bitcoin payment
  2. he verifies the proofā“.

Without the first check, an attacker can create alternative transaction chain originating from the genesis transaction, but isĀ notĀ on the Bitcoin blockchain. Without the second check, the token transaction may not link to the genesis transaction.

The proof is of constant size of only a few KBs and can be verified within seconds regardless of the chain length, incurring negligible overhead. The token transfer is effectively instant, just like a regular bitcoin payment.

Prover time

The most time-consuming part of recursive SNARKs is generating a proof, which can be up to a minute on a resource-constraint device. To enable instant token transfer, a proof can be pre-computed as soon as a token is received by Bob, so it is ready when Bob transfers it to the next owner. In case where Bob needs to send the token to Charlie immediately after receiving it from Alice, he can send the old proof received from Alice and have Charlie verify the last two links in the transaction chain, without generating a new proof as a fallback.

Implementation

We have implemented the recursive SNARK usingĀ snarkyjsĀ as below.

Recursive B2G Proof

To start, we need to first compile the program to get the verification key. Note that there isĀ noĀ trusted setup.

The key can be made public at a central registry associated with the genesis transaction, or it can be placed in another output of the genesis transaction.

TheĀ genesisĀ method starting from Line 5 is called to generate the initial proof, which simply checksĀ txid0Ā is the genesis transaction id at Line 9.

TheĀ transferĀ method starting from Line 13 is called to generate a new proof attesting to:

  • the last proof is valid at Line 17
  • the current transaction spends the last transaction at Line 18 and 19.

Finally, we can verify a proof against the verification key.

The full code can be found inĀ this Github repo.

Summary

We only present a simple NFT example using recursive SNARKs. It can be extended to a directed acyclic graph (DAG), rather than a chain of transactions. It may also be extended to fungible tokens or any other use cases where a user needs to efficiently ensure a transaction can be linked to some ancestor transaction.

Acknowledgements

We thank nChain for sharing the original idea of applying recursive SNARKs to the B2G problem. We also thank Gregor Mitscha-Baude ofĀ O(1) LabsĀ for helping with the SHA256 circuit implementation.

***

NOTES:

[1] WP1590 Transaction Chain Proof, M. S. Kiraz and O. Vaughan, patent pending GB2200400.6.

[2] In a more general form, transactions form a directed acyclic graph (DAG), making solving B2G even more computationally intensive.

[3] This can be enforced in a smart contract or the SNARK circuit, or both. In the former, we can use theĀ OP_PUSH_TXĀ technique to limit the number of inputs and outputs in all transactions descending from the genesis transaction. For example, we can enforce that any NFT transaction has two inputs and one output. The second input covers transaction fee.

[4] Optionally, the proof verification can be done on chain. It only requires implementing the verifier in theĀ snarkyjs proof system, similar to theĀ Groth16 verifierĀ we have implemented.

Watch: The BSV Global Blockchain Convention presentation, Smart Contracts and Computation on BSV

YouTube video

New to blockchain? Check out CoinGeek’s Blockchain for Beginners section, the ultimate resource guide to learn more about blockchain technology.