곰투 크립토
guide전체 41편 중 23편

이더리움 이벤트 로그 완벽 정리: 토픽·데이터·eth_getLogs 읽는 법

이더리움 이벤트 로그의 토픽과 데이터 구조, eth_getLogs 필터링, ABI 디코딩과 체인 재구성 리스크를 실무 관점에서 설명합니다.

GOMTU
GOMTU
크립토 리서치 · 2026년 8월 20일 · 약 7분
공유𝕏in

최종 업데이트

토큰이 이동하거나 스왑이 끝나면 블록 익스플로러에는 금세 읽기 쉬운 활동 내역이 나타납니다. 이 기록은 컨트랙트 변수를 매번 전부 훑어서 만드는 것이 아니라 **이벤트 로그(Event Log)**를 바탕으로 구성하는 경우가 많아요. 로그는 블록체인 기초를 우리가 매일 보는 화면, 알림, 온체인 분석과 연결합니다. 다만 로그는 컨트랙트 코드가 내보낸 증거이지, 화면의 라벨이나 해석이 항상 옳다는 독립적인 보증은 아닙니다.

이 글에서는 Solidity 이벤트가 이더리움 로그로 바뀌는 원리, 토픽(Topic)과 데이터의 인코딩 차이, eth_getLogs 필터링 방법, 디코딩과 체인 재구성(Reorg)에서 확인할 리스크를 설명해요.

이더리움 이벤트 로그란 무엇인가요?

광고

스마트 컨트랙트를 식당 주방, 이벤트 로그를 번호가 붙은 주문표라고 생각해 보세요. 주방이 실제 재고를 바꾸는 일은 컨트랙트 상태(State) 변경에 해당합니다. 주문표는 외부 시스템이 쉽게 보고 분류할 수 있는 간결한 기록이에요. 프런트엔드는 잔액 화면을 갱신하고, 인덱서는 토큰 이동 내역을 만들며, 모니터링 서비스는 보안상 중요한 행동을 감지해 알림을 보낼 수 있습니다.

Solidity 컨트랙트는 event를 선언하고 트랜잭션 실행 중 emit으로 이벤트를 발생시켜요. 트랜잭션이 성공해 블록에 포함되면 영수증(Receipt)에 로그 항목이 들어갈 수 있습니다. 각 로그에는 이벤트를 발생시킨 컨트랙트 주소, topics, data 바이트열이 담깁니다.

로그는 모든 보고용 값을 컨트랙트 스토리지(Storage)에 저장하는 것보다 오프체인 소프트웨어가 검색하기 쉽습니다. 하지만 컨트랙트는 과거 로그를 읽을 수 없어요. 로그를 내보낸 컨트랙트 자신도 실행 중 이전 로그를 조회하지 못합니다. 실행이 되돌려지면(Revert) 그 실행에서 발생한 상태 변경과 로그도 남지 않아요.

이벤트는 어떻게 토픽과 데이터로 나뉘나요?

널리 쓰이는 ERC-20 이벤트 형태를 살펴볼게요.

event Transfer(address indexed from, address indexed to, uint256 value);

익명(Anonymous)이 아닌 일반 이벤트는 보통 다음 구조로 기록됩니다.

address: 로그를 발생시킨 컨트랙트
topics[0]: keccak256("Transfer(address,address,uint256)")
topics[1]: 32바이트로 인코딩한 indexed from 주소
topics[2]: 32바이트로 인코딩한 indexed to 주소
data: ABI로 인코딩한 uint256 value

topics[0]은 이벤트 셀렉터(Event Selector)예요. 정규 이벤트 시그니처를 Keccak-256으로 해시한 값이며 같은 컨트랙트가 내보낸 여러 이벤트를 구분합니다. 일반 Solidity 이벤트에는 indexed 매개변수를 최대 3개 지정할 수 있어요. 네 개의 토픽 슬롯 중 하나를 시그니처가 사용하기 때문입니다.

