반응형
ERC-165 (Ethereum Request for Comments 165)
ERC-165는 Smart Contract에서 Interface 지원을 위해 사용하는 Ethereum 표준 규격으로, Smart Contract가 특정 Interface를 구현하고 있는 지 확인하는 기능을 지원합니다.
ERC-165를 준수하는 Smart Contract는 다른 Contract나 Client가 해당 Contract가 특정 Interface를 지원하고 있는 지 확인할 수 있도록 supportsInterface 함수가 구현되어있습니다.
pragma solidity ^0.4.20;
interface ERC165 {
/// @notice Query if a contract implements an interface
/// @param interfaceID The interface identifier, as specified in ERC-165
/// @dev Interface identification is specified in ERC-165. This function
/// uses less than 30,000 gas.
/// @return `true` if the contract implements `interfaceID` and
/// `interfaceID` is not 0xffffffff, `false` otherwise
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
모든 Solidity는 4Byte의 Hash 값인 Selector를 가지고 있으며, Selector는 해당 함수의 이름과 매개변수의 타입 등을 조합하여 생성된 고유한 식별 값입니다. 해당 함수의 Selector 값을 확인할 수 있는 방법은 아래와 같습니다.
예시 함수 : function test(address test_address) external view returns (bool)
- keccak256을 이용한 해싱
- bytes4(keccak256("test(address)"))
- keccak256 함수를 사용하여 문자열을 해싱
- 앞에서부터 4Byte 선택
- bytes4(keccak256("test(address)"))
- Contract 내부에서 각 메서드의 Selector 호출
- this.test.selector
- type 함수와 .interfaceId 사용
- bytes4 interfaceId = type(InterfaceName).interfaceId;
- type 함수를 사용하여 인터페이스 유형을 가져옴
- .interfaceId를 사용하여 인터페이스의 인터페이스 식별자 참조
- bytes4 interfaceId = type(InterfaceName).interfaceId;
ERC-165가 구현된 Smart Contract에서 특정 Interface의 구현 여부를 판단하는 방법도 이러한 Selector 값을 기준으로 확인을 하게 됩니다.
아래의 코드는 openzeppelin에서 ERC-165를 구현한 코드 입니다.
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.19;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
'Hack > Cryptocurrency' 카테고리의 다른 글
Contract Application Binary Interface (ABI) (0) | 2023.07.01 |
---|---|
브릿지와 크로스 체인, 멀티 체인, 옴니 체인을 알아보자 (0) | 2023.06.24 |
Flash Loan Attack in Crypto Currency (0) | 2023.05.20 |
Transaction Order Dependence Attack in Smart Contract (0) | 2023.05.05 |
[DAO Hacking] Reentrancy Attack 실제 사례 분석 (0) | 2023.04.30 |
댓글