Ens multichain support (#2304)

* 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
This commit is contained in:
Nick Johnson 2019-10-02 10:16:38 +10:00 committed by GitHub
parent d3d730fbf3
commit e10d542fde
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 129 additions and 0 deletions

129
EIPS/eip-2304.md Normal file
View File

@ -0,0 +1,129 @@
---
eip: 2304
title: Multichain address resolution for ENS
author: Nick Johnson <nick@ens.domains>
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/).