Smart Contracts
Herodotus Smart Contract Workflow on L1 and L2
Overview
Herodotus smart contracts can be deployed on L1 and L2s, L3s and app-chains. In this documentation, we will focus on our deployments targetting L1 and L2.
The black arrows represent smart contract calls that can mutate the state, and the green arrows are read-only calls.
Layer 1
SHARP proofs aggregators factory
Factory contract for creating new SharpFactsAggregator
contracts,
These contracts are created by Clones
, which ensures they are upgradeable.
The purpose of using the Factory pattern is to have the ability to manage the creation and extension of multiple MMRs. By using this approach, we can simultaneously extend the tree with recent blocks by snapshotting a recent block hash and also extend the tree to the left by performing the cryptographic link check.
Notable Functions
All instances of the SharpFactsAggregator
can be validated whether they have been created by the Factory since smart contract addresses on Ethereum are deterministic and can be computed by:
keccak256(FACTORY_ADDRESS, factoryNonceAtCloneCreationTime)[0:20]
Or by querying the variable stored in the Factory:
aggregatorsById
SHARP proofs aggregator
The important functions from the perspective of E2E integration are:
Notable Functions
Messages sender
The Messages Sender contract is responsible for transmitting data(messages) to Layer 2.
The contract is used to send block hashes as well as the Poseidon or Keccak MMR roots to Layer 2. This is done by providing the identifier of the tree
. It’s imperative that the contract confirms that the Factory has genuinely created the tree
before proceeding with the transmission of the MMR roots.
Future work
L2 Roots Cache
The L2 Roots Cache will be built off-chain.
Layer 2
The code shown is pseudocode. The exact code can be found on our GitHub.
Inbox/Dispatcher
The role of this contract is to receive and properly handle cross-rollup messages sent from the L1: Messages sender
.
Depending on the received message, the contract will pass the call over to a different contract, which is why it acts as a dispatcher.
Each time it receives the message, it emits an event.
Headers Store
The Headers Store contract is responsible for managing the Merkle Mountain Range (MMR), which stores the hashes of provably valid Ethereum block headers.
A key feature of the Header Store contract is its implementation of the Memento pattern, which lets the contract recall its past roots, ensuring that inclusion proofs remain indefinitely valid.
This contract also supports buffering or branching. New MMRs can be created and mutated independently from each other, allowing resource management and avoidance of global locks that would be required due to the non-homomorphic nature of hash-based accumulators.
Each branch of the MMR is given its own distinctive ID. Additionally, it's tagged with its present size to mark its version.
Tree creation methods
MMRs can be instantiated by calling one of these methods:
Tree growth methods
processBlocksBatch(bytes customEncodedParams)
The reason behind having customEncodedParams is that in the previous versions, we used two methods:
AND
The main reason behind having two methods is the need for differentiation between:
Processing an element already present in the MMR implies traversing the chain of headers from the left.
Processing a recent
blockhash
sent through the transport layer from L1, which is not present in the MMR.
Facts Registry/Storage proofs verifier
This contract is responsible for verifying actual storage proofs and executing the final step of the workflow, which involves the verification of inclusion proofs.
The contract's main responsibilities are:
Verify Merkle Mountain Range (MMR) inclusion proofs.
Verify state/inclusion proofs related to accounts, receipts, transactions and/or proofs that attest to storage slot values.
This contract only reads data from the HeadersStore
.
Notable Functions
Future work
Batched verification
Support for batch storage proof verification will enable up to 200 data entries to be proven per one generated proof, significantly decreasing costs.
Batched verification of storage proofs will provide a less latency-optimized alternative to using the FactsRegistry.
Facts Registry
Facts Registries support for transaction_receipts
and transactions
.
Compressed Facts Registry
A parallel version of FactsRegistry that is fully merkelized, similar to the HeadersStore. The only difference is that it would be paged to optimize for time-series queries.
Current Deployments
Our current smart contract deployments can be found here.
Last updated