Hardhat으로 ropsten testnet에 Upgradeable Contracts 배포하기
webstrom 새로운 폴더 열고
$ npm init
-> package.json 생성됨
package.json 설치할 것 작성
{
"name": "upgradeable",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"devDependencies": {
"@nomiclabs/hardhat-ethers": "^2.0.3",
"@nomiclabs/hardhat-etherscan": "^2.1.8",
"@openzeppelin/hardhat-upgrades": "^1.12.0",
"ethers": "^5.5.2",
"hardhat": "^2.8.0"
},
"dependencies": {
"@openzeppelin/contracts": "^4.4.1",
"@openzeppelin/contracts-upgradeable": "^4.4.1"
},
"author": "",
"license": "ISC"
}
모두 설치하기
$ npm i
이 실패해서
$ npm i --force
로 진행함
$ npx hardhat
으로 프로젝트 시작
upgradeable > contracts > box.sol & boxV2.sol 파일 생성
box.sol = first version of smart contract
box.sol
* 특이점 : upgradeable contract 에는 constructor 가 올 수 없음
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
contract Box {
uint public val;
// constructor(uint _val) {
// val = _val;
// }
function initialize(uint _val) external {
val = _val;
}
}
boxV2.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
contract BoxV2 {
uint public val;
// function initialize(uint _val) external {
// val = _val;
// }
function inc() external {
val += 1;
}
}
여기선 initialize() 가 box.sol 첫번째 contract에 이미 있기때문에 주석처리 함
hardhat.config.js
require("@nomicfoundation/hardhat-toolbox");
require("@nomiclabs/hardhat-ethers");
require("@openzeppelin/hardhat-upgrades");
require("@nomiclabs/hardhat-etherscan");
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: "0.8.10",
networks: {
ropsten: {
url: `https://ropsten.infura.io/v3/${process.env.INFURA_API_KEY}`, // infura에서 가져오는 api key
accounts: [process.env.PRI_KEY] // 지갑의 private key !! ropsten 등 네트워크와 관련없이 그냥 내 지갑의 개인키
}
},
etherscan: {
apiKey: process.env.ETHERSCAN_API_KEY, // 이더스캔에서 가져오는 api key
},
};
scripts > deploy_box_v1.js 파일 생성 및 코드 작성
const { ethers, upgrades } = require("hardhat");
async function main() {
const Box = await ethers.getContractFactory("Box");
const box = await upgrades.deployProxy(Box, [42], {
initializer: "initialize",
});
await box.deployed();
console.log('Box deployed to :', box.address);
}
main()
Proxy로 배포하는 걸 가져온 Box 에 시작 함수는 initialize 인자값은 42 설정
이제 아래 명령어로 배포 실행
env $(cat .env) npx hardhat run --network ropsten scripts/deploy_box_v1.js
결과 :
Box deployed to : 0x869fd12A5367c3B3cF582690175cF5aD3E31638C
해당 주소를 받으면 etherscan ropsten testnet에 가서 배포된 거 확인해보기
배포한 계좌 주소 (내 이더 지갑 주소)로 검색하면 총 3개의 tx 이 생성되어 있고 각 contract name은 아래와 같다.
TransparentUpgradeableProxy
ProxyAdmin
Box
upgradeable contract으로 하게되면 이렇게 3개가 나오나보다... 그 중에 마지막 Box는 직접 입력한 스마트 컨트렉트 이름이다. Box tx contract 를 누르면 verify하라고 나온다.
hardhat을 사용해서 verify 하기
* 여기에 들어갈 contract address는 위에서 console.log로 나온 것이 아니라 creator 배포한 나의 지갑 주소로 들어가면 tx 3개가 나오고 거기 중 첫 tx 에 -> contract -> ByteCode로 나온 것 (verify and publish!) 라고 나온 tx의 주소를 넣어야함
env $(cat .env) npx hardhat verify --network ropsten [contract address (implemetaton one)]
verify 중 Error: ENOENT: no such file or directory, <- 요 에러가 나면
env $(cat .env) npx hardhat clear
를 한 후 다시 시도하면 잘 된다.
다시 해당 tx으로 가보면 bytecode -> 내가 작성한 solidity code들이 잘 보인다.
Contract Name : TransparentUpgradeableProxy Tx로 들어가서 -> More Options -> Is this a proxy? 클릭 -> veryfy -> 하고 다시 contract 들어가면 Reas as Proxy , Write as Proxy 가 생긴다.
Read as Proxy 하면 val -> 42가 나온다.
요 42는 Proxy contract에 저장된 것
이제 Box -> BoxV2 로 SmartContract 업그레이드 시키기
scripts > upgrade_box_v2.js 파일 생성 및 코드 작성
const { ethers, upgrades } = require("hardhat");
const PROXY = '0x3C7cf16a985FC7cc64f13eC260f55601f4D93A4D';
async function main() {
const BoxV2 = await ethers.getContractFactory("BoxV2");
await upgrades.upgradeProxy(PROXY, BoxV2);
console.log("Box upgraded");
}
main();
BoxV2 contract 가져와서 Proxy -> BoxV2로 업그레이드
hardhat 명령어 입력
env $(cat .env) npx hardhat run --network ropsten scripts/upgrade_box_v2.js
upgraded
첫번째 tx : BoxV2 배포
두번째 tx : upgrade proxy admin
upgrate() 함수로 implemetation box -> boxV2 로 업그레이드 함
첫번째 tx verify by hardhat 하고 코드보면 Box2 contract 나옴
이전 TransparentUpgradeableProxy tx로 돌아가서 다시 etherscan이 최신의 implement를 바라보도록 "More options" -> is this a Proxy ? 클릭 -> verify
-> 다시 해당 proxy contract 에서 "Write as Proxy" -> connect metatmask -> inc 함수 write 클릭 -> 그리고 이제 Read as Proxy를 클릭하면 43 이 되어 있음 ! 아까는 42
Reference : https://www.youtube.com/watch?v=JgSj7IiE4jA
'Block Chain' 카테고리의 다른 글
코인? 토큰? 모르면 손해 보는 구별법 (0) | 2022.11.05 |
---|---|
Solidity 솔리디티 기본 개념 배우기(feat.crypto zombie Lesson 1) (0) | 2022.09.13 |
[eth.getTransaction]ERC20 토큰 이체 value 알아내기 / input data value 0 (0) | 2022.04.03 |
MetaMask: 'ethereum.enable()' is deprecated and may be removed in the future. Please use the 'eth_requestAccounts' RPC method instead. (0) | 2022.03.31 |
[truffle] 이더리움 테스트넷 rinkeby에 스마트컨트랙트 배포하기 (0) | 2022.03.29 |
댓글