EIPs
EIP-1271 — Standard signature validation for contracts
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
| Export | Type | Purpose |
|---|---|---|
MAGIC_VALUE | Bytes4 | 0x1626ba7e — the success sentinel. |
verify_hash | Readable<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/crypto —
verify_message,verify_typed_data.