체인의정석

스마트컨트렉트 배포 시 hardhat etherscan verify 로직 추가 본문

블록체인/Ethers & web3

스마트컨트렉트 배포 시 hardhat etherscan verify 로직 추가

체인의정석 2022. 2. 15. 18:14
728x90
반응형

스마트컨트렉트를 배포할 때 이더스캔에 대한 apikey가 있으면 이더스캔에서 verify를 할 수 있다.

어차피 프로덕트레벨로 운영을 해야하면 진행을 해야 하며,

실제 테스트네트워크에서 값을 확인할 때도 tenderly 같은 툴을 사용하여 분석을 할 수 있기 때문에 로컬 테스트레벨이 아닌 공식 테스트넷 레벨의 테스트 단계부터는 이더스캔에서 verify하는 작업이 필요하다.

 

3년전에 개발을 할때는 falt한 컨트렉트를 만드느라고 매우 고생을 했었는데 요즘에는 툴이 발달하여 이더스캔 api키를 이용하여 이더스캔 verify를 배포시에 할 수 있다. 특히 스마트컨트렉트 개발자로서 병목이 항상 스마트컨트렉트이기 때문에 개발할 때 한사이클을 먼저 만들어주는 역할이 중요하기 때문에 이 작업은 로컬 테스트가 끝나자마자 진행을 해주면 좋은것 같다.

 

https://forum.openzeppelin.com/t/how-to-verify-with-hardhat-or-truffle-a-smart-contract-using-openzeppelin-contracts/4119

 

How to verify with Hardhat or Truffle a smart contract using OpenZeppelin Contracts

