I agree this is a challenge, and I’d say it’s the single major challenge remaining in designing rent schemes! Here’s an overview of ideas we have now:
- Require each contract to have a fixed small storage size (eg. <= 4096 bytes). If you need infinite-sized mappings for your application, you can create a new contract for each entry, where the contract’s address would be based on what mapping and what key you are accessing, and the contract’s code would be a simple code that allows the parent contract to read and write the value inside. Mapping read/writes would then turn into contract calls. This allows mapping entries to be separable from each other and individually pay rent, hibernate and wake. Note that ENS is essentially architected this way already.
- Put storage into a Merkle tree, and only store the root inside the contract. Users would have to process historical data to figure out what Merkle branches to use client-side, and the network would only need to bother with O(1) storage. So essentially the stateless client model, but at the contract level.
A major challenge with the first approach is how to handle the following sequence of events (I’ll use an ERC20 for example):
- Alice sends Zachary 20 tokens. Zachary never had any tokens before, so a contract gets created to record the balance.
- Zachary contract expires and hibernates.
- Bob sends Zachary 10 tokens. Zachary does not seem to have an active contract, so a new one gets created to register the 10-token balance.
How do the 10 tokens and 20 tokens get aggregated together? And what if this is a more complex application, where aggregating together states is not a matter of simple addition?