eth.rb icon indicating copy to clipboard operation
eth.rb copied to clipboard

eth/client: support resolving ENS domains

Open mculp opened this issue 4 years ago • 13 comments

I think this may tie or interfere with the implementation of #72 also.

mculp avatar Apr 16 '22 09:04 mculp

An ::EnsResolver could be part of the client. Once you instantiate a client, it should have the ability to resolve ::Ens to ::Address

q9f avatar Apr 16 '22 15:04 q9f

That would be great!

arenzel avatar May 02 '22 15:05 arenzel

NameHash: https://docs.ens.domains/contract-api-reference/name-processing

Resolver: https://docs.ens.domains/dapp-developer-guide/resolving-names

q9f avatar May 06 '22 13:05 q9f

same address on all networks: 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e

https://etherscan.io/address/0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e#readContract

q9f avatar May 06 '22 17:05 q9f

I'll work on this next

mculp avatar May 11 '22 06:05 mculp

Working on this now.

mculp avatar Aug 06 '22 01:08 mculp

@mculp / @q9f I was looking for this as well, and started this here: https://github.com/withfabricxyz/eth.rb/commit/7194b7e4a3af6f4bb2b1578bb410390697aafac3

The biggest issue is in normalizing the domain. The ICU libraries for ruby don't seem to do exactly what is needed. This will work for basic names, but it's not properly encoding tokens with Cyrillic characters, etc. I tried a few libraries, which generate puny code symbols, but that isn't quite enough. See: https://github.com/jcranmer/idna-uts46 , which is used by https://github.com/ensdomains/eth-ens-namehash/blob/master/index.js#L26

dansimpson avatar Aug 25 '22 19:08 dansimpson

Thank you, Dan.

I would love to consider accepting this for now. Some thoughts:

  • adding a test case to resolve a name on mainnet (we can set an INFURA_ID in CI)
  • maybe renaming Eth::Ens::Resolver::DEFAULT_ADDRESS to Eth::Ens::DEFAULT_REGISTRY or something meaningul in the ::Ens namespace
  • We already deploy the registry to our test chain, maybe we can try to set a name and resolve it straight away? https://github.com/q9f/eth.rb/blob/main/spec/eth/client_spec.rb#L107-L113

In general, we can split this up in multiple PRs if you want to only submit the resolver for now and look into the encoding issues later, I'd be happy to review it.

q9f avatar Sep 26 '22 13:09 q9f

@dansimpson The encoding issue was the issue I ran into as well when trying to work on this. I was trying to follow the ENS spec to the T and couldn't seem to find a library that correctly encoded all names.

Thanks for doing this

mculp avatar Sep 26 '22 17:09 mculp

@dansimpson FYI this is the recursive namehash implementation that I had. I ported it from the python reference implementation.

      def namehash(name)
        if name.empty?
          "\0" * 32
        else
          label, _, remainder = name.partition('.')
          Eth::Util.keccak256(namehash(remainder) + Eth::Util.keccak256(label))
        end
      end

mculp avatar Sep 27 '22 04:09 mculp

@dansimpson If you open a PR, I have a couple pretty minor comments I'd like to make on your changes.

mculp avatar Sep 27 '22 04:09 mculp

@mculp

  def namehash(name)
    if name.empty?
      Eth::Util.prefix_hex("00"*32)
    else
      label, _, remainder = name.partition('.')
      Eth::Util.prefix_hex(
        sha3(Eth::Util.hex_to_bin(namehash(remainder) + sha3(label)))
      )
    end
  end  
  def sha3 str
    Eth::Util.bin_to_hex(Eth::Util.keccak256(str))
  end  
  def labelhash label
    Eth::Util.prefix_hex Eth::Util.bin_to_hex(Eth::Util.keccak256(label))
  end

musik avatar Sep 28 '22 06:09 musik

@musik yeah, once this gets merged these conversions should be easier

mculp avatar Sep 29 '22 00:09 mculp

#150

#192

infura = Eth::Client.create("https://mainnet.infura.io/v3/#{ENV['INFURA_TOKEN']}")
# => #<Eth::Client::Http:0x00005614b684fd70
infura.resolve_ens "ncwc6edqldzy6mlo.eth"
# => "0xde270e46d63b1816d1b798cff473c4ba238aca73"

q9f avatar Dec 28 '22 18:12 q9f

https://github.com/q9f/eth.rb/wiki/ENS-Resolver

q9f avatar Jan 02 '23 16:01 q9f