[Draft-5] EIP-5559: Off-Chain Data Write Protocol

3668 was actually written for ENS, so this isn’t really accurate.

No need to throw shade on DeFi :laughing:

I think this first paragraph can probably be omitted entirely, though.

If this is going to be a PR to 5559, it shouldn’t refer to 5559 in the third person. This will replace that spec. In general the spec still needs rewriting to be a comprehensive replacement that doesn’t reference the earlier version.

I mentioned this on the previous draft: I don’t see any reason to require all reverts to have the same signature and pack their domain-specific data into a metadata field. It seems clearer and cleaner to just encode that data as arguments of the revert directly.

Is Solana support something we really need to encode into 5559? I don’t see anyone demanding it, and each additional storage handler adds complexity for implementers.

Relatedly, this spec should specify whether clients are required to implement all the handlers or only some - and if only some, we need to consider how they can tell an unknown 5559-based revert apart from any other revert reason.

I think you mean to say that they should be base56 decoded and stored natively; hex is simply a representation commonly used by Ethereum libraries; data in Ethereum is natively stored as bytes.

It seems a little odd to show first unpacking these values, then packing them back up again. I think it would be clearer to leave out the first part and note that the derivation of those two values is up to the implementer.

Isn’t callData supposed to be opaque to the implementing client?

Where does account come from? Isn’t access control also something that should be opaque to the implementer?

I mentioned this on the previous draft - a contract being able to prompt a user to make an arbitrary transaction to any chain is an enormous security vulnerability. Absent some other mitigation, we need to put restrictions on the payload.

What is the mechanism by which it would not be included?

Why does being offchain preclude us from deriving an address for the signer?

I would say instead that “the signature will be produced by the account with address dataSigner”; eth_sign is an implementation detail. It’s also worth noting that this could facilitate apps prompting the user to change wallets where necessary.

It would help to state explicitly that this standard doesn’t describe a mechanism for this.

Since both keys are derived from a single signature, can’t we instead encode the address of the signer from which the keys are derived?

This is a basic requirement in order to implement this standard; I think we need to tell users how they can retrieve the version number.

Can you clarify? How would these standards help with this?

If you’re not going to specify key derivation inline here, you at least need to mention that the key is derived, and where to read that section of the spec.

Can you be more specific here?

Using what API?

I don’t think there’s any reason to include the signature in the salt, since it’s already included in the kdf.

This still needs to be more prescriptive. Say I’m implementing this in the ENS Manager app; how do I know how to treat the username?

This seems to add a lot of complexity to the protocol. Could we just specify one or the other? I’d be in favor of a single signer per wallet for simplicity; if users want to separate their names they can use multiple accounts, and this then mirrors the security profile of the names themselves.

I don’t think there’s any practical way to do this in a CCIP-Read callback that doesn’t just work out to relying on the gateway to be honest.

Based on reading this, I don’t understand how I would implement the signing process for StorageHandledByDatabase.

I think we should specify one mechanism or the other, not both.

It’s not clear to me why an additional signature is required here; can you elaborate?

Is this intended to be part of the “Revert StorageHandledByDatabase()” section? I think it would be clearer if most of these sections were moved up the spec to the main section on each storage type, with only the bits that are actually shared kept in common down below.

I don’t think there’s anywhere we specify a format like text/avatar or address/60. This needs more detail and some examples.

Why is this nested? Is it intended to represent arbitrary data the app supplies?

And what “off-chain data file”? Is this specifying the encoding of IPFS files? Wouldn’t that be up to the CCIP-Read handler to define and interpret? Why prescribe it here?

How can anyone implement this spec if it doesn’t specify an API for the POST request?

What do you mean by “protocol” in this context? Are you referring to new extensions of 5559 for new storage types? Most of this seems like something the implementer can specify, and needn’t standardize unless they want others to interoperate with it; in most cases the API that a CCIP-Read enabled contract uses to talk to its gateway is an internal implementation decision.

I think that if 5559 is written correctly, there should be no need for a separate ENS-specific spec; a client should be able to simply implement 5559 and leave the ENS-specific details to the resolver contract and its gateway.

A spec can’t and shouldn’t require a specific client library. It needs to specify things at a sufficient level of granularity that you could write a client library based on it.

I don’t think there’s any reason to specify internal data formats here, though - those are an implementation detail for specific resolvers to implement.

Can I suggest that going forward, GitHub would be a more productive way to collaborate on this? A PR has all the tools built in for commenting on specific lines, tracking revisions etc; doing this all via forum threads makes it difficult to keep track of the spec as it evolves.

1 Like