Let's say I make a transaction from Wallet W to Contract A, which calls Contract B.

W => A => B

Would only the first call W => A be stored or also the subsequent call A=>B. Does anything change if B is an external library? I don't know much about rollups myself. Maybe someone knows a good source where one can read about it?

Background: The largest cost of Rollups is calldata (I've heard numbers of 80-90%), so I'm wondering how to write gas efficient code for rollups.


Rollup sources :

(Some sources are coming from this Reddit post)

Additionally, if you want to understand more in details zk-Rollups, you'll want to understand zk-SNARKS (at least at a high level), I found this paper to be a great introduction / explanation, but it's an advanced and complicated subject. Ethereum seems to be more targeted towards Optimistic Rollups for now. You can read this and this which I found very informative and clear to get a clear global view of Optimistic rollups.

At a very high level, Rollups are a way to bundle many L2 transactions together into a single one that will be posted to a dedicated L1 smart contract. This single transaction has all information about the bundled transactions and the state transition in a compressed form.

Rollups are "destined" to become the execution environment, while L1 becomes mainly focused on essential data management and providing security to L2.

Would only the first call W => A be stored or also the subsequent call A=>B. Does anything change if B is an external library?

Only the transaction is stored to L1 in calldata so : W => A there is no need to store A => B given that Rollups don't change anything to the deterministic nature of smart contracts. Having the tx and the state prior the tx execution is enough to validate the tx by re executing it.

B being an external library won't change anything to it. Don't confuse public transactions (from Externally Owned Account (EOA) to EOA or Smart Contract (SC)) with external or internal calls that fall into the "internal transactions" category.

In L1 or L2 Rollups, given :

  • The transaction (EOA to {EOA, SC})
  • The state
  • Deterministic Smart Contract

Every internal tx can be inferred by re-executing the initial tx, so no need to store them.

The largest cost of Rollups is calldata

That's true, there is an upcoming EIP discussed here to further reduce calldata gas cost to favor Rollups development (the global roadmap is this one), because the data from L2's transactions bundled together is stored as calldata on the L1 blockchain. This ensures cheap permanent storage while providing secured / long term data availability. zk-Rollups have additional cost to verify the proof generated, but they provide immediate finality while Optimistic Rollups require a challenge period to come to expiration but no work is performed if no fraud proof was submitted.

Don't bother with writing gas efficient code "for Rollups", your code will be executed on L2 and state changes will be posted to L1. Focus on writing gas efficient code for you and your users, it's more than enough (and all you can / should do actually).

I personally like to think of Optimistic Rollups as Lazy Rollups and of zk-Rollups as Active Rollups since Optimistic Rollups run verifications only if a fraud proof was given during a challenge period while zk-Rollups have a per batch verification mechanism due to zk-SNARKS proof verifications, submitting an invalid state transition to L1 is not possible with zk-Rollups.

I find zk-Rollups to be superior in theory since they don't rely on incentives and users actively monitoring the state, but the difficulty to incorporate smart contract support in it was a big drawback, zkSync apparently has support for it now. Optimistic Rollups were almost immediately compatible with smart contracts and reached production earlier.

  • Thank you so much for this great summary. I will read through it in the next few days!
    – ikijong
    Nov 29 '21 at 17:16
  • Just to clarify my question about gas-efficient code. There are a lot of resources on how to write gas-efficient code for mainnet (mainly reduce sstores and sreads). Currently, many projects simply deploy code developed for mainnet on layer-2. This is good as you save development/audit costs, but I wonder if there is more room for optimizations when developing code that runs exclusively on rollups (like Arbitrum, Optimism, ZkEVM, etc.).
    – ikijong
    Nov 29 '21 at 17:17
  • 1
    Well if I understand correctly, the only important point would be to reduce gas consumption, this is dependent on the EVM gas cost per OPCODES running on the L2 of your choice, I'm not aware of such differences though (except some unavailable / replaced OPCODES). Btw, Optimistic Rollups fraud proof imply a verification that require to re-execute the tx on L1, so you cannot make the assumption that your code is exclusively running on L2.
    – hroussille
    Nov 29 '21 at 17:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.