Skip to content

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 NamespaceName in the ENS registry
Default (Ethereum)reverse
Ethereumaddr.reverse
Arbitrum8000a4b1.reverse
Base80002105.reverse
Linea8000e708.reverse
Optimism8000000a.reverse
Scroll80082750.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

ChainAddress
Default (Ethereum)0x283F227c4Bd38ecE252C4Ae7ECE650B0e913f1f9
Ethereum0xa58E81fe9b61B5c3fE2AFD33CF304c454AbFc7Cb
Arbitrum One0x0000000000D8e504002cC26E3Ec46D81971C1664
Base0x0000000000D8e504002cC26E3Ec46D81971C1664
Linea0x0000000000D8e504002cC26E3Ec46D81971C1664
Optimism0x0000000000D8e504002cC26E3Ec46D81971C1664
Scroll0x0000000000D8e504002cC26E3Ec46D81971C1664

Testnet Deployments

L2 Testnet ChainAddress
Default (Ethereum)0x4F382928805ba0e23B30cFB75fC9E848e82DFD47
Ethereum0xA0a1AbcDAe1a2a4A2EF8e9113Ff0e02DD81DC0C6
Arbitrum Sepolia0x00000BeEF055f7934784D6d81b6BC86665630dbA
Base Sepolia0x00000BeEF055f7934784D6d81b6BC86665630dbA
Linea Sepolia0x00000BeEF055f7934784D6d81b6BC86665630dbA
Optimism0x00000BeEF055f7934784D6d81b6BC86665630dbA
Scroll Sepolia0x00000BeEF055f7934784D6d81b6BC86665630dbA

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 to resolver; 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.