Skip to main content

Manage ROFL Apps

The rofl command combines a series of actions for managing the Runtime OFfchain Logic (ROFL) apps:

  • build ROFL locally,
  • verify the ROFL bundle,
  • register, deregister and update ROFL apps on the network,
  • show information about the registered ROFL apps,
  • other convenient tooling for ROFL app developers.

Initialize a new ROFL app manifest

The rofl init command will prepare a new ROFL app manifest in the given directory (defaults to the current directory). The manifest is a YAML file named rofl.yaml which defines the versions of all components, upgrade policies, etc. needed to manage, build and deploy the ROFL app.

oasis rofl init
Creating a new ROFL app with default policy...
Name: myapp
Version: 0.1.0
TEE: tdx
Kind: container
Created manifest in 'rofl.yaml'.
Run `oasis rofl create` to register your ROFL app and configure an app ID.

Note that by default the manifest will not contain any deployments. In order to create deployments, use rofl create.

Create a new ROFL app on the network

Use rofl create to register a new ROFL app on the network using an existing manifest.

You can also define specific Network, ParaTime and Account parameters as those get recorded into the manfiest so you don't need to specify them on each invocation:

oasis rofl create --network testnet --account my_rofl_acc
You are about to sign the following transaction:
Format: plain
Method: rofl.Create
Body:
{
"policy": {
"quotes": {
"pcs": {
"tcb_validity_period": 30,
"min_tcb_evaluation_data_number": 17,
"tdx": {}
}
},
"enclaves": [],
"endorsements": [
{
"any": {}
}
],
"fees": 2,
"max_expiration": 3
},
"scheme": 1
}
Authorized signer(s):
1. sk5kvBHaZ/si0xXRdjllIOxOgr7o2d1K+ckVaU3ndG4= (ed25519)
Nonce: 319
Fee:
Amount: 0.0101405 TEST
Gas limit: 101405
(gas price: 0.0000001 TEST per gas unit)

Network: testnet
ParaTime: sapphire (Sapphire Testnet)
Account: test:dave

Returned is the unique ROFL app ID starting with rofl1 and which you will refer to for managing your ROFL app in the future. The manifest is automatically updated with the newly assigned app identifier.

info

In order to prevent spam attacks registering a ROFL app requires a certain amount to be deposited from your account until you decide to remove it. The deposit remains locked for the lifetime of the app. Check out the Stake Requirements chapter for more information.

