Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
fhEVM is a technology that enables confidential smart contracts on the EVM using Fully Homomorphic Encryption (FHE).
Learn the basics of fhEVM, set it up, and make it run with ease.
Start developing fhEVM smart contracts in Solidity by exploring its core features, discovering essential guides, and learning more with user-friendly tutorials.
Access to additional resources and join the Zama community.
Refer to the API and access additional resources for in-depth explanations while working with fhEVM.
Ask technical questions and discuss with the community. Our team of experts usually answers within 24 hours in working days.
Collaborate with us to advance the FHE spaces and drive innovation together.
We value your feedback! Take a 5-question developer survey to improve the fhEVM library and the documentation and help other developers use FHE.
There used to be a dilemma in blockchain: keep your application and user data on-chain, allowing everyone to see it, or keep it privately off-chain and lose contract composability. Thanks to a breakthrough in homomorphic encryption, Zama’s fhEVM makes it possible to run confidential smart contracts on encrypted data, guaranteeing both confidentiality and composability.
fhEVM contracts are simple solidity contracts that are built using traditional solidity toolchains. Developers can use the euint data types to mark which part of their contracts should be private. All the logic for access control of encrypted states is defined by developers in their smart contracts.
Tokenization: Swap tokens and RWAs on-chain without others seeing the amounts.
Blind auctions: Bid on items without revealing the amount or the winner.
On-chain games: Keep moves, selections, cards, or items hidden until ready to reveal.
Confidential voting: Prevents bribery and blackmailing by keeping votes private.
Encrypted DIDs: Store identities on-chain and generate attestations without ZK.
Private transfers: Keep balances and amounts private, without using mixers.
🎥 Workshop during ETHcc [by Morten Dahl — Zama]
🎥 How to Write Confidential Smart Contracts Using Zama's fhEVM [by Clément Danjou (Zama)]
📃 Programmable Privacy and Onchain Compliance using Homomorphic Encryption [by Rand Hindi and Clément Danjou — Zama]
📃 Confidential ERC-20 Tokens Using Homomorphic Encryption [by [Clément Danjou — Zama]
📃 On-chain Blind Auctions Using Homomorphic Encryption [by Clément Danjou — Zama]
🖥️ Darkpool [by Owen Murovec]
Here are the main steps from the official guide provided by Metamask:
Add these information to access to blockchain
We provide a docker image to spin up a fhEVM node for local development.
WARNING: >
OracleCaller.sol
must be imported at least once in one of your smart contracts if you wish to use the recommendedfhevm:start
command, or else the bash script will emit an error and decryptions would fail. This is needed because hardhat needs to compile the oracle predeploy contract before your initial deployment. This can be done simply by adding the following import at the top of any of the smart contracts used in your project:import "fhevm/oracle/OracleCaller.sol";
If you need to get coins for a specific wallet, you can use the faucet as follow:
Fields | Value |
---|---|
Fields | Value |
---|---|
You can get 10 Zama token on .
Type | URL |
---|
However, we advise developers to use directly pnpm fhevm:start
or npm run fhevm:start
commands available within the , instead of the previous command, as this will launch a bash script which will also deploy automatically the oracle contract and launch the oracle relayer service, which are needed for asynchronous decryption requests.
Network Name
Zama Network
New RPC URL
https://devnet.zama.ai
Chain ID
8009
Currency symbol
ZAMA
Block explorer URL (Optional)
https://main.explorer.zama.ai
Network Name
Zama Local
New RPC URL
http://localhost:8545/
Chain ID
9000
Currency symbol
ZAMA
Block explorer URL (Optional)
JSON-RPC | http://127.0.0.1:8545 |
Websocket | http://127.0.0.1:8546 |
Our library compiles seamlessly with the traditional Solidity compiler and is generally compatible with traditional Solidity tools. However, it's important to note that the execution is designed to function exclusively on a fhEVM. As a result, this library is not intended for deployment on a classic EVM, such as Goerli or Ganache.
To get started with fhEVM Solidity Library, you need to install it as a dependency in your JavaScript project. You can do this using npm (Node Package Manager) or Yarn. Open your terminal and navigate to your project's directory, then run one of the following commands:
This will download and install the fhEVM Solidity Library and its dependencies into your project.
1/ For quick prototyping of a specific feature, use the Zama version of the Remix IDE. This will let you quickly deploy a contract on the devnet via Metamask, and interact easily with it through the Remix UI. Otherwise, for a bigger project, you should use our custom fhevm-hardhat-template
repository. Hardhat is a popular development environment for Solidity developers and will let you test and deploy your contracts to the fhEVM using TypeScript.
2/ A good first step is to start with an unencrypted version of the contract you want to implement, as you would usually do on a regular EVM chain. It is easier to reason first on cleartext variables, before thinking on how to add confidentiality.
3/ When you're ready, you can start to add confidentiality by using the TFHE
solidity library. Typically, this would involve converting some uintX
types to euintX
, as well as following all the detailed advices that we gave in the pitfalls to avoid and best practises section of the documentation. For inspiration, you can take a look at the examples inside the fhevm
repository. If you're using the Hardhat template, read the advices that we gave in the Hardhat section.
The best way to start writing smart contracts with fhEVM is to use our Hardhat template.
It allows you to start a fhEVM docker image and run your smart contract on it. Read the README for more information.
When developing confidential contracts, we recommend to use first the mocked version of fhEVM for faster testing with pnpm test:mock
and coverage computation via pnpm coverage:mock
, this will lead to a better developer experience. However, keep in mind that the mocked fhEVM has some limitations and discrepancies compared to the real fhEVM node, as explained in the warning section at the end of this section.
It's essential to run tests of the final contract version using the real fhEVM. You can do this by running pnpm test
before deployment.
For faster testing iterations, instead of launching all the tests on the local fhEVM node via pnpm test
or npx hardhat test
which could last several minutes, you could use instead a mocked version of the TFHE.sol
library. The same tests should (almost always) pass, as is, without any modification: neither the javascript files neither the solidity files need to be changed between the mocked and the real version. The mocked mode does not actually use encryption for encrypted types and runs the tests on a local hardhat node which is implementing the original EVM (i.e non-fhEVM).
To run the mocked tests use either:
Or equivalently:
In mocked mode, all tests should pass in few seconds instead of few minutes, allowing a better developer experience.
Furthermore, getting the coverage of tests is only possible in mocked mode. Just use the following command:
Or equivalently:
Then open the file coverage/index.html
. This will allow increased security by pointing out missing branches not covered yet by the current test suite.
⚠️ Warning : Notice that, due to intrinsic limitations of the original EVM, the mocked version differ in few corner cases from the real fhEVM, the most important change is the TFHE.isInitialized
method which will always return true
in the mocked version. Another big difference in mocked mode, compared to the real fhEVM implementation, is that there is no ciphertext verification neither checking that a ciphertext has been honestly obtained in the mocked version (see section 4
of the whitepaper). This means that before deploying to production, developers still need to run the tests with the original fhEVM node, as a final check in non-mocked mode, with pnpm test
or npx hardhat test
.
You can use Remix to interact with a blockchain using fhEVM. If you want to send an encrypted input, you need to encrypt it with fhevmjs CLI tool for example. It becomes more complex if you want to reencrypt a value directly in Remix.
To avoid this problem, we developed a version of Remix IDE with these two missing features:
Encryption of input
Generation of public key and signature for reencryption and decryption.
You can use it on https://remix.zama.ai.
To import TFHE library, simply import it at the top of your contract.
import "fhevm/lib/TFHE.sol";
Be sure to be on the correct network before deploying your contract
````
The TFHE
library provides encrypted integer types and a type system that is checked both at compile time and at run time.
Encrypted integers with overflow checking are coming soon to the TFHE
library. They will allow reversal in case of an overflow, but will leak some information about the operands.
In terms of implementation in the fhEVM
, encrypted integers take the form of FHE ciphertexts. The TFHE
library abstracts away that and, instead, exposes ciphertext handles to smart contract developers. The e(u)int
types are wrappers over these handles.
The following encrypted data types are defined:
Higher-precision integers are supported in the TFHE-rs
library and can be added as needed to fhEVM
.
When users send serialized ciphertexts as bytes
to the blockchain, they first need to be converted to the respective encrypted integer type. Conversion verifies if the ciphertext is well-formed and includes proof verification. These steps prevent usage of arbitrary inputs. For example, following functions are provided for ebool
, euint8
, euint16
and euint32
:
TFHE.asEbool(bytes ciphertext)
verifies the provided ciphertext and returns an ebool
TFHE.asEuint4(bytes ciphertext)
verifies the provided ciphertext and returns an euint4
TFHE.asEuint8(bytes ciphertext)
verifies the provided ciphertext and returns an euint8
TFHE.asEuint16(bytes ciphertext)
verifies the provided ciphertext and returns an euint16
TFHE.asEuint32(bytes ciphertext)
verifies the provided ciphertext and returns an euint32
TFHE.asEuint64(bytes ciphertext)
verifies the provided ciphertext and returns an euint64
TFHE.asEaddress(bytes ciphertext)
verifies the provided ciphertext and returns an eaddress
... more functions for the respective encrypted integer types
If you require a state variable that utilizes these encrypted types, you cannot assign the value with immutable
or constant
keyword. If you're using these types, the compiler attempts to ascertain the value of TFHE.asEuintXX(yy)
during compilation, which is not feasible because asEuintXX()
invokes a precompiled contract. To address this challenge, you must not declare your encrypted state variables as immutable
or constant
. Still, you can use the following methods to set your variables:
The TFHE
library defines the following operations with FHE ciphertexts:
NOTE 1: Random encrypted integers that are generated fully on-chain. Currently, implemented as a mockup by using a PRNG in the plain. Not for use in production!
NOTE 2: The shift operators
TFHE.shr
andTFHE.shl
can take any encrypted typeeuintX
as a first operand and either auint8
or aeuint8
as a second operand, however the second operand will always be computed modulo the number of bits of the first operand. For example,TFHE.shr(euint64 x, 70)
will actually be equal toTFHE.shr(euint64 x, 6)
because70 % 64 = 6
. This is in contrast to the classical shift operators in Solidity where there is no intermediate modulo operation, so for instance anyuint64
shifted right via>>
would give a null result.
The fhEVM does not work with Foundry as Foundry employs its own EVM, preventing us from incorporating a mock for our precompiled contract. An is exploring the possibility of incorporating a plugin system for precompiles, which could potentially pave the way for the utilization of Foundry at a later stage.
However, you could still use Foundry with the mocked version of the fhEVM, but please be aware that this approach is NOT recommended, since the mocked version is not fully equivalent to the real fhEVM node's implementation (see warning in ). In order to do this, you will need to rename your TFHE.sol
imports from fhevm/lib/TFHE.sol
to fhevm/mocks/TFHE.sol
in your solidity source files.
Encrypted integers behave as much as possible as Solidity's integer types. Currently, however, behaviour such as "revert on overflow" is not supported as this would leak some information about the encrypted value. Therefore, arithmetic on e(u)int
types is , i.e. there is wrap-around on overflow.
type | supported |
---|
name | function name | symbol | type |
---|
Overloaded operators +
, -
, *
, &
, ... on encrypted integers are supported (). As of now, overloaded operators will call the versions without an overflow check.
More information about the supported operations can be found in the page or in the .
If you find yourself in search of a missing feature, we encourage you to for upcoming developments. Alternatively, don't hesitate to reach out to us on Discord or visit our community forum.