DEV Community

Cover image for How I built a simple healthcare Dapp using Solidity & React
Jeffrey Yu
Jeffrey Yu

Posted on

How I built a simple healthcare Dapp using Solidity & React

Last weekend I attended NextStep Hacks, a hackathon sponsored by Ethereum. I was interested in blockchain for a long time, but this is my first time developing a blockchain project.

In two days, my teammate Akilesh and I learned the basics and built a simple healthcare Dapp, which ended up winning the 3rd place. Here I'll share how I built it and hopefully it will help you jump start with blockchain development ⏫

Inspiration

For decades, medical records are under the ownership of hospitals. It often it takes days to request a hospital to transfer a record, and sometimes impossible to transfer across countries.

Medical record transfer process

When I arrived at US for college, I tried to transfer records of Covid vaccination from China, but rejected by local hospitals. I had to take two more dozes of Pfizer and suffering days of side effects like fever 😣

That's why we built MedChain - a blockchain-based electrical medical records (EMR) decentralized application (Dapp).

How it works

MedChain is powered by IPFS, where patients’ medical records are stored on the distributed file system, not owned by any centralized entity.

A patient or a doctor can access the patient's records by interacting with a smart contract on the Ethereum blockchain. Here is a graph showing how the Dapp works:

Dapp interactions

The client first connects with MetaMask, and uses smart contract to mint a patient or doctor block, registered by the wallet address.

The client can upload a record file to IPFS, which address is linked to a patient block in ETH chain. The client can get all record addressed stored in a patient block from smart contract, and get a record file by its address from IPFS.

Setup

We chose Truffle, a powerful development tool for Ethereum, and React since it's our most familiar frontend framework.

We used Truffle React Box as a boilerplate for this project. It already has React context set up to connect with MetaMask and interact with Truffle.

To get a local blockchain network running on my computer, I set up Ganache and imported test accounts to MetaMask.

Write smart contract

For this project, we only need one Solidity smart contract called EHR. First I defined structures for medical record, patient, and doctor.

Smart contract structures

Then functions to register user. A doctor can register itself and register patients.

Smart contract register functions

Finally, functions to add and get records of a patient. Only a doctor can add records, but both doctor and patient can read records.

Smart contract records functions

To deploy the contract, run truffle deploy and EHR.sol will be deployed as EHR.json.

Connect React with smart contract

Skipping writing components, the important part of this React project is iteracting with the smart contract.

With ETH context provided in the boilterplate, it sets up Web3.js initialization for me. You can find the same logic as the following:

Web3.js init

Since the constants above are stored in context, I can use them easily in a register button component.

Register doctor

The same thing applies to register patient with the patient account as input.

Upload & Download record from IPFS

Another important part is uploading records to IPFS and pushing address to the smart contract. I used ipfs-http-client to handle this easily in React.

First I set up IPFS client using my Infura project. Infura is an infrastructure tool to use IPFS API.

IPFS client setup

After a doctor drags a file in the dropzone, FileReader reads it as a buffer and upload it to IPFS client.

Then I call addRecord contract method with the patient address and the hash returned by IPFS client. Lastly, call getRecords to refresh records.

Upload file to IPFS

Then a patient or doctor can download the record in one click.

Download IPFS file

Final product

You can check out our repo and our project on DevPost.

We hope our project help push revolutionizing the centralized ownership of medical records and let people own their health. Go blockchain 🚀

Top comments (21)

Collapse
 
sofiiasov profile image
SofiiaSov

Great article! It's fascinating to see how Solidity and React can be used to build a simple healthcare Dapp. The combination of blockchain technology and web development frameworks opens up exciting possibilities for the healthcare industry. For more insights and information on creating EMR and EHR systems, I recommend checking out this article by Cleveroad. It provides valuable guidance on building robust and secure electronic medical record systems. Keep up the good work!

Collapse
 
tudan profile image
Thắng Lê

Hi Jeffrey Yu, This is very great Idea. I had the same project about this. And I had an error when doing npm start like this:
C:\Users\ADMIN\thesis_bc\client>npm start

truffle-client@0.1.0 start
react-scripts start

i 「wds」: Project is running at 0.0.0.0:3000/
i 「wds」: webpack output is served from
i 「wds」: Content not from webpack is served from C:\Users\ADMIN\thesis_bc\client\public
i 「wds」: 404s will fallback to /
Starting the development server...
Compiled with warnings.

./src/contexts/EthContext/EthProvider.jsx
Module not found: Can't resolve '../../contracts/SimpleStorage.json' in 'C:\Users\ADMIN\thesis_bc\client\src\contexts\EthContext'

Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.

Can you give me any suggestion!

Collapse
 
jeffreythecoder profile image
Jeffrey Yu

Hi Thang, sorry for the late reply. Make sure you compiled and deployed your truffle contract under client\src\contracts and the name is the same as the imported one in EthContext.

Collapse
 
tudan profile image
Thắng Lê

Hi Jeffrey Yu , I wonder, when the doctor uploads the record file, is there anything to show its immutability. As you know, the purpose of Blockchain is immutable, so when creating a transaction to upload a file, is there a hash or identifier for it. And where is it saved? Can I see them?

Thread Thread
 
jeffreythecoder profile image
Jeffrey Yu

The immutability concept in blockchain is to retain an unalterable history of transactions. In the case of this project, the patient can see every edit history made to his or her record. This is implement-able.

Collapse
 
sergizzzz profile image
Sergizzzz

Did you manage to resolve this problem? If so, what did you do? I'm having the same issues

Collapse
 
tudan profile image
Thắng Lê

Hi Sergizzzz. This is what I did and it was very great. You download file from Git, then from the root directory of that file install npm + truffle if you dont have. Then, cd to the truffle directory: ' truffle compile' - 'truffle migrate'. Make sure that you open your ganache or testnet. After that, cd to client folder: 'npm start'. I worked for me

Collapse
 
crypto_mois profile image
🤖Moi.crypto

Hello Jefrrey, I am a Blockchain fan from Venezuela, a medical student, I want to do my thesis on Blockchain Technology and its use in medicine and I have always loved this use case, how can I contact you, so that you can guide me And if your dapp is still in development!

Collapse
 
jeffreythecoder profile image
Jeffrey Yu

Hi Moi, you can connect with me on LinkedIn: linkedin.com/in/jeffrey-zepeng-yu/. I would love to help!

Collapse
 
reako profile image
Reako • Edited

Hello, is this project on public blockchain? How do you ensure sensitive data security, if data will be forever on chain? Are you encrypt that data?

Thanks in advance :)

Collapse
 
jeffreythecoder profile image
Jeffrey Yu

Hi Reako, this is a hackathon project so I didn't publish it to the public network. Security measures like encryption and authorization is definitely necessary for that case.

Collapse
 
tudan profile image
Thắng Lê

same question

Collapse
 
shamikmaity-ltts profile image
Shamik Maity

Hi Jeffrey

It was fascinating idea. Was trying to run the code. Took the code from the Git - github.com/JeffreytheCoder/med-chain

Ran all the commands :

$ cd truffle
$ npm install
$ truffle compile
$ truffle deploy

$ cd ../client
$ npm install
$ npm start

localhost:3000 - opened in my chrome and the first page i could see. But after that nothings happened can not even register doctor. Here is the log:

*index.js:1 TypeError: Cannot read properties of undefined (reading 'address')
at EthProvider.jsx:17:1
console. @ index.js:1
index.js:1 TypeError: Cannot read properties of undefined (reading 'address')
at EthProvider.jsx:17:1
console. @ index.js:1
index.js:1 TypeError: Cannot read properties of undefined (reading 'methods')
at registerDoctor (index.jsx:24:1)
at handleClick (index.jsx:45:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
at invokeGuardedCallback (react-dom.development.js:4277:1)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:4291:1)
at executeDispatch (react-dom.development.js:9041:1)
at processDispatchQueueItemsInOrder (react-dom.development.js:9073:1)
at processDispatchQueue (react-dom.development.js:9086:1)
at dispatchEventsForPlugins (react-dom.development.js:9097:1)
at react-dom.development.js:9288:1
at batchedUpdates$1 (react-dom.development.js:26140:1)
at batchedUpdates (react-dom.development.js:3991:1)
at dispatchEventForPluginEventSystem (react-dom.development.js:9287:1)
at dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay (react-dom.development.js:6465:1)
at dispatchEvent (react-dom.development.js:6457:1)
at dispatchDiscreteEvent (react-dom.development.js:6430:1)
console. @ index.js:1
overrideMethod @ react_devtools_backend.js:2655
registerDoctor @ index.jsx:29
handleClick @ index.jsx:45
callCallback @ react-dom.development.js:4164
invokeGuardedCallbackDev @ react-dom.development.js:4213
invokeGuardedCallback @ react-dom.development.js:4277
invokeGuardedCallbackAndCatchFirstError @ react-dom.development.js:4291
executeDispatch @ react-dom.development.js:9041
processDispatchQueueItemsInOrder @ react-dom.development.js:9073
processDispatchQueue @ react-dom.development.js:9086
dispatchEventsForPlugins @ react-dom.development.js:9097
(anonymous) @ react-dom.development.js:9288
batchedUpdates$1 @ react-dom.development.js:26140
batchedUpdates @ react-dom.development.js:3991
dispatchEventForPluginEventSystem @ react-dom.development.js:9287
dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @ react-dom.development.js:6465
dispatchEvent @ react-dom.development.js:6457
dispatchDiscreteEvent @ react-dom.development.js:6430
*

