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 requests decryption of the highest bid and bidder address. This triggers the asynchronous decryption process.
4
Reveal Winner
After decryption completes, the auctioneer can reveal the winner. The contract provides both safe and unsafe methods for retrieving the decrypted 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 contract provides two methods to reveal the winner:
Copy
Ask AI
function safelyRevealWinner() external onlyAuctioneer { require(auctionClosed, "Auction isn't closed"); // Check if bid decryption is ready (uint64 bidValue, bool bidReady) = FHE.getDecryptResultSafe(highestBid); require(bidReady, "Bid not yet decrypted"); // Check if bidder decryption is ready (address bidderValue, bool bidderReady) = FHE.getDecryptResultSafe(highestBidder); require(bidderReady, "Bidder not yet decrypted"); winningBid = bidValue; winningBidder = bidderValue; emit RevealedWinningBid(bidderValue, bidValue);}
The unsafe method will revert the entire transaction if decryption results aren’t ready. The safe method allows you to handle this gracefully with a custom error message.