🚎 The State Of State Channels — Issue No. 102

Last month, in issue number 99 of this newsletter, we discussed Validium, a new layer 2 scaling approach being developed on Ethereum. We looked at Validium in the context of other layer 2 approaches that make different sets of tradeoffs, namely: zkRollups, Optimistic Rollups, and Plasma. Link.

Left out of that discussion, though, was the grandaddy of layer 2 scaling techniques: state channels. While they didn't fit neatly in the framework I was presenting in that issue, state channels are nonetheless a noteworthy technology being leveraged in different ways on both Bitcoin and Ethereum.

In this edition of the newsletter, we'll learn the basics of how state channels work, and why they're complex to implement. We'll discuss how they're used in Bitcoin's Lightning network for payments, and how they can be leveraged for more complex applications when backed by Ethereum smart contracts. We'll close by looking at why state channels haven't seen much adoption to date, but why that could be poised to change.

How State Channels Work

The core premise of state channels is surprisingly simple to understand. Instead of using on-chain transactions, parties who wish to transact regularly with each other can first lock funds in a smart contract, then exchange signed messages off-chain which update the state of who owns which funds. Any number of transactions can occur off-chain, at a rate which is limited only by the parties' ability to exchange signed messages. Whenever any one of the parties wants to, they can exit the channel by submitting the latest signed state to the on-chain smart contract, which validates the signatures and distributes funds according to the agreed upon allocation.
Image
Let's look at the simplest example of state channels: simple payments between two parties. We'll call upon our old friends, Alice and Bob. Let's assume that these two have reason to exchange funds regularly. They both deposit funds— we'll say 5 ETH each for this example— to a smart contract on the base chain. Alice signs a message paying Bob 1 ETH, meaning she updates her balance to 4 ETH and his to 6 ETH. Alice sends the signed message to Bob, who signs the updated state and returns it. Later, Bob pays Alice 0.5 ETH by decrementing his balance to 5.5 ETH and incrementing hers to 4.5 ETH. He signs his message, sends it to her, and she then co-signs and sends it back.

This same process repeats, as frequently as Alice and Bob like, and for as long as they'd like. Notably, micropayments are possible in this system. Since there are no fees until the channel is settled, sending 1,000 payments of 0.001 ETH is as economically viable as sending a single payment of 1 ETH.

Eventually, Alice and Bob's economic interactions come to a close. The last balance signed by both parties leaves Alice with 7 ETH and Bob with 3 ETH. She submits this last co-signed state to the base chain, which first validates that both parties have indeed signed it with their private key, then distributes funds to both parties according to the balances represented. Simple and elegant, right? Well, yes, but we've glossed over some key details.

Devils in the Details

Like many things in the blockchain world, state channels work swimmingly when all parties act in the way they're expected to. But if all parties always acted in the way they're expected to, we wouldn't need decentralized cryptonetworks in the first place! The whole reason blockchains exist is to allow parties to transact in a trust minimized way, and that necessitates preventing malicious behavior in an adversarial environment.

For state channels, accounting for those adversarial conditions adds an enormous amount of incidental complexity, even in our simple two-party payment channel example. Consider this scenario: What if Bob pays Alice 2 ETH in return for some good or service, but once he's received his merchandise, he uses an outdated state— one signed before he'd made his latest payment— to close the channel on-chain. Both Alice and Bob signed the earlier state, and the smart contract doesn't know the later state exists. This would allow Bob to claim funds Alice believed belonged to her.

To prevent this bad behavior, our system could require both users sign a special "final" state that explicitly marks the channel as closed, and only distribute funds when such a state is submitted. What happens, then, if one party refuses to sign such a final state, or simply disappears or goes offline for an extended period of time? Both parties' funds would be stuck in the smart contract.

To avoid such "griefing" attacks, it needs to be possible for parties to exit channels and withdraw their funds with intermediate states. Most implementations add a waiting period for fund disbursement when the channel isn't explicitly closed by both parties. This gives each party the opportunity to contest a withdrawal by presenting a more recent state, signed by both parties, thus proving the other party was attempting to cheat. Such a proof often comes with a penalty for the offender.

