在 Solidity 中验证签名消息
参考https://learnblockchain.cn/article/4250
前端签名
<script>
async function signMessage() {
if (!window.ethereum) return alert("Please Install Metamask");
// connect and get metamask account
const accounts = await ethereum.request({ method: "eth_requestAccounts" });
// message to sign
const message = "hello";
console.log({ message });
// hash message
const hashedMessage = Web3.utils.sha3(message);
console.log({ hashedMessage });
// sign hashed message
const signature = await ethereum.request({
method: "personal_sign",
params: [hashedMessage, accounts[0]],
});
console.log({ signature });
// split signature
const r = signature.slice(0, 66);
const s = "0x" + signature.slice(66, 130);
const v = parseInt(signature.slice(130, 132), 16);
console.log({ r, s, v });
alert(signature);
}
</script>
例子中对"hello"进行签名
{message: 'hello'}
{hashedMessage: '0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8'}
{signature: '0xd78666fa24e699025c8bd4ec8046a721e6f7fda112710fd9…d7e45ed0347c719601b37a61346e01c2961051599db88db1b'}
{r: '0xd78666fa24e699025c8bd4ec8046a721e6f7fda112710fd95549becc40ddbd21', s: '0x14fb13cc76f7db607d7e45ed0347c719601b37a61346e01c2961051599db88db', v: 27}
solidity验证
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract Verify {
function VerifyMessage(bytes32 _hashedMessage, uint8 _v, bytes32 _r, bytes32 _s) public pure returns (address) {
bytes memory prefix = "\x19Ethereum Signed Message:\n32";
bytes32 prefixedHashMessage = keccak256(abi.encodePacked(prefix, _hashedMessage));
address signer = ecrecover(prefixedHashMessage, _v, _r, _s);
return signer;
}
}
运行之后,得到签名的钱包
Last updated