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:
-
EVM Fallback Address —
coinType = 0x80000000
is considered the universal EVM address. If this address is set and you query a nonexistant EVM coinType likeaddr(60)
oraddr(8453)
, it will automatically fallback to the universal address. -
LastModifiedResolver — given any record like
addr(60)
,text(avatar)
,contenthash()
you can querylastMod(record)
and get the timestamp when that record was last changed. -
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
. -
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.
-
Gasless Expiration — if the namespace program returns an invalid namespace, the name doesn’t resolve
Simplest example: Link an ENS name to a Namespace
- Get an ENS name on Sepolia, unwrap it (no NameWrapper support yet), and set the resolver to
LinkedResolver
(0x084462610A20eFbDB686b30fe587ecA0E234D2EF
) create()
a Namespace on Base- get
ns
from transaction events - (optional) set some records
- get
setLink()
on LinkedResolver to your namespace, formatted as uint256 in hex- ns = 10 →
0x000000000000000000000000000000000000000000000000000000000000000A
- ns = 10 →
- 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.