-
ERC-165 살펴보기BlockChain Tech 2019. 3. 29. 17:51
ERC-165
- SmartContract에 구현되어 있는 인터페이스를 게시하고, 검색하는 표준 매소드를 만든다.
쉽게 생각해보면, 해당 SmartContract에 내가 사용해야할
'function hungry(string food)'라는 함수가 있는지 검색할 수 있는 함수를 구현하는 것이 ERC-165이다.
어떻게 작동하는지 소스코드를 살표보자.
썩 복잡한 코드는 아니였고, 사용하기 쉽고 효율적인 코드라고 생각되지도 않았다.
(물론, 구현 해놓으면 사고 예방에는 좋긴 할 것이다.)
(1) _registerInterface를 통해 interfaceId를 등록하고,
(2) supportsInterface를 통해 해당 interface 즉, 함수가 있는지 확인한다.
interfaceID이란?
interfaceID라는 것이 무엇일까?
쉽게 말하면, 함수에 대한 정보를 16진수로 표현하는 것이다.
함수를 bytes4 형으로 변환하고, _supportedInterfaces에 매핑 한다.
0x01ffc9a7 메소드가 존재 한다면,
_supportedInterfaces[0x01ffc9a7] = true
0x01ffc9a7 메소드가 존재하지 않는다면,
_supportedInterfaces[0x01ffc9a7] = false 라는 데이터를 얻게 될 것 이다.
interfaceID 변환 방법
IERC165 Interface를 변환하는 방법은 2가지가 있다.
(1) 직접 변환
- bytes4(keccak256('supportsInterface(bytes4)'))
(2) 메소드 사용
- this.supportsInterface.selector
두 방법 모두 0x01ffc9a7라는 같은 결과값을 얻을 수 있다.
ERC721을 예로 InterfaceID를 만들어보면 아래와 같다.
XOR 연산을 해주면 된다.
* 0x80ac58cd ===
* bytes4(keccak256('balanceOf(address)')) ^
* bytes4(keccak256('ownerOf(uint256)')) ^
* bytes4(keccak256('approve(address,uint256)')) ^
* bytes4(keccak256('getApproved(uint256)')) ^
* bytes4(keccak256('setApprovalForAll(address,bool)')) ^
* bytes4(keccak256('isApprovedForAll(address,address)')) ^
* bytes4(keccak256('transferFrom(address,address,uint256)')) ^
* bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^
* bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)'))
(여러가지 방법이 있지만, 해당 연산을 하는 가장 쉬운 방법은 Remix 를 통해 특정 변수에 저장 한 후 출력해보는 것 같다.)
보통, 여러 SmartContract 소스를 보면 interfaceID 의 경우 미리 계산을 한 후, 변수에 값만 대입해놓았다.
(GAS비 절약을 위해서인 듯)
Interface가 정해진 ERC 들의 경우 결국 모두 같은 interfaceID 를 갖게 되므로
이 값이 어떻게 생성되었는지 명시적으로 적어놓을 필요가 없을 수도 있겠다.
ERC-165를 사용하는 이유
(여러가지 이유가 있겠지만, 내가 공감한 부분은 예외처리 부분만..)
예외처리
- function을 통하여 생성, 수정, 거래 등을 할 수 있다.
어떠한 실수로 SmartContract에 없는 매소드를 호출 했거나, 인자 값을 다르게 입력했을 경우 Remix나 좋은 IDE를 사용했다면 서비스 단에서 막아주겠지만, 그렇지 않은 경우가 발생 될 수 있다.
- safemath를 사용하지 않아 오버플로우가 발생 된다거나, 출금 함수도 없는데 입금을 해버린다던가..? 이런 부분을 ERC-165로 방지 할 수도 있다.
결론
생각해보면 굉장히 비효율적일 수도 있다.
ERC165를 구현해주고, 모든 interfaceID를 직접 추가 해주어야 한다. (보통 Constructor에서 입력 해준다.)
또, 해당 인터페이스가 있는지 검색을 할 때는
함수명이 아닌, 함수명 & 인자값 들로 byte4 interfaceID를 만든 후 조회 해야한다.
ERC-165를 구현한다고 가스비가 절약이 되는 것은 아니지만, 구현해서 손해볼 것은 없을 것 같다.
언제든 예외처리는 좋은 습관이기 때문..
하지만 165는 강제 예외처리는 아니지..ㅎ
'BlockChain Tech' 카테고리의 다른 글
ERC-721 살펴보기 (0) 2019.03.31 블록체인 Oracle Problem (0) 2019.01.02 이중 지불 (Double Spent) / 51% Attack (0) 2019.01.02