Corda Chain Snipping & The Reissuance CorDapp
By: Thor Gilman
Tags: R3, Cordapp, Corda, Blockchain, Distributed Ledgers

This post focuses on the new chain snipping feature released in Corda 4.7. The official Corda documentation for that feature can be found here. We will review what chain snipping is and how to go about utilizing the Reissuance CorDapp in your own CorDapps.

The Transaction Backchain

When you would like to update a state in Corda, you must provide the old version of that state as an input to the transaction. When you run the transaction, contract logic is executed to ensure that the old version of that state is allowed to evolve into the new version. However, how can we be assured that the old version of that state was created in accordance with proper contract logic? We need to go back in time and check the contract logic for how that older state was created. Then we need to check the contract logic for the state that evolved into the older state. And so on and so on. This will happen recursively until we reach the original issuance of that state. In Corda, this process is referred to as backchain verification.

While this might seem like a tedious process, there is good news. If a node has already verified a state’s transaction backchain and has that backchain cached in their vault, then there is no reason to verify the backchain each time. Only new participants to a state must retrieve the backchain from a counterparty and run backchain verification.

Below we can see an example of how backchain verification is performed. On the right, Alice is attempting to pay Bob with some Cash. To determine if the Cash is a valid state, Bob needs to recursively check the entire backchain for that Cash state to make sure it was properly issued onto the ledger.

Backchain Verification Example

While backchain verification is a critically important feature of Corda that helps to ensure the validity of data, it does come with some tradeoffs. For long-lived states, transaction backchains can sometimes become problematic.

If a state represents an asset, and that asset is traded between parties thousands of times (or more) then you can potentially run into issues with performance. If that state is traded to a new party that has not seen the states backchain, it will need to receive the entire backchain from its peers and recursively verify the chain all the way back to that state’s original issuance. While Corda 4.4 introduced bulk backchain fetching to remediate this issue through fetching entire transaction backchains in a single call, it is still time intensive to verify the contract logic for very long backchains.

Additionally, transaction backchains may cause concern for some privacy issues. In the previous example above with Alice & Bob, it’s possible that Dan may not want Bob to see the transaction he did with Alice to exchange the bond for cash. There is a concept of confidential identities in Corda which partially solves for this, however we won’t be exploring that here.

Chain Snipping

In order to prevent these issues with backchain verification, we can use a process called chain snipping. In this process, a party would decide on when to create a break in the chain, exit that state and then in a separate transaction reissue a new state with the same data. While this might seem like a simple solution, there are real concerns about what is the best chain snipping process to ensure ledger integrity. Because two different Corda transactions are running to perform chain snipping, it isn’t an atomic operation. While implementations of chain snipping have been created in the past, there hasn’t been a clear and secure way to perform it. Until now…

The Reissuance CorDapp

In Corda 4.7, R3 released the Reissuance CorDapp as the standard way to perform chain snipping in the safest way possible. A “requester” (some node that wants to snip a chain) will ask the original issuer of that state to reissue that state. As we’ve mentioned, chain snipping is not atomic as the issuer could choose not to reissue the state after it is exited. The Reissuance CorDapp solves this by having the issuer re-issue an encumbered (locked) state before the original state is deleted and allow the requester to unlock the re-issued state immediately after the original state is deleted. Encumbrance is a lesser-known concept in Corda that forces state A (the encumbered state) to only be consumed if state B (the encumbering state) is also present in the transaction.

Let’s quickly go through the entirety of the reissuance process. We will refer to the state we are reissuing as an “AssetState” but the Reissuance CorDapp is generic and can be applied to any Corda state.

Requesting a Reissuance (Tx 1): The requesting party who wishes to snip the chain creates a ReissuanceRequest state and shares that state with the issuer as well as the relevant transaction backchain. Accepting a Reissuance Request (Tx 2): The issuer will accept the reissuance request and issue an encumbered ReissuanceLock state as well as a new version of the relevant AssetState which is also encumbered. Because they are both encumbered, both states must be consumed in the same transaction. This prevents the reissued AssetState from being updated unless the ReissuanceLock is updated and set to inactive. (The issuer can also reject the reissuance request however we won’t be covering that in detail here). Exiting the original state (Tx 3): The requester will exit the original state using whatever exit command that state has. It is a requirement that there are no output states to this transaction. Unlocking the reissued state (Tx 4): Once the original state is exited, the requester can immediately unlock the reissued states as long as they provide the original state’s exit transaction as an attachment. This acts as proof that the state can now be reissued. Both the ReissuanceLock and the AssetState become unencumbered so that the AssetState can be used in the future. (Alternatively, if the AssetState is updated and not exited, then it is now impossible to unlock the reissued state and the requester should call a separate flow to delete both the ReissuanceLock and reissued asset state).

The below diagram depicts this process in more detail using Corda Design Language (CDL).