Skip to main content

Analytics dApp built on Zama fhEVM

· 7 min read
Jimmy Chu
Site Author

Project Artifacts

Background

After my last project on Semaphore and modular smart accounts, I wanted to continue advancing my knowledge of programmable cryptography. I have developed a solid understanding of zero-knowledge proof and now wish to learn more about multi-party computation (MPC), fully homomorphic encryption (FHE), and indistinguishability obfuscation (iO). I have been studying materials on MPC, such as oblivious transfer and garbled circuits, as well as FHE topics like learning with errors and lattice-based problems.

While digesting the theoretical aspects of these cryptographic primitives, I came across two interesting discoveries. The first is Noirhack, a hackathon focuses on using Noir language to write circuits and can generate both frontend (prover) and backend (verifier) code for zero-knowledge proof. The second is the Zama team, who are making significant advancements in FHE. FHE was once considered a purely theoretical concept due to its computational overhead and high time costs, making it impractical for real-world use. However, Zama has pushed the technology to the point where it is now practically usable. While it is still relatively slow, processing FHE-encrypted values now takes seconds rather than minutes or hours. Not only is Zama advancing the field of FHE, but they are also building a tool stack to make this technology applicable in two main areas: blockchain, with their fhEVM stack, and machine learning/AI, with Concrete ML.

The Zama team is also running a bounty program at this time. While I am familiar with zero-knowledge proofs writing using circom and have built a guessing game before, I wanted to experience firsthand what it’s like to build on FHE. Therefore, I decided to join the Zama Bounty program - building a confidential benchmarking and polling system onchain - which led to the creation of this project.

Project Use Cases

A voting and analytics platform is, in fact, a perfect use case for FHE. With zero-knowledge proofs, you can protect user privacy, but you cannot perform further computation on the proof beyond verifying its validity. With FHE, you achieve the same privacy while also enabling computation on the encrypted data. Souce data never leaves the user’s side, as it is encrypted on the client, transmitted over the internet, and stored on-chain.

This means we can store encrypted user ballot data on-chain, keeping individual choices private and secure, yet still tally all user ballots to compute final results, such as how many users selected a particular option or what the sum or mean of all user responses is.

This is exactly what I set out to build in this project.

Project Features

Project Overview

This confidential polling dApp offers the following features:

  1. A question creator can define a question set consisting of a main question and up to four meta questions. Each question can be either an option where the respondent selects one choice, or a value with specified minimum and maximum bounds.

    Example 1:

    • Main: Which L2 chain do you use most? (options: OP Mainnet, Base, Arbitrum, Zk Sync).
    • Meta 1: Your Gender (option: male, female)
    • meta 2: Your Age (value: 18 - 150)

    Example 2:

    • Main: What is your annual salary (USD)? (value: 0 - 100,000,000)
    • Meta 1: Your Gender (option: male, female)

    In practice, the meta question is capped to four in the application.

    Question Set
  2. Respondent answer sets are encrypted client-side before being sent on-chain. The encrypted answer set is validated by the smart contract to ensure values fall within the specified range, leveraging FHE provided by the fhEVM library. After validation, the validity flag (a boolean) is decrypted. If the answer set is valid, it is stored on-chain.

    Answer
  3. When a question set reaches its query threshold, the question creator can raise a Query Request with zero or multiple predicates. If the main question is an Option type, all matching answers are tallied and displayed. If the main question is a Value type, the system computes the minimum, sum, and maximum. A predicate can apply to any meta question, using operators such as equal, not equal, greater than or equal, or less than or equal.

    Query Request
  4. After a Query Request is created, the question creator must execute the query request to process the answers. This involves accumulating FHE-encrypted answer values, which can be gas-intensive. A steps parameter specifies how many answers to process at a time, writing intermediate results to storage. In practice, processing 5 - 8 answers per step balances execution count with the 3,000,000 FHE gas limit per block.

    Once a Query Request is fully processed, the result is re-encrypted and decrypted client-side.

Demo

You are invited to watch the demo video and try out the project. The smart contracts are deployed on the Sepolia testnet.

If you are a developer, feel free to explore the source code in the Github respository. The project is currently in the prototype stage and requires further enhancements and gas optimizations to be production-ready, but its core functionality is already in place.

Development Experience (DX)

The following summarizes my development experience using fhEVM and its technology stack.

Highlights

  • The fhEVM smart contract libraries are well-encapsulated and easy to use.
  • fhEVM provides dedicated encrypted data types (e.g., ebool, euint32), making it clear when you are working with encrypted data and need to use the THE.* computation libraries.
  • The use of asynchronous callbacks for decrypting values in smart contracts helps save time and improves efficiency.
  • The fhevmjs library is available for client-side operations.
  • The design for reencryption and decryption on the client side to retrieve encrypted values is ingenious.
  • The fhEVM Gateway and smart contract components deployed on Sepolia testnet are stable enough to provide a smooth user experience.

Area for Improvement

  • The fhEVM hardhat-template includes additional code to run a local Hardhat node with fhEVM contracts pre-loaded. It would be beneficial if the team could further encapsulate this code and release it as a Hardhat plugin.
  • During local development, the gateway contracts or the mock server (possibly due to issues with the Hardhat node as well) can be unstable. The mock server often stops receiving events from the gateway contract after running 5–10 minutes, causing on-chain decryption to halt. In such cases, both the Hardhat node and mock server need to be restarted.
  • Deploying the gateway contracts on multiple L2 testnets could help reduce the cost of developer testnet deployments. Testing on the Sepolia testnet is still relatively expensive.
  • Currently, each re-encryption and decryption operation requires a signature from the user’s wallet. When retrieving multiple values from smart contracts, users are prompted to sign multiple times in succession, which impacts the user experience. It would be a significant improvement if signatures could be batched, allowing users to authorize multiple operations with a single signature.

Acknowledgement

Thanks to the following folks on discussion and feedback on this project and their helps along the way:

  • Zama Team: immortaltofu and 0xalexbel_zama on their support in Discord on using fhEVM library APIs.