LinkedResolver Proof-of-Concept

The key idea is that the contract and the namespace program can be anything.

  • It can be a ERC-721, ERC-1155, or something custom.
  • It could link from label to labelhash to namespace (Rental example)
  • It could link from label to integer to namespace (eg. 10K collection)
  • It could link from label to “claimed name” using a separate claiming mechanism that associates “claimed name” with namespace, where only the owner of a 1
    • I have Good Morning Cafe #331
    • As owner of 331, I can claim "raffy" (eg. 331 → raffy)
    • As owner of 331, I can set namespace to X
    • raffy.[gmcafe.eth] → ns = X
  • It could link to something unrelated to a token, like another contract, maybe a directory of ERC-20s?
  • It could associate ENS names to an existing NFT

The namespace program can also execute logic. In the Rental example, the rental mechanism is solely defined on L2 yet enforced on L1.

  • any rental logic you want
  • any pricing logic you want
  • any minting logic you want
  • you could make a name resolve randomly
  • you could make a name resolve different based on time
  • anything!

Advanced Features

Any feature added to the LinkedResolver is shared by all users of this protocol.

The LinkedResolver implements the following new features:

  1. EVM Fallback Address — coinType = 0x80000000 is considered the universal EVM address. If this address is set and you query a nonexistant EVM coinType like addr(60) or addr(8453), it will automatically fallback to the universal address.

  2. LastModifiedResolver — given any record like addr(60), text(avatar), contenthash() you can query lastMod(record) and get the timestamp when that record was last changed.

  3. Consolidated Storage Keys — all records are translated into universal key format. This massively simplifies the complexity of LinkedResolver and Namespace contracts as all lookups are just bytes → bytes.

  4. Hashed Storage — regardless of how large of data you store in the Namespace, the value can be efficiently proven crosschain because it first proves the hash of the value, and then is supplied the value unproven (instead of storage proofs), and then the hash is verified.

  5. Gasless Expiration — if the namespace program returns an invalid namespace, the name doesn’t resolve

Simplest example: Link an ENS name to a Namespace

  1. Get an ENS name on Sepolia, unwrap it (no NameWrapper support yet), and set the resolver to LinkedResolver (0x084462610A20eFbDB686b30fe587ecA0E234D2EF)
  2. create() a Namespace on Base
  3. setLink() on LinkedResolver to your namespace, formatted as uint256 in hex
    • ns = 10 → 0x000000000000000000000000000000000000000000000000000000000000000A
  4. Resolve your name!

Note: The LinkedResolver demo on Sepolia is using a TrustedVerifier that talks to my server, which is connected to Base. My server is signing the stateRoots such that modifications on Base are visible within a minute. The LinkedResolver can be deployed with any verifier w/o modification. A production deployment for Base would rely on Base’s Rollup (via OPFaultVerifier) and have a finalization delay (minimum of 1.75 days). Other rollups have different finalization periods, some significantly shorter than optimistic fault proofs.

image

1 Like