Skip to content

Instantly share code, notes, and snippets.

@publu
Last active March 1, 2023 22:38
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 publu/240570aad3ada169b458c30933ce297c to your computer and use it in GitHub Desktop.
Save publu/240570aad3ada169b458c30933ce297c to your computer and use it in GitHub Desktop.
/// SPDX-License-Identifier: MIT
/// @title Minuscule Key-Value Store
/// @notice A contract that allows users to store and retrieve key-value pairs on-chain
/// @dev Uses EIP-712 signatures to ensure that only authorized relayers can execute key-value changes
/// @dev Users sign a message that authorizes a specific relayer address to execute the change
/// @dev The signature acts as an API key, and is only valid for a certain period of time
contract Minuscule {
using ECDSA for bytes32;
mapping(address => mapping(bytes32 => bytes32)) private store;
/// @notice Sets a key-value pair for the calling user
/// @dev Requires a valid EIP-712 signature from an authorized relayer
/// @param dataKey The key for the data to be stored
/// @param value The value of the data to be stored
/// @param deadline The timestamp by which the signature must be executed
/// @param relayer The address of the authorized relayer that can execute the signature
/// @param signature The EIP-712 signature that authorizes the relayer to execute the change
function set(bytes32 dataKey, bytes32 value, uint256 deadline, address relayer, bytes memory signature) public {
require(block.timestamp <= deadline, "Expired signature");
require(relayer != address(0), "Invalid relayer address");
bytes32 message = getMessage(dataKey, value, deadline, relayer);
address signer = message.recover(signature);
require(signer == relayer, "Invalid signature");
store[msg.sender][dataKey] = value;
}
/// @notice Gets the value of a key for the calling user
/// @param dataKey The key for the data to retrieve
/// @return The value of the data stored at the specified key
function get(bytes32 dataKey) public view returns (bytes32) {
return store[msg.sender][dataKey];
}
/// @notice Returns the EIP-712 hash of a message
/// @param dataKey The key for the data to be stored
/// @param value The value of the data to be stored
/// @param deadline The timestamp by which the signature must be executed
/// @param relayer The address of the authorized relayer that can execute the signature
/// @return The EIP-712 hash of the message
function getMessage(bytes32 dataKey, bytes32 value, uint256 deadline, address relayer) private view returns (bytes32) {
return keccak256(abi.encodePacked(dataKey, value, deadline, relayer, address(this)));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment