curl -L https://foundry.paradigm.xyz | bash && source ~/.bashrc && foundryup
forge install foundry-rs/forge-std --no-commit --no-git
./test/goerli.sh
This specification is an extension of ENSIP-10 (EIP-2544/EIP-3688) using mutable and immutable storage pointers for off-chain records storage.
function resolve(bytes calldata name, bytes calldata data) external view returns(bytes memory result)
CCIP2 relies on IPNS hashes serving as proxies to upgradeable IPFS or IPLD content. In the parent IPNS directory (called a recordhash
), the records must be stored in the RFC-8615 compliant .well-known
directory format. ENS records for any name sub.domain.eth
must then be stored in JSON format under a reverse-DNS style directory path using /
instead of .
as separator, i.e. in format ipfs://<hash>/.well-known/eth/domain/sub/<record>.json
.
- ENS text record for
vitalik.eth
's avatar is stored atipns://<ipns_hash>/.well-known/eth/vitalik/text/avatar.json
formatted as
{ data: abi.encode(<avatar>) }
- ETH address record for
sub.domain.eth
is stored athttps://<ipns_hash>/.well-known/eth/domain/sub/address/60.json
formatted as
{ data: abi.encode(<address/60>) }
CCIP2 also offers the experimental feature of setting a global wallet-specific recordhash
(called a masterhash
), which stores common records that may be shared across many names in a wallet. This feature will be enabled in the CCIP2 client in the future. When masterhash
is enabled, the reverse-DNS path is replaced with eth:address(<owner>)
in storage pointers.
Note: If the JSON data is signed by the Registrant of domain.eth
, it must be prefixed with bytes4
of callback
function selector as,
{ data: bytes.concat(Resolver.___callback.selector, <signedData>}
To ensure secure record resolution, records must be signed by either the owner of a domain or a domain-specific signer (called approvedSigner
) set by the owner. The approvedSigner
may be stored on-chain or off-chain by the owner in the CCIP2 contract. Upon each resolution, CCIP2 resolver verifies the signature against on-chain and/or off-chain approvedSigner
, aka on-chain signer and/or off-chain signer approved by the owner.
Type | Function | JSON File |
---|---|---|
Text Records | text(bytes32 node, string memory key) |
text/<key>.json |
Ethereum Address | addr(bytes32 node) |
address/60.json |
Contenthash* | contenthash(bytes32 node) |
contenthash.json |
Multichain Address‡ | addr(bytes32 node, uint coinType) |
address/<coinType>.json |
Public Key | pubkey(bytes32 node) |
pubkey.json |
Name† | name(bytes32 node) |
name.json |
Interface‡ | interfaceImplementer(bytes32 node, bytes4 _selector) |
interface/0x<bytes4Selector>.json |
ABI‡ | ABI(bytes32 node, uint256 contentTypes) |
abi/<contentTypes>.json |
Zonehash‡ | zonehash(bytes32 node) |
dns/zonehash.json |
DNS Record‡ | dnsRecord(bytes32 node, bytes name, uint16 resource) |
dns/<record>.json |
* This is the user's web-facing contenthash contained inside the recordhash
† Name is not implemented as reverse record; users must use the official ENS on-chain reverse record for that feature
‡ Available in v1.1
Type | Identifier | Gateway URL |
---|---|---|
ipns://<contenthash> |
0xe5 |
https://<base36-CID-v1>.ipns.dweb.link/.well-known/.. |
ipfs://<contenthash> |
0xe3 |
https://<base32-CID-v1>.ipfs.dweb.link/.well-known/.. |
ENS + IPNS Node | https://domain-eth.ipns.dweb.link/.well-known/.. |
|
ENS | https://domain.eth.limo/.well-known/.. |
|
ENS + IPFS2 resolver | 0xe3 , 0xe5 |
https://<CID-v1>.ipfs2.eth.limo/.well-known/.. |
Key | Type | Nature |
---|---|---|
K_EOA |
secp256k1 |
Ethereum Wallet Key |
K_IPNS |
ed25519 |
Deterministic Key(gen) |
K_SIGN |
secp256k1 |
Deterministic Key(gen) |
K_N |
schnorr |
Deterministic Key(gen) |