Hardhat-deploy: μ—…κ·Έλ ˆμ΄λ“œ κ°€λŠ₯ν•œ 계약 배포에 λŒ€ν•œ 질문

에 λ§Œλ“  2021λ…„ 06μ›” 08일  Β·  9μ½”λ©˜νŠΈ  Β·  좜처: wighawag/hardhat-deploy

OpenZeppelin μ—…κ·Έλ ˆμ΄λ“œ κ°€λŠ₯ 계약을 λ°°ν¬ν•˜λŠ” μ˜¬λ°”λ₯Έ 방법은 λ¬΄μ—‡μž…λ‹ˆκΉŒ?
OpenZeppelin upgrdableμ—λŠ” hardhat μ—…κ·Έλ ˆμ΄λ“œ ν”ŒλŸ¬κ·ΈμΈμ— μ˜ν•΄ ν˜ΈμΆœλ˜λŠ” κΈ°λ³Έ initialize() ν•¨μˆ˜κ°€ μžˆμŠ΅λ‹ˆλ‹€.
hardhat-deployμ—μ„œ μžλ™ ν˜ΈμΆœμ€ μ—†μœΌλ©° ν˜ΈμΆœν•  수 μžˆλŠ” 사후 μ—…κ·Έλ ˆμ΄λ“œ λ©”μ„œλ“œλ§Œ μžˆμŠ΅λ‹ˆλ‹€.

λ¨Όμ € 배포 ν΄λ”μ˜ 슀크립트λ₯Ό 톡해 계약을 λ°°ν¬ν•œ λ‹€μŒ 배포 폴더 μ™ΈλΆ€μ˜ 일뢀 μŠ€ν¬λ¦½νŠΈμ—μ„œ μ΄ˆκΈ°ν™” κΈ°λŠ₯을 ν˜ΈμΆœν•΄μ•Ό ν•©λ‹ˆκΉŒ? μ•„λ‹ˆλ©΄ 배포 폴더 μžμ²΄μ—μ„œ ν˜ΈμΆœν•˜λŠ” initialize() ν•¨μˆ˜λ₯Ό ν†΅ν•©ν•˜λŠ” 방법이 μžˆμŠ΅λ‹ˆκΉŒ?

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

ν”„λ‘μ‹œμ— λŒ€ν•œ μž¬μ΄ˆκΈ°ν™” κΈ°λŠ₯

hardhat-deploy 0.8.0에 μƒˆ μ˜΅μ…˜(아직 μ‚¬μš© κ°€λŠ₯ν•œ methodName λŒ€μ‹ )을 μΆ”κ°€ν–ˆμŠ΅λ‹ˆλ‹€.

https://github.com/wighawag/template-ethereum-contracts/blob/595c1b5ec9cdf1276f4d3a43b4825bcef78bd2cd/deploy/004_deploy_erc20_always_proxied_via_openzeppelin#_proxy.ts λ₯Ό μ°Έμ‘°ν•˜μ‹­μ‹œμ˜€

λ¬Έμ œκ°€ λ°œμƒν•˜λ©΄ μ•Œλ €μ£Όμ‹­μ‹œμ˜€.

λͺ¨λ“  9 λŒ“κΈ€

hardhat-deployκ°€ 기본적으둜 배포 슀크립트λ₯Ό κ³ λ €ν•˜λŠ” 방식은 λ©±λ“±μ„±μž…λ‹ˆλ‹€. ν”„λ‘μ‹œ 배포에도 λ™μΌν•˜κ²Œ μ μš©λ©λ‹ˆλ‹€. 이것은 당신이 μ›ν•˜λŠ” μƒνƒœμ— λŒ€ν•΄μ„œλ§Œ μƒκ°ν•˜λ©΄ 되고 hardhat-deployκ°€ λͺ¨λ“  것을 κ·Έ μƒνƒœμ— λ„λ‹¬ν•˜λ„λ‘ λ§Œλ“€ κ²ƒμ΄λ―€λ‘œ 개발/배포에 μœ μš©ν•©λ‹ˆλ‹€.

