Perun Channels coming to Nervos CKB

Perun Network
PolyCrypt
Published in
10 min readMar 24, 2023

--

An in-depth description of the Perun project on Nervos.

The Perun channel framework can be used to make transactions more scalable and to enable a plethora of use cases. The first step towards more advanced use cases like payment networks, blockchain interoperability or application channels is, however, a payment channel. PolyCrypt has received a grant from Nervos to implement Perun on CKB. In this article, we outline how we go about this, what will be possible and how you can use channels soon! We are excited to extend Perun channels to Nervos and believe that we can make a big splash in this striving ecosystem.

Authors: Jan Bormet, Norbert Dzikowski and Marcel Kaiser

Why Payment Channels?

This section aims at a brief overview of the usages and benefits of payment channels for UTXO-based chains, especially Nervos, before we take a deep dive into how we implement Perun on Nervos layer 1.

To remain in the analogy so elegantly lined out by Nervos, imagine a nervous system that, in addition to myelin coatings making interactions smoother, is also enhanced with super-conducting molecules or nano-sized gold particles. The increase in information throughput (i.e. transactions) increases the performance of the entire system.

Perun’s payment channels should build the foundation for highly performant off-chain transaction processing on CKB. While payment channels are already available for the EVM-compatible Godwoken and can also be used there, the objective of this project is to bring them to Nervos layer 1 blockchain as well. It will benefit the main layer in the following ways:

Cost-effectiveness: Payment channels can significantly reduce transaction fees since only the final settlement is recorded on the blockchain.

Instant transactions: Payment channels enable fast transactions between parties, as they do not need to wait for CKB confirmations.

Increased privacy: By conducting transactions off-chain, payment channels can help protect the privacy of the parties involved.

Further evolutions of channels (app channels, virtual channel networks, cross-chain channels) will of course add massively to the feature set. These benefits make CKB ready for more use cases revolving around payment in the future.

Micropayments: Payment channels can enable micropayments in applications such as online games, content-sharing platforms, and social media platforms.

Online marketplaces: Payment channels can facilitate transactions on online marketplaces by allowing buyers and sellers to conduct multiple transactions without incurring fees.

Payment gateways: Payment channels can be used as payment gateways in e-commerce platforms, enabling seamless and cost-effective payments for users.

The following sections provide you with a deeper understanding of how we will make Perun channels a reality on Nervos.

Implementation

This grant aims to integrate Perun payment channels with CKB. This will foster fast and secure payment settlement on Nervos. As part of this grant, we will adapt the go-perun framework so that two-party single-asset payment channels between users on Nervos can be created, processed, closed and disputed.

Protocol specification

The following protocol specification will outline how the Perun protocol for payment channels will be adapted and realized using the CKB Cell Model. We want to note that if there are multiple solutions given for any of the following sub-problems, it can be assumed that our initial implementation will use the simpler solution first unless we explicitly mention otherwise. This tends to keep our focus on security, and optimizations are only done afterward. The KISS design principle applies.

Preliminary

The diagrams will use some abstractions for the CKB Cell Model, which eases the formalization and explanation of the protocol adaptations. E.g., we refrain from discussing the explicit transaction structure and the fact that the data of a given cell is in reality stored in a parallel array of a transaction. What follows are explanations of the required abstractions.

It is assumed that the reader has a basic understanding of CKB’s Cell Model. This includes knowledge about Lock Script, Type Script and their execution contexts.

Cell: A cell carries the capacity (CKBytes), Lock Script, Type Script and Data.

Data: Arbitrary bytes.

The Perun protocol can be reduced to five steps, each of which will have a dedicated section showcasing how we consider realizing Perun on CKB.

Perun Deployment

CKB’s unique design and usability allow us to deploy the channel logic into a reference cell, which contains the Smart Contract/Script code. At the time of writing, we are still unsure whether or not we will split up the Smart Contract implementation into a PerunLockScript & PerunTypeScript. Conceptually, we would like to adhere to CKB’s best practices and extract the access right management to its own lock script, which is associated with a Perun-type script upon channel opening.

We will consider this split in the following but want to mention that it is possible for us to keep the Smart Contract unified into a single type script if there are simplifying arguments to be found later down the line.

PerunLockScript

The PerunLockScript shall handle the access rights to a channel’s live cell. It holds that any channel participant is allowed to consume a live channel cell as long as he can prove to the lock script that he is indeed a participant of said channel.

This is done by committing the public identifier of each participant in the PerunLockScript.args field, s.t. any on-chain TX which tries to consume the live channel cell has to contain a witness with the proper proof.

For the Perun protocol to work, it is mandatory that only one live cell for a given channel id exists at any time. We will use the PerunLockScript.args field to store the channel id together with the parameters and signatures of all required parties, to ensure this invariant holds as long as there is at least one honest user.

Only, if every participant is colluding with each other, can a channel be created with the same ID. But this would lead to every party being malicious, which makes any security guarantee obsolete.

PerunTypeScript

The PerunTypeScript shall handle the validation logic for state transitions. It works together with the PerunLockScript in the sense that both Scripts know about the channel ID they were instantiated for. Furthermore, the PerunTypeScript will ensure that only ever a maximum of one live cell for the managed channel can be created in the output.

The validation logic for state transitions does not change in this design.

Channel Funding

Channel funding is the process of collecting funds from all channel participants securely. This includes the possibility of aborting a channel funding and reimbursing all users with their already done investments.

Funding in a UTXO-based system allows for multiple approaches. We will consider two approaches with increasing complexity.

Sequential funding of a channel in a predetermined order. Users who want to engage in a payment channel with one another decide on an order of funding prior to funding the channel on-chain. This funding commitment is reflected in the channel’s opening parameters.

