일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Vue
- 스마트 컨트렉트 함수이름 중복
- chainlink 설명
- multicall
- ambiguous function description
- ethers v6
- SBT표준
- 컨트렉트 동일한 함수이름 호출
- 러스트 기초
- ethers
- ethers websocket
- ethers typescript
- vue기초
- 러스트 기초 학습
- 스마트컨트렉트프록시
- 오블완
- ethers type
- 프록시배포구조
- 티스토리챌린지
- rust 기초
- Vue.js
- 스마트컨트렉트테스트
- 머신러닝기초
- 러스트기초
- nest.js설명
- 스마트컨트렉트 함수이름 중복 호출
- 스마트컨트렉트 예약어 함수이름 중복
- 컨트렉트 배포 자동화
- git rebase
- 체인의정석
- Today
- Total
체인의정석
Solidity) internal 트랜잭션에 대한 이벤트 로그 테스트하기 본문
현재 hardhat + ether.js에서 인터널 트랜잭션에 대한 이벤트 로그 테스트가 이루어지고 있지 않은 상황이다.
완벽한 단위 테스트를 위하여서 인터널 트랜잭션에 대한 이벤트 로그를 업데이트 하기로 하였다.
해당 케이스를 보니 오픈제플린의 모듈을 사용하면 된다고 한다.
예시 코드도 발견하였다.
pragma solidity ^0.5.0;
contract A {
function doAStuff() public {
emit DidAStuff("A");
}
event DidAStuff(string message);
}
A 컨트렉트가 있어서 호출되는 상황이고
pragma solidity ^0.5.0;
import "./A.sol";
contract B {
A _a;
constructor(A a) public {
_a = a;
}
function doBStuff() public {
_a.doAStuff();
emit DidBStuff("B");
}
event DidBStuff(string message);
}
B 컨트렉트의 경우는 A를 가져와서 호출하는 경우이다. 여기서도 이벤트가 발생한다.
const { expectEvent } = require('openzeppelin-test-helpers');
const A = artifacts.require('A');
const B = artifacts.require('B');
contract('B', function () {
beforeEach(async function () {
this.a = await A.new();
this.b = await B.new(this.a.address);
});
it('does stuff', async function () {
const receipt = await this.b.doBStuff();
// Log-checking will not only look at the event name, but also the values, which can be addresses, strings, numbers, etc.
await expectEvent.inLogs(receipt.logs, 'DidBStuff', { message: "B" });
await expectEvent.inTransaction(receipt.tx, A, 'DidAStuff', { message: "A" });
});
});
이러면 openzeppelin-test-helpers 모듈을 받아서 expectEvent를 불러온다.
그리고 expectEvent.inLogs라는 것을 사용해서 인터널 트랜잭션의 로그값을 받아올 수 있다.
근데 문서를 확인해 보니 아무래도 web3를 사용했을때만 이러한 오픈제플린 테스트 모듈을 사용할 수 있는거 같다.
https://ethereum-waffle.readthedocs.io/en/latest/matchers.html
지금 사용중인건 waffle에서 예시를 찾아볼 수 있었다.
문제는 여기서는 아직 2개의 emit은 안된다고 되어 있엇는데, 실제로 해보니까 체크가 잘되었었다. internal Transaction도 잡아주고 다른 이벤트 로그로 했을때도 잘못된 경우 테스트 통과가 안되고 에러가 나는것을 확인할 수 있었다.
await expect(contractName1.functionName(input))
.to.emit(contractName1, "EventName1")
.withArgs(event_expect1,event_expect2)
.to.emit(contractName2, "EventName2")
.withArgs(event_expect1,event_expect2)
만약 2개의 다른 컨트렉트에 이벤트가 발생한다면 위와 같이 구문을 2번 반복하면 이벤트 로그 검사가 진행되는 것을 확인할 수 있었다.
+) 추가적으로 테스트 코드를 보완하다가 알게 된 점은 이벤트로그의 경우 발생하는 순서대로 체크하지 않으면 에러가 난다는 점이다. 따라서 다중 이벤트로그를 체크할 경우 실행 순서를 확인하고 하는 작업이 필요하다.
그리고 뒤에 이벤트가 남아있음에도 .withArgs 뒤에 ; 를 다는 경우 에러가 난다.
따라서 ;는 마지막 줄에만 작성한다.