ERC-165는 계약이 특정 인터페이스를 구현한다고 스스로 밝히는 supportsInterface(bytes4) 조회 규약입니다. 인터페이스 ID는 해당 인터페이스에 속한 함수 선택자들을 XOR한 bytes4 값이며, supportsInterface 호출은 30,000 가스 안에서 응답해야 합니다. 탐지하는 쪽은 먼저 ERC-165 ID 0x01ffc9a7에 true, 무효 ID 0xffffffff에 false를 돌려주는지 확인한 뒤 목표 ID를 묻습니다. 하지만 true는 계약의 자기 선언일 뿐, 각 함수가 올바른 의미·권한·반환값으로 동작한다거나 악성 콜백이 없다는 암호학적 증명이 아닙니다.
인터페이스 ID는 선택자 집합의 XOR입니다
함수 선택자는 정규 시그니처를 keccak256으로 해시한 값의 앞 4바이트입니다. ERC-165 인터페이스 ID는 그 인터페이스에 속한 함수 선택자들을 XOR해서 만듭니다. 반환 타입은 선택자에 들어가지 않고, 이름이 같은 오버로드 함수는 인수 타입이 달라 선택자도 따로 생깁니다. 이벤트와 오류 선택자는 인터페이스 ID에 넣지 않습니다.
솔리디티에서는 type(IMyInterface).interfaceId로 계산할 수 있지만, 상속한 인터페이스의 함수가 어떻게 포함되는지와 컴파일러 표현은 시험 벡터로 확인합니다. 소스의 함수 이름을 정렬해 문자열 해시 하나를 만드는 방식이 아닙니다.
supportsInterface의 true는 계약이 그 표찰을 붙였다는 뜻이며, 표찰에 적힌 행동을 정직하게 수행한다는 보증서는 아닙니다.
JOBCOIN 해설

그림은 이 주제의 공통 개념을 단순화한 설명입니다. 아래 항목에서 이 글의 구체적인 조건과 예외를 함께 읽어보세요.
- 인터페이스 ID는 선택자 집합의 XOR입니다
함수 선택자는 정규 시그니처를 keccak256으로 해시한 값의 앞 4바이트입니다.
- 두 단계 사전 검사로 ERC-165 지원을 확인합니다
EIP-165의 탐지 절차는 STATICCALL 방식의 조회로 0x01ffc9a7에 true를 돌려주는지, 0xffffffff에는 false를 돌려주는지 확인합니다.
- NFT 수신자 사례에서 실제 콜백을 따로 봅니다
ERC-721 계약이 수신자의 ERC165 응답만 보고 safeTransfer를 끝내지 않고, onERC721Received를 실제로 호출해 약속된 반환값(magic value)을 검사하는 이유가 바로 이 경계에 있습니다.
설명을 위한 개념도 · 실제 가격·거래 내역·통계가 아닙니다.
두 단계 사전 검사로 ERC-165 지원을 확인합니다
EIP-165의 탐지 절차는 STATICCALL 방식의 조회로 0x01ffc9a7에 true를 돌려주는지, 0xffffffff에는 false를 돌려주는지 확인합니다. 두 검사를 통과한 계약에만 목표 인터페이스 ID를 묻습니다. 호출이 실패하거나 반환 데이터가 짧거나 형식이 깨져 있으면 false 또는 알 수 없음으로 처리합니다.
30,000 가스 제한은 조회가 지나친 연산으로 호출자의 가스를 다 써 버리지 않게 하려는 장치입니다. 프록시 폴백, 되돌림, 빈 반환이 있을 수 있으므로 ABI bool 값을 디코딩하기 전에 성공 여부와 정확한 반환 길이를 검사합니다.
| 관찰 | 판정 | 후속 |
|---|---|---|
| 165 true·ffff false | ERC-165 후보 | 목표 ID 조회 |
| 165 false | 미지원 | 다른 탐지 정책 |
| ffff true | 규약 불일치 | 결과 불신 |
| 목표 ID true | 지원 선언 | 실제 동작 시험 |
| 되돌림·형식 오류 | 알 수 없음·미지원 | 안전한 대체 처리 |
NFT 수신자 사례에서 실제 콜백을 따로 봅니다
ERC-721 계약이 수신자의 ERC165 응답만 보고 safeTransfer를 끝내지 않고, onERC721Received를 실제로 호출해 약속된 반환값(magic value)을 검사하는 이유가 바로 이 경계에 있습니다. 수신자가 인터페이스 지원을 true로 선언해도 콜백에서 되돌리거나 다른 값을 돌려줄 수 있습니다.
반대로 일부 오래된 계약은 기능은 구현했지만 ERC-165 선언은 하지 않았을 수 있습니다. 애플리케이션이 미지원 계약을 허용할지, 안전 확인 없는 전송을 제공할지는 자산 복구 위험과 함께 정책으로 정합니다. 인터페이스 탐지를, 있지도 않은 함수를 안전하게 부르는 방법으로 바꿔 쓰지 않습니다.
- 목표 함수의 정규 시그니처를 확정합니다.
- 선택자 각각과 XOR 인터페이스 ID를 독립적으로 계산합니다.
- ERC-165 ID와 무효 ID 응답을 먼저 검사합니다.
- 성공 여부·반환 데이터 길이·bool 값을 검증합니다.
- 목표 함수의 실제 반환값과 상태 변화도 시험합니다.
프록시와 업그레이드는 응답을 바꿀 수 있습니다
프록시는 폴백의 delegatecall로 구현 계약의 supportsInterface를 실행하므로 업그레이드 뒤에는 같은 주소라도 응답이 달라질 수 있습니다. 결과를 캐시에 영구 저장하면 새 기능을 놓치거나, 이미 빠진 인터페이스를 계속 지원한다고 표시할 수 있습니다. 블록 해시와 구현 계약의 코드 해시를 함께 기록합니다.
다이아몬드 같은 모듈형 계약은 선택자 라우팅 표와 supportsInterface 등록 정보가 어긋날 수 있습니다. 등록 정보 갱신과 패싯 변경을 한 번에 처리하고, 실제 선택자가 어느 대상으로 가는지 확인합니다.
보안·경제적 의미는 따로 검증합니다
ERC-165는 함수의 의미, 접근 제어, 토큰 지급 능력, 표준 전체 준수 여부를 검사하지 않습니다. 악성 계약은 어떤 ID에든 true를 돌려주면서 실제 호출 때 자산을 훔치거나 가스를 다 태워 버릴 수 있습니다.
인덱서는 인터페이스 지원 true를 분류용 참고 정보로만 쓰고 검증된 코드, 호출 결과, 이벤트와 교차 확인합니다. 프런트엔드는 ‘ERC-721 지원’ 같은 표시를 감사나 공식 인증처럼 보여 주지 말고, 관찰한 블록과 확인 범위를 함께 남깁니다.
자주 묻는 질문
supportsInterface가 true면 함수 호출도 성공하나요?
아닙니다. 함수가 되돌리거나 잘못된 값을 돌려줄 수 있으므로 실제 호출 조건을 검증해야 합니다.
인터페이스 ID에 이벤트도 포함하나요?
아닙니다. 해당 인터페이스의 함수 선택자만 XOR합니다.
일반 지갑 계정(EOA)에 supportsInterface를 호출해도 되나요?
코드가 없으므로 정상적인 ERC-165 응답을 기대할 수 없습니다. 먼저 코드가 있는지와 호출 결과를 확인합니다.
더 깊이 읽기
본문에서 다룬 개념과 확인 절차를 다음 글에서 이어서 살펴보세요.



