Wednesday, 28 February 2018

Patient Medical Data on Hyper-ledger Fabric block chain using go and node.js - Sandeep Kanao

Patient Medical Data smart contract on Hyper-ledger Fabric block chain using go and node.js - Sandeep Kanao


Chaincode - smart contract

/*
 * The smart contract for documentation topic:
 * Writing healthdata smart contract
 */

package main

/* Imports
 * 4 utility libraries for formatting, handling bytes, reading and writing JSON, and string manipulation
 * 2 specific Hyperledger Fabric specific libraries for Smart Contracts
 */
import (
 "bytes"
 "encoding/json"
 "fmt"
 "strconv"

 "github.com/hyperledger/fabric/core/chaincode/shim"
 sc "github.com/hyperledger/fabric/protos/peer"
)

// Define the Smart Contract structure
type SmartContract struct {
}

// Define the patient structure, with  properties.  Structure tags are used by encoding/json library
type Patient struct {
 Name  string `json:"name"`
 Address  string  `json:"address"`
     DOB      string `json:"dob"` 
 BloodGroup   string `json:"bloodgroup"`
 DoctorID  string `json:"doctorid"`
 TreatmentDate   string `json:"treatmentdate"`
 Medicine string  `json:"medicine"`
}

/*
 * The Init method is called when the Smart Contract "healthdata" is instantiated by the blockchain network
 * Best practice is to have any Ledger initialization in separate function -- see initLedger()
 */
func (s *SmartContract) Init(APIstub shim.ChaincodeStubInterface) sc.Response {
 return shim.Success(nil)
}

/*
 * The Invoke method is called as a result of an application request to run the Smart Contract "healthdata"
 * The calling application program has also specified the particular smart contract function to be called, with arguments
 */
func (s *SmartContract) Invoke(APIstub shim.ChaincodeStubInterface) sc.Response {

 // Retrieve the requested Smart Contract function and arguments
 function, args := APIstub.GetFunctionAndParameters()
 // Route to the appropriate handler function to interact with the ledger appropriately
 if function == "queryPatient" {
  return s.queryPatient(APIstub, args)
 } else if function == "initLedger" {
  return s.initLedger(APIstub)
 } else if function == "createPatient" {
  return s.createPatient(APIstub, args)
 } else if function == "queryAllPatients" {
  return s.queryAllPatients(APIstub)
 } else if function == "changeDoctorID" {
  return s.changeDoctorID(APIstub, args)
 }

 return shim.Error("Invalid Smart Contract function name.")
}

func (s *SmartContract) queryPatient(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {

 if len(args) != 1 {
  return shim.Error("Incorrect number of arguments. Expecting 1")
 }

 patientAsBytes, _ := APIstub.GetState(args[0])
 return shim.Success(patientAsBytes)
}

func (s *SmartContract) initLedger(APIstub shim.ChaincodeStubInterface) sc.Response {
 patients := []Patient{
 Patient {Name: "John", Address: "New York", DOB: "03-02-1967", BloodGroup : "A+", DoctorID: "1111", TreatmentDate : "01-12-2018", Medicine : "Tynalol"},
Patient {Name: "Ken", Address: "New York", DOB: "06-02-1963", BloodGroup : "A+", DoctorID: "1112", TreatmentDate : "01-11-2018", Medicine : "Helix"},
Patient {Name: "Sam", Address: "New York", DOB: "06-02-1954", BloodGroup : "O", DoctorID: "1112", TreatmentDate : "02-11-2018", Medicine : "Benix"},
Patient {Name: "Kim", Address: "Toronto", DOB: "05-02-1933", BloodGroup : "O", DoctorID: "1113", TreatmentDate : "02-14-2018", Medicine : "Benix"},
Patient {Name: "Kit", Address: "New York", DOB: "06-02-1955", BloodGroup : "B-", DoctorID: "1112", TreatmentDate : "02-11-2018", Medicine : "Qrex"},
}



 i := 0
 for i < len(patients) {
  fmt.Println("i is ", i)
  patientAsBytes, _ := json.Marshal(patients[i])
  APIstub.PutState("PATIENT"+strconv.Itoa(i), patientAsBytes)
  fmt.Println("Added", patients[i])
  i = i + 1
 }

 return shim.Success(nil)
}

func (s *SmartContract) createPatient(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {

 if len(args) != 7 {
  return shim.Error("Incorrect number of arguments. Expecting 7")
 }

 var patient = Patient{Name: args[1], Address: args[2], DOB: args[3], BloodGroup: args[4], DoctorID: args[5], TreatmentDate: args[6], Medicine: args[7]}

 patientAsBytes, _ := json.Marshal(patient)
 APIstub.PutState(args[0], patientAsBytes)

 return shim.Success(nil)
}

func (s *SmartContract) queryAllPatients(APIstub shim.ChaincodeStubInterface) sc.Response {

 startKey := "PATIENT1"
 endKey := "PATIENT22"

 resultsIterator, err := APIstub.GetStateByRange(startKey, endKey)
 if err != nil {
  return shim.Error(err.Error())
 }
 defer resultsIterator.Close()

 // buffer is a JSON array containing QueryResults
 var buffer bytes.Buffer
 buffer.WriteString("[")

 bArrayMemberAlreadyWritten := false
 for resultsIterator.HasNext() {
  queryResponse, err := resultsIterator.Next()
  if err != nil {
   return shim.Error(err.Error())
  }
  // Add a comma before array members, suppress it for the first array member
  if bArrayMemberAlreadyWritten == true {
   buffer.WriteString(",")
  }
  buffer.WriteString("{\"Key\":")
  buffer.WriteString("\"")
  buffer.WriteString(queryResponse.Key)
  buffer.WriteString("\"")

  buffer.WriteString(", \"Record\":")
  // Record is a JSON object, so we write as-is
  buffer.WriteString(string(queryResponse.Value))
  buffer.WriteString("}")
  bArrayMemberAlreadyWritten = true
 }
 buffer.WriteString("]")

 fmt.Printf("- queryAllPatients:\n%s\n", buffer.String())

 return shim.Success(buffer.Bytes())
}

func (s *SmartContract) changeDoctorID(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {

 if len(args) != 2 {
  return shim.Error("Incorrect number of arguments. Expecting 2")
 }

 patientAsBytes, _ := APIstub.GetState(args[0])
 patient := Patient{}

 json.Unmarshal(patientAsBytes, &patient)
 patient.DoctorID = args[5]

 patientAsBytes, _ = json.Marshal(patient)
 APIstub.PutState(args[0], patientAsBytes)

 return shim.Success(nil)
}

// The main function is only relevant in unit test mode. Only included here for completeness.
func main() {

 // Create a new Smart Contract
 err := shim.Start(new(SmartContract))
 if err != nil {
  fmt.Printf("Error creating new Smart Contract: %s", err)
 }
}



No comments:

Post a Comment