## 3 Smart Contract Design
### User Access Control and User Management  
The user access control algorithm in the smart contract is described in Algorithm 1. We define three roles: Administrator (Admin for short), Writer, and Reader. The Admin has all the privileges, including user management, the right to write data into the smart contract, and the right to read from the smart contract. The Writer has the right to write data into the smart contract and the right to read from the smart contract, but does not have usermanagement privilege. The Reader only has the right to read from the smart contract. This design means that for a user (i.e., the corresponding account) to read from or write to the smart contract, the user must be added to the list of accounts with proper roles. Each role is represented by a 32-byte long byte array (using the Solidity bytes32 type) obtained by hashing a string literal (\"Admin\" for the Admin, \"Write\" for the Writer, and \"Read\" for the Reader) using the keccak256 secure hash function (A represents the Admin, W represents the Writer, and R represents the Reader). Access control is enforced for all public functions defined in the smart contract using a modifier called onlyrole. As shown in lines 1-12 in Algorithm 1, this modifier takes one argument as the minimum role for the called operation, and checks if the calling account has already been assigned a role that is the same or more privileged. The call is rejected if the check fails. By default, the account that created the smart contract assumes the Admin role. This account may add other accounts as Admin, Writer, or Reader via the grantadminrole, grantwriterrole, and grantreaderrole functions. To keep track of the accounts that have been authorized with Admin, Writer, or Reader roles, a mapping roles is defined, as shown in Figure 5. In Solidity, a mapping is a hash table that takes a key and a value. The roles mapping would map a role into another mapping that maps an account address to a boolean value. In cases where multiple accounts have Admin, Writer, or Reader role, the value of the roles mapping would resemble an array. However, unlike an array, the value in a mapping cannot be iterated. One would have to know the account address in the value of the roles mapping to know whether the account has been granted one of the roles. The roles mapping is essentially a two-dimensional hash table with the role as the first key and the address of an account as the second key. If an account with an address acct is authorized with a particular role, then roles[role][acct] is set to true, as illustrated in Figure 5. It is possible that an account was first granted a particular role, but was later removed from the role, in which case, the account is still kept in value of the roles mapping with the Boolean value set to false. As shown in Algorithm 1, if an account acct is granted the Admin role, roles[A][acct], roles[W][acct], roles[R][acct] are all set to true in lines 5-7; if an account acct is granted the Writer role, roles[W][acct], roles[R][acct] are set to true in lines 10-11; and if an account is granted the Reader role, then only roles[R][acct] is set to true in line 14. An Admin account may also remove the Writer or Reader role from other accounts by calling the delewriter and delereader functions. When removing a role from an account, the roles mapping for the corresponding account is set to false (in lines 24-25 when removing the writer role, and in line 28 when removing the reader role). Only the contract owner may remove the Admin role from an account (in line 17), and roles[A][acct], roles[W][acct], roles[R][acct] are all set to false in lines 18-20. Figure 5: Data structures used for user management and their relationship.