> ## 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.

# Inputs

> Learn how to handle encrypted user inputs in confidential smart contracts

## Overview

One of the key aspects of writing confidential smart contracts is receiving encrypted inputs from users:

```solidity theme={null}
function transfer(
    address to,
    externalEuint32 inAmount,  // <------ encrypted input here
    bytes calldata inputProof  // <------ the proof that authenticates it
) public virtual returns (euint32 transferred) {
    euint32 amount = FHE.asEuint32(inAmount, inputProof);
}
```

<Note>
  Notice in the example above the distinction between **`externalEuint32`** and **`euint32`**.
</Note>

## Input Types Conversion

The **input types** `externalEuintXX` (and `externalEbool`, `externalEaddress`) represent **user input**. Each one is a ciphertext handle that travels with a separate `bytes` proof, and the pair is what lets the contract authenticate the value. For more on that, read about the [ZK-Verifier](/deep-dive/cofhe-components/zk-verifier).

Before you can use an encrypted input, convert it to a regular **encrypted type**, passing the proof alongside the handle:

```solidity theme={null}
euint32 amount = FHE.asEuint32(inAmount, inputProof);
```

One signature covers every encrypted input in a call, so the proof is shared. It follows the handle it authenticates rather than sitting last in the parameter list.

<Tip>
  Avoid storing `externalEuintXX` values in contract state. They are unverified until you convert them, so storing one keeps a handle the contract has not authenticated. Always convert with `FHE.asE...()` first.
</Tip>

Now that `amount` is of type `euint32`, you can store or manipulate it:

```solidity theme={null}
toBalance = FHE.sub(toBalance, amount);
```

<Tip>
  Read more about the available FHE types and operations in the [FHE Encrypted Operations](/fhe-library/core-concepts/encrypted-operations) guide.
</Tip>

## Full Example

Here's a complete example showing how to handle encrypted inputs in a transfer function:

```solidity theme={null}
function transfer(
    address to,
    externalEuint32 inAmount,
    bytes calldata inputProof
) public virtual returns (euint32 transferred) {
    euint32 amount = FHE.asEuint32(inAmount, inputProof);

    toBalance = _balances[to];
    fromBalance = _balances[msg.sender];

    _updateBalance(to, FHE.add(toBalance, amount));
    _updateBalance(from, FHE.sub(fromBalance, amount));
}
```

<Note>
  For the example above to work correctly, you will also need to manage access to the newly created ciphertexts in the `_updateBalance()` function. Learn more about access control in the [ACL Mechanism](/fhe-library/core-concepts/access-control) guide.
</Note>

## Passing encrypted values between contracts

`externalEuintXX` is for values arriving from a user. A value arriving from **another contract** uses `sharedEuintXX` instead.

The distinction matters for security. FHE operations check the permission of the contract performing them, not of whoever called it. A function that accepts a bare `euintXX` from outside can therefore be handed any handle that contract is allowed on, including one read out of its own storage. It can then be made to return something derived from it.

`sharedEuintXX` closes that. The sharer grants access and records itself in the same step, and the receiver checks who handed the value over:

```solidity theme={null}
// Sender: grants access and directs the value at one receiver
token.pull(FHE.shareEuint64(amount, address(token)));

// Receiver: unwraps it, checking the sharer is the caller
function pull(sharedEuint64 shared) external {
    euint64 amount = FHE.receiveEuint64Param(shared);
    ...
}
```

Pick the receive form by how the value reached you:

| How it arrived                      | Use                                      | Sharer is checked against  |
| ----------------------------------- | ---------------------------------------- | -------------------------- |
| An argument to your function        | `receiveEuintXXParam(shared)`            | your caller (`msg.sender`) |
| The return value of a call you made | `receiveEuintXXFromCall(shared, callee)` | the contract you called    |

For `receiveEuintXXFromCall`, `callee` must be the address called in that same expression. Naming a merely trusted address checks who *created* the share rather than who *handed it over*.

A share is single-use and lasts one transaction, so it cannot be stored, replayed, or rebuilt from an event. To keep a received value, call `FHE.allowThis` on the unwrapped `euintXX`. Expect `NotShared` when nothing was shared with you, `UnexpectedSharer` when the share came from someone other than the party you named, and `SenderNotAllowed` when the sharer does not hold the handle.

<Warning>
  The old spelling, an `FHE.allowTransient` grant plus a bare `euintXX` parameter, still compiles and still runs. The compiler will not find these for you, so they have to be found by search. See [migrating to 0.7](/client-sdk/introduction/migrating-to-0-7) for the full pass.
</Warning>

## Additional Examples

### Voting in a Poll

```solidity theme={null}
function castEncryptedVote(address poll, externalEbool encryptedVote, bytes calldata inputProof) public {
    _submitVote(poll, FHE.asEbool(encryptedVote, inputProof));
}
```

### Setting Encrypted User Preferences

```solidity theme={null}
function updateUserSetting(address user, externalEuint8 encryptedSetting, bytes calldata inputProof) public {
    _applyUserSetting(user, FHE.asEuint8(encryptedSetting, inputProof));
}
```