κ·Έλž˜μ„œ κ·€ν•˜μ˜ μ§ˆλ¬Έμ— λŒ€λ‹΅ν•˜κΈ° μœ„ν•΄, μ œκ°€ 일반적으둜 ν•˜λŠ” 일은 μ΄ˆκΈ°ν™” κΈ°λŠ₯을 λ©±λ“±μ„±μœΌλ‘œ λ§Œλ“œλŠ” κ²ƒμ΄λ―€λ‘œ 이미 μ΄ˆκΈ°ν™”λœ 경우 κ·Έλƒ₯ κ±΄λ„ˆλ›°λŠ” λŒ€μ‹  λ˜μ§€μ‹­μ‹œμ˜€. λ”°λΌμ„œ ν•΄λ‹Ή κΈ°λŠ₯을 postUpgrade κΈ°λŠ₯으둜 μΆ”κ°€ν•  수 있으며 λͺ¨λ‘ 잘 μž‘λ™ν•©λ‹ˆλ‹€. 개발 쀑에 ν•„μš”ν•œ 경우 μ—…κ·Έλ ˆμ΄λ“œν•  λ•Œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λ„λ‘ μ΄ˆκΈ°ν™” κΈ°λŠ₯을 λ³€κ²½ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

더 λ³΅μž‘ν•œ μ‹œλ‚˜λ¦¬μ˜€μ˜ 경우 각 μ—…κ·Έλ ˆμ΄λ“œλ₯Ό λ³„λ„μ˜ 배포 슀크립트둜 ꡬ성할 수 μžˆμŠ΅λ‹ˆλ‹€.

변경될 수 μžˆλŠ” λ¬Έμ„œν™”λ˜μ§€ μ•Šμ€ κΈ°λŠ₯이 μžˆμŠ΅λ‹ˆλ‹€. upgradeIndex λ§€κ°œλ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄ μˆœμ„œλŒ€λ‘œ μ‹€ν–‰ν•΄μ•Ό ν•˜λŠ” 배포 슀크립트λ₯Ό 지정할 수 μžˆμŠ΅λ‹ˆλ‹€.

μ—…κ·Έλ ˆμ΄λ“œ 기둝 μ‚¬μ΄μ˜ μ–΄λŠ μ‹œμ μ—μ„œλ‚˜ yoru ν”„λ‘μ‹œλ₯Ό ν…ŒμŠ€νŠΈν•˜κ³  λͺ¨λ“  μž‘λ™μ„ 확인할 수 μžˆμœΌλ―€λ‘œ ν…ŒμŠ€νŠΈμ— μ ν•©ν•©λ‹ˆλ‹€.

λΉ λ₯Έ λ‹΅λ³€ κ°μ‚¬ν•©λ‹ˆλ‹€.
λͺ¨λ“  μž‘μ—…μ„ μ›ν™œν•˜κ²Œ μˆ˜ν–‰ν•  수 μžˆμ—ˆλ˜ 것 κ°™μŠ΅λ‹ˆλ‹€. OpenZeppelin Initializable κΈ°λ³Έ κ³„μ•½μ˜ initialize deploy() λ₯Ό μ‚¬μš©ν•œ λ‹€μŒ execute λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€. execute() λŠ” trueλ₯Ό λ°˜ν™˜ν•˜λ―€λ‘œ 계약을 μ—…κ·Έλ ˆμ΄λ“œν•  λ•Œ μ‹€ν–‰λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

// deploy/01_deploy_skin_rewards.js

module.exports = async ({
  getNamedAccounts,
  deployments,
}) => {
  const {deploy} = deployments;
  const {deployer} = await getNamedAccounts();
  await deploy('SkinRewards', {
    from: deployer,
    proxy: {
      owner: deployer,
      proxyContract: 'OpenZeppelinTransparentProxy',
    },
    args: [],
    log: true,
  });
};
module.exports.tags = ['SkinRewards'];

그리고

// deploy/02_init_skin_rewards.js

