Skip to main content

Application

This chapter will show you how to quickly create, build and test a minimal containerized ROFL app.

ROFL apps come in different flavors and the right choice is a tradeoff between TCB size and ease of use. The easiest to use are TDX container-based apps which are presented in this guide and more advanced flavors with smaller TCBs are described separately.

How do ROFL Apps Work?

ROFL diagram

Each ROFL app runs in its own Trusted Execution Environment (TEE) which is provisioned by an Oasis Node from its bundle (a zip archive containing the program binaries and metadata required for execution). ROFL apps register to the Oasis Network in order to be able to easily authenticate to on-chain smart contracts and transparently gain access to the decentralized per-app key management system.

Inside the TEE, the ROFL app performs important functions that ensure its security and enable secure communication with the outside world. This includes using a light client to establish a fresh view of the Oasis consensus layer which provides a source of rough time and integrity for verification of all on-chain state. The ROFL app also generates a set of ephemeral cryptographic keys which are used in the process of remote attestation and on-chain registration. These processes ensure that the ROFL app can authenticate to on-chain modules (e.g. smart contracts running in the Sapphire runtime) by signing and submitting special transactions.

The ROFL app can then perform arbitrary work and interact with the outside world through (properly authenticated) network connections. Connections can be authenticated via HTTPS/TLS or use other methods (e.g. light clients for other chains).

App Directory and Manifest

First we create the basic directory structure for the ROFL app using the Oasis CLI. We also need to select the network (in this case testnet) and the account that will be the initial administrator of the ROFL app (in this case myaccount):

oasis rofl init myapp --network testnet --account myaccount

This will create the myapp directory and initialize some boilerplate needed to build a TDX container-based ROFL app. The rest of the guide assumes that you are executing commands from within this directory.

The command will output a summary of what is being created:

Creating a new ROFL app with default policy...
Name: myapp
Version: 0.1.0
TEE: tdx
Kind: container
Deployment 'default':
Network: testnet
ParaTime: sapphire
Debug: false
Admin: myaccount
Created manifest in 'rofl.yaml'.
Run `oasis rofl create --update-manifest` to register your ROFL app and configure an app ID.

After you complete this guide, the directory structure will look as follows:

myapp
├── compose.yaml # Container compose file.
└── rofl.yaml # ROFL app manifest.

The manifest contains things like ROFL app metadata, secrets, requested resources and can be modified either manually or by using the CLI commands.

Create

Before the ROFL app can be built it needs to be created on chain to assign it a unique identifier (the app ID) which can be used by on-chain smart contracts to ensure that they are talking to the right app and also gives the app access to a decentralized key management system.

Anyone with enough funds can create an app. Currently, this threshold is 10,000 TEST on Sapphire Testnet and Localnet (funded automatically). ROFL registration on Sapphire Mainnet is yet to be enabled.

tip

In order to obtain TEST tokens needed for creating and running your ROFL apps use the faucet or ask on Discord. To make things easier you should create or import a secp256k1-bip44 account that you can also use with the Ethereum-compatible tooling like Hardhat.

Passing the --update-manifest argument will make the CLI automatically update the app manifest (rofl.yaml) with the assigned app identifier.

oasis rofl create --update-manifest

After successful creation, the CLI will also output the new identifier:

Created ROFL application: rofl1qqn9xndja7e2pnxhttktmecvwzz0yqwxsquqyxdf

The app deployer account automatically becomes the initial admin of the app so it can update the app's configuration. The admin address can always be changed by the current admin.

info

While the CLI implements a simple governance mechanism where the admin of the ROFL app is a single account, even a smart contract can be the admin. This allows for implementation of advanced agent governance mechanisms, like using multi-sigs or DAOs with veto powers to control the upgrade process.

Oracle Contract

info

While we are using EVM-based smart contracts in this example, the on-chain part can be anything from a WASM-based smart contract to a dedicated runtime module.

We have prepared a simple oracle contract for this example. You can find it by checking out the prepared example project from the Oasis SDK repository. It contains a simple Oracle.sol contract which collects observations from authenticated ROFL app instances, performs trivial aggregation and stores the final aggregated result. Read the Sapphire quickstart chapter to learn how to build and deploy Sapphire smart contracts, but to get you up and running for this part, simply copy the example project from above, install dependencies and compile the smart contract by executing:

npm install
npx hardhat compile

Configure the PRIVATE_KEY of the deployment account and the ROFL app identifier (be sure to use the identifier that you received during registration), then deploy the contract by running, for example:

PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" \
npx hardhat deploy rofl1qqn9xndja7e2pnxhttktmecvwzz0yqwxsquqyxdf --network sapphire-testnet

After successful deployment you will see a message like:

Oracle for ROFL app rofl1qqn9xndja7e2pnxhttktmecvwzz0yqwxsquqyxdf deployed to 0x1234845aaB7b6CD88c7fAd9E9E1cf07638805b20

You can now proceed to building and deploying the ROFL app itself. Remember the address where the oracle contract was deployed to as you will need it in the next step.

Define Containerized Services

What the core of the ROFL app does is defined with services running in Podman containers defined in the compose file. Anything that can run as a bunch of containers can also be run as a ROFL app.

For an easier start, we will use the oasisprotocol/demo-rofl container which is defined in the demo-rofl repository and implements a trivial oracle in a shell script.

The compose file (compose.yaml) looks as follows:

services:
oracle:
# See the 'docker' subdirectory in demo-rofl for the content of this image.
# Note that we are using the sha256 hash of the image to ensure integrity.
image: docker.io/oasisprotocol/demo-rofl:latest@sha256:42c32ccfe0a0c84ac5969a1399e4658bed8e8d1517cc6b26cdce67439c66c910
environment:
# Address of the oracle contract deployed on Sapphire Testnet.
- CONTRACT_ADDRESS=1234845aaB7b6CD88c7fAd9E9E1cf07638805b20
# Ticker.
- TICKER=ROSEUSDT
volumes:
- /run/rofl-appd.sock:/run/rofl-appd.sock

Build

Whenever you make changes to your ROFL app and want to deploy it, you first need to build it. The build process takes the compose file together with other ROFL app artifacts and deterministically generates a bundle that can later be deployed.

The build process also computes the enclave identity of the bundle which is used during the process of remote attestation to authenticate the app instances before granting them access to the key management system and other features.

To build a ROFL app and update the enclave identity in the app manifest, simply run:

oasis rofl build --update-manifest

This will generate the resulting ROFL app bundle which can be used for later deployment and output something like:

ROFL app built and bundle written to 'myapp.default.orc'.

Update On-chain App Config

After any changes to the ROFL app policy defined in the manifest, the on-chain app config needs to be updated in order for the changes to take effect.

The designated admin account is able to update this policy by issuing an update transaction which can be done via the CLI by running:

oasis rofl update