How do upgrades work?

Thanks for your response, @abcoathup!

I have another question: the openzeppelin-labs example shows an inheritance to persist state between version (

I wrote a solidity example, OP create and then OP verify.

Then OP upgrade and OP verify.

In this case, there is no inheritance. How does it persist state between versions?


1 Like

Hi @nogueiradalmeida,

I assume you mean openzeppelin or oz when you say OP.

To understand how OpenZeppelin Upgrades work I suggest you read (if you haven’t already) about the “unstructured storage” proxy pattern in the documentation.

You don’t need to use inheritance between different versions of the contract (though you can).

I moved this to a new topic, as I think it makes it easier for the community to answer if it is a question (or a subject) per topic.

Feel free to ask all the questions that you need.

1 Like

Yes, thanks!

Please consider that you have a state variable X in a LogicContract implementation v0. X was set to value 1, for instance.
Then you do upgrade using OpenZeppelin to LogicContract implementation v1.
Therefore the autogenerated Proxy will now delegatecall to v1.

How does OpenZeppelin is able to hold the state variable X, in a way that v1 keeps X’s value (1) that was set on v0?

1 Like

Hi @nogueiradalmeida,
A very important thing to note is that the code makes use of the EVM’s delegatecall opcode which executes the callee’s code in the context of the caller’s state. That is, the logic contract controls the proxy’s state and the logic contract’s state is meaningless. Thus, the proxy doesn’t only forward transactions to and from the logic contract, but also represents the pair’s state. The state is in the proxy and the logic is in the particular implementation that the proxy points to.

This means that the state of variable X defined in the logic contracts (both in v0 and v1) is stored in the proxy contract and hence the value doesn’t change when the logic contract that the proxy points to is upgraded from v0 to v1.

1 Like