I'm new to OpenZeppelin and I try to wrote upgradeable contracts, when I upgrade contract, I getting this error:
An unexpected error occurred:
Error: New storage layout is incompatible
@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36: Inserted `__gap`
> New variables should be placed after all existing inherited variables
Code to reproduce
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
import "hardhat/console.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
error GreeterError();
contract Greeter is Initializable {
string public greeting;
function initialize(string memory _greeting) public initializer {
console.log("Deploying a Greeter with greeting:", _greeting);
greeting = _greeting;
}
/// @custom:oz-upgrades-unsafe-allow constructor
// solhint-disable-next-line no-empty-blocks
constructor() initializer {}
function greet() public view returns (string memory) {
return greeting;
}
function setGreeting(string memory _greeting) public {
console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
greeting = _greeting;
}
function throwError() external pure {
revert GreeterError();
}
}
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.4;
import "hardhat/console.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
error GreeterError();
contract GreeterV2 is Initializable, OwnableUpgradeable {
string public greeting;
function initialize(string memory _greeting) public initializer {
console.log("Deploying a Greeter with greeting:", _greeting);
greeting = _greeting;
__Ownable_init();
}
/// @custom:oz-upgrades-unsafe-allow constructor
// solhint-disable-next-line no-empty-blocks
constructor() initializer {}
function greet() public view returns (string memory) {
return greeting;
}
function setGreeting(string memory _greeting) public onlyOwner {
console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
greeting = _greeting;
}
function throwError() external pure {
revert GreeterError();
}
}
import { task } from "hardhat/config";
import { TaskArguments } from "hardhat/types";
import { Greeter } from "../../types";
task("deploy:Greeter")
.addParam("greeting", "Say hello, be nice")
.setAction(async function (taskArguments: TaskArguments, { ethers, upgrades }) {
const greeterFactory = await ethers.getContractFactory("Greeter");
const greeter = <Greeter>(
await upgrades.deployProxy(greeterFactory, [taskArguments.greeting], { initializer: "initialize" })
);
await greeter.deployed();
console.log("Greeter deployed to: ", greeter.address);
});
task("upgrade:Greeter")
.setAction(async function (_, { ethers, upgrades }) {
const greeterV1 = await ethers.getContractAt("Greeter", "0xXAddressX");
const greeterV2Factory = await ethers.getContractFactory("GreeterV2");
await upgrades.upgradeProxy(greeterV1, greeterV2Factory);
console.log("Greeter upgraded");
});
Environment
Hardhat: 2.8.4
@openzeppelin/contracts-upgradeable: 4.5.1