Zama's fhEVM Coprocessor is now available

Zama's fhEVM

A simple and powerful solution for building decentralized apps with full privacy and confidentiality on Ethererum leveraging Fully Homomorphic Encryption (FHE).
Ready to use FHE for your business? Talk to our team.

400+

Stars on Github

Trusted by
tier-1 teams
Read the whitepaper
Read the whitepaper
Read the whitepaper
Read the whitepaper
Read the whitepaper
Read the whitepaper
Read the whitepaper
Read the whitepaper
Read the whitepaper
Read the whitepaper
SOLVING the BLOCKCHAIN CONFIDENTIALITY dilemma

Why, and How?

Privacy has been a major hurdle for blockchain adoption, with everything onchain public by default. Zama's fhEVM simplifies implementing privacy by enabling developers to write confidential smart contracts in Solidity for Ethereum, opening up a range of new use cases, and without a deep knowledge of cryptography.

Fully Homomorphic Encryption

Or FHE for short.

FHE allows computations to be performed directly on encrypted data.

No cryptography knowledge required

Ease of use.

Developers can write simple confidential solidity smart contracts.

Deploy your dApps easily,
on any EVM chain

Using Zama's fhEVM Coprocessor.

Introducing Zama's fhEVM Coprocessor

Run FHE smart contracts on any EVM chain, including those that don’t support FHE natively.

Jambo Content Placeholder

Confidentiality on any EVM chain.The fhEVM Coprocessor enables developers to build fully confidential smart contracts on Ethereum, Base, Polygon, and other EVM chains without requiring native FHE support. Data stays encrypted, ensuring privacy without sacrificing composability.

Unparalleled Scalability: Process up to 20 transactions per second with the ability to scale to hundreds or thousands of TPS using additional hardware. Our groundbreaking compression and ZK-proof technologies drastically reduce storage and processing overhead.

Developer-Friendly with Solidity. No need for new languages or complex circuits—build confidential dApps seamlessly using Solidity. Transform your existing contracts with minimal changes to unlock powerful privacy features.

How does it works?

1. Use the fhEVM JavaScript SDK to encrypt transfer amounts and submit transactions as usual.

2. Update your ERC20 contract by replacing uint types with euint for FHE functionality, allowing users to decrypt their balances.

3. Decrypt and display user balances using the JavaScript SDK.

That's it. It really is that simple.

Read release blog post

Build Confidential Decentralized Apps Just as You Would Build Regular Ones

Solidity Integration
FhEVM contracts are simple solidity contracts that are built using traditional Solidity toolchains.

Simple DevX
Developers can use the euint data types to mark which part of their contracts should be private.

Programmable Privacy
‍All the logic for access control of encrypted states is defined by developers in their smart contracts.

function transfer(address to, einput encryptedAmount, bytes calldata inputProof) public {
		euint64 amount = TFHE.asEuint64(encryptedAmount, inputProof);
   // makes sure the owner has enough tokens
   ebool canTransfer = TFHE.le(amount, balances[msg.sender]);
   euint64 transferValue = TFHE.select(canTransfer, amount, TFHE.asEuint64(0));
   // add to the balance of `to`...
   euint64 newBalanceTo = TFHE.add(balances[to], transferValue);
   balances[to] = newBalanceTo;
   TFHE.allow(newBalanceTo, address(this));
   TFHE.allow(newBalanceTo, to);
   //  and substract from the balance of `from`.
   euint64 newBalanceFrom = TFHE.sub(balances[from], transferValue);
   balances[from] = newBalanceFrom;
   TFHE.allow(newBalanceFrom, address(this));
   TFHE.allow(newBalanceFrom, from);
   }
SOLUTION AND BENEFITS

A Myriad of New Use Cases for Consumers, Businesses, and Regulated Industries

Tokenization

Swap tokens and real-world assets (RWAs) onchain without revealing amounts to unauthorized parties.

Stablecoins

Add compliant confidentiality to stablecoins and bridge them securely across blockchain networks.

Confidential Voting

Prevent bribery and blackmailing by ensuring votes remain private and protected throughout the process.

Blind Auctions

Enable users to bid on items without revealing bid amounts or the winner, ensuring fairness in competitive processes.

Encrypted DIDs

Store identities onchain and generate attestations without using Zero-Knowledge proofs (ZK), providing secure and private identification.

Private Transfers

Keep balances and transaction amounts private without needing to rely on mixers or third-party solutions.

Build Your First Confidential dApp With These Step-By-Step Demos

