Coder Social home page Coder Social logo

dymchenkko / rollups Goto Github PK

View Code? Open in Web Editor NEW

This project forked from cartesi/rollups

0.0 0.0 0.0 6.27 MB

Cartesi Rollups

License: Apache License 2.0

Shell 0.32% JavaScript 0.07% Lua 0.54% Rust 64.66% Awk 0.05% TypeScript 2.97% PLpgSQL 0.09% HCL 0.26% Dockerfile 0.89% Solidity 30.13%

rollups's Introduction

Cartesi Rollups

This repository contains the on-chain and off-chain pieces that are used to deploy, launch and interact with Cartesi Rollups DApps. The code presented here is work in progress, continuously being improved and updated.

Table of contents

Documentation

Check the official Cartesi Rollups documentation website.

On-chain Rollups

Designed to mediate the relationship between the off-chain components with other smart contracts and externally owned accounts. It is composed by several modules, each with clear responsibilities and well-defined interfaces. The modules are depicted in the diagram below. The yellow boxes correspond to the core contracts, and the blue boxes correspond to externally-owned accounts (EOAs) or other contracts.

graph TD
    classDef core fill:#ffe95a,color:#000
    classDef external fill:#85b4ff,color:#000
    classDef hasLink text-decoration: underline

    InputBox[Input Box]:::core
    CartesiDApp[Cartesi DApp]:::core
    CartesiDAppFactory[Cartesi DApp Factory]:::core
    EtherPortal[Ether Portal]:::core
    ERC20Portal[ERC-20 Portal]:::core
    ERC721Portal[ERC-721 Portal]:::core
    ERC1155SinglePortal[ERC-1155 Single Transfer Portal]:::core
    ERC1155BatchPortal[ERC-1155 Batch Transfer Portal]:::core
    DAppAddressRelay[DApp Address Relay]:::core
    Consensus:::external
    
    ERC20[Any ERC-20 token]:::external
    ERC721[Any ERC-721 token]:::external
    ERC1155[Any ERC-1155 token]:::external
    DAppOwner[Cartesi DApp Owner]:::external
    Anyone1[Anyone]:::external
    Anyone2[Anyone]:::external
    Anyone3[Anyone]:::external

    Anyone1 -- executeVoucher --> CartesiDApp
    Anyone1 -. validateNotice .-> CartesiDApp
    Anyone1 -- newApplication --> CartesiDAppFactory
    DAppOwner -- migrateToConsensus ---> CartesiDApp
    CartesiDApp -. getClaim .-> Consensus
    CartesiDApp -- withdrawEther --> CartesiDApp
    CartesiDAppFactory == creates ==> CartesiDApp
    Anyone2 -- addInput -------> InputBox
    Anyone2 -- depositEther ---> EtherPortal
    EtherPortal -- "Ether transfer" ----> Anyone3
    EtherPortal -- addInput -----> InputBox
    Anyone2 -- depositERC20Tokens ---> ERC20Portal
    ERC20Portal -- transferFrom ----> ERC20
    ERC20Portal -- addInput -----> InputBox
    Anyone2 -- depositERC721Token ---> ERC721Portal
    ERC721Portal -- safeTransferFrom ----> ERC721
    ERC721Portal -- addInput -----> InputBox
    Anyone2 -- depositSingleERC1155Token ---> ERC1155SinglePortal
    ERC1155SinglePortal -- safeTransferFrom ----> ERC1155
    ERC1155SinglePortal -- addInput -----> InputBox
    Anyone2 -- depositBatchERC1155Token ---> ERC1155BatchPortal
    ERC1155BatchPortal -- safeBatchTransferFrom ----> ERC1155
    ERC1155BatchPortal -- addInput -----> InputBox
    Anyone2 -- relayDAppAddress ---> DAppAddressRelay
    DAppAddressRelay -- addInput -----> InputBox

    class ERC20,ERC721,ERC1155 hasLink
    click ERC20 href "https://eips.ethereum.org/EIPS/eip-20"
    click ERC721 href "https://eips.ethereum.org/EIPS/eip-721"
    click ERC1155 href "https://eips.ethereum.org/EIPS/eip-1155"
Loading

Input Box

