[Solidity] Struct 구조체 서명방법(EIP-712)

in upvu •  2 years ago 

관련 자료 : https://eips.ethereum.org/EIPS/eip-712

Struct 구조체에 대해서 서명값을 구하기 위해서는 별도의 방법을 이용해서 구해야 합니다.

여기에 관련된 표준으로 EIP-712(721 아님!)가 있는데요.

간단히 알아봅니다.


Struct Hash 값 구하는 방법

  • 아래와 같은 구조체가 있다고 가정해봅니다.(Mail)
struct Mail {
    address from;
    address to;
    string contents;
}
  • 이 구조체에 대한 TypeHash 를 먼저 구해야 합니다.(아래와 같이 하면 구할 수 있음)
  • 단, enum으로 선언된 변수의 경우 uint8을 사용해야 함
// 아래 함수 실행하면 결과값은:536e54c54e6699204b424f41f6dea846ee38ac369afec3e7c141d2c92c65e67f
bytes32 constant MAIL_TYPEHASH = keccak256(
  "Mail(address from,address to,string contents)");
  • 위와 같이 TypeHash를 구한 다음에 실제 구조체를 Hashing 하는 방법은 아래와 같습니다.
  • abi.encode를 이용하여 인코딩을 하고 첫번째 변수에 위에서 구한 TypeHash 값을 입력합니다.
  • address처럼 byte 수가 고정된 경우는 그냥 변수를 넘겨줘도 되지만, string이나 bytes 같은 경우에는 길이가 동적이기 때문에 keccak256으로 묶어서 변수에 입력해야 합니다.
function hashStruct(Mail memory mail) pure returns (bytes32 hash) {
    return keccak256(abi.encode(
        MAIL_TYPEHASH,
        mail.from,
        mail.to,
        keccak256(mail.contents)
    ));
}
  • 위 값을 이용해서 특정 address가 서명을 했다는 것을 증명해보자..!!
function validateSig(
        Mail memory mail,
        Sig memory sig
    ) internal pure {
        bytes32 mailHash = hashStruct(mail);

        // Hash 값과 rsv 값을 이용하여 서명한 Address와 동일한지 확인해서 검증을 할 수 있음
        // ecrecover 내부에 sig 값은 v>s>r 순서대로 입력을 해야함.
        require(ecrecover(mailHash, sig.v, sig.r, sig.s) == mail.from);
    }
Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE BLURT!