Skip to content

Add ERC: Clear Signing On-Chain Descriptors Registry - #1789

Open
forshtat wants to merge 57 commits into
ethereum:masterfrom
forshtat:create-erc7730-onchain-registry
Open

forshtat wants to merge 57 commits into
ethereum:masterfrom
forshtat:create-erc7730-onchain-registry

Conversation

@forshtat

@forshtat forshtat commented Jun 3, 2026 •

Copy link
Copy Markdown
Contributor

The descriptors for ERC-7730 "Clear Signing" are too big to be stored on-chain, but it does not mean we can't do anything about it and fall back to using Github as a registry.
The "registry" contract can store IPFS identifiers and EAS attestations for the descriptor files.

This approach closes the loop:

  • ERC-7730 - defines descriptor file format
  • ERC-8176 - defines the attestation format
  • TBD ERC-8265 - defines the "transaction envelope" format (metadata like transaction simulation outcomes, transaction assertions, resolved ENS names etc. can be bundled there)
  • This ERC - defines the on-chain open resolution mechanism for clear signing

These four standards together create a full clear signing ecosystem that can actually address the security of signing Ethereum transactions of any non-trivial complexity.

@eip-review-bot

eip-review-bot commented Jun 3, 2026 •

Copy link
Copy Markdown
Collaborator

File ERCS/erc-8283.md

Requires 1 more review from Editors: @g11tech, @jochem-brouwer, @samwilsn, @xinbenlv

Comment thread ERCS/erc-xxxx.md Outdated
Comment thread ERCS/erc-xxxx.md Outdated
Comment thread ERCS/erc-xxxx.md Outdated
title: On-Chain Registry for ERC-7730 Clear Signing Descriptors
description: An open on-chain protocol-agnostic registry for ERC-7730 descriptors with EAS-backed attestations
author: Alex Forshtat (@forshtat)
discussions-to: https://ethereum-magicians.org/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please create a discussions topic on Eth Magicians linking to this PR

Comment thread ERCS/erc-xxxx.md Outdated
Co-authored-by: Andrew B Coathup <28278242+abcoathup@users.noreply.github.com>
Co-authored-by: Alex Forshtat <forshtat1@gmail.com>
@eip-review-bot eip-review-bot changed the title Add ERC: On-Chain Registry for ERC-7730 Clear Signing Descriptors Add ERC: Clear signing descriptors onchain registry Jun 5, 2026
@PatrickAlphaC

Copy link
Copy Markdown

Have you seen my proposal here?

ethereum/clear-signing-erc7730-registry#2577

If the schema updates, it's a lot of work to update these contracts too.

@forshtat

Copy link
Copy Markdown
Contributor Author

Have you seen my proposal here?

ethereum/clear-signing-erc7730-registry#2577

If the schema updates, it's a lot of work to update these contracts too.

Hello @PatrickAlphaC !

Yes, I have looked at this proposal briefly, and as far as I understand the release process outlined in it I would say these two proposals are complimentary.
As long as the clear signing descriptors schema is not final, and the entire clear signing registry may require an in-place update, using a fully on-chain registry is indeed not feasible.
But once the ERC-7730 is final, and implemented in various cold storage hardware wallets around the world, I can see a strong argument in favour of moving from a multisig-controlled ENS resolver to a fully permissionless on-chain registry over time.

Will be happy to discuss these proposals in more detail!

forshtat and others added 4 commits June 12, 2026 08:34
…cleanup, ERC-8176 alignment

Specification and reference implementation fixes:

* Require an EIP-712 registration signature binding contextIds and
  mirrorListId to the attester when a registration is relayed by a third
  party. Prevents front-running an attester's EAS delegated attestation
  to register it under attacker-chosen context IDs or mirror lists.
  Replay protection comes from binding the signed struct to the
  single-use EAS attestation signature, with no extra nonce state.
  Verified via ECDSA for EOAs and ERC-1271 for contract attesters;
  skipped when the attester submits the transaction directly.

* Add permissionless clearRevokedEndorsements(attesters[], contextIds[][])
  to remove slots whose backing attestation was revoked or expired
  directly on EAS. Skips still-valid and empty slots instead of
  reverting so a multi-attester watchdog sweep cannot be blocked by a
  slot changing state in flight; returns the number of cleared slots.

* Require the active attestation to be revocable; an irrevocable one
  would permanently freeze its slots since replacement demands
  revocation. Require the attested data to be exactly 32 bytes.

* Enforce the displaced-UID revocation check even when the revocations
  batch is empty; previously an active slot could be silently replaced
  without revoking the prior attestation.

* Rename descriptorId to descriptorHash and define it by reference to
  the ERC-8176 hash computation (includes-resolved, RFC 8785/JCS
  canonicalized), replacing the contradictory raw-file-bytes wording.
  Wallets verify retrieved descriptors by recomputing this hash.

* Fix the EIP-712 domain-separator context tag string diverging between
  the spec (domainseparator) and the implementation (domain-separator),
  which would have produced disjoint context IDs.

* Align spec text with implementation behavior (revoke-then-attest
  order), remove stale updateMirrorList reference, add normative wallet
  requirements to verify attestation revocation and expiry per
  ERC-8176, and add 1271 to required EIPs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add resolveDescriptors(attesters[], contextIds[]) as the primary
