Hi, I would like to close this topic cause it seems like this is a duplicated topic. Before posting, I think you should extensively search the internet and the forum for relevant posts. And please read this How do I ask a good question? to follow, thanks!
I would like to help with this but we need you to provide a lot more detail about the situation.
Are you running against Ganache or a testnet? If Ganache, is it a fork? What are the exact steps that you followed for the deployment and first upgrade, and then the second upgrade?
For the subsequent upgrades I created a new contract file and the following deployment code (note the “2” is just an example here, and was different for each subsequent attempt):
So I tried reproducing this and was able to deploy and upgrade twice a contract on Ropsten.
I suspect that the address in your migration is wrong. I would recommend to get the address programmatically instead of hardcoding it.
One way that you can do this is by reading it from the address field of the previous version, since it will be stored in the artifact. But this may be finicky and won’t work in the future unless you commit your artifact to git.
Yes, this is the address of the proxy, and it should not change once it’s been deployed.
If you run deployProxy in a migration (passing in the deployer argument), the plugin will store the proxy address in the artifact as a deployment of the contract. So this is why Token.address or Token.deployed() should be working.
I deleted the JSON file under the .openzeppelin file by mistake, which caused below error when I upgraded
Error: Proxy admin is not the one registered in the network manifest
I have fix this error.I restore the json through mock all versions upgrade process in local ganache,and get the each upgrade records,and then replace local chain net to public net contract address and txhash.Finally,it works!
I'm getting the same error while trying to upgrade a contract on Mainnet, after it was originally deployed, I made the contract's DEFAULT_ADMIN_ROLE a multisig contract and renounced the role from the deployer's address; could that be why I'm getting the error? The deployer is still the current owner of the admin contract however, so it shouldn't make a difference.
Having tried to restore manually the mainnet.json file without success, I discovered the new OpenZeppelin forceImport plugin and it worked like a charm:
@Cosimo_de_Medici_di Be careful with how you use forceImport. The contract that you pass in should be the implementation that is currently being used (e.g. the v1 contract). Then you can upgrade it to the v2 contract (and the plugin would validate that the upgrade from v1 to v2 is safe).
The way that your example is set up, that looks like an upgrade from v2 to v2 (from the plugin's point of view) so would miss some validations.
Hi @ericglau thank you very much! I just realized that in fact my deployment script ended up calling upgrade() on the proxy admin and passing the implementation address of v1 again.
Just a follow up question if I may, am I supposed to keep both v1 and v2 contracts in my project folder? I wanted the upgraded implementation to keep the same contract name as v1, since I've only done a minor change; is there a way to pass the harcoded ABI of v1 to forceImport, in order to keep only the upgraded contract file in my project folder?
@Cosimo_de_Medici_di After a contract is imported, there isn't necessarily a need to keep the source code in the project folder. So you could do this for example (assuming the actual proxy is currently using v1):
Revert the contract in the project folder to v1
forceImport with v1
Change the source code in the project folder to v2
upgradeProxy from v1 to v2
That said, it's useful to have the different versions of your contracts available so you can run local tests for upgrades.