궁금한 주제를 찾아보세요

비트코인, 스테이블코인, 온체인 데이터처럼 주제로 검색하세요.

다시 읽을 이야기

저장한 글은 이 브라우저에만 보관됩니다.

해설블록체인 기술

eth_getProof로 계정·저장소 값을 검증하는 방법

신뢰한 블록 헤더의 stateRoot에서 accountProof와 storageProof를 검증해 RPC 응답의 잔액·코드·저장 슬롯을 독립적으로 확인하는 절차입니다.

난이도 중급주제 카테고리와 개념 밀도 기준
계정과 저장소의 값에서 증명 가지를 따라 상태 루트에 연결되는 eth_getProof 검증 개념도
주제의 이해를 돕기 위한 개념 일러스트
먼저 읽는 핵심

증명의 신뢰 기준점은 RPC 응답 자체가 아니라 별도로 신뢰한 블록 헤더의 stateRoot입니다.
계정 trie와 contract storage trie는 서로 다른 root와 키 경로를 사용합니다.
포함되지 않은 계정·slot도 올바른 trie 부재 증명으로 확인할 수 있습니다.

eth_getProof는 지정한 주소의 nonce, balance, codeHash, storageHash와 함께 이 값을 블록의 stateRoot에 연결하는 accountProof, 요청한 슬롯별 storageProof를 돌려줍니다. 검증자는 먼저 믿을 수 있는 블록 헤더와 정확한 stateRoot를 확보한 뒤, 주소를 Keccak-256으로 해시한 계정 트라이(account trie) 경로를 따라 증명 노드를 검증합니다. 이렇게 검증한 계정 안의 storageRoot를 기준으로, 각 32바이트 슬롯 키를 Keccak-256으로 해시한 경로와 RLP 값을 확인합니다. RPC가 함께 준 balance나 value만 비교해서는 부족하며, 증명이 고정된 블록 해시와 헤더의 루트에 실제로 이어지는지 확인해야 합니다.

증명은 신뢰한 stateRoot에서 시작합니다

eth_getProof 응답에는 address, balance, nonce, codeHash, storageHash, accountProof, storageProof가 들어 있습니다. 이 필드들이 한 JSON 안에 같이 있다고 해서 진짜라는 보장은 없습니다. 검증자는 대상 블록 해시의 헤더를 믿을 수 있는 경로로 얻고, 그 헤더의 stateRoot를 루트로 삼아 accountProof 노드를 차례로 확인해야 합니다.

같은 RPC 엔드포인트에서 헤더와 증명을 모두 받으면 전송 오류를 잡는 데는 도움이 됩니다. 하지만 악의적인 제공자까지 독립적으로 검증하는 신뢰 모델은 되지 못합니다. 합의를 검증하는 경량 클라이언트, 직접 운영하는 노드, 또는 따로 합의된 헤더 출처가 필요합니다. 증명보다 먼저 블록 헤더의 신뢰 경계를 정합니다.

머클 증명은 값을 믿으라는 서명이 아니라, 이미 신뢰한 루트에 그 값이 연결된다는 경로입니다.

JOBCOIN 해설

그림으로 보기프로토콜 실행의 기본 구조
입력이 실행 규칙을 통과할 때 상태가 바뀌는 프로토콜 개념도
그림과 함께 짚어볼 본문 내용

그림은 이 주제의 공통 개념을 단순화한 설명입니다. 아래 항목에서 이 글의 구체적인 조건과 예외를 함께 읽어보세요.

  1. 증명은 신뢰한 stateRoot에서 시작합니다

    eth_getProof 응답에는 address, balance, nonce, codeHash, storageHash, accountProof, storageProof가 들어 있습니다.

  2. accountProof에서 계정의 네 필드를 복원합니다

    이더리움 상태 트라이에서 계정 키는 20바이트 주소 그 자체가 아니라 주소의 Keccak-256 해시입니다.

  3. storageProof는 검증된 storageRoot에서 다시 시작합니다

    storageProof의 각 항목은 요청한 key, value와 증명 노드 배열을 담고 있습니다.

설명을 위한 개념도 · 실제 가격·거래 내역·통계가 아닙니다.

accountProof에서 계정의 네 필드를 복원합니다

이더리움 상태 트라이에서 계정 키는 20바이트 주소 그 자체가 아니라 주소의 Keccak-256 해시입니다. 증명 노드를 해시 참조나 인라인 참조 규칙에 따라 따라가면 해당 키의 리프 값에 닿습니다. 계정 값은 nonce, balance, storageRoot, codeHash를 RLP로 인코딩한 구조이므로, 이를 디코딩해 응답 필드와 대조합니다.

