> ## Documentation Index
> Fetch the complete documentation index at: https://cofhe-docs.fhenix.zone/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 → write tx" flow: encrypt plaintext values into `InE*` structs and pass them directly into a contract call.

`encryptInputs` returns `EncryptedItemInput` objects that match the Solidity `InE*` input structs. The on-chain CoFHE library validates the verifier signature before the contract can use the ciphertext.

## Flow

1. Ensure your contract function accepts encrypted `InE*` parameters.
2. Encrypt the plaintext values with [`encryptInputs`](/client-sdk/guides/encrypting-inputs).
3. Send a transaction and pass the encrypted structs as the `InE*` arguments.

## Prerequisites

1. [Create and connect a client](/client-sdk/guides/client-setup).
2. Your contract function must accept encrypted `InE*` structs.

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

* `Encryptable.uint32(...)` → `InEuint32`
* `Encryptable.bool(...)` → `InEbool`
* `Encryptable.address(...)` → `InEaddress`

## 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(InEuint32 memory _inCount) external {
      count = FHE.asEuint32(_inCount);
      FHE.allowThis(count);
      FHE.allowSender(count);
    }
  }
  ```

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

  const encryptedCounterAbi = parseAbi([
    'function setCount((uint256 ctHash, uint8 securityZone, uint8 utype, bytes signature) _inCount)',
  ]);

  // 1) Encrypt right before sending the transaction
  const [inCount] = await cofheClient
    .encryptInputs([Encryptable.uint32(42n)])
    .execute();
  assertCorrectEncryptedItemInput(inCount);

  // 2) Pass the encrypted struct as the InE* argument
  const hash = await walletClient.writeContract({
    chain: sepolia,
    account,
    address: encryptedCounterAddress,
    abi: encryptedCounterAbi,
    functionName: 'setCount',
    args: [inCount],
  });

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

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

  // 1) Encrypt
  const [inCount] = await cofheClient
    .encryptInputs([Encryptable.uint32(42n)])
    .execute();

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

## Common pitfalls

* **Wrong `Encryptable` type**: the `Encryptable.*` factory must match the Solidity parameter type (`InEuint32` vs `InEuint64`, etc).
* **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.
* **ABI struct shape mismatch**: if you hand-write an ABI, ensure the tuple fields are `(ctHash, securityZone, utype, signature)` in the same order your client library expects.
