Cryptoassets and The State of The Channel

If you are interested in reducing the amount of transactions committed to the blockchain to a minimum for privacy or efficiency reasons, you will eventually run into the concept of State Channel. This post is about state channels and presents a prototype we have created at @PokitDokDev using Hyperledger Sawtooth.

As most know by now blockchain is a technology that proposes a medium of interaction for parties who want to engage with one another. When two entities agree to use a blockchain, they first must decide the structure of their interactions defined by the possible states and transactions that are logically valid and authorized. The description of these states and possible transactions is commonly called a smart contract and the blockchain is in charge of executing the smart contract in a secure and transparent fashion. For more information on our view of Smart Contracts see "Why Smart Contracts Are The Asset".

The more users adopt a blockchain the more successful it is. But with this success come the problems of scalability and performance. Bitcoin, the most successful blockchain network, has predefined block size and a predefined rate of blocks mined by units of time. This has the consequence of limiting the volume of transactions that can be processed by the Bitcoin network. Since the demand for processing transactions is higher than the network can actually process, the transaction fees are increasing as a way to incentivize the nodes in the network to process transactions with the highest fees. When transferring a small amount of bitcoins, the high fees might be prohibitive, which is an impediment to the transaction neutrality of the network. To address this issue Bitcoin has a micropayment channel[2] mechanism using the multisig and locktime features.

Another feature of most popular blockchains is that the underlying ledger is publicly available. However, not all businesses users want their transactions be visible on the network, especially if the information is sensitive. It would be convenient to have a mechanism to submit only the state of agreement between parties, without all the details of the transactions. Privacy is a major concern for businesses who are considering moving some of their infrastructure to a public blockchain. This problem can be solved if parties can agree to abstract their transactions by mapping every transaction to a token transfer between them. As a result, a trail of transactions becomes equivalent to a sequence of token transfer on the blockchain.

State channels is a blockchain concept that promises to address the two issues of efficiency and privacy discussed above. The idea is simple: reduce the amount of information transitioning on the blockchain to its bare minimum: the initialization of the smart contract and its closing. Everything in between happens privately -- offchain -- between the parties involved. The only thing the parties have to do when they interact offchain is keep track of their interactions through a trail of transactions that is progressively acknowledged and signed by all of them. At the closing phase, the trail is submitted by involved parties and can be verified by the blockchain and can be used to resolve conflicts if need be. When the transactions in the trail consist of small payments, this is called a micropayment channel, but the transactions in the trail could also be the state of the smart contract. This is when we talk about state channel. These concepts have been put forward by blockchain platforms like Lightning Network[3], Raiden Network[4] or Æternity[5]. In the remainder of this post, we further explain how to design a simple state channel capability based on a prototype we implemented in Hyperledger Sawtooth[1].

Let's first look at what is a verifiable trail of transactions. The design is very simple but could be easily generalized to more sophisticated trail formats. In the following, we suppose Alice (A) and Bob (B) want to interact with one another and record their interaction on a trail. Initially, the trail contains no transactions but is seeded with a unique identifier associated with the channel. Every time A or B want to add a message m to the trail T, both must acknowledge the addition of m to T by signing the new trail using public/private keys. As the trail can grow arbitrarily large, it is important to fully minimize the signature process and to not sign the entire trail. Instead A and B only sign the concatenation of 1) the hash of the two signatures of the latest message in T and 2) the message m itself. Notice the similarity between this process of signing a trail of transaction and how the blocks are chained in a blockchain.

#

message

signatureA =A.encrypt(Digest[i-1],message[i])

signatureB = B.encrypt(Digest[i-1],message[i])

Digest =

hash(signA, signB)

0

NA

NA

NA

e38d805c

1

Transfer 7 tokens from A to B

f445ea70

020bcbbb

48948268

2

Transfer 3 tokens from B to A

3e16f9fd

e862e59d

6563c40e

3

Transfer 5 tokens from A to B

cc87b04d

dccff3cd