익명 이벤트는 시그니처 토픽을 생략해 매개변수를 최대 4개 인덱싱할 수 있습니다. 대신 일반적인 방식으로 이벤트 이름을 필터링할 수 없어요.

인덱싱된 매개변수는 검색에 적합합니다. 인덱싱하지 않은 값은 애플리케이션 바이너리 인터페이스(ABI)에 따라 data에 함께 인코딩돼요. 문자열이나 배열 같은 동적 값을 인덱싱하면 원본 대신 특별한 인코딩의 해시가 토픽에 들어갑니다. 알고 있는 후보를 올바르게 해시해 필터링할 수는 있지만, 해시만 보고 모르는 원문 문자열을 복원할 수는 없습니다.

이벤트와 콜데이터는 서로 다른 질문에 답해요

이더리움 콜데이터는 트랜잭션이 컨트랙트에 무엇을 요청했는지 보여 줍니다. 이벤트 로그는 실행된 컨트랙트가 무엇을 알리기로 했는지 보여 줘요. 한 트랜잭션이 여러 컨트랙트를 호출해 많은 로그를 만들 수 있습니다. 반대로 상태를 바꾸면서 화면이 기대하는 이벤트를 내보내지 않을 수도 있어요. 전체 맥락을 파악하려면 입력, 영수증 상태, 로그, 실제 상태 변화를 함께 비교해야 합니다.

트랜잭션 영수증은 어떻게 읽나요?

JSON-RPC의 eth_getTransactionReceipt는 아직 영수증이 없으면 null을 반환합니다. 블록에 포함된 트랜잭션의 영수증에는 블록 해시, 블록 번호, 실행 상태, 사용한 가스, logs 배열 등이 들어가요.

로그 객체에서 주로 확인하는 필드는 다음과 같습니다.

  • address: 로깅 명령을 실행한 컨트랙트 주소
  • topics: 이벤트 식별자와 인덱싱된 값을 담은 순서 있는 목록
  • data: 인덱싱하지 않은 값을 ABI로 인코딩한 바이트열
  • blockHash, blockNumber: 로그가 포함된 블록
  • transactionHash, transactionIndex: 로그를 만든 트랜잭션
  • logIndex: 블록 내 로그 순서
  • removed: 체인 재구성으로 이전에 전달한 로그가 제거됐는지 여부

먼저 영수증의 status를 확인하세요. 성공 상태는 이더리움 가상 머신(EVM) 실행이 되돌려지지 않았다는 뜻입니다. 컨트랙트가 안전하다거나 익스플로러의 사람이 읽는 라벨이 진짜라는 뜻은 아니에요. 다음으로 이벤트 발생 주소를 확인하고 해당 네트워크의 정확한 컨트랙트 ABI를 확보해야 합니다. 프록시(Proxy) 구조에서는 로그에 프록시 주소가 보이더라도 구현 컨트랙트의 ABI가 필요할 수 있어요.

eth_getLogs 필터는 어떻게 작동하나요?

eth_getLogs는 필터 객체와 일치하는 로그를 이더리움 노드에 요청하는 메서드입니다. 블록 범위, 하나 이상의 컨트랙트 주소, 토픽 위치가 핵심 필터예요.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_getLogs",
  "params": [
    {
      "fromBlock": "0x1200000",
      "toBlock": "latest",
      "address": "0xContractAddress",
      "topics": ["0xEventSignatureHash", null, "0xPaddedIndexedAddress"]
    }
  ]
}

토픽 순서는 중요합니다. 위 예시에서 0번 위치는 이벤트 시그니처를 고르고, null은 첫 번째 인덱싱 값은 무엇이든 허용하며, 2번 위치는 두 번째 인덱싱 값을 제한해요. 이더리움 JSON-RPC 명세에 따르면 같은 위치의 중첩 배열은 OR 조건이고 서로 다른 위치는 AND 조건입니다.

