In one of my brief but intense weekly study sessions (so I don’t get technically RUSTy, you know) I revisited a technology whose whitepaper I read a few years ago, Enigma. I remember that apart from the fact that Enigma is a privacy-focused project (and you know I like that), the thing that impressed me the most about the project was their use of homomorphic encryption to perform computation on encrypted data. Anyway, I came across this project again, and I thought its revision was worth a publication.
Enigma? Why Enigma?
So, first thing’s first. While Enigma isn’t a blockchain, it is a blockchain project. They are building a second layer protocol to be plugged into blockchain networks to make them private and scalable. Enigma is based on two principles:
The transformation of “ordinary” smart contracts in a blockchain network into “secret contracts” where all the data in the contract is conveniently encrypted (privacy).
The delegation of computation to nodes offchain to offload heavy computation from the blockchain network (scalability).
Enigma uses a secure multi-party computation model where data queries are computed in a distributed way. It is designed to be connected to an existing blockchain and off-load private and intensive computations to an off-chain network. All transactions are facilitated by the blockchain, which enforces access-control based on digital signatures and programmable permissions. Code is executed both on the blockchain (public parts) and on Enigma (private or computationally intensive parts). To achieve this it relies in the following schemes:
Storage: It uses a distributed hash table (DHT) accessible to store data in nodes by dividing it in parts. This data is accessible through the blockchain, which stores references to the data (but not the actual data). Private data should be encrypted on the client-side before storage and access-control protocols are programmed into the blockchain.
Privacy-enforcing computation: Enigma’s network can execute code without leaking the raw data to any of the nodes, while ensuring correct execution through the use of “secret contracts”. If you like the hard stuff, and in order to deeply understand the magic behind Enigma’s MPC model, I encourage you to read their original white paper.
Heavy processing: Even when privacy is not a concern, the blockchain cannot scale to clearing many complex transactions. The same off-chain computational network is used to run heavy publicly verifiable computations that are broadcast through the blockchain.
Enigma’s Network Arcihtecture
Enigma’s current testnet only supports Ethereum. In their current version, secret contracts are identical to Ethereum contracts with the ability to perform computation on sensitive data. Secret contracts are written in Rust and compiled into WASM (in future publications I will share my opinion on how I feel WASM will become the standard target compilation language for the implementation and execution of smart contracts in different blockchain platforms). The Enigma network is divided in the following parts:
Secret nodes achieve privacy-preserving computations by using Trusted Execution Environment (TEE) technology. TEE technology is a secure hardware that decrypts sensitive data inside an enclave that is not accessible by the owner of the hardware. Unlike software cryptography methods, TEEs enable high performance and general purpose computation, which are critical concepts to achieve usage and adoption of decentralized technologies. This is a slight limitation, as it means that in order to install a secret node we require a device with a compatible TEE installed (such as Intel SGX, for instance).
A P2P network where secret contracts are stored. Enigma’s network is based on a libp2p network that’s built from scratch to accommodate the needs of the protocol. Over this network secret states are implemented, which are contract states not accessible by network participants.
Let me show you how the Enigma network works sharing a user story from one of Enigma’s blog post:
Developers build blockchain applications using secret contracts in Rust. These contracts are interoperable with Ethereum, which means Ethereum developers can continue to build on Ethereum and use the Enigma network for secret computations. One good example is a Rock Paper Scissors Game, where Ethereum is used to store user balances and bets, while the Enigma network is used to run the game logic based on encrypted user inputs. Once a contract is completed, it is stored in the Enigma network and its bytecode is uploaded to Ethereum.
Users interact with secret contracts using the Enigma Client. Enigma Client encrypts user inputs locally and sends them to the Enigma network. In this release of Discovery, we are also storing a TaskRecord on Ethereum for every input into the Enigma network. In our next iteration of the network, this TaskRecord will be removed.
Workers (similar to miners / validators in other networks) run nodes to power the Enigma network. Once a user inputs a task into the Enigma network, a randomly-selected node picks up the inputs and propagates the encrypted inputs into a group of workers that will be working on that specific secret contract for that specific epoch, which is an interval of time. These workers are selected based on a stake-weighted lottery.
Selected workers can decrypt the inputs inside their enclaves, compute on the data without having access to it, and reach a simple consensus on the result. Once this consensus is reached, the state of the secret contract is updated and Ethereum smart contracts may be called (for example, in Rock Paper Scissors to move funds from the losing account to the winning account). In this release of Discovery, there will be one worker per secret contract per epoch. In the next iteration of our network, a consensus protocol will be implemented.
See? It’s not strictly but it is a blockchain project. Everything you learnt while programming DApps in Ethereum can be applied here.
Enigma’s Testnet and Secret Contracts (shh!)
One of the features I liked the most in my latest revision to Enigma’s technology (after my first contact with their whitepaper) was its secret contracts. I wanted to clearly understand how they worked. Fortunately, I found this great resource to get my hands dirty and start playing with secret contracts. The post guides you through the installation of an Enigma test network, the implementation of a secret contract (solving the Millionaire Problem), the compilation and deployment of the contract, and the run of a set of tests against the deployed contract. Instead of copy-pasting the aforementioned extensive post, I will share here the most interesting concepts about secret contracts I identified while following the guide (if you are a nerdy programmer like me, skip this section and go straight to the guide to develop your own contract).
In the end, a secret contract is just a Rust library which is compiled using the discovery CLI (Engima’s testnet CLI). The output is either a .json file for standard Ethereum smart contracts, or the corresponding .wasm files for a secret contract. The code for a secret contract is pretty straightforward:
// Built-In Attributes
#![no_std]
// Imports
extern crate eng_wasm;
extern crate eng_wasm_derive;
extern crate serde;
use eng_wasm::*;
use eng_wasm_derive::pub_interface;
use serde::{Serialize, Deserialize};
// Encrypted state keys
static MILLIONAIRES: &str = "millionaires";
// Structs
#[derive(Serialize, Deserialize)]
pub struct Millionaire {
address: H160,
net_worth: U256,
}
// Public struct Contract which will consist of private and public-facing secret contract functions
pub struct Contract;
// Private functions accessible only by the secret contract
impl Contract {
fn get_millionaires() -> Vec<Millionaire> {
read_state!(MILLIONAIRES).unwrap_or_default()
}
}
// Public trait defining public-facing secret contract functions
#[pub_interface]
pub trait ContractInterface{
fn add_millionaire(address: H160, net_worth: U256);
fn compute_richest() -> H160;
}
// Implementation of the public-facing secret contract functions defined in the ContractInterface
// trait implementation for the Contract struct above
impl ContractInterface for Contract {
#[no_mangle]
fn add_millionaire(address: H160, net_worth: U256) {
let mut millionaires = Self::get_millionaires();
millionaires.push(Millionaire {
address,
net_worth,
});
write_state!(MILLIONAIRES => millionaires);
}
#[no_mangle]
fn compute_richest() -> H160 {
match Self::get_millionaires().iter().max_by_key(|m| m.net_worth) {
Some(millionaire) => {
millionaire.address
},
None => H160::zero(),
}
}
}
In this secret contract we want to solve the Millionaire’s Problem (where Alice and Bob are two billionaires that want to know who is richer without having to disclose their actual net worth). Secret contracts have the following interesting parts:
All secret contracts start with built-in attributed
#![no_std]
to ensure code compatibility with different execution environments such as Intel’s SGX (the TEE environment).The
eng_wasm*
libraries expose all the relevant functions related to Enigma that we require to implement our secret contracts. Finally, theserde
library allows the serialization and desearialization of custom data types in and out the secret contract state.We can see how Enigma exposes new data types compatible with Ethereum such as H160 and U256, which correspond to an address type and a 256 bits integer, respectively.
Apart from this, nothing fancy not inferable from context, such as the write_state! and get_state! macros to interact with the contract state, the use of the struct Contract to declare the contract construction, or the annotations used to define the public interface to interact with the contract (the equivalent to the ABI interface).
In short, if you know a bit of Solidity, how to program Ethereum smart contracts, and you are able to (at least) read a Rust program, you are more than prepared to start developing your first Enigma secret contracts.
In search of the killer app.
Technically, Enigma is a cool project with a (in my opinion) technically sound solution to fix the privacy and scalability issues of current blockchain platforms (I can already hear blockchain maximalists spitting at my face from the distance for this claim). However, as with blockchain technology itself, we still need to find the use case or killer app to justify its usage. There is no doubt that Multi-Party Computational models, distributed networks, and advanced cryptography are a set of building blocks with an enormous value, and that we will see widely integrated in future systems. Any future IoT or artifical intelligence system will leverage several of this scheme. Nonetheless, I feel we haven’t yet found the “Google” or “e-commerce” of distributed technologies, we are still in the browser and Netscape era of distributed networks. We’ll keep searching….
In the meantime, there is a huge HUGE amount of resources to start learning Enigma out there. The project has done an awesome work to boost their community and spread the word about their technology, so I invite you to get advantage of it (in the process you may even learn Rust by accident).