diff --git a/ens-improvement-proposals/ensip-16-offchain-metadata.md b/ens-improvement-proposals/ensip-16-offchain-metadata.md index 30f88abd..8212441f 100644 --- a/ens-improvement-proposals/ensip-16-offchain-metadata.md +++ b/ens-improvement-proposals/ensip-16-offchain-metadata.md @@ -23,7 +23,7 @@ This ENSIP addresses this by adding a way of important metadata to be gathered o The metadata should include 2 different types of info -- Offchain data storage location related info: `graphqlUrl` includes the URL to fetch the metadata. +- Offchain data storage location related info: `graphqlUrl` includes the URL to fetch the metadata. - Ownership related info: `owner`, `isApprovedForAll` defines who can own or update the given record. @@ -47,23 +47,17 @@ By passing the name through metadata, we empower the resolution process, enablin // To be included in // https://github.com/ensdomains/ens-contracts/blob/staging/contracts/resolvers/Resolver.sol interface IOffChainResolver { - /** @dev Returns the owner of the resolver on L2 - * @param node - * @return owner in bytes32 instead of address to cater for non EVM based owner information - */ - owner(bytes32 node) returns (bytes owner); - // optional. // this returns data via l2 with EIP-3668 so that non EVM chains can also return information of which address can update the record // The same function name exists on L2 where delegate returns address instead of bytes function isApprovedFor(bytes context, bytes32 node, bytes delegate) returns (bool); - /** @dev Returns the owner of the resolver on L2 + /** @dev Returns the metadata about the node * @return name can be l2 chain name or url if offchain * @return coinType according to https://github.com/ensdomains/address-encoder * @return graphqlUrl url of graphql endpoint that provides additional information about the offchain name and its subdomains * @return storageType 0 = EVM, 1 = Non blockchain, 2 = Starknet - * @storageLocation = l2 contract address + * @storageLocation = When storageType is 0, l2 contract address. When storageType is 1, url endpoint in bytes format * @return context = an arbitrary bytes string to define the namespace to which a record belongs such as the name owner. */ function metadata(bytes calldata name) @@ -190,6 +184,49 @@ type Resolver @entity { } ``` +### Offchain storage service + +[EIP-5559](https://eips.ethereum.org/EIPS/eip-5559#data-stored-in-an-off-chain-database) has already been proposed to handle both L2 and off chain storage by utilizing the similar method to [EIP-3668](https://eips.ethereum.org/EIPS/eip-3668). +While this is technically feasible, it adds extra function calls simply to discover how to update the data. The simpler alternative for ENS related storage update is to query storage service endpoint from `storageLocation` in bytes format when `storateType` is set to `1`. The client then make a HTTP POST call to the storage location with signature information. + +The body attached to the request is a JSON object that includes sender, data, inception date and a signed copy of the abi encoded data, sender, and inception date. + +Example HTTP POST request including requestParams and signature: + +``` + const keccak256 = ethers.utils.solidityKeccak256 + const name = 'vitalik.eth' + const node = ethers.utils.namehash(name) + const iface = new ethers.utils.Interface(['function setAddr(bytes,address)']) + const signer = signers[0] + const signerAddress = signer.address + const data = iface.encodeFunctionData('setAddr',[node, signerAddress]) + const hasheddata = keccak256(['bytes'], [data]) + const block = await ethers.provider.getBlock('latest') + inception = block.timestamp + signature = await signers[0].signMessage( + ethers.utils.arrayify( + keccak256( + ['bytes', 'uint256'], + [ + hasheddata, + inception + ], + ), + ), + ) +``` + +``` + const request = { + data:, + inception, + signature + } +``` + +Once the storage service receives the request, it decodes the sender information from the signed signature and perform the data update if the `sender` matches the name onwer defined by the optional `context` field. + ### Backwards Compatibility None @@ -200,4 +237,4 @@ None ### Copyright -Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). \ No newline at end of file