블록체인 트랜잭션 메타데이터로 LDA 토픽 모델링하기
블록체인 트랜잭션 입력 데이터와 이벤트 로그를 정규화하고 LDA 토픽 모델링으로 온체인 행위 패턴을 분석하는 방법을 다룬다.
2026-08-14 · 최초 발행 2025-10-31
트랜잭션 메타데이터를 분석 코퍼스로 바꾸는 일
블록체인 원장에는 자산 이동만 남는 것이 아니다. 트랜잭션 입력 데이터, 이벤트 로그, OP_RETURN 같은 메모, 호출 함수 시그니처, 컨트랙트 주소 라벨에는 온체인 행위의 의도와 반복 패턴을 읽을 단서가 담긴다. 일부 정보는 체인에 직접 기록되고, 일부는 URI처럼 오프체인 리소스를 가리키는 참조값으로 남는다.
이 데이터를 텍스트 마이닝 대상으로 다루려면 ABI 디코딩으로 함수명과 이벤트명을 해석하고, 파라미터 타입과 주소 라벨을 분석용 토큰으로 정규화해야 한다. 주소, 토큰 심볼, 프로토콜명에 관한 도메인 사전을 결합하면 토큰의 의미 밀도를 높일 수 있다.
LDA는 문서·주제·단어의 확률적 생성 모델이다. 알파는 문서-주제 분포를, 에타/베타는 주제-단어 분포를 조절하며 주제 sparsity에 영향을 준다. 모델 적합도는 Coherence와 Perplexity로 평가한다.
수집부터 서빙까지의 분석 계층
수집 단계에서는 풀 노드나 아카이브 노드, The Graph·Dune API 같은 Indexing 서비스, Infura·Alchemy 같은 Provider API를 조합할 수 있다. 재현성을 위해 체인 ID와 블록 높이를 고정해 관리한다. 재org를 고려해 N-컨펌 이후 확정 스냅샷을 만들며, 원문 예시처럼 L1은 12블록 확정 뒤 처리할 수 있다. 블록 범위를 스캔할 때 결측과 중복을 어떻게 다룰지도 미리 정해야 한다.
정규화에서는 4byte function selector를 함수명으로 매핑하고 이벤트 시그니처를 토큰화한다. address는 addr, uint256은 u256처럼 파라미터 타입을 축약 토큰으로 만들 수 있다. 거래소·브릿지·디파이 주소 라벨을 붙이고 체인별 토큰 심볼을 표준화한 뒤, min_df와 n-gram 적용 여부를 결정한다. 스팸이나 에어드랍 패턴은 이 단계에서 걸러낸다.
코퍼스의 문서 단위는 주소, 컨트랙트, 시간 윈도우 등으로 정할 수 있다. 상·하위 빈도 컷으로 희소성을 조절하고, K와 alpha/eta의 대칭·비대칭 설정을 비교한다. Coherence(cv)를 기준으로 K를 탐색하며 Seed를 고정해 실험 결과를 재현 가능하게 관리한다.
운영 환경에서는 배치 재학습과 실시간 추론을 함께 두고, 주제 분포를 시계열로 관찰해 내러티브의 부상과 하락을 추적한다. 토픽 드리프트, 신조어와 새 프로토콜에 따른 사전 변경, 데이터 지연 SLA도 지속적으로 확인해야 한다. 공개 온체인 데이터라도 재식별 위험을 최소화하고, 라벨 출처와 변경 이력을 남기는 거버넌스가 필요하다.
분석 결과가 쓰이는 지점
규제와 콤플라이언스 영역에서는 믹서와 브릿지 사용 패턴을 주제화하고 신규 스캠 시그니처를 탐지할 수 있다. 주소 군집 분석과 연결하면 AML 조사 리드를 단축하는 데 활용할 수 있다.
디파이에서는 특정 기간에 stake, unstake, liquidation 관련 주제가 급증하는지 확인해 유동성 위험의 조기 경보 신호로 삼을 수 있다. NFT와 커뮤니티 분석에서는 민팅·리빌·에어드랍 이벤트와 메시지 토큰을 결합해 컬렉션 내러티브를 파악하고 마케팅 성과를 역추적한다.
인프라 운영 관점에서는 가스 가격이 급등할 때 호출 함수 분포가 어떻게 바뀌는지 분석해 트래픽 셰이핑과 비용 최적화에 반영할 수 있다.
파이프라인에서 확인할 제어 지점
수집 오류는 재시도와 재스캔으로 처리하고, 정규화된 데이터는 규칙과 ML 기반 중복·스팸 필터를 거친다. 모델 단계에서는 버전과 Seed를 고정해야 이후 결과를 비교할 수 있다.
온체인 조회와 오프체인 인덱싱의 선택
| 아키텍처 | 성능 | 확장성 | 일관성 | 안정성 | 운영 편의 |
|---|---|---|---|---|---|
| 온디맨드 온체인 쿼리 | 초기 비용 낮음, 지연 높음 | API 한도 제약, 수평 확장 어려움 | 재org 영향 큼 | Provider 품질 의존 | 빠른 PoC, 단순 운영 |
| 오프체인 데이터레이크/인덱서 | 배치·컬럼형 쿼리 고성능 | 샤딩/파티셔닝 용이 | 스냅샷 기반 강한 일관성 | 재처리·백필로 복구 용이 | 파이프라인 운영 부담, 자동화 필요 |
빠른 PoC에는 온디맨드 쿼리가 맞을 수 있지만 API 한도와 Provider 품질의 영향을 받는다. 반복 분석과 대규모 쿼리가 필요한 경우에는 데이터레이크나 인덱서를 운영하는 편이 유리하다. 대신 자동화와 파이프라인 유지 부담이 생긴다.
이더리움 메타데이터로 LDA를 학습하는 예시
전제조건은 다음과 같다.
- Python 3.10+, 패키지: web3==6.*, pandas, gensim, numpy, python-dotenv
- Ethereum HTTPS Provider(Infura/Alchemy) 키 보유
- 테스트 범위 축소(최근 200~500개 트랜잭션) 권장
# requirements:
# pip install web3==6.11.3 pandas gensim numpy python-dotenv
import os
from dotenv import load_dotenv
from web3 import Web3
from gensim import corpora, models
from collections import defaultdict
from datetime import datetime
load_dotenv()
RPC = os.getenv("ETH_RPC", "https://mainnet.infura.io/v3/YOUR_KEY")
w3 = Web3(Web3.HTTPProvider(RPC))
assert w3.is_connected(), "RPC 연결 실패"
# 대표 함수 시그니처 매핑(예시)
SIG_MAP = {
"0xa9059cbb": "transfer(address,uint256)",
"0x095ea7b3": "approve(address,uint256)",
"0x23b872dd": "transferFrom(address,address,uint256)",
"0x5ea1b01d": "stake(uint256)",
"0x2e1a7d4d": "withdraw(uint256)",
}
def fetch_block_range(latest, span=20):
end = latest
start = max(0, latest - span + 1)
return range(start, end + 1)
latest_block = w3.eth.block_number
blocks = fetch_block_range(latest_block, span=30)
documents = [] # 각 문서 = 블록 단위 토큰 리스트
doc_ids = [] # 블록 번호 목록
for bn in blocks:
block = w3.eth.get_block(bn, full_transactions=True)
tokens = []
for tx in block.transactions:
# 컨트랙트 호출만 대상으로 함
if tx.to is None and tx.input: # 컨트랙트 배포는 제외
continue
if tx.input and len(tx.input) >= 10:
sig = tx.input[:10].lower()
fname = SIG_MAP.get(sig, f"sig:{sig}")
tokens.append(fname)
# 주소 라벨 토큰(간단화): EOAs/Contracts 구분
tokens.append("to:contract" if w3.eth.get_code(tx.to) else "to:eoa")
if tokens:
documents.append(tokens)
doc_ids.append(bn)
# 빈 문서 제거
assert documents, "토큰 문서 없음. 블록 범위를 확장할 것"
# 단어 빈도 하한 적용
frequency = defaultdict(int)
for doc in documents:
for token in doc:
frequency[token] += 1
filtered_docs = [[t for t in doc if frequency[t] >= 2] for doc in documents]
dictionary = corpora.Dictionary(filtered_docs)
corpus = [dictionary.doc2bow(text) for text in filtered_docs]
# LDA 학습
K = 5
lda = models.LdaModel(
corpus=corpus,
id2word=dictionary,
num_topics=K,
passes=5,
alpha="symmetric",
eta="auto",
random_state=42,
)
print(f"학습 문서 수={len(corpus)}, 어휘 수={len(dictionary)}")
for t in range(K):
terms = lda.show_topic(t, topn=8)
print(f"Topic {t}: " + ", ".join([w for w, _ in terms]))
# 블록별 주제 분포 예시 출력
for i, bow in enumerate(corpus[:5]):
dist = lda.get_document_topics(bow, minimum_probability=0.05)
ts = w3.eth.get_block(doc_ids[i]).timestamp
print(datetime.utcfromtimestamp(ts), doc_ids[i], dist)
random_state와 데이터 스냅샷 버전을 고정하면 결과를 다시 검토할 수 있다. 운영 범위에서는 SIG_MAP을 4byte 디렉터리와 ABI 레지스트리로 확장하고, 주소 라벨 소스를 병합한다. 블록 단위 문서에서 주소나 컨트랙트 단위 문서로 전환하면 토큰 다양성이 늘어나므로 K 증가가 필요하다.
데이터 신뢰도와 해석 가능성의 균형
확정 처리 뒤 재org를 감지하면 해당 블록을 재처리하고, 인덱싱 수집기에는 지연 경보를 둔다. 크라우드소스 라벨을 병합할 때는 출처와 신뢰도에 가중치를 부여하며, 오탐을 줄이기 위해 블랙리스트와 화이트리스트를 함께 운영한다.
온체인 공개 정보라도 개인 식별 정보와의 결합을 금지하고 AML/KYC 목적에는 최소 수집 원칙을 적용한다. 실시간성과 정확도, 비용과 해석 가능성은 함께 조정해야 하는 조건이다. K와 사전을 확장할수록 토픽 해석 난이도가 높아질 수 있다.
신규 공격이나 사기 패턴의 주제 출현을 일찍 감지하면 대응 시간을 30~60% 단축할 수 있다. AML·포렌식 큐레이션 시간은 40% 내외 절감하고 거짓 양성률을 낮출 수 있으며, 프로토콜·자산·이벤트 축의 주제 히트맵은 의사결정 속도를 높인다. 중복 스캔을 줄여 운영 비용을 20%↓ 절감하는 효과도 기대할 수 있다.