//v,s,r这三个参数是链下私钥签名签出来的, 这三个参数可以合成一个传给合约然后在合约里面做分割
function test(address owner, address sender, uint256 amount, bytes calldata sign) public {
bytes32 digest = keccak256(abi.encodePacked(keccak256(abi.encode(sender, amount))));
require(ecrecovery(digest, sign) == owner, "Sign Validation Failed");
}
function ecrecovery(bytes32 hash, bytes memory sig) private pure returns (address) {
bytes32 r;
bytes32 s;
uint8 v;
if (sig.length != 65) {
return address(0);
}
assembly {
r := mload(add(sig, 32))
s := mload(add(sig, 64))
v := and(mload(add(sig, 65)), 255)
}
// https://github.com/ethereum/go-ethereum/issues/2053
if (v < 27) {
v += 27;
}
if (v != 27 && v != 28) {
return address(0);
}
/* prefix might be needed for geth only
* https://github.com/ethereum/go-ethereum/issues/3731
*/
// bytes memory prefix = "\x19Ethereum Signed Message:\n32";
// hash = sha3(prefix, hash);
return ecrecover(hash, v, r, s);
}
//
ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)
利用椭圆曲线签名恢复与公钥相关的地址,错误返回零值。
函数参数对应于 ECDSA签名的值:
r = 签名的前 32 字节
s = 签名的第2个32 字节
v = 签名的最后一个字节
ecrecover 返回一个 address, 而不是 address payable 。他们之前的转换参考 address payable ,如果需要转移资金到恢复的地址。
Sort: Trending