뱅어봇에 필터 달기 — 10분 분석으로 스캠 토큰 걸러내기
이 글은 개인 프로젝트 기록이며 투자 조언이 아닙니다.
지난 글에서 Printr 팩토리를 감지해서 자동매수하는 봇을 만들었다.
문제가 있었다. 새 토큰이 런칭되면 무조건 샀다.
Printr에 하루에 런칭되는 토큰이 몇 개인지 모르겠지만, 대부분은 0으로 간다. 발행자가 직접 산 후 팔고 튀는 러그풀, 처음부터 거래가 없어서 조용히 죽는 토큰. 무조건 사면 돈을 버릴 뿐이다.
그래서 필터를 달았다.
필터 설계 원칙
온체인에서 런칭 즉시 확인할 수 있는 것과, 몇 분 기다려야 알 수 있는 것을 구분했다.
즉시 확인 가능
- 발행자 지갑 트랜잭션 수 (지갑 나이/활성도)
- 발행자 ETH 잔액
시간이 필요한 것
- 5분 후 거래 건수 (초기 거래량)
- 10분 후 홀더 수
이 4가지를 점수로 환산해서, 기준 점수 이상일 때만 매수한다.
점수표
| 조건 | 점수 | |------|------| | 활성 지갑 (트랜잭션 50회 이상) | +30 | | 중간 지갑 (10~50회) | +10 | | 신규 지갑 (10회 미만) | -50 | | ETH 잔액 0.1 이상 | +20 | | ETH 잔액 0.01~0.1 | +10 | | ETH 잔액 0.01 미만 | -20 | | 5분 거래 50건 이상 | +20 | | 5분 거래 10~50건 | +10 | | 10분 홀더 30명 이상 | +10 | | 10분 홀더 10~30명 | +5 |
최대 80점, 30점 이상만 매수한다.
신규 지갑(-50점)과 잔고 부족(-20점)이 겹치면 -70점이라 어떤 조건을 만족해도 기준을 못 넘는다. 사실상 즉시 차단이다.
핵심 코드
async def score_token(token_addr, creator_addr, launch_block):
score = 0
reasons = []
# 조건 1+3: 발행자 트랜잭션 수
nonce = w3.eth.get_transaction_count(creator_cs)
if nonce < 10:
score -= 50
reasons.append(f"❌ 신규지갑 (tx={nonce}) -50점")
elif nonce < 50:
score += 10
else:
score += 30
# 조건 2: 발행자 ETH 잔액
bal = w3.eth.get_balance(creator_cs)
eth = bal / 1e18
if eth < 0.01:
score -= 20
elif eth < 0.1:
score += 10
else:
score += 20
# 5분 대기 후 거래량 체크
await asyncio.sleep(300)
logs = w3.eth.get_logs({
"address": token_cs,
"topics": [TRANSFER_SIG],
"fromBlock": launch_block,
"toBlock": w3.eth.block_number,
})
tx_count = len(logs)
if tx_count >= 50:
score += 20
elif tx_count >= 10:
score += 10
# 추가 5분 대기 후 홀더 수 체크
await asyncio.sleep(300)
logs = w3.eth.get_logs({ ... })
holders = set(log["topics"][2].hex()[-40:] for log in logs if len(log["topics"]) >= 3)
if len(holders) >= 30:
score += 10
elif len(holders) >= 10:
score += 5
return score, reasons
Transfer 이벤트를 가져와서 고유 수신 주소를 세는 방식으로 홀더 수를 근사한다. 완벽하진 않지만 런칭 직후 기준으로는 충분하다.
비동기 처리가 중요한 이유
필터 분석에 10분이 걸린다. 그 사이에 새 토큰이 또 런칭될 수 있다.
처음엔 순차적으로 처리했는데, 이러면 A 토큰 분석하는 10분 동안 B, C 토큰을 놓친다.
# 이전: 블로킹
await process_token(log)
# 수정: 비블로킹
asyncio.create_task(process_token(log))
create_task()로 각 토큰을 독립 태스크로 실행하면, 분석 중에도 폴링이 계속 돌아간다.
텔레그램 알림 예시
런칭 감지 즉시:
🚨 새 토큰 런칭!
🪙 MEME ($MEME)
📍 0xABCD...
👤 발행자: 0x1234...
⏳ 10분 필터 분석 중...
10분 후 통과 시:
✅ 필터 통과! (55/80점)
✅ 활성지갑 (tx=143) +30점
✅ 잔고 (0.823 ETH) +20점
✅ 5분 거래 67건 +20점
🟡 홀더 18명 +5점
💸 매수 진행...
미통과 시:
❌ 필터 미통과 (-20/80점)
❌ 신규지갑 (tx=3) -50점
🟡 잔고 (0.042 ETH) +10점
🟡 5분 거래 12건 +10점
🟡 홀더 11명 +5점
한계
10분 기다리면 얼리 타이밍은 포기하는 거다. 뱅어 토큰은 보통 런칭 직후 5분에 가장 많이 오른다.
필터 없이 100개 사면 1개 10배. 필터 걸면 10개 사는 대신 통과율이 올라가는 게 목표다. 데이터가 쌓이면 조건을 다듬을 예정이다.