![](https://cdn.nodeguardians.io/backend-production/solidity_bg_fc76a87eed/solidity_bg_fc76a87eed.webp)
Standalone
State Channels
![](https://cdn.nodeguardians.io/backend-production/State_Channels_04_part2_c2709dd5dc/State_Channels_04_part2_c2709dd5dc.webp)
Part II
Bidirectional State Channel
In the previous section, we saw how to use a unidirectional state channel to enable a simple payment redemption system. It is also possible to support more complex off-chain interactions with bidirectional state channels, where all parties can both send and receive messages. Like before, the state channel is less concerned with how agreements are arrived at off-chain, and more concerned with ensuring that the final state is agreed upon by all relevant parties.
Counting Game
In the mines, the owner devises a simple two-player game to incentivize her workers to fill their carts faster. The rules of the game are as follows:
Two workers take turns loading ores into a minecart.
Each turn, they can load between 1 to 4 ores.
If the total ores loaded onto the cart is a multiple of 5, the cart spills a little, and two ores fall out.
The first player to get the total ore count to above 20 wins themselves a bonus pay.
Say we wish to implement this game as a contract. A naive implementation will require 1 transaction for each turn. This is expensive and slow.
A cheaper alternative will be to implement the game as a bidirectional state channel. Like the payment channel in Part 1, the channel is opened with a deposit of funds by the channel's creator (e.g., the mine owner). The parties then send signed messages to each other via an off-chain channel, describing the amount of ores in the mine cart.
At any time, either party can submit any of these signed messages to the contract to update the on-chain state, so long as the message describes a future state of the contract. Once there is a winner, the channel is closed and the winner receives the contract's funds.
![state_channels_02.webp](https://cdn.nodeguardians.io/backend-production/state_channels_02_1126b48788/state_channels_02_1126b48788.webp)
You will be implementing the functions of this contract, known as MineCart
.
Exchanged Messages
The messages exchanged between the parties should describe the total amount of ores already loaded onto the cart. Additionally, it should also include a turn counter (messageNum
) to ensure that no party can exploit the system by submitting older, yet still valid, states to the contract.
Like before, the message format follows the EIP-191 standard, and signatures are signed using ECDSA, under the secp256k1 curve.
bytes memory message = abi.encodePacked(
"\x19Ethereum Signed Message:\n",
"84",
address(mineCart),
totalOres,
messageNum
)
Each time either party wishes to update the on-chain state, they provide the game contract with a message that corresponds to the new totalOres
and messageNum
, with a corresponding signature signed by the other party. By verifying the signature, the contract can be certain that the new state has been agreed upon by both parties. If so, the contract doesn't need to know the details of how the parties arrived at this state to safely accept the state as true.
Withholding Messages
It is possible that one party may withhold messages from the contract, thereby preventing the game from advancing. To prevent this, the contract should allow:
The active worker to make their next immediate move without the other party's signature, so long as the move is valid.
The game to time out if the active worker does not make a move within a certain time frame.
These will be achieved with the load
and timeOut
functions.
The active worker is the worker whose turn it is to load the mine cart.
ABI of MineCart
Constructor | Description |
| Creates a |
View Function | Description |
| Address of |
| Address of |
| Total amount of ores already loaded onto the mine cart. |
| Current turn number. Starts at 1 (i.e., |
| Represents whether the channel is open or closed. |
Function | Description |
| Update |
| Load |
| If the current worker does not update the state in time, transfer all funds to the other worker and close the channel. |
Your Task
Complete the functions in MineCart.sol
as described in the ABI table above.
Run tests in Questplay
Submit work in Questplay
![](https://cdn.nodeguardians.io/backend-production/State_Channels_04_part2_c2709dd5dc/State_Channels_04_part2_c2709dd5dc.webp)
The miners are working again, but perhaps a bonus would encourage them to work harder…