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

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

목차

EIP-712란?

EIP-712의 장점

예시 코드


EIP-712란?

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


EIP-712의 장점

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

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

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


예시 코드

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

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

무지개곰

@무지개곰

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