Skip to content

Commit

Permalink
Merge pull request #45 from zama-ai/fhevm06
Browse files Browse the repository at this point in the history
feat: upgrade fhevm06
  • Loading branch information
jatZama authored Dec 6, 2024
2 parents ca874bc + f65e337 commit 951ab7b
Show file tree
Hide file tree
Showing 52 changed files with 3,838 additions and 3,684 deletions.
15 changes: 2 additions & 13 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,13 +1,2 @@
export INFURA_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
export MNEMONIC="adapt mosquito move limb mobile illegal tree voyage juice mosquito burger raise father hope layer"
export PRIVATE_KEY_GATEWAY_DEPLOYER="717fd99986df414889fd8b51069d4f90a50af72e542c58ee065f5883779099c6"
export PRIVATE_KEY_GATEWAY_OWNER="717fd99986df414889fd8b51069d4f90a50af72e542c58ee065f5883779099c6"
export PRIVATE_KEY_GATEWAY_RELAYER="7ec931411ad75a7c201469a385d6f18a325d4923f9f213bd882bbea87e160b67"

# Block explorer API keys
export ARBISCAN_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
export BSCSCAN_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
export ETHERSCAN_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
export OPTIMISM_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
export POLYGONSCAN_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
export SNOWTRACE_API_KEY="zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
export MNEMONIC="exchange vintage ocean narrow danger return culture ignore trim solve clock hidden buddy wise emotion"
export SEPOLIA_RPC_URL="https://sepolia.infura.io/v3/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
3 changes: 0 additions & 3 deletions .vscode/extensions.json

This file was deleted.

6 changes: 0 additions & 6 deletions .vscode/settings.json

This file was deleted.

6 changes: 0 additions & 6 deletions CustomProvider.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { ethers } from "ethers";
import { ProviderWrapper } from "hardhat/plugins";
import type { EIP1193Provider, RequestArguments } from "hardhat/types";

Expand All @@ -19,11 +18,6 @@ class CustomProvider extends ProviderWrapper implements Test {
}