This module is the one responsible for receiving inputs from users that want to interact with DApps. For each DApp, the module keeps an append-only list of hashes. Each hash is derived from the input and some metadata, such as the input sender, and the block timestamp. All the data needed to recontstruct a hash is available forever on-chain. As a result, one does not need to trust data providers in order to sync the off-chain machine with the latest input. Note that this module is completely permissionless, and we leave the off-chain machine to judge whether an input is valid or not.

Cartesi DApp

A Cartesi DApp contract, just like any other contract on Ethereum, has a unique address. With this address, a DApp can hold ownership over digital assets on the base layer like Ether, ERC-20 tokens, and NFTs. In the next sections, we'll explain how DApps are able to receive assets through portals, and perform arbitrary message calls, such as asset transfers, through vouchers.

Since there is no access control to execute a voucher, the caller must also provide a proof that such voucher was generated by the off-chain machine. This proof is checked on-chain against a claim, that is provided by the DApp's consensus. Therefore, a DApp must trust its consensus to only provide valid claims. However, if the consensus goes inactive or rogue, the DApp owner can migrate to a new consensus. In summary, DApp users must trust the DApp owner to choose a trustworthy consensus.

Cartesi DApp Factory

The Cartesi DApp Factory allows anyone to deploy Cartesi DApp contracts with a simple function call, costing only 3.5% more gas than deploying the DApp contract directly. It also provides greater convenience to the deployer, and security to users and validators, as they know the bytecode could not have been altered maliciously.

Portals

Portals, as the name suggests, are used to safely teleport assets from the base layer to the execution layer. It works in the following way. First, for some types of assets, the user has to allow the portal to deduct the asset(s) from their account. Second, the user tells the portal to transfer the asset(s) from their account to some DApp's account. The portal then adds an input to the DApp's input box to inform the machine of the transfer that just took place in the base layer. Finally, the off-chain machine is made aware of the transfer through the input sent by the portal. Note that the machine must know the address of the portal beforehand in order to validate such input.

The DApp developer can choose to do whatever they want with this information. For example, they might choose to create a wallet for each user in the execution layer, where assets can be managed at a much lower cost through inputs that are understood by the Linux logic. In this sense, one could think of the DApp contract as a wallet, owned by the off-chain machine. Anyone can deposit assets there but only the DAppโ€”through vouchersโ€”can decide on withdrawals.

The withdrawal process is quite simple from the user's perspective. Typically, the user would first send an input to the DApp requesting the withdrawal, which would then get processed and interpreted off-chain. If all goes well, the machine should generate a voucher that, once executed, transfers the asset(s) to the rightful recipient.

Currently, we support the following types of assets:

Input encodings for deposits

As explained above, in order to teleport assets from the base layer to the execution layer, the portals add inputs to the DApp's input box, which will then need to be interpreted and validated by the off-chain machine. To do that, the machine will need to understand and decode each input's payload.

The input payloads for deposits are always specified as packed ABI-encoded parameters, as detailed below:

Asset Payload
Ether address sender, uint256 value, bytes execLayerData
ERC-20 bool success, address token, address sender, uint256 amount, bytes execLayerData
ERC-721 address token, address sender, uint256 tokenId, bytes data *
ERC-1155 (single) address token, address sender, uint256 tokenId, uint256 value, bytes data *
ERC-1155 (batch) address token, address sender, bytes data **

* The ERC-721 and ERC-1155 (single) data fields correspond to the standard (unpacked) ABI-encoding of: bytes baseLayerData, bytes execLayerData

** The ERC-1155 (batch) data field corresponds to the standard (unpacked) ABI-encoding of: uint256[] tokenIds, uint256[] values, bytes baseLayerData, bytes execLayerData

As an example, the deposit of 100 Wei (of Ether) sent by address 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 with data 0xabcd would result in the following input payload:

0xf39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000000000000000000000000000000000000000000064abcd

Vouchers

Vouchers allow DApps in the execution layer to interact with contracts in the base layer through message calls. They are emitted by the off-chain machine, and executed by anyone in the base layer. Each voucher is composed of a destination address and a payload. In the case of vouchers destined to Solidity contracts, the payload generally encodes a function call.

