견고성: ETH 잔액 변경 테스트는 번거로울 수 있습니다.

NFT 판매 계약을 구현한다고 가정해 보겠습니다. 그리고 소유자는 자신에게 ETH를 인출할 수 있습니다.

이 같은.

// solidity
function withdrawAllETH() onlyOwner {
    uint256 balance = address(this).balance;
    Address.sendValue(payable(owner()), balance);
}


무엇을 테스트하고 싶습니까? 🧑‍🔧



그 중 하나는 소유자가 ETH를 올바르게 받았는지 확인하는 것입니다! 🤑

함께 하자! 🔥

Note: I am using Hardhat here as a sample of testing.



// javascript
it('owner can withdraw all ETH', async () => {
  // let's say contract has 5 ETH, owner has 10 ETH

  // 1. let's do a withdrawal
  await contract.connect(owner).withdrawAllETH()

  // 2. Now owner should have 15 ETH, right?
  expect(await owner.getBalance()).to.eq(parseEther(15))
})


그리고 우리가 그것을 실행할 때.

❌ AssertionError: Expected "14999957824852287212" to be equal 15000000000000000000


무슨 버그!? 🐞🐞🐞



테스트 결과 실제 잔액은 14.999.. ETH가 아니라 15 ETH입니다. 음... 사용된 가스를 확인하는 것을 잊었습니다. 하지만 어떻게 해야 할까요?

사랑하는 StackOverflow thread 덕분에 (항상 😂) 해결책을 얻었습니다.

Gas Spent = Gas Used x Effective Gas Price


그리고 거래 영수증에서 데이터를 얻을 수 있습니다!

Note: we can use cumulativeGasUsed instead of gasUsed if you want to get the gas spent from the whole block.



솔루션 🌟



알겠습니다. 이제 알았으니 대신 이렇게 합시다.

// 2nd attempt
it('owner can withdraw all ETH', async () => {
  // let's say contract has 5 ETH, owner has 10 ETH

  // 1. let's do a withdrawal
  const tx = await contract.connect(owner).withdrawAllETH()

  // 2. Let's calculate the gas spent
  const receipt = await tx.wait()
  const gasSpent = receipt.gasUsed.mul(receipt.effectiveGasPrice)

  // 3. Now we know, it is 15 ETH minus by gasSpent! 
  expect(await owner.getBalance()).to.eq(parseEther(15).sub(gasSpent))
})


그리고 우리가 그것을 실행할 때.

✔ owner can withdraw all ETH


예이! 이제 작동합니다! 🥳🥳🥳

좋은 웹페이지 즐겨찾기