Skip to main content

Overview

This tutorial provides practical examples of using Access Control Lists (ACL) to manage permissions for encrypted data in your CoFHE contracts. See ACL Mechanism for explanation of why the ACL mechanism is needed.

Solidity API

The following functions are available for managing access control:
  1. FHE.allowThis(CIPHERTEXT_HANDLE) - allows the current contract access to the handle
  2. FHE.allow(CIPHERTEXT_HANDLE, ADDRESS) - allows the specified address access to the handle
  3. FHE.allowTransient(CIPHERTEXT_HANDLE, ADDRESS) - allows the specified address access to the handle for the duration of the transaction

Automatic Transaction-Scoped Allowance

The contract that creates the value for the first time will automatically get ownership of the ciphertext for the duration of the transaction, by using ACL.allowTransient(this) behind the scenes.
This automatic allowance only lasts for the duration of the current transaction. To use encrypted values in future transactions, you must explicitly grant access.

Persistent Allowance for This Contract

To use the results in other transactions, explicit ownership must be granted with FHE.allow(address) or FHE.allowThis().
If you don’t call FHE.allowThis() after modifying encrypted values, you won’t be able to use them in future transactions. Always call FHE.allowThis() after operations that modify encrypted state variables.

Allowance for Decryptions

To decrypt a ciphertext off-chain via the decryption network, the issuer must be allowed on the ciphertext handle via FHE.allow(userAddress).
When allowing users to decrypt their own encrypted values, use FHE.allow() to grant persistent access. This enables users to decrypt values off-chain using decryptForView without requiring additional transactions.

Allow Other Contracts

You can also allow other contracts to use your ciphertexts, either persistently or only for the course of this transaction via FHE.allowTransient(handle, address).
Use FHE.allowTransient() when you only need to grant access for a single transaction. Use FHE.allow() when you need persistent access across multiple transactions.

Common Patterns

Pattern 1: Allow Contract and User

When modifying encrypted values that users need to access:

Pattern 2: Allow Sender

A common pattern is to allow the message sender:

Pattern 3: Global Access

For values that should be accessible to everyone:

Best Practices

1

Always allow after modifications

After modifying any encrypted state variable, call FHE.allowThis() to ensure the contract can use it in future transactions.
2

Allow users for decryption

If users need to decrypt their own values off-chain, use FHE.allow() or FHE.allowSender() to grant them access.
3

Use transient for single-use access

When passing encrypted values to other contracts for a single operation, use FHE.allowTransient() instead of FHE.allow().

Next Steps