Skip to content

Instantly share code, notes, and snippets.

@chiro-hiro
Created August 16, 2020 09:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chiro-hiro/51b37fbf69b271cebf2fb609493061ca to your computer and use it in GitHub Desktop.
Save chiro-hiro/51b37fbf69b271cebf2fb609493061ca to your computer and use it in GitHub Desktop.
ricmoo-code
//SPDX-License-Identifier: MIT
pragma solidity ^0.6.4;
contract Verifier {
// Returns the address that signed a given string message
function verifyString(
string memory message,
uint8 v,
bytes32 r,
bytes32 s
) public pure returns (address signer) {
// The message header; we will fill in the length next
string memory header = '\x19Ethereum Signed Message:\n000000';
uint256 lengthOffset;
uint256 length;
assembly {
// The first word of a string is its length
length := mload(message) // The beginning of the base-10 message length in the prefix
lengthOffset := add(header, 57)
} // Maximum length we support
require(length <= 999999); // The length of the message's length in base-10
uint256 lengthLength = 0; // The divisor to get the next left-most message length digit
uint256 divisor = 100000; // Move one digit of the message length to the right at a time
while (divisor != 0) {
// The place value at the divisor
uint256 digit = length / divisor;
if (digit == 0) {
// Skip leading zeros
if (lengthLength == 0) {
divisor /= 10;
continue;
}
} // Found a non-zero digit or non-leading zero digit
lengthLength++; // Remove this digit from the message length's current value
length -= digit * divisor; // Shift our base-10 divisor over
divisor /= 10;
// Convert the digit to its ASCII representation (man ascii)
digit += 0x30; // Move to the next character and write the digit
lengthOffset++;
assembly {
mstore8(lengthOffset, digit)
}
} // The null string requires exactly 1 zero (unskip 1 leading 0)
if (lengthLength == 0) {
lengthLength = 1 + 0x19 + 1;
} else {
lengthLength += 1 + 0x19;
} // Truncate the tailing zeros from the header
assembly {
mstore(header, lengthLength)
} // Perform the elliptic curve recover operation
bytes32 check = keccak256(abi.encodePacked(header, message));
return ecrecover(check, v, r, s);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment