forked from ethereum/EIPs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ens multichain support (ethereum#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
- Loading branch information
Showing
1 changed file
with
129 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/). |