Using blockchain to store medical data

Using blockchain to store medical data

The question of whether blockchain is suitable for public data is complex and there is no one-size-fits-all solution. However, there are some potential solutions to consider:

  1. Private Networks: One solution to the privacy concerns surrounding blockchain technology is to use private blockchains instead of public blockchains. Private blockchains can offer the benefits of blockchain technology, such as immutability and transparency, while also ensuring data privacy and security.
  2. Hybrid Approach: Another option is to use a hybrid approach where sensitive data is stored on a private blockchain and non-sensitive data is stored on a public blockchain. This enables you to enjoy the benefits of both blockchains while keeping sensitive information safe.
  3. Layered architecture: A layered architecture can be used to separate sensitive data from non-sensitive data, ensuring that sensitive information is stored securely while non-sensitive data can be stored on a public blockchain.
  4. Encryption: Encryption can be used to keep sensitive data safe. This can provide an extra layer of security and help prevent unauthorized access to sensitive information.

Smart contract development

Define variables to store the contract owner, medical records, authorized users, and access restrictions for each record. recordsand accessRestrictionsvariables are maps, key-value stores, where keys and values ​​can be of any type.

recordsA map maps keys of type bytes32to Recordvalues ​​of type , the latter being a structure defined later in the contract. authorizedUsersThe mapping maps addresses to boolean values ​​indicating whether a user can access a record. accessRestrictionsA map maps bytes32keys to Restrictionsvalues ​​of type , which is also the structure defined later by the contract.

pragma solidity ^0.7.0;0.7.0;
// 在使用任何智能合约之前彻底审查和测试它是很重要的。

contract MedicalRecord {
    // 合同所有者的地址。
    address private owner;
    // 正在存储的医疗记录。
    mapping(bytes32 => Record) private records;
    // 允许访问记录的授权用户。
    mapping(address => bool) private authorizedUsers;
    // 对每条记录的访问限制。
    mapping(bytes32 => Restrictions) private accessRestrictions;

The lines given below define the "Record" and "Restrictions" structures, which are used to store the data of a single medical record, and the access restrictions on a single record, respectively. RecordThe structure has two fields: data, which is a bytesvalue that stores the actual medical record data, and timestamp, which is a uint256value that stores the last time the record was added or updated. RestrictionsThe structure contains three fields: authorizedUsers, which is a map that stores the users who have access to the record, , minRolewhich is a uint8value that stores the minimum roles required to access the record, and expirationDate, which is a uint256 value that stores The record's expiration date.

// 用户可以拥有的角色。
    // The data for a single medical record.
    struct Record {
        bytes data;
        uint256 timestamp;
    }

    // 对访问单个记录的限制。
    struct Restrictions {
        // 允许访问记录的用户。
        mapping(address => bool) authorizedUsers;
        // 访问记录所需的最低角色。
        uint8 minRole;
        // The expiration date for the record.
        uint256 expirationDate;
    }

Now, define an (enumeration) type Rolesnamed enumto represent the different roles a user can have. enumHas three possible values: Patient, , Doctorand Administrator.

// 用户可以拥有的角色。
    enum Roles {
        Patient,
        Doctor,
        Administrator
    }

Create a mapping name "userRoles" that maps addresses to values ​​of type "Roles", which is the "enum" defined earlier. This map is used to store each user's role. Here's what it looks like:

// 每个用户的角色。
    mapping(address => Roles) private userRoles;

Create a contract constructor, called when deploying a contract. The constructor ownersets the variable to the address of the user who deployed the contract. Here's how to do it:

// 构造函数设置合约的所有者。
    constructor() public {
        owner = msg.sender;
    }

Now, create functions to allow the contract owner to authorize or revoke user access to records and set the user's role. authorizedUsersThe map is updated to reflect the change in authorization status. userRolesMappings have also been updated to reflect the role changes. This is what it looks like:

// 只有所有者才能授权用户访问记录。
    function authorizeUser(address user) public onlyOwner {
        authorizedUsers[user] = true;
    }

    // 只有所有者才能取消用户访问记录的授权。
    function removeAuthorization(address user) public onlyOwner {
        authorizedUsers[user] = false;
    }

    // 只有所有者才能设置用户的角色。
    function setUserRole(address user, Roles role) public onlyOwner {
        userRoles[user] = role;
    }

Now, create a function that allows authorized users to retrieve medical records. The function takes as input a key of type "bytes32" that identifies the record. The function first retrieves the record and its restrictions from storage using the "records" and "accessRestrictions" maps. The function then checks that the current time is before the record's expiration date, that the user's role is equal to or higher than the minimum role required to access the record, and that the user has permission to access the record.

If any of these conditions are not met, the function will throw an error. If all conditions are met, the function will return the recorded data. You may see the following:

// 如果当前时间在记录的到期日期之前,则只有授权用户才能访问记录
    // 并且用户的角色等于或高于访问记录所需的最低角色。
    function getRecord(bytes32 key) public view onlyAuthorized returns (bytes memory) {
        Record storage record = records[key];
        Restrictions storage restrictions = accessRestrictions[key];
        require(block.timestamp < restrictions.expirationDate, "This record has expired.");
        require(uint8(userRoles[msg.sender]) >= restrictions.minRole, "Your role is not high enough to access this record.");
        require(restrictions.authorizedUsers[msg.sender], "You are not authorized to access this record.");
        return record.data;
    }

setRecordFunctions allow owners to add or update medical records. The function takes a key and record data of type "bytes32" as input and an expiration date. It looks like this:

// 只有所有者可以添加或更新记录。
    function setRecord(bytes32 key, bytes memory data, uint256 expirationDate, uint8 minRole, address[] memory authorizedUsers) public onlyOwner {
        Record storage record = records[key];
        record.data = data;
        record.timestamp = block.timestamp;
        Restrictions storage restrictions = accessRestrictions[key];
        restrictions.expirationDate = expirationDate;
        restrictions.minRole = minRole;
        for (uint i = 0; i < authorizedUsers.length; i++) {
            restrictions.authorizedUsers[authorizedUsers[i]] = true;
        }
    }

deleteRecordFeature allows owner to delete medical records. The function takes as input a key of type "bytes32" and uses the "delete" keyword to delete the record and its limits from storage. You can do this:

// 只有所有者才能删除记录。
    function deleteRecord(bytes32 key) public onlyOwner {
        delete records[key];
        delete accessRestrictions[key];
    }

The following line defines two "decorator" functions: "onlyOwner" and "onlyAuthorized". modifieris a function that can be used to modify the behavior of other functions. onlyOwnerModifiers can be applied to functions to restrict the function to be called only by the contract owner.

onlyAuthorizedModifiers can be applied to functions to restrict that function to be called only by authorized users. modifierFunctions use requirethe keyword to enforce limits. requireThe function throws an error if the conditions specified in the statement are not met .

// 只有所有者才能调用这些函数。
    modifier onlyOwner {
        require(msg.sender == owner, "Only the owner can perform this action.");
        _;
    }

    // 只有授权用户才能调用这些函数。
    modifier onlyAuthorized {
        require(authorizedUsers[msg.sender], "You are not authorized to perform this action.");
        _;
    }
}

