Hi @Nadim,
Welcome to the community
I recommend using OpenZeppelin Upgrades Plugins for Truffle and Hardhat if you want to deploy and test upgradeable contracts: https://docs.openzeppelin.com/upgrades-plugins/1.x/
There isn’t an Upgrades Plugin for Remix, so you would need to deploy the implementation contract, followed by the proxy (and optionally a ProxyAdmin) yourself. The Upgrades Plugins perform upgrade safety checks and make it easy to write high level tests for upgradeable contracts.
I suggest looking at the following Step by Step Tutorials:
- OpenZeppelin Upgrades: Step by Step Tutorial for Truffle
- OpenZeppelin Upgrades: Step by Step Tutorial for Hardhat
I created a very simple example ERC20 contract and deployed it to the inbuilt Truffle development network (using the setup from the Step by Step tutorial for Truffle).
MyToken.sol
This example token has a fixed supply that is minted to the deployer of the contract.
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol";
contract MyToken is Initializable, ERC20Upgradeable {
function initialize(string memory name, string memory symbol, uint256 initialSupply) public virtual initializer {
__ERC20_init(name, symbol);
_mint(_msgSender(), initialSupply);
}
}
2_deploy_token.js
The token is initialized with the name, symbol and the initial supply.
// migrations/2_deploy_token.js
const MyToken = artifacts.require('MyToken');
const { deployProxy } = require('@openzeppelin/truffle-upgrades');
module.exports = async function (deployer) {
await deployProxy(MyToken, ['My Token', 'TKN', '100000000000000000000000'], { deployer, initializer: 'initialize' });
};
Truffle console
I deployed the token using migrate
and then interacted with the upgradeable contract.
$ npx truffle develop
Truffle Develop started at http://127.0.0.1:9545/
...
truffle(develop)> migrate
Compiling your contracts...
===========================
> Compiling ./contracts/Migrations.sol
> Compiling ./contracts/MyToken.sol
...
Starting migrations...
======================
> Network name: 'develop'
> Network id: 5777
> Block gas limit: 6721975 (0x6691b7)
1_initial_migration.js
======================
...
2_deploy_token.js
=================
Deploying 'MyToken'
-------------------
> transaction hash: 0x508efaac2ff912035645518ee02aee25d11403728d8acf37aca2d7c2d635e7bb
> Blocks: 0 Seconds: 0
> contract address: 0xDEE9411430c7Dd9b67fC6DA723DE729AdAB50AD7
...
Deploying 'ProxyAdmin'
----------------------
> transaction hash: 0xd254a960020144c71ab1e28164cd6d91d53cea238f4ca109fb05f0594fe6e5ba
> Blocks: 0 Seconds: 0
> contract address: 0xc105BA878b6dE2472D441F0f2C4709fA622208f3
...
Deploying 'AdminUpgradeabilityProxy'
------------------------------------
> transaction hash: 0x4367f909eb988d940a1df1dc8788b76bf7b2cb60bc859b56d7519a453ecec98d
> Blocks: 0 Seconds: 0
> contract address: 0xB715B0DAF6097Be133A1E09AF21a84719582E720
...
truffle(develop)> token = await MyToken.deployed()
undefined
truffle(develop)> token.address
'0xB715B0DAF6097Be133A1E09AF21a84719582E720'
truffle(develop)> token.name()
'My Token'
truffle(develop)> token.symbol()
'TKN'
truffle(develop)> (await token.totalSupply()).toString()
'100000000000000000000000'
truffle(develop)> (await token.balanceOf(accounts[0])).toString()
'100000000000000000000000'