hey everyone, I have one question that most likely is answered somewhere but I cannot find it
In the contract Initializable.sol
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
says it allows nesting only in the context of the constructor.
my question is: why does it only allow nesting in the constructor?
Hey @RenanSouza2
The reason is that vanilla Solidity supports nested constructors and an upgradeable contract can be initialized during construction. Consider the following scenario:
contract A {
constructor() public { ... }
}
contract B is A {
constructor() public A() {}
}
In this case, A's constructor runs as part of B's constructor. Previous to the addition of _disableInitializers()
, the recommendation was to initialize during construction so that the initialize
function is disabled as a consequence. However, we still support the pattern of initializing during construction, as you can see in the contracts-upgradeable tests.
By allowing this pattern, some can do the following without hitting an "already initialized" error because of nested constructors.
contract A is Initializable {
constructor() initializer { /* ... */ }
}
contract B is A {
constructor() initializer { /* ... */ }
}
Removing this behavior is something we're considering in favor of _disableInitializers
but likely won't make it into 5.0. See this issue
1 Like