Hi @ethicraul,
We can’t use the initializer
modifier for initializing state in an upgrade, if it was already used for initializing state in the original version. I assume this why the upgrade is reverting.
Instead we need to create a custom guard to ensure that any upgrade function is only called once.
If you already have a version you could do a check something like the following:
function upgradeToV2() public {
require(_version < 2, "MyContract: Already upgraded to version 2");
_version = 2;
}
Upgrade initialization should be appropriately tested and audited.
The following simple example hasn’t been tested.
MyContract.sol
// contracts/MyContract.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "@openzeppelin/upgrades/contracts/Initializable.sol";
contract MyContract is Initializable {
uint256 private _version;
function initialize() public initializer {
_version = 1;
}
}
MyContract.sol (upgraded)
// contracts/MyContract.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import "@openzeppelin/upgrades/contracts/Initializable.sol";
contract MyContract is Initializable {
uint256 private _version;
function initialize() public initializer {
_version = 1;
}
function upgradeToV2() public {
require(_version < 2, "MyContract: Already upgraded to version 2");
_version = 2;
}
}
Deploy
$ npx oz deploy
Nothing to compile, all contracts are up to date.
? Choose the kind of deployment upgradeable
? Pick a network development
? Pick a contract to deploy MyContract
✓ Added contract MyContract
✓ Contract MyContract deployed
All implementations have been deployed
? Call a function to initialize the instance after creating it? Yes
? Select which function * initialize()
✓ Setting everything up to create contract instances
✓ Instance created at 0x254dffcd3277C0b1660F6d42EFbB754edaBAbC2B
To upgrade this instance run 'oz upgrade'
0x254dffcd3277C0b1660F6d42EFbB754edaBAbC2B
Upgrade
$ npx oz upgrade
? Pick a network development
? Which instances would you like to upgrade? Choose by address
? Pick an instance to upgrade MyContract at 0x254dffcd3277C0b1660F6d42EFbB754edaBAbC2B
? Call a function on the instance after upgrading it? Yes
? Select which function upgradeToV2()
Nothing to compile, all contracts are up to date.
✓ Contract MyContract deployed
All implementations have been deployed
✓ Instance upgraded at 0x254dffcd3277C0b1660F6d42EFbB754edaBAbC2B. Transaction receipt: 0x1f8958e5541d32684013244835c4fbcfa61d68b395c650051e7e86b481087a35
✓ Instance at 0x254dffcd3277C0b1660F6d42EFbB754edaBAbC2B upgraded
As an aside, we released OpenZeppelin Upgrades Plugins for Buidler and Truffle so that we can upgrade in Buidler and Truffle.