Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
nabheetscn
Active Contributor

Motivation for this Proof of Concept


The idea for doing this proof of concept came because of a real life problem which i have gone through in the past(will not delve to much in those details). God forbid, imagine if  one or many of critical organs does not work properly then doctor advise the patient for a transplant. In India he/she can get the transplant done either from a donor from the family or from people who are declared as brain dead and their family is willing to donate the organs.

Just to summarize as the title suggest this Proof of Concept(POC) is to help all those people who are looking for Organs to be transplanted across states & country(if countries agree).. As of now in India all the hospitals are using different softwares which only communicate maximum within their organization only, their is a strong disconnect between them. Few years back,I myself was looking for a Liver for one of my family member and trust me there is nothing available. Even within hospitals of same organization there is  preference given to people who can still wait over the critical ones.

This is where i believe the idea of bringing all hospital on to a network which is transparent and trustworthy came. So this POC will cover setting up of BlockChain as a backend and then making a frontend app using OpenUI5. In this part of the blog we will cover how do we set up the backend using Hyperledger Fabric Technology as a service which implements BlockChain using SAP Cloud Platform and in next we will create the app.


Image Courtesy Mainpal Hospital



What will this POC do?


Since this a POC only, we will have two type of requests which our BlockChain created via Hyperledger Fabric  will entertain.

  • Adding  organ available for transplant to BlockChain - Pos request

  • Different type of Organ available across different organization - Query


 

Just to highlight here for people who want to try out BlockChain as a service, I would recommend them to first understand the basics of Hyperledger Fabric  then only it will make more sense to them, this documentation of hyperledger covers the basics in detail. After that i will recommend you completely read in detail the SAP Help for Hyperledger.

Creating a BlockChain Instance.


We will be using SAP Cloud platform HyperLedger Fabric as a service to create the instance as highlighted in the this blog by akashkumar1987 . Since we are using cloud service it creates network with below mentioned details.




Creating a Channel


Once we have created the instance for Blockchain in previous step, next step was to create a Channel which binds the peer and the corresponding organizations.  We will generate the keys for the channel which we will use in our OpenUI5 to access the chaincode API’s. Chaincode is something which interacts with the blockchain,contains the business logic and provide API access to interact with the BlockChain, details covered in next section.


Creating the Chaincode.


Once we have the Channel created in previous step, next step was to deploy our business logic and ability to access it via API which is nothing but our chaincode.  Two important documents which helped me in understanding about Channels and go shall must be gone through SAP Help for ChainCode and Hyperledger Sample Chaincode

The chain code consist of three parts as mentioned below.

  • One is the name of the application


Id:       com-sap-icn-blockchain-organTrans9
Version: 2


  • Second is the structure of API to be exposed in YAML format, this basically defines for what path which function or business logic will be called.


swagger: "2.0"


info:
description: "Organ Transplant using OpenUI5 and BlockChain"
version: "1.0"
title: "Organ Transplant using OpenUI5 and BlockChain"


consumes:
- application/x-www-form-urlencoded
produces:
- application/json


parameters:

OrganType:
name: OrganType
in: path
description: Type of Organ for Transplant
required: true
type: string
maxLength: 255

BloodGroup:
name: BloodGroup
in: formData
description: Bloodgroup
required: true
type: string
maxLength: 255

Hospital:
name: Hospital
in: formData
description: Hospital Name
required: true
type: string
maxLength: 255

City:
name: City
in: formData
description: City
required: true
type: string
maxLength: 255

State:
name: State
in: formData
description: State
required: true
type: string
maxLength: 255

paths:

/{OrganType}:


get:
operationId: organsByType
summary: Get list of Organs available for Transplant by organ type
parameters:
- $ref: '#/parameters/OrganType'
responses:
200:
description: OK
schema:
type: object
properties:
values:
type: array
items:
type: object
properties:
OrganType:
type: string
Hospital:
type: string
City :
type: string
State:
type: string
400:
description: Mismatch
404:
description: Not Found

post:
operationId: initorgan
summary: Post an organ available for Transplant
parameters:
- $ref: '#/parameters/OrganType'
- $ref: '#/parameters/BloodGroup'
- $ref: '#/parameters/Hospital'
- $ref: '#/parameters/City'
- $ref: '#/parameters/State'

responses:
200:
description: Organ for Transplant updated
201:
description: Organ for Transplant updated
400:
description: Mismatch
409:
description: Organ already posted.


  • Third is basically the GO file which contain our two functions for Posting and reading the organs data.


