What are Storage Proofs and how can they improve Oracles?
Apr 21, 2023·11 min read
by Starknet

What are Storage Proofs and how can they improve Oracles?

Introduction

Storage proofs are a cryptographic way to track blockchain information so that it can be shared across chains. Similar to oracles, storage proofs provide proof that the information is true. However, unlike oracles, they do not require trust in a third party for this proof; rather, with storage proofs, the trust is built into the storage.

In some cases, storage proofs can replace oracles. In other cases, storage proofs can enhance them and open up new blockchain use cases that weren’t possible before.

So let’s look in detail at storage proofs — what they are, how they work, their use cases, and how they can enhance (and sometimes replace) oracles.

What are storage proofs?

Storage proofs allow you to open cryptographic commitments of state, They can be optimized by marrying them with S[N/T]ARKS. . These validity proofs prove that a particular state existed and was valid at a particular block in the past.

Fundamentally, blockchains are databases that contain data cryptographically committed using Merkle trees, Merkle Patricia trees, Verkle trees, etc.). Since all the data is committed, we can prove that some information is encapsulated in a given state. However, with simple commitment schemes, the size of this proof becomes more prominent as the size of the data it includes becomes larger. Verifying such proofs on-chain becomes too expensive to be practical.

Storage proofs, on the other hand, when used in conjunction with STARKs or SNARKs, can be relatively small, and allow you to verify a specific piece of state, at a specific point in time, and on any domain — without trusting a third party. Instead of third parties, they rely on the security of the underlying chain itself.

Why is this important? Ethereum today is not the simple monolithic chain (L1) it was several years ago. With the advent of L2 solutions, the data is now spread across multiple chains.

Synchronous assumptions about the state of the chain can no longer be made. Many solutions for sharing data are now live such as L1->L2 messaging systems, cross-chain bridges, and oracles. But the issue with these current solutions is that they include trust in a third party such as relayers, multisig signers, and committees. Storage proofs allow us to validate the state of a blockchain at any point in time using cryptographic commitments assuming no trust in a third party.

The use cases for storage proofs

Since storage proofs allow us to efficiently “compress” a blockchain and transmit the data elsewhere, they have quite a few applications. The affordable verification cost, an integral property of storage proofs, allows the proof to be validated on the destination chain, minimizing the need to develop cross-chain messaging systems.

Potential use cases include:

Typical Cross bridge flow image

An example of a storage proof

Generating storage proofs on EVM-compatible chains is straightforward. For example, Web3.js library has the getProof function that can generate proof of a contract’s state on Ethereum (and other EVM-compatible chains such as Polygon or BSC). A contract address and the storage slot for the contract must be passed to the function.

In Ethereum, smart contracts use a key-value store to store data in their storage. Each piece of data is stored in a specific location known as a “storage slot.” Storage slots are memory locations within the contract’s storage and are identified by a unique index. Let’s look at a sample smart contract with the following code deployed on Ethereum mainnet at 0xcc…da8b.

// SPDX-License-Identifier: MIT
pragma solidity >=0.4.22 <0.9.0;

contract Migrations {
  address public owner = msg.sender;
  uint public last_completed_migration;
  function setCompleted(uint completed) public {
    last_completed_migration = completed;
  }
}

The owner variable would be stored at slot 0. Now, to generate the proof that the owner of this contract was an address A, we can use the getProof function as follows:

web3.eth
  .getProof(
    "Oxcca577ee56d30a444c73f8fc8d5ce34ed1c7da8b", // corresponding to the address of the deployed contract
    ["0x0000000000000000000000000000000000000000000000000000000000000000"], // corresponding to slot O
    "Ox10185A7" // the 0x10185A7 corresponds to block 16876967
  )
  .then(console.log);

The output of the code above looks something like this:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "address": "Oxcca577ee56d30a444c73£8c8d5ce34ed1c7da8b",
    "accountProof": ["Oxf90211a0..", "..."],
    "balance": "Ox0",
    "codeHash": "0x6c7686cf8£47£081f63d3f53a87c3c2ca0de63eb057e795£5c0414c6f861f9e3",
    "nonce": "Ox0",
    "storageHash": "0x7317ebbe7d6c43dd6944ed0e2c5£79762113cb75fa0bed7124377c0814737fb4",
    "storageProof": [
      {
        "key": "Ox0",
        "value": "Oxde74da73d5102a796559933296c73e7d1c6f37fb",
        "proof": ["Oxf8518080...", "..."]
      }
    ]
  }
}

The “storageProof” returned contains the storage proof for the “owner” variable. Since Ethereum uses Merkle Patricia Trees to commit to its state the state of accounts and their storage, the storage generated can be used to prove a storage slot (or account state). However, as previously stated, these proofs are not scalable enough to discuss cross-chain message transfers. Using complex ZK mathematics on top of this can decrease the computation required to verify the proof.

So how do storage proofs compare and contrast with oracles?

By design, blockchains cannot retrieve off-chain data. This keeps a blockchain trustless but also introduces limits on a smart contract’s ability to make decisions based on real-world events. Oracles are also commonly employed for obtaining historical blockchain information, as acquiring this data directly is highly challenging and consequently susceptible to mistakes.

To solve this problem, special entities named oracles were created to retrieve this off-chain data (or retrieve results from some heavy off-chain computation). Currently, these oracles require a third party, such as an institution or a decentralized network of node operators to submit data on-chain that becomes public to users and smart contracts. This assumption of trust is currently inevitable, yet not ideal (though several teams are working on minimizing this trust requirement such as Pragma)

Chainlink is an example of a blockchain oracle that provides a wide variety of real-world data (stock prices, weather data, etc.), off-chain computation services to minimize the cost of heavy computations on-chain, and cross-chain services that read and write information between different blockchains.

Since smart contracts have no other way of knowing what is happening in the real world except for using oracles, oracles have become an indispensable part of the blockchain ecosystem.

The state of oracles on Starknet

On Starknet testnet, the previously mentioned Chainlink currently provides price data feeds for seven pairs of cryptocurrencies and has partnered with the Starkware team to “further accelerate app development and general growth for the StarkNet ecosystem.” Chainlink minimizes the assumption of trust with a decentralized network of nodes that provide data from off-chain sources, but the data aggregation occurs off-chain.

Pragma and Stork Network are two of the largest oracle providers on Starknet, operating on both mainnet and testnet. Along with the price tickers for multiple cryptocurrency pairs, Pragma is working on implementing a verifiable randomness feed on mainnet that would allow protocols to request secure randomness on-chain. Price feeds on Pragma are based on price submissions by large institutions and market makers, and price aggregation occurs on-chain leveraging efficient ZK technology.

Can oracles be replaced or improved by storage proofs?

In some cases, yes, a storage proof can replace an oracle.

Not all data provided by oracles actually needs to be supplied by a third party. In some cases, the data provided by an oracle was already available on chain (in the form of on-chain storage, or a transaction) and can be retrieved by taking a peek at a previous state of the blockchain. In these cases, a storage proof can replace the need for trust in a third party and the oracle, and allow smart contracts to rely completely on the security of cryptographic commitments.

In other cases, where storage proofs can’t completely replace an oracle, they can often still enhance them with additional functionality, such as the following:

Conclusion

Over the last several months, the growing use of L2s on Ethereum has given us a clearer view of the industry’s future. The L2 narrative has been gaining traction with networks like Starknet, Optimism, and Arbitrum. However, one of the primary backstops for its growth has been implementing a decentralized cross-chain messaging system. Although they are still at a nascent stage, storage proofs promise incredible improvements to this problem.

Big thanks to Marcello Bardus & Kacper Koziol for reviewing this article.