Code Walkthrough for Generalised State Channels

Machinomy
Machinomy
Mar 30, 2018 · 3 min read

Last time we presented a framework for generalised state channels. This is a way to construct off-chain asset transfers between known participants. One could securely transfer Ether or tokens, non-fungible energy like kitties or titties, and whatnot using the same set of blockchain transactions. We cleaned up the code, made it tolerable in terms of gas, added human-readable tests, and are ready to present the implementation of the framework.

The code is in the machinomy/mc2 repository. It is a typical Truffle-managed contracts repository, with a familiar layout: /build, /contracts, /migrations and so on. Actually, it represents a fork of our payment channels contracts repo, so that later it could be merged with the upstream. The meat is in the /contracts and /test folders.

Construction of a state channel starts with the deployment of a Multisig contract. This puts a transaction on a blockchain, if all the participants agree with it. Our Multisig is restricted to just two participants. For an elaborate case, one could use a more advanced multisignature contract, Gnosis Safe.

Multisig exposes three methods:

doCall executes an ordinary call to the destination address. doDelegate executes a delegatecall. The latter is useful for a complex assets transfer from the Multisig to a subchannel contract, like moving funds to all the participants at once. The Multisig uses a separate contract for transferring logic. DistributeToken, for example, atomically sends ERC20 tokens to both parties.

Cooperative Case

  1. Create the Multisig;
  2. Move assets to the Multisig;
  3. Sign a Multisig transaction to move funds out of the Multisig;
  4. Execute it.

This kind of behaviour would be futile to assume in a cruel world. We must enforce honesty, and make cheating costly. The framework takes care of that.

Dispute

  1. Deploy Bidirectional,
  2. Move funds from Multisig to Bidirectional,
  3. Do a Bidirectional transfer.

These two transactions are signed, but not yet deployed to the blockchain. This would happen if such a need arose. The same set of participants could support multiple channels over time. The best way to prevent a replay attack is now a sequential Multisig nonce. After a few rounds of subchannels opened and closed, a malicious participant could deploy a wrong transaction with an allowed Multisig nonce. To prevent that, we fix the set of transactions in a Lineup.

It stores a merkleRoot of the transactions list. One could then conditionally execute a transaction. If it is contained in the merkleRoot of the list.

So, the preparation step is really this:

  1. Counterfactually deploy Lineup,
  2. Counterfactually and conditionally deploy Bidirectional,
  3. Counterfactually and conditionally move funds to Bidirectional,
  4. Do a Bidirectional transfer.

Now a participant is able to trust her funds to the Multisig. In the case of a dispute, Lineup and Bidirectional contracts are deployed to the blockchain. Then the parties update the Bidirectional state according to their transfer state. After that, the Bidirectional subchannel distributes the funds, thus resolving the dispute.

Conclusion

Machinomy

Micropayments for the Web of Everything

Machinomy

Micropayments for the Web of Everything

Machinomy

Written by

Machinomy

Micropayments for the Web of Everything

Machinomy

Micropayments for the Web of Everything