require('dotenv').config();
const RewardPeriods = ethers.BigNumber.from(process.env.REWARD_PERIODS);
module.exports = async ({getNamedAccounts, deployments}) => {
  const { deployer } = await getNamedAccounts();
  const SnookGame = await deployments.get('SnookGame');
  const SnookState = await deployments.get('SnookState');
  const SnookToken = await deployments.get('SnookToken');
  const SkillToken = await deployments.get('SkillToken');
  const Afterdeath = await deployments.get('Afterdeath');
  const Treasury = await deployments.get('Treasury');

  await deployments.execute(
    'SkinRewards',
    {from:deployer},
    'initialize',
    RewardPeriods,
    Treasury.address,
    SnookGame.address,
    SnookState.address,
    SnookToken.address,
    SkillToken.address,
    Afterdeath.address
  );
  deployments.log('Initialized SkinRewards');
  return true;
};
module.exports.tags = ['initSkinRewards'];
module.exports.id = 'initSkinRewards';

이 방법이 _쒋은 μŠ΅κ΄€_으둜 간주될 수 μžˆμŠ΅λ‹ˆκΉŒ? 당신이 그것을 μ°ΎλŠ” λ°©λ²•μž…λ‹ˆκΉŒ?

μœ„μ—μ„œ μ–ΈκΈ‰ν–ˆλ“―μ΄ SkinRewards μ—μ„œλŠ” initialize() ν•¨μˆ˜κ°€ λ¨Όμ € ν˜ΈμΆœλ˜λ„λ‘ μ •μ˜ν•˜λŠ” OpenZeppelin의 Initializable 계약을 μƒμ†ν•©λ‹ˆλ‹€. λ”°λΌμ„œ 사후 μ—…κ·Έλ ˆμ΄λ“œλ₯Ό μ‹€ν–‰ν•˜λŠ” 방법을 μ•Œ 수 μ—†μŠ΅λ‹ˆλ‹€. μ„€λͺ…ν•΄μ£Όμ‹€ 수 μžˆλ‚˜μš”? 감사 ν•΄μš”

쒋은 것 κ°™μŠ΅λ‹ˆλ‹€. methodName ("postUpgrade")λ₯Ό μ‚¬μš©ν•˜λŠ” 것과 비ꡐ할 λ•Œ 단점은 1 λŒ€μ‹  2 txλ₯Ό μ‹€ν–‰ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

μ΄ˆκΈ°ν™” ν•¨μˆ˜λ₯Ό λ©±λ“±μˆ˜λ‘œ λ§Œλ“€λ©΄ μΆ”κ°€ 호좜이 μƒνƒœλ₯Ό μˆ˜μ •ν•˜μ§€ μ•ŠλŠ”μ§€ ν™•μΈν•˜μ—¬ λ˜μ§€μ§€ μ•Šκ³  μ—¬λŸ¬ 번 ν˜ΈμΆœν•  수 μžˆμŠ΅λ‹ˆλ‹€(이미 μ΄ˆκΈ°ν™”λœ 경우 κ±΄λ„ˆλ›°κΈ°). 그러면 methodName μ˜΅μ…˜μ„ 톡해 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. . 첫 번째 λ°°ν¬μ—μ„œλ„ μ‹€ν–‰λ©λ‹ˆλ‹€.

인수λ₯Ό μ‚¬μš©ν•˜κ³  배포 κΈ°λŠ₯이 μ„€μ •λ˜μ–΄ ν”„λ‘μ‹œ μ˜΅μ…˜μ„ 끄고 λ³€κ²½ν•  수 μ—†λŠ” 계약이 μž‘λ™ν•˜λ„λ‘ ν•˜κΈ° λ•Œλ¬Έμ— methodName #$ μ˜΅μ…˜μ€ μΈμˆ˜μ— args μ˜΅μ…˜μ„ μ‚¬μš©ν•©λ‹ˆλ‹€.
μ΄λŠ” ν”„λ‘μ‹œ κ΅¬ν˜„μ˜ μƒμ„±μžμ—λ„ μ΄λŸ¬ν•œ μΈμˆ˜κ°€ μžˆμ–΄μ•Ό 함을 μ˜λ―Έν•©λ‹ˆλ‹€. ν”„λ‘μ‹œ 없이 계약을 μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ €λ©΄ 인수둜 아무 것도 ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

μ‹€μ œλ‘œ 편의λ₯Ό μœ„ν•΄ κ΅¬ν˜„ 계약에 arg construtcorκ°€ 0이면 μƒμ„±μžλ₯Ό μ™„μ „νžˆ λ¬΄μ‹œν•˜μ§€λ§Œ 그것이 쒋은 생각인지 ν™•μ‹ ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

