pragma solidity ^0.4.18; contract CMCEnabled { address CMC; function setCMCAddress(address cmcAddr) returns (bool result){ if (CMC != 0x0 && msg.sender != CMC) { return false; } CMC = cmcAddr; return true; } function remove(){ if (msg.sender == CMC) { selfdestruct(CMC); } } } contract InfoManEnabled is CMCEnabled { function isInfoMan() constant returns (bool) { if (CMC != 0x0) { address im = CProvider(CMC).contracts("infoman"); return msg.sender == im; } return false; } } contract CMC { address owner; mapping(bytes32 => address) public contracts; modifier onlyOwner { if (msg.sender == owner) _; } function CMC(){ owner = msg.sender; } function addContract(bytes32 name, address addr) onlyOwner returns (bool result) { CMCEnabled cmce = CMCEnabled(addr); if (!cmce.setCMCAddress(address(this))) { return false; } contracts[name] = addr; return true; } function getContract(bytes32 name) constant returns (address addr) { return contracts[name]; } function removeContract(bytes32 name) onlyOwner returns (bool result) { if (contracts[name] == 0x0) { return false; } contracts[name] = 0x0; return true; } function remove() onlyOwner { address im = contracts["infoman"]; address ime = contracts["infomanenabled"]; address perms = contracts["perms"]; address permsdb = contracts["permsdb"]; address patient = contracts["patient"]; address patientinfodb = contracts["pinfodb"]; address doctor = contracts["doctor"]; address hcp = contracts["hcp"]; selfdestruct(owner); } } contract InfoMan is CMCEnabled { address owner; function InfoMan(){ owner = msg.sender; } function addEHR(address patAddr, bytes32 ehr) returns (bool res) { uint8 requestCode = 2; if (patAddr == 0x0 || ehr == 0x0) { return false; } address doctor = CProvider(CMC).contracts("doctor"); address perms = CProvider(CMC).contracts("perms"); if (doctor == 0x0 || perms == 0x0 || Perms(perms).checkPerms(msg.sender) < 1 || Perms(perms).checkAgree(patAddr, msg.sender, requestCode)) { return false; } bool success = Doctor(doctor).addEHR(msg.sender, patAddr, ehr); if (!success) { msg.sender.send(msg.value); } return success; } function addPatient(address patAddr, bytes32 ehr) returns (bool res) { uint8 requestCode = 2; if (patAddr == 0x0) { return false; } address doctor = CProvider(CMC).contracts("doctor"); address perms = CProvider(CMC).contracts("perms"); if (doctor == 0x0 || perms == 0x0 || Perms(perms).checkPerms(msg.sender) < 1 || Perms(perms).checkAgree(patAddr, msg.sender, requestCode)) { return false; } bool success = Doctor(doctor).addPatient(msg.sender, patAddr, ehr); if (!success) { msg.sender.send(msg.value); } return success; } function providing(address patAddr, bytes32 caseHash) returns (uint256 res) { if (patAddr == 0x0 || caseHash == 0) { return 0x0; } address hcp = CProvider(CMC).contracts("hcp"); address perms = CProvider(CMC).contracts("perms"); if (hcp == 0x0 || perms == 0x0 || Perms(perms).checkPerms(msg.sender) < 2) { return 0x0; } return HCP(hcp).providing(patAddr, caseHash); } function setPermission(address addr, uint8 permLvl) returns (bool res) { if (addr == 0x0) { return false; } address perms = CProvider(CMC).contracts("perms"); if (perms == 0x0) { return false; } uint userPerm = Perms(perms).checkPerms(addr); if (userPerm < 3) { return false; } bool success = Perms(perms).setPermission(addr, permLvl); if (!success) { msg.sender.send(msg.value); } return success; } function setAgree(address addr, uint8 agreeCode) returns (bool) { if (addr == 0x0) { return false; } address patient = CProvider(CMC).contracts("patient"); if (patient == 0x0) { return false; } bool success = Patient(patient).setAgree(msg.sender, addr, agreeCode); if (!success) { msg.sender.send(msg.value); } return success; } function isPatient(address patAddr) returns (bool){ if (patAddr == 0x0) { return false; } address doctor = CProvider(CMC).contracts("doctor"); if (doctor == 0x0) { return false; } bool success = Doctor(doctor).isPatient(patAddr); if (!success) { msg.sender.send(msg.value); } return success; } function confirmEHR(address patAddr, bytes32 ehr) returns (bool){ uint8 requestCode = 2; if (patAddr == 0x0 || ehr == 0x0) { return false; } address patient = CProvider(CMC).contracts("patient"); address doctor = CProvider(CMC).contracts("doctor"); address hcp = CProvider(CMC).contracts("hcp"); address perms = CProvider(CMC).contracts("perms"); address pInfodb = CProvider(CMC).contracts("pinfodb"); bool success = false; if ((patient == 0x0 && msg.sender == patAddr) && (perms == 0x0 || doctor == 0x0 || Perms(perms).checkPerms(msg.sender) < 1 || Perms(perms).checkAgree(patAddr, msg.sender, requestCode)) && (perms == 0x0 || hcp == 0x0 || Perms(perms).checkPerms(msg.sender) < 2)) { return false; } success = PInfoDb(pInfodb).confirmEHR(patAddr, ehr); if (!success) { msg.sender.send(msg.value); } return success; } function setEhrAgree(address docAddr, bytes32 ehr) returns (bool res) { if (docAddr == 0x0 || ehr == 0x0) { return false; } address patient = CProvider(CMC).contracts("patient"); address perms = CProvider(CMC).contracts("perms"); if (patient == 0x0 || perms == 0x0 || Perms(perms).checkPerms(docAddr) < 1) { return false; } bool success = Patient(patient).setEhrAgree(msg.sender, docAddr ,ehr); if (!success) { msg.sender.send(msg.value); } return success; } function checkEhrAgree(address patAddr, bytes32 ehr) returns (bool) { if (patAddr == 0x0 || ehr == 0x0) { return false; } address doctor = CProvider(CMC).contracts("doctor"); address perms = CProvider(CMC).contracts("perms"); if (doctor == 0x0 || perms == 0x0 || Perms(perms).checkPerms(msg.sender) < 1) { return false; } bool success = Doctor(doctor).checkEhrAgree(patAddr, msg.sender, ehr); if (!success) { msg.sender.send(msg.value); } return success; } function getNumOfEHRs(address patAddr) returns (uint256){ uint8 requestCode = 2; if (patAddr == 0x0) { return 0x0; } address patient = CProvider(CMC).contracts("patient"); address doctor = CProvider(CMC).contracts("doctor"); address perms = CProvider(CMC).contracts("perms"); address pInfodb = CProvider(CMC).contracts("pinfodb"); if ((patient == 0x0 && msg.sender == patAddr) && (perms == 0x0 || doctor == 0x0 || Perms(perms).checkPerms(msg.sender) < 1 || Perms(perms).checkAgree(patAddr, msg.sender, requestCode))) { return 0x0; } return PInfoDb(pInfodb).getNumOfEHRs(patAddr); } function getEHRByIndex(address patAddr, uint8 index) returns (bytes32) { uint8 requestCode = 2; if (patAddr == 0x0) { return 0x0; } address patient = CProvider(CMC).contracts("patient"); address doctor = CProvider(CMC).contracts("doctor"); address perms = CProvider(CMC).contracts("perms"); address pInfodb = CProvider(CMC).contracts("pinfodb"); if ((patient == 0x0 && msg.sender == patAddr) && (perms == 0x0 || doctor == 0x0 || Perms(perms).checkPerms(msg.sender) < 1 || Perms(perms).checkAgree(patAddr, msg.sender, requestCode))) { return 0x0; } return PInfoDb(pInfodb).getEHRByIndex(patAddr, index); } } contract CProvider { function contracts(bytes32 name) returns (address addr) {} } contract PermsDb is CMCEnabled { struct agreedPatientEHRTuple { address doctor; bytes32 ehr; } struct agreePatientCode { address docOrHCP; uint8 agreeCode; } mapping(address => uint8) public perms; mapping(address => agreePatientCode) public patientDoctorAgree; mapping(address => agreedPatientEHRTuple) public prescripPatientAgree; // 0 - Patient // 1 - HCP // 2 - Doctor function setPermission(address addr, uint8 perm) returns (bool res) { if (CMC != 0x0) { address permC = CProvider(CMC).contracts("perms"); if (msg.sender == permC) { perms[addr] = perm; return true; } return false; } else { return false; } } function setAgree(address patAddr, address docOrHCPAddr, uint8 agreeCode) returns (bool res) { if (CMC != 0x0) { address patientC = CProvider(CMC).contracts("patient"); var agr = agreePatientCode(docOrHCPAddr, agreeCode); if (agreeCode < 4 && msg.sender == patientC) { patientDoctorAgree[patAddr] = agr; return true; } else { return false; } } return false; } function checkAgree(address patAddr, address docOrHCPAddr, uint8 agreeCode) returns (bool){ if (CMC != 0x0) { address doctor = CProvider(CMC).contracts("doctor"); address hcp = CProvider(CMC).contracts("hcp"); if (agreeCode < 4 && (docOrHCPAddr == doctor || docOrHCPAddr == hcp) && patientDoctorAgree[patAddr].docOrHCP == docOrHCPAddr && patientDoctorAgree[patAddr].agreeCode == agreeCode) { return true; } else { return false; } } return false; } function setEhrAgree(address patAddr, address docAddr, bytes32 ehr) returns (bool res) { if (CMC != 0x0) { address patientC = CProvider(CMC).contracts("patient"); var agrPP = agreedPatientEHRTuple(docAddr, ehr); if (msg.sender == patientC) { prescripPatientAgree[patAddr] = agrPP; return true; } else { return false; } } return false; } function checkEhrAgree(address patAddr, address docAddr, bytes32 ehr) returns (bool){ if (CMC != 0x0) { address doctor = CProvider(CMC).contracts("doctor"); var agrPP = agreedPatientEHRTuple(docAddr, ehr); if (docAddr == doctor && prescripPatientAgree[patAddr].doctor == docAddr && prescripPatientAgree[patAddr].ehr == ehr) { return true; } else { return false; } } return false; } } contract Perms is InfoManEnabled { function setPermission(address addr, uint8 perm) returns (bool res) { if (!isInfoMan()) { return false; } address permdb = CProvider(CMC).contracts("permsdb"); if (permdb == 0x0) { return false; } return PermsDb(permdb).setPermission(addr, perm); } function checkPerms(address addr) returns (uint){ if (!isInfoMan()) { return 0x0; } address permdb = CProvider(CMC).contracts("permsdb"); if (permdb == 0x0) { return 0x0; } return PermsDb(permdb).perms(addr); } function checkAgree(address patAddr, address docOrHCPAddr, uint8 agreeCode) returns (bool){ if (!isInfoMan()) { return false; } address permdb = CProvider(CMC).contracts("permsdb"); if (permdb == 0x0) { return false; } return PermsDb(permdb).checkAgree(patAddr, docOrHCPAddr, agreeCode); } function checkEhrAgree(address patAddr, address docAddr, bytes32 ehr) returns (bool){ if (!isInfoMan()) { return false; } address permdb = CProvider(CMC).contracts("permsdb"); if (permdb == 0x0) { return false; } return PermsDb(permdb).checkEhrAgree(patAddr, docAddr, ehr); } } contract PInfoDb is CMCEnabled { struct Patient { address prev; address next; bytes32[] ehrs; address[] responsible; bool init; } uint public size; address public tail; address public head; mapping(address => Patient) public patientList; function addPatient(address respAddr, address patAddr, bytes32 ehr) returns (bool) { if (CMC != 0x0) { address doctor = CProvider(CMC).contracts("doctor"); if (msg.sender == doctor) { if (patientList[patAddr].init == false) { bytes32[] presc; presc.push(ehr); address[] resp; resp.push(respAddr); Patient memory pat = Patient(0, 0, presc, resp, true); patientList[patAddr] = pat; if (size == 0) { tail = patAddr; head = patAddr; } else { patientList[head].next = patAddr; patientList[patAddr].prev = head; head = patAddr; } size++; return patientList[patAddr].init; } } } return false; } function addEHR(address docAddr, address patAddr, bytes32 ehr) returns (uint result) { if (CMC != 0x0) { address doctor = CProvider(CMC).contracts("doctor"); if (msg.sender == doctor) { if (patientList[patAddr].init == false) { return 0; } else if (ehr == 0) { return 1; } else { patientList[patAddr].ehrs.push(ehr); patientList[patAddr].responsible.push(docAddr); return 2; } } } return 0; } function getEHRByIndex(address patAddr, uint8 index) returns (bytes32) { if (CMC != 0x0) { address doctor = CProvider(CMC).contracts("doctor"); address patient = CProvider(CMC).contracts("patient"); if (msg.sender == doctor || msg.sender == patient) { if (patientList[patAddr].init == false) { return 0x0; } else { return patientList[patAddr].ehrs[index]; } } } return 0x0; } function getNumOfEHRs(address patAddr) returns (uint256){ if (CMC != 0x0) { address doctor = CProvider(CMC).contracts("doctor"); address patient = CProvider(CMC).contracts("patient"); if (msg.sender == doctor || msg.sender == patient) { if (patientList[patAddr].init == false) { return 0; } else { return patientList[patAddr].ehrs.length; } } } return 0; } function confirmEHR(address patAddr, bytes32 ehr) returns (bool){ if (CMC != 0x0) { if (patientList[patAddr].init == false || ehr == 0) { return false; } for (uint i = 0; i < patientList[patAddr].ehrs.length; i++) { if (patientList[patAddr].ehrs[i] == ehr) { return true; } } } return false; } function isPatient(address patAddr) returns (bool){ if (patientList[patAddr].init == true) { return true; } else { return false; } } } contract Patient is InfoManEnabled { // Agree levels: // 0 - no permissions // 1 - addr, being a hcp, can propound prescribed things to sender // 2 - addr, being a doctor, can prescribe things for sender // 3 - addr, being a doctor, can add sender as patient with a ehr function setAgree(address patAddr, address addr, uint8 agreeCode) returns (bool success) { if (!isInfoMan()) { return false; } address permissionsdb = CProvider(CMC).contracts("permsdb"); if (permissionsdb == 0x0) { return false; } success = PermsDb(permissionsdb).setAgree(patAddr, addr, agreeCode); return success; } function setEhrAgree(address patAddr, address docAddr, bytes32 ehr) returns (bool res) { if (!isInfoMan()) { return false; } address permissionsdb = CProvider(CMC).contracts("permsdb"); if (permissionsdb == 0x0) { return false; } res = PermsDb(permissionsdb).setEhrAgree(patAddr, docAddr, ehr); return res; } } contract Doctor is InfoManEnabled { function addPatient(address docAddr, address patAddr, bytes32 ehr) returns (bool res) { if (!isInfoMan()) { return false; } address pInfodb = CProvider(CMC).contracts("pinfodb"); if (pInfodb == 0x0) { msg.sender.send(msg.value); return false; } bool success = PInfoDb(pInfodb).addPatient(docAddr, patAddr, ehr); if (!success) { msg.sender.send(msg.value); } return success; } function addEHR(address docAddr, address patAddr, bytes32 ehr) returns (bool res) { if (!isInfoMan()) { return false; } address pInfodb = CProvider(CMC).contracts("pinfodb"); if (pInfodb == 0x0) { msg.sender.send(msg.value); return false; } uint result = PInfoDb(pInfodb).addEHR(docAddr, patAddr, ehr); if (result == 0 || result == 1) { return false; } else if (result == 2) { return true; } else { return false; } } function checkEhrAgree(address patAddr, address docAddr, bytes32 ehr) returns (bool) { if (!isInfoMan()) { return false; } address perms = CProvider(CMC).contracts("perms"); if (perms == 0x0) { msg.sender.send(msg.value); return false; } bool success = Perms(perms).checkEhrAgree(patAddr, docAddr, ehr); if (!success) { msg.sender.send(msg.value); } return success; } function isPatient(address patAddr) returns (bool) { if (!isInfoMan()) { return false; } address patientinfodb = CProvider(CMC).contracts("pinfodb"); if (patientinfodb == 0x0) { return false; } return PInfoDb(patientinfodb).isPatient(patAddr); } } contract HCP is InfoManEnabled { function providing(address patAddr, bytes32 ehr) returns (uint256 res) { } }
0.4.18