A voucher can only be executed once the DApp's consensus submits a claim containing it. They can be executed in any order. Although the DApp contract is indifferent to the content of the voucher being executed, it enforces some sanity checks before allowing its execution. First, it checks whether the voucher has been successfully executed already. Second, it ensures that the voucher has been emitted by the off-chain machine, by requiring a validity proof.

Because of their generality, vouchers can be used in a wide range of applications: from withdrawing funds to providing liquidity in a DeFi protocol. Typically, DApps use vouchers to withdraw assets. Below, we show how vouchers can be used to withdraw several types of assets. You can find more information about a particular function by clicking on the ๐Ÿ“„ emoji near it.

Asset Destination Function signature
Ether DApp contract withdrawEther(address,uint256) ๐Ÿ“„
ERC-20 Token contract transfer(address,uint256) ๐Ÿ“„
ERC-20 Token contract transferFrom(address,address,uint256) ๐Ÿ“„ 1
ERC-721 Token contract safeTransferFrom(address,address,uint256) ๐Ÿ“„
ERC-721 Token contract safeTransferFrom(address,address,uint256,bytes) ๐Ÿ“„ 2
ERC-1155 Token contract safeTransferFrom(address,address,uint256,uint256,data) ๐Ÿ“„
ERC-1155 Token contract safeBatchTransferFrom(address,address,uint256[],uint256[],data) ๐Ÿ“„ 3

Please note that the voucher payload should be encoded according to the Ethereum ABI specification for calling contract functions. As such, it should start with the first four bytes of the Keccak-256 hash of the function signature string (as given in the table above), followed by the ABI-encoded parameter values.

As an example, the voucher for a simple ERC-20 transfer (2nd line in the table above) to address 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 with amount 100 should specify the following payload:

0xa9059cbb000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb922660000000000000000000000000000000000000000000000000000000000000064

DApp Address Relay

In the previous section, we showed how vouchers can be used to withdraw different types of assets. Most of those vouchers contain the address of the DApp contract, either as the destination address or as a function argument. So, the off-chain machine needs to "know" the DApp contract address at some point. If the off-chain machine knew the DApp contract address from the beginning, it would create a cyclical dependency between the initial machine state hash (also called "template hash") and the DApp contract address. This is due to the fact that the address of a DApp contract depends on its construction arguments, which include the template hash; and that the template hash is the Merkle root of the machine address space, which includes the DApp contract address.

This "chicken-and-egg" problem is circumvented by a very small permissionless contract in the base layer, the DApp Address Relay (source). Its only job is to add an input to a DApp's input box with the DApp contract address. The off-chain machine then decodes this input and stores the address somewhere for future use. Just like in the case of portals, the machine must also know the address of the relay in order to validate the origin of the input.

Notices

Notices are informational statements that can be proved by contracts in the base layer. They're emitted by the off-chain machine and contain a payload, in bytes. DApp developers are free to explore different use cases for notices, their generality and negligible cost of emission makes them a powerful tool to assist integration between DApps and contracts or even other DApps. Similar to vouchers, notices can only be proved once they've been finalized on-chain and if they're accompanied by a validity proof. A chess DApp could, for example, emit a notice informing the underlying blockchain of the winner of a tournament. While that information is not necessarily "actionable", it could be used by other applications for different purposes.

Consensus

This module is responsible for providing valid claims to DApps after reaching some form of consensus. The module's interface aims to be as generic as possible to accomodate any consensus model, since there are plenty to choose from. The way claims are encoded and stored is abstracted entirely by the interface. Implementation-wise, this is left to a History contract.

The only type of consensus that is currently implemented by Cartesi is called Authority. It is owned by a single address, who has complete power over the consensus. It is arguably the simplest consensus to implement, although quite vulnerable.

History

The sole purpose of this module is to store claims and to allow them to be retrieved later. Just as with the consensus interface, we leave much of the details open for the implementation to define.

Our only implementation of history stores claims in a very simple manner: each claim is composed of an epoch hash and a range of input indices. Each DApp has its own append-only list of claims, where ranges don't overlap, and come one after the other. As a result, one cannot overwrite past claims, or skip inputs, or claim in a non-linear order.

Dispute Resolution

