EIPs

EIP-1271 — Standard signature validation for contracts

eips.ethereum.org/EIPS/eip-1271

EOAs sign with their private key; smart contracts can’t. EIP-1271 specifies how a contract validates a signature on its own behalf — the contract implements isValidSignature(hash, signature) which returns the magic value 0x1626ba7e for valid signatures.

import { verify_hash, MAGIC_VALUE } from "@ethernauta/eip/1271";

const ok = await verify_hash({
  address: contract_address,
  hash: digest,
  signature,
})(reader({ chain_id: eip155_1.chain_id }));
// ok === true iff isValidSignature returned MAGIC_VALUE

Surface

ExportTypePurpose
MAGIC_VALUEBytes40x1626ba7e — the success sentinel.
verify_hashReadable<boolean>Call isValidSignature and compare.

How it fits

verify_hash is the EIP-1271 verification primitive. For the common “verify a signed message” or “verify a signed typed data” flow, use the higher-level @ethernauta/crypto verifiers — they call verify_hash automatically when the address has deployed code, and fall through to EOA recovery when it doesn’t.

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

// works whether `address` is an EOA or a smart account
const ok = await verify_message({ address, message, signature })(reader);

Counterfactual addresses

If the contract isn’t deployed yet, EIP-1271 by itself can’t validate — there’s no code to call. EIP-6492 wraps the signature with deployment instructions and a validator contract that handles the not-yet-deployed case. Use verify_message_universal / verify_typed_data_universal from @ethernauta/crypto when you need that.

See also

  • EIP-191 — what a personal-sign signature looks like.
  • EIP-712 — typed-data signatures (the more common 1271 input).
  • EIP-6492 — counterfactual signatures.
  • @ethernauta/cryptoverify_message, verify_typed_data.