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

# Writing Encrypted Data to Contract

> Encrypt plaintext values and pass them directly into a contract call

This page covers the "encrypt to write tx" flow: encrypt plaintext values and pass them straight into a contract call.

`encryptInputs` returns one ciphertext handle per value, followed by a single signature covering the batch. Each handle is an `externalEuintXX`, and the signature is the `bytes` proof that follows it in the function signature. The onchain CoFHE library verifies the proof before the contract can use the ciphertext.

## Flow

1. Ensure your contract function accepts an `externalEuintXX` handle plus a `bytes` proof.
2. Encrypt the plaintext values with [`encryptInputs`](/client-sdk/guides/encrypting-inputs), naming the contract that will consume them.
3. Send a transaction, passing the handle and the proof.

## Prerequisites

1. [Create and connect a client](/client-sdk/guides/client-setup).
2. Your contract function must accept `externalEuintXX` parameters with a `bytes` proof.

The encrypted type you choose in TypeScript must match the Solidity parameter type:

* `Encryptable.uint32(...)` to `externalEuint32`
* `Encryptable.bool(...)` to `externalEbool`
* `Encryptable.address(...)` to `externalEaddress`

## Example: encrypt and call a contract

<CodeGroup>
  ```solidity Solidity theme={null}
  // SPDX-License-Identifier: UNLICENSED
  pragma solidity ^0.8.28;

  import '@fhenixprotocol/cofhe-contracts/FHE.sol';

  contract EncryptedCounter {
    euint32 public count;

    function setCount(externalEuint32 inCount, bytes calldata inputProof) external {
      count = FHE.asEuint32(inCount, inputProof);
      FHE.allowThis(count);
      FHE.allowSender(count);
    }
  }
  ```

  ```typescript TypeScript (viem) theme={null}
  import { Encryptable } from '@cofhe/sdk';
  import { parseAbi } from 'viem';
  import { sepolia } from 'viem/chains';

  // externalEuint32 is a bytes32 value type on the wire
  const encryptedCounterAbi = parseAbi([
    'function setCount(bytes32 inCount, bytes inputProof)',
  ]);

  // 1) Encrypt right before sending the transaction
  const [countHash, signature] = await cofheClient
    .encryptInputs([Encryptable.uint32(42n)])
    .setConsumingContract(encryptedCounterAddress)
    .execute();

  // 2) Pass the handle and its proof
  const hash = await walletClient.writeContract({
    chain: sepolia,
    account,
    address: encryptedCounterAddress,
    abi: encryptedCounterAbi,
    functionName: 'setCount',
    args: [countHash, signature],
  });

  await publicClient.waitForTransactionReceipt({ hash });
  ```

  ```typescript TypeScript (ethers) theme={null}
  import { Encryptable } from '@cofhe/sdk';

  // 1) Encrypt
  const [countHash, signature] = await cofheClient
    .encryptInputs([Encryptable.uint32(42n)])
    .setConsumingContract(encryptedCounterAddress)
    .execute();

  // 2) Send the transaction
  const tx = await contract.setCount(countHash, signature);
  await tx.wait();
  ```
</CodeGroup>

## Common pitfalls

* **Wrong `Encryptable` type**: the factory must match the Solidity parameter, `externalEuint32` against `externalEuint64`.
* **Wrong account / chain**: encrypted inputs are authorized for a specific `account + chainId`. If you encrypt under the wrong wallet/network, the contract call may revert.
* **Stale ABI shape**: the old `(ctHash, securityZone, utype, signature)` tuple is gone. A hand-written ABI takes `bytes32` for the handle and `bytes` for the proof.
* **Missing or wrong consuming contract**: name the contract that runs `FHE.asEuint*`. Getting it wrong compiles and reverts at runtime.
