-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathddis.sol
More file actions
164 lines (135 loc) · 5.4 KB
/
ddis.sol
File metadata and controls
164 lines (135 loc) · 5.4 KB
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// DECENTRALIZED DIGITAL IDENTITY SOLUTION
// AUTHOR: PRANAV UNNI
// --------------------------------
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// NOTES
// COMPANIES LIKE AMAZON WILL CREATE A WALLET,
// THEN TAKE CONSENT FROM USER ABOUT WHAT DATA TO RETRIEVE. BASED ON THE BOOL VALUES, THE DATA CAN BE ACCESSED
contract OneTimeKYC{
// VARIABLES
// struct of details of the user
struct details {
string name;
string dob_dd_mm_yyyy;
string email;
string mob;
bool is_verified;
string ipfsVideoProofLink;
string ipfsDocumentProofLink;
}
// struct to ask for consent
struct consent {
bool name;
bool dob_dd_mm_yyyy;
bool email;
bool mob;
bool ipfsVideoProofLink;
bool ipfsDocumentProofLink;
}
// mapping for walletAddr and details
mapping(address => details) walletAddrToDetails;
// verifier address map: The address of entities which can act as verifiers.
mapping(address => bool) private verifierAddressMap;
// give consents: Maps a user to the address of companies to whom he has given/revoke consents
mapping(address => address[]) giveConsent;
// consents defined by the company
mapping(address => consent) public consentDefinition;
// mapping of wallet address and company name
mapping(address => string) public addressToCompanyName;
// FUNCTIONS
// SETTERS
// constructor to add owner of contract as verifier
constructor() {
verifierAddressMap[msg.sender] = true;
}
// fill the details: called by user
function fillDetails(string memory name, string memory dob_dd_mm_yyyy, string memory email,
string memory mob, string memory ipfsVideoProofLink, string memory ipfsDocumentProofLink) external {
// fill basic details
walletAddrToDetails[msg.sender] = details(name, dob_dd_mm_yyyy, email, mob, false, ipfsVideoProofLink, ipfsDocumentProofLink);
}
// verify user: called by verifier
function verifyUser(address walletAddr) external{
// check if the caller is a verifier
require(verifierAddressMap[msg.sender] == true, "you are not a verifier");
details storage data = walletAddrToDetails[walletAddr];
data.is_verified = true;
}
// create consent: called by company
function createConsent(string memory companyName, bool name, bool dob_dd_mm_yyyy, bool email, bool mob, bool ipfsVideoProofLink, bool ipfsDocumentProofLink) external{
addressToCompanyName[msg.sender] = companyName;
consentDefinition[msg.sender] = consent(name, dob_dd_mm_yyyy, email, mob, ipfsVideoProofLink, ipfsDocumentProofLink);
}
// give consent: called by user if he accepts the consent asked by the company
function giveCompanyConsent(address companyAddress) external returns (bool){
address[] storage arr = giveConsent[msg.sender];
arr.push(companyAddress);
giveConsent[msg.sender] = arr;
return true;
}
// revoke consent: called by user.
function revokeCompanyConsent(address companyAddress) external {
address[] storage arr = giveConsent[msg.sender];
int index = -1;
for(uint i = 0; i < arr.length; i++){
if(arr[i] == companyAddress){
index = int256(i);
break;
}
}
if(index != -1){
uint ina = uint256(index);
arr[ina] = arr[arr.length-1];
arr.pop();
}
}
// GETTERS
// retrieve data: called by the user to get to know his data he stored.
function retrieveData() external view returns(details memory){
return walletAddrToDetails[msg.sender];
}
// retrieve consents given by user to company: called by user
function retrieveConsents() external view returns(address[] memory){
return giveConsent[msg.sender];
}
// access data based on consent: called by company
function retrieveDataBasedOnConsent(address userAddress) external view returns (details memory){
address[] memory arr = giveConsent[userAddress];
if(arr.length == 0){
revert("user did not give consent");
}
for(uint i = 0; i < arr.length; i++){
if(arr[i] == msg.sender){
break;
}
else if(i == arr.length-1){
revert("user did not give consent");
}
}
details memory tempdata = walletAddrToDetails[userAddress];
consent memory tempconsent = consentDefinition[msg.sender];
if(!tempconsent.name){
tempdata.name = "";
}
if(!tempconsent.dob_dd_mm_yyyy){
tempdata.dob_dd_mm_yyyy = "";
}
if(!tempconsent.email){
tempdata.email = "";
}
if(!tempconsent.ipfsDocumentProofLink){
tempdata.ipfsDocumentProofLink = "";
}
if(!tempconsent.ipfsVideoProofLink){
tempdata.ipfsVideoProofLink = "";
}
if(!tempconsent.mob){
tempdata.mob = "";
}
return tempdata;
}
}
// in order for company to retrieve data of a user, it needs to know the user's wallet address. Based on which it can ping
// the contract to retrieve data. So, the company have to integrate the function `giveCompanyConsent` within the frontend.
// If the user accepts the consent, then the company can call `retrieveDataBasedOnConsent`