I assume that by "validating", you mean verifying that the message has indeed been signed with the "verifier" address.
There are multiple ways to do this. The most commons are either solidity's ecrecover()
or OpenZeppelin's ECDSA
library.
Let's see how to do it with the vanilla ecrecover()
.
You'll need to know in the execution environment :
- The address of the signer here is
address verifier
- The message that is being signed
For this answer, I'll use a common usage of such concept: whitelisted presale. I guess most StackExchange viewers will look for this case.
The owner of the presale signs a message containing the address of the whitelisted buyer. The buyer can then submit this "password" to get access to the presale. You can generalize it by adding more data in abi.encodePacked()
function verify(bytes memory signature, address target) public view returns (bool) {
uint8 v;
bytes32 r;
bytes32 s;
(v, r, s) = splitSignature(signature);
bytes32 senderHash = keccak256(abi.encodePacked(target));
return (verifier == address(ecrecover(senderHash, v, r, s)));
}
// This will process the signature in a readable format for ecrecover()
function splitSignature(bytes memory sig)
internal
pure
returns (uint8, bytes32, bytes32)
{
require(sig.length == 65);
bytes32 r;
bytes32 s;
uint8 v;
assembly {
// first 32 bytes, after the length prefix
r := mload(add(sig, 32))
// second 32 bytes
s := mload(add(sig, 64))
// final byte (first byte of the next 32 bytes)
v := byte(0, mload(add(sig, 96)))
}
return (v, r, s);
}
The tricky part is usually to generate a compatible signature. For this (simple) example, I used the ``eth-crypto``` node.js library. You may find different implementations, depending on the signing lib that you use ("Ethereum Signed Message" standard, for instance)