Writing an E3 Contract
The E3 contract defines your program on-chain. It verifies parameters during the creation of new E3 instances, validates inputs for your Secure Process, and publishes the computation output.
Smart Contract Components
Each E3 Program consists of two contract components:
- E3 Program contract
- Input Validator contract
E3 Program
The E3 program forms the core of each E3, implementing two functions: one to validate input parameters when a new E3 instance is created and another to verify the output of the computation.
validate
function validate(
uint256 e3Id,
uint256 seed,
bytes calldata e3ProgramParams,
bytes calldata computeProviderParams
)
external
returns (bytes32 encryptionSchemeId);When a new instance of your E3 Program is requested, the validate function is called to validate
and initialize the new E3. Some useful validations include:
- Random Seed Initialization: Use the
seedparameter to instantiate the E3 with a specific random seed - Custom Parameters: Utilize
e3ProgramParamsto pass in any additional arbitrary parameters, most commonly the address of your Input Validator contract. - Compute Provider Setup: Use
computeProviderParamsto validate the configuration of the Compute Provider chosen for your E3 Program.
For an example, see this mockup (opens in a new tab) or check out the demo implementation for the CRISP protocol (opens in a new tab).
verify
function verify(
uint256 e3Id,
bytes32 ciphertextOutput,
bytes memory proof
) external returns (bool success);The verify function intakes the output of the E3 computation and the accompanying proof generated by your chosen Compute Provider to assess the validity of the proof and ciphertext. You can see an example of this using RISC Zero's Verifier in our CRISP E3 contract (opens in a new tab).
Input Validation
In order to ensure correct computation, we should be checking that the encrypted data submitted to your E3 is properly structured. This will most likely be used in tandem with a proof generated by your Data Provider. The function should be implemented in the E3 Program contract.
Responsibilities:
- Data Decoding: Decode encrypted input data to its intended format.
- ZKP Verification: Verify any associated ZKPs to ensure input correctness.
- Input Acceptance: Return validated input for inclusion in the computation.
Example:
pragma solidity >=0.8.27;
function validateInput(address sender, bytes memory data) external returns (bytes memory input) {
// Decode the input data
// Verify associated ZKPs
// Return the validated input
return data; // Placeholder: replace with actual validated input
}