Skip to content

Commit

Permalink
Ens multichain support (ethereum#2304)
Browse files Browse the repository at this point in the history
* First draft for ENS multicoin support

* Rewrite multicoin support to use maps

* Tweaks and fixes

* Update and rename eip-draft-ens-multicoin.md to eip-2304.md
  • Loading branch information
Arachnid authored Oct 2, 2019
1 parent d3d730f commit e10d542
Showing 1 changed file with 129 additions and 0 deletions.
129 changes: 129 additions & 0 deletions EIPS/eip-2304.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
eip: 2304
title: Multichain address resolution for ENS
author: Nick Johnson <[email protected]>
type: Standards Track
category: ERC
status: Draft
created: 2019-09-09
discussions-to: https://discuss.ens.domains/t/new-standard-proposal-ens-multicoin-support/1148
requires: 137
---

## Abstract

This EIP introduces the `address` field for ENS resolvers, which permits resolution of addresses for other blockchains via ENS.

## Motivation

With the increasing uptake of ENS by multi-coin wallets, wallet authors have requested the ability to resolve addresses for non-Ethereum chains inside ENS. This specification standardises a way to enter and retrieve these addresses in a cross-client fashion.

## Specification

A new accessor function for resolvers is specified:

```
function addr(bytes32 node, uint coinType) external view returns(bytes memory);
```

The EIP165 interface ID for this function is 0xf1cb7e06.

When called on a resolver, this function must return the cryptocurrency address for the specified namehash and coin type. A zero-length string must be returned if the specified coin ID does not exist on the specified node.

`coinType` is the cryptocurrency coin type index from [SLIP44](https://github.com/satoshilabs/slips/blob/master/slip-0044.md).

The return value is the cryptocurency address in binary format. For example, the Bitcoin address `1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa` is base58-decoded and stored as the 25 bytes `0x0062e907b15cbf27d5425399ebf6f0fb50ebb88f18c29b7d93`, while the Ethereum address `0x314159265dd8dbb310642f98f50c066173c1259b` is hex-decoded and stored as the 20 bytes `0x314159265dd8dbb310642f98f50c066173c1259b`. In general, the native binary representation of the address should be used.


A new event for resolvers is defined:

```
event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress);
```

Resolvers MUST emit this event on each change to the address for a name and coin type.

### Recommended accessor functions

The following function provides the recommended interface for changing the addresses stored for a node. Resolvers SHOULD implement this interface for setting addresses unless their needs dictate a different interface.

```
function setAddr(bytes32 node, uint coinType, bytes calldata addr);
```

`setAddr` adds or replaces the address for the given node and coin type. The parameters for this function are as per those described in `addr()` above.

This function emits an `AddressChanged` event with the new address; see also the backwards compatibility section below for resolvers that also support `addr(bytes32)`.

### Example

An example implementation of a resolver that supports this EIP is provided here:

```
pragma solidity ^0.5.8;
contract AddrResolver is ResolverBase {
bytes4 constant private ADDR_INTERFACE_ID = 0x3b3b57de;
bytes4 constant private ADDRESS_INTERFACE_ID = 0xf1cb7e06;
uint constant private COIN_TYPE_ETH = 60;
event AddrChanged(bytes32 indexed node, address a);
event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress);
mapping(bytes32=>mapping(uint=>bytes)) _addresses;
/**
* Sets the address associated with an ENS node.
* May only be called by the owner of that node in the ENS registry.
* @param node The node to update.
* @param a The address to set.
*/
function setAddr(bytes32 node, address a) external authorised(node) {
setAddr(node, COIN_TYPE_ETH, addressToBytes(a));
}
/**
* Returns the address associated with an ENS node.
* @param node The ENS node to query.
* @return The associated address.
*/
function addr(bytes32 node) public view returns (address) {
bytes memory a = addr(node, COIN_TYPE_ETH);
if(a.length == 0) {
return address(0);
}
return bytesToAddress(a);
}
function setAddr(bytes32 node, uint coinType, bytes memory a) public authorised(node) {
emit AddressChanged(node, coinType, a);
if(coinType == COIN_TYPE_ETH) {
emit AddrChanged(node, bytesToAddress(a));
}
_addresses[node][coinType] = a;
}
function addr(bytes32 node, uint coinType) public view returns(bytes memory) {
return _addresses[node][coinType];
}
function supportsInterface(bytes4 interfaceID) public pure returns(bool) {
return interfaceID == ADDR_INTERFACE_ID || interfaceID == ADDRESS_INTERFACE_ID || super.supportsInterface(interfaceID);
}
}
```

### Implementation

An implementation of this interface is provided in the [ensdomains/resolvers](https://github.com/ensdomains/resolvers/) repository.

## Backwards Compatibility

If the resolver supports the `addr(bytes32)` interface defined in EIP137, the resolver MUST treat this as a special case of this new specification in the following ways:

1. The value returned by `addr(node)` from EIP137 should always match the value returned by `addr(node, 60)` (60 is the coin type ID for Ethereum).
2. Anything that causes the `AddrChanged` event from EIP137 to be emitted must also emit an `AddressChanged` event from this EIP, with the `coinType` specified as 60, and vice-versa.

## Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).

0 comments on commit e10d542

Please sign in to comment.