_signTypedData method on ethers does not match with ERC712 solidity code
Asked Answered
R

1

8

I've faced an ethers signature unmatched problem.

Everything is normal. Already compared domainData, types, message variable in the js code with contract.

Below is the JS Code to generate signature and call contract.

      const contractAddress = await contract.address;

      domainData.chainId = 31337;
      domainData.verifyingContract = contractAddress;

      const signature = await signer._signTypedData(domainData, types, message);
      const { r, s, v } = ethers.utils.splitSignature(signature);

      const result = await contract.recoverAddressFromTypedData(
        message,
        v,
        r,
        s
      );
      expect(result).to.equal(signer.address);

Below is the solidity code which use "@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol"

function recoverAddressFromTypedData(
    Bid memory bid,
    uint8 v,
    bytes32 r,
    bytes32 s
) public view returns (address) {
    bytes32 digest = _hashTypedDataV4(hashBid(bid));
    address signer = ecrecover(digest, v, r, s);
    return signer;
}

But I got following error on the last line of JS code.

AssertionError: expected '0x7Da34C07B95dB4A1c85fe4C5d313F4860E85e340' to equal '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266'
      + expected - actual

      -0x7Da34C07B95dB4A1c85fe4C5d313F4860E85e340
      +0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266

Is there anything wrong with my code?

Raffaello answered 21/5, 2021 at 2:50 Comment(0)
J
1

I don't know if I have the same reason as you, in my case I had a struct member containing a string type which needed to be converted to bytes32.

contract MyContract is Ownable, AccessControl, EIP712 {
    struct Action {
        address initiator;
        string name;
    }
    bytes32 public constant ACTION_TYPE_HASH = keccak256("Action(address initiator,string name)");
    function _hashStruct(Action memory action) private pure returns (bytes32) {
        // If your struct member has string type,
        // you need to use keccak256(abi.encodePacked(string))
        // convert it to bytes32
        return keccak256(abi.encode(ACTION_TYPE_HASH, action.initiator, keccak256(abi.encodePacked(action.name))));
    }
    function _hashTypedDataV4(Action memory action) private view returns (bytes32) {
        bytes32 structHash = _hashStruct(action);
        return EIP712._hashTypedDataV4(structHash);
    }
    // more...
}

code.png

Jessalyn answered 26/2, 2022 at 22:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.