This document aims to provide documentation for smart contract CovidCredentialRegistry.
This smart contract will serve as a public database to store information self-attested by citizens related to the Coronavirus. The citizens will be able to use different apps/wallets to attest that information. Apps/wallets will generate verifiable credentials for the users that contain the self-attested information. Apps/wallets will also send to this smart contract some of the information from the verifiable credentials that is public and pseudonymous. Then, different services will subscribe to events from the smart contratc in order to generate dashboards and maps that display the public information.
Summarizing, this smart contract allows to register, revoke and verify a verifiable credential and metadata related to citizen from a specific country.
Use cases
-
Verifiable credentials Wallets allow users to generate their Covid verifiable credentials.
-
Wallets allow users revoke their Covid verifiable credentials.
-
Wallets will send public information from the credentials to a unique and public smart contract.
-
Externap services will consume the information from the smart contract.
-
Any organization or user can verify if the credential is valid against the smart contract.
It is an interface which defines following enums:
CovidCode
enum CovidCode {
Confinement,
Interruption,
Symptoms,
Infection,
Recovery
}
which handles the different types of covid credentials.
InterruptionReason
enum InterruptionReason {
Food,
Work,
Medicines,
Doctor,
Moving,
Assist,
Financial,
Force,
Pets,
Other
}
Which handles reasons for a confinement interruption form.
Sex
enum Sex{
Male,
Female,
Unspecified,
Other
}
Which handles sex of a citizen.
CovidMetadata
struct CovidMetadata {
bytes32 subjectId;
uint startDate;
uint iat;
uint exp;
Sex sex;
uint8 age;
bytes6 geoHash;
CovidCode credentialType;
InterruptionReason reason;
byte symptoms;
bool status;
}
This struct will save metadata related the verifiable credential and the citizen(user) who register the covid verifiable credential.
-
id: is an unique citizen(user) identifier generated by each app. It must not be associated to personal data. For Example: 0x93FA3E4624676F2E9AA143911118B4547087E9B6E0B6076F2E1027D7A2DA2B0A
-
startDate: datetime in milliseconds when the citizen started your confinement, happened an interruption, etc.
-
iat: the timestamp in milliseconds when the credential is issued. For example: 123456
-
exp: the timestamp in milliseconds when the credential expires. For example: 124000
-
sex: the Sex enum which is detailed above.
-
age: age of the citizen. For example 35
-
geoHash: the geoHash of latitude and longitude with precision 6
For example to describe the neighborhood Lince located in Lima-Peru (-12.0877217, -77.044704), the contract will receive "6mc5qb". Test to get a geoHash here. -
credentialType: the CovidCode enum which is detailed above.
-
reason: the InterruptionReason wich is detailed above.
-
symptoms: describe symptoms of a person: "Symptoms", "Fever", "Cough", "Breathing issues", "Lost smell and taste", "Headache", "Muscle pain", "Sore Throat". These are handled with 8 bits 0=false 1=true.
-
status: The state of the credential. true for valid and false for invalid.
This contract manages the whitelist roles. Any organization registered can whitelist new user address. This contract is an implementation from WhitelistedRole Openzeppelin.
This contract implements the ICredentialRegistry interface and inherits WhiteListedRoles methods.
Add Address Whitelisted
function addWhitelisted(address account) public onlyWhitelistAdmin
This function will be executed by the organizations that have previously been assigned the role to add new addresses to the whitelist.
- address: Is a citizen(user) or organization address.
Register covid credential
function register(bytes32 hash, bytes32 id, uint startDate, uint exp, Sex sex, uint8 age, bytes6 geoHash, CovidCode credentialType, InterruptionReason reason, byte symptoms) onlyWhitelisted override external returns(bool)
This function register a new covid credential and metadata from a whitelisted address.
- hash: this parameter is the hash of some fields in the verifiable credentials that are common to all the apps. These are the ones that go from "givenName" to "startDate". Check the Verifiable Credential structures proposed. In order to do so, to generate the hash we take all the fields of the credentialSubject:
"credentialSubject": {
"id": "did:12345",
"givenName": "Adria",
"familyName": ["Pareja", "Abarca"],
"nickName": "ccamaleon",
"sameAs": "urn:pe:dni:23434343",
"sex":"Male",
"birthDate": "YYYY", // Year only is enough since we want the age
"confinement": {
"geo": {
"latitude":"-12.04",
"longitude":"77.08"
},
"numberOfParticipants": 4,
"startDate": "2020-03-01T19:23:24Z"
}
}
we get out the id field from the credentialSubject object, remove the white spaces, order fields alphabetically (a-z) and finally put the values in capital letters. For example for this case, the object from which we would generate the hash, would be like this:
"credentialSubject":{"birthDate":"YYYY","confinement":{"geo":{"latitude":"-12.04","longitude":"77.08"},"numberOfParticipants":4,"startDate":"2020-03-01T19:23:24Z"},"familyName":["PAREJA","ABARCA"],"givenName":"ADRIAN","nickName":"CCAMALEON","sameAs":"URN:PE:DNI:23434343","sex":"MALE"}
Finally to obtain the hash use the algorithm sha-256, which would be: F094F56522F9EAD2305CB4B2BC84B12409556AC76F613E2448EBE320C3CDA947
The rest of parameters are explained in CovidMetadata struct
section.
For example, the parameters to register a covid credential could be:
- hash: 0x7A906FA6137E4325646E8F8814C4F719345D50C1BB056FCF78A2A031A6A584E0
- id: 0x93FA3E4624676F2E9AA143911118B4547087E9B6E0B6076F2E1027D7A2DA2B0A
- startDate: 1586571297000 (Sat Apr 11 2020 02:14:57 UTC)
- exp: 1586771297000 (Mon Apr 13 2020 09:48:17 UTC)
- sex: Sex.Male (value:0)
- age: 35
- geoHash: 0x366d63357162 (Hexadecimal value of 6mc5qb)
- credentialType: CovidCode.Confinement (value:0)
- reason: InterruptionReason.Food (value:0)
- symptoms: 0xF0 "Symptoms", "Fever", "Cough", "Breathing issues". (value of 11110000)
The requirements for the credential to be registered are that:
- the address that sends the transaction is whitelisted by any organization and that the credential does not exist.
In order to be able to do so, the organization that wishes to be whitelisted can reach out to [email protected].
Revoke covid credential
function revoke(bytes32 hash) onlyWhitelisted override external returns(bool)
This function revoke a covid credential previously registered.
- hash: this parameter is the hash of the verifiable credential that will be revoked.
the requirements for the credential to be revoked are that:
- only the same address that registered the credential can revoke it (the credential exists) and that the credential is in a valid state.
Verify a credential
function verify(bytes32 hash, address citizen) override external view returns(bool isValid)
This function verify if a credential is valid.
- hash: this parameter is the hash of the verifiable credential that will be verified.
- citizen: address of a citizen who generated the credential.
We are using Openzeppelin Cli to deploy the upgradable smart contract.
First, you need to install openzeppelin cli dependencies.
$ npm install --save-dev @openzeppelin/cli
Second, you need to modify the networks.js file to set the node and private key to deploy the smart contract. Next execute the command to deploy.
$ npx openzeppelin deploy
If you need to upgrade the smart contract then execute the following command.
npx openzeppelin upgrade
Upgradable Smart Contract on Lacchain --> 0x13Bf54153c34555205D009e492FD725D42287e99 ONLY TEST - Upgradable Credentials Smart Contract on Covid-Network - TEST --> 0xE2Aa96695EF268eCbf693d5ab276D5CBEA2A2251
PRODUCTION - Credentials Registry on Covid-Network --> 0x06c87D3D3881b3a802B392913A3C451dC3da6ed0