Skip to content

view Modifier Incompatibility with FHE.fromExternal and FHE Precompiles (Undocumented DX Issue) #2026

@manchain

Description

@manchain
## Problem

When writing a function that logically feels read-only — such as checking whether a submitted encrypted value meets a threshold — developers will naturally reach for the `view` modifier:

```solidity
function meetsThreshold(
    uint256 id,
    externalEuint32 req
) external view returns (ebool) {
    euint32 val = FHE.fromExternal(req, permission);
    return FHE.ge(val, thresholds[id]);
}

This fails to compile with:

TypeError: Function declared as view, but this expression (potentially) modifies the state.

The error is technically correct but non-obvious and currently undocumented.


Root Cause

FHE.fromExternal internally calls Impl.verify(), which validates the external ciphertext proof against the FHE coprocessor. This writes state at the EVM level, making it incompatible with view — even though it doesn't mutate any application-level contract state.

The same applies to other FHE precompile operations including FHE.add, FHE.sub, FHE.mul, FHE.ge, FHE.le, and FHE.eq in certain contexts.


Proposed Fix

No code change needed. This is purely a documentation improvement.

The Getting Started guide and FHE.fromExternal API reference should explicitly state:

Functions using FHE.fromExternal or any FHE precompile operation cannot be marked as view. Although these operations do not modify your contract's application state, they perform internal proof validation that modifies EVM state under the hood. Declare such functions without view and invoke them as regular transactions or via eth_call.

Additionally, a short note on the recommended pattern for developers wanting off-chain query-like behavior would be helpful. For example, separating proof submission and threshold evaluation into two distinct steps.


Environment

  • fhEVM version: latest
  • Toolchain: Hardhat / Foundry (standard solc setups)
  • Network: SepoliaETH

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions