This example demonstrates how to build a fully confidential auction system where bids remain encrypted throughout the bidding process. Only when the auction closes can the winner be revealed, ensuring that bidders cannot see or react to each other’s bids.
The auctioneer deploys the contract, which initializes the auction with zero bid and address values, both encrypted.
2
Bidding Phase
Participants submit bids by sending plaintext amounts that are immediately encrypted. Each bid is compared against the current highest bid using encrypted comparison (FHE.gt), and the highest bid and bidder are updated accordingly.
3
Close Auction
The auctioneer closes the auction and calls FHE.allowPublic on the highest bid and bidder, making them eligible for public decryption.
4
Decrypt Off-Chain
Anyone can call decryptForTx off-chain to obtain the plaintext values and Threshold Network signatures for the winning bid and bidder.
5
Reveal Winner
The decrypted values and signatures are submitted on-chain via revealWinner, which calls FHE.publishDecryptResult to verify the proofs and store the results.
function bid(uint256 amount) external { require(!auctionClosed, "Auction is closed"); // 1. Encrypt the bid amount euint64 emount = FHE.asEuint64(amount); // 2. Check if this bid is higher (encrypted comparison) ebool isHigher = FHE.gt(emount, highestBid); // 3. Update highest bid using max highestBid = FHE.max(emount, highestBid); // 4. Update highest bidder using select highestBidder = FHE.select( isHigher, FHE.asEaddress(msg.sender), highestBidder ); // 5. Grant contract access to new encrypted values FHE.allowThis(highestBid); FHE.allowThis(highestBidder); emit BidPlaced(msg.sender);}
Notice how the contract never reveals the current highest bid to bidders. All comparisons and updates happen on encrypted data, maintaining complete confidentiality throughout the bidding process.
The auctioneer closes the auction and allows public decryption of the winning bid and bidder:
Copy
Ask AI
function closeBidding() external onlyAuctioneer { require(!auctionClosed, "Auction is already closed"); // Allow anyone to request decryption of the results FHE.allowPublic(highestBid); FHE.allowPublic(highestBidder); auctionClosed = true; emit AuctionClosed();}
Since FHE.allowPublic is used, anyone can request decryption off-chain without needing a permit. The values are not revealed until someone submits the proof on-chain.
FHE.publishDecryptResult verifies the Threshold Network signature before accepting the plaintext. If the signature is invalid, the transaction reverts.
Bids remain completely encrypted during the auction. No one can see the current highest bid or react to other bids.
Encrypted Comparisons
The contract uses FHE.gt(), FHE.max(), and FHE.select() to update the highest bid without decrypting values.
Access Control
Every encrypted value created must have permissions granted via FHE.allowThis() for the contract to access it later. Use FHE.allowPublic() when values are ready to be revealed.
Decrypt-with-Proof
Decryption happens off-chain via decryptForTx, and results are verified on-chain via FHE.publishDecryptResult with a Threshold Network signature.