基于区块链的医疗信息隐私性系统的设计与实现

本系统旨在利用区块链技术实现医疗信息的安全存储和访问控制,保障患者隐私,提升医疗数据管理效率。

系统设计流程图

系统设计流程图

开发工具

  • Solidity:用于智能合约的编写
  • Remix:Solidity 在线 IDE
  • Truffle:用于智能合约的部署和测试
  • Ganache:用于本地区块链的搭建和测试
  • Metamask:浏览器插件,用于与区块链交互

环境

  • 操作系统:Windows 10
  • 编程语言:Solidity、JavaScript
  • 区块链平台:Ethereum
  • 开发工具:Remix、Truffle、Ganache、Metamask
  • 数据库:无

源码

智能合约源码

pragma solidity ^0.8.0;

contract MedicalRecord {
    struct Record {
        uint256 id;
        string name;
        string gender;
        uint256 age;
        string disease;
        string treatment;
        uint256 timestamp;
    }

    mapping(address => bool) private _doctors;
    mapping(uint256 => Record) private _records;
    uint256 private _recordCount;

    event RecordAdded(uint256 id, string name, string gender, uint256 age, string disease, string treatment, uint256 timestamp);

    modifier onlyDoctor() {
        require(_doctors[msg.sender], 'Only doctors can perform this action');
        _;
    }

    function addDoctor(address doctor) public onlyDoctor {
        _doctors[doctor] = true;
    }

    function removeDoctor(address doctor) public onlyDoctor {
        _doctors[doctor] = false;
    }

    function isDoctor(address doctor) public view returns (bool) {
        return _doctors[doctor];
    }

    function addRecord(string memory name, string memory gender, uint256 age, string memory disease, string memory treatment) public onlyDoctor {
        _recordCount++;
        _records[_recordCount] = Record(_recordCount, name, gender, age, disease, treatment, block.timestamp);
        emit RecordAdded(_recordCount, name, gender, age, disease, treatment, block.timestamp);
    }

    function getRecord(uint256 id) public view returns (string memory name, string memory gender, uint256 age, string memory disease, string memory treatment, uint256 timestamp) {
        Record memory record = _records[id];
        require(record.id != 0, 'Record does not exist');
        return (record.name, record.gender, record.age, record.disease, record.treatment, record.timestamp);
    }
}

该智能合约实现了医疗记录的添加和查询功能。只有医生才能添加医疗记录,普通用户只能查询记录。记录包含病人姓名、性别、年龄、疾病、治疗方案和记录时间等信息。

前端页面源码

<!DOCTYPE html>
<html>
  <head>
    <meta charset='UTF-8' />
    <title>Medical Record</title>
  </head>
  <body>
    <h1>Medical Record</h1>
    <form>
      <label for='name'>Name:</label>
      <input type='text' id='name' /><br />
      <label for='gender'>Gender:</label>
      <input type='text' id='gender' /><br />
      <label for='age'>Age:</label>
      <input type='number' id='age' /><br />
      <label for='disease'>Disease:</label>
      <input type='text' id='disease' /><br />
      <label for='treatment'>Treatment:</label>
      <input type='text' id='treatment' /><br />
      <input type='button' value='Submit' onclick='addRecord()' />
    </form>
    <hr />
    <h2>Records</h2>
    <table>
      <thead>
        <tr>
          <th>ID</th>
          <th>Name</th>
          <th>Gender</th>
          <th>Age</th>
          <th>Disease</th>
          <th>Treatment</th>
          <th>Timestamp</th>
        </tr>
      </thead>
      <tbody id='records'></tbody>
    </table>
    <script src='./app.js'></script>
  </body>
</html>

该页面包含一个表单用于添加医疗记录,以及一个表格用于展示所有的记录。用户可以在表单中输入病人的信息,然后点击提交按钮来添加记录。记录添加成功后,页面会自动刷新并展示最新的记录。

前端页面 JavaScript 代码