계약 바이트코드는 상태 트라이 안에 직접 들어 있지 않고, 계정의 codeHash가 코드의 Keccak-256 값을 가리킵니다. 코드까지 검증하려면 같은 블록에서 eth_getCode로 바이트를 받아 해시를 비교합니다. 일반 지갑 계정(EOA)은 보통 빈 코드의 해시를 담고 있지만, 계정이 있는지 여부와 nonce·balance는 증명으로 따로 판정합니다.

eth_getProof 필드와 검증 기준
필드 검증 기준 자주 하는 오류
accountProof 헤더의 stateRoot 응답의 balance만 비교
storageHash 검증된 계정 값 RPC 값을 새 루트로 신뢰
storageProof.key 요청한 슬롯 키 매핑의 논리 키와 혼동
storageProof.value 저장소 트라이 리프의 RLP 32바이트 워드 그대로라고 가정
codeHash 코드 바이트의 Keccak-256 코드가 트라이 리프에 있다고 가정

storageProof는 검증된 storageRoot에서 다시 시작합니다

storageProof의 각 항목은 요청한 key, value와 증명 노드 배열을 담고 있습니다. 먼저 accountProof에서 얻은 storageRoot를 기준으로 삼습니다. 요청한 슬롯은 32바이트로 정규화하고, 그 바이트의 Keccak-256 값을 저장소 트라이 경로로 씁니다. 리프에서 나온 RLP 스칼라를 디코딩해 정수로 되돌린 뒤 응답의 value, 기대하는 ABI 표현과 대조합니다.

솔리디티 매핑의 논리 슬롯 계산과 트라이 경로 계산은 서로 다른 두 단계입니다. 예를 들어 mapping(address=>uint) 원소의 슬롯은 ABI 방식으로 키와 매핑 기준 슬롯을 32바이트씩 이어 붙여 Keccak-256으로 해시해 구합니다. 그렇게 얻은 슬롯 키를 다시 Keccak-256으로 해시한 값이 저장소 트라이의 경로가 됩니다. 매핑 슬롯 해시와 트라이 키 해시를 한 번으로 합치지 않습니다.

  • 대상 chainId와 블록 해시를 먼저 고정합니다.
  • 헤더를 검증하고 stateRoot를 신뢰 기준점으로 둡니다.
  • 주소 해시 경로로 accountProof를 검증합니다.
  • RLP 계정 값에서 storageRoot와 codeHash를 복원합니다.
  • 솔리디티 저장소 배치에 따라 요청할 논리 슬롯을 계산합니다.
  • 슬롯 해시 경로로 storageProof와 값의 부재를 검증합니다.
  • 디코딩한 값과 애플리케이션이 기대하는 타입을 대조합니다.

값이 없다는 결과도 정상적인 증명입니다

머클 패트리샤 트라이(Merkle Patricia Trie) 증명은 리프에 닿는 경우만 보여 주지 않습니다. 경로 중간의 분기 노드에 필요한 자식이 없거나, 확장·리프 노드의 압축 경로가 요청 키와 달라 더 나아갈 수 없음을 보이면 키가 없다는 사실도 검증할 수 있습니다. 따라서 아직 만들어지지 않은 계정이나 값이 비어 있는 저장소 슬롯은 ‘노드가 오류를 냈다’가 아니라 검증할 수 있는 부재일 수 있습니다.

다만 값 0과 계정 자체의 부재를 업무상 같은 의미로 볼지는 별개 문제입니다. 생성되지 않은 계정, 존재하지만 잔액이 없는 계정, selfdestruct나 프로토콜 변화와 얽힌 계정 상태를 구분하려면 nonce, codeHash, 증명 결과를 함께 해석합니다. 빈 값도 증명 경로를 끝까지 검사합니다.

블록을 고정하지 않으면 증명과 기대값이 엇갈립니다

balance를 latest 기준으로 읽고 잠시 뒤 증명도 latest로 요청하면, 두 호출 사이에 새 블록이 들어와 값이 달라질 수 있습니다. 대상 헤더 해시를 먼저 정하고 같은 블록 식별자로 eth_getProof, eth_getCode와 관련 조회를 실행합니다. 지원하는 엔드포인트라면 EIP-1898의 blockHash 기반 요청과 정식 체인 요구 조건도 검토합니다.