This is a workable solution, but we can see how much complexity it's already added. For a simple two-party payment channel, both parties must now monitor the chain constantly to ensure the other party hasn't tried to cheat. They must maintain cached copies of their latest states and be prepared to make an on-chain transaction to prove that cheating has occurred. Furthermore, if the counter-party stops responding, a user must be prepared to wait out the challenge period before getting their funds back.

Beyond Two-Party Payments

Now, here's the thing— two-party payment-only state channels are pretty limited in their usability. How many economic relationships involve repeated payments, back and forth between only two parties, where both parties would be comfortable committing a chunk of their money exclusively to serve the purpose of exchanging payments with that specific counter-party? Probably pretty few.

To make state channels more useful, we need to expand what they can do. There are two ways in which we can do so. One is to increase the number of parties who can participate in a channel. The second is to expand the capability of a state channel beyond just payments, enabling more generalized kinds of state, and thus more complex use cases.

Let's look at the expansion of participants first. The simplest way to do this would be to have one large channel, where all participants deposit to the same contract and sign all updates. For obvious reasons, this approach fails to be useful beyond a small number of users. Instead of a single channel, we need a network of channels.

Lightning: A Payment Channel Network

To really make payment channels useful, Bitcoin's Lightning Network makes them routable. Any given user might open channels with one or more nodes, which anyone can operate. Payments then "hop" between nodes, with each node shifting funds to the next, until they arrive at the intended receiver. For their trouble, each node takes a small fee along the way. Link.
Image
As you can imagine, such a system comes with an explosion of complexity, and Lightning Network has taken a long time to work out its kinks. It still has a ways to go, and adoption has stalled over the last 12-18 months. Honestly, I'm not sure if Lightning will gain traction or not, but the technology that's been built out is impressive nonetheless.

While Lightning has made state channels more useful by making payments possible across a whole network of participants, others have taken a different tact: keeping channels limited to small groups, but expanding what they can do to include more functionality.

Putting the State in State Channels

By including specific rules about what kind of state transitions are allowed— rules that can be validated and enforced in an on-chain smart contract in case of a dispute— state channels can be used to build multi-party decentralized applications with the same performance as traditional apps. Link.

The most common examples for envisioning the kinds of apps which are possible with such state channels tend to be games. Imagine, for example, Alice and Bob want to play a game of chess and put some money on it. With a smart contract encoding the rules of chess, and some basic data structures used to represent the state of the board, Alice and Bob could deposit their bets and proceed to play a full game of chess off-chain by exchanging signed messages. When the game ends, the channel can be closed, and the winner can receive their payout.

If either party attempts to cheat, the other user has the smart contract mediation to fall back on. By presenting the recent states, they can prove a valid game state, and ultimately close the channel. In a normal scenario, though, the game would proceed with the performance expected of any web-based chess application. The only difference would be on-chain transactions at the beginning and end of the game to open and close the channel.

Whither Usage?

The relative simplicity of state channels as a concept means they were one of the first scaling solutions to be proposed and researched in the blockchain world. After years of research, though, they're still not adopted widely in any meaningful way. What gives?

As I've tried to impress upon you, the concept of state channels is relatively straightforward, but the actual implementations involve quite a bit of complexity, especially if you're trying to build something actually useful. Handling the many edge cases associated with malicious behavior, while also implementing something people actually want, has proven quite difficult. It's possible we haven't seen much adoption yet because it's taken so long to work out robust, usable implementations.

I wouldn't give up on state channels just yet. For one, Lightning continues to mature and may yet see greater adoption. Additionally, there are a number of teams pursuing generalized state channels in the Ethereum ecosystem, which would make it easier to build state channel based apps. Link.

One such project was formerly called Counterfactual, but is now (confusingly) named simply "State Channels." I've had a chance to dive into this project recently, and while it's still under development, I'm impressed with the progress they've made. By abstracting over the complex bits like dispute resolution, "State Channels" makes it easier for developers to focus on the rules and data structures that are unique to their app. Link.

If toolkits like this continue to become more approachable for everyday developers, we could see some real creative applications emerge. In particular, there are a whole host of competitive games that could be built. I'll be keeping my eye out for this in the months ahead.