What's the difference between onlyInitializing and initialzer?

 function initialize(string memory name, string memory symbol, string memory baseURI_) external onlyInitializing {
        require(bytes(baseURI_).length>0, "Invalid BaseURI");
        __NFT__init(name, symbol, baseURI_);
    }

vs

 function initialize(string memory name, string memory symbol, string memory baseURI_) external initializer {
        require(bytes(baseURI_).length>0, "Invalid BaseURI");
        __NFT__init(name, symbol, baseURI_);
    }

Openzepplin Documentation reccomends using initailizer for initailizer functions (used instead for constructors in upgradable contract) while most of the upgradeable contract at @openzepplin/contracts-upgradeable use onlyInitializing.

1 Like

Hi @Richdevs,

As mentioned in the docs, your contracts can use the initializer modifier to prevent its initializer function from being invoked twice.

Whereas onlyInitializing protects an initialization function (e.g. a function that helps to initialize a parent library) so that it can only be invoked by functions with the initializer modifier, directly or indirectly.

1 Like

One way to understand it is that initializer is for public-facing functions, and onlyInitializing is protection for internal functions.

3 Likes

Just to be clear: An initialize function with an initializer modifier cannot be called after the contract deployment right? That's what it does I guess. Similarly, does reinitializer modifier provide the same protection?

More specifically:

An initialize function with an initializer modifier cannot be called after it was previously called. (You could have a contract deployed where the initializer was not called yet, so anyone can initialize it in that case. That's why it's important to initialize it at the same time as deployment, or as early as possible to avoid frontrunning).

For reinitializer, it cannot be called if it was previously initialized to the same or greater version.