-
Notifications
You must be signed in to change notification settings - Fork 2
/
ProofOfExistence.sol
75 lines (60 loc) · 1.83 KB
/
ProofOfExistence.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;
contract ProofOfExistence {
mapping(bytes32 => address) public files;
mapping(address => bytes32[]) public users;
event Claimed(address indexed owner, bytes32 indexed file);
event Forfeited(address indexed owner, bytes32 indexed file);
error NotFileOwner();
error FileAlreadyClaimed();
modifier isOwner(bytes32 hash) {
address from = msg.sender;
if (files[hash] != from) revert NotFileOwner();
_;
}
modifier notClaimed(bytes32 hash) {
address from = msg.sender;
if (files[hash] != address(0)) revert FileAlreadyClaimed();
_;
}
function hasClaimed(bytes32 hash) public view returns (bool) {
address owner = files[hash];
return (owner != address(0));
}
function ownedFiles() public view returns (bytes32[] memory) {
address from = msg.sender;
return users[from];
}
function claim(bytes32 hash) public notClaimed(hash) returns (bool) {
address from = msg.sender;
// update storage files
files[hash] = from;
// update storage users
bytes32[] storage userFiles = users[from];
userFiles.push(hash);
emit Claimed(from, hash);
return true;
}
function forfeit(bytes32 hash) public isOwner(hash) returns (bool) {
address from = msg.sender;
// update storage files
delete files[hash];
// locate the index of the file going to be deleted.
bytes32[] storage userFiles = users[from];
uint32 delIdx = 0;
for (uint32 i = 0; i < userFiles.length; i++) {
if (userFiles[i] == hash) {
delIdx = i;
break;
}
}
// update storage users by swap-delete
if (delIdx != userFiles.length - 1) {
userFiles[delIdx] = userFiles[userFiles.length - 1];
}
// delete
userFiles.pop();
emit Forfeited(from, hash);
return true;
}
}