궁금한 주제를 찾아보세요

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

다시 읽을 이야기

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

해설블록체인 기술

Solidity custom error와 revert data를 디코딩하는 법

Custom error selector와 ABI 인수, Error(string)·Panic(uint256)·빈 returndata를 구분하고 신뢰할 ABI 없이 이름을 단정하지 않는 진단법을 설명합니다.

난이도 중급주제 카테고리와 개념 밀도 기준
원시 오류 데이터가 해독 장치를 지나 경고 원인과 매개변수로 나뉘는 Solidity custom error 개념도
주제의 이해를 돕기 위한 개념 일러스트
먼저 읽는 핵심

Custom error는 4바이트 selector와 ABI 인수로 구성됩니다.
Error string·Panic code·custom selector·빈 returndata를 먼저 분류합니다.
오류 bytes는 호출 경계를 넘어 전달되거나 위조될 수 있어 call trace가 필요합니다.

솔리디티(Solidity) 사용자 정의 오류(custom error)의 되돌림 데이터(revert data)는 오류의 정규 시그니처를 Keccak-256으로 해시한 값의 앞 4바이트 선택자 뒤에 ABI로 인코딩한 인수를 붙인 형식입니다. 예를 들어 InsufficientBalance(uint256,uint256)의 선택자 뒤에는 requested와 available을 담은 32바이트 워드 두 개가 옵니다. Error(string)은 0x08c379a0, Panic(uint256)은 0x4e487b71로 시작합니다. 가스 부족·잘못된 옵코드·반환 데이터가 없는 저수준 호출 실패에서는 빈 바이트가 돌아올 수도 있습니다. 외부 계약은 어떤 되돌림 바이트든 만들어 낼 수 있으므로, 선택자가 ABI의 오류 이름과 맞는다는 사실만으로 오류의 출처나 진위를 믿어서는 안 됩니다.

첫 네 바이트는 오류 시그니처의 선택자입니다

사용자 정의 오류를 error Unauthorized(address caller)로 선언하면 정규 시그니처 문자열은 Unauthorized(address)이고, 이를 keccak256으로 해시한 결과의 첫 4바이트가 선택자입니다. 되돌릴 때는 선택자 뒤에 caller 값을 ABI 워드로 인코딩해 붙입니다. 매개변수 이름은 시그니처에 들어가지 않으며, 튜플·배열은 정규 타입 표기를 따라야 합니다.

함수 선택자와 같은 4바이트 공간을 쓰기 때문에 서로 겹칠 수 있고, 선택자 데이터베이스가 내놓는 이름 후보는 증거가 아닙니다. 검증된 소스나 배포 바이트코드에 대응하는 ABI에서 오류 정의를 가져오고, 반환 데이터의 길이·오프셋·패딩이 전체 구조와 맞는지 확인합니다.

되돌림 선택자는 오류 이름표의 후보일 뿐입니다. 어느 호출 프레임이 어떤 조건에서 그 바이트를 만들었는지는 실행 추적(trace)이 증명합니다.

JOBCOIN 해설

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

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

  1. 첫 네 바이트는 오류 시그니처의 선택자입니다

    사용자 정의 오류를 error Unauthorized(address caller)로 선언하면 정규 시그니처 문자열은 Unauthorized(address)이고, 이를 keccak256으로 해시한 결과의 첫 4바이트가 선택자입니다.

  2. 표준 형식 세 가지와 빈 데이터를 구분합니다

    require(false, string)와 revert(string)는 보통 Error(string) 선택자 0x08c379a0 뒤에 동적 문자열의 오프셋·길이·바이트를 돌려줍니다.

  3. 잔액 부족 예제를 워드 단위로 풀어 봅니다

    error InsufficientBalance(uint256 requested,uint256 available)를 선언하고 requested=100, available=40으로 되돌렸다고 해 보겠습니다.

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

표준 형식 세 가지와 빈 데이터를 구분합니다

require(false, string)와 revert(string)는 보통 Error(string) 선택자 0x08c379a0 뒤에 동적 문자열의 오프셋·길이·바이트를 돌려줍니다. assert 실패나 산술 오버플로 같은 컴파일러 패닉은 Panic(uint256) 선택자 0x4e487b71과 패닉 코드를 씁니다. 사용자 정의 오류는 선언마다 고유한 선택자와 인수를 담습니다.

코드가 없는 주소에 인터페이스 호출을 했거나 가스 부족, 잘못된 옵코드, 반환 데이터 복사 전 실패 같은 경우에는 빈 바이트가 보일 수 있습니다. 빈 데이터만 보고 원인을 하나로 단정하지 말고 호출 대상 코드, 가스, 옵코드 추적, 클라이언트 오류를 서로 대조합니다.

Revert data 분류
형식 앞부분 다음 확인
Error(string) 0x08c379a0 오프셋·길이·UTF-8 바이트
Panic(uint256) 0x4e487b71 패닉 코드의 의미
사용자 정의 오류 keccak(signature)[0:4] 신뢰할 수 있는 ABI와 인수
빈 바이트 길이 0 가스·대상 코드·추적
알 수 없는 바이트 기타 선택자 충돌·전달·형식 오류

잔액 부족 예제를 워드 단위로 풀어 봅니다

error InsufficientBalance(uint256 requested,uint256 available)를 선언하고 requested=100, available=40으로 되돌렸다고 해 보겠습니다. 반환 데이터 앞 4바이트를 시그니처 해시와 비교하고, 남은 64바이트를 uint256 두 개로 디코딩합니다. 정적 타입이라 오프셋이 없지만, string이나 bytes 인수가 있으면 머리 부분의 오프셋을 따라가 꼬리 부분의 길이와 범위를 검사합니다.

디코더가 선택자를 떼지 않고 전체 바이트를 abi.decode에 넣으면 워드 정렬이 4바이트 밀립니다. 반대로 길이가 짧은 데이터를 억지로 잘라 내면 또 다른 예외가 생겨 원래 오류를 가립니다. 최소 길이와 모든 동적 오프셋이 반환 데이터 범위 안에 있는지 확인한 뒤에야 사람이 읽을 메시지를 만듭니다.

  • 성공 플래그와 반환 데이터의 헥스 값·길이를 먼저 보존합니다.
  • 4바이트 선택자를 떼어 내 알려진 세 형식으로 분류합니다.
  • 배포 주소·코드 해시에 맞는 ABI를 고릅니다.
  • 정적 워드와 동적 오프셋의 범위를 검증합니다.
  • 실패한 프레임과 호출자의 catch·전파 동작을 추적합니다.

오류는 외부 계약에서 위조돼 올라올 수 있습니다

솔리디티 ABI 명세는 오류 데이터가 호출 사슬을 타고 올라오며, 어떤 계약이든 다른 계약의 오류처럼 보이는 바이트를 만들 수 있다고 경고합니다. 라우터가 토큰의 사용자 정의 오류를 그대로 올려 보낼 수도 있고, 악성 토큰이 라우터 자체의 오류 선택자를 돌려줄 수도 있습니다. 그래서 화면에서 ‘라우터가 Unauthorized를 일으켰다’고 단정하지 않습니다.

try/catch는 Error(string)와 Panic(uint256) 같은 알려진 형식을 나눠 받을 수 있지만, 사용자 정의 오류는 저수준 바이트로 받아 선택자를 직접 디코딩해야 할 수 있습니다. catch가 실패를 정상 대체 경로처럼 처리한다면 상태 전이가 안전한지도 검토합니다. 오류 설명은 권한 판단의 근거가 아닙니다.

eth_call 오류와 채굴된 영수증을 같은 증거로 보지 않습니다

eth_call·estimateGas는 노드가 고른 블록 상태에서 실행해 되돌림 데이터를 돌려줄 수 있습니다. 하지만 대기 상태나 보낸 주소·금액·가스 설정이 실제 거래와 다르면 결과도 달라집니다. RPC 제공자가 error.data를 감싸거나 빼 버리는 방식도 클라이언트마다 다를 수 있습니다.

채굴된 영수증의 status 0은 실패를 증명하지만, 영수증 자체에는 되돌림 데이터가 저장되지 않습니다. 거래를 같은 과거 블록 상태에서 다시 실행하거나 디버그 추적을 해야 할 수 있습니다. 상태 덮어쓰기(state override)로 재현한 결과는 원본 실행의 증거라고 부르지 않습니다. 블록 해시·클라이언트 버전과 호출 매개변수를 함께 기록합니다.

자주 묻는 질문

영수증에서 사용자 정의 오류를 바로 읽을 수 있나요?

일반 영수증에는 되돌림 데이터가 없습니다. RPC 실행 오류나 과거 상태 재실행·추적에서 얻어야 하며, 제공자마다 지원 범위가 다릅니다.

선택자 데이터베이스가 찾은 이름은 확정인가요?

아닙니다. 4바이트 충돌과 위조가 일어날 수 있으므로 해당 배포 코드에 맞는 신뢰할 수 있는 ABI와 인수 디코딩을 확인해야 합니다.

빈 되돌림 데이터는 가스 부족 때문인가요?

여러 원인 중 하나일 뿐입니다. 대상 코드 유무, 잘못된 옵코드, 가스와 호출 추적을 함께 확인해야 합니다.

더 깊이 읽기

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

참고한 원문 자료

자료 확인 기준일 2026.09.27
  1. Solidity Contract ABI Specification — Errorsdocs.soliditylang.org
  2. Solidity Documentation — Error handlingdocs.soliditylang.org
작성 방식과 확인 범위
출처 수집
원문 링크 2개 제공
작성·확인
공식 기관 자료를 근거로 AI 도구를 활용해 작성했고, 운영자가 발행 전에 읽어 확인합니다.
전문가 검토
세무·법률 전문가 검토는 거치지 않았습니다.

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

이해를 위한 정보 콘텐츠

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

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