etherjs和web3.js签名相同,solidity自己实现和openzeppelin验签结果地址不对 js使用了vue
ether.js
async walletSignMessage() {
const message = {
from: "0xE3a463d743F762D538031BAD3f1E748BB41f96ec",
to: "0x39Ef50bd29Ae125FE10C6a909E42e1C6a94Dde29",
value: 12345789,
};
const domain= {
name: "Demo",
version: '1.0',
};
const types = {
Mail: [
{name: 'from', type: 'address'},
{name: 'to', type: 'address'},
{name: 'value', type: 'uint256'},
],
};
const signature = await window.ethProvider
.getSigner()
._signTypedData(domain, types, message);
console.log("signature====" + signature);
const address = verifyTypedData(
domain,
types,
message,
signature
).toLowerCase();
console.log("验证address===" + address);
},
web3.js
async sign111() {
const typedData = {
types: {
EIP712Domain: [
{name: 'name', type: 'string'},
{name: 'version', type: 'string'},
],
Mail: [
{name: 'from', type: 'address'},
{name: 'to', type: 'address'},
{name: 'value', type: 'uint256'},
],
},
domain: {
name: 'Demo',
version: '1.0',
},
primaryType: 'Mail',
message: {
from: "0xE3a463d743F762D538031BAD3f1E748BB41f96ec",
to: "0x39Ef50bd29Ae125FE10C6a909E42e1C6a94Dde29",
value: 12345789,
},
}
var privateKeyHex = Buffer.from("privateKey", 'hex')
var signature = sigUtil.signTypedData_v4(privateKeyHex, {data: typedData})
console.log("signature:", signature)
},
上面函数得到的结果都是
0xf1105ec987e4e3a5e03917945baab82cdb9a58be6e5475145148ec813bdc321b2604d9017d878644f650dce7923860f9f6c69f2ae21310fd27302cf7e9e4118f1c
solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/draft-EIP712.sol";
contract MyContract is EIP712 {
constructor(string memory name, string memory version) EIP712(name, version) {
}
function recoverV4(
address from,
address to,
uint256 value,
bytes memory signature
) public view returns (address) {
bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
keccak256("Mail(address from,address to,uint256 value)"),
from,
to,
value
)));
return ECDSA.recover(digest, signature);
}
}
solidity验签的结果就不同,求教是solidity哪里写错了吗?困在这两天了,闹心 我是想做opensea那样的对订单签名,或者有什么别的更好的签名方式吗。
吐槽一下:ETH的签名真的是太太太太太恶心了,网上的教程还都基本是千篇一律的
你的代码里 Solidity 的domain 和 web3.js 的domain不一样。
代码里web3.js 的domain 需按Solidity ERC712 的标准处理:
EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)
这个是签名的特性决定的,哪怕签名内容多了一个空格, 结果就完全不一样。这个其实和 ETH 无关。