최종 확정된 헤더를 기준으로 검증하면 재편성 위험은 낮아지지만 최신성은 떨어집니다. latest 기준 증명은 암호학적으로 그 헤더와 연결되더라도, 그 헤더 자체가 나중에 정식 체인에서 빠질 수 있습니다. 증명의 유효성과 체인의 확정성은 서로 다른 검증 축입니다.

라이브러리 구현은 트라이 인코딩의 경계를 시험합니다

증명 노드는 RLP로 인코딩된 트라이 노드 바이트이며, 분기 노드는 17개 항목, 확장 노드와 리프 노드는 두 항목으로 이뤄집니다. 헥스 접두 압축 인코딩의 리프 종료 표시, 홀수·짝수 니블 플래그, 32바이트보다 짧은 노드의 인라인 참조 규칙을 직접 구현하면 경계 오류가 자주 납니다. 충분히 검증된 트라이 라이브러리를 쓰고 원문 시험 벡터를 추가합니다.

테스트에는 존재하는 계정, 없는 계정, 값이 비어 있는 슬롯, 값이 있는 매핑 슬롯, 짧은 인라인 자식, 잘못된 노드 해시, 다른 블록의 루트를 넣습니다. 증명 배열의 순서를 바꾸거나 노드 하나의 니블을 고쳤을 때는 반드시 실패해야 합니다. 성공 사례만으로는 제공자가 준 값을 그대로 통과시키는 가짜 검증기를 찾아내기 어렵습니다.

운영 기록은 재현할 수 있는 검증 묶음으로 남깁니다

감사 기록에는 chainId, 블록 번호·해시, 헤더의 stateRoot, 주소, 원래 요청한 슬롯, 증명 바이트, 검증기 버전, 최종 디코딩 값을 보관합니다. 동적 배열이나 매핑이라면 솔리디티 컴파일러의 저장소 배치와 키 계산 입력값도 남겨 나중에 같은 슬롯을 재현합니다.

엔드포인트를 바꿔 같은 블록 해시의 증명을 받으면 노드 배열 구성은 다를 수 있지만, 같은 루트와 값으로 검증돼야 합니다. 실패했을 때 헤더 불일치, 계정 경로, 저장소 경로, RLP 디코딩, ABI 디코딩 단계를 나눠 기록해 둬야 원인을 제공자 탓으로 성급히 단정하지 않습니다.

자주 묻는 질문

eth_getProof 응답만 있으면 누구도 믿지 않고 상태를 검증할 수 있나요?

아닙니다. 따로 신뢰하거나 합의 검증을 거친 블록 헤더의 stateRoot가 증명의 기준점으로 필요합니다.

솔리디티 매핑 슬롯을 한 번 해시하면 증명 키가 되나요?

매핑 원소의 논리 슬롯을 계산한 뒤, 그 32바이트 슬롯 키를 다시 Keccak-256으로 해시해야 저장소 트라이 경로가 됩니다.

값이 0이면 증명 노드가 없어도 되나요?

0이나 부재를 주장할 때도, 트라이 경로에 해당 키가 없음을 증명하는 유효한 증명 노드들이 필요합니다.

더 깊이 읽기

본문에서 다룬 개념과 확인 절차를 다음 글에서 이어서 살펴보세요.

참고한 원문 자료

자료 확인 기준일 2026.09.27
  1. EIP-1186: RPC-Method to get Merkle Proofs — eth_getProofeips.ethereum.org
  2. ethereum.org — Merkle Patricia Trieethereum.org
  3. EIP-1898: Add blockHash to defaultBlock methodseips.ethereum.org
작성 방식과 확인 범위
출처 수집
원문 링크 3개 제공
작성·확인
공식 기관 자료를 근거로 AI 도구를 활용해 작성했고, 운영자가 발행 전에 읽어 확인합니다.
전문가 검토
세무·법률 전문가 검토는 거치지 않았습니다.

투자·세무 판단은 전문가와 상의하세요. 제도와 거래소 안내는 바뀔 수 있으니 원문의 적용 대상과 최신 안내를 함께 확인해 주세요.

이해를 위한 정보 콘텐츠

이 글은 특정 자산의 매수·매도 또는 수익을 권유하지 않습니다. 자료의 발표 시점과 이후 변경 사항을 함께 확인해 주세요.

편집 원칙 보기 →이 기사 정정 제보 →