ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ERC-165 살펴보기
    BlockChain Tech 2019. 3. 29. 17:51

    https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md

    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

    댓글

Developer RyuK