wallet-facing entry point. For every non-empty (attester, contextId)
slot it returns the descriptor hash, the backing attestation UID with
its expiration and revocation times read from EAS in the same call,
and the attester's MirrorList contents. A wallet derives its candidate
context IDs locally (contract key for calldata transactions, deployment
and domain-separator keys for EIP-712 messages, factory keys for
factories it supports) and completes the entire on-chain lookup in a
single eth_call instead of three to five sequential ones.

Remove getMirrorList(attester, descriptorHash): wallets get mirror data
from resolveDescriptors, and indexers get it from MirrorListUpdated
events combined with getMirrorListById. getDescriptors stays as the
lightweight raw-slot primitive for on-chain callers, and
getMirrorListById stays as the only standalone reader of published
MirrorList contents, since MirrorListPublished only emits the ID.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Document the approximate cost structure of populating the registry:
~400-450k gas per descriptor (dominated by the EAS attestation and the
one-time MirrorList storage) plus ~50k per context ID, with a round
reference point of 10,000 descriptors at two deployments each costing
on the order of 5 billion gas (~50 ETH at 10 gwei). Notes the three
properties that keep the cost manageable: one-time bootstrap with
incremental re-attestation, idempotent MirrorList sharing saving
subsequent attesters roughly a third, and linear scaling. Explicitly
framed as order-of-magnitude estimates without enshrining current
registry sizes or market prices.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The markdown-no-backticks rule rejects EIP/ERC number patterns inside
backticks, which the full asset paths in link texts triggered. Use the
bare file names as link text instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions github-actions Bot added w-ci and removed w-ci labels Jun 12, 2026
forshtat and others added 2 commits June 12, 2026 09:43
…ual-flow MirrorLists

Reduce per-descriptor registration gas by roughly 20% and improve
attester operations:

* Store only the EAS attestation UID per (attester, contextId) slot.
  The endorsed descriptor hash is already carried in the attestation's
  data, verified at registration time, and is read from EAS when
  queried, so it is never duplicated in registry storage. Saves one
  storage slot per context ID and removes a consistency invariant.
  The AttesterEndorsementUpdated event now carries the previous
  attestation UID, linking the supersession chain for indexers.

* Replace the single-descriptor write function with a batched
  createDescriptorAttestations(DescriptorRegistration[], ...) call:
  attestations[0].data[i] is the active attestation for
  registrations[i], one merged EAS call covers the whole batch, and a
  single EIP-712 registration signature (nested
  ClearSigningRegistrationBatch struct) authorizes the entire release,
  reducing a multisig attester's signing ceremonies to one per release.
  Replay protection is unchanged: the batch is bound to the single-use
  EAS delegated attestation signatures.

* Support two MirrorList flows per registration. Reference flow: a
  non-zero mirrorListId points to a list published by anyone via the
  batched publishMirrorLists, keeping mirror operation a separate role
  from attestation. Inline flow: mirrorListUris are published
  idempotently within the registration with mirrorListId required to be
  zero, making a first registration a single transaction. The
  registration signature always covers the effective MirrorList ID,
  which is safe because published lists are immutable and
  content-addressed.

* Update the Rationale gas estimates to the new cost structure
  (~350-400k gas per descriptor plus ~25k per context ID; the 10,000
  descriptor reference point drops to ~4 billion gas, about 40 ETH at
  10 gwei).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
forshtat and others added 4 commits July 11, 2026 11:15
The motivation entry now states the interoperability problem instead of
describing the set mechanics. The expiration rationale no longer claims
revocation is freshness-independent: a stale state view hides a recent
revocation like any other registry update; the honest argument is that
revocation adds no trust input beyond the state view wallets need anyway,
while expiration needs a clock the target devices do not have.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Drop sentences duplicated in the Specification or the interface file:
error-name revert bookkeeping, restated MirrorList properties, gas
complexity analysis, and rhetorical summaries. Also remove a dangling
cross-reference to a nonexistent ENS recommendation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Drop restatements of the data model comments, duplicate wallet
verification requirements, event and nonce bookkeeping visible in the
reference implementation, and cross-reference navigation notes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
forshtat and others added 4 commits August 10, 2026 23:27
Adds deriveFactoryContextKeyId, deriveEip712DeploymentContextKeyId, and
deriveDomainSeparatorContextKeyId plus a worked register/resolve example,
since the walkthrough previously only covered contract.deployments even
though the registry supports all four ERC-7730 context binding types.
Also fixes leftover chainId/vaultContractAddress references left over
from the contextId -> contextKeyId rename.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1. The 'schemaMajor' and 'formatId' names are confusing.
Renamed to "descriptorSchemaMajor" and "attestationFormatId".

2. The 'attestationFormatId' but only EAS is declared.
Provied an example ML-DSA based signature (artificial example).

3. There is no need to create atomic flows inside the registry.
Removed 'revocations' and 'MirrorListRefs' from the registration flow.
Atomicity can be achieved with externally batching the transactions.

4. Improve the README.md, provide examples for factory-based contexts.
forshtat and others added 5 commits September 22, 2026 23:20
… repo

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The external GitHub link and its erc7730-containing link text tripped
markdown-rel-links and markdown-re-erc-dash. Switched to a plain,
non-linked mention.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions github-actions Bot removed the w-ci label Sep 22, 2026
@github-actions

Copy link
Copy Markdown

The commit 6ed9f3b (as a parent of 75a4342) contains errors.
Please inspect the Run Summary for details.

@github-actions github-actions Bot added the w-ci label Sep 22, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants