Neutrino 방식의 경량 wallet은 주소 목록을 server에 직접 보내는 대신 full node가 block별로 만든 BIP158 compact filter를 받아 자기 scriptPubKeys와 local match합니다. BIP157에 따라 먼저 proof-of-work block headers와 filter header chain을 동기화·검증하고, filter가 관련 가능성을 보인 block만 전체 다운로드해 실제 transaction을 검사합니다. Filter는 probabilistic해 false positive가 가능하지만 false negative가 없도록 정해진 element set과 encoding을 정확히 구현해야 합니다.
필터 생성은 server가 하고 검색은 client가 합니다
BIP37 Bloom filter 방식은 client가 관심 데이터를 peer에게 전달해 privacy와 node DoS 문제를 만들었습니다. BIP157은 방향을 반대로 바꿔 full nodes가 결정적인 block filters를 생성·저장하고 모든 clients에 같은 값을 제공합니다. Client는 자신의 wallet data를 local에서 질의합니다.
Filter match는 transaction inclusion proof 자체가 아닙니다. Client는 일치한 full block을 받아 block header의 Merkle root와 proof-of-work chain에 연결되는지 확인하고 transaction outputs·inputs를 직접 scan합니다. Server 응답만으로 wallet balance를 확정하지 않습니다.
Neutrino는 내 주소를 서버에 물어보는 대신, 서버가 제공한 공통 블록 요약을 내 기기에서 검색합니다.
JOBCOIN 해설

그림은 이 주제의 공통 개념을 단순화한 설명입니다. 아래 항목에서 이 글의 구체적인 조건과 예외를 함께 읽어보세요.
- 필터 생성은 server가 하고 검색은 client가 합니다
BIP37 Bloom filter 방식은 client가 관심 데이터를 peer에게 전달해 privacy와 node DoS 문제를 만들었습니다.
- Filter header chain이 응답 변조를 드러냅니다
각 filter hash는 serialized filter의 double-SHA256이고 filter header는 현재 filter hash와 이전 filter header를 이어 다시 double-SHA256한 값입니다.
- BIP158 basic filter의 element set을 지킵니다
BIP158 basic filter는 block의 non-OP_RETURN outputs scriptPubKeys와 그 block이 소비한 이전 outputs의 scriptPubKeys 등을 정해진 규칙으로 포함합니다.
AI로 제작한 개념도 · 실제 가격·거래 내역·통계가 아닙니다.
Filter header chain이 응답 변조를 드러냅니다
각 filter hash는 serialized filter의 double-SHA256이고 filter header는 현재 filter hash와 이전 filter header를 이어 다시 double-SHA256한 값입니다. 그래서 앞선 filter 하나가 바뀌면 이후 chain이 달라집니다. Client는 cfcheckpt와 cfheaders를 여러 peers에서 받아 충돌 지점을 찾을 수 있습니다.
BIP157은 먼저 전체 block header chain을 headers-first로 sync하라고 요구합니다. Filter header가 어떤 block hash에 대응하는지 고정한 뒤 cfilter를 검증합니다. 가장 많은 proof-of-work chain을 판정하지 않은 채 filter부터 믿으면 악성 peer가 가짜 history view를 만들 수 있습니다.
| 단계 | 데이터 | 검증 |
|---|---|---|
| 1 | Block headers | proof of work·best chain |
| 2 | Filter checkpoints | peer 간 비교 |
| 3 | Filter headers | 이전 header 연결 |
| 4 | Compact filters | filter hash 일치 |
| 5 | Matched blocks | Merkle·transaction scan |
BIP158 basic filter의 element set을 지킵니다
BIP158 basic filter는 block의 non-OP_RETURN outputs scriptPubKeys와 그 block이 소비한 이전 outputs의 scriptPubKeys 등을 정해진 규칙으로 포함합니다. Coinbase input과 empty scripts 같은 예외가 있습니다. 구현이 elements를 임의로 빼면 wallet이 관련 transaction을 영구히 놓치는 false negative가 생깁니다.
Elements는 block hash에서 만든 SipHash key로 범위에 map되고 정렬된 차이를 Golomb-Rice coding으로 압축합니다. Parameter P와 M은 filter type에 고정됩니다. 단순 Bloom filter library로 대체하거나 address 문자열을 그대로 넣지 않습니다. Wallet이 찾는 대상은 decode된 script data입니다.
- Best block header chain을 먼저 동기화합니다.
- 여러 peer에서 checkpoints·filter headers를 비교합니다.
- Filter hash와 header chain을 검증합니다.
- Wallet scripts를 local match합니다.
- 일치 block을 무작위 peer에서 받아 직접 scan합니다.
False positive와 요청 패턴을 관리합니다
Probabilistic filter는 관련 없는 block을 match할 수 있습니다. Client는 full block scan 뒤 실제 wallet transaction이 없으면 false positive로 버리고 balance를 바꾸지 않습니다. False positive rate는 bandwidth tradeoff이며 사용자가 받는 금액 정확도와 혼동하면 안 됩니다.
특정 peer에 match한 blocks만 연속 요청하면 교차 분석으로 wallet 활동 범위를 추정할 수 있습니다. BIP157은 blocks를 random outbound peers에서 받을 수 있다고 설명합니다. Tor만 쓴다고 요청 패턴이 사라지지는 않으며 decoy·batch 전략은 구현별 privacy·bandwidth 비용을 평가해야 합니다.
Pruned node와 rescan 범위를 확인합니다
Full node는 filter를 생성한 뒤 오래된 block data를 prune할 수 있습니다. Filter는 제공해도 match한 과거 full block을 같은 peer가 줄 수 없을 수 있어 client는 다른 archival peer나 source가 필요합니다. Filter index 활성화와 보유 block range를 별도 capability로 확인합니다.
복구 wallet은 birthday height 이전을 불필요하게 scan하지 않되 잘못된 birthday로 입금을 놓치지 않게 margin을 둡니다. 상태에는 last verified block header, filter header, scanned block을 각각 checkpoint합니다. 중단 재개 시 한 숫자로 모두 완료 처리하지 않습니다.
자주 묻는 질문
Filter가 match하면 내 거래가 반드시 있나요?
아닙니다. False positive가 가능해 full block을 받아 실제 scripts와 거래를 검사해야 합니다.
Neutrino node는 내 주소를 알 수 없나요?
주소를 직접 보내지 않지만 요청한 block 패턴과 network metadata로 추정 가능성이 남습니다.
Filter header만 검증하면 transaction도 검증한 건가요?
아닙니다. Filter commitment를 확인한 것이며 match block과 transaction을 별도로 검증해야 합니다.
더 깊이 읽기
본문에서 다룬 개념과 확인 절차를 다음 글에서 이어서 살펴보세요.



