Skip to content

Commit c4d484e

Browse files
committed
shutter-service: add initial ShutterRegistry
1 parent 9337160 commit c4d484e

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

foundry.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
src = "src"
33
out = "out"
44
libs = ["lib"]
5-
solc = "0.8.22"
5+
solc = "0.8.28"
66

77
extra_output = ['devdoc', 'userdoc', 'metadata', 'storageLayout']
88
bytecode_hash = 'none'
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.28;
3+
4+
import "openzeppelin/contracts/access/Ownable.sol";
5+
6+
/**
7+
* @title ShutterRegistry
8+
* @dev A contract for managing the registration of identities with timestamps, ensuring unique and future-dated registrations.
9+
* Inherits from OpenZeppelin's Ownable contract to enable ownership-based access control.
10+
*/
11+
contract ShutterRegistry is Ownable {
12+
13+
// Custom error for when an identity is already registered.
14+
error AlreadyRegistered();
15+
16+
// Custom error for when a provided timestamp is in the past.
17+
error TimestampInThePast();
18+
19+
/**
20+
* @dev Mapping to store registration timestamps for each identity.
21+
* The identity is represented as a `bytes32` hash and mapped to a uint64 timestamp.
22+
*/
23+
mapping(bytes32 identity => uint64 timestamp) public registrations;
24+
25+
/**
26+
* @dev Emitted when a new identity is successfully registered.
27+
* @param identityPrefix The raw prefix input used to derive the registered identity hash.
28+
* @param sender The address of the account that performed the registration.
29+
* @param timestamp The timestamp associated with the registered identity.
30+
*/
31+
event IdentityRegistered(
32+
bytes32 identityPrefix,
33+
address sender,
34+
uint64 timestamp
35+
);
36+
37+
/**
38+
* @dev Initializes the contract and assigns ownership to the deployer.
39+
*/
40+
constructor() Ownable(msg.sender) {}
41+
42+
/**
43+
* @notice Registers a new identity with a specified timestamp.
44+
* @dev The identity is derived by hashing the provided `identityPrefix` concatenated with the sender's address.
45+
* @param identityPrefix The input used to derive the identity hash.
46+
* @param timestamp The future timestamp to be associated with the identity.
47+
* @custom:requirements
48+
* - The identity must not already be registered.
49+
* - The provided timestamp must not be in the past.
50+
*/
51+
function register(bytes32 identityPrefix, uint64 timestamp) external {
52+
// Generate the identity hash from the provided prefix and the sender's address.
53+
bytes32 identity = keccak256(abi.encodePacked(identityPrefix, msg.sender));
54+
55+
// Ensure the identity is not already registered.
56+
require(registrations[identity] == uint64(0), AlreadyRegistered());
57+
58+
// Ensure the timestamp is not in the past.
59+
require(timestamp >= block.timestamp, TimestampInThePast());
60+
61+
// Store the registration timestamp.
62+
registrations[identity] = timestamp;
63+
64+
// Emit the IdentityRegistered event.
65+
emit IdentityRegistered(
66+
identityPrefix,
67+
msg.sender,
68+
timestamp
69+
);
70+
}
71+
}

0 commit comments

Comments
 (0)