Compact Block Filters는 Bitcoin 블록 내용을 작게 요약한 데이터입니다. 지갑은 이를 내려받고 자신의 기기에서 어떤 블록에 관련 결제가 있을지 확인한 뒤, 필요한 블록 전체를 요청합니다. 데이터 사용량을 줄이고 무엇을 찾는지도 덜 드러낼 수 있습니다. 하지만 필터가 일치한다고 결제가 증명되는 것은 아니며, Bitcoin 규칙을 모두 검증하는 과정도 대신하지 못합니다.
안나는 휴대전화 지갑으로 입금을 기다리고 있습니다. 지갑은 비트코인을 받고 보내는 앱이나 기기입니다. 블록은 거래 묶음이지만, 휴대전화가 모든 묶음을 통째로 내려받을 필요는 없습니다. 책의 색인을 보고 필요한 페이지를 찾듯이, 먼저 작은 필터들을 살펴볼 수 있습니다. 같은 블록과 필터 유형에 대해서는 모든 사용자가 같은 요약을 받습니다. 안나와 관련 있는지 고르는 일은 휴대전화 안에서 일어납니다. 기술 문서 BIP 157은 필터를 받고 확인하는 방법을, BIP 158은 내용과 만드는 방법을 정합니다. 지갑은 먼저 블록들을 연결하는 기본 기록인 블록 헤더를 검증하고, 이어서 필터 확인 데이터와 필터 자체를 받습니다. 일치하면 블록 전체를 내려받아 실제 거래를 찾습니다. 이름이 비슷한 BIP 152의 Compact Blocks는 다른 문제, 즉 새 블록을 노드 사이에서 빨리 전달하는 문제를 해결합니다. 노드는 거래와 블록을 검증하고 네트워크의 다른 참여자와 통신하는 소프트웨어입니다. [1] [2] [5] [6]
Bitcoin 거래는 금액과 나중에 쓸 수 있는 조건을 담은 출력을 만듭니다. 그 조건을 표현하는 코드는 scriptPubKey라고 합니다. 새 거래의 입력은 쓰려는 이전 출력을 가리킵니다. 따라서 0x00으로 식별하는 basic 필터에는 새 출력의 스크립트뿐 아니라 해당 블록에서 쓰는 이전 출력의 스크립트도 들어갑니다. 안나는 이를 통해 받은 돈과 쓴 돈을 찾을 수 있습니다. 새 출력 중 OP_RETURN으로 시작하는 스크립트는 제외합니다. 이 명령은 출력을 쓸 수 없게 만듭니다. 이전 출력을 쓰지 않고 채굴자 보상을 배정하는 coinbase 거래의 특수 입력도 제외합니다. 빈 항목은 빼고 중복 항목은 한 번만 셉니다. 모든 거래 식별자 txid, 주소 문자열, 서명 같은 witness 데이터를 나열한 목록은 아닙니다. 올바르게 만들려면 새 블록 외에도 그 안의 거래가 쓰는 이전 출력 데이터가 필요합니다. [2]
서버는 안나의 결제를 고의로 뺀 요약을 보낼 수 있습니다. 그래서 지갑은 이전 필터와의 연결도 확인합니다. 해시는 데이터의 짧은 디지털 지문입니다. 저장된 필터에 SHA-256을 두 번 적용하면 double-SHA256 해시가 됩니다. 이 지문을 이전 필터 헤더에 이어 붙이고 같은 방식으로 해시하면 다음 헤더가 나옵니다. 이전 필터가 바뀌면 뒤의 확인 데이터도 달라집니다. 하지만 채굴로 보호되는 블록 헤더에는 이 보조 필터 체인의 해시가 들어 있지 않습니다. 연결된 모든 서버가 같은 가짜 체인을 주면 지문들이 완벽하게 이어질 수도 있습니다. 수학적으로 일관된다는 사실만으로 요약이 실제 블록과 맞는다고 증명되지는 않습니다. [1]
따라서 BIP 157은 서로 독립적인 여러 노드, 이 통신에서 peers라고 부르는 상대에 연결할 것을 권합니다. 자신의 노드처럼 신뢰하는 노드에 안전하게 연결하는 것도 방법입니다. 필터 체인들이 충돌하면 지갑은 첫 차이점을 찾고, 해당 블록과 필요한 이전 출력으로 올바른 필터를 다시 만들 수 있습니다. 정확한 필터를 식별한다는 보장은 적어도 하나의 정직한 피어를 전제로 합니다. 같은 공격자에게 여러 번 연결해도 그 조건을 충족하지 못합니다. 체인 자체도 바뀔 수 있습니다. 재구성 때는 체인 끝부분이 누적된 입증 작업량이 더 많은 가지로 교체됩니다. 지갑은 새 가지의 필터를 따라가며 영향을 받은 결제를 다시 판단해야 합니다. 이전에 찾은 확인도 네트워크가 어느 체인을 받아들이는지에 계속 의존합니다. [1] [2]
이전 BIP 37 방식에서는 지갑이 관찰하려는 대상을 담은 개인 필터를 서버에 보냈습니다. Compact Block Filters는 반대로 일반 데이터를 내려받은 뒤 기기 안에서 개인적인 선택을 합니다. 따라서 관찰하는 스크립트에 관한 정보가 덜 새어 나갑니다. 그래도 제공자는 안나가 나중에 어떤 전체 블록을 요청하는지 보고, 이를 연결의 네트워크 주소인 IP 주소와 묶을 수 있습니다. 반복 접속은 추가 패턴을 드러낼 수 있습니다. BIP 157은 지갑이 먼저 연결을 연 노드들 중에서 전체 블록 제공자를 무작위로 선택하도록 권합니다. 블록은 필터와 다른 노드에서 받아도 됩니다. 프라이버시는 나아지지만 익명성이 보장되지는 않습니다. [1]
필터는 이미 체인에 들어간 블록을 설명합니다. 특정 노드가 전달하거나 채굴하기 위해 보관하는 미확인 거래 집합인 현재 Mempool은 다루지 않습니다. 일치했다고 해서 안나가 발견된 자금을 쓸 키를 갖고 있다는 뜻도 아닙니다. 개인키는 지갑이 자금 지출을 승인하는 디지털 서명을 만들 때 사용하는 비밀 숫자 값입니다. 지갑은 실제 거래와 블록 포함 여부를 확인해야 합니다. 그래도 경량 클라이언트는 Full Node처럼 모든 블록의 모든 거래를 모든 규칙에 따라 검증하지는 않습니다. 자원 절약에는 실제 보안상의 절충이 따릅니다. 데이터 가용성은 별개입니다. Pruned Node는 검증한 옛 블록을 지우면서 필터는 보관할 수 있습니다. 안나는 요약을 받더라도 옛 블록 전체는 다른 곳에서 받아야 합니다. 오래된 데이터를 지운다는 사실만으로 노드가 완전한 규칙 검증을 그만두는 것은 아닙니다. [1] [5]
작은 크기에는 대가가 있습니다. 찾는 항목이 블록에 없어도 필터가 “있을 수도 있다”고 답할 수 있습니다. 이것이 false positive, 즉 오탐입니다. 안나는 불필요한 블록을 내려받지만 지갑은 실제 결제를 찾지 못하므로 잔액에 더해서는 안 됩니다. 올바른 필터는 규칙상 실제로 포함한 항목을 놓치지 않습니다. 다만 이 성질이 부정직한 서버가 지어낸 데이터까지 믿을 만하게 만들지는 않습니다. 기술적으로는 SipHash-2-4가 항목을 N × M 크기의 범위 안 숫자로 바꿉니다. N은 항목 수입니다. 숫자를 정렬하고 차이를 Golomb-Rice 방식으로 작게 저장합니다. P=19는 인코딩을 조절하고, M=784931은 우연한 일치에 영향을 줍니다. 집합 밖 항목 하나를 조회할 때 오탐 확률은 약 1/M입니다. 바이트는 데이터의 양을 나타내는 일반적인 단위입니다. SipHash 키는 블록 해시를 little-endian, 즉 하위 바이트부터 나열했을 때 처음 16바이트입니다. 지갑의 비밀 키가 아닙니다. 여기서 SipHash는 항목을 필터에 쓸 숫자로 바꿀 뿐, 암호화하지 않습니다. 저장된 필터는 음이 아닌 정수용 CompactSize 형식으로 쓴 N부터 시작합니다. [2]
검토일 2026-10-17 기준 두 문서의 상태는 Deployed입니다. 프로토콜이 배포되었다는 뜻이지 모든 지갑이 지원한다는 뜻은 아닙니다. 아래 설정 예시는 구체적으로 Bitcoin Core 29.0을 다룹니다. -blockfilterindex는 로컬 인덱스를 만듭니다. 다른 노드에 제공하려면 -peerblockfilters와 basic 인덱스가 필요하며 NODE_COMPACT_FILTERS가 지원을 알립니다. 프로그램용 RPC 인터페이스에서 getblockfilter는 지정 블록의 filter와 header 필드를 반환합니다. 따라서 RPC가 작동하는 것만으로 다른 네트워크 노드가 필터를 받을 수 있다고 볼 수 없습니다. 명세를 읽을 때 getcfilters/cfilter는 필터를, getcfheaders/cfheaders는 연결 확인 데이터를, getcfcheckpt/cfcheckpt는 보조 체인의 검사 지점을 다룬다는 점을 알면 됩니다. 이들은 네트워크 메시지 이름이지 모바일 지갑 사용자가 입력해야 하는 명령이 아닙니다. [3] [4]
더 정확히 이해하려면 이 항목과 함께 다음도 읽어 보세요 Neutrino, Full Node, Pruned Node, Bitcoin 프라이버시, Compact Blocks, Mempool. 다음 항목에서도 이 글을 참조합니다 Compact Block Filters, Neutrino.