methodName μ˜΅μ…˜μ΄ μžˆλŠ” μŠ€ν¬λ¦½νŠΈλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

// deploy/01_deploy_skin_rewards.js

module.exports = async ({
  getNamedAccounts,
  deployments,
}) => {
  const {deploy} = deployments;
  const {deployer} = await getNamedAccounts();
  await deploy('SkinRewards', {
    from: deployer,
    proxy: {
      methodName: 'initialize`,
      owner: deployer,
      proxyContract: 'OpenZeppelinTransparentProxy',
    },
    args: [
      RewardPeriods,
      Treasury.address,
      SnookGame.address,
      SnookState.address,
      SnookToken.address,
      SkillToken.address,
      Afterdeath.address
    ],
    log: true,
  });
};
module.exports.tags = ['SkinRewards'];

_μ΄ˆκΈ°ν™” ν•¨μˆ˜λ₯Ό λ©±λ“±μ„±μœΌλ‘œ λ§Œλ“œλŠ” 경우, 즉 μΆ”κ°€ 호좜이 μƒνƒœλ₯Ό μˆ˜μ •ν•˜μ§€ μ•ŠλŠ”μ§€ ν™•μΈν•˜μ—¬(이미 μ΄ˆκΈ°ν™”λœ 경우 λ‹¨μˆœνžˆ κ±΄λ„ˆλ›°μ–΄) throwν•˜μ§€ μ•Šκ³  μ—¬λŸ¬ 번 ν˜ΈμΆœν•  수 있으면 methodName μ˜΅μ…˜μ„ 톡해 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 첫 번째 λ°°ν¬μ—μ„œλ„ μ‹€ν–‰λ©λ‹ˆλ‹€._

즉, https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/release-v4.0/contracts/proxy/utils/Initializable.sol μ—μ„œ initialize() ν•¨μˆ˜λ₯Ό κ·ΈλŒ€λ‘œ μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€. .

@freebyte 참으둜

λ‚˜λŠ” 이런 μ’…λ₯˜μ˜ 행동을 μ–»κΈ° μœ„ν•΄ μ˜΅μ…˜μ„ μΆ”κ°€ν•˜λŠ” 것을 κ³ λ €ν•  κ²ƒμž…λ‹ˆλ‹€.

μ’‹μ•„μš”, κ°μ‚¬ν•©λ‹ˆλ‹€!

또 λ‹€λ₯Έ μ§ˆλ¬Έμ€ 배포된 계약 μ‚¬μš©μ— κ΄€ν•œ κ²ƒμž…λ‹ˆλ‹€. 특히 Uniswap 에 λŒ€ν•΄ 묻고 μžˆμŠ΅λ‹ˆλ‹€.

ν”ŒλŸ¬κ·ΈμΈ λ¬Έμ„œ 의 이 λΆ€λΆ„μ—μ„œ 배포된 Uniswap κ³„μ•½μ˜ μ£Όμ†Œλ₯Ό μ œκ³΅ν•˜λŠ” 방법을 λ³Ό 수 μ—†μŠ΅λ‹ˆλ‹€. Uniswap NPM은 μ•„ν‹°νŒ©νŠΈκ°€ μžˆλŠ” build 폴더와 ν•¨κ»˜ μ œκ³΅λ˜μ§€λ§Œ ν”ŒλŸ¬κ·ΈμΈμ΄ νŠΉμ • μ£Όμ†Œμ˜ 계약에 λŒ€ν•΄ μ•Œλ„λ‘ ν•˜λ €λ©΄ μ–΄λ–»κ²Œ ν•΄μ•Ό ν•©λ‹ˆκΉŒ? μš°λ¦¬λŠ” 배포 μŠ€ν¬λ¦½νŠΈμ—μ„œ etherλ₯Ό μ‚¬μš©ν•˜κ³  싢지 μ•ŠμŠ΅λ‹ˆλ‹€. κ·Έλ ‡μ£ ?

λ‹€μŒ μ½”λ“œλŠ” 배포 μŠ€ν¬λ¦½νŠΈμ—μ„œ μ›ν•˜λŠ” 것이 μ•„λ‹™λ‹ˆλ‹€.

const { ethers } = require("hardhat");

