This document represents an overview about the current specification and is work in progress.
- Anyone can submit, challenge and finalize a Block.
- Submitting a Block requires a bond. The bond is used to repay finalization / challenge gas costs.
- There can be any number of Block submissions inside a Layer-1 (root-)Block.
- Blocks are sequenced and are being processed in order.
- Solutions for submitted blocks can be submitted in advance. This is limited for up to 256 blocks.
- Solutions can be disputed, disputed blocks needs to verified on Layer-1 once all blocks before the disputed block are finalized.
- TODO: Blocks can have a
deadlineparameter, the block is skipped if it is not finalized before thedeadline. - TODO: Require a smaller bond on
challengethat gets burned or returned depending if the solution was indeed wrong or not.
Take a look at the definitions here.
Signature.vis either0x1bor0x1cfor RLP transactions.- For EIP-712 transactions,
0x65is added toSignature.v.- Thus,
signature.vis either0x80or0x81.
- Thus,
if (signature.v === 0x80 || signature.v === 0x81) {
// EIP-712
}
if (signature.v === 0x1b || signature.v === 0x1c) {
// RLP
}
<signature.v - 1 byte>
<signature.r - 32 bytes>
<signature.s - 32 bytes>
<nonce - variable>
<to - 20 bytes>
<data - variable>
const nonceBytes = arrayify(tx.nonce);
const calldataBytes = arrayify(tx.data);
let enc = arrayify(tx.v)
.concat(arrayify(tx.r))
.concat(arrayify(tx.s));
if (nonceBytes.length > 1 || nonceBytes[0] > 0xde) {
enc.push(0xff - nonceBytes.length);
enc = enc.concat(nonceBytes);
} else {
enc = enc.concat(nonceBytes);
}
enc = enc.concat(arrayify(tx.to));
if (calldataBytes.length >= 0xff) {
enc.push(0xff);
enc.push(calldataBytes.length >> 8);
enc.push(calldataBytes.length & 0xff);
} else {
enc.push(calldataBytes.length);
}
return enc.concat(calldataBytes);
Transaction encoding is the same as on Ethereum (RLP encoded) with the following rules for the fields:
gasPricemust be always zerogasLimitmust be always zerovaluemust be always zerotomust be always 20 bytes
Additionally, chainId is currently fixed to zero.
const typedData = {
types: {
EIP712Domain: [
{ name: 'name', type: 'string' },
{ name: 'version', type: 'string' },
],
Transaction: [
{ name: 'to', type: 'address' },
{ name: 'nonce', type: 'uint256' },
{ name: 'data', type: 'bytes' },
],
},
primaryType: 'Transaction',
domain: {
name: 'NutBerry',
version: '2',
},
message: {
to: '0x0000000000000000000000000000000000000000',
nonce: 1,
data: '0xff',
},
};
0x65 is added to signature.v and the transaction's encoding is the Internal Transaction Encoding.
A Block consists of a arbitrary number of internal encoded transactions and must not exceed MAX_BLOCK_SIZE.
The block nonce is the uint256 block number for that block, thus block hash is keccak256(nonce + block).
function deposit(address token, uint256 amountOrId)
Deposit ERC-20/ERC-721 token with amountOrId into the Bridge.
This creates a new Deposit-Block.
function withdraw(address token, uint256 tokenId)
Withdraw token and tokenId from the Bridge.
tokenId is zero for ERC-20 tokens.
A user has to do a token.transfer(to(0), amount) for ERC-20 and token.transferFrom(from, to(0), tokenId) for ERC-721 tokens - on Layer-2 - to take it out for exit.
This makes it available to the Bridge so that the user can withdraw the accumulated amount or tokenId back to the root-chain.
Rules:
- Anyone can submit a block.
- Must not exceed
MAX_BLOCK_SIZE. - Blocks are ordered in sequence; in the order they arrive.
- Only one block can be finalized at a time and in the correct order.
There is currently no time limit between Block submissions or any cap on the number of pending blocks.
- A solution must not be larger than
MAX_SOLUTION_SIZE. - Up to 256 solutions can be submitted and being marked as invalid in advance.
Any block can be directly finalized even if the correspond solution are not marked invalid. However, block solutions marked as invalid needs to be finalized on-chain.
A block solution can only be finalized if:
block.number > timeOfSubmission + INSPECTION_PERIODis true for the solution,- the solution is not marked as invalid,
- if there are no open disputes,
- the previous block is finalized.
If the solution can be finalized, then the Bridge applies all the storage key-value's and moves to the next pending Block.