제네시스부터 매번 다시 요청하지 말고 제한된 블록 구간을 조회한 뒤 체크포인트를 저장하세요. RPC 제공자는 구간, 응답 크기, 호출 횟수를 제한할 수 있습니다. 이는 제공자의 운영 정책이지 이더리움 합의 규칙은 아니에요. EIP-234는 fromBlock, toBlock 대신 blockHash로 특정 블록의 로그를 필터링하는 방식도 표준화했습니다.

신뢰할 수 있는 인덱싱 순서

1. 식별 정보를 고정해요

체인 ID, 이벤트 발생 주소, ABI 버전, 배포 블록을 기록하세요. 같은 형태의 인터페이스나 주소 문자열이라도 다른 네트워크라면 별개의 맥락입니다.

2. 시그니처를 직접 계산하고 확인해요

정확한 매개변수 자료형으로 정규 이벤트 시그니처를 만들고 Keccak-256 해시를 계산합니다. 매개변수 이름과 indexed 키워드는 시그니처 문자열에 포함되지 않아요. 검증된 소스에서 직접 계산할 수 있다면 신뢰할 수 없는 게시물의 토픽을 복사하지 마세요.

3. 일정한 구간으로 조회해요

제한된 구간을 가져와 디코딩하고, 마지막으로 처리한 블록 번호와 해시를 함께 저장한 뒤 다음 구간으로 넘어갑니다. 체인, 블록 해시, 트랜잭션 해시, 로그 인덱스를 조합한 고유 키처럼 멱등성(Idempotency)을 고려한 저장 구조는 재시도 때 중복 처리를 막는 데 도움이 돼요.

4. 용도에 맞는 확신 수준까지 기다려요

최근 제안된 블록은 교체될 수 있습니다. 사용자 화면은 잠정 결과를 빠르게 보여 줄 수 있지만 정산처럼 결과가 중요한 시스템은 명시적인 컨펌 또는 최종성 정책을 적용해야 해요. 블록체인 최종성 가이드에서 ‘관찰됨’과 ‘되돌릴 수 없음’이 왜 다른지 설명합니다.

5. 체인 재구성 때 되돌려요

구독 시스템은 체인 재구성 뒤 removed: true인 로그를 전달할 수 있습니다. 폴링 시스템도 저장한 블록 해시와 현재 정식 체인을 비교해야 해요. 교체된 블록에서 파생한 기록을 되돌린 뒤 새 체인을 처리합니다. 추가만 가능한 데이터베이스는 더 이상 정식 체인에 없는 이벤트를 조용히 보존할 수 있어요.

리스크와 한계

로그 바이트가 정확해도 해석은 오해를 만들 수 있어요

로그는 특정 주소가 내보낸 바이트를 정확히 기록합니다. 그러나 이벤트 이름과 필드 라벨은 익스플로러, 앱, 개발자가 제공한 ABI에서 와요. 악성 컨트랙트도 익숙한 토큰 이벤트와 같은 모양의 로그를 내보낼 수 있습니다. 라벨만 보지 말고 주소, 코드, 상태를 확인하세요.

이벤트가 없다고 아무 일도 없었던 것은 아니에요

이벤트는 컨트랙트 작성자가 선택한 규칙입니다. 상태 변경이 로그를 생략하거나 비표준 이벤트를 쓰거나 인덱서가 추적하지 않는 실행 경로를 통과할 수 있어요. 로그는 훌륭한 연동 수단이지만 모든 EVM 효과를 빠짐없이 증명하는 범용 감사 기록은 아닙니다.

동적 값 인덱싱은 가독성과 검색성을 맞바꿔요

문자열을 해시해 토픽에 넣으면 정확히 알고 있는 값으로 검색할 수 있지만 직접 디코딩할 수 없어요. 검색성과 가독성이 모두 필요하다면 Solidity 문서가 설명하듯 해시된 인덱싱 값과 평문 비인덱싱 값을 함께 두는 설계를 고려할 수 있습니다. 로그 데이터 비용은 늘어납니다.

체인 재구성과 제공자 동작이 전달 결과에 영향을 줘요

