궁금한 주제를 찾아보세요

비트코인, 스테이블코인, 온체인 데이터처럼 주제로 검색하세요.

다시 읽을 이야기

저장한 글은 이 브라우저에만 보관됩니다.

해설블록체인 기술

EVM 체인 재구성 때 로그 인덱서가 되돌림을 처리하는 법

removed 로그, block hash, 확인 단계와 멱등 처리를 연결해 체인 재구성 뒤에도 파생 잔액과 주문 상태를 일관되게 유지하는 방법을 설명합니다.

난이도 중급주제 카테고리와 개념 밀도 기준
체인 분기에서 폐기된 기록을 되돌리고 새 정식 블록의 로그를 처리하는 재구성 대응 그림
주제의 이해를 돕기 위한 개념 일러스트
먼저 읽는 핵심

로그 식별자는 transaction hash 하나가 아니라 block hash와 log index까지 포함합니다.
removed=true는 삭제 신호가 아니라 이전 적용 효과를 정확히 되돌릴 입력입니다.
구독 재연결 뒤에는 저장한 커서와 블록 해시를 대조하고 범위를 다시 조회합니다.

로그 인덱서는 이벤트를 받자마자 확정된 사실로 덮어쓰지 말고, blockHash·blockNumber·transactionHash·logIndex와 함께 원본을 저장해야 합니다. 이미 처리한 로그가 removed=true로 다시 들어오면 그 로그가 만든 파생 효과를 거꾸로 되돌리고, 새 정식 체인의 로그는 몇 번 받아도 결과가 같도록(멱등하게) 적용합니다. 웹소켓(WebSocket) 구독은 연결이 끊긴 동안의 과거 이벤트를 채워 주지 않으므로, 마지막으로 빠짐없이 확인한 블록부터 eth_getLogs로 빈 구간을 다시 조회해야 합니다. 화면용 빠른 상태, safe 상태, finalized 상태를 서로 다른 단계로 운영하면 속도와 재구성 위험을 감추지 않을 수 있습니다.

블록 높이는 같아도 정식 체인은 바뀔 수 있습니다

실행 클라이언트는 같은 높이에서 서로 다른 블록 해시를 볼 수 있습니다. 예를 들어 높이 21,000,100의 A 블록에서 Deposit 로그를 받아 사용자 잔액을 5 ETH 올렸는데, 다음 헤드의 parentHash가 A가 아니라 다른 조상을 가리킨다면 A의 효과는 더 이상 정식 체인의 상태가 아닐 수 있습니다. 블록 번호만 저장한 인덱서는 이 차이를 잡아내지 못합니다.

Geth의 로그 구독은 체인 재구성(reorg)으로 옛 체인에 남은 로그를 removed=true로 다시 보내고, 새 체인에 들어간 거래의 로그도 보냅니다. 같은 거래가 여러 번 전달될 수 있으므로 transactionHash만으로 중복을 걸러 내지 않습니다. 체인 안의 위치를 나타내는 blockHash와 logIndex를 함께 보존해야 합니다.

재구성 대응은 로그를 지우는 예외 처리가 아니라, 적용과 취소를 같은 수준의 상태 전이로 설계하는 일입니다.

JOBCOIN 해설

그림으로 보기프로토콜 실행의 기본 구조
입력이 실행 규칙을 통과할 때 상태가 바뀌는 프로토콜 개념도
그림과 함께 짚어볼 본문 내용

그림은 이 주제의 공통 개념을 단순화한 설명입니다. 아래 항목에서 이 글의 구체적인 조건과 예외를 함께 읽어보세요.

  1. 블록 높이는 같아도 정식 체인은 바뀔 수 있습니다

    실행 클라이언트는 같은 높이에서 서로 다른 블록 해시를 볼 수 있습니다.

  2. 원본 로그와 파생 상태를 분리합니다

    원본 이벤트 테이블에는 chainId, blockNumber, blockHash, transactionHash, transactionIndex, logIndex, address, topics, data와 removed 상태를 기록합니다.

  3. A 체인에서 B 체인으로 바뀌는 순서를 고정합니다

    높이 100의 블록 A에 Deposit 5와 OrderFilled 1이 들어 있었다고 가정합니다.

