Hardhat 메인넷 포크를 사용한 스마트 계약 통합 테스트

이더리움 블록체인에서 스마트 계약의 데이터와 코드는 온체인에 저장됩니다. 스마트 계약은 일반적으로 승인이 필요하거나 공용 네트워크에서 액세스할 수 없는 Web 2.0 API와 달리 무허가 방식으로 서로 상호 작용할 수 있습니다. 따라서 구성 가능성이 달성됩니다. 새로운 분산 응용 프로그램은 다른 응용 프로그램을 기반으로 만들어지고 통합될 수 있습니다.

이러한 응용 프로그램을 만들 때 다른 응용 프로그램과의 통합, 스마트 계약의 상호 작용을 테스트할 수 있는 것이 중요합니다. 예를 들어 특정 "스왑"을 Sushiswap, Uniswap, Curve 등의 교환 중 하나로 라우팅하는 Swap Aggregator 서비스를 작성한다고 가정해 보겠습니다. 계약은 다음과 같습니다.

// SwapAggregator.sol

contract SwapAggregator {
  public uint256 SUSHISWAP = 0;
  public uint256 sushiswapRouter = 0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f;

  // other variables…

  function swap(uint256 dexId, address tokenIn, address tokenOut, uint256 amountIn) external {
    if (dexId == SUSHISWAP) {
      // here goes some interaction with Sushiswap router
      ISushiswapRouter(sushiswapRouter).swap(tokenIn, tokenOut, amountIn, msg.sender);
    } // else if ...
  }

  // other methods…
}


스마트 계약이 다른 거래소의 스마트 계약과 올바르게 상호 작용하는지 확인해야 합니다. 어떻게 했니?

스마트 계약 모의



첫째, hardhat은 편리한 계약 테스트 도구를 제공합니다. 필요한 방법이 있는 단순화된 버전의 교환 계약을 작성할 수 있습니다. 예를 들어 원하는 기능이 있는 swap 메서드가 있는 SushiswapRouter 스마트 계약을 생성할 수 있습니다(해당 인터페이스는 메인넷의 SushiswapRouter 스마트 계약 인터페이스와 일치함). 살펴봅시다:

// test.js

it("Should swap through Sushiswap", async () => {
  const SushiswapRouter = await ethers.getContractFactory("SushiswapRouter");
  const sushiRouter = await SushiswapRouter.deploy();

  const SwapAggregator = await ethers.getContractFactory("SwapAggregator");
  const swapAggregator = await SwapAggregator.deploy(sushiRouter.address);

  const tx = await swapAggregator.swap(sushiswapId, USDC, 1000000)
  // validate tx receipt
})


이 접근 방식에는 몇 가지 단점이 있습니다.
  • 스마트 계약의 기능을 잘못 구현할 수 있습니다. 테스트는 로컬에서 통과하지만 스마트 계약은 메인넷에서 작동하지 않습니다.
  • 테스트 스마트 계약을 구현하는 데 시간을 할애해야 하므로 어렵습니다. 통합이 복잡할수록 수행하기가 더 어려워집니다.

  • 테스트넷에서 테스트



    두 번째 옵션은 테스트넷에 계약을 배포하고 그곳에서 통합을 적절하게 테스트하는 것입니다. 이는 좋은 옵션이며 대부분의 경우 수행해야 합니다. 그러나 때로는 불가능합니다.
  • 모든 프로젝트가 테스트넷에 배포되는 것은 아니므로 필요한 스마트 계약을 사용하지 못할 수도 있습니다.
  • 필요한 모든 데이터가 없을 수 있습니다(예: 교환을 지원하려는 특정 토큰)
  • .

    포크 메인넷



    세 번째 옵션은 메인넷의 상태와 로컬 블록체인의 통합을 확인하는 것입니다. Hardhat은 메인넷을 포크할 수 있습니다.

    발신자 documentation:

    You can start an instance of Hardhat Network that forks mainnet. This means that it will simulate having the same state as mainnet, but it will work as a local development network. That way you can interact with deployed protocols and test complex interactions locally



    메인넷에서 분기된 상태로 로컬 노드를 시작하려면:

    npx hardhat node --fork https://rpc.flashbots.net/ 
    


    이제 테스트를 실행할 수 있습니다.

    npx hardhat --network localhost test
    


    그리고 메인넷에서 컨트랙트와 상호 작용할 수 있습니다.

    // test:
    
    it("Swap should work", async () => {
      // Sushiswap router address in mainnet
      const sushiswapRouterAddress = "0xd9e1ce17f2641f24ae83637ab66a2cca9c378b9f"
    
      const SwapAggregator = await ethers.getContractFactory("SwapAggregator");
      const swapAggregator = await SwapAggregator.deploy(sushiswapRouterAddress);
    
      const tx = await swapAggregator.swap(sushiswapId, USDC, 1000000)
      // validate tx receipt
    })
    


    기본적으로 포크는 가장 최근의 메인넷 블록을 사용하므로 테스트는 다른 상태로 실행됩니다. 이것은 일반적으로 바람직하지 않으며 안전모를 사용하면 특정 블록에서 포크를 만들 수 있습니다.

    npx hardhat node --fork https://eth-mainnet.alchemyapi.io/v2/<key> --fork-block-number 14390000
    


    예를 들어 Alchemy와 같은 아카이브 노드가 필요합니다. 자신의 키로 교체하는 것을 잊지 마십시오.

    테스트 자금



    스마트 계약의 일부 기능을 테스트하려면 자금이 필요할 수 있습니다(분명히 이를 교환하려면 일부 토큰이 필요합니다). ETH를 얻으려면 hardhat_setBalance를 사용할 수 있습니다.

    await network.provider.send("hardhat_setBalance", [
      "0x0d2026b3EE6eC71FC6746ADb6311F6d3Ba1C000B",
      ethers.utils.parseUnits(1),
    ]);
    // now account 0x0d2026b3EE6eC71FC6746ADb6311F6d3Ba1C000B has 1 ETH after this
    


    예를 들어 USDC와 같은 일부 토큰을 얻으려면 모든 교환을 사용하여 ETH를 교환할 수 있습니다(이 예에서는 이를 위해 SwapAggregator를 사용할 수 있음).

    계약에 대한 액세스



    경우에 따라 다른 스마트 계약의 구성을 변경해야 할 수도 있으며 이를 위해서는 해당 권한을 가진 계정에 대한 액세스 권한이 필요합니다. hardhat_impersonateAccount가 도움이 될 것입니다.

    await hre.network.provider.request({
      method: "hardhat_impersonateAccount",
      params: ["0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6"],
    });
    //  after that, all transactions will be sent on behalf of 0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6
    


    기타 유용한 기능



    보다 복잡한 경우, Hardhat을 사용하면 스마트 계약 저장소의 데이터를 다시 작성하거나 전체 계약의 코드를 변경할 수 있습니다. 유틸리티 방법 목록:
  • hardhat_impersonateAccount
  • hardhat_stopImpersonatingAccount
  • hardhat_setNonce
  • hardhat_setBalance
  • hardhat_setCode
  • hardhat_setStorageAt

  • the hardhat documentation에서 이에 대해 자세히 알아볼 수 있습니다.

    요약하면 메인넷 포크를 사용하여 다른 앱과의 복잡한 상호 작용을 테스트할 수 있습니다. 그리고 모든 것이 메인넷에서 작동하는지 확인하면서 계약을 배포하십시오.

    좋은 웹페이지 즐겨찾기