Testnet deployment addresses (Holesky and Sepolia)

I just deployed the ENS contracts to Holesky. Since Goerli is being deprecated, going forward we will only be deploying testnet contracts to Holesky and Sepolia. I’ve listed the testnet addresses below, but if these break, please check directly in the ens-contracts repo for the latest deployments. You can also check the docs here: Deployments | ENS Docs

Discovery mechanisms

It is recommended to use these discovery mechanisms within your app to avoid using the wrong contract as and when contracts are being upgraded. If you are directly using an address for an upgradeable, expect it to break in the future.

As usual these contracts can be discovered using ENS directly:

  • NameWrapper - ens.resolver(namehash('eth')).interfaceImplementer('0x019a38fe')
  • .eth Registrar Controller - ens.resolver(namehash('eth')).interfaceImplementer('0x612e8c09')
  • BaseRegistrar - ens.owner(namehash('eth'))
  • Reverse Registrar - ens.owner(namehash('addr.reverse'))
  • Public Resolver (mainnet) - ens.resolver(namehash('resolver.ens.eth')).addr()
  • Public Resolver (testnets) - ens.resolver(namehash('resolver.eth')).addr()

Main addresses

Below are the main ENS contracts. If you need some of the internal contracts, you can directly check the ens-contracts repo to see the latest deployments in the deployments folder

Holesky Updated: 27/1/24

  • ENSRegistry: 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
  • BaseRegistrarImplementation: 0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85
  • ETHRegistrarController: 0x179Be112b24Ad4cFC392eF8924DfA08C20Ad8583
  • PublicResolver: 0x9010A27463717360cAD99CEA8bD39b8705CCA238
  • NameWrapper: 0xab50971078225D365994dc1Edcb9b7FD72Bb4862
  • UniversalResolver: 0x2548a7E09deE955c4d97688dcB6C5b24085725f5
  • ReverseRegistrar: 0x132AC0B116a73add4225029D1951A9A707Ef673f

Sepolia Updated: 27/1/24

  • ENSRegistry: 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
  • BaseRegistrarImplementation: 0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85
  • ETHRegistrarController: 0xFED6a969AaA60E4961FCD3EBF1A2e8913ac65B72
  • PublicResolver: 0x8FADE66B79cC9f707aB26799354482EB93a5B7dD
  • NameWrapper: 0x0635513f179D50A207757E05759CbD106d7dFcE8
  • UniversalResolver: 0xBaBC7678D7A63104f1658c11D6AE9A21cdA09725
  • ReverseRegistrar: 0xA0a1AbcDAe1a2a4A2EF8e9113Ff0e02DD81DC0C6

Mainnet Updated 27/1/24

  • ENSRegistry: 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
  • BaseRegistrarImplementation: 0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85
  • ETHRegistrarController: 0x253553366Da8546fC250F225fe3d25d0C782303b
  • PublicResolver: 0x231b0Ee14048e9dCcD1d247744d114a4EB5E8E63
  • NameWrapper: 0xD4416b13d2b3a9aBae7AcD5D6C2BbDBE25686401
  • UniversalResolver: 0x8cab227b1162f03b8338331adaad7aadc83b895e
  • ReverseRegistrar: 0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb

For anyone interested in the derivation of those interface IDs:

  • NameWrapper 0x019a38fe
	"function allFusesBurned(bytes32 node, uint32 fuseMask) view returns (bool)",
	"function approve(address to, uint256 tokenId)",
	"function balanceOf(address account, uint256 id) view returns (uint256)",
	"function balanceOfBatch(address[] accounts, uint256[] ids) view returns (uint256[])",
	"function canModifyName(bytes32 node, address addr) view returns (bool)",
	"function ens() view returns (address)",
	"function extendExpiry(bytes32 node, bytes32 labelhash, uint64 expiry) returns (uint64)",
	"function getApproved(uint256 tokenId) view returns (address)",
	"function getData(uint256 id) view returns (address, uint32, uint64)",
	"function isApprovedForAll(address account, address operator) view returns (bool)",
	"function isWrapped(bytes32, bytes32) view returns (bool)",
	"function isWrapped(bytes32) view returns (bool)",
	"function metadataService() view returns (address)",
	"function name() view returns (string)",
	"function names(bytes32) view returns (bytes)",
	"function ownerOf(uint256 id) view returns (address owner)",
	"function registerAndWrapETH2LD(string label, address wrappedOwner, uint256 duration, address resolver, uint16 ownerControlledFuses) returns (uint256 registrarExpiry)",
	"function registrar() view returns (address)",
	"function renew(uint256 labelHash, uint256 duration) returns (uint256 expires)",
	"function safeBatchTransferFrom(address from, address to, uint256[] ids, uint256[] amounts, bytes data)",
	"function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes data)",
	"function setApprovalForAll(address operator, bool approved)",
	"function setChildFuses(bytes32 parentNode, bytes32 labelhash, uint32 fuses, uint64 expiry)",
	"function setFuses(bytes32 node, uint16 ownerControlledFuses) returns (uint32 newFuses)",
	"function setMetadataService(address _metadataService)",
	"function setRecord(bytes32 node, address owner, address resolver, uint64 ttl)",
	"function setResolver(bytes32 node, address resolver)",
	"function setSubnodeOwner(bytes32 node, string label, address newOwner, uint32 fuses, uint64 expiry) returns (bytes32)",
	"function setSubnodeRecord(bytes32 node, string label, address owner, address resolver, uint64 ttl, uint32 fuses, uint64 expiry) returns (bytes32)",
	"function setTTL(bytes32 node, uint64 ttl)",
	"function setUpgradeContract(address _upgradeAddress)",
	"function supportsInterface(bytes4 interfaceID) view returns (bool)",
	"function unwrap(bytes32 node, bytes32 label, address owner)",
	"function unwrapETH2LD(bytes32 label, address newRegistrant, address newController)",
	"function upgrade(bytes name, bytes extraData)",
	"function upgradeContract() view returns (address)",
	"function uri(uint256 tokenId) view returns (string)",
	"function wrap(bytes name, address wrappedOwner, address resolver)",
	"function wrapETH2LD(string label, address wrappedOwner, uint16 ownerControlledFuses, address resolver) returns (uint64 expires)"


  • ETH Registrar Controller 0x612e8c09
	"function available(string) view returns (bool)",
	"function commit(bytes32)",
	"function makeCommitment(string, address, uint256, bytes32, address, bytes[], bool, uint16) pure returns (bytes32)",
	"function register(string, address, uint256, bytes32, address, bytes[], bool, uint16) payable",
	"function renew(string, uint256) payable",
	"function rentPrice(string, uint256) view returns (tuple(uint256, uint256))"


@jefflau.eth Thanks for deploying these. Can you take a look at this Sepolia/Holesky - public resolver namehash for "resolver.eth" not set on ENS registry TL:DR ens.resolver(namehash('resolver.eth')).addr() is not set on sepolia/holesky registries

1 Like

Hi three9s,

Thanks for bringing this up. Unfortunately we didn’t add these to our deploy scripts, so currently on Sepolia resolver.eth is owned by someone else. If the owner does read this, please transfer it to us here: 0x0f32b753afc8abad9ca6fe589f707755f4df2353.

I set resolver.eth on Holesky to the public resolver.


We own resolver.eth on Sepolia. Raffy pinged us today. Fixing this. @artii


Thanks cap!

1 Like

Would be good to update the docs with this information: I’m at a hackathon where they asked me about it and the only source of info which was not 3 years old was this forum post:

1 Like