ReInitialize
reInitializeについて学習します
reInitializeはupgradeToを呼んだ際に追加で変数をinitializeするために用いられます
reInitialize
initializerは実装コントラクトを最初にデプロイしたときに利用されるのに対して、reInitializerは2回目以降のアップグレードに用いられる
引数に明示的にバージョンを指定することでアップグレードの間違い・競合を防ぐ
またバージョンはuint64で管理されており、アップグレーダビリティを放棄する際にはuint64の最大値を格納することで実質的にアップグレード不可能にするという措置が取られる
contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
function initializeV2() reinitializer(2) public {
__ERC20Permit_init("MyToken");
}
}
modifier reinitializer(uint64 version) {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing || $._initialized >= version) {
revert InvalidInitialization();
}
$._initialized = version;
$._initializing = true;
_;
$._initializing = false;
emit Initialized(version);
}
function _disableInitializers() internal virtual {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing) {
revert InvalidInitialization();
}
if ($._initialized != type(uint64).max) {
$._initialized = type(uint64).max;
emit Initialized(type(uint64).max);
}
}