The initialize function will be called only on time, so you can't just update it's parameters and reuse it.
What I'd do in your case is:
- keep the same initialize method definition
- add your new variable at the end of the storage
- add a new method
setXto update the value and a getter -getX - upgrade to
BoxV2 - call the
setXmethod to update the variable value
// contracts/Box.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
contract Box is Initializable {
uint256 public value;
uint256 public x;
function initialize(uint256 _value) public initializer {
value = _value;
}
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
// Emitted when the stored value changes
event ValueChanged(uint256 newValue);
// Stores a new value in the contract
function store(uint256 newValue) public {
value = newValue;
emit ValueChanged(newValue);
}
// Reads the last stored value
function retrieve() public view returns (uint256) {
return value;
}
function setX(uint256 newValue) public {
x = newValue;
}
function getX() public view returns (uint256) {
return x;
}
}
Or you have the following alternative: When is initialize() called? - #3 by frangio