Signature Verification
Source: Verifying Signature, solidity-by-example.org [7].
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract Yul {
function splitSignature(bytes memory signature) public pure returns (
bytes32 r,
bytes32 s,
uint8 v
) {
// Signatures are 65 bytes in length. r => 32, s => 32, v => 1.
// Although some signatures can be packed into 64 bytes.
if (signature.length != 65) revert();
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
}
function verifySignature(
address signer,
bytes32 hash,
bytes memory sig
) public pure returns (bool) {
(bytes32 r, bytes32 s, uint8 v) = splitSignature(sig);
address recovered = ecrecover(hash, v, r, s);
return (recovered != address(0) && recovered == signer);
}
}
byte(a, b)
retrieves a single byte at position a
in a 32-byte memory word, b
. In our case, we are simply saying "Return the first byte in the 32-byte location at add(signature, 0x60)
."
ecrecover(a, b, c, d)
returns the address of a signer when given four arguments, a
, the hash that was signed and b
, c
, d
being the v
, r
and s
components of the signature, respectively.