Collapse
 
jeffreythecoder profile image
Jeffrey Yu

Hi Shamik,

The error is because it could not get networkID of your local Truffle network. Make sure your local Truffle network is configured and running correctly. Here's a help page.

Collapse
 
shash007 profile image
Shashank

$ cd truffle
$ npm install
$ truffle compile
$ truffle deploy

$ cd ../client
$ npm install

npm ERR! code 128
npm ERR! An unknown git error occurred
npm ERR! command git --no-replace-objects ls-remote ssh://git@github.com/hugomrdias/concat-stream.git
npm ERR! git@github.com: Permission denied (publickey).
npm ERR! fatal: Could not read from remote repository.
npm ERR!
npm ERR! Please make sure you have the correct access rights
npm ERR! and the repository exists.

I'm getting this error, please help me out.

Collapse
 
shash007 profile image
Shashank

$ cd truffle
$ npm install
$ truffle compile
$ truffle deploy

$ cd ../client
$ npm install
in this step I'm getting this

npm ERR! code 128
npm ERR! An unknown git error occurred
npm ERR! command git --no-replace-objects ls-remote ssh://git@github.com/hugomrdias/concat-stream.git
npm ERR! git@github.com: Permission denied (publickey).
npm ERR! fatal: Could not read from remote repository.
npm ERR!
npm ERR! Please make sure you have the correct access rights
npm ERR! and the repository exists.

I'm getting this error, please help me out.

Collapse
 
jeffreythecoder profile image
Jeffrey Yu

Hi Shashank! Sorry for the late reply - I just saw your comment as another person with the same issue reached out to me.

The error is caused by a decrepated IPFS dependency and I just fixed it. If you pull the latest code it should be running ok.

Collapse
 
sevalc profile image
Seval Ç.

Can we use Ubuntu 20.04 to install the development environment?

Collapse
 
sevalc profile image
Seval Ç.

I installed everything like: Node.js v18.17.1, NPM v10.2.5, Truffle v5.11.5, Ganache v7.9.1, Solidity v0.5.16 (solc-js), Web3.js v1.10.0. Then I got this error:
med-chain-master/client$ npm install
npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR!
npm ERR! While resolving: @material-ui/core@4.12.4
npm ERR! Found: react@18.2.0
npm ERR! node_modules/react
npm ERR! react@"^18.1.0" from the root project
npm ERR! peer react@">=16.8.0" from @emotion/react@11.10.0
npm ERR! node_modules/@emotion/react
npm ERR! @emotion/react@"^11.10.0" from the root project
npm ERR! peer @emotion/react@"^11.0.0-rc.0" from @emotion/styled@11.10.0
npm ERR! node_modules/@emotion/styled
npm ERR! @emotion/styled@"^11.10.0" from the root project
npm ERR! 3 more (@mui/material, @mui/styled-engine, @mui/system)
npm ERR! 3 more (@mui/material, @mui/styled-engine, @mui/system)
npm ERR! 17 more (@emotion/styled, @mui/base, @mui/icons-material, ...)
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.8.0 || ^17.0.0" from @material-ui/core@4.12.4
npm ERR! node_modules/@material-ui/core
npm ERR! @material-ui/core@"^4.12.4" from the root project
npm ERR! peer @material-ui/core@"^4.0.0" from @material-ui/icons@4.11.3
npm ERR! node_modules/@material-ui/icons
npm ERR! @material-ui/icons@"^4.11.3" from the root project
npm ERR! 1 more (material-ui-dropzone)
npm ERR! 1 more (material-ui-dropzone)
npm ERR!
npm ERR! Conflicting peer dependency: react@17.0.2
npm ERR! node_modules/react
npm ERR! peer react@"^16.8.0 || ^17.0.0" from @material-ui/core@4.12.4
npm ERR! node_modules/@material-ui/core
npm ERR! @material-ui/core@"^4.12.4" from the root project
npm ERR! peer @material-ui/core@"^4.0.0" from @material-ui/icons@4.11.3
npm ERR! node_modules/@material-ui/icons
npm ERR! @material-ui/icons@"^4.11.3" from the root project
npm ERR! 1 more (material-ui-dropzone)
npm ERR! 1 more (material-ui-dropzone)
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!

Collapse
 
sevalc profile image
Comment marked as low quality/non-constructive by the community. View Code of Conduct
Seval Ç.

I tried all versions of Node and NPM and your damn project does not work. It is a waste of time.

Thread Thread
 
jeffreythecoder profile image
Jeffrey Yu

You can run npm install --force --legacy-peer-deps as it's suggested in your error output. And please don't use bad language here.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.