package main

import (
"bytes"
"encoding/json"
"fmt"
"strings"
"time"

"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
)
var logger = shim.NewLogger("chaincode")
type OrganDonorChainCode struct {
}

type organ struct {
OrganType string `json:"organType"`
BloodGroup string `json:"BloodGroup"`
Hospital string `json:"Hospital"`
City string `json:"City"`
State string `json:"State"`
}
// start of program
func main() {
err := shim.Start(new(OrganDonorChainCode))
if err != nil {
fmt.Printf("Error Occured: %s", err)
}
}
// Start a chaincode.
func (t *OrganDonorChainCode) Init(stub shim.ChaincodeStubInterface) pb.Response {
return shim.Success(nil)
}
// Decode incoming request and call relevant methods.
func (t *OrganDonorChainCode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
function, args := stub.GetFunctionAndParameters()
switch function {
// Creating a new organ
case "initorgan":
return t.initorgan(stub, args)

// Get list of organs by type of organ
case "organsByType":
return t.organsByType(stub, args)
default:
return shim.Error("error occured ")
}
}
// FM to add the entry for the available organ
func (t *OrganDonorChainCode) initorgan(stub shim.ChaincodeStubInterface, args []string) pb.Response {
var err error
// key as combination of time and input aruments
organBloodGroup := args[0] + args[1] + args[2] + args[3] + args[4] + time.Now().UTC().String()
organBloodGroup1 := args[1]
Hospital := strings.ToLower(args[2])
State := strings.ToLower(args[4])
City := strings.ToLower(args[3])


// check if by chance any entry exists
organAsBytes, err := stub.GetState(organBloodGroup)
if err != nil {
return shim.Error("error occure " + err.Error())
} else if organAsBytes != nil {
fmt.Println("organ exists " + organBloodGroup)
return shim.Error("organ exists " + organBloodGroup)
}

// create organ as json
OrganType := args[0]
organ := &organ{OrganType, organBloodGroup1, Hospital, City, State}
logger.Errorf("Data %d ", organ)
organJSONasBytes, err := json.Marshal(organ)
if err != nil {
return shim.Error(err.Error())
}

// save organ to blockchain
err = stub.PutState(organBloodGroup, organJSONasBytes)
if err != nil {
return shim.Error(err.Error())
}

return shim.Success(nil)
}


func (t *OrganDonorChainCode) organsByType(stub shim.ChaincodeStubInterface, args []string) pb.Response {


Organ := args[0]

queryString := fmt.Sprintf("{\"selector\":{\"organType\":\"%s\"}}", Organ)
logger.Errorf("QueryString %d ", queryString)
queryResults, err := getQueryResultForQueryString(stub, queryString)
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(queryResults)
}
// =========================================================================================
// getQueryResultForQueryString executes the passed in query string.
// Result set is built and returned as a byte array containing the JSON results.
// =========================================================================================
func getQueryResultForQueryString(stub shim.ChaincodeStubInterface, queryString string) ([]byte, error) {

fmt.Printf("- getQueryResultForQueryString queryString:\n%s\n", queryString)

resultsIterator, err := stub.GetQueryResult(queryString)
if err != nil {
return nil, err
}
defer resultsIterator.Close()

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

bArrayMemberAlreadyWritten := false
for resultsIterator.HasNext() {
queryResponse, err := resultsIterator.Next()
if err != nil {
return nil, err
}
// 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("- getQueryResultForQueryString queryResult:\n%s\n", buffer.String())

return buffer.Bytes(), nil
}


Swagger Testing


This is another thing which i learnt recently. how you can define the structure of your api and then you can generate client libraries for different languages of your choice including testing etc.  more details are available here . We have tested our code for basic Creating organ availability requests and searching for which organ is available for transplant where as  highlighted in screenshot.





BlockChain Explorer shows you the stored content also.


Next Steps


Next steps are very important to enhance my understanding of the blockchain concepts and build a full fledge application after the successful POC.

  • In next part of the series we will be developing Frontend for the POC using OpenUI5 and exploring other features

  • Once POC is completed, then plan is to bring in all the features so that it can serve as single platform for organ transplant donors and receivers and many other purposes.


Last but not the list working on such POC’s bring together load many ideas to be tried and shared. Looking forward for your feedback and idea, open to all ears. 

 
3 Comments
Labels in this area