I'm studing proxy upgradeable contracts and there are several questions I'm stuck into. Would you mind to clarify it to me?
The first question:
So I got it right, if I want to use a transparent proxy I should use TransparentUpgradeableProxy.sol as my proxy contract and create a logic contract with Initializable.sol and upgradeable libs.
If I want to use upps proxy I should create a logic contract with UUPSUpgradeable, Initializable and other upgradeable libs and for proxy contract I have to use ERC1967Proxy.sol.
Is that correct?
And the second question:
If I use OpenZeppelin wizard to create, let's say, upgradeable ERC20 contract, I'll get this:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
contract MyToken is Initializable, ERC20Upgradeable {
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
function initialize() initializer public {
__ERC20_init("MyToken", "MTK");
}
}
I different tutorial I saw that contract should be deployed with hardhat, aw well as updated with it.
However I do not understand where is a proxy contract in it?
Where can I find its address?
And if I don't want to update it with hardhat does there any other way to do it?
Thanks in advance! I hope I made a clear enough questions.
However I do not understand where is a proxy contract in it?
The code from Wizard is for the implementation (logic) contract only. You can use Hardhat Upgrades plugin to help deploy the proxy contract -- the plugin deploys TransparentUpgradeableProxy.sol or ERC1967Proxy.sol using precompiled bytecode.
Where can I find its address?
Which address are you referring to?
And if I don't want to update it with hardhat does there any other way to do it?
You can use Truffle, Remix, or you can do things manually.
If you are not using Hardhat or Truffle, you should still run tests to validate for upgrade safety, for example using the @openzeppelin/upgrades-core library from a JavaScript project. (The Hardhat or Truffle plugins would perform these validations automatically).
how can I find proxy contract address if I use wizard to create a logic contract and deploy it via hardhat?
When you call the deployProxy function, it returns a contract instance representing the proxy, where you can call .address on the object. See this example.
How can I do it manually If I used hardhat to deploy it?
You can call the upgradeTo(address newImplementation) function on the proxy contract. But if you used Hardhat to deploy it, I strongly suggest to continue using Hardhat when you want to upgrade it so that it will automatically perform upgrade safety checks.
Thanks for clarifing these questions for me! You are the only perspn who made it clear.
And the last question:
In terms of proxy contracts we use Initializable.sol for logic contracts. So I'd like to know where uint8 private _initialized and bool private _initializing are stored: in proxy contract or in logic contract?
I'm tring to understand that if it is stored in proxy contract so how we can update these variables with the next updated logic contract?
In terms of proxy contracts we use Initializable.sol for logic contracts. So I'd like to know where uint8 private _initialized and bool private _initializing are stored: in proxy contract or in logic contract?
It is stored in the context of the proxy's address. More broadly, ALL storage variables that you use in your logic are actually stored in the context of the proxy's address, not the logic contract's address.
how we can update these variables with the next updated logic contract?
You can do this by creating a function in your updated logic contract to use the reinitializer modifier, and call that function during upgrade. (If using the Hardhat Upgrades plugin, when you call upgradeProxy, that function name or signature should be provided to the call option.)