El presente artículo se enfoca en solucionar uno de los grandes problemas de la sociedad en cuanto a la oferta ilegal y falsificación de medicamentos en el mercado. Este proyecto se creó utilizando contratos inteligentes de Ethereum para reducir el suministro de drogas ilegalmente. Este proyecto rastrea el ciclo de la medicina desde las materias primas utilizadas hasta las manos de los consumidores. En cada paso del ciclo del medicamento se realiza un seguimiento del estado del medicamento. Analicemos el proyecto en detalle con todo el código fuente.
Planteamiento del problema: Resolver los problemas relacionados con el suministro ilegal y la falsificación de medicamentos en el mercado.
Casos de uso:
- Se puede usar para rastrear las vacunas para covid-19.
- Se puede utilizar para rastrear la transferencia internacional de medicamentos.
- Se puede utilizar para realizar un seguimiento del rendimiento de los medicamentos en el mercado.
Características:
- Cree una materia prima y siga su progreso.
- Ver las materias primas creadas anteriormente.
- Crea un medicamento utilizando las materias primas creadas.
- Lleve un registro del medicamento que se exporta.
- Distribuir el medicamento a los minoristas.
- Actualizar el estado del medicamento (vendido, vencido, dañado, no recibido, etc.)
- realizar un seguimiento del ciclo de medicamentos en cada paso del camino.
Roles y contratos inteligentes
Administración:
- Da de alta un nuevo usuario (Proveedor, Transportista, Fabricante, Distribuidor, Minorista).
- Reasignar roles a usuarios existentes.
- Revocar roles de usuarios existentes.
- realizar un seguimiento de los usuarios.
A continuación se muestra el código de solidez para el rol de usuario anterior:
Solidity
// Solidity program to implement // the above approach pragma solidity >=0.5.0 <0.8.6; contract Admin { address public owner; constructor() public { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "sorry!, Only owner is allowed to visit!"); _; } enum roles { norole, supplier, transporter, manufacturer, distributor, retailer, revoke } // Events are triggered at every step of way. event UserRegister(address indexed EthAddress, string Name); event UserRoleRevoked(address indexed EthAddress, string Name, uint Role); event UserRoleRessign(address indexed EthAddress, string Name, uint Role); struct UserInfo { string name; string location; address ethAddress; roles role; } mapping(address => UserInfo) public UsersDetails; address[] users; function registerUser( address EthAddress, string memory Name, string memory Location, uint Role) public onlyOwner { require(UsersDetails[EthAddress].role == roles.norole, "User Already registered"); UsersDetails[EthAddress].name = Name; UsersDetails[EthAddress].location = Location; UsersDetails[EthAddress].ethAddress = EthAddress; UsersDetails[EthAddress].role = roles(Role); users.push(EthAddress); emit UserRegister(EthAddress, Name); } function revokeRole(address userAddress) public onlyOwner { require(UsersDetails[userAddress].role != roles.norole, "user not registered"); emit UserRoleRevoked(userAddress, UsersDetails[userAddress].name, uint(UsersDetails[userAddress].role)); UsersDetails[userAddress].role = roles(6); } function reassignRole(address userAddress, uint Role) public onlyOwner { require(UsersDetails[userAddress].role != roles.norole, "User not registered"); UsersDetails[userAddress].role = roles(Role); emit UserRoleRessign(userAddress, UsersDetails[userAddress].name, uint(UsersDetails[userAddress].role)); } /***User Section***/ function getUserInfo(address userAddress) public view returns(string memory, string memory, address, uint) { return ( UsersDetails[userAddress].name, UsersDetails[userAddress].location, UsersDetails[userAddress].ethAddress, uint(UsersDetails[userAddress].role) ); } function getUsersCount() public view returns(uint count) { return users.length; } function getUserByIndex(uint index) public view returns(string memory, string memory, address,uint) { return getUserInfo(users[index]); } function getRole(address _address) public view returns(uint) { return uint(UsersDetails[_address].role); } }
Proveedor
- Crea una nueva materia prima.
- Realiza un seguimiento de las materias primas creadas previamente.
A continuación se muestra el programa solidity para implementar el rol de usuario anterior:
Solidity
// Solidity program to implement // the above approach pragma solidity >=0.5.0 <0.8.6; import "./Admin.sol"; import "./RawMaterial.sol"; contract Supplier { address admin; constructor(address _admin) public { admin=_admin; } enum roles { norole, supplier, transporter, manufacturer, distributor, retailer, revoke } mapping(address => address[]) supplierRawProductInfo; event RawSupplyInit( address indexed productId, address indexed supplier, address shipper, address indexed receiver ); function createRawPackage( string memory _description, string memory _ownerName, string memory _location, uint256 _quantity, address _shipper, address _manufacturer ) public { require(roles(Admin(admin).getRole(msg.sender)) == roles.supplier, "Only supplier can create a package!"); RawMaterial rawData = new RawMaterial( msg.sender, _description, _ownerName, _location, _quantity, _shipper, _manufacturer ); supplierRawProductInfo[msg.sender].push(address(rawData)); emit RawSupplyInit(address(rawData), msg.sender, _shipper, _manufacturer); } function getPackageCountSupplier(address _supplier) public view returns(uint) { require(roles(Admin(admin).getRole(_supplier)) == roles.supplier, "Only supplier can get a package!"); return supplierRawProductInfo[_supplier].length; } function getPackageIdByIndexSupplier(uint index, address _supplier) public view returns(address) { require(roles(Admin(admin).getRole(_supplier)) == roles.supplier, "Only supplier can call this function!"); return supplierRawProductInfo[_supplier][index]; } }
Fabricante
- Utiliza la materia prima recibida para crear nuevos medicamentos.
- Registra el nuevo medicamento.
- Exporta el nuevo medicamento al distribuidor.
- Realiza un seguimiento de los medicamentos existentes.
A continuación se muestra el programa solidity para implementar el rol de usuario anterior:
Solidity
// Solidity program to implement // the above approach mapping(address => address[]) RawPackagesAtManufacturer; mapping(address => string) Hash; mapping(address => address[]) ManufacturedMedicine; event MedicineNewBatch( address indexed BatchId, address indexed Manufacturer, address shipper, address indexed Receiver ); function rawPackageReceived(address rawmaterialAddress) public { require(roles(Admin(admin).getRole(msg.sender)) == roles.manufacturer, "Only manufacturer can receive the packages"); RawMaterial(rawmaterialAddress).receivePackage(msg.sender); RawPackagesAtManufacturer[msg.sender].push(rawmaterialAddress); } function getPackagesCountManufacturer(address _manufacturer) public view returns(uint) { require(roles(Admin(admin).getRole(_manufacturer)) == roles.manufacturer, "Only Manufacturer is allowed to call this"); return RawPackagesAtManufacturer[_manufacturer].length; } function getPackageIdByIndexManufacturer(uint index, address _manufacturer) public view returns(address) { require(roles(Admin(admin).getRole(_manufacturer)) == roles.manufacturer, "Only Manufacturer is allowed to call this"); return RawPackagesAtManufacturer[_manufacturer][index]; } function manufactureMedicine( string memory _description, address _rawmaterial, uint _quantity, address _shipper, address _distributor ) public { require(roles(Admin(admin).getRole(msg.sender)) == roles.manufacturer, "Only Manufacturer is allowed to call this"); Medicine newMedicine = new Medicine( msg.sender, _description, _rawmaterial, _quantity, _shipper, _distributor ); ManufacturedMedicine[msg.sender].push(address(newMedicine)); emit MedicineNewBatch(address(newMedicine), msg.sender, _shipper, _distributor); } function getManufacturedMedicineCountManufacturer(address _manufacturer) public view returns(uint) { require(roles(Admin(admin).getRole(_manufacturer)) == roles.manufacturer, "Only Manufacturer is allowed to call this"); return ManufacturedMedicine[_manufacturer].length; } function getManufacturedMedicineIdByIndexManufacturer(uint index, address _manufacturer) public view returns(address) { require(roles(Admin(admin).getRole(_manufacturer)) == roles.manufacturer, "Only Manufacturer is allowed to call this"); return ManufacturedMedicine[_manufacturer][index]; } function setHash(string memory _hash) public { Hash[msg.sender] = _hash; } function getHash() public view returns(string memory) { return Hash[msg.sender]; }
Distribuidor
- Reciba el medicamento del fabricante.
- Distribuye el medicamento a los minoristas.
- Realiza un seguimiento de la medicina distribuida.
A continuación se muestra el programa solidity para implementar el rol de usuario anterior:
Solidity
// Solidity program to implement // the above approach mapping(address=>address[]) MedicineBatchRetailer; enum salestatus { notfound, atretailer, sold, expire, damaged } mapping(address=>salestatus) sale; event MedicineStatus( address BatchID, address indexed Retailer, uint status ); function medicineReceivedAtRetailer(address _batchId, address _distributorAddress) public { require(roles(Admin(admin).getRole(msg.sender)) == roles.retailer, "Only retailer can access this function"); Distributor(_distributorAddress).receivePackageRetailer(_batchId, msg.sender); MedicineBatchRetailer[msg.sender].push(_batchId); sale[_batchId] = salestatus(1); } function updateSaleStatus( address _batchId, uint _status ) public { require(roles(Admin(admin).getRole(msg.sender)) == roles.retailer, "Only retailer can update status!"); require(sale[_batchId] == salestatus.atretailer, "Medicine is not at retailer"); sale[_batchId]=salestatus(_status); emit MedicineStatus(_batchId, msg.sender, _status); } function salesInfo(address _batchId) public view returns(uint) { return uint(sale[_batchId]); } function getBatchesCountRetailer(address _retailer) public view returns(uint){ require(roles(Admin(admin).getRole(_retailer)) == roles.retailer, "Only retailer can call this function!"); return MedicineBatchRetailer[_retailer].length; } function getBatchedIdByIndexRetailer(uint index, address _retailer) public view returns(address){ require(roles(Admin(admin).getRole(_retailer)) == roles.retailer, "Only retailer can call this function!"); return MedicineBatchRetailer[_retailer][index]; } }
Detallista
- Recibe el medicamento del distribuidor.
- Vende la medicina.
- Actualiza el estado del medicamento.
- Realiza un seguimiento de la medicina vendida.
A continuación se muestra el programa solidity para implementar el rol de usuario anterior:
Solidity
// Solidity program to implement // the above approach pragma solidity >=0.5.0 <0.8.6; contract Admin { address public owner; constructor() public { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "sorry!, Only owner is allowed to visit!"); _; } enum roles { norole, supplier, transporter, manufacturer, distributor, retailer, revoke } // Events are triggered at every step of way. event UserRegister(address indexed EthAddress, string Name); event UserRoleRevoked(address indexed EthAddress, string Name, uint Role); event UserRoleRessign(address indexed EthAddress, string Name, uint Role); struct UserInfo { string name; string location; address ethAddress; roles role; } mapping(address => UserInfo) public UsersDetails; address[] users; function registerUser( address EthAddress, string memory Name, string memory Location, uint Role) public onlyOwner { require(UsersDetails[EthAddress].role == roles.norole, "User Already registered"); UsersDetails[EthAddress].name = Name; UsersDetails[EthAddress].location = Location; UsersDetails[EthAddress].ethAddress = EthAddress; UsersDetails[EthAddress].role = roles(Role); users.push(EthAddress); emit UserRegister(EthAddress, Name); } function revokeRole(address userAddress) public onlyOwner { require(UsersDetails[userAddress].role != roles.norole, "user not registered"); emit UserRoleRevoked(userAddress, UsersDetails[userAddress].name, uint(UsersDetails[userAddress].role)); UsersDetails[userAddress].role = roles(6); } function reassignRole(address userAddress, uint Role) public onlyOwner { require(UsersDetails[userAddress].role != roles.norole, "User not registered"); UsersDetails[userAddress].role = roles(Role); emit UserRoleRessign(userAddress, UsersDetails[userAddress].name, uint(UsersDetails[userAddress].role)); } /***User Section***/ function getUserInfo(address userAddress) public view returns(string memory, string memory, address, uint) { return ( UsersDetails[userAddress].name, UsersDetails[userAddress].location, UsersDetails[userAddress].ethAddress, uint(UsersDetails[userAddress].role) ); } function getUsersCount() public view returns(uint count) { return users.length; } function getUserByIndex(uint index) public view returns(string memory, string memory, address,uint) { return getUserInfo(users[index]); } function getRole(address _address) public view returns(uint) { return uint(UsersDetails[_address].role); } }
transportador
- Transporta el medicamento del proveedor al fabricante.
- Transporta el medicamento desde el fabricante hasta el distribuidor.
- Transporta el medicamento del distribuidor al minorista.
A continuación se muestra el programa solidity para implementar el rol de usuario anterior:
Solidity
// Solidity program to implement // the above approach pragma solidity >=0.5.0 <0.8.6; import "./Admin.sol"; import "./RawMaterial.sol"; import "./Medicine.sol"; import "./Distributor.sol"; contract Transporter { enum roles{ norole, supplier, transporter, manufacturer, distributor, retailer, revoke } address admin; constructor(address _admin) public { admin = _admin; } function loadConsignment( address batchId, uint transporterType, address distributorId ) public { require(roles(Admin(admin).getRole(msg.sender)) == roles.transporter, "Only transporter can call this function."); require(transporterType > 0, "Transporter type undefined"); if(transporterType == 1) { RawMaterial(batchId).pickPackage(msg.sender); } else if(transporterType == 2) { Medicine(batchId).pickPackageDistributor(msg.sender); } else if(transporterType == 3) { Distributor(distributorId).pickPackageForRetailer(batchId, msg.sender); } } }
Producción:
Consulte este video para obtener más detalles sobre el flujo del proyecto
https://www.geeksforgeeks.org/videos/medical-chain-project/
Se puede acceder al código fuente del proyecto desde aquí .
Publicación traducida automáticamente
Artículo escrito por aaryanmahendra22835 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA