# Vitalik: Deeper dive on cross-L2 reading for wallets and other use cases **Published by:** [Cookies Research](https://paragraph.com/@cookies-research/) **Published on:** 2023-06-25 **URL:** https://paragraph.com/@cookies-research/vitalik-deeper-dive-on-cross-l2-reading-for-wallets-and-other-use-cases ## Content Article TL;DRMake it easier to read L1 from L2, L2 from L1, or L2 from another L2Necessary to implement asset / keystore separation architectureCan be used to optimize reliable cross-L2 callsGoalWhen L2s become more mainstream → Users will have assets across multiple L2s and L1s When smart contract wallets become mainstream → Keys needed to access some account are going to change over time (old keys will no longer be valid) Once both of the above occurs → User needs to find a way to change the keys that can access many accounts which live in many different places → Without making extremely high no. of txnsThis is essentially saying that they are allowing the users to access the different smart contract wallets (accounts) they have on the different networks with specific keys. And there is a need to implement an architecture to achieve this without creating a complex UXNeed a way to handle counterfactual addresses which are:Addresses that have not yet been ‘registered’ in any way on-chain → But need to receive and securely hold fundsNecessary for all: When using Ethereum for the first time → A user generates an ETH address that someone uses to transfer assets to → This address is not registered on-chain yetRegistered on-chain: Require paying of txn fees → Which requires the wallet to already hold onto some ETHWe can think of this as a sort of ‘kick-start’ mechanism → Where the address will be registered once they have started making txns → Active wallet instead of passive wallet (purely receiving, not making txns and paying gas fees)All EOAs start off as counterfactual addressesPossible for smart contract wallets to be counterfactual addressesCREATE2: Allows ETH address to only be filled by a smart contract that has code matching a particular hashChallenges of Smart Contract WalletsPossibility of access keys changing Smart contract wallets have an address (unique identifier for the wallet) → Generated based on initcode → Only contain initial verification key (password for wallet) Current verification key (might be different from the initial verification key) → Stored inside wallet’s storageThis is not propagated to other L2sUser might have multiple addresses on different L2s → Should there be counterfactual addresses that are not known yet by the L2s (since they are not registered) → Changing the access keys becomes a challengeSolution: Asset / Keystore Separation Architecture2 main components:Keystore Contract Can be on a L1 / L2 Stores verification key for all wallets owned by user Stores rules for changing keyWallet Contract Exist on both L1 and L2 Communicate with each other across different systems to retrieve verification key stored in keystore contractAsset/Keystore Separation ArchitectureSummary: User has a main contract (keystore contract) that holds all the keys and rules, and separate contracts (wallet contracts) on different systems that talk to each other to get the correct key from the main contractImplementing Asset / Keystore Separation ArchitectureLight version: Check only to update keys Each wallet stores the verification key locally Each wallet contains a function that can be called to check a cross-chain proof of the keystore’s current state → Update its locally stored verification key to match When a wallet is used for the first time on a specific L2: Necessary to call the function to get current verification key from keystore Upside: (a) Minimizes use of cross-chain proofs (expensive) (b) Since all funds can only be spent with current keys → Wallet security is maintainedHeavy version: Check for every txn Cross-chain proof showing key currently in keystore is necessary for every txn Upside: (a) Less systemic complexity (b) Keystore updating is cheap Downside: (a) Expensive per txn (b) Not easily compatible with ERC-4337 → Does not currently support cross-contract reading of mutable objects during validationSummary:Light version checks for key updates periodically, reducing the reliance on cross-chain proofs but incurring higher gas costs for key changesHeavy version checks the keystore for every transaction, which is cheaper for keystore updates but requires more engineering effort to optimize cross-chain proof costs and may face compatibility challenges with certain standardsWhat Does Cross-chain Proof Look Like?Scenario: Keystore is on Linea, wallet is on KakarotFull proof of the keys to the wallet consists ofProof proving current Linea state root → Given the current Ethereum state root that Kakarot knowsProof proving the current keys in the keystore → Given current Linea state root2 challenges for implementationWhat kind of proofs to useHow does the L2 learn the recent L1 (Ethereum) state root + How does the L1 learn the L2 state root → What is the delay for thisPotential Proof SchemesMerkle proofsGeneral-purpose zk-SNARKsSpecial-purpose proofs (e.g. with KZG)Verkle proofs (between KZG and zk-SNARKs for infrastructure workload and cost)No proofs and rely on direct state readingEvaluation of Proof SchemesAggregation <> Cross-chain ProofsAggregation: Aggregate all proofs supplied by users within each block into a big meta-proof that combines all of them Possible for SNARKs and KZG Not possible for Merkle branches (can be combined but the cost is not worth) Aggregation is only worth it when the scheme has a substantial number of users → Realistically it’s okay for v1 to leave aggregation outDirect State ReadingOnly for L2 reading L1Modify L2s → Let them make static calls to contracts on L1 directlyCan be done with an opcode or precompile → Allows calls into L1 → Provide destination address, gas, and calldata → Return outputThis essentially allows the L2 to understand what the L1 state is by specifying the information that they requireStatic calls → Cannot change any L1 stateIf keystore is on L1 + L2s integrate L1 static-call functionality → No proofs are required at allIf L2s don’t integrate L1 static-calls → If keystore is on L2 (which it may eventually have to be) → Once L1 gets too expensive for users to use → Proofs will be requiredHow Does L2 Learn the Recent Ethereum State Root?All L2s have some functionality to access the recent L1 stateThis functionality is needed to process messages coming in from L1 to L2 (most notably deposits)If an L2 has a deposit feature → Use that L2 as-is to move L1 state roots into a contact on L2Have a contract on L1 call the BLOCKHASH opcode → Pass it to L2 as deposit messageFull block header can be received + state root extracted on the L2 sideIt is however, better to have every L2 have an explicit way to access either the full recent L1 state / L1 state roots directlyMethods for L2s to Read L1sMain challenge with optimizing how L2s receive recent L1 state roots → Simultaneously achieving safety and low latencyL2s implement ‘direct reading of L1’ functionality in a lazy way → Only reading finalized L1 state roots → Delay will normally be 15 minsIn extreme case of inactivity leaks → Delay can be several weeksL2s can be designed to read much more recent L1 state rootsBut if L1 reverts (which can happen during inactivity leaks) → Even with single slot finality → L2 need to be able to revert as well → Technically challenging from a software engineering perspectiveOptimism has this capabilityUse deposit bridge to bring L1 state roots into L2Simple economic viability might require a long time between deposit updatesOracles are not acceptableWallet key management: Very security-critical low-level functionalityShould depend on at most a few pieces of very simple, cryptographically trustless low-level infrastructureMethods for L1s to Read L2sOptimistic rollups: State roots take 1 week to reach L1Because of fraud proof delayOn zk-rollups: Takes a few hours → Still slow due to proving times and economic limitsPre-confirmations from sequencers, attesters, etc.Not an acceptable solution for L1 reading L2Level of security of L2 → L1 communication must be absoluteOnly state roots that L1 should trust → State roots that have been accepted as final by L2’s state-root-holding contract on L1Duration for L1 <> L2 CommunicationSome of the methods mentioned above for trustless cross-chain operations are unacceptably slow for many DeFi use cases → These need faster bridges with more imperfect security modelsFor the use case of updating wallet keys → Longer delays are more acceptable → It’s not the txns that are getting delayed by hours → It’s the key changesJust have to keep the old keys around longerIf user is changing keys because the keys are stolen → There is a significant period of vulnerability → Can be mitigated by having a freeze functionBest latency-minimizing solution → For L2s to implement direct reading of L1 state roots in an optimal way → Each L2 block (or state root computation log) contains a pointer to the most recent L1 block → If L1 reverts → L2 revertKeystore contracts should be placed either on mainnet / on L2s that are zk-rollups and can quickly commit to L1For chains that hold wallets with keystores that are rooted on Ethereum / L2: How much connection to Ethereum is needed?Answer: Not that muchNot limited to rollup → Wallets can be held on L3 / validium tooAs long as keystores are either on L1 / zk-rollupRequirement: Chain needs to have direct access to Ethereum state roots + Technical and social commitment to be willing to reorg if Ethereum reorgs + hard fork if Ethereum hard forksResearch problem: Identify to what extent it is possible for a chain to have this form of connection to multiple other chainsNode operators and community will have double the technical and political dependenciesSounds similar to spillover effects from leveraging the same set of resources for multiple applications (similar to the concept of rehypothecation)End of the day: Can use the technique to connect to a few other chains → But at increasing costPreserving PrivacyIf a keystore manages multiple wallets, we want to make sure that:It is not publicly know that those wallets are all connected to each otherSocial recovery guardians don’t learn what the other managed addresses areA few issuesMerkle proofs cannot be used → They do not preserve privacyKZG / SNARKs: Proof needs to provide a blinded version of the verification key without revealing location of verification keyAggregation: Aggregator should not learn the location in plaintextIt should receive blinded proofsLight version cannot be usedIt creates a privacy leakIf many wallets get updated at the same time due to an update procedure → Timing leaks the information that those wallets are likely relatedCan’t really comprehend why this might be the caseSNARKs: Proofs are information-hiding by defaultAggregator produces recursive SNARK to prove SNARKs → Currently, this process is quite slowDirect reading L1 from L2: Does not preserve privacyAdditional ResourcesThe Three Transitions | VitalikHolding assets across multiple chains | SafeThe need for wide adoption of social recovery walletszk-SNARKsPrivacy applications of zk-SNARKsKZG commitments | DankradVerkle trees ## Publication Information - [Cookies Research](https://paragraph.com/@cookies-research/): Publication homepage - [All Posts](https://paragraph.com/@cookies-research/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@cookies-research): Subscribe to updates