diff --git a/.gitignore b/.gitignore index f4324a3..52aa9eb 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ abi/ # files *.env *.log +.env.docker .DS_Store .pnp.* coverage.json diff --git a/Makefile b/Makefile index 8543f1e..26c1727 100644 --- a/Makefile +++ b/Makefile @@ -32,12 +32,12 @@ generate-fhe-keys: run-full: $(MAKE) generate-fhe-keys - @docker compose -f docker-compose/docker-compose-full.yml up --detach + @docker compose --env-file .env.docker -f docker-compose/docker-compose-full.yml up --detach @echo 'sleep a little to let the docker start up' sleep 5 stop-full: - @docker compose -f docker-compose/docker-compose-full.yml down + @docker compose --env-file .env.docker -f docker-compose/docker-compose-full.yml down clean: diff --git a/docker-compose/docker-compose-full.yml b/docker-compose/docker-compose-full.yml index 58382d1..45ba51b 100644 --- a/docker-compose/docker-compose-full.yml +++ b/docker-compose/docker-compose-full.yml @@ -65,12 +65,12 @@ services: - GATEWAY__ETHEREUM__WSS_URL=ws://fhevm-validator:8546 - GATEWAY__ETHEREUM__HTTP_URL=http://fhevm-validator:8545 - GATEWAY__ETHEREUM__FHE_LIB_ADDRESS=000000000000000000000000000000000000005d - - GATEWAY__ETHEREUM__ORACLE_PREDEPLOY_ADDRESS=c8c9303Cd7F337fab769686B593B87DC3403E0ce + - GATEWAY__ETHEREUM__ORACLE_PREDEPLOY_ADDRESS=${GATEWAY_CONTRACT_PREDEPLOY_ADDRESS} - GATEWAY__KMS__ADDRESS=http://kms-validator:9090 - GATEWAY__KMS__KEY_ID=408d8cbaa51dece7f782fe04ba0b1c1d017b1088 - GATEWAY__STORAGE__URL=http://gateway-store:8088 - ASC_CONN__BLOCKCHAIN__ADDRESSES=http://kms-validator:9090 - - GATEWAY__ETHEREUM__RELAYER_KEY=7ec931411ad75a7c201469a385d6f18a325d4923f9f213bd882bbea87e160b67 + - GATEWAY__ETHEREUM__RELAYER_KEY=${PRIVATE_KEY_GATEWAY_RELAYER} - RUST_BACKTRACE=1 depends_on: fhevm-validator: @@ -80,7 +80,7 @@ services: fhevm-validator: environment: - - TFHE_EXECUTOR_CONTRACT_ADDRESS=0x05fD9B5EFE0a996095f42Ed7e77c390810CF660c + - TFHE_EXECUTOR_CONTRACT_ADDRESS=${TFHE_EXECUTOR_CONTRACT_ADDRESS} image: ghcr.io/zama-ai/ethermint-dev-node:v0.5.0-2 ports: - "26656-26657:26656-26657" diff --git a/hardhat.config.ts b/hardhat.config.ts index 2c96ae5..2b82be9 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -85,6 +85,12 @@ task("test", async (taskArgs, hre, runSuper) => { // Run modified test task if (hre.network.name === "hardhat") { // in fhevm mode all this block is done when launching the node via `pnmp fhevm:start` + const privKeyDeployer = process.env.PRIVATE_KEY_GATEWAY_DEPLOYER; + await hre.run("task:computePredeployAddress", { privateKey: privKeyDeployer }); + await hre.run("task:computeACLAddress"); + await hre.run("task:computeTFHEExecutorAddress"); + await hre.run("task:computeKMSVerifierAddress"); + await hre.run("compile:specific", { contract: "contracts" }); const sourceDir = path.resolve(__dirname, "node_modules/fhevm/"); const destinationDir = path.resolve(__dirname, "fhevmTemp/"); @@ -103,11 +109,6 @@ task("test", async (taskArgs, hre, runSuper) => { await hre.network.provider.send("hardhat_setCode", [targetAddress, bytecode]); console.log(`Code of Mocked Pre-compile set at address: ${targetAddress}`); - const privKeyDeployer = process.env.PRIVATE_KEY_GATEWAY_DEPLOYER; - await hre.run("task:computePredeployAddress", { privateKey: privKeyDeployer }); - await hre.run("task:computeACLAddress"); - await hre.run("task:computeTFHEExecutorAddress"); - await hre.run("task:computeKMSVerifierAddress"); await hre.run("task:deployACL"); await hre.run("task:deployTFHEExecutor"); await hre.run("task:deployKMSVerifier"); diff --git a/launch-fhevm.sh b/launch-fhevm.sh index 63c0e2d..97a9e8f 100755 --- a/launch-fhevm.sh +++ b/launch-fhevm.sh @@ -1,9 +1,12 @@ #!/bin/bash # Assumes the following: -# 1. A local and **fresh** fhEVM node is already running. -# 2. All test addresses are funded (e.g. via the fund_test_addresses.sh script). -npx hardhat clean +# 1. Predeploys addresses have been precomputed via the precomputeAddresses.sh script. +# 2. A local and **fresh** fhEVM node is already running. +# 3. All test addresses are funded (e.g. via the fund_test_addresses.sh script). + +npx hardhat compile:specific --contract contracts + mkdir -p fhevmTemp cp -L -r node_modules/fhevm fhevmTemp/ npx hardhat compile:specific --contract fhevmTemp/fhevm/lib @@ -11,18 +14,10 @@ npx hardhat compile:specific --contract fhevmTemp/fhevm/gateway mkdir -p abi cp artifacts/fhevmTemp/fhevm/lib/TFHEExecutor.sol/TFHEExecutor.json abi/TFHEExecutor.json -PRIVATE_KEY_GATEWAY_DEPLOYER=$(grep PRIVATE_KEY_GATEWAY_DEPLOYER .env | cut -d '"' -f 2) -npx hardhat task:computePredeployAddress --private-key "$PRIVATE_KEY_GATEWAY_DEPLOYER" - -npx hardhat compile:specific --contract contracts - -npx hardhat task:computeACLAddress -npx hardhat task:computeTFHEExecutorAddress -npx hardhat task:computeKMSVerifierAddress npx hardhat task:deployACL npx hardhat task:deployTFHEExecutor npx hardhat task:deployKMSVerifier -rm -rf fhevmTemp +npx hardhat task:launchFhevm --skip-get-coin true -npx hardhat task:launchFhevm --skip-get-coin true \ No newline at end of file +rm -rf fhevmTemp \ No newline at end of file diff --git a/package.json b/package.json index b75e657..5128871 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "eslint": "^9.9.0", "eslint-config-prettier": "^8.5.0", "ethers": "^6.8.0", - "fhevm": "^0.5.8", + "fhevm": "^0.5.9", "fhevmjs": "^0.5.2", "fs-extra": "^10.1.0", "globals": "^15.9.0", @@ -91,7 +91,7 @@ "task:getEthereumAddress": "hardhat task:getEthereumAddress", "task:deployERC20": "hardhat task:deployERC20", "task:accounts": "hardhat task:accounts", - "fhevm:start": "make run-full && ./scripts/fund_test_addresses_docker.sh && ./launch-fhevm.sh", + "fhevm:start": "./precomputeAddresses.sh && make run-full && ./scripts/fund_test_addresses_docker.sh && ./launch-fhevm.sh", "fhevm:stop": "make clean", "fhevm:restart": "fhevm:stop && fhevm:start", "fhevm:faucet": "npm run fhevm:faucet:alice && sleep 5 && npm run fhevm:faucet:bob && sleep 5 && npm run fhevm:faucet:carol && sleep 5 && npm run fhevm:faucet:dave && sleep 5 && npm run fhevm:faucet:eve", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 18af4e9..74ba3c0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -85,8 +85,8 @@ importers: specifier: ^6.8.0 version: 6.13.2 fhevm: - specifier: ^0.5.8 - version: 0.5.8 + specifier: ^0.5.9 + version: 0.5.9 fhevmjs: specifier: ^0.5.2 version: 0.5.2(encoding@0.1.13) @@ -1468,8 +1468,8 @@ packages: fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} - fhevm@0.5.8: - resolution: {integrity: sha512-fzTQnnw/7EajQywXUfZyTEGlsPe2SmvcVLklsmHEeZ5YQRmbp9pGR2rFuRcXED+Ou76Miq9oExRKIhkcdPlySg==} + fhevm@0.5.9: + resolution: {integrity: sha512-9cSfmAa4AJUuROd4kESvtNYJpnea1PUvjU7yaNnrJsaHqPkVGQvpnIDEnO4KTsJ36Etup1ksPs8PvyGNYwkatQ==} engines: {node: '>=20.0.0'} fhevmjs@0.5.2: @@ -4861,7 +4861,7 @@ snapshots: dependencies: reusify: 1.0.4 - fhevm@0.5.8: + fhevm@0.5.9: dependencies: '@openzeppelin/contracts': 5.0.2 diff --git a/precomputeAddresses.sh b/precomputeAddresses.sh new file mode 100755 index 0000000..cb8fff0 --- /dev/null +++ b/precomputeAddresses.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +npx hardhat clean +PRIVATE_KEY_GATEWAY_DEPLOYER=$(grep PRIVATE_KEY_GATEWAY_DEPLOYER .env | cut -d '"' -f 2) +npx hardhat task:computeACLAddress --network hardhat +npx hardhat task:computeTFHEExecutorAddress --network hardhat +npx hardhat task:computeKMSVerifierAddress --network hardhat +npx hardhat task:computePredeployAddress --private-key "$PRIVATE_KEY_GATEWAY_DEPLOYER" --network hardhat + +# Paths to input files +ENV_EXEC="node_modules/fhevm/lib/.env.exec" +ENV_GATEWAY="node_modules/fhevm/gateway/.env.gateway" +ENV_FILE=".env" + +# Path to output file +ENV_DOCKER=".env.docker" + +# Check if input files exist +for file in "$ENV_EXEC" "$ENV_GATEWAY" "$ENV_FILE"; do + if [ ! -f "$file" ]; then + echo "Error: $file does not exist." + exit 1 + fi +done + +# Extract values +TFHE_EXECUTOR_CONTRACT_ADDRESS=$(grep "^TFHE_EXECUTOR_CONTRACT_ADDRESS=" "$ENV_EXEC" | cut -d'=' -f2) +GATEWAY_CONTRACT_PREDEPLOY_ADDRESS=$(grep "^GATEWAY_CONTRACT_PREDEPLOY_ADDRESS=" "$ENV_GATEWAY" | cut -d'=' -f2) +GATEWAY_CONTRACT_PREDEPLOY_ADDRESS_NO0X=${GATEWAY_CONTRACT_PREDEPLOY_ADDRESS#0x} +PRIVATE_KEY_GATEWAY_RELAYER=$(grep PRIVATE_KEY_GATEWAY_RELAYER .env | cut -d '"' -f 2) + +# Write to .env.docker +cat << EOF > "$ENV_DOCKER" +TFHE_EXECUTOR_CONTRACT_ADDRESS=$TFHE_EXECUTOR_CONTRACT_ADDRESS +PRIVATE_KEY_GATEWAY_RELAYER=$PRIVATE_KEY_GATEWAY_RELAYER +GATEWAY_CONTRACT_PREDEPLOY_ADDRESS=$GATEWAY_CONTRACT_PREDEPLOY_ADDRESS_NO0X +EOF + +echo "Successfully created $ENV_DOCKER with the aggregated environment variables." \ No newline at end of file diff --git a/scripts/fund_test_addresses_docker.sh b/scripts/fund_test_addresses_docker.sh index 6a9f48c..9acb523 100755 --- a/scripts/fund_test_addresses_docker.sh +++ b/scripts/fund_test_addresses_docker.sh @@ -1,15 +1,60 @@ #!/usr/bin/env bash -docker exec -i zama-dev-fhevm-validator-1 faucet a5e1defb98efe38ebb2d958cee052410247f4c80 -sleep 8 -docker exec -i zama-dev-fhevm-validator-1 faucet fCefe53c7012a075b8a711df391100d9c431c468 -sleep 8 -docker exec -i zama-dev-fhevm-validator-1 faucet a44366bAA26296c1409AD1e284264212029F02f1 -sleep 8 -docker exec -i zama-dev-fhevm-validator-1 faucet c1d91b49A1B3D1324E93F86778C44a03f1063f1b -sleep 8 -docker exec -i zama-dev-fhevm-validator-1 faucet 305F1F471e9baCFF2b3549F9601f9A4BEafc94e1 -sleep 8 -docker exec -i zama-dev-fhevm-validator-1 faucet c45994e4098271c3140117ebD5c74C70dd56D9cd -sleep 8 -docker exec -i zama-dev-fhevm-validator-1 faucet 97F272ccfef4026A1F3f0e0E879d514627B84E69 \ No newline at end of file +# Read MNEMONIC from .env file, remove 'export' and quotes +MNEMONIC=$(grep MNEMONIC .env | cut -d '"' -f 2) +PRIVATE_KEY_GATEWAY_DEPLOYER=$(grep PRIVATE_KEY_GATEWAY_DEPLOYER .env | cut -d '"' -f 2) +PRIVATE_KEY_GATEWAY_OWNER=$(grep PRIVATE_KEY_GATEWAY_DEPLOYER .env | cut -d '"' -f 2) +PRIVATE_KEY_GATEWAY_RELAYER=$(grep PRIVATE_KEY_GATEWAY_DEPLOYER .env | cut -d '"' -f 2) + +# Verify that global envs are set +if [ -z "$MNEMONIC" ]; then + echo "Error: MNEMONIC is not set." + exit 1 +fi +if [ -z "$PRIVATE_KEY_GATEWAY_DEPLOYER" ]; then + echo "Error: PRIVATE_KEY_GATEWAY_DEPLOYER is not set." + exit 1 +fi +if [ -z "$PRIVATE_KEY_GATEWAY_OWNER" ]; then + echo "Error: PRIVATE_KEY_GATEWAY_OWNER is not set." + exit 1 +fi +if [ -z "$PRIVATE_KEY_GATEWAY_RELAYER" ]; then + echo "Error: PRIVATE_KEY_GATEWAY_RELAYER is not set." + exit 1 +fi + +# Compute addresses using ethers.js v6 - signers[0] to signers[4] are Alice, Bob, Carol, David and Eve. signers[9] is the fhevm deployer. +addresses=$(node -e " +const { ethers } = require('ethers'); +const derivationPath = \"m/44'/60'/0'/0\"; +const mnemonicInstance = ethers.Mnemonic.fromPhrase('$MNEMONIC'); +const hdNode = ethers.HDNodeWallet.fromMnemonic(mnemonicInstance, derivationPath); +const indices = [0, 1, 2, 3, 4, 9]; +for (const i of indices) { + const childNode = hdNode.derivePath(\`\${i}\`); + console.log(childNode.address); +} +const deployerAddress = new ethers.Wallet('$PRIVATE_KEY_GATEWAY_DEPLOYER').address; +console.log(deployerAddress); +const ownerAddress = new ethers.Wallet('$PRIVATE_KEY_GATEWAY_OWNER').address; +console.log(ownerAddress); +const relayerAddress = new ethers.Wallet('$PRIVATE_KEY_GATEWAY_RELAYER').address; +console.log(relayerAddress); +" 2>/dev/null) + +# Check if addresses were generated successfully +if [ -z "$addresses" ]; then + echo "Error: Failed to generate addresses." + exit 1 +fi + +# Convert the addresses string into an array +IFS=$'\n' read -rd '' -a addressArray <<<"$addresses" + +# Loop through each address, strip '0x', and run the Docker command +for addr in "${addressArray[@]}"; do + addr_no0x=${addr#0x} + docker exec -i zama-dev-fhevm-validator-1 faucet "$addr_no0x" + sleep 8 +done diff --git a/tasks/taskTFHE.ts b/tasks/taskTFHE.ts index 24a6bd3..15ee0ef 100644 --- a/tasks/taskTFHE.ts +++ b/tasks/taskTFHE.ts @@ -66,15 +66,15 @@ address constant fhevmCoprocessorAdd = ${execAddress};\n`; task("task:computeKMSVerifierAddress").setAction(async function (taskArguments: TaskArguments, { ethers }) { const deployer = (await ethers.getSigners())[9].address; - const kmsVerfierAddress = ethers.getCreateAddress({ + const kmsVerifierAddress = ethers.getCreateAddress({ from: deployer, nonce: 2, // using nonce of 2 for the Kms Verifier contract }); const envFilePath = path.join(__dirname, "../node_modules/fhevm/lib/.env.kmsverifier"); - const content = `KMS_VERIFIER_CONTRACT_ADDRESS=${kmsVerfierAddress}\n`; + const content = `KMS_VERIFIER_CONTRACT_ADDRESS=${kmsVerifierAddress}\n`; try { fs.writeFileSync(envFilePath, content, { flag: "w" }); - console.log(`KMS Verifier address ${kmsVerfierAddress} written successfully!`); + console.log(`KMS Verifier address ${kmsVerifierAddress} written successfully!`); } catch (err) { console.error("Failed to write KMS Verifier address:", err); } @@ -83,7 +83,7 @@ task("task:computeKMSVerifierAddress").setAction(async function (taskArguments: pragma solidity ^0.8.24; -address constant KMS_VERIFIER_CONTRACT_ADDRESS = ${kmsVerfierAddress};\n`; +address constant KMS_VERIFIER_CONTRACT_ADDRESS = ${kmsVerifierAddress};\n`; try { fs.writeFileSync("node_modules/fhevm/lib/KMSVerifierAddress.sol", solidityTemplate, { diff --git a/test/encryptedERC20/EncryptedERC20.ts b/test/encryptedERC20/EncryptedERC20.ts index b210fd7..5bd83fd 100644 --- a/test/encryptedERC20/EncryptedERC20.ts +++ b/test/encryptedERC20/EncryptedERC20.ts @@ -17,7 +17,7 @@ describe("EncryptedERC20", function () { this.instances = await createInstances(this.signers); }); - it("should mint the contract", async function () { + it.only("should mint the contract", async function () { const transaction = await this.erc20.mint(1000); await transaction.wait();