1

I am making a dapp using web3 1.0. I have a contract that stores medical data for every patient (represented by account). Their medical data can be set by doctor (account address) using the set function. I want that before the set function is called, a notification should be sent to the patient whose data is modified. Only if the patient approves, the function should be called and the data should be set, else, the request should be discarded. How can I achieve this with web3 1.0 ? Here is my smart contract -

pragma solidity ^0.5.4;
pragma experimental ABIEncoderV2;

contract MedicalHistory {
    struct medicalData {
        address provider_address;
        string date;
        string[] medicine_name;
        uint[] quantity;
    }
    mapping (address=>medicalData[]) medicalDataHistory;

    function getData() public view returns(medicalData[] memory) {
        return medicalDataHistory[msg.sender];
    }
    function setData(address a,string memory d, string[] memory s, uint[] memory u) public {
        medicalData memory m = medicalData(a, d, s, u);
        medicalDataHistory[msg.sender].push(m);
    }
}

1 Answer 1

0

This has actually nothing to do with web3 as I assume you want the logic to stay in the blockchain. So this is a Solidity logic question.

The biggest problem you will face is the notification part. A smart contract can't send direct notifications to the external world. A smart contract is deterministic so it has no direct access to the external world - all information it has needs to come to it through a transaction.

I'm sure there are some services which offer such functionality so that you call a specific contract and then some backend system notices the call and performs some notification - unsure if for example Oraclize offers such.

Otherwise for the approval you can do it in a few phases (as you mostly already outlined):

1) Doctor sends a transaction which attempts to write patient data. The data is not stored for the patient directly but put in an approval queue of some sort

2) Patient somehow finds out he has to go approve stuff. He checks the smart contract for the data and if it's ok he issues a transaction which approves the data. Then the data is stored for the patient in the contract.

An approval queue is really easy to implement and it's basically almost the same (or maybe even the same) as your records mapping. So something like this:

pragma solidity ^0.5.4;
pragma experimental ABIEncoderV2;

contract MedicalHistory {
    struct medicalData {
        address provider_address;
        string date;
        string[] medicine_name;
        uint[] quantity;
    }

    mapping(address => medicalData) approvalQueue;

    mapping (address=>medicalData[]) medicalDataHistory;

    function getData() public view returns(medicalData[] memory) {
        return medicalDataHistory[msg.sender];
    }

    // unsure what address a is so added a new address for the patient
    function setData(address a,string memory d, string[] memory s, uint[] memory u, address patient) public {
        medicalData memory m = medicalData(a, d, s, u);
        approvalQueue[patient] = m;
        // notify patient
    }

    function approve() public {
        medicalDataHistory[msg.sender].push(approvalQueue[msg.sender]);
        delete approvalQueue[msg.sender];
    }
}
4
  • Thanks for the answer. But any idea on how to implement an approval queue ? I can use a back-end system but then it would have to be maintained by a central authority who will have access to the notifications and medical data waiting for approval. This will break the core advantages of using a blockchain system like confidentiality, decentralization etc. Other way I can do this is probably write a notification contract that stores notification for each user address. When the user opens the application, the notifications will be fetched from that contract for that account. Does that sound ok ?
    – harshit
    Mar 28, 2019 at 15:37
  • Edited answer to display an example of a queue. Mar 28, 2019 at 18:46
  • Thanks Lauri, this will solve my problem. I would like that approvalQueue to be a mapping from address to an array of medicalData. While approving, can we then delete a particular medicalData instead of all depending on what medicalData the patient wants to approve ?
    – harshit
    Mar 30, 2019 at 8:58
  • Yes, you just have to loop through the array then to find the one you want to approve. Mar 30, 2019 at 12:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.