State Channels

close button

Part I

Unidirectional State Channel

Download quests in Questplay

A major limitation of blockchain technology is the expense and time delay incurred whenever a transaction is executed on-chain, especially on popular blockchains such as Ethereum. One solution is to take most of the interaction between parties off-chain, relying on the blockchain only to record or enforce a consensus. Such a solution, known as a state channel, works best when the parties involved can agree on an off-chain communication channel and intend to communicate many times before coming to an agreed-upon final state.

Payment Channel

A simple use case of a state channel, known as a payment channel, requires one user (the sender) to first deposit funds into the payment channel contract. The sender then uses an off-chain communication channel to send signed messages to another user (the receiver). These messages describe the total amount of funds owed to the receiver by the contract. Then, when the receiver wishes to withdraw their funds, they simply submit the most recent signed message to the contract. The contract verifies the message's signature belongs to the sender before transferring the receiver the appropriate amount of funds.

This type of channel, where only one party sends messages and the other only receives them, is known more generally as a unidirectional state channel.


Unlike the naive solution, where every transfer from the sender to the receiver is recorded on-chain, a payment channel ensures that the blockchain state is only modified once after the contract's creation - when the receiver is ready to withdraw. This solution reduces costs for users and increases transaction throughput while maintaining the security and immutability of the blockchain for the final state.

You will be implementing the functions of a payment channel contract, known as PaymentChannel, to help a mine owner pay her workers.

Payment Messages

Off-chain, the mine owner signs and sends messages to a worker to update the total amount of funds owed to the worker. These messages follow the EIP-191 standard.

message = abi.encodePacked( "\x19Ethereum Signed Message:\n", "52", address(paymentChannel), amount )

Each time, the mine owner wishes to pay her worker an additional amount of ETH, she signs and send a new off-chain message that corresponds to the new total amount owed. Signatures are signed using ECDSA, under the secp256k1 curve.

ABI of PaymentChannel



constructor(address payable _worker, uint256 _time) payable

Creates a PaymentChannel with msg.sender as the sender and _worker as the receiver. _time represents the time between the current time and the channel's expiration time. The ETH sent to the contract during creation is the pool of funds from which payments are made.

View Function


owner() → address payable

Sender of funds.

worker() → address payable

Receiver of funds.

expiration() → uint256

Expiration time. After this time, the channel can no longer be closed by the worker, and the owner can call timeOut() to retrieve their funds and close the channel.

isActive() → bool

Represents whether the channel is open or closed. An open channel is still in operation and can be interacted with, whereas a closed channel is no longer usable and cannot have its state changed.



addTime(uint256 _time)

Extends the time window for the worker to close the channel. Can only be called by the owner.


If the worker does not close the channel in time, transfer all funds to the owner and close the channel. Can only be called by the owner.

closeChannel(uint256 _amount, bytes memory _signature)

If _signature is valid, the worker receives _amount of ETH and the owner gets the remainder back. The channel is then closed. Can only be called by the worker and before expiration.

The full interface can also be found in interfaces/IPaymentChannel.sol.

Your Task

Implement PaymentChannel.sol as described in the ABI table above.

Run tests in Questplay

Create a payment system that ensures everyone gets paid on time…