Proxy Patterns - Implementation storage solutions for non-conflicting upgrades, is there a best?

I'm following OpenZepplin's "Upgrading using the Upgrades Plugins"
and am using their Proxy Pattern.

I've seen Eternal Storage as being a solution to resolving implementation upgrade conflicts in the context of proxy patterns. The gist from what I've gathered is essentially the Proxy contract stores state of it's own state and whatever it delegatecalls. It seems OpenZepplin takes care of the Proxy storage and logic contract storage conflict by using unstructured storage implementation. This then leaves implementation upgrade storage conflicts to be resolved.

A simple way to implement Eternal Storage would be append new state variables to your Top level contract (with respect to contract inheritance) every implementation upgrade.

Yet Eternal Storage on a long-live production Dapp could become quite a slog for future development, having to scan through state variables out of sorts.

The main issue of Eternal Storage to my understanding is the inflexibility of adding state variables on new implementation upgrades

One could conceive of some middleware that reorganizes the state variables to the developer's preference, in turn processing it into a compatible format that abides by the append-state variable rule. So there would be two different logic contracts that are completely equivalent with respect to a solidity compiler, aside from storage addresses of state variables, in which the middleware makes it implementation upgradable.

Also there may be something interesting that can be done with storing via mappings, the following link being one something of this nature, https://medium.com/rocket-pool/upgradable-solidity-contract-design-54789205276d

After reading it just seems there's too much overhead and increased gas fees for what seems to be, albeit legitimate solution, overly-complex implementation of Eternal Storage. (In this case it seems they're also trying to implement their own proxy pattern, which in my case I'm sticking to OpenZepplin's implementation)

Anyone that has some ideas and/or experience on storage solutions for non-conflicting upgrades, I'd like to hear from you!

The beauty of external storage is there does not have to be just one storage contract. New state variables can be added to new external storage contracts as long as a mechanism is retained to tell existing contracts about the new coming storage contracts, if necessary.

I find the external storage pattern extremely useful. It can help maintain system-level parameters. It allows building extremely complex dapp. One project I built has more than 160 smart contracts and interfaces. Without using this external storage pattern, it would be extremely difficult to develop, test, and maintain.

2 Likes

It seems like you are talking about the Transparent proxy pattern, if possible, you can have a look at the another proxy pattern: UUPS Proxies - OpenZeppelin Docs

1 Like

external storage

By this do you mean creating an Oracle to interact with a Decentralized Database Network?

Thanks I will take a look at that.

Just took a look at diamond patterns by Nick Mudge, have yet to finish reading.

I've been looking at quite a bit of OpenZepplin's documentation and guides in the past few days, so still soaking in all the valid options of Proxy Upgradable Implementations.

Nah, it's a proxy pattern, a way of organizing smart contracts such that most if not all state variables are stored in a dedicated contract whereas all other contracts interact with this contract for state variables.