const UniswapV2FactoryArtifact = require('@uniswap/v2-core/build/UniswapV2Factory.json');
const UniswapV2FactoryAddress = '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f';

module.exports = async ({getNamedAccounts, deployments}) => {
  const {deployer} = await getNamedAccounts();
  const UniswapFactory = await ethers.getContractAt(UniswapV2FactoryArtifact.abi, UniswapV2FactoryAddress);
// continue...

deployments var에 Uniswap 배포λ₯Ό κ°€μ Έμ˜€λ €λ©΄ μ–΄λ–»κ²Œ ν•©λ‹ˆκΉŒ?

이미 배포된 κ³„μ•½μ˜ 경우 ν•΄λ‹Ή 배포 폴더에 νŒŒμΌμ„ λ§Œλ“œλŠ” 것이 κ°€μž₯ μ’‹μŠ΅λ‹ˆλ‹€.
λ”°λΌμ„œ 메인넷 uniswap의 경우 hardhat.config.js에 메인넷 λ„€νŠΈμ›Œν¬κ°€ κ΅¬μ„±λ˜μ–΄ μžˆλ‹€κ³  κ°€μ •ν•˜λ©΄ "deployments/mainnet/UniswapFactory.json" νŒŒμΌμ„ 생성할 수 μžˆμŠ΅λ‹ˆλ‹€. μ΅œμ†Œν•œ μ£Όμ†Œμ™€ BI ν•„λ“œκ°€ ν•„μš”ν•©λ‹ˆλ‹€.

그런 λ‹€μŒ ν•΄λ‹Ή λ„€νŠΈμ›Œν¬μ— μžˆμ„ λ•Œ 배포λ₯Ό 톡해 μ•‘μ„ΈμŠ€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ•„ν‹°νŒ©νŠΈ(uniswap λΉŒλ“œ 폴더)에 μ•‘μ„ΈμŠ€ν•˜κ±°λ‚˜ 슀크립트λ₯Ό 배포할 수 μžˆλ„λ‘ κ°€λ¦¬ν‚€λŠ” λ¬Έμ„œ 링크, κ·ΈλŸ¬λ‚˜ ν›„μžλŠ” ν•΄λ‹Ή ν”„λ‘œμ νŠΈκ°€ μ΄λŸ¬ν•œ 배포 슀크립트λ₯Ό μ–΄λ”˜κ°€μ— λ…ΈμΆœν•œ κ²½μš°μ—λ§Œ μž‘λ™ν•©λ‹ˆλ‹€.

https://github.com/wighawag/universal-forwarder 와 같은 λ‚΄ ν”„λ‘œμ νŠΈμ—μ„œ 이λ₯Ό μˆ˜ν–‰ν•˜μ—¬ μ‚¬μš©μžκ°€ npm νŒ¨ν‚€μ§€λ₯Ό μ„€μΉ˜ν•˜κΈ°λ§Œ ν•˜λ©΄ 전체 ν”„λ‘œμ νŠΈλ₯Ό ν…ŒμŠ€νŠΈ λ˜λŠ” 자체 λ„€νŠΈμ›Œν¬μ— 배포할 수 μžˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ uniswap은 그것을 μ œκ³΅ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€

μ—„μ²­λ‚œ. 정말 κ°μ‚¬ν•©λ‹ˆλ‹€.

ν”„λ‘μ‹œμ— λŒ€ν•œ μž¬μ΄ˆκΈ°ν™” κΈ°λŠ₯

hardhat-deploy 0.8.0에 μƒˆ μ˜΅μ…˜(아직 μ‚¬μš© κ°€λŠ₯ν•œ methodName λŒ€μ‹ )을 μΆ”κ°€ν–ˆμŠ΅λ‹ˆλ‹€.

https://github.com/wighawag/template-ethereum-contracts/blob/595c1b5ec9cdf1276f4d3a43b4825bcef78bd2cd/deploy/004_deploy_erc20_always_proxied_via_openzeppelin#_proxy.ts λ₯Ό μ°Έμ‘°ν•˜μ‹­μ‹œμ˜€

λ¬Έμ œκ°€ λ°œμƒν•˜λ©΄ μ•Œλ €μ£Όμ‹­μ‹œμ˜€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