머클 증명은 특정 leaf와 각 트리 단계의 sibling hash를 결합해 신뢰한 Merkle root를 재계산함으로써 그 leaf가 해당 데이터 집합에 포함됐음을 효율적으로 확인합니다. 유효한 증명은 데이터의 진실성, 최신성, 소유권까지 보증하지 않습니다. 어떤 root를 신뢰하는지, leaf를 어떤 바이트로 인코딩하고 해시했는지, 좌우 순서와 정렬 규칙이 무엇인지가 같아야 합니다.
증명자는 전체 데이터 대신 경로의 해시를 제공한다
머클 트리는 leaf들을 해시하고 인접 노드 해시를 다시 결합하는 과정을 root 하나가 남을 때까지 반복합니다. 특정 leaf를 검증할 때는 같은 층의 sibling hash와 좌우 위치만 있으면 위쪽 부모 해시를 차례로 계산할 수 있습니다. 전체 N개 항목을 보내는 대신 대략 log2(N)개의 해시가 필요합니다.
8개 leaf의 균형 트리라면 한 leaf에서 root까지 세 단계이므로 sibling 세 개가 필요합니다. 검증자는 leaf hash를 첫 sibling과 결합하고 그 결과를 다음 sibling과 결합해 최종 root를 만듭니다. 계산한 값이 신뢰한 root와 같을 때 해당 인코딩 leaf의 포함을 인정합니다.
| 검사 | 확인 가능 | 추가로 필요한 것 |
|---|---|---|
| 포함 증명 | leaf가 root 집합에 포함 | root의 신뢰 근거 |
| 데이터 무결성 | leaf 바이트가 바뀌지 않음 | 원문 인코딩 규칙 |
| 최신성 | root가 가리키는 시점만 | 최근 root 여부 |
| 비포함 | 일반 증명만으로 부족 | 정렬·sparse tree 규칙 |
해시 결합 순서와 leaf 인코딩이 일치해야 한다
부모를 hash(left || right)로 만드는 트리에서는 sibling이 왼쪽인지 오른쪽인지 알아야 합니다. 일부 구현은 두 hash를 정렬한 뒤 결합해 방향 비트를 생략합니다. OpenZeppelin MerkleProof는 정렬된 쌍을 전제로 하는 함수가 있으므로 트리를 만든 라이브러리와 검증 함수의 규칙을 맞춰야 합니다.
주소와 수량을 leaf로 쓴다면 abi.encode인지 abi.encodePacked인지, 수량 타입이 uint256인지, 도메인과 인덱스를 포함했는지가 중요합니다. 화면에 같은 값처럼 보여도 바이트 인코딩이 다르면 leaf hash가 달라집니다. leaf 생성 코드를 배포 문서에 고정합니다.
머클 증명은 문자열의 의미가 아니라 정확한 바이트와 root의 관계를 검증한다.
JOBCOIN 해설
root를 어디서 얻었는지가 증명의 신뢰를 결정한다
공격자가 root와 proof를 함께 제공하면 자기 데이터로 일관된 트리를 만들 수 있습니다. 검증자는 스마트 계약 상태, 충분히 확정된 블록 헤더, 서명된 공식 배포처럼 독립적으로 신뢰한 root를 가져와야 합니다. root를 웹 API 응답 하나에서 받아 그대로 검증하면 해시 계산은 맞아도 출처 검증이 없습니다.
Bitcoin 블록 헤더의 merkle root는 해당 블록 거래 집합을 커밋합니다. SPV 사용자는 거래 포함 증명과 함께 헤더가 작업증명 체인에 속하는지 확인합니다. 포함 증명만으로 그 거래가 충분히 확정됐거나 되돌릴 수 없다는 결론은 내릴 수 없습니다.
- root의 체인·계약·블록 높이와 출처를 확인한다.
- leaf 원문과 직렬화·해시 함수를 고정한다.
- sibling 순서 또는 정렬 규칙을 확인한다.
- 확정성·소유권·최신성은 별도 증거로 검증한다.
포함 증명은 데이터의 진실을 보증하지 않는다
에어드롭 트리에 주소와 수량이 포함됐다는 증명은 운영자가 그 root에 해당 항목을 넣었다는 뜻입니다. 사용자가 실제 자격 요건을 충족했는지, 수량 계산이 공정했는지까지 증명하지 않습니다. 준비금 트리도 leaf 잔액의 합과 root 관계를 보일 수 있지만 숨은 부채와 키 통제를 보이지 못합니다.
문서 해시가 트리에 포함돼도 문서 내용의 법적 효력이나 작성자 신원은 별도입니다. 검증 UI는 'proof valid'를 '사실 확인 완료'로 번역하지 말고 root·leaf·시점·검증 범위를 함께 표시해야 합니다.
일반 포함 증명의 실패는 비포함 증명이 아니다
주어진 proof로 root를 만들지 못하면 proof가 잘못됐거나 leaf·인코딩·root 중 하나가 다르다는 뜻입니다. 해당 leaf가 전체 집합 어디에도 없다는 사실을 직접 증명하지 않습니다. 서버가 일부러 다른 경로를 제공했을 가능성도 있습니다.
비포함을 증명하려면 정렬된 leaf 사이의 이웃 관계, sparse Merkle tree의 기본 빈 노드, Patricia trie 경로 같은 구조 규칙이 필요합니다. 어떤 트리 형식인지 모른 채 라이브러리 verify false만 보고 제외됐다고 단정하지 않습니다.
중복 leaf와 multiproof 경계를 시험한다
같은 leaf hash가 여러 위치에 있을 수 있으면 증명은 특정 인덱스 의미를 구분하지 못할 수 있습니다. 인덱스나 도메인을 leaf에 포함해 재사용 충돌을 줄입니다. 64바이트 raw leaf가 내부 노드 두 개의 연결과 혼동되는 구현상의 주의도 공식 라이브러리 문서에서 확인합니다.
multiproof는 여러 leaf의 공통 경로를 줄일 수 있지만 leaf 순서와 proofFlags 규칙이 복잡합니다. 빈 집합 처리와 완전하지 않은 트리 조건을 테스트합니다. 온체인 검증 gas와 calldata 크기를 함께 측정하고, root 변경 권한에는 timelock과 이벤트 감시를 적용합니다.
자주 묻는 질문
유효한 머클 증명이면 데이터가 사실인가요?
해당 leaf가 신뢰한 root에 포함됐다는 뜻입니다. 데이터 내용의 진실성, 소유권, 공정성은 별도 검증이 필요합니다.
증명 실패는 목록에 없다는 뜻인가요?
아닙니다. proof·인코딩·root가 맞지 않을 수 있으며 비포함에는 이를 지원하는 트리 구조와 증명이 필요합니다.
왜 전체 목록 대신 증명을 쓰나요?
균형 트리에서는 N개 전체 대신 대략 log2(N)개의 sibling hash로 포함을 확인해 전송량과 온체인 비용을 줄일 수 있습니다.



