Skip to content

Lesson 2: From Mock to Mainnet — Deployment & Frontend

Duration: ~60 minutes | Prerequisites: Lesson 1: Sealed-Bid Auction | Scripts: deploy/*.ts


Learning Objectives

By the end of this lesson, you will:

  • Understand what changes between local mock mode and real FHEVM execution
  • Deploy the bootcamp contracts with Hardhat on localhost and Sepolia
  • Use encrypted client inputs through the Hardhat FHEVM runtime
  • Decrypt encrypted outputs with proper permissions
  • Verify deployed contracts on Etherscan
  • Apply a production-minded checklist before shipping

1. Mock Mode vs Real Mode

Throughout the bootcamp you use the default Hardhat network in mock mode. That gives you the correct contract interface and encrypted workflow, but without the cost and latency of real FHE infrastructure.

AspectMock ModeReal Mode
EncryptionLocal mock runtimeReal FHE ciphertext
CoprocessorIn-memory test runtimeReal FHEVM infrastructure
DecryptionFast local flowPermissioned off-chain decryption
SpeedFast feedbackSlower, production-shaped latency
NetworkHardhat 31337Sepolia / Mainnet

What Stays the Same

Your Solidity contract code does not change. ZamaEthereumConfig still resolves the correct runtime addresses based on block.chainid, and your contract still expects encrypted handles plus proofs.

What Changes

  1. Encryption is no longer mocked.
  2. Permissioning matters end to end.
  3. Decryption goes through the supported FHEVM path instead of a local debugger.
  4. Deployment and verification become part of the workflow, not just local tests.

2. Configure Deployment Variables

Use Hardhat vars:

bash
npx hardhat vars set MNEMONIC
npx hardhat vars set INFURA_API_KEY
npx hardhat vars set ETHERSCAN_API_KEY

The repo also supports .env and .env.local as fallbacks for:

  • MNEMONIC
  • INFURA_API_KEY
  • RPC_URL
  • PRIVATE_KEY
  • ETHERSCAN_API_KEY

3. Deploy with Hardhat

The bootcamp uses hardhat-deploy.

Localhost

bash
npm run chain
npm run deploy:localhost

Deploy only the counter:

bash
npm run deploy:localhost:fhecounter

Sepolia

bash
npm run deploy:sepolia

Deploy only one contract by tag:

bash
npx hardhat deploy --network sepolia --tags SealedBidAuction

4. Encrypted Input Flow

The same encrypted input model you use in tests is what you carry into real interaction flows.

ts
const encryptedBid = await hre.fhevm
  .createEncryptedInput(contractAddress, bidder.address)
  .add64(1_000)
  .encrypt();

await auction.connect(bidder).placeBid(encryptedBid.handles[0], encryptedBid.inputProof);

The pattern is:

  1. Bind encryption to a specific contract and user.
  2. Encrypt the plaintext input locally.
  3. Send the encrypted handle and proof to the contract.

5. Decryption Flow

Once a signer has permission, they can decrypt through the FHEVM runtime:

ts
const highestBid = await hre.fhevm.userDecryptEuint(
  FhevmType.euint64,
  await auction.getHighestBid(),
  contractAddress,
  auctioneer,
);

For encrypted addresses:

ts
const highestBidder = await hre.fhevm.userDecryptEaddress(
  await auction.getHighestBidder(),
  contractAddress,
  auctioneer,
);

6. Verification

Verify a deployment on Sepolia:

bash
npx hardhat verify --network sepolia <DEPLOYED_ADDRESS>

With constructor arguments:

bash
npx hardhat verify --network sepolia \
  <DEPLOYED_ADDRESS> \
  "Confidential Token" \
  "CFHE"

7. Deployment Checklist

Before treating a contract as production-ready:

  • [ ] All local tests pass in mock mode
  • [ ] The relevant contract is deployed and exercised on Sepolia
  • [ ] FHE.allowThis() is applied after every handle-changing operation
  • [ ] FHE.allow() is only granted to the intended decrypting principals
  • [ ] No encrypted values are leaked through events
  • [ ] No encrypted conditions are exposed through revert behavior
  • [ ] The frontend or script uses the correct deployed addresses and ABI
  • [ ] Contract verification is complete

Key Takeaways

  1. The contract code stays the same between local and real environments.
  2. Hardhat handles both encrypted testing and deployment for this bootcamp.
  3. createEncryptedInput and user decryption are the core integration points.
  4. Deployment is only complete once verification and permission-aware interaction both work.

Next: Complete the Week 4 Homework and extend the auction into a Vickrey design.

Built for the Zama Developer Program — Bounty Track