EIP-6384: Readable EIP-712 signatures

Thanks. We will look into it. Quite amazing you were thinking about such solutions back in 2017!

To be fair, I wasnā€™t thinking about it for off-chain signatures specifically, but rather contract calls. I think both are more or less the same problem though. We need a trustless way to present human understandable data to the user in their signing tool.

Iā€™d argue that they are only different problems in future cases where the contract in question supports the proposed standard. For all existing (non-upgradable) contracts, and any future contracts that donā€™t conform the proposed on-chain standard, the problem is the same.

The security threat model is already different today, regardless of which solution gets implemented.

With tokens the contract cannot attest for itself, as the contract might be malicious (this is the original problem to be solved). Therefore, we must resort to solution in which others should attest to it and in this context tokenlist-like solution makes a lot of sense.

In the case of EIP-712 signatures, the contract is already trusted

These problem may share some similarities but are not identical.
In general transactions, the contract cannot be trusted and the results can be simulated.
With EIP-712 the verifying contract can be, and in fact is already, trusted (see the EIP https://eips.ethereum.org/EIPS/eip-6384#the-threat-model for a more detailed discussion) and on the other hand cannot be simulated.
Therefore a different solution is required.

Glad to hear youā€™re thinking about localization/i18n!

For now, would you be open to a pr on the eip-6384 that takes as input the iso-639 language code in addition to the other parameters.
So

/**
 * @dev Returns the expected result of the offchain message.
*/

function evalEIP712Buffer(
    bytes32 domainHash,
    string memory primaryType,
    bytes memory typedDataBuffer
) external view returns (string[] memory) {
   ...
}

becomes

function evalEIP712Buffer(
    bytes32 domainHash,
    string memory primaryType,
    string memory locale,
    bytes memory typedDataBuffer
) external view returns (string[] memory) {
   ...
}

If you are actively considering other alternatives to the i18n problem please ignore but it seems this change would be part of a minimally viable solution (otherwise thereā€™s no way to display the strings in the userā€™s language).

The implementation of the method could ignore the locale variable and return a default set of strings if it doesnā€™t support the chosen locale.

Canā€™t we simply make a new ERC that adds additional constraints on EIP712, making it specifically authorize a series of (address, method, params) tuples?

Then you could just use radspec to show the user exactly what would be done. And the exact values would be interpolated.

Arbitrary payloads (eg Permits) usually are processed by dedicated methods (eg withPermit) and methods have the ability to have radspec.

@MicahZoltu the radspec discussion actually referenced your thread from 2017x

@talbeerysec this may be the simplest solution. We plan to implement Radspec in all our Intercoin smart contracts Applications of Intercoin: Making Crypto Mainstream - Applications - Intercoin and bringing more attention to that spec would actually encourage all smart contract developers to write code in plain english.

An alternative for already-deployed contracts is to create a mapping from (address, keccak) to a radspec. Or if that is somehow too expensive, you could have a hash of the radspec and its URI on eg IPFS. If it is missing or not available at the moment the wallet would simply show a warning!

@talbeerysec how can I best get in contact with you?

I think I have an improvement to the system you proposed. Existing deployed contracts may not support your ERC but many of them do support the Ownable interface. And therefore if an address owns the instance or factory, they should be able to sign a transaction and post the plain-English explanations at some URLs, like NFT metadata is. More than that, they can do it in many languages and the hash of the entire file (or of a Merkle tree of translations) can be posted on the blockchain.

That way, the URLs where the metadata is located can be indicated in a separate smart contract, which just checks that the transaction to update the URL + hash was signed by the owner of the contract (instance or factory).

Then wallets like the Intercoin wallet (which we are building) would just consult these things the same exact way they consult NFT metadata. The only danger is that they would cut corners and load from a centralized API provider (like OpenSea or Infura) rather than verifying that it really came from the blockchain itself. But thatā€™s the responsibility of wallet makers not to cut corners.

Iā€™m wondering if people are interested in a client-side open source library as an interim solution that would parse commonly used EIP-712 message formats (e.g. OpenSea Seaport orders, OpenGSN or permit messages) into token transfer data that could be displayed in wallets.


For example this Seaport offer:

offerer: 0xA0c4571EAF0bBe5e435F3CB23ef39eb1cc178D3f
offer:
    0:
        itemType: 3
        token: 0xf4910C763eD4e47A585E2D34baA9A4b611aE448C
        identifierOrCriteria: 7110658531898830932532616175266681881710314738603942312904763592289181237298
        startAmount: 1
        endAmount: 1
consideration:
    0:
        itemType: 0
        token: 0x0000000000000000000000000000000000000000
        identifierOrCriteria: 0
        startAmount: 9750000000000000
        endAmount: 9750000000000000
        recipient: 0xA0c4571EAF0bBe5e435F3CB23ef39eb1cc178D3f
    1:
        itemType: 0
        token: 0x0000000000000000000000000000000000000000
        identifierOrCriteria: 0
        startAmount: 250000000000000
        endAmount: 250000000000000
        recipient: 0x0000a26b00c1F0DF003000390027140000fAa719
        startTime: 1674302934
        endTime: 1676981334
orderType: 1
zone: 0x0000000000000000000000000000000000000000
zoneHash: 0x0000000000000000000000000000000000000000000000000000000000000000
salt: 24446860302761739304752683030156737591518664810215442929815317462366706250707
conduitKey: 0x0000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f0000
counter: 0

Would be turned into an object that looks something like this:

{
  address: "0xA0c4571EAF0bBe5e435F3CB23ef39eb1cc178D3f",
  tokensOut: [{
    chainId: 1, 
    tokenType: "native", 
    amount: 10000000000000000
  }],
  tokensIn: [{
    chainId: 1,
    tokenType: "ERC721",
    contractAddress: "0xf4910C763eD4e47A585E2D34baA9A4b611aE448C",
    amount: 1
  }]
}

Similarly, an OpenGSN message such as this:

From: 0xA0c4571EAF0bBe5e435F3CB23ef39eb1cc178D3f
To: 0x1980A588fA420E874fC5fB1e0E68FBE39c34672f
Value: 0
Gas: 100000
Nonce: 0
Data: 0xa9059cbb00000000000000000000000031908fbfafa43ec774a51c794af183a91729a6110000000000000000000000000000000000000000000000000000000000000001
ValidUntilTime: 1684591855
RelayData:
    MaxFeePerGas: 4982400014
    MaxPriorityFeePerGas: 4982400014
    TransactionCalldataGasUsed: 27968
    RelayWorker: 0x7b5...Ca96
    Paymaster: 0x086...E4d8
    Forwarder: 0xB2b...4A87
    PaymasterData: 0x
    ClientId: 1

Would be turned into an object that looks something like this:

{
  address: "0xA0c4571EAF0bBe5e435F3CB23ef39eb1cc178D3f",
  tokensOut: [{
    chainId: 137, 
    tokenType: "ERC20", 
    contractAddress: "0x1980A588fA420E874fC5fB1e0E68FBE39c34672f",
    amount: 1
  }],
  tokensIn: []
}

Note that getting this info from an OpenGSN message would require transaction simulation that the library would handle on the client side.


Please let me know if youā€™d be interested in using or collaborating on such a library!

:+1 That this could be an interim solution. Iā€™m not the author of this lib but it seems to be doing what youā€™re describing GitHub - scamsniffer/EIP712-Readability

1 Like

Great and thanks for the link! Itā€™s a nice partial solution. It doesnā€™t handle meta transactions, as that needs transaction simulation in addition to an EIP-712 parser.

Another consideration is that Iā€™d implement the library in Rust, as thatā€™d make it accessible from the growing Rust Ethereum ecosystem along with JS through WASM + any other language through a C FFI.

Hi, would love to hear more about this idea. We can do it here, or Just DM on Twitter https://twitter.com/TalBeerySec/

I did send you a Twitter DM @talbeerysec ā€¦ check for it
You can also try messaging me here