Interoperable Addresses is a binary format to describe an address specific to one chain with a companion 'Interoperable Names' specification for human-readable display.
This is achieved through a versioned, length-prefixed binary envelope that supports arbitrary-length data. The interpretation and serialization rules for the data within this envelope are defined by companion standards, which provide profiles for each chain type.
Current Ethereum addresses (ERC-55) lack chain specificity and have optional checksums, creating several challenges:
Interoperable Addresses build on insights from , CAIP-10 and CAIP-50, offering a unified format which combines: - Binding chain specificity (via explicit chain identifiers) to the raw address. - Compact & canonical binary format for use on cross-chain message passing and intent declaration. - Checksums for name collision mitigation & user error prevention.
Furthermore, this proposal adds a few features to make addresses interoperable with infrastructure at the edges of and beyond the ethereum ecosystem, by supporting the representation of addresses of non-evm chains as well, for the benefit of cross-chain liquidity movements and cross-chain message passing.
CAIP-10 proposes a standard text format to represent what in this document is defined as target addresses. Since it's a text-only standard, it does not concern itself with the serialization/deserialization of the various chains' address formats, simply using the text representation of addresses already defined by the respective chains. This means it is trivial to add support for chains to CAIP-10, while doing so with this standard involves defining a serialization scheme.
The above has the drawback of not being able to guarantee canonicity. That is, there could be multiple valid CAIP-10 addresses pointing to the same target address.
Also, the text format is of little use for smart contracts involved with cross-chain liquidity transfers and message passing due to its reduced data efficiency and lack of canonicity.
Interoperable Names are convertible to CAIP-10 without even going through the binary representation, so backwards-compatibility with actors expecting CAIP-10 identifiers should not be an issue.
The interop roadmap is better served by having a standardized binary format for addresses first, which allows the message passing and intents verticals to move forward on a common interface, with a good-enough text representation which is familiar to users and useful for developers, and as a next step develop a chain & address name resolving standard on top of it, leveraging its uniformity and extensibility.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
Interoperable Address : A binary payload which unambiguously identifies a target address and allows conversion to a human-readable name.
Interoperable Name : A string representation of an interoperable address, meant to be used by humans.
Target address : The (address, chain ID) pair a particular Interoperable Address points to.
In binary format, addresses MUST have the following encoding:
┌─────────┬───────────┬──────────────────────┬────────────────┬───────────────┬─────────┐
│ Version │ ChainType │ ChainReferenceLength │ ChainReference │ AddressLength │ Address │
└─────────┴───────────┴──────────────────────┴────────────────┴───────────────┴─────────┘
Where:
Version
: A 2-byte version identifier. For version 1, this must be 0x0001
(big-endian). Future versions SHOULD be standardized in separate ERCs.
ChainType : A 2-byte value as defined in CAIP-350, corresponding to a CAIP-2 namespace, which allows users to know how to interpret & display the other two fields.
ChainReferenceLength : A 1-byte integer encoding the length of ChainReference in bytes. Note that it MAY be zero, in which the Interoperable Address will not include a chain reference.
ChainReference : Variable length, binary representation of CAIP-2 chain namespace & reference serialized as explained in the CAIP-350 profile for the chain type, encoding the chain ID.
AddressLength
: 1-byte integer encoding the length of Address in bytes. Note that it MAY be zero, in which the Interoperable Address will not include an address. It MUST NOT be zero if ChainReferenceLength
is also zero.
Address : Variable length field containing the binary format of the address component. For serialization details of different types of addresses see the CAIP-350 profile for the chain type.
These rules ensure that future versions of Interoperable Addresses maintain backwards compatibility and consistent behavior across implementations:
<human readable name> ::= <address> @ <chain> # <checksum>
<address> ::= [.-:_%a-zA-Z0-9]*
<chain> ::= [.-:_a-zA-Z0-9]*
<checksum> ::= [0-9A-F]{8}
Where:
Chain
: String representation of CAIP-2 blockchain identifier, recovered from the binary representation described in the CAIP-350 profile for the chain type. In the case where ChainReferenceLength
is zero, it should be the CAIP namespace alone, and no trailing colon. Note that it's not possible to specify a reference without a namespace.
Address
: Chain namespace specific text representation of the address from the binary representation. Mapping between the two described in the CAIP-350 profile for the chain type. In the case where AddressLength
is zero, it should be the empty string.
Checksum
: 4-byte checksum calculated by computing the keccak256 hash of the concatenated ChainType
, ChainReferenceLength
, ChainReference
, AddressLength
and Address
fields of the binary representation (that is, the v1 binary representation skipping the Version
field), and truncating all but the first 4 bytes of the output. Represented as a base16 string as defined in RFC 4648.
@
symbol for the separator, freeing up :
) and CAIP-10 account IDs, with the caveat that no length restriction is placed, so chains with longer address formats or full 256-bit EVM chainids can be represented.%
as a valid character to allow for url-encoding of any other characters.Chain: Ethereum Mainnet
Address: 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
Interoperable Name: 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045@eip155:1#4CA88C9C
Interoperable Address:
0x00010000010114D8DA6BF26964AF9D7EED9E03E53415D37AA96045
^^^^-------------------------------------------------- Version: decimal 1
^^^^---------------------------------------------- ChainType: 2 bytes of CAIP namespace
^^-------------------------------------------- ChainReferenceLength: decimal 1
^^------------------------------------------ ChainReference: 1 byte to store uint8(1)
^^---------------------------------------- AddressLength: decimal 20
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Address: 20 bytes of ethereum address
keccak256 input for checksum: 0x0000010114D8DA6BF26964AF9D7EED9E03E53415D37AA96045
note the version field is removed before hashing
Chain: Solana Mainnet
Address: MJKqp326RZCHnAAbew9MDdui3iCKWco7fsK9sVuZTX2
Interoperable Name: MJKqp326RZCHnAAbew9MDdui3iCKWco7fsK9sVuZTX2@solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d#88835C11
Interoperable Address:
0x000100022045296998a6f8e2a784db5d9f95e18fc23f70441a1039446801089879b08c7ef02005333498d5aea4ae009585c43f7b8c30df8e70187d4a713d134f977fc8dfe0b5
^^^^---------------------------------------------------------------------------------------------------------------------------------------- Version: decimal 1
^^^^------------------------------------------------------------------------------------------------------------------------------------ ChainType: 2 bytes of CAIP namespace
^^---------------------------------------------------------------------------------------------------------------------------------- ChainReferenceLength: decimal 32
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------------------------------------------------------------------ ChainReference: 32 bytes of solana genesis block
^^---------------------------------------------------------------- AddressLength: decimal 32
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- Address: 32 bytes of solana address
keccak256 input for checksum: 0x00022045296998a6f8e2a784db5d9f95e18fc23f70441a1039446801089879b08c7ef02005333498d5aea4ae009585c43f7b8c30df8e70187d4a713d134f977fc8dfe0b5
.
Note the version field is removed before hashing.
Chain: eip155
namespace, chainid not specified.
Address: 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
Interoperable Name: 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045@eip155#B26DB7CB
Interoperable Address:
0x000100000014D8DA6BF26964AF9D7EED9E03E53415D37AA96045
^^^^------------------------------------------------ Version: decimal 1
^^^^-------------------------------------------- ChainType: 2 bytes of CAIP namespace
^^------------------------------------------ ChainReferenceLength: zero, indicating no chainid
^^---------------------------------------- AddressLength: decimal 20
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Address: 20 bytes of ethereum address
keccak256 input for checksum: 0x00000014D8DA6BF26964AF9D7EED9E03E53415D37AA96045
Note the version field is removed before hashing.
Chain: Solana Mainnet.
Address: Not specified.
Interoperable Name: @solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d#2EB18670
Interoperable Address:
0x000100022045296998a6f8e2a784db5d9f95e18fc23f70441a1039446801089879b08c7ef000
^^^^------------------------------------------------------------------------ Version: decimal 1
^^^^-------------------------------------------------------------------- ChainType: 2 bytes of CAIP namespace
^^------------------------------------------------------------------ ChainReferenceLength: decimal 32
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-- ChainReference: 32 bytes of solana genesis block
^^ AddressLength: zero, indicating no address
keccak256 input for checksum: 0x00022045296998a6f8e2a784db5d9f95e18fc23f70441a1039446801089879b08c7ef000
.
Note the version field is removed before hashing.
While this standard aims to be a foundation to be able to canonically refer to addresses on different chains, that guarantee is going to be a leaky abstraction in the real world, given that e.g. a particular chain namespace might define a serialization scheme that can't guarantee canonicity of addresses, or a given network might have two valid CAIP-2 ids referring to it.
It is therefore advised for implementers requiring canonicity of addresses (e.g by using them as keys in smart contract mappings or other key-value stores), to thoroughly review the CAIP-350 profile of a chain namespace for the possibility of a lack of canonicity of addresses (which should be noted in the profile's 'Extra Considerations' section) as well as collisions with other already-supported namespaces.
Copyright and related rights waived via CC0.