설명을 위한 개념도 · 실제 가격·거래 내역·통계가 아닙니다.

원본 로그와 파생 상태를 분리합니다

원본 이벤트 테이블에는 chainId, blockNumber, blockHash, transactionHash, transactionIndex, logIndex, address, topics, data와 removed 상태를 기록합니다. 파생된 잔액·포지션·주문에는 어떤 원본 이벤트가 만든 변화인지 연결해 둡니다. 그러면 A 블록이 빠질 때 그 이벤트가 더한 5 ETH만 되돌리고 다른 입금은 건드리지 않을 수 있습니다.

상태 전이는 멱등해야 합니다. 같은 활성 로그가 다시 오면 두 번 더하지 않고, 이미 취소한 로그가 다시 removed로 와도 두 번 빼지 않습니다. 고유 키에는 체인과 블록 안의 위치를 반영하고, 처리 결과와 원본 상태 변경을 데이터베이스 트랜잭션 하나로 묶습니다.

재구성 대응 데이터의 역할
데이터 저장 이유 재처리 동작
blockHash·parentHash 정식 연결 관계 확인 공통 조상까지 되돌아감
txHash·logIndex 블록 안 로그 위치 식별 같은 위치 중복 방지
removed 상태 옛 체인 로그 판별 파생 효과 되돌리기
처리 위치 표시 구독 빈 구간 범위 결정 eth_getLogs로 다시 조회
확정 단계 노출 위험 전달 잠정·safe·finalized 분리

A 체인에서 B 체인으로 바뀌는 순서를 고정합니다

높이 100의 블록 A에 Deposit 5와 OrderFilled 1이 들어 있었다고 가정합니다. 인덱서는 두 로그를 잠정 상태로 적용합니다. 이후 높이 100의 블록 B가 정식 체인에 연결되면 A의 두 로그를 역순으로 취소하고 B의 로그를 차례로 적용합니다. 같은 거래가 B에도 들어갔더라도 블록 해시나 로그 순번이 달라질 수 있으므로 새 위치의 이벤트로 취급합니다.

파생 작업도 함께 되돌릴 수 있어야 합니다. 외부 송금이나 이메일처럼 체인 상태 밖으로 나가는 부작용을 잠정 로그 하나만 보고 바로 실행하면, 데이터베이스를 되돌리는 것만으로는 복구되지 않습니다. 가치 이전은 필요한 확정 단계를 지난 뒤에 실행하고, 빠른 알림에는 잠정 상태라고 표시합니다.

  • 새 헤드의 parentHash를 직전 정식 헤드의 해시와 비교합니다.
  • 어긋나면 저장해 둔 조상 해시를 따라 공통 조상을 찾습니다.
  • 옛 가지 로그의 파생 효과를 역순으로 취소합니다.
  • 새 가지의 블록과 영수증을 앞에서부터 검증하며 적용합니다.
  • 마지막 연속 블록부터 범위 조회로 구독 빈 구간을 메웁니다.
  • safe·finalized 경계가 앞으로 나아가면 상태 라벨을 올립니다.

확인 개수와 합의 확정성을 구분합니다

‘12 confirmations’ 같은 숫자는 애플리케이션이 헤드와의 거리로 정한 정책입니다. 자산 가치, 네트워크, 장애 시나리오에 따라 달라지며, 그 자체가 합의 프로토콜의 확정(finalized) 판정은 아닙니다. Ethereum 지분증명(PoS)에서 justified·finalized 체크포인트는 검증자 투표와 에폭 규칙에 묶여 있습니다.

