> ## Documentation Index
> Fetch the complete documentation index at: https://fhenix-ci-version-drift-check.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Your First FHE Contract

> Step-by-step tutorial for building your first FHE-enabled smart contract from scratch

## Overview

Let's take a look at a simple contract that uses FHE to encrypt a counter, and break it down into its components.

## Complete Contract Example

```solidity theme={null}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;

import {FHE, euint64, externalEuint64} from "@fhenixprotocol/cofhe-contracts/FHE.sol";

contract SimpleCounter {
    address owner;

    euint64 counter;
    euint64 delta;

    modifier onlyOwner() {
        require(msg.sender == owner, "Only the owner can access that function");
        _;
    }

    constructor(uint64 initial_value) {
        owner = msg.sender;
        counter = FHE.asEuint64(initial_value);
        FHE.allowThis(counter);

        // Encrypt the value 1 only once instead of every value change
        delta = FHE.asEuint64(1);
        FHE.allowThis(delta);
    }

    function increment_counter() external onlyOwner {
        counter = FHE.add(counter, delta);
        FHE.allowThis(counter);
    }

    function decrement_counter() external onlyOwner {
        counter = FHE.sub(counter, delta);
        FHE.allowThis(counter);
    }

    function reset_counter(externalEuint64 value, bytes calldata inputProof) external onlyOwner {
        counter = FHE.asEuint64(value, inputProof);
        FHE.allowThis(counter);
    }

    function allow_counter_publicly() external onlyOwner {
        FHE.allowPublic(counter);
    }

    function reveal_counter(uint64 _decrypted, bytes memory _signature) external {
        FHE.publishDecryptResult(counter, _decrypted, _signature);
    }

    function get_counter_value() external view returns(uint256) {
        (uint256 value, bool decrypted) = FHE.getDecryptResultSafe(counter);
        if (!decrypted)
            revert("Value is not ready");

        return value;
    }

    function get_encrypted_counter_value() external view returns(euint64) {
       return counter;
    }
}
```

## Breaking Down the Contract

### Importing the FHE Library

To start using FHE, we need to import the FHE library.

In this example, we're importing the types `euint64` and `externalEuint64` from the [FHE library](/fhe-library/reference/fhe-sol/overview).

```solidity theme={null}
import {FHE, euint64, externalEuint64} from "@fhenixprotocol/cofhe-contracts/FHE.sol";
```

We want to keep the counter encrypted at all times, so we'll use the `euint64` type.

### State Variables

Next, we define some state variables for the contract:

```solidity theme={null}
euint64 counter;
euint64 delta;
```

### Constructor Initialization

In the constructor, we initialize the `counter` and `delta` variables.

We encrypt the `delta` here to avoid calculating the same encrypted value every time we increment or decrement the counter.

```solidity theme={null}
counter = FHE.asEuint64(initial_value);
delta = FHE.asEuint64(1);
```

<Accordion title="Trivial Encryption" icon="info">
  <Note>
    We wanted the example contract to be as simple as possible, so readers can plug-and-play it into their preferred environment.

    There are some privacy improvements that could be made to this contract.
  </Note>

  When we initialize the `delta` and `counter` variables, we use **trivial encryption**.

  **Trivial encryption** produces a ciphertext from a public value, but this variable, even though represented as a ciphertext handle, is not really confidential because everyone can see what is the plaintext value that went into it.

  To make it completely private, we need to initialize these variables with an `InEuint` from the calldata.

  More about trivial encryption [here](/fhe-library/core-concepts/trivial-encryption).
</Accordion>

### Access Control

For every encrypted variable, we need to call `FHE.allowThis()` to allow the contract to access it.

**Allowing access to encrypted variables** is an important concept in FHE-enabled contracts.

Without it, the contract could not continue to use this encrypted variable in future transactions.

You can read more about this in the [ACL Mechanism](/fhe-library/core-concepts/access-control) page.

```solidity theme={null}
FHE.allowThis(counter);
FHE.allowThis(delta);
```

### Increment and Decrement Functions

In the `increment_counter` and `decrement_counter` functions, we use the `FHE.add` and `FHE.sub` functions to increment and decrement the counter, respectively.

And we also call `FHE.allowThis()` to allow the contract to access the new counter value.

```solidity theme={null}
counter = FHE.add(counter, delta);
FHE.allowThis(counter);
```

### Reset Function

In the `reset_counter` function, we receive an `externalEuint64` handle and the `bytes` proof that authenticates it. Together they represent an encrypted value that can be used to reset the counter, and `FHE.asEuint64(value, inputProof)` converts the pair into a `euint64` the contract can compute on.

Both come from the client, created with the SDK (read more about it [here](/client-sdk/guides/encrypting-inputs)).

### Decryption: Allow Public and Reveal

Decryption follows a two-step onchain pattern, with an offchain step in between.

**Step 1: Allow public decryption (onchain)**

The owner calls `allow_counter_publicly` to mark the counter as eligible for public decryption:

```solidity theme={null}
function allow_counter_publicly() external onlyOwner {
    FHE.allowPublic(counter);
}
```

**Step 2: Decrypt offchain**

Anyone can now request decryption offchain using `decryptForTx`, which returns the plaintext value and a Threshold Network signature:

```typescript theme={null}
const countCtHash = await counter.counter();

const result = await client
  .decryptForTx(countCtHash)
  .withoutACP()
  .execute();
```

**Step 3: Publish onchain with proof**

The decrypted value and signature are submitted onchain. `FHE.publishDecryptResult` verifies the signature and stores the plaintext. If the signature is invalid, the transaction reverts:

```solidity theme={null}
function reveal_counter(uint64 _decrypted, bytes memory _signature) external {
    FHE.publishDecryptResult(counter, _decrypted, _signature);
}
```

### Reading the Decrypted Value

Once the result has been published, anyone can read the counter's value using `get_counter_value`. This function uses `FHE.getDecryptResultSafe` to check if a published result is available:

```solidity theme={null}
function get_counter_value() external view returns(uint256) {
    (uint256 value, bool decrypted) = FHE.getDecryptResultSafe(counter);
    if (!decrypted)
        revert("Value is not ready");

    return value;
}
```

If the result has not been published yet, the function reverts. Otherwise, it returns the plaintext value.

## Privacy Considerations

In this contract, only the owner can allow public decryption. Once `reveal_counter` is called, the plaintext value is published onchain and visible to everyone.

What if we want to allow the owner to privately read the value without revealing it publicly?

For that, we need to add a call for `FHE.allow(counter, owner)` or `FHE.allowSender(counter)` every time that we change the counter's value.

This will allow the owner to read the encrypted counter's value using the `get_encrypted_counter_value` function and decrypt it privately offchain using `decryptForView`:

```solidity theme={null}
function increment_counter() external onlyOwner {
    counter = FHE.add(counter, delta);
    FHE.allowThis(counter);
    FHE.allowSender(counter);
}

function get_encrypted_counter_value() external view returns(euint64) {
   return counter;
}
```

```typescript theme={null}
// Decrypt privately off-chain (no on-chain transaction, no public reveal)
const countCtHash = await counter.get_encrypted_counter_value();

const result = await client
  .decryptForView(countCtHash)
  .withACP()
  .execute();

console.log(`Counter value (private): ${result.decryptedValue}`);
```

## Next Steps

* Explore [Adding FHE to an Existing Contract](/tutorials/adding-fhe-to-existing-contract)
* Review [ACL Usage Examples](/tutorials/acl-usage-examples) for more access control patterns
* Understand [Decryption Operations](/fhe-library/core-concepts/decryption-operations) in detail