Disputes occur when two validators claim different state updates to the same epoch. Because of the deterministic nature of our virtual machine and the fact that the inputs that constitute an epoch are agreed upon beforehand, conflicting claims imply dishonest behavior. When a conflict occurs, the module that mediates the interactions between both validators is the dispute resolution.

The code for rollups dispute resolution is not being published yet, but a big part of it is available on the Cartesi Rollups SDK, using the Arbitration dlib

Off-chain Rollups

The Rollups machine and the smart contracts live in fundamentally different environments. This creates the need for a middleware that manages and controls the communication between the blockchain and the machine. As such, the middleware is responsible for first reading data from our smart contracts, then sending them to the machine to be processed, and finally publishing their results back to the blockchain.

The middleware can be used by anyone who's interested in the rollups state of affairs. We divide interested users into two roles, which run different types of nodes: readers and validators.

Reader nodes are only interested in advancing their off-chain machine. They consume information from the blockchain but do not bother to enforce state updates, trusting that validators will ensure the validity of all on-chain state updates.

Validators, on the other hand, have more responsibility: they not only watch the blockchain but also fight to ensure that the blockchain will only accept valid state updates.

For more information, refer to the Off-chain documentation.

Experimenting

To get a taste on how to use Cartesi to develop your DApp, check the following resources: See Cartesi Rollups in action with the Simple Echo Examples in C++, JavaScript, Lua, Rust and Python. To have a glimpse on how to develop your DApp locally using your favorite IDE and tools check our Host Environment in the Rollups Examples repository.

Talk with us

If you're interested in developing with Cartesi, working with the team, or hanging out in our community, don't forget to join us on Discord and follow along.

Want to stay up to date? Make sure to join our announcements channel on Telegram or follow our Twitter.

Contributing

Thank you for your interest in Cartesi! Head over to our Contributing Guidelines for instructions on how to sign our Contributors Agreement and get started with Cartesi!

Please note we have a Code of Conduct, please follow it in all your interactions with the project.

Setting up

Cloning submodules

In order to also clone submodules like grpc-interfaces and forge-std, you need to run the following command.

git submodule update --init --recursive

Building the Docker images

To build the Rollups Docker images, run the following command.

docker buildx bake --load

Compiling the on-chain code

In order to install dependencies for the on-chain code, you'll need yarn. See the Yarn documentation for instructions on how to install yarn on your system. Once you have yarn installed on your system, you can install the necessary dependencies and build the on-chain code by running the following commands.

cd onchain/rollups
yarn
yarn build

Compiling the off-chain code

The off-chain code is written in Rust. For that, you'll need cargo. See the Rust documentation for instructions on how to install cargo on your system.

cd offchain
cargo build

Testing

Once you've setup the repository, you can test the different pieces that compose Cartesi Rollups individually.

Testing the on-chain code

In order to run the on-chain tests, you'll also need forge. Please consult the Foundry documentation for installation instructions. In case you already have forge on your machine, then please make sure you have the latest version. Furthermore, you'll also need to generate Merkle proofs for output validation tests. Please carefully read this README for further instructions. Once everything is properly set up, you can test the on-chain code by running the following commands.

cd onchain/rollups
yarn test

License

Note: This component currently has dependencies that are licensed under the GNU GPL, version 3, and so you should treat this component as a whole as being under the GPL version 3. But all Cartesi-written code in this component is licensed under the Apache License, version 2, or a compatible permissive license, and can be used independently under the Apache v2 license. After this component is rewritten, the entire component will be released under the Apache v2 license. The arbitration d-lib repository and all contributions are licensed under GPL 3. Please review our COPYING file.

Footnotes

  1. If the DApp owns the tokens, prefer to use transfer(address,uint256) โ†ฉ

  2. If no data is being passed as argument, prefer to use safeTransferFrom(address,address,uint256) โ†ฉ

  3. If only one token is being transferred, prefer to use safeTransferFrom(address,address,uint256,uint256,data) โ†ฉ

rollups's People

Contributors

guidanoli avatar felipeargento avatar tuler avatar gcdepaula avatar gligneul avatar victornogueirario avatar mayorcoded avatar gmkrieger avatar endersonmaia avatar miltonjonat avatar marcelstanley avatar torives avatar renan061 avatar romanhodulak avatar zzzzhui avatar claudioantonio avatar nazeim avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.