With the --scheme parameter, you can select one of the following ROFL app ID derivation schemes:

  • cn for the ROFL app creator address (the account you're using to sign the transaction) combined with the account's nonce (default). This behavior is similar to the one of the Ethereum smart contract address derivation and is deterministic.
  • cri uses the ROFL app creator address combined with the block round the transaction will be validated in and its position inside that block.

Build ROFL

The rofl build command will execute a series of build commands depending on the target Trusted Execution Environment (TEE) and produce the Oasis Runtime Container (ORC) bundle.

Additionally, the following flags are available:

  • --output the filename of the output ORC bundle. Defaults to the pattern <name>.<deployment>.orc where <name> is the app name from the manifest and <deployment> is the deployment name from the manifest.

  • --verify also verifies the locally built enclave identity against the identity that is currently defined in the manifest and also against the identity that is currently set in the on-chain policy. It does not update the manifest file with new entity id(s).

  • --no-update-manifest do not update the enclave identity stored in the app manifest.

info

Building ROFL apps does not require a working TEE on your machine. However, you do need to install all corresponding tools. Check out the ROFL Prerequisites chapter for details.

Secrets management

Set secret

Run rofl secret set <secret_name> <filename>|- command to end-to-end encrypt a secret with a key derived from the selected deployment network and store it to the manifest file.

If you have your secret in a file, run:

oasis rofl secret set MY_SECRET mysecret.txt

You can also feed the secret from a standard input like this:

echo -n "this-is-a-very-secret-value-here" | oasis rofl secret set MY_SECRET -

Once the secret is encrypted and stored, there is no way of obtaining the unencrypted value back again apart from within the TEE on the designated ROFL deployment.

Shells store history

Passing secrets as a command line argument will store them in your shell history file as well! Use this approach only for testing. In production, always use file-based secrets.

Get secret info

Run rofl secret get <secret-name> to check whether the secret exists in your manifest file.

oasis rofl secret get MY_SECRET
Name:        MY_SECRET
Size: 156 bytes

Remove secret

Run rofl secret rm <secret-name> to remove the secret from your manifest file.

oasis rofl secret rm MY_SECRET

Update ROFL app config on-chain

Use rofl update command to push the ROFL app's configuration to the chain:

oasis rofl update
You are about to sign the following transaction:
Format: plain
Method: rofl.Update
Body:
{
"id": "rofl1qzd82n99vtwesvcqjfyur4tcm45varz2due7s635",
"policy": {
"quotes": {
"pcs": {
"tcb_validity_period": 30,
"min_tcb_evaluation_data_number": 17,
"tdx": {}
}
},
"enclaves": [],
"endorsements": [
{
"any": {}
}
],
"fees": 2,
"max_expiration": 3
},
"admin": "oasis1qrk58a6j2qn065m6p06jgjyt032f7qucy5wqeqpt"
}
Authorized signer(s):
1. sk5kvBHaZ/si0xXRdjllIOxOgr7o2d1K+ckVaU3ndG4= (ed25519)
Nonce: 320
Fee:
Amount: 0.010145 TEST
Gas limit: 101450
(gas price: 0.0000001 TEST per gas unit)

Network: testnet
ParaTime: sapphire (Sapphire Testnet)
Account: test:dave

The current on-chain policy, metadata and secrets will be replaced with the ones in the manifest file. Keep in mind that ROFL replicas need to be restarted in order for changes to take effect.

Show ROFL information

Run rofl show to obtain the information from the network on the ROFL admin account, staked amount, current ROFL policy and running instances:

oasis rofl show
App ID:        rofl1qzd82n99vtwesvcqjfyur4tcm45varz2due7s635
Admin: oasis1qrk58a6j2qn065m6p06jgjyt032f7qucy5wqeqpt
Staked amount: 10000.0
Policy:
{
"quotes": {
"pcs": {
"tcb_validity_period": 30,
"min_tcb_evaluation_data_number": 17,
"tdx": {}
}
},
"enclaves": [
"z+StFagJfBOdGlUGDMH7RlcNUm1uqYDUZDG+g3z2ik8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"6KfY4DqD1Vi+H7aUn5FwwLobEzERHoOit7xsrPNz3eUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="
],
"endorsements": [
{
"any": {}
}
],
"fees": 2,
"max_expiration": 3
}

=== Instances ===
- RAK: UwuhJrOYX6FDOc27NilQSrcVEtWD9voq+ST+ohsaRTI=
Node ID: DbeoxcRwDO4Wh8bwq5rAR7wzhiB+LeYn+y7lFSGAZ7I=
Expiration: 7

Deploy ROFL app

Run rofl deploy to automatically deploy your app to a machine obtained from the ROFL marketplace. If a machine is already configured in your manifest file a new version of your ROFL app will be deployed there. If no machines are rented yet, you can use the following arguments to select a specific provider and offer:

  • --provider <address> specifies the provider to rent the machine from. On Sapphire Testnet, the Oasis-managed provider will be selected by default.
  • --offer <offer_name> specifies the offer of the machine to rent. Run --show-offers to list offers and specifications.
oasis rofl deploy
Using provider: oasis1qp2ens0hsp7gh23wajxa4hpetkdek3swyyulyrmz (oasis1qp2ens0hsp7gh23wajxa4hpetkdek3swyyulyrmz)
Pushing ROFL app to OCI repository 'rofl.sh/2db0216a-17eb-46a4-8dcc-3115564ced5c:1748005573'...
No pre-existing machine configured, creating a new one...
Taking offer: playground_short [0000000000000001]
Unlock your account.
? Passphrase:
You are about to sign the following transaction:
Format: plain
Method: roflmarket.InstanceCreate
Body:
{
"provider": "oasis1qp2ens0hsp7gh23wajxa4hpetkdek3swyyulyrmz",
"offer": "0000000000000001",
"deployment": {
"app_id": "rofl1qrjtky678pd3uchsdlhqtjugnsvtck3wyg7w5324",
"manifest_hash": "5de346e10f8306ffcdbbe02a87c850b39727dd175b786f2d2daad03ba9a34013",
"metadata": {
"net.oasis.deployment.orc.ref": "rofl.sh/2db0216a-17eb-46a4-8dcc-3115564ced5c:1748005573@sha256:0c09081e9802de746e5a862b6ee77c8b6cd915928558cd0770a5f35957dd535d"
}
},
"term": 1,
"term_count": 1
}
Authorized signer(s):
1. +xJDGEpqAtJIJP8suwwDtWKgqxAeWNAGY7tzocCpACM= (ed25519)
Nonce: 7
Fee:
Amount: 0.0121918 TEST
Gas limit: 121918
(gas price: 0.0000001 TEST per gas unit)

Network: testnet
ParaTime: sapphire
Account: test:dave

Advanced

Upgrade ROFL app dependencies

Run rofl upgrade to bump ROFL bundle TDX artifacts in your manifest file to their latest versions. This includes:

  • the firmware
  • the kernel
  • stage two boot
  • ROFL containers middleware (for TDX containers kind only)
oasis rofl upgrade

Remove ROFL app from the network

Run rofl remove to deregister your ROFL app:

oasis rofl remove
WARNING: Removing this ROFL app will DEREGISTER it, ERASE any on-chain secrets and local configuration!
WARNING: THIS ACTION IS IRREVERSIBLE!
? Remove ROFL app 'rofl1qzd82n99vtwesvcqjfyur4tcm45varz2due7s635' deployed on network 'testnet' Yes
Unlock your account.
? Passphrase:
You are about to sign the following transaction:
Format: plain
Method: rofl.Remove
Body:
{
"id": "rofl1qzd82n99vtwesvcqjfyur4tcm45varz2due7s635"
}
Authorized signer(s):
1. sk5kvBHaZ/si0xXRdjllIOxOgr7o2d1K+ckVaU3ndG4= (ed25519)
Nonce: 321
Fee:
Amount: 0.0011288 TEST
Gas limit: 11288
(gas price: 0.0000001 TEST per gas unit)

Network: testnet
ParaTime: sapphire (Sapphire Testnet)
Account: test:dave

The deposit required to register the ROFL app will be returned to the current administrator account.

Secrets will be permanently lost

All secrets stored on-chain will be permanently lost when the ROFL app is deregistered! If you backed up your manifest file, those secrets will also be unretrievable since they were encrypted with a ROFL deployment-specific keypair.

ROFL provider tooling

The rofl provider commands offers tools for managing your on-chain provider information and your offers.

An example provider configuration file looks like this:

rofl-provider.yaml
# Network name in your Oasis CLI
network: testnet
# ParaTime name in your Oasis CLI
paratime: sapphire
# Account name in your Oasis CLI
provider: rofl_provider
# List of Base64-encoded node IDs allowed to execute ROFL apps
nodes:
-
# Address of the scheduler app
scheduler_app: rofl1qrqw99h0f7az3hwt2cl7yeew3wtz0fxunu7luyfg
# Account name or address of who receives ROFL machine rental payments
payment_address: rofl_provider
offers:
- id: small # Short human-readable name
resources:
tee: tdx # Possible values: sgx, tdx
memory: 4096 # In MiB
cpus: 2
storage: 20000 # In MiB
payment:
native: # Possible keys: native, evm
terms:
hourly: 10 # Possible keys: hourly, monthly, yearly
capacity: 50 # Max number of actively rented machines

Initialize a ROFL provider

The rofl provider init initializes a new provider configuration file.

info

Network and ParaTime selectors are available for the rofl provider init command.

Create a ROFL provider on-chain

Run rofl provider create to register your account as a provider on the configured network and ParaTime.

oasis rofl provider create
Unlock your account.
? Passphrase:
You are about to sign the following transaction:
Format: plain
Method: roflmarket.ProviderCreate
Body:
{
"nodes": [],
"scheduler_app": "rofl1qrqw99h0f7az3hwt2cl7yeew3wtz0fxunu7luyfg",
"payment_address": {
"native": "oasis1qrk58a6j2qn065m6p06jgjyt032f7qucy5wqeqpt"
},
"offers": null,
"metadata": {}
}
Authorized signer(s):
1. AyZKkxNFeyqLI5HGTYqEmCcYxKGo/kueOzSHzdnrSePO (secp256k1eth)
Nonce: 858
Fee:
Amount: 0.012167 TEST
Gas limit: 121670
(gas price: 0.0000001 TEST per gas unit)

Network: testnet
ParaTime: sapphire
Account: test:dave
info

In order to prevent spam attacks registering a ROFL provider requires a certain amount to be deposited from your account until you decide to remove it. The deposit remains locked for the lifetime of the provider entity. Check out the Stake Requirements chapter for more information.

Update ROFL provider policies

Use rofl provider update to update the list of endorsed nodes, the scheduler app address, the payment recipient address and other provider settings.

oasis rofl provider update
Unlock your account.
? Passphrase:
You are about to sign the following transaction:
Format: plain
Method: roflmarket.ProviderUpdate
Body:
{
"provider": "oasis1qrk58a6j2qn065m6p06jgjyt032f7qucy5wqeqpt",
"nodes": [],
"scheduler_app": "rofl1qrqw99h0f7az3hwt2cl7yeew3wtz0fxunu7luyfg",
"payment_address": {
"native": "oasis1qrk58a6j2qn065m6p06jgjyt032f7qucy5wqeqpt"
},
"metadata": {}
}
Authorized signer(s):
1. AyZKkxNFeyqLI5HGTYqEmCcYxKGo/kueOzSHzdnrSePO (secp256k1eth)
Nonce: 860
Fee:
Amount: 0.0121698 TEST
Gas limit: 121698
(gas price: 0.0000001 TEST per gas unit)

Network: testnet
ParaTime: sapphire
Account: test:dave

To update your offers, run rofl provider update-offers instead.

Update ROFL provider offers

Use rofl provider update-offers to replace the on-chain offers with the ones in your provider manifest file.

oasis rofl provider update-offers
$ oasis rofl provider update-offers 
Unlock your account.
? Passphrase:
Going to perform the following updates:
Add offers:
- small
Update offers:
<none>
Remove offers:
<none>
You are about to sign the following transaction:
Format: plain
Method: roflmarket.ProviderUpdateOffers
Body:
{
"provider": "oasis1qrk58a6j2qn065m6p06jgjyt032f7qucy5wqeqpt",
"add": [
{
"id": "0000000000000000",
"resources": {
"tee": 2,
"memory": 4096,
"cpus": 2,
"storage": 20000
},
"payment": {
"native": {
"denomination": "",
"terms": {
"1": "10000000000000000000"
}
}
},
"capacity": 50,
"metadata": {
"net.oasis.scheduler.offer": "small"
}
}
]
}
Authorized signer(s):
1. AyZKkxNFeyqLI5HGTYqEmCcYxKGo/kueOzSHzdnrSePO (secp256k1eth)
Nonce: 860
Fee:
Amount: 0.0133782 TEST
Gas limit: 133782
(gas price: 0.0000001 TEST per gas unit)

Network: testnet
ParaTime: sapphire
Account: test:dave

To update your provider policies, run rofl provider update instead.

Remove ROFL provider from the network

Run rofl provider remove to deregister your ROFL provider account:

oasis rofl provider remove
Unlock your account.
? Passphrase:
You are about to sign the following transaction:
Format: plain
Method: roflmarket.ProviderRemove
Body:
{
"provider": "oasis1qrk58a6j2qn065m6p06jgjyt032f7qucy5wqeqpt"
}
Authorized signer(s):
1. AyZKkxNFeyqLI5HGTYqEmCcYxKGo/kueOzSHzdnrSePO (secp256k1eth)
Nonce: 859
Fee:
Amount: 0.0121578 TEST
Gas limit: 121578
(gas price: 0.0000001 TEST per gas unit)

Network: testnet
ParaTime: sapphire
Account: test:dave

The deposit required to register the ROFL provider will be returned to its address.

Show ROFL identity

Run rofl identity to compute the cryptographic identity of the ROFL app:

oasis rofl identity rofl-oracle.orc
wzwUd5Ym/e5OO87pGVk2yWL4v0x12U3Zx/48Vdoe1PyTBkRbZbh9kPyqgY1RsvenXEIHQA0c2nR/WlmvS1vbcg==

The output above is Base64-encoded enclave identity which depends on the ROFL source code and the build environment. Enclave identities should be reproducible on any computer and are used to prove and verify the integrity of ROFL binaries on the network. See the Reproducibility chapter to learn more.

Show the current trust-root

In order the ROFL app can trust the environment it is executed in, it needs to have a hardcoded trust root. Typically, it consists of:

To obtain the latest trust root in rust programming language, run oasis rofl trust-root:

oasis rofl trust-root
TrustRoot {
height: 1022,
hash: "bb3e63d729dd568ce07b37eea33eddf8082ed4cacbd64097aad32168a4a4fc9a".into(),
runtime_id: "8000000000000000000000000000000000000000000000000000000000000000".into(),
chain_context: "074f5ba071c4385a7ad24aea0a3a7b137901395e8f3b35479c1cce87d3170f4e".to_string(),
}

You can also define specific Network and ParaTime parameters:

oasis rofl trust-root --network testnet --paratime sapphire