const contractAddress = '0x1234567890123456789012345678901234567890';
const contractABI = [
  {
    inputs: [],
    stateMutability: 'nonpayable',
    type: 'constructor',
  },
  {
    inputs: [
      {
        internalType: 'address',
        name: 'doctor',
        type: 'address',
      },
    ],
    name: 'addDoctor',
    outputs: [],
    stateMutability: 'nonpayable',
    type: 'function',
  },
  {
    inputs: [
      {
        internalType: 'string',
        name: 'name',
        type: 'string',
      },
      {
        internalType: 'string',
        name: 'gender',
        type: 'string',
      },
      {
        internalType: 'uint256',
        name: 'age',
        type: 'uint256',
      },
      {
        internalType: 'string',
        name: 'disease',
        type: 'string',
      },
      {
        internalType: 'string',
        name: 'treatment',
        type: 'string',
      },
    ],
    name: 'addRecord',
    outputs: [],
    stateMutability: 'nonpayable',
    type: 'function',
  },
  {
    inputs: [
      {
        internalType: 'address',
        name: 'doctor',
        type: 'address',
      },
    ],
    name: 'isDoctor',
    outputs: [
      {
        internalType: 'bool',
        name: '',
        type: 'bool',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [
      {
        internalType: 'uint256',
        name: 'id',
        type: 'uint256',
      },
    ],
    name: 'getRecord',
    outputs: [
      {
        internalType: 'string',
        name: '',
        type: 'string',
      },
      {
        internalType: 'string',
        name: '',
        type: 'string',
      },
      {
        internalType: 'uint256',
        name: '',
        type: 'uint256',
      },
      {
        internalType: 'string',
        name: '',
        type: 'string',
      },
      {
        internalType: 'string',
        name: '',
        type: 'string',
      },
      {
        internalType: 'uint256',
        name: '',
        type: 'uint256',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [
      {
        internalType: 'address',
        name: 'doctor',
        type: 'address',
      },
    ],
    name: 'removeDoctor',
    outputs: [],
    stateMutability: 'nonpayable',
    type: 'function',
  },
  {
    inputs: [],
    name: '_doctors',
    outputs: [
      {
        internalType: 'mapping(address => bool)',
        name: '',
        type: 'mapping(address => bool)',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [],
    name: '_recordCount',
    outputs: [
      {
        internalType: 'uint256',
        name: '',
        type: 'uint256',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
  {
    inputs: [
      {
        internalType: 'uint256',
        name: '',
        type: 'uint256',
      },
    ],
    name: '_records',
    outputs: [
      {
        internalType: 'uint256',
        name: 'id',
        type: 'uint256',
      },
      {
        internalType: 'string',
        name: 'name',
        type: 'string',
      },
      {
        internalType: 'string',
        name: 'gender',
        type: 'string',
      },
      {
        internalType: 'uint256',
        name: 'age',
        type: 'uint256',
      },
      {
        internalType: 'string',
        name: 'disease',
        type: 'string',
      },
      {
        internalType: 'string',
        name: 'treatment',
        type: 'string',
      },
      {
        internalType: 'uint256',
        name: 'timestamp',
        type: 'uint256',
      },
    ],
    stateMutability: 'view',
    type: 'function',
  },
];

const web3 = new Web3(Web3.givenProvider);
const contract = new web3.eth.Contract(contractABI, contractAddress);

async function addRecord() {
  const name = document.getElementById('name').value;
  const gender = document.getElementById('gender').value;
  const age = document.getElementById('age').value;
  const disease = document.getElementById('disease').value;
  const treatment = document.getElementById('treatment').value;

  const accounts = await web3.eth.requestAccounts();
  const doctor = accounts[0];

  const isDoctor = await contract.methods.isDoctor(doctor).call();
  if (!isDoctor) {
    alert('You are not authorized to perform this action');
    return;
  }

  await contract.methods.addRecord(name, gender, age, disease, treatment).send({ from: doctor });

  location.reload();
}

async function loadRecords() {
  const tbody = document.getElementById('records');

  const recordCount = await contract.methods._recordCount().call();
  for (let i = 1; i <= recordCount; i++) {
    const [name, gender, age, disease, treatment, timestamp] = await contract.methods.getRecord(i).call();

    const tr = document.createElement('tr');
    tr.innerHTML = `<td>${i}</td><td>${name}</td><td>${gender}</td><td>${age}</td><td>${disease}</td><td>${treatment}</td><td>${new Date(timestamp * 1000)}</td>`;
    tbody.appendChild(tr);
  }
}

loadRecords();

该 JavaScript 代码使用了 Web3.js 库与智能合约进行交互。用户可以在表单中输入病人的信息,然后点击提交按钮来添加记录。添加记录时,需要使用 Metamask 插件进行身份验证。如果用户不是医生,则无法添加记录。页面加载时,会自动从智能合约中读取所有的记录,并展示在表格中。


原文地址: https://www.cveoy.top/t/topic/gjVQ 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录