contract EncryptedERC20{
    // ...
    function transfer(address to, einput encryptedAmount, bytes calldata inputProof) public {
        ebool canTransfer = TFHE.le(amount, _balances[msg.sender]); // Ensure owner has enough tokens
        euint64 transferValue = TFHE.select(isTransferable, amount, TFHE.asEuint64(0));
        euint64 newBalanceTo = TFHE.add(_balances[to], transferValue); // Add to the balance of `to`
        _balances[to] = newBalanceTo;
        TFHE.allowThis(newBalanceTo);
        TFHE.allow(newBalanceTo, to);
        euint64 newBalanceFrom = TFHE.sub(_balances[from], transferValue); // Subtract to the balance of `for`
        _balances[from] = newBalanceFrom;
        TFHE.allowThis(newBalanceFrom);
        TFHE.allow(newBalanceFrom, from);
    }
}
contract VotingDapp is GatewayCaller, Ownable {
    uint256 public dateEndVote;
    uint256 public totalVotes;
    euint64 internal totalVotesForProposalEncrypted;
    uint64 public totalVotesForProposalResult;
    bool public finalResultIsDecrypted;

    mapping(address user => bool canVote) public isWhiteListed;
    mapping(address user => bool hasVoted) public hasAlreadyVoted;
    /// ...

    constructor(uint256 voteDuration) Ownable(msg.sender) {
        dateEndVote = block.timestamp + voteDuration;
        totalVotesForProposalEncrypted = TFHE.asEuint64(0);
        TFHE.allowThis(totalVotesForProposalEncrypted);
    }

    function whiteListUser(address user) external onlyOwner {
        isWhiteListed[user] = true;
    }

    function castVote(einput encryptedSupport, bytes calldata inputProof) external {
        if (block.timestamp >= dateEndVote) revert TooLateToCastVote();
        if (!isWhiteListed[msg.sender] || hasAlreadyVoted[msg.sender]) revert UserUnauthorized();
        ebool voteFor = TFHE.asEbool(encryptedSupport, inputProof);
        totalVotesForProposalEncrypted = TFHE.add(totalVotesForProposalEncrypted, TFHE.asEuint64(voteFor));
        TFHE.allowThis(totalVotesForProposalEncrypted);
        totalVotes++;
        hasAlreadyVoted[msg.sender] = true;
    }

    function requestRevealVoteResult() external { // anyone could request to decrypt the final result after end of the voting period
        if (block.timestamp < dateEndVote) revert TooEarlyToRevealResult();

        // Request decryption of vote results through the Gateway
        uint256[] memory cts = new uint256[](1);
        cts[0] = Gateway.toUint256(totalVotesForProposalEncrypted);
        Gateway.requestDecryption(cts, this.revealVoteResult.selector, 0, block.timestamp + 100, false);
    }

    function revealVoteResult(uint256 /*requestId*/, uint64 result) external onlyGateway {
        totalVotesForProposalResult = result;
        finalResultIsDecrypted = true;
    }

    function isProposalVoted() public view returns (bool) {
        if (!finalResultIsDecrypted) revert ResultNotRevealedYet();
        if (2 * totalVotesForProposalResult >= totalVotes) return true;
        return false;
    }
}
contract DID is Ownable {
    struct Identity {
        euint128 id; // Encrypted unique ID
        ebytes64 name; // Encrypted name
        euint64 birthdate; // Encrypted birthdate for age verification
    }
    mapping(address user => Identity) private citizenIdentities;
    // ...

    /// @dev Owner is able to add new identity for a specific user addres
    function registerIdentity(
        address user, einput name_, einput birthdate_, bytes calldata inputProof
    ) public onlyOwner {
        euint64 newId = TFHE.randEuint128(); // Generate a new encrypted random unique ID
        citizenIdentities[user] = Identity({
            id: newId,
            name: TFHE.asEbytes64(name_, inputProof),
            birthdate: TFHE.asEuint64(birthdate_, inputProof)
        });
        /// @dev Allow the user to access their own data
        TFHE.allow(citizenIdentities[user].id, addressToBeAllowed);
        TFHE.allow(citizenIdentities[user].name, addressToBeAllowed);
        TFHE.allow(citizenIdentities[user].birthdate, addressToBeAllowed);

        /// @dev Allow the contract to access the data
        TFHE.allowThis(citizenIdentities[user].id);
        TFHE.allowThis(citizenIdentities[user].name);
        TFHE.allowThis(citizenIdentities[user].birthdate);
    }

    /// @dev Grants claim contract access to encrypted birth date
    function generateAgeClaim(address claimAddress, string memory claimFn) public {
        TFHE.allowTransient(citizenIdentities[msg.sender].birthdate, claimAddress);
        (bool success, bytes memory data) = claimAddress.call(abi.encodeWithSignature(claimFn, msg.sender));
        if (!success) revert ClaimGenerationFailed(data);
    }

    function getBirthdate(address user) public view returns (euint64) {
        return citizenIdentities[user].birthdate;
    }
}

contract EmployerClaim {
  mapping(address user => ebool isAdult) private adultClaims;
  // ...

  /// @dev Generates an encrypted claim verifying if a user is above 18 years old
  function generateAdultClaim(address user) public {
      if (msg.sender != address(didContract)) revert NotAuthorized();
      euint64 birthdate = didContract.getBirthdate(user); // Retrieve user's encrypted birthdate from the DID contract
      ebool isAdult = TFHE.le(birthdate, _AGE_THRESHOLD); // Check if user is adult
      adultClaims[user] = isAdult; // Store claim result
      TFHE.allowThis(isAdult);
      TFHE.allow(isAdult, user);
  }
}
Developer experience

Build Faster with Powerful Features Out of the Box

Fully Homomorphic Encryption
End-to-End Encryption
Zero-Knowledge Proofs
Multi-Party Computation
Compatibility to Ethereum
Programmable Privacy
Onchain Composability
Compatible with Existing Wallet
Solidity Integration
Out-of-box Javascript Library
High-Precision Encrypted Integers
Full-Range of Operators
Onchain Randomness
Unbounded Compute Depth
Data Availability Layer
Access Control List on Ethereum

Operational Versatility by Design

Consensus:
Proof of Stake (permissionless)
Proof of Authority (permissioned)

Deployment:
L1, L2 or L3 public or enterprise chain
App chain
ZK-fraud-proof rollup (coming 2024)

Decryption:
PoS or PoA threshold decryption
KMS or HSM based centralized decryption

ALREADY POWERED BY ZAMA

Join The Zama Developer Newsletter

Receive only what matters to you, like product releases, tutorials, bounties, and other great opportunities. 
No spam, never.