For a complete list of resources regarding verification visit How to verify a contract on Etherscan/BscScan/PolygonScan. The recommended way to verify a smart contract inheriting from OpenZeppelin Contracts is as a "multi-file" contract (corresponding to t

forum.openzeppelin.com

역시 오랜만에 하려니 기억이 나지 않아 구글에 검색을 해서 진행을 하였다.

 

require('@nomiclabs/hardhat-ethers');
require("@nomiclabs/hardhat-etherscan");
/**
 * @type import('hardhat/config').HardhatUserConfig
 */
module.exports = {

  networks: {
    rinkeby: {
      url: `https://rinkeby.infura.io/v3/${infuraProjectId}`,
      accounts: {mnemonic: mnemonic}
    },
    ropsten: {
      url: `https://ropsten.infura.io/v3/${infuraProjectId}`,
      accounts: {mnemonic: mnemonic}
    },
    kovan: {
      url: `https://kovan.infura.io/v3/${infuraProjectId}`,
      accounts: {mnemonic: mnemonic}
    },
    goerli: {
      url: `https://goerli.infura.io/v3/${infuraProjectId}`,
      accounts: {mnemonic: mnemonic}
    },
    mainnet: {
      url: `https://mainnet.infura.io/v3/${infuraProjectId}`,
      accounts: {mnemonic: mnemonic}
    }
  },

  etherscan: {
    // Your API key for Etherscan
    // Obtain one at https://etherscan.io/
    apiKey: etherscanApiKey
  },
  solidity: "0.6.12"
};

위의 링크를 보면 config에 apiKey를 먼저 넣어주라고 한다. 물론 이걸 그대로 올리면 안되고 env 파일에 설정하여 올려주도록 한다.

 

  etherscan: {
    apiKey: process.env.etherscanApiKey
  },
  solidity: "0.5.0"

config 파일에 위와 같이 이더스캔 api key를 받고. (이 api key는 이더스캔사이트에서 무료로 발급 받을 수 있다.)

 

그리고 검증을 할 때는 아래의 명령어를 입력하면 된다고 한다.

npx hardhat verify --network mainnet DEPLOYED_CONTRACT_ADDRESS "Constructor argument 1"

이걸 보니 기억이 났는데 verify가 작동하는 순서는 deploy 이후였다. 주소만 있으면 verify가 가능하다.

 

Error HH303: Unrecognized task verify

근데 에러가 나서 찾아봤다.

https://forum.openzeppelin.com/t/error-verifying-on-etherscan-unable-to-generate-contract-bytecode-and-abi/6428/4

 

Error verifying on Etherscan: Unable to generate Contract ByteCode and ABI

Hi, Forgot to ask! In the field where it says “accounts: {mnemonic: mnemonic}”, does mnemonic mean my wallet address used to deploy the contract? I am trying to verify on Rospten. Thank you very much once again. Chloe

forum.openzeppelin.com

모듈을 하나 가져와야 한다고 한다.

 

먼저 모듈 하나 설치 

npm install --save-dev @nomiclabs/hardhat-etherscan

그후

import "@nomiclabs/hardhat-etherscan";

이걸 config에 넣어주고 다시 명령어 실행

npx hardhat verify --network ropsten "0x69a5E187587d4e101F317e5Bbd90df74bE70e7De"

그치만 역시 오류가 발생하였다.

 

일단 생성자가 있는 경우에 생성자를 추가해주어야 한다고 한다.

https://hardhat.org/plugins/nomiclabs-hardhat-etherscan.html

 

Ethereum development environment for professionals by Nomic Labs

Compile, deploy, test and debug your Ethereum software. Get Solidity stack traces, console.log, mainnet forking and more.

hardhat.org

이걸 해결하는 방법은 몇가지가 있는데 먼저 배포 시 자동으로 하는 방법!

  const ExampleERC721 = await ethers.getContractFactory("ExampleERC721");
  const exampleERC721URI = "http://babyapeclub.io/SecretFolderWithMetadata"
  const exampleERC721 = await ExampleERC721.deploy("ExampleNFT","ENFT",exampleERC721URI);

  await exampleERC721.deployed();
  console.log(`export const LUNIVERSE_ERC721_CONTRACT_ADDRESS = ${exampleERC721.address};`);
  await run("verify:verify", {
    address: exampleERC721.address,
    constructorArguments: [
      "ExampleNFT",
      "ENFT",
      exampleERC721URI
    ],
  });

위와 같이 생성자를 넣어주면서 바로 배포 로직에 넣어버리면 된다.

 

이게 아니고 이미 배포된걸 verify시키고 싶을땐 arguments.js를 만들어서 넣어주면 되는것 같다.

module.exports = [
  "ExampleNFT",
  "ENFT",
  "http://babyapeclub.io/SecretFolderWithMetadata"
];

이런식으로 파일을 만들어서 생성자를 넣어준 후 아래와 같이 배포후에 명령어로 지정해주는것이다.

npx hardhat verify --constructor-args Arguments_erc721.js --network ropsten 0x69a5E187587d44101F317e5Bbd90df74bE70e7De

근데 에러가 발생하고 해결이 또 안된다. 밑에 페이지를 보니 어쩌면 솔리디티 5버전 과 지금 환경에선 지원이 안되는 걸수도 있겠다.

 

https://github.com/rkalis/truffle-plugin-verify/issues/40

 

Failed to connect to Etherscan API at url https://api-ropsten.etherscan.io/api · Issue #40 · rkalis/truffle-plugin-verify

Help me, follow the documentation, but always fail https://api-ropsten.etherscan.io/api?apiKey=my-api-key&module=account&action=txlist&address=address&page=1&sort=asc&offset...

github.com

트러플에서 전에 했었을 땐 verify 가 원래 코드로 쉽게 되었었는데, 안되니 일단 급한마음에 수동으로 verify를 하였다.

 

최후의 방법 , 수동으로 검증받기

 

원래 스마트컨트렉트는 배포할 때 falt 컨트렉트로 만든 후 배포된다.

근데 이러한 flat contract는 일반적으로 만드려면 따로 명령어를 주어야 한다. 아니면 수동으로 붙여넣기도 한치의 오차도 없다면 되긴한다.

https://ethereum-waffle.readthedocs.io/en/latest/getting-started.html#flattener

 

Getting Started — waffle documentation

After you have successfully authored a Smart Contract you can now think about testing it. Fortunately for you, Waffle is packed with tools that help with that. Tests in waffle are written using Mocha alongside with Chai. You can use a different test enviro

ethereum-waffle.readthedocs.io

npx waffle flatten

난 와플을 사용했기 때문에 이 명령어를 쓰면 flat 한 컨트렉트를 얻을 수 있는데

이 컨트렉트를 그대로 복사해서 이더스캔에다 붙여넣어도 verify가 된다.

 

일단 오딧을 넘기기까지 컨트렉트 작성이 급하니 verify를 자동으로 시키는건 다음기회에 다시 해봐야겠다.

 

728x90
반응형
Comments