async request(args: RequestArguments): ReturnType<EIP1193Provider["request"]> {
if (args.method === "eth_estimateGas") {
const estimatedGasLimit = BigInt((await this._wrappedProvider.request(args)) as bigint);
const increasedGasLimit = ethers.toBeHex((estimatedGasLimit * 120n) / 100n); // override estimated gasLimit by 120%, to avoid some edge case with ethermint gas estimation
return increasedGasLimit;
}
if (args.method === "evm_revert") {
const result = await this._wrappedProvider.request(args);
const blockNumberHex = (await this._wrappedProvider.request({ method: "eth_blockNumber" })) as string;
Expand Down
50 changes: 0 additions & 50 deletions Makefile

This file was deleted.

105 changes: 31 additions & 74 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,53 +66,23 @@ You can edit the CI script in [.github/workflows/ci.yml](./.github/workflows/ci.

### Pre Requisites

Install [docker](https://docs.docker.com/engine/install/)

Install [pnpm](https://pnpm.io/installation)

Before being able to run any command, you need to create a `.env` file and set a BIP-39 compatible mnemonic as an
environment variable. You can follow the example in `.env.example` and start with the following command:
Before being able to run any command, you need to create a `.env` file and set a BIP-39 compatible mnemonic as the `MNEMONIC`
environment variable. You can follow the example in `.env.example` or start with the following command:

```sh
cp .env.example .env
```

If you don't already have a mnemonic, you can use this [website](https://iancoleman.io/bip39/) to generate one.
If you don't already have a mnemonic, you can use this [website](https://iancoleman.io/bip39/) to generate one. An alternative, if you have [foundry](https://book.getfoundry.sh/getting-started/installation) installed is to use the `cast wallet new-mnemonic` command.

Then, proceed with installing dependencies - please **_make sure to use Node v20_** or more recent or this will fail:
Then, install all needed dependencies - please **_make sure to use Node v20_** or more recent:

```sh
pnpm install
```

### Start fhEVM

During installation (see previous section) we recommend you for easier setup to not change the default `.env` : simply
copy the original `.env.example` file to a new `.env` file in the root of the repo.

Then, start a local fhEVM docker compose that inlcudes everything needed to deploy FHE encrypted smart contracts using:

```sh
# In one terminal, keep it opened
# The node logs are printed
pnpm fhevm:start
```

Previous command will take 2 to 3 minutes to do the whole initial setup - wait until the blockchain logs appear to make
sure setup is complete (we are working on making initial deployment faster).

You can then run the tests simply in a new terminal via :

```
pnpm test
```

Once your done with your tests, to stop the node:

```sh
pnpm fhevm:stop
```

### Compile

Compile the smart contracts with Hardhat:
Expand All @@ -129,38 +99,9 @@ Compile the smart contracts and generate TypeChain bindings:
pnpm typechain
```

### List accounts

From the mnemonic in .env file, list all the derived Ethereum adresses:

```sh
pnpm task:accounts
```

### Get some native coins

In order to interact with the blockchain, one need some coins. This command will give coins to the first 5 addresses
derived from the mnemonic in .env file.

```sh
pnpm fhevm:faucet
```

<br />
<details>
<summary>To get the first derived address from mnemonic</summary>
<br />

```sh
pnpm task:getEthereumAddress
```

</details>
<br />

### Test

Run the tests with Hardhat:
Run the tests with Hardhat - this will run the tests on a local hardhat node in mocked mode (i.e the FHE operations and decryptions will be simulated by default):

```sh
pnpm test
Expand All @@ -182,13 +123,6 @@ Lint the TypeScript code:
pnpm lint:ts
```

### Report Gas

See the gas usage per unit test and average gas per method call:

```sh
REPORT_GAS=true pnpm test
```

### Clean

Expand All @@ -205,22 +139,45 @@ encrypted types are not really encrypted, and the tests are run on the original
network instance. To run the tests in mocked mode, you can use directly the following command:

```bash
pnpm test:mock
pnpm test
```

You can still use all the usual specific [hardhat network methods](https://hardhat.org/hardhat-network/docs/reference#hardhat-network-methods), such as `evm_snapshot`, `evm_mine`, `evm_increaseTime`, etc, which are very helpful in a testing context. Another useful hardhat feature, is the [console.log](https://hardhat.org/hardhat-network/docs/reference#console.log) function which can be used in fhevm smart contracts in mocked mode as well.

To analyze the coverage of the tests (in mocked mode necessarily, as this cannot be done on the real fhEVM node), you
can use this command :

```bash
pnpm coverage:mock
pnpm coverage
```

Then open the file `coverage/index.html`. You can see there which line or branch for each contract which has been
covered or missed by your test suite. This allows increased security by pointing out missing branches not covered yet by
the current tests.

Finally, a new fhevm-specific feature is available in mocked mode: the `debug.decrypt[XX]` functions, which can decrypt directly any encrypted value. Please refer to the [utils.ts](https://github.com/zama-ai/fhevm/blob/main/test/utils.ts#L87-L317) file for the corresponding documentation.

> [!Note]
> Due to intrinsic limitations of the original EVM, the mocked version differs in rare edge cases from the real fhEVM, the main difference is the gas consumption for the FHE operations (native gas is around 20% underestimated in mocked mode). This means that before deploying to production, developers should still run the tests with the original fhEVM node, as a final check - i.e in non-mocked mode (see next section).
### Non-mocked mode - Sepolia

To run your test on a real fhevm node, you can use the coprocessor deployed on the Sepolia test network. To do this, ensure you are using a valid value `SEPOLIA_RPC_URL` in your `.env` file. You can get free Sepolia RPC URLs by creating an account on services such as [Infura](https://www.infura.io/) or [Alchemy](https://www.alchemy.com/). Then you should use the following command:

```bash
npx hardhat test [PATH_TO_YOUR_TEST] --network sepolia
```

The `--network sepolia` flag will make your test run on a real fhevm coprocessor. Obviously, for the same tests to pass on Sepolia, contrarily to mocked mode, you are not allowed to use any hardhat node specific method, and neither use any of the `debug.decrypt[XX]` functions.

> [!Note]
> Due to intrinsic limitations of the original EVM, the mocked version differ in few corner cases from the real fhEVM, the main difference is the difference in gas prices for the FHE operations. 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`.
> For this test to succeed, first ensure you set your own private `MNEMONIC` variable in the `.env` file and then ensure you have funded your test accounts on Sepolia. For example you can use the following command to get the corresponding private keys associated with the first `5` accounts derived from the mnemonic:
```
npx hardhat get-accounts --num-accounts 5
```
This will let you add them to the Metamask app, to easily fund them from your personal wallet.

If you don't own already Sepolia test tokens, you can for example use a free faucet such as [https://sepolia-faucet.pk910.de/](https://sepolia-faucet.pk910.de/).

### Syntax Highlighting

Expand Down
Loading

0 comments on commit 951ab7b

Please sign in to comment.