fhEVM
WebsiteLibrariesProduct & ServicesDevelopersSupport
0.5
0.5
  • Welcome to fhEVM
  • Getting Started
    • What is fhEVM
    • Deploy on fhEVM native
      • Using Zama Faucet
      • Local dev node
    • Deploy on Ethereum
    • Whitepaper
  • Fundamentals
    • Write contract
      • Using Hardhat
      • Using Remix
      • Other development environment
    • Encrypted types
      • Operations on encrypted types
      • Branching in FHE
      • Generate random number
    • Encrypted inputs
    • Access Control List
    • Decrypt and reencrypt
    • Contracts standard library
  • Guides
    • Decryption
    • Reencryption
    • Build a web application
    • Build with Node
    • Common pitfalls and best practises
    • How can I break a loop ?
    • Gas estimation on devnet
    • Use the CLI
    • Common webpack errors
  • Tutorials
    • See all tutorials
    • Write confidential smart contract with fhEVM
  • References
    • API function specifications
    • fhevmjs function specifications
    • Repositories
  • Developer
    • Contributing
    • Development roadmap
    • Release note
    • Feature request
    • Bug report
Powered by GitBook

Libraries

  • TFHE-rs
  • Concrete
  • Concrete ML
  • fhEVM

Developers

  • Blog
  • Documentation
  • Github
  • FHE resources

Company

  • About
  • Introduction to FHE
  • Media
  • Careers
On this page
  • Condition with encrypted boolean
  • Error handling

Was this helpful?

Export as PDF
  1. Fundamentals
  2. Encrypted types

Branching in FHE

PreviousOperations on encrypted typesNextGenerate random number

Last updated 10 months ago

Was this helpful?

The result of is of type ebool. Typical boolean operations are not supported for this type, because it is an encrypted boolean.

Condition with encrypted boolean

fhEVM provides a method which acts as a ternary operator on encrypted integers. This method is called .

function bid(einput encryptedValue, bytes calldata inputProof) public onlyBeforeEnd {
  euint64 bid = TFHE.asEuint64(encryptedValue, inputProof);
  ebool isAbove = TFHE.lt(highestBid, bid);

  // Replace highest bid
  highestBid = TFHE.select(isAbove, bid, highestBid);
  TFHE.allow(highestBid, address(this));
}

It is important to keep in mind that each time we assign a value using TFHE.select, the value changes, even if the plaintext value remains the same.

Error handling

If a condition is not satisfied, the transaction will not be reverted, potentially posing a challenge when attempting to communicate issues to users. A recommended approach to address this is by implementing an error handler in which the contract stores the latest error information for all wallets.

struct LastError {
  euint8 error;
  uint timestamp;
}

euint8 internal NO_ERROR;
euint8 internal NOT_ENOUGH_FUND;

constructor() {
  NO_ERROR = TFHE.asEuint8(0);
  NOT_ENOUGH_FUND = TFHE.asEuint8(1);
}

function setLastError(euint8 error, address addr) private {
  _lastErrors[addr] = LastError(error, block.timestamp);
  emit ErrorChanged(addr);
}

function _transfer(address from, address to, euint32 amount) internal {
  // Make sure the sender has enough tokens.
  ebool canTransfer = TFHE.le(amount, balances[from]);
  setLastError(TFHE.select(canTransfer, NO_ERROR, NOT_ENOUGH_FUND), msg.sender);

  // Add to the balance of `to` and subract from the balance of `from`.
  balances[to] = TFHE.add(balances[to], TFHE.select(canTransfer, amount, TFHE.asEuint32(0)));
  TFHE.allow(balances[to], address(this));
  TFHE.allow(balances[to], to);

  balances[from] = TFHE.sub(balances[from], TFHE.select(canTransfer, amount, TFHE.asEuint32(0)));
  TFHE.allow(balances[from], address(this));
  TFHE.allow(balances[from], from);
}
comparison operations
select