Reverse Registrars
Reverse resolution is the process of mapping an EVM address (eg, 0x1234...5678
) to an ENS name on a number of different chains. This is accomplished by using special namespaces in the ENS registry:
Reverse Namespace | Name in the ENS registry |
---|---|
Default (Ethereum) | reverse |
Ethereum | addr.reverse |
Arbitrum | 8000a4b1.reverse |
Base | 80002105.reverse |
Linea | 8000e708.reverse |
Optimism | 8000000a.reverse |
Scroll | 80082750.reverse |
L2 namespaces are derived via [coinTypeAsHex].reverse
as specified in ENSIP-19, and users' reverse records can be resolved via [address].[reverseNamespace]
.
For example, the account 0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5
can claim b8c2c29ee19d8307cb7255e1cd9cbde883a267d5.addr.reverse
in the ENS registry. After doing so, it can configure a resolver and expose metadata, such as a canonical ENS name for this address.
The reverse registrar provides functions to claim
a reverse record,
as well as a convenience function (setName
) to configure the record as it's most commonly used, as a way of specifying a canonical name for an address.
Supported Chains
Reverse Registrars are deployed on Ethereum Mainnet (L1) and popular L2s (Base, OP Mainnet, Arbitrum One, Scroll, and Linea). This enables users to set a chain-specific reverse record while also supporting a default reverse record on L1 that acts as a fallback when a chain-specific record is not set.
In practice, it's strongly recommended to not hardcode the reverse registrar addresses because they can change in the future and unexpectedly break your application. Instead, resolve them according to ENSIP-19.
For convenience, the latest deployments of the reverse registrars are listed below.
Mainnet Deployments
Testnet Deployments
L2 Testnet Chain | Address |
---|---|
Default (Ethereum) | 0x4F382928805ba0e23B30cFB75fC9E848e82DFD47 |
Ethereum | 0xA0a1AbcDAe1a2a4A2EF8e9113Ff0e02DD81DC0C6 |
Arbitrum Sepolia | 0x00000BeEF055f7934784D6d81b6BC86665630dbA |
Base Sepolia | 0x00000BeEF055f7934784D6d81b6BC86665630dbA |
Linea Sepolia | 0x00000BeEF055f7934784D6d81b6BC86665630dbA |
Optimism | 0x00000BeEF055f7934784D6d81b6BC86665630dbA |
Scroll Sepolia | 0x00000BeEF055f7934784D6d81b6BC86665630dbA |
Setting Records
The updated Reverse Registrar interface exposes methods to support that make it easier to set a reverse record for an EOA or smart contract:
/// @notice Sets the `name()` record for the reverse ENS record associated with the calling account.
/// @param name The name to set
/// @return The ENS node hash of the reverse record
function setName(string memory name) external returns (bytes32);
/// @notice Sets the `name()` record for the reverse ENS record associated with the addr provided account.
/// Can be used if the addr is a contract that is owned by an SCA.
/// @param addr The address to set the name for
/// @param name The name to set
/// @return The ENS node hash of the reverse record
function setNameForAddr(
address addr,
string memory name
) external returns (bytes32);
/// @notice Sets the `name()` record for the reverse ENS record associated with the contract provided that is owned with `Ownable`.
/// @param contractAddr The address of the contract to set the name for (implementing Ownable)
/// @param owner The owner of the contract (via Ownable)
/// @param name The name to set
/// @param coinTypes The coin types to set. Must be inclusive of the coin type for the contract
/// @param signatureExpiry The expiry of the signature
/// @param signature The signature of an address that will return true on isValidSignature for the owner
/// @return The ENS node hash of the reverse record
function setNameForOwnableWithSignature(
address contractAddr,
address owner,
string calldata name,
uint256[] memory coinTypes,
uint256 signatureExpiry,
bytes calldata signature
) external returns (bytes32);
/// @notice Sets the `name()` record for the reverse ENS record associated with the addr provided account using a signature.
/// @param addr The address to set the name for
/// @param name The name of the reverse record
/// @param coinTypes The coin types to set. Must be inclusive of the coin type for the contract
/// @param signatureExpiry Date when the signature expires
/// @param signature The signature from the addr
/// @return The ENS node hash of the reverse record
function setNameForAddrWithSignature(
address addr,
string calldata name,
uint256[] calldata coinTypes,
uint256 signatureExpiry,
bytes calldata signature
) external returns (bytes32);
Signatures
Signature format for setNameForAddrWithSignature
:
validatorAddress, // the address of the reverse registrar
functionSignature, // 0x2023a04c
name, // string name value
addr, // address to set name for
coinTypes, // array of coinTypes wanting to be set
signatureExpiry // expiry of the signature, up to 1 hour in the future
Signature format for setNameForOwnableWithSignature
:
validatorAddress, // the address of the reverse registrar
functionSignature, // 0x975713ad
name, // string name value
contractAddr, // contract address to set name for
owner, // owner address of contract (i.e. the signature being verified)
coinTypes, // array of coinTypes wanting to be set
signatureExpiry // expiry of the signature, up to 1 hour in the future
Other Functions
Claim Address
function claim(address owner) public returns (bytes32);
Claims the caller's address in the reverse registrar, assigning ownership of the reverse record to owner
. Equivalent to calling claimWithResolver(owner, 0)
. Doesn't actually set the reverse record.
function claimWithResolver(address owner, address resolver) public returns (bytes32)
Claims the caller's address in the reverse registrar, assigning ownership
of the reverse record to owner. If resolver
is nonzero, also updates the record's resolver.
After calling this function:
- The reverse record for the caller (1234....addr.reverse) is owned by
owner
. - If
resolver
is nonzero, the reverse record for the caller has its resolver set toresolver
; otherwise it is left unchanged.
Get Default Resolver
function defaultResolver() public view returns (address);
Returns the address of the resolver contract that the ReverseRegistrar
uses for setName
.
Do's and Dont's
Under no situation is it recommended to force a user to change their primary name, nor doing so without clearly notifying the user of what the transaction they are about to execute could modify.
Doing so could be seen as hostile or undesired behaviour by end users and might degrade their experience with your app.