Loading repository data…
Loading repository data…
Andrew-Tsegaye / repository
Rock Paper Scissors dApp is developed using Python and integrates with the Ethereum blockchain using Web3.
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
This repository includes examples of decentralized applications implemented using Cartesi Rollups.
You can use online development environments such as Gitpod and CodeSandbox to open this repository directly in your browser with all required dependencies already installed. These services allow you to start experimenting immediately, but keep in mind that they are provided by third-parties and are subject to unavailability and policy changes. They may also require access to your GitHub account in order to work properly.
From a developer’s point of view, each decentralized application or DApp is composed of two main parts: a front-end and a back-end.
The front-end corresponds to the user-facing interface, which for these examples will correspond to a command-line console application.
On the other hand, the back-end contains the business logic of the application, similar to what traditional systems would run inside a server. Its basic goal is to store and update the application state as user input is received, producing corresponding outputs. These outputs can come in the form of vouchers (transactions that can be carried out on layer-1, such as a transfer of assets) and notices (informational statements that can be verified on layer-1, such as the resulting score of a game). In addition to that, the back-end can also issue reports, which correspond to general information that does not need to be verifiable by third-parties, such as application logs.
When compared to traditional software development, the main difference of a Cartesi DApp is that the back-end is deployed to a decentralized network of layer-2 nodes, who continuously verify the correctness of all processing results. As a consequence, the front-end and back-end do not communicate directly with each other. Rather, the front-end sends inputs to the Cartesi Rollups framework, who in turn makes them available to the back-end instances running inside each node. After the inputs are processed by the back-end logic, the corresponding outputs are then informed back to the Rollups framework, which enforces their correctness and makes them available to the front-end and any other interested parties.
As discussed above, the front-end and back-end parts of a Cartesi DApp communicate with each other through the Rollups framework. This is accomplished in practice by using a set of HTTP interfaces, which are specified in Cartesi's OpenAPI Interfaces repository.
The DApp's back-end interacts with the Cartesi Rollups framework by retrieving processing requests and then submitting corresponding outputs.
The front-end part of the DApp needs to access the Cartesi Rollups framework to submit user inputs and retrieve the corresponding vouchers, notices and reports produced by the back-end. As mentioned before, it is possible to interact with all the examples in this repository through the minimalistic and general-purpose frontend-console application.
Docker version 20.10.14 with Docker Buildkit enabled is required for building the environment and executing the examples.
We recommend using Docker Desktop, which already enables Buildkit by default.
Alternatively, an environment variable with value DOCKER_BUILDKIT=1 can also be set.
The below instructions have been tested in systems running both Linux (Ubuntu), MacOS, and Windows (using WSL, which is highly recommended for Windows users).
To run the examples, first clone the repository as follows:
git clone https://github.com/cartesi/rollups-examples.git
Then, for each example, build the required docker images:
cd <example>
docker buildx bake --load
This will also build the example's Cartesi Machine containing the DApp's back-end logic.
Each application can be executed in Production and Host modes, as explained below.
In this mode, the DApp's back-end logic is executed inside a Cartesi Machine, meaning that its code is compiled to the machine's RISC-V architecture. This ensures that the computation performed by the back-end is reproducible and hence verifiable, enabling a truly trustless and decentralized execution.
After building an example as described in the previous section, you can run it in production mode by executing:
cd <example>
docker compose -f ../docker-compose.yml -f ./docker-compose.override.yml up
Allow some time for the infrastructure to be ready. How much will depend on your system, but eventually the container logs will only show the continuous production of empty blocks in the local blockchain, as displayed below:
rollups-examples-hardhat-1 | Mined empty block range #32 to #33
rollups-examples-hardhat-1 | Mined empty block range #32 to #34
rollups-examples-hardhat-1 | Mined empty block range #32 to #35
rollups-examples-hardhat-1 | Mined empty block range #32 to #36
The environment can be shut down with the following command:
docker compose -f ../docker-compose.yml -f ./docker-compose.override.yml down -v
The Cartesi Rollups Host Environment provides the very same HTTP API as the regular one, mimicking the behavior of the actual layer-1 and layer-2 components. This way, the Cartesi Rollups infrastructure can make HTTP requests to a back-end that is running natively on localhost. This allows the developer to test and debug the back-end logic using familiar tools, such as an IDE.
The host environment can be executed with the following command:
docker compose -f ../docker-compose.yml -f ./docker-compose.override.yml -f ../docker-compose-host.yml up
Note: In production mode, rejected inputs are guaranteed to have no effect on the back-end, since in that case the Cartesi Machine is completely rolled back to its previous state. However, in host mode there is no such guarantee and it is possible for changes to persist, for instance if the DApp allows an invalid input to change a global variable or produce a database write before it is rejected.
Note: When running in host mode, localhost port 5004 will be used by default to allow the DApp's back-end to communicate with the Cartesi Rollups framework.
Whether in production mode or in host mode, it is possible to configure the level of logging information printed by the environment components. The main docker-compose.yml file specifies the environment services and their configurations, and these include environment variables that can be used to control the level of logging detail for each service.
For most services, the variable RUST_LOG defines the log level. The possible values for it are the following: trace, debug, info, warn, and error.
In production mode, the server_manager service has two different variables to control logging levels. SERVER_MANAGER_LOG_LEVEL controls the level of detail for the service itself, while REMOTE_CARTESI_MACHINE_LOG_LEVEL controls it for the Cartesi Machine in which the back-end is executing. The possible values for these variables are slightly different: trace, debug, info, warning, error, and fatal. Note that these definitions do not affect the output printed by the back-end code itself, which has independent control of its logging level.
It is possible to start an interactive console for the Cartesi Machine containing the application's back-end logic. This allows you to experiment with the back-end's software stacks within its production environment, allowing you to evaluate performance and explore the most adequate technology choices for its implementation.
After the Building step above is executed, a corresponding console Docker image is made available for that purpose. To run it and start your interactive console, type the following command:
docker run --rm -it cartesi/dapp:<example>-devel-console
The example's specific resources can generally be found within the /mnt/dapp directory.
To run the console as the root user, type the following command:
docker run --rm -it cartesi/dapp:<example>-devel-console run-machine-console.sh --run-as-root
When executing an example, it is possible to advance time in order to simulate the passing of epochs. To do that, run:
curl --data '{"id":1337,"jsonrpc":"2.0","method":"evm_increaseTime","params":[864010]}' http://localhost:8545
Deploying a new Cartesi DApp to a blockchain requires creating a smart contract on that network, as well as running a validator node for the DApp.
The first step is to build the DApp's back-end machine, which will produce a hash that serves as a unique identifier.
Make sure to inform for which network (defaults to localhost) the back-end machine is going to be built by overriding build argument *.args.NETWORK.
For example, to build a machine to be deployed to Sepolia, proceed as follows:
cd <example>
docker buildx bake machine --load --set *.args.NETWORK=sepolia
Once the machine docker image is ready, we can use it to deploy a corresponding Rollups smart contract.
In order to do that, you will need to provide an account with some funds for submitting transactions. The account is often specified by providing a mnemonic string, and optionally an account index to use from that mnemonic. For testnets such as Sepolia, it is usually possible to get free testnet funds by using token faucets. But do keep in mind that individual faucets are kept by third-parties, are not guaranteed to be functioning at all times, and may be discontinued.
Aside from the account to use, submitting transactions also requires you to provide the URL of an appropriate RPC gateway node for the target network. There are many options for that, and several services provide private nodes with free tiers that are more than enough for running these examples. Some options include Alchemy, Infura and Moralis.
You can specify the account and RPC gateway to use by defining the following environment variables:
export MNEMONIC=<user sequence of twelve words>
export RPC_URL=<https://your.rpc.gateway>
For example, to configure deployment to the Sepolia testnet using an Alchemy RPC node, you could execute:
export MNEMONIC=<user sequence of twelve words>
export RPC_URL=https://eth-sepolia.g.alchemy.com/v2/<USER_KEY>
With that in place, you can submit a deploy transaction to the Cartesi DApp Factory contract on the target network by executing the following command:
DAPP_NAME=<example> docker compose --env-file ../env.<network> -f ../deploy-testnet.yml up
Here, env.<network> specifies general parameters for the target network, like its name and chain ID. In the case of Sepolia, the command would be:
DAPP_NAME=<example> docker compose --env-file ../env.sepolia -f ../deploy-testnet.yml up
This will create a file at ../deployments/<network>/<example>.json with the deployed contract's address.
Once the command finishes, it is advi