8571df36

4

...

...

...

...

The verification of the trail is done by traversing the signed trail backwards, and by checking that every message is correctly signed using the public keys of A and B, and that the digest is correct for every entry line:

There are two interesting properties that come with this design. The first one is that anyone, with knowledge of the public keys of A and B, can verify that every message has been acknowledged by both A and B. The second property is the ability to compare two trails to find the stronger one. This is possible because trails are monotonically increasing by design. For example, suppose B decides to submit a partial trail because it is more advantageous to him, then A would still have the option to submit a more complete trail, and a third party could compare the two submitted trails and find out that A's trail is more complete.

Now that we have a trail design in place, we can describe how it plays with the main part of the state channel. Here is a scenario describing a common interaction between Alice and Bob using a state channel:

Alice and Bob agree to use a blockchain and a state channel smart contract with Jane (J) as the arbitrator.

Alice submits a transaction indicating that she wants to initiate a state channel with Jane, she indicates that the state channel expects Bob to participate and she indicates a specific amount of tokens to escrow with Jane:

Alice.init(arbitrator=Jane,roleB=Bob,amount=42)

Bob submits a transaction to join the state channel by adding an amount of tokens in escrow with Jane:

Bob.coinit(arbitrator=Jane,amount=37)

Outside the blockchain, Alice and Bob exchange goods and/or services and create a trail of transactions reflecting their interactions. Nothing is submitted to the blockchain during this phase.

Once Alice and Bob have finished their interaction offchain, they close the state channel by both submitting their trail. If Alice and Bob are satisfied they will submit the same trail, otherwise, in case of dispute, they are allowed to submit two different trails.

Alice.close(arbitrator=Jane,trail=trailA)

Bob.close(arbitrator=Jane,trail=trailB)

Since Jane the arbitrator has access to both closing statements, she sends a transaction to finalize the state channel and process the strongest closing statements submitted.

Jane.finalize()

Hyperledger Sawtooth is a blockchain platform that is language agnostic with respect to the programming language used to develop smart contracts. We have implemented full consensus and smart contract acceleration in HyperLedger Sawtooth as referenced in Full Consensus and Distributed Ledger Hardware Acceleration. The transactions are executed by a transaction processor that applies modifications to a key-value store. To illustrate how transactions listed in the scenario above are implemented in Sawtooth, let's look at the code for the finalize() transaction:

The scenario described above uses a specific sequence of transactions, a combination of init(), coinit(), close() and finalize(). During the life cycle of a smart contract, certain transactions can be used only once like init(), whereas others can be used more than once, like close() that must be used twice. The sequence of transactions used in the scenario is not the only one that would have been acceptable. It would be legitimate for Bob to submit the closing statement first and then Alice to submit hers. These two sequences of transactions are both acceptable and are described succinctly as a state diagram:

Every circle corresponds to a state of the smart contract in its life cycle. During its execution, the smart contract transitions from state to state according to the transactions processed. This state diagram not only identifies the sequence of transactions that are acceptable, but also rejects the sequences considered pathological, like closing before initializing, or Alice attempting to submit two closing statements. This state diagram does not capture all the possible scenarios. One scenario that is not captured is having Jane finalize the state channel before Alice or Bob have the time to submit their own closing statement. In that case we would add two transitions from the states ClosedA and ClosedB to the state Finalized. While the adoption of the state diagram approach is not strictly necessary, it might be good practice in an expressive language agnostic smart contract environment like the one provided by Hyperledger Sawtooth.

That's all for this introduction to State Channel. This concept is inevitable in the blockchain world. It relates to numerous concepts like privacy, signatures, arbitrator, sidechain, hashlocks, and it is so flexible that it can be adapted to many situations. It's definitely worth adding to the smart contract developer toolkit and I hope this post will make you think about all the possible applications.

We see several benefits in creating smart contracts to take advantage of these processes in Permissioned Blockchains. In future blogs we will be writing about how we are processing cryptoassets with respect to State Channels.