Skip to content

Add "default" chain id 0 to ENSIP-11#32

Closed
stevieraykatz wants to merge 3 commits into
ensdomains:masterfrom
stevieraykatz:ensip-11-revision
Closed

Add "default" chain id 0 to ENSIP-11#32
stevieraykatz wants to merge 3 commits into
ensdomains:masterfrom
stevieraykatz:ensip-11-revision

Conversation

@stevieraykatz
Copy link
Copy Markdown
Contributor

The idea to use chain id 0 to represent a "default" ENSIP-11 was initially proposed in this complete ENSIP draft: #7.

This revision to ENSIP-11 attempts to make the spec more lightweight and land it where it is most relevant. At its core, this spec introduces:

  1. The chain id 0 which represents all EVM-compatible chains. This identification has precedence given CAIP-10.
  2. An added step to ENSIP-11 resolution requests which requires checking the existence of a default address if a chain-specific request does not return an address.

@adraffy
Copy link
Copy Markdown
Member

adraffy commented May 9, 2025

If we're editing, I think:

export const convertCoinTypeToEVMChainId = (coinType: number) =>{
  return  (0x7fffffff & coinType) >> 0
}

Should be:

export function convertCoinTypeToEVMChainId(coinType: bigint): number {
  const EVM_BIT = 0x8000_0000n;
  if (coinType == 60n) return 1;
  return coinType == BigInt.asUintN(32, coinType) && coinType & EVM_BIT ? Number(coinType ^ EVM_BIT)  : 0;
}

convertCoinTypeToEVMChainId(            0) = 0
convertCoinTypeToEVMChainId(            1) = 0
convertCoinTypeToEVMChainId(  0x8000_0000) = 0
convertCoinTypeToEVMChainId(           60) = 1
convertCoinTypeToEVMChainId(  0x8000_0001) = 1
convertCoinTypeToEVMChainId(  0x8000_2105) = 8453
convertCoinTypeToEVMChainId(0x1_8000_2105) = 0

https://github.com/ensdomains/ens-contracts/blob/staging/test/fixtures/ensip19.ts#L6-L11
https://github.com/ensdomains/ens-contracts/blob/staging/contracts/utils/ENSIP19.sol#L15-L28

@adraffy
Copy link
Copy Markdown
Member

adraffy commented May 12, 2025

Greg and I were internally talking about this:

The resolution process remains as normal with an additional step. If the initial resolution request does not yield an address, now an extra lookup shall be implemented to check for the existence of an address against the EOA chain ID.

I think this is the expected behavior now that we have a purpose for chain 0 but who is responsible? As written, I think this is part of the client resolution protocol but it's not explicit.

If it's part of the resolver logic, it would require full redeployment since revolvers are consulted directly and don't implement the fallback, however there is prior art for putting address logic in the resolver: addr() = addr(60).

The UR could implement this logic, but then clients can't tell if addr(<evm coinType>) is set when addr(EVM_BIT) exists. On the flip side, this would remove the special case on UR.reverse() since the forward check would fallback automatically.

The UR could support a fake profile, like rawaddr(coinType) which does addr() w/o the fallback, but that's weird.

@stevieraykatz
Copy link
Copy Markdown
Contributor Author

The UR could implement this logic, but then clients can't tell if addr() is set when addr(EVM_BIT) exists.

Why do clients need to care about which address is returned? IMO, the client is just trying to complete a resolution request and doesn't need to be context-aware under the hood.

I think this is the expected behavior now that we have a purpose for chain 0 but who is responsible? As written, I think this is part of the client resolution protocol but it's not explicit.

If it's part of the resolver logic, it would require full redeployment since revolvers are consulted directly and don't implement the fallback, however there is prior art for putting address logic in the resolver: addr() = addr(60).

Re: clients vs resolvers: i think that this should be implemented at first as a client spec. However, per my point above, if eventually resolvers implement the logic, then the clients will have less work to do. As a phased approach, this makes the most sense to me: start with client implementation and eventually resolvers new resolvers can do the lifting.

@Arachnid
Copy link
Copy Markdown
Member

Arachnid commented May 28, 2025

I think the fallback logic here needs to be in the resolver just as it is for cointype 60, meaning a new resolver implementation and deployment will be required.

We definitely don't want to force clients to implement it and then also force resolvers to implement it. If we went with the former it should be included in the universal resolver permanently.

@stevieraykatz stevieraykatz marked this pull request as ready for review June 5, 2025 15:21
@stevieraykatz
Copy link
Copy Markdown
Contributor Author

This has been added to the ENSIP-19 text. Closing

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants