(This is a general-public-facing companion to the June 2026 Morph Channel paper. The paper is the canonical specification; this article is an audience-friendly explainer. Also there is an original draft proposal written in Chinese )
The one-line summary: Morph Channel is a payment-channel design for Nervos CKB. It does three things at once:
- splits the “money box” from the “evidence box” ,
- pays transaction fees from a separate sponsor wallet instead of from the channel itself,
- keeps the channel’s books in five strictly separated ledgers.
Around that central design, it then builds dispute resolution, channel resizing, and multi-party factories. The result is a channel protocol that is auditable in the manner of a strictly organised accounting system.
01 Why payment channels exist at all
Imagine you and a friend split coffee every morning. If every latte had to settle on a bank wire that takes ten minutes, you’d stop doing it. Payment channels solve the same problem on a blockchain: they let two parties exchange many small updates quickly, and only touch the chain when they open the channel or close it.
The general idea has been around for nearly a decade. Open a channel by locking some funds into a multisignature contract on-chain. Then exchange signed “balance updates” off-chain, as fast as you can sign them. If both of you stay cooperative, you never touch the chain again until you decide to close. If one of you goes silent — or worse, tries to cheat — the other party can publish the most recent signed state and let the chain enforce it.
That second part is the hard one. “Enforce it on-chain” means: take the latest signed evidence, build a transaction that follows whatever settlement rules the channel protocol defined, and get it confirmed before any deadline. The protocol’s job is to make sure that
(a) you can always publish the truth,
(b) a stale state cannot become final if a newer valid state is published in time.
The Lightning Network on Bitcoin is the canonical implementation of this idea. It works. Millions of people use it. But it has structural problems that come from Bitcoin’s data model, not from anyone’s engineering mistake. Morph Channel is an attempt to get the same guarantees on a different kind of ledger — CKB , while sidestepping those structural problems at the root.
02 How Bitcoin’s UTXO approach works - and where it shows its age
Bitcoin’s ledger is a forest of “unspent transaction outputs” (UTXOs). A UTXO is essentially a coin: it has an amount and a spending condition (a script). To “update a channel state” in Lightning, both parties create a new set of transactions that describe how the locked funds would be split in the future. Each new “commitment transaction” reshapes the spending paths on the funding output.
This of course works, but it has a fundamental coupling here: the same object holds the money and represents the contract. Every state update is a new arrangement of future spends over the same funding output. To “replace” an old state, you have to either invalidate it with a penalty transaction (Lightning’s current approach) or have the chain recognise a newer signed version (the eltoo idea).
03 CKB’s Cell model: a different design space
CKB is a UTXO-style chain too, but its “unspent object” (the Cell) is much richer. Think of a Cell as a small transparent locker:
data: arbitrary bytes stored in the lockerlock script: the rule for who can open (spend) ittype script: the rule for what must be true about it when it is created or modifiedcapacity: the locker’s size, denominated in CKB. Capacity is the native resource used to occupy on-chain storage. Transaction fees are paid as the difference between input capacity and output capacity. Execution cost, separately, is measured in CKB-VM cycles. So CKB is a fee medium, but it is not an EVM-style “gas” model.
That last bullet is the part most newcomers find confusing, so let me restate it carefully: 1 CKB is not just a unit of value. It also represents the capacity required for a live Cell to occupy on-chain state. A Cell must carry enough capacity for as long as it remains live. Every Cell needs enough capacity to cover its own on-chain footprint. Any extra capacity above that minimum is the “user-visible” balance that the owner can actually spend. This is why “channel reserve” is a thing — it is the slice of capacity a channel Cell must keep around just to stay alive.
The deeper design point: because Cells can carry typed data and run scripts against it, a CKB protocol can give different Cells completely different responsibilities. One Cell can hold value; another can carry the evidence or policy that governs how that value may later move. They evolve on different schedules, and the scripts can verify one against the other.
For a payment channel, this means you can do something Bitcoin can’t easily do: keep the “money box” sitting still forever, while a separate “evidence box” rolls forward every time the parties update their state. That’s the whole architectural insight Morph Channel builds on.
04 The three “old problems” Morph Channel is trying to fix
The paper is unusually candid about what’s broken in current channel designs. It names three problems by name, and the rest of the construction is essentially a layered fix for each one.
4.1 The funding-state coupling problem
In many UTXO channel designs, the locked value and the channel state are operationally the same thing. The “state” is literally a new set of spending paths over the locked value. That’s fine for Bitcoin, but a CKB native channel protocol design probably doesn’t have to follow that pattern.
Morph’s answer is to stop treating the funding object as the state object.The funding bundle remains stable; the State Cell is the only rolling evidence track. Because those roles are separated, force-close templates can stop mixing settlement authorisation, fee selection, and asset accounting into a single tangled check.
4.2 The fee boundary problem
“There’s a fee cap of X” and “the channel pays zero fees” sound similar, but they are not equivalent.
A fee cap says channel value may be consumed up to a limit. Zero channel-paid fees says channel value does not participate in fee accounting at all. CKB makes the distinction particularly sharp because capacity is simultaneously storage resource, fee medium, and user-visible value. Morph’s invariant is the strict version: after funding, channel-owned capacity can never be reduced by a transaction fee. Publication fees are a property of the sponsor partition, and only of the sponsor partition.
4.3 The authority object problem
A well-designed protocol should have one source of truth for “what the current state is.” In practice, poorly separated designs let authority drift across several objects: the funding Cell, a plaintext witness, a local snapshot, a root commitment, a transaction body with sponsor inputs. When a script accepts more than one of these as authoritative, it opens attack surface. Morph’s rule is stark: the only authoritative object is the signed State Header, plus the witness or proof its mode requires. The transaction body is treated as a rebuildable wrapper, not as evidence.
Why this matters in practice: if you ever look at a post-mortem of a channel exploit, almost every one traces back to a moment where two authority sources disagreed, and a script accepted the wrong one. Morph’s design thesis is that on CKB, you can build a channel that has only one authority source by construction. That’s the whole paper in one sentence.
05 The central design: three separations
If you remember only one architectural idea from this article, make it this: Morph Channel separates three things that other designs fuse together. Once you see the three separations, every later mechanism falls out of them almost mechanically.
5.1 Separation #1 — Vaults vs. State Evidence
Separate the value-holding layer from the evidence-carrying layer.
- Vault Cell(s) hold channel-owned value. They sit there, untouched, for the entire lifetime of the channel. Their lock script refuses to release value unless the spender can also present a current, authentic State Cell that authorises the spend.
- State Cell carries the latest signed settlement evidence. Every time a unilateral publication happens, the State Cell is consumed and a successor is created. It’s a “rolling” object that lives in its own update track.
The benefit is operational, not only aesthetic. At force-close time, the settlement transaction only has to prove that a current State Cell authorises a particular descriptor over a particular vault set. It does not need to reshuffle the value holder, smuggle in fee policy, or treat the transaction body itself as settlement evidence.
5.2 Separation #2 — Sponsor vs. Channel
Separate publication funding from channel ownership.
Channel-owned value never pays a transaction fee. The carrier transaction that publishes a State Cell is funded by a separate party: the user’s normal wallet, a watchtower, or for the most safety-critical case, a bounded SponsorBudget Cell delegated to a fixed channel and a fixed state-number range.
This separation unlocks something subtle but important: the signed State Header does not commit to which sponsor inputs are used or what fee rate is paid. That means a watchtower can rebuild the publication transaction with different sponsor coins and a higher fee rate if the network gets congested, and it does not need fresh signatures from the channel participants. The signature is over the state, not over the carrier.
5.3 Separation #3 — Partition Conservation (the five-lane ledger)
Split the channel’s books into five ledgers that cannot borrow from each other.
Because this is the main accounting invariant, it deserves its own section.
06 The five-lane ledger (partition conservation)
Here’s the rule that makes everything else verifiable. Every cell in a post-funding transaction is classified into one of five categories, and each category has its own conservation rule. The categories are:
| Lane | Source | Role | Pays fees? |
|---|---|---|---|
| Sponsor | standard wallet, watchtower, or budget Cells | transaction fees and change | Yes |
| State Carrier | State Cell + carrier refund outputs | storage capacity for the moving state track | No |
| Channel Reserve | channel-owned CKB capacity | keeps vault Cells alive and pays reserve refunds | No |
| Business CKB | channel-owned CKB above reserve | user-visible CKB that can be settled to participants | No |
| Business xUDT | channel-owned xUDT balances (per type script) | user-visible token balances for each registered asset | No |
The conservation rule per lane, simplified:
- PUBLISH / SUPERSEDE:
channel_in == channel_out; carrier capacity is conserved; sponsor lane absorbs the fee difference. - FINALIZE: channel value flows into descriptor-authorised settlement outputs (which are themselves classified by lane); carrier capacity can be retired into a refund output that is also classified as State Carrier.
- SPLICE:
channel_out == channel_in + delta_in - delta_out, where every delta must be a signed protocol object binding asset type, amount, capacity, cell shape, and descriptor policy. - Always:
carrier_in == carrier_out;sponsor_in - sponsor_out == tx_fee; the three sets (channel lanes, carrier, sponsor) are disjoint.
Five-lane conservation: inputs and outputs balance per laneInputsSponsorState CarrierChannel ReserveBusiness CKBxUDT (per type)each lane balances itself; no borrowing across lanesOutputsSponsor ChangeState / Carrier RefundReserve (or refund)Business CKBxUDT (per type)
Each lane balances itself. The fee deficit is always absorbed by the Sponsor lane, never by Channel Reserve or Business CKB or Business xUDT.
There are two non-obvious things in this scheme that are worth lingering on.
First, “channel reserve” and “business CKB” are not the same thing. This is the earlier capacity point showing up inside the channel ledger. A CKB Cell needs capacity to exist; that capacity is the reserve. Anything above the reserve is “business CKB” that the user can actually move around. The two are kept in separate lanes because conflating them is exactly how channels leak user value into fees or into reserve refunds the user did not expect. A State Cell that looks as if it merely shrank by a few shannons might have consumed business balance as a hidden fee — partition conservation makes that impossible to hide.
Second, xUDT (CKB’s extensible user-defined token standard) accounting is per-type-script, not per-symbol or per-name. If two tokens claim the same ticker, they are different assets for partition conservation purposes because their type scripts differ. A sponsor change output that smuggles a registered xUDT back to the user will be rejected. The accounting is by cryptographic identity, not by human label.
The headline invariant: “If partition conservation holds for a post-funding transaction, then publication fees cannot reduce channel-owned value.” This is Proposition 1 in the paper and it’s the single most useful sentence to memorize. Proof sketch: transaction fees are input_capacity - output_capacity. Each lane is conserved under its own rules. Therefore the only lane that can have a deficit is the sponsor lane. Therefore channel-owned value is never the fee payer.
07 The State Header: the authoritative envelope
If partition conservation is the accounting rule, the State Header is the contract. It is a single canonical record that says, in effect: “I am the current state of channel X, dated at funding epoch Y, locking value into vault set Z, governed by settlement descriptor D, and I have been signed by the required participants.” The header lives inside a State Cell. The State Cell is not consumed during ordinary off-chain updates. It is consumed and recreated only when state evidence is published on-chain, superseded, spliced, or finalised under the relevant script branch. The header is what gets carried forward (with a higher state number) at those on-chain transitions.
The canonical State Header has roughly these fields:
// Slightly simplified — see paper Section 5.3 for the full struct.
struct StateHeader {
protocol_version // which version of the protocol parses this
chain_id // prevents cross-chain replay
signature_scheme_id // which signature algorithm is in use
channel_id // the channel's immutable genesis identity
funding_epoch // advances on splice; prevents old-sig reuse
funding_anchor_identity // outpoint of the current funding Cell
vault_set_commitment // hash of the current set of vault Cells
state_number // strictly monotonic; bigger wins
mode // bilateral plaintext vs factory proof
phase // active / settling / closed
participants_commitment
asset_registry_commitment // which xUDT type scripts are recognised
settlement_descriptor_commitment
descriptor_version // grammar version, not descriptor instance
payload_commitment // hash of balances, HTLCs, etc.
challenge_policy_commitment
state_layout_version
}
The signature is computed over a domain-separated hash:
mn = H("CKB_MORPH_CHANNEL_STATE_V1" || canonical(Header_n))
That string prefix is doing real work. Without it, an attacker could try to feed the signed bytes into a different protocol or a different chain that happens to use the same signature scheme. With it, the signature is bound to this protocol, this version, this chain, this channel, and this funding context. Replay across any of those dimensions is impossible by construction.
Two design choices in the header deserve their own emphasis.
7.1 The funding_epoch field
Funding epoch is a monotonic counter that advances every time the channel is resized (a “splice”). It exists to solve a specific attack: suppose Alice signed State 100 when the channel had 1000 CKB. Then you splice the channel up to 5000 CKB. Alice’s old signature still says State 100, but it now refers to an outdated funding context. If scripts accepted it, Alice could try to claim her old 1000-CKB settlement out of a 5000-CKB vault. The funding_epoch field — and the matching funding_anchor_identity and vault_set_commitment fields — are part of the signed domain, so the moment you splice, every prior signature becomes invalid. Watchtower packages from before the splice are inert. This is what the paper calls “splice freshness.”
7.2 The settlement descriptor is bounded
The settlement descriptor is a small structured object that says “given this header and this payload, the settlement outputs are these specific Cells, with these locks, these capacities, and these type scripts.” It is not a Turing-complete program. It is a versioned grammar with a fixed output count, a fixed role vocabulary, and no dynamic dispatch. This is deliberate. If you let people put arbitrary scripts in the witness, you’ve turned the channel into a general smart-contract platform, with all the verification cost and attack surface that implies. By keeping the descriptor narrow, the protocol stays auditable and the CKB-VM cycles stay predictable.
The State Cell’s type script is the script-level enforcement point. Every time a transaction tries to consume the current State Cell and create a successor, the type script runs through a check list: header format is canonical, state number strictly increases, funding context unchanged (for normal updates), signatures are valid, payload matches the payload commitment, partition conservation holds, output capacity is sufficient to host the new State Cell. A transaction that fails any one of these checks is rejected before it ever reaches consensus.
08 Disputes and the challenge window
Now the messy part.
Suppose Alice and Bob are running a channel. They sign State 100 offline and stop talking. Alice goes rogue and publishes State 95 (which is older and more favourable to her). What happens?
Morph’s rule is the eltoo-style “newer state wins” rule, but implemented with CKB primitives rather than a Bitcoin sighash change:
- Alice’s publish transaction consumes the currently live active State Cell, or the currently live settling State Cell if the channel is already in dispute, and creates a settling State Cell at number 95.
- The channel is now in the
settlingphase. A challenge window starts, encoded as a CKBrelative sinceon the State Cell input. - Bob has State 100 in his back pocket. He builds a “supersession” transaction that consumes Alice’s State 95 and creates a successor at State 100.
- If Bob’s transaction confirms before the challenge window expires, the new live State Cell is 100. Alice’s 95 is gone.
- If the challenge window expires with no supersession, the chain lets anyone finalise Alice’s 95 by presenting the live State Cell and the elapsed time.
Challenge window timelineAlice publishes 95Bob detects staleBob builds tx for 100100 confirmedFinalisation allowedchallenge window Δ = relative since on State Cell
The newer state must confirm on-chain before the challenge window expires, or the stale state becomes final.
The challenge window’s length Δ is a deployment parameter, not a hard-coded constant. The paper gives a budget equation:
Δ ≥ Δ_detect // confirmations before a watchtower treats stale state as actionable
+ Δ_poll // watchtower service interval
+ Δ_build // time to construct and broadcast a replacement tx
+ Δ_confirm // time for the newer-state tx to confirm
+ Δ_margin // safety margin for fee bumps and reorg risk
Each of those terms has to be measured on the actual network. A deployment profile has to record its assumptions (detection depth, polling interval, sponsor budget multiple for fee bumps, conservative reorg margin) and verify them periodically. The paper is explicit that “naked integer comparison” — treating a raw integer in the since field as if it were a delay — is not a valid challenge-window check. The script must parse the since as an encoded relative-block condition that matches the committed challenge policy. Otherwise a challenger could craft a malicious since value that the script accepts but the network interprets differently.
One more subtlety: fee bumping in CKB is not Bitcoin’s “replace-by-fee.” It means rebuilding the publication transaction against the currently live State Cell, using different sponsor inputs and a higher fee rate. Because the State Header doesn’t commit to which sponsor inputs are used, the watchtower can do this without re-signing. If the original tx is stuck because fees spiked, the watchtower builds a fresh one. The only invariant is that the new tx must consume the current live State Cell — CKB’s single-spend rule guarantees that a stuck tx and a new tx cannot both succeed.
09 Splice: resizing a live channel
Then life goes on, your business grows, and the channel needs more liquidity. Or a participant wants to withdraw some. Morph handles this with a splice: a signed re-anchoring event that consumes the current funding context, advances the funding epoch, and creates a new funding context with a new vault set.
And there are two flavours of Splice.
Splice-in admits external value into the channel — Alice puts in another 1000 CKB, the channel’s locked value grows.
Splice-out releases value while keeping enough post-splice vault value to satisfy the latest signed settlement descriptor.
Either way, the splice transaction must bind: the old funding anchor, the new funding anchor, the old vault-set commitment, the new vault-set commitment, the per-asset deltas, and the required participant signatures. CKB and xUDT are tracked separately, not lumped together as “value.”
The crucial property: a watchtower package from before the splice is not automatically valid after it, even if the package has a higher state number than the live State Cell, because its signed funding epoch and vault-set commitment refer to a different enforceable value object. This is splice freshness, and it is the only thing standing between you and the “I have a better signature” attack after a channel resize.
10 Factory mode: many participants, one liquidity pool
A bilateral channel is two people. A factory is many people sharing one liquidity pool, each with their own balances, sub-channels, and exit paths. Factories are useful for the same reason shared ledgers are useful: you can put one big pot of money on-chain and let many small relationships draw from it without each relationship having to lock up its own capital.
But factories have a problem bilateral channels don’t: disclosure. If every local exit has to publish the entire factory state, you leak everyone’s balances to the world, and the witness size grows with factory size. So Morph adopts a commitment-first design for factories.
10.1 The factory state is a header plus roots
A factory’s authoritative state is a State Header plus a few Merkle roots: a balances root, a sub-channels root, a membership root, a reserve root. Each root commits to a tree of leaves that describe the relevant factory data. To prove that your local action is valid, you don’t publish the whole tree; you publish a Merkle proof that touches only the leaves you care about.
10.2 Envelope-first admission
This is where the envelope-first design does most of its work. A factory transaction is admissible in two stages.
Stage 1 — the envelope. The transaction carries a small outer claim that says “I am a factory transition of kind local_exit, version 1, with these flags, and I commit to a body whose bytes are exactly body_len long with hash body_commitment.” The script checks the envelope first. If the envelope is malformed, the body is never even parsed. If the envelope is valid, the script knows which proof grammar to apply before it starts reading the body.
// The envelope is a tiny admission-control object:
struct FactoryEnvelope {
magic // identifies this as a factory transition
version // grammar version of the envelope itself
kind // local_exit | update | splice | reduced_right | ...
flags // e.g. asymmetric, one-sided, typed
body_len // hard byte bound; checked before parsing
body_commitment // hash of the canonical body bytes
}
// The body_commitment binds the envelope context, so swapping the body
// under a different envelope is detectable:
body_commitment = H("CKB_MORPH_FACTORY_BODY_V1"
|| magic || version || kind || flags
|| body_len || body_bytes)
Stage 2 — the body. Only after the envelope is verified does the script parse the body, which contains the access manifest (which leaves you claim to touch), the proof bundle, the touched leaf payloads, and the signatures.
Why two stages? Because it prevents the “re-skin” attack. Suppose a transition family A is conservatively authorised (needs all-participant signatures) and a transition family B is locally authorised (needs only the affected participants’ signatures). If the script simply looked at the body and decided which authority class to apply, an attacker could write a body that is actually a family-A operation but claim it is a family-B body, and the script would apply the lighter check. By fixing the family in the envelope and binding the body to the envelope, the script knows the authority class before it interprets the body. A transaction cannot claim to be a “local exit” while its body is in fact a “global update.”
10.3 What non-interference is and why it matters
The deepest property in factory mode is non-interference. The question it answers: “When I take a local action, am I sure I haven’t changed anything that some other participant has a right to?”
Factory rights are the things a participant might care about: their balance, their reserve claim, their membership, their exit path, their sponsor-budget claim. Some of these rights are obviously local — your balance is your balance. But others are not. A factory has shared reserve, shared exit paths, shared sponsor budgets. If you change your balance, you might also change the shared reserve available to fund other participants’ exit paths, even if you don’t directly touch those leaves.
Morph’s answer is a rights-dependency schema: a versioned declaration that says, for each right in the factory, “if I touch right X, these are the other rights that might also change as a consequence.” The schema is part of the protocol, not a per-deployment afterthought. A local transition must prove non-interference with respect to all untouched participants, which means: for every right that the schema says depends on something I’m touching, prove that the dependency is either unchanged or irrelevant. If you can’t prove it, the transition is global and requires all-participant signatures.
Proposition 2 in the paper is the safety statement for this: if a factory action cannot prove non-interference, a conservative profile requires signatures from all participants. If non-interference is proven, the signing set can be reduced — but only when the touched rights also satisfy participant authorisation, local validity, and value conservation. Non-interference doesn’t grant value rights on its own. It just lets you skip asking people who are provably unaffected.
A useful mental model: think of a factory as a corporate board meeting. A local action is like a committee making a decision: they need to show that the decision doesn’t change anything that other committees have authority over. If they can’t, the full board has to vote. Non-interference is the proof that “this is a committee decision,” and the rights-dependency schema is the corporate bylaws that say which decisions are committee-eligible.
Note that a Merkle proof of “I touched these leaves and no others” is not enough. The proof must also cover the dependencies named by the schema: shared reserve, membership, exit path, sponsor budget. A factory vault, for example, can be rebalanced by a local exit even if the exit only touches one balance leaf, because the vault rebalance is a side effect that the schema has to acknowledge. If the schema says the touched leaf’s effect on the vault is “change the participant’s reserve claim,” then the proof has to either leave that claim unchanged or fall back to full signatures.
This is also where envelope-first admission earns its keep. The envelope fixes the transition family before the body is read. That means the rights-dependency check happens under the right authority class. Without the envelope, a body that says “I’m a local update” could be interpreted as a body that says “I’m a value-mint” if the proof bytes happened to support it. Envelope-first removes that ambiguity at the protocol level.
11 What’s still unsolved
Let’s also be honest about Morph’s current limits.
The construction is a script-level design, it doesn’t change CKB consensus or introduce new transaction types. But that also means the heavy lifting is now in deployment engineering. The open questions are mostly empirical:
- Witness size for bilateral plaintext mode in realistic payment states — does it fit, and at what cost?
- Factory proof size under realistic touched-footprint distributions — is commitment-first actually cheaper than plaintext at scale?
- CKB-VM cycles for signature, hash, and proof verification — what’s the actual cost?
- Challenge reliability under realistic CKB confirmation behaviour, fee volatility, and watchtower-polling parameters.
- Sponsor policy failure modes: insufficient budget, inadmissible script-level expiry, wrong change destination.
- State Cell uniqueness under contention: what happens when two parties publish competing transactions in the same block?
- Splice freshness tests: prove that pre-splice watchtower packages cannot govern post-splice vaults.
- Descriptor grammar coverage: how many descriptor families do we need before deployment, and what are the version boundaries?
- Factory acceptance: does the candidate deployment pass every positive and negative family in the matrix’s factory section?
- Mechanised non-interference: the rights-dependency schema is informal today; it needs machine-checked coverage before reduced signing sets are safe in broader transition families.
There are also a few things I deliberately have not tried to solve in the thesis: routing, liquidity discovery, gossip, privacy networks, watchtower markets, factory governance. Those are meaningful real-world problems currently beyond this paper’s scope.





