我正在尝试通过MetaMask "eth_signTypedData_v4“对输入数据进行签名。通过recoverTypedSignature_v4恢复签名者将返回我签署数据的正确地址。但是智能契约每次都会返回随机地址作为every输出。无法理解代码有什么问题。
联署材料:
//constructing a thing
const EIP712Domain = [
{ name: 'name', type: 'string' },
{ name: 'version', type: 'string' },
{ name: 'chainId', type: 'uint256' },
{ name: 'verifyingContract', type: 'address' }
]
const domain = {
name: 'SomeName', //(replaced from original value)
version: '1',
chainId: 500, //(replaced from original value)
verifyingContract: '0xd093dD097772300939Ec1ED7482B415bd43D9246'
}
const SomeObject = [
{ name: 'someAddress', type: 'address' },
{ name: 'someAddressTwo', type: 'address' },
{ name: 'someAddressThree', type: 'address' },
{ name: 'value', type: 'uint256' },
{ name: 'valueTwo', type: 'uint256' },
{ name: 'someAddressFour', type: 'address' },
{ name: 'deadline', type: 'uint256' }
]
const message = {
someAddress: account,
someAddressTwo: from,
someAddressThree: to,
value: '1000000000000000000',
valueTwo: '17',
someAddressFour: account,
deadline: deadline.toString()
}
const data = JSON.stringify({
types: {
EIP712Domain,
SomeObject
},
domain,
primaryType: 'SomeObject',
message
})
//signing
library?.send('eth_signTypedData_v4', [account, data])
.then(sig => {
return splitSignature(sig)
})
.then(signature => {
return signature
})
//using signature in smart contract call
const args = [
account,
from,
to,
'1000000000000000000',
'17',
account,
deadline.toString(),
signature?.v,
signature?.r,
signature?.s
]
const response = await mainContract?.doSomething(args)Smart合同方:
function doSomething(SomeObject memory someobject) public {
bytes32 hash = someobject.hash();
address signer = EIP712.recover(DOMAIN_SEPARATOR, hash, someobject.v, someobject.r, someobject.s);
//failing here
require(signer != address(0) && signer == someobject.someAddress, "wrong signature");
}
struct SomeObject {
address someAddress;
address someAddressTwo;
address someAddressThree;
uint256 value;
uint256 valueTwo;
address someAddressFour;
uint256 deadline;
uint8 v;
bytes32 r;
bytes32 s;
}
function recover(
bytes32 DOMAIN_SEPARATOR,
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
bytes32 digest = keccak256(abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, hash));
return ecrecover(digest, v, r, s);
}
function hash(SomeObject memory someobject) internal pure returns (bytes32) {
return
keccak256(
abi.encode(
SOMEOBJECT_TYPEHASH,
someobject.someAddress,
someobject.someAddressTwo,
someobject.someAddressThree,
someobject.value,
someobject.valueTwo,
someobject.someAddressFour,
someobject.deadline
)
);
}
constructor() public {
uint256 chainId;
assembly {
chainId := chainid()
}
DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address
verifyingContract)"),
keccak256("SomeName"),
keccak256("1"),
chainId,
address(this)
)
);
}发布于 2021-05-07 19:31:07
Nvm,现在起作用了。在数组const SomeObject = ...中有错误的元素顺序(在提出这个问题之前修正了),这扰乱了整个事情。
https://ethereum.stackexchange.com/questions/98511
复制相似问题