I'm trying to deploy a contract, delete it, and then deploy it again using CREATE2 with hardhat-deploy's deterministic feature.
However, I can't seem to get my contracts to have the same address. Here are my two contracts:
Box:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
contract Box{
function version() public pure returns (uint256) {
return 1;
}
function destroy() public {
selfdestruct(payable(msg.sender));
}
}
BoxV2:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
contract BoxV2{
function version() public pure returns (uint256) {
return 2;
}
}
And here is my deploy and "upgrade" (destroy, and re-deploy deterministically) script:
module.exports = async ({ getNamedAccounts, deployments }) => {
const { deploy } = deployments
const { deployer } = await getNamedAccounts()
const box = await deploy("Box", {
from: deployer,
args: [],
deterministicDeployment: "0x1234",
})
const boxContract = await ethers.getContract("Box")
await boxContract.destroy()
const boxV2 = await deploy("BoxV2", {
from: deployer,
args: [],
deterministicDeployment: "0x1234",
})
console.log(`Box address ${box.address}`)
console.log(`BoxV2 address ${boxV2.address}`)
}
However, I get different addresses:
Box address 0x5c5457177d92B27981809C6B5a3C960E69a2Cb23
BoxV2 address 0xBCf2C4fE08453C6898E7C18eFE4AF24521196622
Best Answer
In order to use Create2 and get the same address, you have to pass the same variables:
So if your
contractBytecode
is different in create2, you'll not get the same address. To make a metamorphic contract, you'll have to deploy a proxy contract that will point to your different code. Something like this:And then, destroy the proxy contract and redeploy it with a different implementation address to wipe storage and redeploy.