@jkm.eth Great question β and yes, this lands on us. Hereβs the
concrete answer after working through the ERC-8121 spec carefully.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
NOTE: Project rebrand (relevant to records named below)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Siren is the hackathon name from ETHPrague 2026. Production
release is branded VerAL β Verification Authority Layer for
Ethereum. Same project, same ENS-anchored architecture, same
team. ENS namespace migrates from siren.* to veral.* with
backward compatibility through Term 1. Iβll use Veral in the
technical examples below since thatβs the production identity.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The pointer on Veralβs side would target the EAS contractβs
getAttestation function (v1.0), with a thin Veral verifier contract
as an upgrade path (v1.5+). Both paths satisfy ERC-8121βs selector
checksum and CCIP-Read enablement requirements.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
OPTION A β EAS-native, no custom contract (v1.0 ship target)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The ENS record veral.cert (per-tier records below) points to the EAS
mainnet contract directly:
contract: 0xA1207F3BBa224E2c9c3c6D5aF63D0eb1582Ce587
functionSignature: βgetAttestation(bytes32)β
functionSelector: 0xa3112a64 // bytes4(keccak256(signature))
parameter: <Veral cert UID for the subject + tier>
The selector here is the actual derived value (verified via
cast sig), satisfying ERC-8121βs checksum requirement β
bytes4(keccak256("getAttestation(bytes32)")) produces 0xa3112a64,
clients reject if the embedded selector doesnβt match.
EAS getAttestation returns the full Attestation struct (data,
attester, time, expirationTime, revocationTime, refUID, schema,
recipient), which embeds our Veral schema payload: tier, score,
validUntil, signer, evidenceBundleHash, scoreFormulaVersion,
optional aiProvenanceHash + forensicHash, and previousUID for
renewal chains.
ERC-8121 mandates clients enable CCIP-Read capability before
resolving. The EAS contract itself doesnβt trigger an off-chain
fetch (data comes from on-chain SLOAD), but the clientβs CCIP-Read
runtime is enabled β fully spec-compliant. This is the simplest
path to a working ENS-anchored verifiable cert with zero new
contracts from us.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
OPTION B β Veral verifier contract + CCIP-Read (v1.5+ path)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
A thin read-only Solidity contract deployed via CREATE2 (same
address per chain via deterministic factory pattern):
contract VeralVerifier {
function verifyForSubject(bytes32 ensNamehash, uint8 tier)
external view
returns (
bytes32 currentUID,
uint16 score,
uint64 validUntil,
bool isExpired,
bytes32 evidenceBundleHash
);
function listActiveTiers(bytes32 ensNamehash)
external view
returns (bytes32[] memory uids, uint8[] memory tiers);
}
Critical design correction from my own thinking: storage stays in
ENS, not in the verifier contract. The verifier reads ENS text
records veral.cert.public / veral.cert.anchored /
veral.cert.sealed (UIDs published by the subject via setText on
issuance), then forwards to EAS for the attestation data. No
Veral-side contract storage = no upgrade migration risk, no Veral
single point of write, ENS-native subject control over their own
records.
This contract pairs with CCIP-Read for cross-chain cert discovery:
the gateway returns signed payloads (ECDSA today; in v2.0
potentially ZK-proven if score formula computation is moved into
a verifiable circuit), validated on-chain by the verifier.
ERC-8121 pointer:
functionSignature: βverifyForSubject(bytes32,uint8)β
functionSelector: <derived via bytes4(keccak256(β¦))>
parameter: ensNamehash + requested tier
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ON THE MULTI-TIER QUESTION
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
A subject may hold multiple active Veral certs simultaneously
(e.g. Public + Anchored, or all three tiers). To handle this
cleanly:
ENS text records, one per tier:
veral.cert.public β EAS UID for active Public cert
veral.cert.anchored β EAS UID for active Anchored cert
veral.cert.sealed β EAS UID for active Sealed cert
veral.cert β pointer to the highest active tier
(convenience for clients wanting βbestβ)
Each record updated via setText on each issuance / renewal β one
transaction per tier per renewal, gas amortized across tier
independence (no cross-tier interference, subject controls timing).
ERC-8121 hook can target any of the four β wallet shows tier-
appropriate cert, explorer surfaces all, governance forums quote
the highest.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ON ZK PROOFS AND OPERATOR TRUST
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
To soften an earlier statement of my own: ZK proofs (when we ship
them in v2.0) reduce the operatorβs trust scope, but donβt eliminate
it. The math:
ZK proves: βgiven evidence bundle hash X, score formula produces Yβ
(arithmetic correctness β verifiable in circuit)
Operator
still attests: βthe evidence bundle X was honestly fetched from
Sourcify/GitHub/etc β these are the real valuesβ
(data authenticity β separate problem, requires
TLSNotary-class proofs or trusted source signing)
So v2.0 with ZK proofs collapses the trust surface from βmath +
dataβ to just βdataβ β significant, not full elimination.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ON THE BROADER PRIMITIVE
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
To answer the implicit framing in @Premm.ethβs earlier point β a
plain URL redirect doesnβt give clients interface stability at the
byte level, and doesnβt compose into the EAS / CCIP-Read / ZK
verification stack the ecosystem is converging on. ERC-8121βs
contribution is making the pointer itself a typed, checksummed
interface fingerprint with mandatory CCIP-Read enablement. We agree
itβs the right primitive for verifiable attestation pointers.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
OPEN QUESTIONS (for the ENS DAO + ERC-8121 reviewers)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
-
For multi-tier subjects with parallel active certs, is the
veral.cert.{tier} per-record pattern preferable to a single
record encoding multiple UIDs (gas-cheaper but less ERC-8121-
composable)?
-
For ERC-8121 multi-chain readers, deterministic same-address
deployment via CREATE2 vs chain-specific addresses in the pointer
β does the spec favor one, or is this issuer choice?
-
Is there appetite in the ENS community for a standard verifier
interface that issuers (Veral, and potentially others β
Verax-class attestation services, audit firms, identity
providers β if they choose to align) could implement, giving
wallets a single integration point for attestation resolution?
The ZK-proof + CCIP-Read direction @Premm.eth referenced is exactly
where we see this going in v2.0, once the off-chain score engine
graduates to a verifiable circuit.