full code

The contract allows owners to store medical records, set restrictions on access to each record, and authorize users to access records. These restrictions include expiration dates, minimum required roles, and authorized user lists. The contract also has a map to store each user's role.

pragma solidity ^0.7.0;


contract MedicalRecord {
    address private owner;

    mapping(bytes32 => Record) private records;

    mapping(address => bool) private authorizedUsers;

    mapping(bytes32 => Restrictions) private accessRestrictions;

    struct Record {
        bytes data;
        uint256 timestamp;
    }

    struct Restrictions {
        mapping(address => bool) authorizedUsers;
        uint8 minRole;
        uint256 expirationDate;
    }

    enum Roles {
        Patient,
        Doctor,
        Administrator
    }

    mapping(address => Roles) private userRoles;

    constructor() public {
        owner = msg.sender;
    }

    function authorizeUser(address user) public onlyOwner {
        authorizedUsers[user] = true;
    }

    function removeAuthorization(address user) public onlyOwner {
        authorizedUsers[user] = false;
    }

    function setUserRole(address user, Roles role) public onlyOwner {
        userRoles[user] = role;
    }

    function getRecord(bytes32 key) public view onlyAuthorized returns (bytes memory) {
        Record storage record = records[key];
        Restrictions storage restrictions = accessRestrictions[key];
        require(block.timestamp < restrictions.expirationDate, "This record has expired.");
        require(uint8(userRoles[msg.sender]) >= restrictions.minRole, "Your role is not high enough to access this record.");
        require(restrictions.authorizedUsers[msg.sender], "You are not authorized to access this record.");
        return record.data;
    }

    function setRecord(bytes32 key, bytes memory data, uint256 expirationDate, uint8 minRole, address[] memory authorizedUsers) public onlyOwner {
        Record storage record = records[key];
        record.data = data;
        record.timestamp = block.timestamp;
        Restrictions storage restrictions = accessRestrictions[key];
        restrictions.expirationDate = expirationDate;
        restrictions.minRole = minRole;
        for (uint i = 0; i < authorizedUsers.length; i++) {
            restrictions.authorizedUsers[authorizedUsers[i]] = true;
        }
    }

    function deleteRecord(bytes32 key) public onlyOwner {
        delete records[key];
        delete accessRestrictions[key];
    }

    modifier onlyOwner {
        require(msg.sender == owner, "Only the owner can perform this action.");
        _;
    }

    modifier onlyAuthorized {
        require(authorizedUsers[msg.sender], "You are not authorized to perform this action.");
        _;
    }
}

Get more blockchain learning materials through Github!

https://github.com/Manuel-yang/BlockChainSelfLearning

Guess you like

Origin blog.csdn.net/qq_23351293/article/details/130592176