EIPs

EIP-6492 — Signature validation for predeploy contracts

eips.ethereum.org/EIPS/eip-6492

EIP-1271 validates a signature against a deployed contract. EIP-6492 extends that to contracts that aren’t deployed yet — the smart account address is known (via CREATE2), but the code isn’t on-chain.

The signature is wrapped: (factory, factory_calldata, inner_signature) || MAGIC_BYTES. A universal validator contract:

  1. Detects the wrapped form via the trailing magic bytes.
  2. If the address has no code, deploys it using the factory + calldata.
  3. Calls isValidSignature on the now-deployed contract.
import {
  wrap_signature,
  unwrap_signature,
  is_wrapped_signature,
  verify_hash,
} from "@ethernauta/eip/6492";

const wrapped = wrap_signature({
  factory,
  factory_calldata,
  inner_signature,
});

const ok = await verify_hash({
  address: counterfactual_account,
  hash: digest,
  signature: wrapped,
})(reader({ chain_id: eip155_1.chain_id }));

Surface

ExportTypePurpose
MAGIC_BYTESBytes320x6492…6492 — sentinel suffix.
VALIDATOR_BYTECODEBytesCompiled universal validator.
wrap_signature(args) => BytesProduce a wrapped signature.
unwrap_signature(bytes) => UnwrappedSignatureReverse wrap_signature.
is_wrapped_signature(bytes) => booleanDetect via magic bytes.
UnwrappedSignaturetype{ factory, factory_calldata, inner_signature }.
verify_hashReadable<boolean>Run the universal validator.

How the universal validator works

The trick is that verify_hash deploys an ephemeral contract (via eth_call with the validator bytecode as to: null) that handles both the deployment and the isValidSignature call in a single state-less execution. No transaction is sent; nothing is persisted. Pure read.

This is what makes counterfactual signatures verifiable from a Readable<T> — no wallet, no gas.

Cross-EIP verification

In practice you rarely call this directly. The universal verifiers in @ethernauta/crypto walk the full hierarchy:

import { verify_message_universal } from "@ethernauta/crypto";

// works for: EOA, deployed smart account, counterfactual smart account
const ok = await verify_message_universal({
  address,
  message,
  signature,
})(reader);

See also

  • EIP-1014 — CREATE2 address derivation (the “counterfactual” half).
  • EIP-1271 — deployed contract signatures (the inner case).
  • @ethernauta/crypto — universal verifiers.