Skip to main content

Bridgeless leap

UTXO Stack enables seamless cross-chain interoperability between RGB++ layer and branch chains, leveraging an isomorphic architecture. This innovative approach eliminates the need for traditional cross-chain bridges, which are often centralized points of failure. By doing so, it improves the efficiency of asset transfer, allowing tokens to move across branch chains without the need for extended locking periods.

image

Branch chain token manager

The Branch Chain Token Manager, referred to as the token manager, is a system contract embedded within every branch chain. It functions as the issuer of branch chain tokens. When assets are transferred from RGB++ layer to a branch chain, the original assets are locked on RGB++ layer, and the token manager issues a wrapped token on the branch chain. Conversely, when assets move from a branch chain back to RGB++ layer, the wrapped tokens are burned on the branch chain, and the original assets on RGB++ layer are unlocked.

The underlying mechanism of the token manager is implemented via a cross-chain message queue. This queue is deployed on both RGB++ layer (as an application contract) and each branch chain (as a system contract), allowing the token manager system contract to access and send cross-chain messages through the queue.

xUDT

Assets on the branch chain are represented by xUDT tokens, with the token manager contract acting as the issuer.

Cross chain message queue

On RGB++ layer: The cross-chain message queue is implemented as application contracts. This contract includes a branch chain light client, which tracks the branch chain's state, and a queue contract that maintains messages related to the branch chain.

On Branch Chains: The message queue is implemented as a system contract. This setup allows branch validators to read messages from RGB++ and submit cross-chain messages to the system contract. Branch chain users can also send messages to the system contract, and validators act as relayers by submitting these messages to RGB++ layer.

Request cell

Due to the nature of CKB cell model, every transaction consumes input cells and generates new output cells. If we naively use a cell to implement a queue, consuming and regenerating the queue cell each time a user pushes a message would prevent simultaneous message interactions. To address this, we introduce the concept of the request cell.

When a user wants to interact with a message queue, they create a request cell instead of directly writing into the queue cell. This is achieved by replacing the lock field of their own cell:

Batch Request Lock Fields

  • cancel_timeout: Specifies the number of blocks after which the request can be canceled.
  • owner_lock_hash: Allows the request to be canceled with this lock hash.
  • request: Serialized byte structure containing the request details.

By creating a request cell, users permit aggregators to collect and batch these requests. This approach allows multiple users to interact with the message queue simultaneously and efficiently.

RGB++ message queue

The RGB++ side of the message queue is structured as follows:

pub struct CKBMessageQueue {
// The merkle tree root of locked assets
locked_assets: Byte32,
// Send queue
outbox: Vec<CKBMessage>,
// Receive queue
inbox: Vec<BranchMessage>,
}

Key operations include:

  • PushRequest: Submit cross chain transfer message.
  • Ack: Confirm messages have been processed by providing branch chain block headers and proofs.
  • HandleRecv: Handle the receive queue.

Branch message queue

The branch chain side of the message queue is structured as follows:

pub struct BranchMessageQueue {
// The merkle tree root of locked assets
locked_assets: Byte32,
// Send queue
outbox: Vec<Bytes(BranchMessage)>,
// Receive queue
inbox: Vec<CKBMessage>,
}

Key operations include:

  • PushRequest: Submit cross chain transfer message.
  • HandleRecv: Handle the receive queue.

Messages

/// CKB messages
pub enum CKBMessage {
Branch(CKBToBranchRequest)
}

pub struct CKBToBranchRequest {
request_id: Bytes,
// Target chain ID
target_chain_id: ChainId,
message: Message,
}

// Branch chain messages
pub enum BranchMessage {
CKB(BranchToCKBRequest)
Branch(BranchToBranchRequest)
}

pub struct BranchToCKBRequest {
request_id: Bytes,
// Initial chain ID
initial_chain_id: ChainId,
message: Message,
}

pub struct BranchToBranchRequest {
request_id: Bytes,
// Initial chain ID
initial_chain_id: ChainId,
// Target chain ID
target_chain_id: ChainId,
message: Message,
}


pub struct Message {
owner_lock_hash: Byte32,
amount: u128,
// Asset type
asset_type: Byte32,
}

Leap

We use $UTXO token as an example to describe the life cycle of cross chain assets.

RGB++ layer to Branch chain

StepCKBBranchCKB Message QueueBranch Message QueueDescription
1UTXOtokencell(lock=user,type=UTXO token cell(lock=user, type=UTXO)---User's assets on CKB
2Request cell(lock=request_lock, type=$UTXO)---Initiates cross-chain transfer request on CKB
3Custodian cell(lock=custodian_lock, type = $UTXO)-outbox: CKBToBranchMessage-Lock assets on CKB, enqueue CKBToBranchMesasge
4--outbox: CKBToBranchMessageinbox: CKBToBranchMessagesubmit message to Branch
5-Wrapped UTXOtokencell(lock=user,type=UTXO token cell(lock=user, type = WUTXO)outbox: CKBToBranchMessage-Mints assets on Branch
6----Acknowledges and remove processed request from CKB outbox

Branch chain to RGB++ layer

StepCKBBranchCKB Message QueueBranch Message QueueDescription
1-wrapped UTXOtokencell(lock=user,type=UTXO token cell(lock=user, type=WUTXO)--User's assets on Branch
2-Request cell(lock=request_lock, type=$WUTXO)--Initiates cross-chain transfer request on Branch
3---outbox: BranchToCKBMessageBurn assets on Branch, enqueue BranchToCKBMessage
4----Commit outbox messages to Branch chain block header
5--inbox: BranchToCKBMessage-Wait challenge period, then submit message to CKB inbox
6UTXOtokencell(lock=user,type=UTXO token cell(lock=user, type = UTXO)---unlock $UTXO token from custodian

Branch chain to Branch chain

StepCKBBranch ABranch BBranch A Message QueueBranch B Message QueueDescription
1-wrapped UTXOtokencell(lock=user,type=UTXO token cell(lock=user, type=WUTXO)---User's assets on Branch A
2-Request cell(lock=request_lock, type=$WUTXO)---Initiates cross-chain transfer request on Branch A
3---outbox: BranchToBranchMessage-Burn assets on Branch A, enqueue BranchToBranchMessage
4-----Commit outbox messages to Branch A block header
5Custodian Transfer Cell(lock=custodian_transfer_lock, type=$WUTXO)----Branch A validarors unlock custodian, initiates custodian transfer on CKB
6Custodian Receipt Cell(lock=custodian_receipt_lock, type=$WUTXO)----Branch B validators accept custodian transfer, and init receipt cell
7--wrapped UTXOtokencell(lock=user,type=UTXO token cell(lock=user, type=WUTXO)-inbox: BranchToBranchMessageOnce Branch B create receipt cell, the assets is minted
8Custodian cell(lock=custodian_lock,type=$WUTXO)----After challenge period, Branch B validators move assets from receipt cell to branch B custodian cell

Conclusion

By enabling seamless cross-chain interoperability, UTXO Stack empowers developers to build applications that can leverage the strengths of different UTXO blockchain networks. This opens up new possibilities for asset exchange, cross-chain lending, and other decentralized finance (DeFi) applications built on top of Bitcoin's robust security and decentralization.