EIP-712 is a more advanced and safer transaction signature method. We can see the implementation of EIP-712 in the Periphery contract of Uniswap V2.
But it is difficult for ordinary people to understand EIP-712. This article is based on an example to experience EIP-712 specifically to achieve a better understanding of it.
There are many articles and examples in GitHub explaining and showing how to use EIP-712, but there are many difficulties in understanding how it works as a whole and how the front-end code and smart contracts are related. This is an example (not an explanation) of EIP712. Prerequisites and version used.
- Solidity basics
- above sea level 7.19.1
- Node 16.2.0
- Metamask 9.8.4
- truffle 5.4.0
EIP-712 is a more advanced and safer transaction signature method. Using this standard, not only can the transaction be signed and the signature can be verified, but also the data and the signature can be passed to the smart contract, and the signature can be verified based on the data to know whether the signer is the person who actually sent the signature to call in the transaction data.
EIP-712 proposes a standard structure of data and a definition process for generating hashes from structured messages. Then use this hash to generate a signature. In this way, there is a clear distinction between a signature generated for sending a transaction and a signature generated for verification of identity or any other purpose. The EIP-712 draft expresses the motivation behind the signature scheme as:
Improve the availability of off-chain message signatures used on-chain. We see more and more people adopting off-chain message signing because it saves gas and reduces the number of transactions on the blockchain.
EIP-712 is a standard for hashing and signing typed structured data, not just byte strings. It includes a
- The theoretical framework of the correctness of the coding function,
- Structured data specification similar and compatible with solid structure,
- The secure hash algorithm is used in the instances of these structures,
- Safely include these instances in the set of signable messages,
- An extensible domain separation mechanism,
- The new RPC calls eth_signTypedData,
- Optimized realization of hash algorithm in EVM.
The implementation of EIP-712 can be seen in the Periphery contract of Uniswap V2. It removes liquidity through permission and finally calls the method in Uniswap V2 Core to complete this operation.
The front-end signature is passed to the method in Periphery, and the signature is used to approve the Router contract on behalf of the user using the method in the Core.
Our example will use the EIP-721 proposal to sign a transaction with data (address, storedData value, and expiration date), which are used to change the value of the variable in the contract.
If the signature and hash give the address of the signatory and the expiration date has not passed, the value of storedData is changed.
This is a useless example, but understanding it will ensure that you can use the standard elsewhere. To use EIP-712 correctly is to create an ERC20 license, just like what the Uniswap team did.
Continue to clone truffle’s react box.
We will simply adjust and add code as needed to make EIP-712 work properly.
Data is the most critical part of EIP-712. The data to be signed must conform to a predefined format. It must have an EIP712Domain and the data to be signed (set in our example). The combination of the two will be signed and sent to the smart contract for verification.
Each data signed under EIP-712 must have an EIP712Domain and another data. The structure of the two can be anything, but must be the same in JS code and SC code.
When using this proposal, the structure of EIP712Domain is a widely accepted standard.
EIP-712 data standard
EIP712Domain has some parameters that specify which network and which specific contract will be used to verify the signature. Another contract with the same code will not be able to verify the signature.
Let’s add a button, when the button is clicked, a meta mask will pop up, and the data will be signed using the eth_signTypedData_v3 method.
Once the data defined above is signed using the eth_signTypedData_v3 method we get the signature and split the signature into its r, s, and v components and send it to the smart contract. These parameters and data hash will be used to recover the signer’s public key using ercrecover.
Write smart contracts.
Just like we define the JS code that contains the EIPdomain and the data to be signed, the smart contract also requires two variables to represent the hash data of each EIPdomain and our data (in this case, the setting data).
On the UI side, we sign the data and send r, s, and v to the smart contract.
The above code does two things, first it hashes the data and generates their hash. Next, it uses the hash (called hash in SC) and signature of the data, and uses the ercrecover method to generate the signer’s public key.
The two kecak hashes of the data shown above should be similar to the data structure defined in the out JS code. If the two are different, the signer’s address cannot be recovered.
The structure of the signature data
Add the mnemonic in infura to the truffle-config.js file (line 3) and specify the address of the deployer (line 18). The above example uses the rinkeby testnet, but any test can be used, and check the truffle documentation to deploy to other testnets.
Then deploy the contract. After deployment, copy the address of simpletorage and replace it with the address on line 76 of app.js under verifyingContract.
Deploy code snippet
Enter the client directory and run npm run start to start the react application.
Press the’Press to sign’ button, and then sign the signature request that pops up in the metamask. Next, confirm the transaction to set the value on the smart contract.
After the transaction is completed, refresh the webapp to see the changes reflected.
Posted by:CoinYuppie，Reprinted with attribution to:https://coinyuppie.com/an-example-to-explain-eip-712/
Coinyuppie is an open information publishing platform, all information provided is not related to the views and positions of coinyuppie, and does not constitute any investment and financial advice. Users are expected to carefully screen and prevent risks.