Skip to content
substrate runtime in Trusted Execution Environment
Branch: master
Clone or download
Latest commit 8014ea4 May 15, 2019


substrate runtime in Trusted Execution Environment

substraTEE is an extension to Parity Substrate, allowing to call a custom state transition function inside a Trusted Execution Environment (TEE), namely an Intel SGX enclave thereby providing confidentiality and integrity. The enclaves operate on an encrypted state which can be read and written only by a set of provisioned and remote-attested enclaves. substraTEE enables use cases demanding transaction privacy as well as atomic cross-chain transfers (bridges).

Concept Study

Different use cases for TEE's and potential software architectures have been analyzed and compared in CONCEPTS. In the following we'll refer to the substraTEE-worker architecture, which has been implemented because it supports the widest range of use cases.


M1 PoC1: single-TEE confidential state transition function

off-chain worker runs STF within an Intel SGX enclave. The state is persisted in a sealed file which can only be read by that very enclave.

The demo STF will be a simple counter.

M2 PoC2: single-TEE confidential state transition function in WASM

In addition to M1, the STF is defined by WASM code which is run by a WASMI interpreter within an Intel SGX enclave.

The demo STF will be a simple counter.

M3 simple enclave provisioning

multiple workers can be assigned to a particular STF (contract). Only one of the enclaves will be master, the others serve as a failover backup. Additional enclaves join by supplying remote attestation (RA) from Intel IAS and get group keys from partially trusted provisioning services (PS).

M4 enclave provisioning

Enhanced provisioning (get rid of partially trusted PS).

enclave joins by supplying RA. With every enclave membership change group keys are renewed using dynamic peer group key agreement among enclaves.

Overview M1

The high level architecture of the current implementation can be seen in the following diagram:


The main building blocks can be found in the following repositories:

  • substraTEE-node: (custom substrate node) A substrate node with a custom runtime module
  • substraTEE-worker (client, worker-app, worker-enclave): A SGX-enabled service that performs a confidential state-transition-function


This repo hosts docker files to showcase the milestones.

M1 PoC1: single-TEE confidential state transition function

The following requirements are needed to run the M1 demo:

  • Docker installed
  • Active internet connection

To build and execute the code, follow these instructions:

  1. Clone the substraTEE repository to your favorite location:

    $ git clone
  2. Build the docker image:

    $ docker build -t substratee -f DockerfileM1 .

    This may take some time (~2h on a recent MacBook), so grab a cup of ☕️ or 🍵 - or two.

  3. Start the docker image and get an interactive shell:

    $ docker run -v $(pwd):/substraTEE/backup -ti substratee

    The -v $(pwd):/substraTEE/backup is used to save the files generated by the enclave for later use and can also be omitted.

    If you are in a PowerShell on Windows, replace the $(pwd) with ${PWD}.

  4. Start the development substraTEE-node in the background and log the output in a file:

    root@<DOCKERID>:/substraTEE# /substraTEE/substraTEE-node-M1/target/release/substratee-node --dev > node.log 2>&1 &

    The node now runs in the background and the output can be inspected by calling: tail -f /substraTEE/node.log.

  5. Start the substraTEE-worker and generate the keys:

    root@<DOCKERID>:/substraTEE# cd /substraTEE/substraTEE-worker-M1
    root@<DOCKERID>:/substraTEE/substraTEE-worker-M1# ./bin/substratee_worker getpublickey
    root@<DOCKERID>:/substraTEE/substraTEE-worker-M1# ./bin/substratee_worker getsignkey

    This will generate the sealed (= encrypted) RSA3072 keypair (./bin/rsa3072_key_sealed.bin), the sealed ED25519 keypair (./bin/ed25519_key_sealed.bin) and the unencrypted public keys (./bin/rsa_pubkey.txt and ./bin/ecc_pubkey.txt). The sealed keypairs can only be decrypted by your specific SGX enclave.

  6. Start the substraTEE-worker in the background and log the output in a file:

    root@<DOCKERID>:/substraTEE/substraTEE-worker-M1# ./bin/substratee_worker worker > /substraTEE/worker.log 2>&1 &

    The worker now runs in the background and the output can be inspected by calling: tail -f /substraTEE/worker.log.

  7. Start the substraTEE-client to send an extrinsic to the substraTEE-node that is then forwarded and processed by the substraTEE-worker (incrementing a counter):

    root@<DOCKERID>:/substraTEE/substraTEE-worker-M1# ./bin/substratee_client | tee /substraTEE/client.log

    The output of the client is also logged to the file /substraTEE/client.log and can be inspected by less /substraTEE/client.log.

    You will see on the last lines of the output the two hashes of the transaction (expected and actual). These should match indicating that all commands were processed successfully.

    Expected Hash: [...]
    Actual Hash:   [...]
  8. Query the counter from the substraTEE-worker:

    root@<DOCKERID>:/substraTEE/substraTEE-worker-M1# ./bin/substratee_client getcounter | tee /substraTEE/counter.log

Whenever you perform the steps 7. and 8., you will see the counter incrementing.


If you exit the container (exit), you will loose the sealed counter state and the generated keys.

To backup the files:

root@<DOCKERID>:/substraTEE# cp /substraTEE/substraTEE-worker-M1/bin/*.txt /substraTEE/backup/
root@<DOCKERID>:/substraTEE# cp /substraTEE/substraTEE-worker-M1/bin/*.bin /substraTEE/backup/

To restore the files:

root@<DOCKERID>:/substraTEE# cp /substraTEE/backup/*.txt /substraTEE/substraTEE-worker-M1/bin/
root@<DOCKERID>:/substraTEE# cp /substraTEE/backup/*.bin /substraTEE/substraTEE-worker-M1/bin/

Enabling SGX HW support

The code is compiled for Simulation Mode meaning that you don't need an actual SGX platform to run the example. This is specified in the DockerfileM1 on line 99 (SGX_MODE=SW make). If you are on a platform that supports the SGX, you can enable HW support by:

  • Installing the Intel SGX Driver 2.5 and make sure that /dev/isgx appears
  • Start the docker with SGX device support:
    $ docker run -v $(pwd):/substraTEE/backup -ti --device /dev/isgx substratee
  • Start the aesm service inside the docker:
    root@<DOCKERID>:/# LD_LIBRARY_PATH=/opt/intel/libsgx-enclave-common/aesm /opt/intel/libsgx-enclave-common/aesm/aesm_service &
  • Compile the substraTEE-worker with HW support:
    root@<DOCKERID>:/substraTEE/substraTEE-worker-M1# make
  • Re-run from demo from step 5.

If you run the Hardware Mode on a platform that does not support SGX, you get the following error from the substraTEE-worker

*** Start the enclave
[2019-05-15T05:15:03Z ERROR substratee_worker::enclave_wrappers] [-] Init Enclave Failed SGX_ERROR_NO_DEVICE!

Enabling Debug output

To enable debug output, call the substraTEE-worker or the substraTEE-client with the following command, respectivly: RUST_LOG=debug ./bin/substratee_client.


The development of substraTEE is financed by web3 foundation's grant programme.

We also thank the teams at

You can’t perform that action at this time.