일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Vue
- Vue.js
- nest.js설명
- 러스트 기초
- SBT표준
- 체인의정석
- ethers typescript
- 스마트컨트렉트테스트
- multicall
- 컨트렉트 동일한 함수이름 호출
- 러스트 기초 학습
- 스마트컨트렉트 함수이름 중복 호출
- rust 기초
- ethers type
- 컨트렉트 배포 자동화
- 스마트 컨트렉트 함수이름 중복
- ethers v6
- 깃허브명령어
- 머신러닝기초
- git rebase
- 스마트컨트렉트 예약어 함수이름 중복
- ambiguous function description
- ethers websocket
- nestjs 튜토리얼
- 스마트컨트렉트프록시
- 러스트기초
- ethers
- chainlink 설명
- 프록시배포구조
- vue기초
- Today
- Total
체인의정석
ethers & hardhat에서 이벤트 로그 다루기 (검색부터 필터링과 decode) 본문
순서대로 다뤄보기
1. 조회하고자 하는 컨트렉트와 연동해준다.
const testContract = await ethers.getContractAt("컨트렉트이름", "컨트렉트주소");
2. 조회를 할 설정값을 넣어서 필터링을 해준다.
const filter = {
address: "컨트렉트 주소",
fromBlock: 0,
toBlock: 10000000,
topics: [testContract.filters."이벤트이름"().topics] //Transfer().topics 이런식으로 활용
};
const logs = await ethers.provider.getLogs(filter);
//filter를 적용한 로그 값을 가져온다.
3. logs를 통해 조회가 가능하지만 해당 값들은 디코딩이 되지 않은 값들이다. 디코딩을 해주어야 한다. logs를 통해 transactionhash를 가져올 수 있다.
4. transaction hash를 가져와서 변수로 둔다.
const receipt = await ethers.provider.getTransactionReceipt("");
5. 인터페이스 변수를 선언한다. abi 파일은 하드햇 경로에서 컴파일 된 걸 그대로 써준다.
let abi = require("../artifacts/contracts/Test.sol/Test.json").abi;
let iface = new ethers.utils.Interface(abi);
6-1. 이제 하나하나 가져와서 이벤트를 디코딩 해준다.
parseLog를 사용하는 것이 핵심이다.
receipt.logs.forEach((log: object) => {
console.log("log >>>", log)
console.log(iface.parseLog(log));
});
6-2. decodeEventLog함수도 있다.
const decodedEvent = iface.decodeEventLog("TestEvent", data, '트랜잭션해시');
console.log("decoded event >>>", decodedEvent)
직면한 오류들
Error: no matching event
이벤트가 없어서 나는 오류이다. 내 경우에서는 컨트렉트 인터페이스만 받아와서 못찾는 거였는데. 오픈제플린 표준같은 다른 컨트렉트를 상속 받는 경우 이벤트 누락이 발생할 수 있다. 이럴땐 컨트렉트 원본 소스를 가져와서 다시 컴파일을 하고 abi를 인터페이스가 아닌 원래 컨트렉트 abi를 가져오면 된다.
코드 작성시 참고한 유용한 예제들
1. 여러개의 log나 나올때 순회하면서 조회하는 법 : 깔끔하고 효과적이다.
let abi = [
"event newConnect (string indexed hashedName, string name, bytes32 connectId, string encrypted, address owner)"
];
let iface = new ethers.utils.Interface(abi)
getLogs.then((logs) => {
logs.forEach((log) => {
console.log(iface.parseLog(log));
});
});
https://github.com/ethers-io/ethers.js/issues/422
2. 이벤트의 필터 가져오는 법 - 이런방법도 있다고 한다. 위에서 내가 쓴 방법이 최종적으로 쓰이긴했다.
filter = {
address: THE_ADDRESS_OF_YOUR_CONTRACT,
topics: [
// the name of the event, parnetheses containing the data type of each event, no spaces
utils.id("Transfer(address,address,uint256)")
]
}
provider.on(filter, () => {
// do whatever you want here
// I'm pretty sure this returns a promise, so don't forget to resolve it
})
https://ethereum.stackexchange.com/questions/87643/how-to-listen-to-contract-events-using-ethers-js
3. 이벤트 로그 분석하는 예시 : 코드를 만들 때 참고하기 좋았던 예시이다.
const receipt = await ethers.provider.getTransactionReceipt("0x0c8300a14a08fffe209dfe5961b3027b1321428184365751b89c4ac6056c28e4");
let abi = [ "event Donation(address donor, uint256 value, uint256 tokenID)" ];
let iface = new ethers.utils.Interface(abi);
let log = iface.parseLog(receipt.logs[1]); // here you can add your own logic to find the correct log
const {donor, value, tokenID} = log.args;
https://github.com/ethers-io/ethers.js/issues/487
4. ethers 공식문서의 예시이다.
// Decoding log data and topics (the entries in a receipt)
const data = "0x0000000000000000000000000000000000000000000000000de0b6b3a7640000";
const topics = [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x0000000000000000000000008ba1f109551bd432803012645ac136ddd64dba72",
"0x000000000000000000000000ab7c8803962c0f2f5bbbe3fa8bf41cd82aa1923c"
];
iface.decodeEventLog("Transfer", data, topics);
// [
// '0x8ba1f109551bD432803012645Ac136ddd64DBA72',
// '0xaB7C8803962c0f2F5BBBe3FA8bf41cd82AA1923C',
// { BigNumber: "1000000000000000000" },
// amount: { BigNumber: "1000000000000000000" },
// from: '0x8ba1f109551bD432803012645Ac136ddd64DBA72',
// to: '0xaB7C8803962c0f2F5BBBe3FA8bf41cd82AA1923C'
// ]
https://docs.ethers.io/v5/api/utils/abi/interface/
타입스크립트에서 타입 지정해 주는법 예시 코드
'블록체인 > Ethers & web3' 카테고리의 다른 글
ethers에 typescript 제대로 적용해보기 (0) | 2023.01.06 |
---|---|
Typescript에서 hardhat 사용하기 - task 사용하는법, config파일 밖으로 꺼내서 코드 가독성 높이는 법 (0) | 2022.12.16 |
ERC20 만들고 test code까지 작성하기 (0) | 2022.08.11 |
스마트컨트렉트 테스트 코드, hardhat & ethers & Typescript에서 상황별 Big number 다루기 (0) | 2022.07.26 |
hardhat 테스트 코드에서 beforeEach 사용하기 VS fixtures 사용하기 (0) | 2022.07.19 |