When is initialize() called?

I understand that initialize() is only called once ever, like a constructor.

Where I'm confused is, wouldn't every subsequent upgrade also invoke an initialize() - since each subsequent version of an upgradeable contract will probably need to initialize some state...

My question reduced to a TLDR:
Is initialize() only EVER called once during the initial proxy deployment or should it also be called on every subsequent upgrade that occurs?

Otherwise, what is the recommended approach for setting state variables in upgraded versions?


Hey @AlvaroLuken
I hope this answers your question:

initialize will normally initialize all state, and will be used during testing and so on. In an upgrade, you usually only want to initialize a subset of the state (the new state).

So you probably want to have a separate function initializeV2 that only initializes the new state that's introduced in an upgrade.

This is the reason we released "reinitializers" in OpenZeppelin Contracts 4.6. You can define something like

function initializeV2() reinitializer(2) {
  // initialize new variables

This is like an initializer function, it can only be invoked once, but note that if you had used initializer as the modifier for this function you would never be able to call it: the contract is already initialized! reinitializer(2) defines a new "version" (2 in this case) that you can initialize.

Read more in the docs.

1 Like