ERC-6093 토큰 공통 커스텀 에러 표준 (Custom errors for commonly-used tokens)

Final · 토큰 · 2022-12-06 작성

ERC-20, ERC-721, ERC-1155 토큰이 실패할 때 쓰는 에러를 공통 형식으로 정합니다. 지갑과 앱이 실패 원인을 구조화된 데이터로 해석해 사용자에게 보여 줄 수 있습니다.

왜 필요한가

이더리움 앱과 지갑은 거래가 실패한 원인을 사용자에게 보여 줄 때 오랫동안 되돌리기 사유 문자열(revert reason string)에 의존해 왔습니다. 솔리디티(Solidity) 0.8.4부터는 원인을 종류별로 해석할 수 있는 커스텀 에러(custom error)가 생겼지만 대표 토큰 표준인 ERC-20, ERC-721, ERC-1155는 그보다 먼저 확정되어 명세에 에러가 전혀 들어 있지 않습니다. 그래서 토큰마다 에러 이름과 내용이 제각각이고 지갑이나 테스트 환경이 실패 원인을 일관되게 해석하기 어렵습니다. 긴 문자열을 배포 코드에 담느라 배포 비용도 커집니다. 이 표준은 세 토큰 표준에서 흔히 일어나는 실패를 구조화된 공통 에러 목록으로 정리해 기존 문자열과 적어도 같은 정보를 더 일관되고 예측 가능한 형태로 제공하게 합니다.

구현해야 하는 것

심층 설명

에러 이름의 문법: 도메인, 접두사, 주체

모든 에러 이름은 <Domain><ErrorPrefix><Subject>(<Arguments>) 문법을 따릅니다. Domain은 ERC20, ERC721, ERC1155 같은 표준 이름이고 ErrorPrefix는 실패 이유를 나타내는 Invalid(일반적 오류)나 Insufficient(양 부족) 등입니다. Subject는 Sender, Receiver, Balance, Approver, Operator, Approval처럼 실패한 주체입니다. 행위(action)는 Transfer와 Approval 두 가지로 봅니다. 행위 자체는 에러의 주체가 되지 않습니다. 어떤 주체가 어떤 행위 중에 실패했는지를 조합해 에러를 만듭니다.

도메인 접두사가 필요한 이유

에러 인자는 토큰 종류에 따라 달라집니다. 같은 이름에 다른 인자를 가진 에러가 있으면 솔리디티 컴파일러가 DeclarationError로 실패합니다. 예를 들어 InsufficientApproval(address spender, uint256 allowance, uint256 needed)와 InsufficientApproval(address operator, uint256 tokenId)는 공존할 수 없습니다. 그래서 ERC 이름과 번호를 앞에 붙인 도메인 접두사(ERC20InsufficientApproval, ERC721InsufficientApproval)로 선언 충돌을 피합니다.

인자 순서: 누가, 무엇이, 왜

인자는 정해진 순서를 따릅니다. 먼저 에러의 주체(예: address sender), 다음으로 무엇이 실패했는지(예: uint256 allowance), 마지막으로 왜 실패했는지를 추가 인자로(예: uint256 needed) 넣습니다. 한 인자가 여러 범주에 겹칠 수 있어 셋이 모두 있지는 않지만 순서는 지켜야 합니다. tokenId가 필요한 토큰은 주체가 아니라 끝의 추가 정보로 넣기를 권합니다. 확장 등 구현별 에러를 추가할 때도 일관성을 위해 이 지침을 따라야 합니다(SHOULD).

사용 지침의 성격: 되돌릴지는 구현자 몫

이 표준은 특정 상황에서 쓸 수 있는 표준 에러를 정의할 뿐, 그 상황에서 반드시 되돌려야(revert) 하는지는 정하지 않습니다. 되돌릴지는 해당 토큰 EIP가 강제하지 않는 한 구현자가 정합니다. 다만 각 에러에는 지켜야 할 규칙이 있습니다. 예를 들어 ERC20InsufficientBalance는 balance가 needed보다 작아야 하고(MUST) ERC20InvalidSender는 승인 작업이나 잔액·한도 요건에 쓰면 안 되며(MUST NOT) 그 경우 ERC20InsufficientBalance나 ERC20InsufficientAllowance를 씁니다. 인자 이름은 Parameter Glossary의 정의대로 써야 합니다(MUST).

표준별 에러 구성

ERC-20은 전송용 4개(InsufficientBalance, InvalidSender, InvalidReceiver, InsufficientAllowance)와 승인용 2개(InvalidApprover, InvalidSpender)로 총 6개입니다. ERC-721은 소유권 중심으로 8개입니다. 잔액 조회용 InvalidOwner, 미발행·소각 토큰용 NonexistentToken, sender가 소유자가 아닐 때의 IncorrectOwner, 승인 부족의 InsufficientApproval 등이 있습니다. ERC-1155는 7개로, 잔액 에러에 tokenId가 붙고 전체 승인 부재를 나타내는 MissingApprovalForAll과 배치 전송의 배열 길이 불일치를 나타내는 InvalidArrayLength가 추가됩니다.

기존 배포 토큰과의 호환

이미 배포된 토큰은 대부분 require와 되돌리기 문자열을 쓰며 솔리디티 0.8.4 이후 배포된 토큰도 문자열 기반 구현을 상속한 경우가 많습니다. 업그레이드할 수 없는 기존 토큰에는 이 표준을 강제할 수 없고 이들은 도메인 유무, 다른 접두사, 비슷한 주체, 다른 어순 같은 작은 변형이 있는 비슷한 관례를 씁니다. 업그레이드 가능한 컨트랙트는 이 표준을 구현하도록 업그레이드할 수 있습니다(MAY). 이 표준을 지원하는 구현자와 디앱 개발자는 비준수 컨트랙트가 내는 다른 에러와 고전적인 되돌리기 문자열도 허용해야 합니다(SHOULD).

쓸 때 주의할 점

ERC 원문 · ← ERCs