Overview

This section is divided into 2 main parts, RootChain Manager Contract and Requesrtable Contract.


RootChain Manager Contract

RootChain contract is a manager contract for Plasma EVM. Operator submits plasma block data to this contract. Users also send transaction to make request for a requestable contract.

The Units

Plasma blocks are abstracted in many way depending on each contexts. Block is the smallest unit that operator commits to RootChain contract. Epoch includes many blocks. Cycle includes many epochs.

3 Types of Block

In Plasma EVM, There are many types of block; Non-Request Block, Request Block, Escape Block. Non-Request Block (NRB) is a regular block that users send transaction. It is same as block of Ethereum, Bitcoin, and other blockchain. Request Block (RB) is a block to apply request in child chain. Users create request and operator mines request block to apply the request in child chain. It is enforced what transactions must be included in request block by RootChain contract calculating transactions root. Escape Block (EB) is kind of request block to provide user to deal with block withholding attack by operator. For escape block, see continuous rebase.

NRB data can be withheld, but RB and EB cannot because anyone can get data from RootChain contract to mine RB and EB.

3 Types of Epoch

Epoch is a period of blocks. There are also Non-Request Epoch (NRE), Request Epoch (RE) and Escape Epoch (EE) for each block type. Epoch is required to determine when other type of block should be placed. Also a single request block cannot take all requests due to block gas limit and block size of child chain (and block gas limit of root chain to computate transactions root of request block).

The length of epoch is the number of blocks in the epoch. So RE and EE can have length of 0 if no RB or EB exists.

Note

The length of NRE is a constant that is provided when RootChain contract is deployed.

Cycle

Continuous Rebase requires many steps to commit a single block to root chain. And Pre-commit and Commit step incldue fixed number of NRBs. Cycle covers Pre-commit, DA check, Commit, Challenge steps and the length of cycle is the number of NREs + the number of OREs + 1 (the number of EE)

Note

The length of cycle is a constant that is provided when RootChain contract is deployed. But the number of blocks in a cycle may change depending on the number of requests.

Block Mining

In 1 cycle, child chain block is mined as below:

  • In pre-commit step, the first epoch is NRE. operator mines NRB with transactions from users.

  • If users create enter requests and exit requests, they are reserved to be included in ORE after next NRE. For example, requests created in NRE#1 or ORE#2 are applied in ORE#4. If no request created, ORE is empty.

  • Pairs of NRE - ORE are repeated (size(cycle)) - 1 / 2 times.

  • In DA check step, user can create escape requests and undo requests.

  • In Commit step, the first epoch is EE. Operator mines escape blocks if any request created in DA step. The parent of first block is the last block of previous cycle’s last block.

  • Operator rebases pre-committed block and commit them.

How to Handle Request

This explains how the request created and applied in child chain as request trasaction.

Addresses of Requestable Contracts in Both Chain

Reqeustable contracts must be deployed in both chain and 2 addresses must be mapped in RootChain contract. Then user can make requests for requestable contracts.

Create Enter Request

User can send transaction to RootChain contract to create enter request.

  1. User send transaction to RootChain contract to call RootChain.startEnter().

  2. RootChain contract apply the request to the corresponding requestable contract. Those happens in root chain.

  3. If step 2 is not reverted, RootChain contract record the request.

  4. In request epoch, operator mines request block with request transactions. See how request is converted into reqeust transaction here.

function startEnter(address _to,bytes32 _trieKey,bytes _trieValue)

to is the address of target reqeustable contract in root chain. trieKey and trieValue is parameters for the request.

Create Exit Request

User also can send transaction to RootChain contract to create exit request.

  1. User send transaction to RootChain contract to call RootChain.startExit().

  2. Unlike enter request, exit request is immediately recorded and mined in reuqest block with reqeust transactions. See how request is converted into reqeust transaction here.

  3. After challenge period for the requst block, challenge period for exit request starts. If the request transaction in step 2 is reverted, anyone can challenge on this by calling RootChain.challengeExit() with the transaction inclusion proof and receipt data.

  4. If there is no successful challenge, User finalize the request by calling RootChain.finalizeRequest(). In the function, RootChain contract apply the request to the corresponding requestable contract in root chain.

function startExit(address _to,bytes32 _trieKey,bytes _trieValue)

Pamateres are same as startEnter.

Apply Request in Child Chain

A request has four important fields, requestor is a address who made the request, to is a address of requestable contract deployed in root chain, trieKey is a identifier for request type, and trieValue is the value of request.

When a request is transformed into request transaction, the transaction has those fields as follow:

  • msg.sender: it is always 0x00. It prevents other from creating request transaction because nobody know the private key of address 0x00. Due to this, signature of request transaction is zero , v = r = s = 0.

  • msg.to: requestable contract deployed in child chain. RootChain contract must know it.

  • msg.value: it is always 0.

  • msg.data: To invoke message-call in transaction, this field must contain function signature and parameters for applyRequestInChildChain function. RootChain contract always knows what bytes should be in this field. See also solidity code here.

When the current epoch is RE, operator mines request block with request transactions to transit state of child chian. RootChain contract enforces operator to include what request transactions should be in the request block by calculating transactions root of the block.

Those request transactions are applied to requestable contract by apply request functions


Requestable Contract

Requestable is a interface to be able to adapt Plasma EVM. Any contract implementiong requestable can accept enter and exit reqeust from RootChain contract.

Request

Request is an entity that makes users to interact with contracts. If user creates request, it is recorded in RootChain manager contract. A request is appiled in child chain as a request transaction. The sender of request transaction is 0x00 and it is included in request block to change the state of child chain. And it is enforced by RootChain contract to mine specific request block.


Before go further, it is recommended to see how RootChain contract handle request here.

Enter and Exit

Enter is “moving something from root chain to child chain”. Exit is “moving something from child chain to root chain”. The most intuitive example is token transfer. Depositing ERC20 to child chain is enter, and withdrawing it from child chain is exit.

Enter request is applied in root chain, then applied in child chain through request transaction. If applying in root chain is invalid, it MUST be reverted to prevent invalid enter request from being created.

Exit request is applied in child chain through request transaction, then applied in root chain. If the request is invalid, anyone can challenge on the invalid exit with transaction receipt as proof. If exit request is not challenged, anyone can finalize the reqeust and apply it to the requestable contract in root chain.

ApplyRequestIn*Chain Functions

If user wants to enter or exit, he sends a transaction to RootChain contract to make enter request or exit request. RootChain.startEnter() and RootChain.startExit() make user to create enter or exit request.

To accept those requests, contracts must implement Requestable interface.

See more how those requests are converted into request transaction and applied in child chain here.

interface RequestableI {
  /// @notice Apply exit or enter request to requestable contract
  ///         deployed in root chain.
  function applyRequestInRootChain(
    bool isExit,
    uint256 requestId,
    address requestor,
    bytes32 trieKey,
    bytes trieValue
  ) external returns (bool success);

  /// @notice Apply exit or enter request to requestable contract
  ///         deployed in child chain.
  function applyRequestInChildChain(
    bool isExit,
    uint256 requestId,
    address requestor,
    bytes32 trieKey,
    bytes trieValue
  ) external returns (bool success);
}

applyRequestIn*Chain functions have common parameters.

  • isExit: true if the request is exit.

  • requestId: Identifier for the request. RootChain contract assigns it.

  • requestor: Address who made the request.

  • trieKey: Identifier for request type. trieKey tells the contract what state variable should be changed for this request

  • trieValue: Value of the request. trieValue tells the contract how state should be changed.

See more examples.