To understand diamond upgrades you have to understand that upgrades occur at the external function level. You can add external functions, you can replace external functions and you can remove external functions. That's all. So to understand upgrades you need to think in terms of add/replacing/removing external functions.
So for example, it is impossible to add new state variables without adding and/or replacing external functions in a diamond.
If you append new state variables to an existing struct that is shared with external functions already in the diamond it is only necessary that you replace the external functions that actually use the new state variables.
If you want to add new external functions that use new state variables that have been appended to an existing struct that is shared then it is only necessary to add the new external functions. You don't have to replace the existing functions in the diamond that use the prior version of the struct.
If you change the source code of one external function that is part of a facet of many external functions you only need to replace that one function in the diamond, not the others. However you could, if you want to, replace all the external functions from the facet in the diamond just for organizational neatness. This way all these external functions come from the same deployed facet and have the same verified source code.
You might ask, âhow do I keep track of the different versions of source code that are used by different facet versionsâ? There could be multiple answers to this and multiple solutions. When a facet is deployed its source code should be verified with Etherscan or other service -- that will ensure that you have the correct source code for any particular external function. If you are using git or other source control then a new tag or release can be made to identify facet/external function source code that is deployed. More tooling here could be useful.
Let's look at an example:
Let's say that you have an existing deployed diamond that has 25 external functions from 4 different facets.
Now you want to add 5 new functions to the diamond that use 6 new state variables. How could you do this?
You could do this by creating a new facet. This new facet could import a struct that you have already been using and sharing and you could append those 6 new state variables to it. Or the new facet could declare a new struct with the 6 new state variables. Either way works.
So this new facet contains 5 new external functions that use 6 new variables.
You deploy your new facet and verify its source code. Then you execute diamondCut to add those 5 new functions. Now you are done. There was no reason to replace any of the existing functionality in the diamond because they don't use the new state variables. If you wanted to modify one of your existing external functions to use a new state variable then you could replace that one. You would not have to replace other external functions that did not change. But you could replace all the external functions from the same facet so that these functions continued to come from the same deployed facet just as an organizational neatness. You can do what you want.
Follow the upgrade rules from the article here: https://eip2535diamonds.substack.com/p/diamond-upgrades
Question: "To upgrade a diamond with new state variables do I need to deploy a completely new diamond and copy all the state variable content to the new diamond and also redeploy all the facets with a new LibDiamond?"
Absolutely not! You only have to add new external functions to the diamond, and you only have to replace existing external functions that you changed to use new state variables that you added. You donât have to replace external functions in a diamond that do not change or use new state variables.
A more technical explanation of upgrades is here: How Diamond Upgrades Work
An example of an upgrade can be found here:
Nice! I've been mentally modelling this as a bipartite graph between state variables and external functions with a 1 to 1..N relationship.
Seems like a lot of the insight/patterns of managing diamonds will come in handy with transient storage too.