빠른 화면은 latest 근처를 잠정 상태로 보여 주고, 출금 승인처럼 위험이 큰 작업은 safe 또는 finalized 기준을 요구할 수 있습니다. RPC 제공자가 해당 태그를 지원하는지, 실행 클라이언트와 합의 클라이언트가 정상적으로 동기화됐는지도 감시해야 합니다. 확인 깊이와 합의 확정성을 같은 숫자로 취급하지 않습니다.

구독은 전달 채널이지 완전한 원장 복제 기능이 아닙니다

Geth 문서에 따르면 구독은 연결에 묶여 있어 연결이 닫히면 사라집니다. 알림은 현재 이벤트를 위한 것이라 과거 이벤트를 채워 주지 않고, 받는 쪽이 내부 버퍼를 따라가지 못하면 연결이 끊길 수도 있습니다. 다시 연결됐다는 것만 보고 빠진 것이 없다고 판단하면 안 됩니다.

운영자는 마지막으로 빠짐없이 처리한 블록 번호와 해시를 영구 저장합니다. 다시 시작할 때 현재 노드에서 그 해시가 같은 높이의 정식 블록인지 확인하고, 어긋나면 공통 조상까지 되감습니다. 그다음 작은 범위로 eth_getLogs를 반복 호출하고, 실시간 구독과 겹치는 구간은 멱등 키로 합칩니다.

장애 연습은 실제 역분개 결과까지 확인합니다

개발망에서 블록 A의 로그를 적용한 뒤 스냅샷 복귀나 대체 가지로 재구성을 일으키고, removed 처리 전후의 원본과 파생 잔액을 비교합니다. 웹소켓을 끊어 둔 사이에 블록 여러 개를 만든 뒤 다시 연결해, 빠진 범위가 모두 채워지는지도 시험합니다.

관측 지표에는 헤드 지연, 부모 해시 불일치, 되감은 깊이, removed 로그 수, 보충 조회 범위, 중복으로 무시한 수, safe·finalized 지연을 둡니다. 경보만 울리고 자동 되감기가 실패할 때를 대비해, 특정 블록 해시부터 다시 재생하는 운영 절차서와 대조 쿼리를 준비합니다.

자주 묻는 질문

removed=true인 로그를 데이터베이스에서 삭제하면 되나요?

감사와 멱등 처리를 위해 원본은 보존하고 removed 상태를 기록한 뒤, 연결된 파생 효과를 되돌리는 편이 안전합니다.

transaction hash는 왜 고유 키로 부족한가요?

재구성 뒤 같은 거래가 새 블록에 다시 들어가 다른 블록 해시나 로그 순번을 가질 수 있고, 한 거래의 로그도 여러 개일 수 있기 때문입니다.

WebSocket을 재연결하면 놓친 로그가 자동으로 오나요?

Geth 구독은 과거 이벤트를 채워 주지 않으므로, 저장해 둔 처리 위치부터 eth_getLogs 범위 조회로 빈 구간을 메워야 합니다.

더 깊이 읽기

본문에서 다룬 개념과 확인 절차를 다음 글에서 이어서 살펴보세요.

참고한 원문 자료

자료 확인 기준일 2026.09.27
  1. go-ethereum — Real-time Eventsgeth.ethereum.org
  2. ethereum.org — Proof-of-stakeethereum.org
작성 방식과 확인 범위
출처 수집
원문 링크 2개 제공
작성·확인
공식 기관 자료를 근거로 AI 도구를 활용해 작성했고, 운영자가 발행 전에 읽어 확인합니다.
전문가 검토
세무·법률 전문가 검토는 거치지 않았습니다.

투자·세무 판단은 전문가와 상의하세요. 제도와 거래소 안내는 바뀔 수 있으니 원문의 적용 대상과 최신 안내를 함께 확인해 주세요.

이해를 위한 정보 콘텐츠

이 글은 특정 자산의 매수·매도 또는 수익을 권유하지 않습니다. 자료의 발표 시점과 이후 변경 사항을 함께 확인해 주세요.

편집 원칙 보기 →이 기사 정정 제보 →