같은 이벤트가 잠정적으로 나타났다 사라지고 다른 블록에서 다시 나타날 수 있습니다. 웹소켓 연결 끊김이나 제공자 제한도 누락을 만들 수 있어요. 운영 시스템은 구독을 정확히 한 번 전달되는 채널로 가정하지 말고 백필(Backfill), 체크포인트, 중복 제거, 재구성 처리를 갖춰야 합니다.

Warning

디코딩된 이벤트 하나만 보고 자산 전송을 승인하거나 입금을 확정하면 안 됩니다. 체인, 정식 블록, 영수증 상태, 이벤트 발생 컨트랙트, 필요한 컨펌 수, 실제 상태를 확인하세요.

실무 체크리스트

  • 체인 ID와 이벤트 발생 컨트랙트 주소를 확인했나요?
  • 검증된 소스와 현재 프록시 구현에 맞는 ABI를 사용하나요?
  • 정규 이벤트 시그니처와 topics[0]을 다시 계산했나요?
  • 인덱싱 값과 비인덱싱 값을 선언된 자료형으로 해석했나요?
  • 영수증 상태와 블록 식별자를 확인했나요?
  • 제한된 구간을 조회하고 블록 번호와 해시를 체크포인트로 저장하나요?
  • 재시도 중복과 removed 로그 또는 블록 해시 불일치를 처리하나요?
  • 결과의 중요도에 맞는 컨펌 또는 최종성 정책이 있나요?
  • 중요한 주장은 컨트랙트 상태와 다시 대조했나요?

자주 묻는 질문

이더리움 이벤트는 컨트랙트 스토리지에 저장되나요?

아니요. 로그는 트랜잭션 영수증에 포함되고 블록 구조를 통해 커밋되지만 컨트랙트 스토리지는 아닙니다. 컨트랙트는 실행 중 과거 로그를 조회할 수 없고 오프체인 클라이언트와 인덱서가 이를 처리해요.

인덱싱된 주소는 읽을 수 있는데 문자열은 왜 읽을 수 없나요?

주소는 한 개의 32바이트 토픽 워드에 들어가 패딩됩니다. 동적 값은 인코딩의 Keccak-256 해시로 표현돼요. 알고 있는 후보가 일치하는지는 검사할 수 있지만 해시를 거꾸로 풀어 원문을 찾을 수는 없습니다.

topics[0]은 항상 이벤트 시그니처인가요?

일반 Solidity 이벤트에서는 그렇습니다. 익명 이벤트는 시그니처 토픽을 생략하므로 모든 토픽이 인덱싱된 매개변수일 수 있어요. 정확한 구조 해석에는 ABI가 필요합니다.

성공한 영수증이면 토큰 전송을 믿어도 되나요?

아니요. 성공은 실행이 되돌려지지 않았다는 뜻입니다. 토큰 메타데이터를 인증하거나 경제적 가치를 증명하거나 익숙한 이벤트가 의도한 컨트랙트에서 왔음을 보장하지 않아요.

1차 출처

로그를 구조화된 증거로 활용하세요

이더리움 이벤트 로그는 컨트랙트 실행과 오프체인 소프트웨어를 잇는 간결한 다리입니다. 토픽은 선택한 필드를 검색 가능하게 만들고, 데이터는 ABI로 인코딩된 세부 내용을 담으며, JSON-RPC는 화면과 인덱서가 이를 가져올 수 있게 해요. 신뢰할 수 있는 시스템은 여기서 멈추지 않습니다. 정확한 신원을 확인하고, 올바른 ABI로 해석하고, 정식 체인을 추적하며, 중요한 결과는 실제 상태와 대조합니다.

이 글은 교육 목적이며 투자 조언이 아닙니다. 온체인 앱과 자산은 실패하거나 가치를 잃을 수 있어요. 최신 1차 문서를 직접 확인하고, 잃어도 되는 금액으로 테스트하며, 스스로 조사하세요(DYOR).

광고

함께 읽으면 좋은 글

관련 주제 살펴보기

GOMTU의 다른 글