A State Channels Adventure with Counterfactual Rick! (Part 1)
Wubba lubba dub dub! It’s Counterfactual Rick! Listen up Morty, today I’m going to take your pathetic excuse for a brain and take a giant steaming state channels dump in it. All this time you’ve been building your dapp with absolutely no idea of how it would scale, just waiting for someone to come along and save you. Fucking hopeless. Well, today is your lucky day because Counterfactual Rick is here, baby! Pay attention on this fun science adventure and maybe you’ll come out the other side useful to humanity instead of remaining a weak-minded fool dependent on others to scale your shit.
Got it? Good. Now before we do anything, I need you to take these seeds…
So the first thing you need to know is the basics. You know the basics, right? You don’t know the basics. Oh jeez this is going to take a while.
Take my portal gun and don’t come back until you have the prerequisite state channels knowledge to even breathe the same air as me. What are you still doing here? Go!
State Channels Resources
- Robert Mccone (Oct. 2015, blog) — Ethereum Lightning Network and Beyond
- Jeff Coleman (Nov. 2015, blog) — State Channels (see also: discussion on /r/ethereum)
- Heiko Hees (Dec. 2015, talk) — Raiden: Scaling Out With Offchain State Networks
- Jeff Coleman (Dec. 2015, interview) — Epicenter Bitcoin: State Networks
- Jehan Tremback (Dec. 2015, blog) — Universal Payment Channels
- Martin Koeppelmann (Jan. 2016, slides) — Scalability via State Channels
- Vitalik Buterin (Jun. 2016, paper) — Ethereum: Platform Review (page 30)
- Ameen Soleimani (Sept. 2016, talk) — An Introduction to State Channels in Depth
- Jeff Coleman (ongoing, wiki) — State Channels Wiki
- Jeff Coleman (ongoing, code) — Toy State Channels
- Heiko Hees (ongoing, code) — Raiden Network
- Sergey Ukustov (ongoing, code) — Machinomy
- Liam Horne and Jeff Coleman (Oct. 2017, blog) — Generalized State Channels
- Josh Stark (Feb. 2018, blog) — Making Sense of Ethereum’s Layer 2 Scaling Solutions
- Li Xuanji (Feb. 2018, talk) — Generalized State Channels
- Nathan Ginnever (ongoing, code) — SpankChain: General State Channels
Today’s adventure is going to cover generalized state channels and counterfactual instantiation, so if you want to go back to school to learn how payments channels and vanilla state channels work, start with this Machinomy post and Ameen’s talk.
Alright Morty, hold on to something because our adventure begins now!
Why Generalized State Channels and Counterfactual Instantiation Matter
So if you were a primitive idiot rubbing sticks together trying to build state channels technology for the first time, you would probably deploy whatever single-purpose state channel contract you needed for your own dapp and call it a day.
This might work for a while, but then eventually you would want to deploy another type of state channel, or upgrade your original channel setup. Because progress Morty. Things change. You don’t want to get left behind do you Morty?
When you go to deploy your new state channel system, you would have to deploy entirely new smart contracts Morty. This is because your primitive mind didn’t plan ahead and now you have to start from scratch. And each of these new contracts would hold funds, so each contract would have to through a rigorous smart contract audit. An audit Morty! Do you know how expensive smart contract audits are in the current ICO bubble? It’s absurd Morty.
And think about your users Morty. If they wanted to upgrade to your new state channels system they would have to take their money out of your original smart contract and move it to your new one. That’s two onchain transactions per user Morty. That’s a lot of gas Morty.
Example: Upgrading Payment Channels
So each of your primitive state channels contracts have a bunch of the same functions. Do you know what a function is Morty? Take a look at this diagram:
This diagram shows the functions for a progression of payment channel systems. The first one is for the simplest possible payment channels: unidirectional and ether-only. The second one upgrades it to allow for token transfers, and the third upgrades it further to allow ether and token payments in both directions.
Did you notice how they have mostly the same functions Morty? That’s because the contracts are basically the same. The key difference is that when upgrading to v1 for token support, the openChannel function needs to understand how to accept tokens and credit the sender, isValidUpdate needs to accept token transfers as valid as well as ether, and the closeChannel function needs to be able to distribute tokens as well as ether based on the final balances.
When upgrading to v2 for bidirectional support, the big change is adding a joinChannel function so both channel participants can fund the channel, and updating isValidUpdate to accept ether and token transfers in both directions as valid.
Intro: Generalized State Channels
You can do better than the primitive idiots who upgrade their state channels by deploying entirely new fund-holding contracts by using a “Bond Manager”. The Bond Manager is a smart contract that provides a “generalized state channels framework” that anyone can can use for whatever state channel system they want to deploy. It acts as the backbone for all integrated state channels systems, holding all the funds and providing the common functions needed by all state channels systems.
Now, in this setup you still need to deploy a new smart contract each time you want to upgrade, but the new contract won’t hold funds and is only responsible for the setState and isValidUpdate functions which are unique to each state channel system. This means you can save time and money developing, testing, and auditing each new state channels contract. Think of the savings Morty.
We call these smaller, more specific, state channel smart contracts “interpreters” Morty. This is because they help the Bond Manager interpret the final channel state and figure out how to distribute the deposited funds.
Using a Bond Manager makes upgrading channels faster and cheaper from a developer standpoint, but it does nothing to fix the user experience issue of needing to do two onchain transactions when you want to upgrade from one channel system to another. This is because you still have to specify which interpreter contract you want to use when you call openChannel, and then you still have to call closeChannel to exit the channel and then call openChannel again to move on to the new interpreter contract.
Whatever could you do about this, I wonder? Maybe hire someone smarter than you to do it better than you could possibly do it in a hundred years? Maybe someone with the solution in their fucking name? That’s right, it’s time for COUNTERFACTUAL RICK to save the day, baby!
Intro: Counterfactual Instantiation
Time to blow your fucking mind Morty. What if instead of the Bond Manager forcing you to pick a specific state channel system to join, it allowed you to enter into a “meta channel” that encompassed all possible state channel systems, even ones that don’t exist yet? Well that’s exactly what counterfactual instantiation lets us do Morty. This shit is the FUTURE!
When you join a meta channel, you can then enter into any number of “subchannels” that are each enforced by interpreter contracts. So let’s say you and I take a bunch of our money and join a meta channel together Morty. We could then decide to move some of our money into a bidirectional payment subchannel and pay each other, bet some of our money on the outcome of a chess game in a chess subchannel, or have our cute little kittens fight to the death in a cryptokitties battledome subchannel. We could do all of these at the same time Morty! All from inside the same meta channel! There are infinite possibilities to behold inside a meta channel Morty!
Alright Morty, I can see you frothing at the mouth, so I’ll share my secret Szechuan sauce that makes this all work. It’s called Counterfactual Instantiation Morty!
The reason you and I can join subchannels from the meta channel is because the Bond Manager can, for any given subchannel, deploy the interpreter smart contract that governs it to the blockchain and then use the deployed interpreter contract to resolve any disputes that may arise for that subchannel. So when we join our subchannel, we don’t actually deploy the interpreter contract to the blockchain Morty. All we are doing is agreeing that in case of a dispute, either of us could deploy it.
Don’t you see Morty? The interpreter contract. It only exists counterfactually Morty. When we agree to join a subchannel together we are “counterfactually instantiating” its interpreter contract. The interpreter contract only exists in our meta channel, and we only deploy it if we have a dispute Morty. And if we play nice we don’t need to deploy it at all. We could have a hundred different subchannels, each governed by its own interpreter contract, and if we never have a dispute we would never need to a deploy a single one of those interpreter contracts to the blockchain Morty.
And chances are that you never need to deploy interpreter contracts to the blockchain. Because Game Theory Morty. The threat of being able to deploy an interpreter contract is enough to never have to, because both people know exactly what will happen if it does Morty. Just like we know exactly what would happen if the residents of my microverse battery ever get off their flooblecranks.
Think back to the example of upgrading payment channels Morty. If you use a meta channel, then one of your users could just enter into a v0 unidirectional ether-only payment subchannel with you. When the user wants to upgrade to v1 for token support, they would be able to close the v0 payment subchannel and open the v1 payment subchannel all offchain. Your users don’t need to make two blockchain transactions to upgrade channels anymore Morty. There’s no gas cost Morty. I told you I could do it Morty. Counterfactual Rick for the WIN! YEEEAAAAAA!
This isn’t even close to over, you idiot of a Morty. I’m just tired and need a nap. I’ll be back next week with Part 2 so you can learn the gory details about how generalized state channels and meta channels and counterfactual instantiation all work. Until then, check out this repo from SpankChain — they have the most advanced state channels system in the galaxy Morty. And watch this overview they put out. And this walkthrough of their code Morty. I’m tired Morty. Good night.