무지개곰
article thumbnail
Published 2023. 7. 2. 17:08
[Solidity] EIP-712란? BlockChain/solidity
반응형

OpenGSN과 Openzeppelin의 defender를 공부하며 알게 된 forwarder contract가 EIP712를 상속받고 있는 것을 보았습니다. EIP712는 무엇인지 어떠한 역할인지 알아보도록 하겠습니다.

1. 목차

EIP-712란?

EIP-712의 장점

예시 코드


2. EIP-712란?

EIP-712는 Typed Structured Data로 구조화된 데이터에 대한 해싱과 서명 검증을 위한 표준입니다. 이 표준은 메시지 형식을 사전에 정의하고, 이를 해싱하여 고유한 메시지 해시를 생성합니다. 이로써 구조화된 데이터의 무결성을 보장하고, 서명 검증을 통해 메시지의 인증과 권한 부여를 신뢰할 수 있게 합니다. 이러한 검증과 무결성을 이용하기 위하여 forwarder에 상속합니다.


3. EIP-712의 장점

데이터의 무결성 : EIP-712은 데이터를 해싱하여 무결성을 보장합니다. 데이터가 변경되면 해시값도 변경되므로 데이터의 위변조를 검사할 수 있습니다.

서명 검증 : EIP-712를 통해 서명된 메시지를 검증할 수 있으며, 메시지를 생성한 주소를 확인할 수 있습니다.

이러한 장점을 이용하여 스마트 계약 간의 통신, 오프체인 서비스와의 상호작용, 탈중앙화된 식별 시스템에 이용할 수 있습니다.


4. 예시 코드

아래의 코드는 openzeppelin에서 제공하는 EIP712 contract입니다.

<bash />
pragma solidity ^0.8.8; import "./ECDSA.sol"; import "../ShortStrings.sol"; import "../../interfaces/IERC5267.sol"; abstract contract EIP712 is IERC5267 { using ShortStrings for *; bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); bytes32 private immutable _cachedDomainSeparator; uint256 private immutable _cachedChainId; address private immutable _cachedThis; bytes32 private immutable _hashedName; bytes32 private immutable _hashedVersion; ShortString private immutable _name; ShortString private immutable _version; string private _nameFallback; string private _versionFallback; constructor(string memory name, string memory version) { _name = name.toShortStringWithFallback(_nameFallback); _version = version.toShortStringWithFallback(_versionFallback); _hashedName = keccak256(bytes(name)); _hashedVersion = keccak256(bytes(version)); _cachedChainId = block.chainid; _cachedDomainSeparator = _buildDomainSeparator(); _cachedThis = address(this); } function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _cachedThis && block.chainid == _cachedChainId) { return _cachedDomainSeparator; } else { return _buildDomainSeparator(); } } function _buildDomainSeparator() private view returns (bytes32) { return keccak256(abi.encode(_TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this))); } function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } function eip712Domain() public view virtual override returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ) { return ( hex"0f", // 01111 _name.toStringWithFallback(_nameFallback), _version.toStringWithFallback(_versionFallback), block.chainid, address(this), bytes32(0), new uint256[](0) ); } }

_domainSeparatorV4 : 현재 체인의 domainSeparator를 반환합니다. 이 메서드는 캐시 된 캐시 된 domainSeparator 값을 반환하며, 체인 ID가 변경되면 캐시 된 값을 무효화하여 보안을 강화합니다.

_buildDomainSeparator : domainSeparator를 구성하기 위한 내부 함수입니다. _TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this) 값을 사용하여 domainSeparator를 생성합니다.

_hashTypedDataV4 : 이미 해싱된 구조체에 대한 EIP-712 메시지의 해시값을 반환합니다. domainSeparator와 구조체 해시를 조합하여 타입화된 데이터의 해시를 계산합니다. 계산되어 나온 해시는 ECDSA의 recover의 함수와 함께 사용하여 메시지의 서명을 복원할 수 있습니다.

eip712Domain : 이 메서드는 EIP-5267 인터페이스에 정의된 함수로, 도메인과 관련된 정보를 반환합니다. 반환되는 정보는 메시지의 도메인을 식별하고, 체인 ID 및 관련 컨트랙트 주소등의 정보를 제공하여 메시지의 유효성을 검증하는 데 사용할 수 있습니다.

반응형

'BlockChain > solidity' 카테고리의 다른 글

[Solidity] ERC-2771이란? (ERC-2771Context란?)  (0) 2023.07.02
[Solidity] ERC20 Permit이란?  (0) 2023.06.17
[Solidity] ERC-1155란?  (0) 2023.05.18
[Solidity] ERC-721이란?  (0) 2023.05.18
[Solidity] ERC20이란? (ERC20 토큰 발행)  (0) 2023.05.14
profile

무지개곰

@무지개곰

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!