getMerkelPath/proof format in starknet?

As part of the ENS integration project we are working on EIP-3668: CCIP Read: Secure offchain data retrieval. We need to export the merkel path\ proof of the state variable in starknet back to L1 to be verified against the stateroot. We need the format of the said proof. I believe getMerkelPath is under development in starknet. If its not finalyzed, can we assume something similar to the format exported by ethereum api eth_getProof (https://github.com/ethereum/EIPs/issues/1186)?

This will help us in starting working on the state verifier and hopefully it can come together in the end. Thanks

5 Likes

We’re not working internally on an eth_getProof analog, my expectation is that this will be taken on by full nodes in the future (there are a few full node efforts currently aiming at a node that can sync from L1 / our sequencer, and support starknet_call functionality, see the rpc-spec). IIUC eth_getProof is part of the archive functionality so I would expect full nodes to add it in a later stage.

That said, we can prioritize this for a future version of our API if the need arises from the community. Archive functionalities don’t yet appear on the spec, but we can add getProof in order to make the format clear for everyone. The format would be something like a sequence of triplets as described here.

Also note that L1 verification is more problematic due to the commitment using Pedersen and not Keccak. This should only be used for disaster recovery (StarkNet is not responsive / sequencers are dosing you), since if you just want to know the value, in the normal state of affairs, you can communicate with L1 via messages. If the issue is knowing the value in past blocks, then you can implement the verification as a StarkNet contract which takes as a parameter a past state root (this will circumvent the different hashes issue).

1 Like

The idea of EIP-3668 is to provide a generic way to read data from L2. It does that via gateway service implementation customized for every L2. In order to avoid any additional trust assumption on the gateway service. The gateway service needs to return a cryptographic proof that a certain state variable has the said value. The cryptographic proof can be checked invisibly/seemlessly within the ethers.js lib without any breaking changes. Thats my understanding from digging into it and going through the CCIP repo which I believe nick just finished updating. https://github.com/smartcontractkit/ccip-read.
The repo has examples of how it can be used for token airdrops as well. This goes above and beyond ENS and potentially useful for Starknet in other use cases.
I am working with another developer who is working part time to do pederson hash implementation in solidity. Since it will only be a view function, a naive implementation might just be fine.
At this point I am kinda curious if I should go with this further if this is not on the roadmap then may be I will shelve it for now but I still believe this could be very useful in other scenarios. Here is a video of nick (ENS founder) explaining the motivation behind the EIP and its gateway based architecture

IIUC you were asking about storage values in StarkNet rather than arbitrary off-chain data committed to on-chain. In this special case, the messages mechanism could be sufficient. Please note that L2->L1 messages do not add any additional assumptions as they’re backed up by the proof, so if your purpose is a trustless way of getting the values of SN variables (or some manipulation of them) to L1, then you’re covered. The downside to this is that you have to wait for the proof to be accepted on L1 (currently, 8-10 hours on mainnet).

That said, there are other usecases where storage proofs become important, e.g. verifying storage in a past SN block. Even here, I think that it makes more sense to implement the storage proof verifier in SN rather than in Ethereum, as Pedersen’s are the native hash and the verification would be much cheaper. The output could be sent to L1 via the messaging mechanism as before. The one advantage that implementing the verifier is solidity does have is that you won’t have to wait for the proof, as you can start verifying the moment someone sends the proof, independently of SN (it’s a critical difference with the current proof times, but will become less so in the future).

Thanks for a great clarification. I understand the l2-l1 message passing being backed by cryptographic proof which can be verified by the starknet solidity contract deployed on L1. But waiting for 8-10 hours or even a bit less might be a deal breaker, but happy to be proved wrong here. Resolving an ENS name to an address stored in a state var on L2 and then using that address in a client(a wallet) should not take more than a few seconds.

And also if this is to fit within CCIP Read gateway architecture (proposed by ENS) it should not use any gas and should be a view function of sorts, though I could be wrong on this one. Message passing currently requires gas. I dont think ENS resolver currently use gas, as it is a view function, and to expect them to pay gas as they move to L2 for name to address resolution might be a step backwards.

If you are questioning whats the point of moving to L2 if its free currently in L1. Its the savings you get when you register ens names and update the state via l2. The should use gas but just reading it should not and should not take a few seconds to resolve in order for the clients to use it.

If reading the value from an RPC node (calling a view function) is sufficient, then why communicating with an SN node is problematic? By the latter I mean just viewing a storage variable on SN, instead of calling a view function that verifies a Merkle-Patricia path with Pedersen hashes on Ethereum. After all, both involve trust in the replying node (unless you run it yourself, which again you can do in both cases). The only difference I see is the delicate issue of SN nodes not existing as of yet, but hopefully this situation will be rectified.

Also, calling the whole path verification free because it’s a view function feels like cheating, there is execution effort to be made (which can be reflected in fees payed to a node running this, depending on your rate of calls).

May be somebody from ENS or chainlink explain better the motivations of CCIP read better but the idea is get some any generic state data from L2, be it optimism, arbitrum, zksync via somekind of gateway service and in order avoid trust assumptions about the gateway service, if its lying or is malicious, is to return cryptographic proof along with it to verify the data. Thats the architecture that is bring implemented with Optimism, Arbitrum etc…

In L2 to L1 message, it gets verified by the starknet solidity contract first I believe but if we directly read a state variable from a node running, wouldnt there be additional trust assumptions? Like how de we know that L2 is giving us the correct info.

May be somebody from ENS will chime in here to give more context. I have asked makoto

I can concur that we need getMerklePath because the ability to view L2 state from L1 can be useful for ENS but also for Trustless Cross chain bridges.

1 Like