EIP 712:基于以太坊的类型化结构化数据哈希和签名 请不要将 EIP 712 与非同质化代币标准 ERC 721 搞混了。EIP 712 是一个关于 “类型化” 已签署数据的提案。通过人类可读的方式将数据呈现出来,这样可以降低数据的验证难度。 - 通过 MetaMask 签署消息。左边是旧版已签署消息界面(使用的是 personal_sign,右边是新版界面(使用的是 EIP-712)。 - EIP-712 定义了一种新的方法来代替 personal_sign:eth_signTypedData(最新版用的是 eth_signTypedData_v4)。如果使用这种方法,我们必须指定所有属性(例如,to、amount 和 nonce)及其各自的类型(如,address、uint256 和 uint256),还有该应用的一些基本信息,称为域(domain)。 域包含应用名称、版本、链 ID、你正在交互的合约和盐值(salt)等信息。合约应该验证这些信息,从而确保同一个签名不能在不同的应用上使用。这样可以解决上文提到的重放攻击问题。 上图所示消息的具体定义如下: {types: {EIP712Domain: [{ name: 'name', type: 'string' },{ name: 'version', type: 'string' },{ name: 'chainId', type: 'uint256' },{ name: 'verifyingContract', type: 'address' },{ name: 'salt', type: 'bytes32' }],Transaction: [{ name: 'to', type: 'address' },{ name: 'amount', type: 'uint256' },{ name: 'nonce', type: 'uint256' }]},domain: {name: 'MyCrypto',version: '1.0.0',chainId: 1,verifyingContract: '0x098D8b363933D742476DDd594c4A5a5F1a62326a',salt: '0x76e22a8ee58573472b9d7b73c41ee29160bc2759195434c1bc1201ae4769afd7'},primaryType: 'Transaction',message: {to: '0x4bbeEB066eD09B7AEd07bF39EEe0460DFa261520',amount: 1000000,nonce: 0}} -来源- 如你所见,这个消息在 MetaMask 上是可见的,我们可以确认我们正在签署的消息就是我们想要执行的。EIP 712 实行 EIP 191,因此数据将以 0x1901 开头:0x19 是前缀,0x01 是版本字节,表示这是一个 EIP 712 签名。 通过 Solidity,我们可以为 Transaction 类型定义一个 struct,并编写一个函数来对交易进行哈希计算: struct Transaction {address payable to;uint256 amount;uint256 nonce;}function hashTransaction(Transaction calldata transaction) public view returns (bytes32) {return keccak256(abi.encodePacked(byte(0x19),byte(0x01),DOMAIN_SEPARATOR,TRANSACTION_TYPE,keccak256(abi.encode(transaction.to,transaction.amount,transaction.nonce))));} 上述交易的数据如下所示: 0x1901fb502c9363785a728bf2d9a150ff634e6c6eda4a88196262e490b191d5067cceee82daae26b730caeb3f79c5c62cd998926589b40140538f456915af319370899015d824eda913cd3bfc2991811b955516332ff2ef14fe0da1b3bc4c0f424929 (责任编辑:admin) |