Note: We left out showing auxiliary inputs and outputs for other cells containing the assets which get funded and redistributed, for brevity.

The above diagram shows how an opened channel with capacity CN and initial channel state CS, stored in the cell’s data part is consumed by a transaction TX, which generates an output cell with capacity CN’ and a transformed channel state CS’. The capacity potentially increased, because the channel might use CKBytes as an asset to fund the channel.
Obviously, the PerunLockScript and PerunTypeScript were already deployed beforehand and the input cell for TX originates from a Channel Opening done by the first participant. This also results in CN containing the funding commitment of the first participant, while CN’ contains the funding commitments for the first and the successive user. Handling of a cell’s capacity regarding a Perun channel will be discussed in the Channel Opening section below.

Funding a channel in successive rounds requires a time lock, s.t. no user is able to block the funds of other users who already funded a channel, by ignoring his funding round.

CKB allows the creation of multi-sig transactions. Conceptually, users that want to participate in a channel can create a shared off-chain transaction, which can be signed by all participants together using their respective access rights to fund and open a channel in one go on-chain. Alternatively, multiple users can create transactions funding their own part in parallel. The PerunTypeScript would then ensure that those transactions are only valid if all participants funded the correct amount. In the case of channels containing more than two participants, this speeds up the process but requires incentive considerations to decide who submits the transaction.

Channel Opening

Every payment channel has to be uniquely identifiable on-chain. Since we plan to pre-deploy the Perun Smart Contract in a code cell, we require a way to parameterize the Smart Contract. The CKB Cell model has a convenient feature, which effectively allows instantiating a Smart Contract instance by passing proper arguments to the Script.args field. This is used by CKBs execution engine to group input and output cells and remove redundant script execution where not necessary. Coincidentally, this allows us to easily ensure the uniqueness and on-chain identification of a living payment channel, by passing a ChannelID as the script argument. The execution context for CKB then allows access to grouped input and output to guarantee that no forks of a living channel can be created.

On the topic of a cell’s capacity. CKBytes not only serve as a native asset which can be used in payments but it is also required that a cell always contains at least as much CKBytes as is occupied by the cell’s storage. This lower bound for CKBytes has to be considered upon channel creation and can be considered ahead of time. The sizes of the data structure of a Channel’s State together with the hashes in a cell are constant upon creation and persist until the Channel is closed and dead. Initially, we will let the initial funder of a channel carry the capacity cost. This will be reflected in the PerunTypeScript, s.t. the initial funder is guaranteed to regain his investment.

Channel Update

Updating a channel happens entirely off-chain. Since CKB does not impose any strict encoding rules, this requires no special attention to the protocol implementation itself.

Channel Dispute

CKB allows access to block headers from on-chain code. It is guaranteed that all block headers which are referenced in a given TX exist and are already committed on-chain. If the previous conditions are not met, the TX cannot be validated.

For Perun channels, we require relative time locks with the added capability of updating them after on-chain disputes are resolved or ongoing. In CKB, it is convenient to access the time from required TXs as stated above, which makes it straightforward to handle channel disputes. We will likely use a timestamp-based approach for our relative time locks, but generally speaking, it is also possible to use epochs or block height.

In detail, we will access the time of input cells via its referenced block header bn_o. Together with an additional block header bn_n added to the consuming TX, we can compare the original time in bn_o with the time in bh_n.

A note on the transaction since field: A TXs since field cannot be used for this case because inputs are required to possibly be consumed before the time lock is done. The time lock in question is only an assurance for Perun users to eventually force close the channel if other parties do not respond.

Channel Close

Channel closing on CKB has the added complexity of properly handling and redistributing CKBytes used in the channel opening to the correct parties.

Happy Channel Close

In the happy case, all parties agreed on a finalized state. This finalized state can then be used by one of the parties to commit an on-chain transaction executing the close functionality of the PerunTypeScript. Closing a channel will redistribute all required funds according to the finalized channel state.

Additionally, we require a way to reimburse all parties CKBytes which were lent as an upkeep for the on-chain channel state. The exact nature of storing this information is still up for debate, but possible options are the PerunLockScript.args field together with the channel ID, or altering the channel state and keeping it there.

The final decision will probably depend on whether we can make out a good place for static script information, which is not supposed to change over the course of a channel’s lifetime. Currently, PerunLockScript.args seems like the ideal choice for this.

Closing a channel will not create a new live cell with the PerunLockScript and PerunTypeScript. Only live cells containing the proper assets are created.

Forced Channel Close

Force closing a channel is subject to the same CKByte consideration as the Happy Channel Close, with the addition of checking that the time lock expired. No other adaptations are required on the protocol level.

Implementation steps

On-Chain

The Perun Channel Contract will be implemented as a Script on CKB in Rust using the Capsule SDK. Implementing the script requires an adaption to the Perun protocol, such that it is compatible with the cell model used in CKB. Alongside getting to know Capsule and its workflow, challenges such as a Cell model compatible funding protocol, on-chain state handling and unique on-chain channel identification have to be addressed.

Off-Chain

Our Off-Chain part consists of both the contract bindings and the perun-nervos-backend implementing the necessary interfaces to connect with our go-perun core. We plan to use the ckb-sdk-go for this.

Remarks

This project is funded in a grant by the CKB. Find out more about the project here!

We hope we could inspire you with your use cases and potentially private usage of channel technology! We are always eager to receive feedback and to get in touch with new communities. If we piqued your interest, follow us on Medium, LinkedIn, Twitter or join our Discord channel! If you want to rather shoot us an old-fashioned mail, we’d love that, too. hi@polycry.pt

--

--