From 9f47fdefd68091c05d23e6eb7d9f8e59e439db15 Mon Sep 17 00:00:00 2001 From: Nick Johnson Date: Mon, 21 Oct 2019 15:03:33 +1300 Subject: [PATCH] Ens multichain (#2317) * Add description and test vectors for different address types; specify bitcoin format as scriptPubkey * Fix table --- EIPS/eip-2304.md | 61 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/EIPS/eip-2304.md b/EIPS/eip-2304.md index ddb993f1e48a30..bffa7f6e1adecc 100644 --- a/EIPS/eip-2304.md +++ b/EIPS/eip-2304.md @@ -12,7 +12,7 @@ requires: 137 ## Abstract -This EIP introduces the `address` field for ENS resolvers, which permits resolution of addresses for other blockchains via ENS. +This EIP introduces new overloads for the the `addr` field for ENS resolvers, which permit resolution of addresses for other blockchains via ENS. ## Motivation @@ -33,8 +33,7 @@ When called on a resolver, this function must return the cryptocurrency address `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 base58check-decoded and stored as the 21 bytes `0x0062e907b15cbf27d5425399ebf6f0fb50ebb88f18`, 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, without any checksum commonly used in the text representation. - +The return value is the cryptocurency address in its native binary format. Detailed descriptions of the binary encodings for several popular chains are provided in the Address Encoding section below. A new event for resolvers is defined: @@ -56,6 +55,51 @@ function setAddr(bytes32 node, uint coinType, bytes calldata addr); This function emits an `AddressChanged` event with the new address; see also the backwards compatibility section below for resolvers that also support `addr(bytes32)`. +### Address Encoding + +In general, the native binary representation of the address should be used, without any checksum commonly used in the text representation. + +A table of encodings for common blockchains is provided, followed by a more detailed description of each format. In the table, 'Format' describes the encoding used to represent the bytes in text format, 'Decoded' describes the result of decoding this format, and 'On ENS' describes how this should be stored in ENS as bytes. + +| Cryptocurrency | Format | Decoded | On ENS | +| --- | --- | --- | --- | +| Ethereum | hex-checksum | `<20 byte hash>` | `<20 byte hash>` | +| Bitcoin | base58check | `0x00 <20 byte hash>` | `0x76a914 <20 byte hash> 0x88ac` | +| Bitcoin | base58check | `0x05 <20 byte hash>` | `0xa914 <20 byte hash> 0x87` | +| Bitcoin | bech32 | ` ` | ` ` | + +#### Ethereum + +To translate a text format Ethereum address into binary format, simply remove the '0x' prefix and hex decode it. `0x314159265dD8dbb310642f98f50C066173C1259b` is hex-decoded and stored as the 20 bytes `314159265dd8dbb310642f98f50c066173c1259b`. + +Before decoding, the [EIP 55](https://eips.ethereum.org/EIPS/eip-55) address checksum must be checked. Addresses with invalid checksums that are not all uppercase or all lowercase MUST be rejected with an error. Implementations may choose whether to accept non-checksummed addresses, but the authors recommend at least providing a warning to users in this situation. + +When encoding an address from binary to text, an [EIP 55](https://eips.ethereum.org/EIPS/eip-55) checksum MUST be used - so the correct encoding of the above address is `0x314159265dD8dbb310642f98f50C066173C1259b`. + +#### Bitcoin + +Bitcoin addresses are encoded as the scriptPubkey for the address. Common Bitcoin addressing formats are encoded and decoded as follows: + +##### P2PKH and P2SH + +Pay to Public Key Hash and Pay To Script Hash addresses are [base58check](https://en.bitcoin.it/wiki/Base58Check_encoding) encoded. After decoding, the first byte is a version byte. For example, the Bitcoin address `1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa` base58check decodes to the 21 bytes `0062e907b15cbf27d5425399ebf6f0fb50ebb88f18`. + +P2PKH addresses have a version byte of 0, followed by a 20 byte pubkey hash. Their scriptPubkey encoding (specified [here](https://en.bitcoin.it/wiki/Transaction#Types_of_Transaction)) is `OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG`. + +The above example address is thus encoded as the 25 bytes `76a91462e907b15cbf27d5425399ebf6f0fb50ebb88f1888ac`. + +P2SH addresses have a version byte of 5, followed by a 20 byte script hash. Their scriptPubkey encoding (specified [here](https://en.bitcoin.it/wiki/Transaction#Pay-to-Script-Hash)) is `OP_HASH160 OP_EQUAL`. A Bitcoin address of `3Ai1JZ8pdJb2ksieUV8FsxSNVJCpoPi8W6` decodes to the 21 bytes `0562e907b15cbf27d5425399ebf6f0fb50ebb88f18` and is encoded as the 23 bytes `a91462e907b15cbf27d5425399ebf6f0fb50ebb88f1887`. + +##### SegWit addresses + +SegWit addresses are encoded with [bech32](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki). Bech32 addresses consist of a human-readable part - 'bc' for Bitcoin mainnet - and a machine readable part. This decodes to a 'witness version', between 0 and 15, and a 'witness program', as defined in [BIP141](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki). + +The scriptPubkey encoding for a bech32 address, as defined in BIP141, is `OP_n`, where `n` is the witness version, followed by a push of the witness program. Note this warning from BIP173: + +> Implementations should take special care when converting the address to a scriptPubkey, where witness version n is stored as OP_n. OP_0 is encoded as 0x00, but OP_1 through OP_16 are encoded as 0x51 though 0x60 (81 to 96 in decimal). If a bech32 address is converted to an incorrect scriptPubKey the result will likely be either unspendable or insecure. + +For example, the SegWit address `BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4` decodes to a version of `0` and a witness script of `751e76e8199196d454941c45d1b3a323f1433bd6`, and then encodes to a scriptPubkey of `0014751e76e8199196d454941c45d1b3a323f1433bd6`. + ### Example An example implementation of a resolver that supports this EIP is provided here: @@ -125,5 +169,16 @@ If the resolver supports the `addr(bytes32)` interface defined in EIP137, the re 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. +## Tests + +The table below specifies test vectors for valid address encodings for each cryptocurrency described above. + +| Cryptocurrency | Text | Onchain (hex) | +| --- | --- | --- | +| Ethereum | `0x314159265dD8dbb310642f98f50C066173C1259b` | `314159265dd8dbb310642f98f50c066173c1259b` | +| Bitcoin | `1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa` | `76a91462e907b15cbf27d5425399ebf6f0fb50ebb88f1888ac` | +| Bitcoin | `3Ai1JZ8pdJb2ksieUV8FsxSNVJCpoPi8W6` | `a91462e907b15cbf27d5425399ebf6f0fb50ebb88f1887` | +| Bitcoin | `BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4` | `0014751e76e8199196d454941c45d1b3a323f1433bd6` | + ## Copyright Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).