EIP-712: eth_signTypedData as a standard for machine-verifiable and human-readable typed data signing

Link for the lazy: https://eips.ethereum.org/EIPS/eip-712

1 Like

Thatā€™s problematic. Itā€™s a good thing there isnā€™t much uptake of this standard yet, although it is very useful and it would be good to clear any issues up.

1 Like

In case of a fork, the signatures would only work in the fork that didnā€™t changed chainId, to solve that, please use EIP-1344 in the 712 standard.

Hi everyone, I am not sure where is the best place to ask this so Iā€™m trying here.
Iā€™m looking at EIP-712 v4 and the scheme to encode arrays.

eth-sig-util is managing it well (and I guess correctly) on the client side but I can find no example on how to do that in solidity.

My understanding is that encoding an array of 3 strings arr = [ā€œ1ā€, ā€œ2ā€, ā€œ3ā€] is equialent to keccak256(abi.encode(keccak256(abi.encodePacked(arr[0])), keccak256(abi.encodePacked(arr[1])), keccak256(abi.encodePacked(arr[2])))

So first thing, is this correct? if yes, how can I implement that in solidity?

Iā€™m sure you can do better / in place by writing it in assembly, but here is a ā€œquickā€ answer:

function hash(string[] calldata array) internal pure returns (bytes32 result) {
    bytes32[] memory _array = new bytes32[](array.length);
    for (uint256 i = 0; i < array.length; ++i) {
        _array[i] = keccak256(bytes(array[i]));
    }
    result = keccak256(abi.encodePacked(_array));
}
1 Like

Hey everyone, I just wanted to bring up what I believe to be a minor issue in the eth_signTypedData JSON RPC specification. Specifically, it doesnā€™t go into much detail about the JSON representation of the message object and the supported Solidity primitive values.

For example, what is an acceptable encoding for a uint32? Are all 100, 1e2, "100", "0x64" accepted? Should they be treated like QUANTITIES so only "0x64" is valid? In this regard, MetaMask for example, seems to accept both hexadecimal and decimal strings for uint256.

While I donā€™t have any particular suggestion on what the supported formats should be, I do believe it should be specified in the EIP.

4 Likes

@Recmo @dekz Do you need help finishing this spec?

How are clients expected to know what parameters to use in the domain separator? This is easy when signing for a particular contract with a known domain separator, but there is no standard mechanism for use cases where it is not known beforehand.

For a concrete example, people have run into this problem in EIP-2612 (ERC20 permit). Some tokens include the version parameter (OpenZeppelin, USDC), others donā€™t (COMP), and those who do may use different values (OpenZeppelin: default "1", USDC: "2"). There is no way to query the contract if version is used and with what value. EIP-2612 includes a DOMAIN_SEPARATOR getter, but it would be wrong to use this value without verifying that it corresponds to the current chain id, for which all the parameters are necessary.

I imagine any other EIP that builds on EIP-712 signatures will run into the same issue. The only solution right now is to make it a part of those EIPs what the domain separator is supposed to look like, but I think it would be better to include a standard mechanism either in EIP-712 or in a complementary EIP.

The current draft of EIP-712 says:

Specification of the eth_signTypedData JSON RPC

The method eth_signTypedData is added to the Ethereum JSON-RPC. The method parallels eth_sign.

eth_signTypedData

The sign method calculates an Ethereum specific signature with: sign(keccak256("\x19Ethereum Signed Message:\n" + len(message) + message))).

I donā€™t understand the last line. Isnā€™t this supposed to be

sign(keccak256("\x19\x01" + domainSeparator + hashStruct(message)))

instead, as described in the ā€œSpecificationā€ section above? The listed
definition describes eth_sign, not the new eth_signTypedData, and
does not seem consistent with Ethersā€™s TypedDataEncoder.encode (as
used in the Wallet implementation of Signer._signTypedData), nor
with OpenZeppelinā€™s ECDSA.toTypedDataHash.

Is this a copy-paste error in the spec, or am I missing something?

1 Like

Anyone has any examples of verifying eth_signTypedData_v4 in Solidity?

Iā€™m using recoverTypedSignature_v4 from eth-sig-util and it works great but when I try to verify the signature with openzeppelinā€™s EIP712 draft, it returns a different address.

Draft EIPs - OpenZeppelin Docs

Of course I also tried to write it myself from the spec, but same results.

It would be nice if this proposal was finalized because then it would be much more usable.
I could only get v3 to workā€¦

EIP-2613 (ERC20 Permit) is blocked from becoming a Final EIP because it has a dependency on EIP-712 which is still a Draft.

Are the EIP authors interested in moving EIP-712 to Final? @Recmo @dekz

1 Like

Any update about this proposal?

Iā€™ve gone ahead and created an EIP to tackle this issue I mentioned.

Please take a look and let me know your thoughts.

1 Like

EIP-712 is now in Last Call.

1 Like