Fabric chaincode error when trying to query the database through a partial Composite Key #fabric-questions #fabric-chaincode


jonashiltl2003@...
 

Hi Community,
this is my first time deploying chaincode to a fabric network and I'm fairely new to golang. 
Right now I'm trying to create a system where a patient can create a permission for a doctor to access the patients files. Just a basic EHR system.
This is the struct of the permission asset:

type Permission struct {
    PermissionId    string `json:"permissionId"` // doctorId + dataCategory + patientId
    DataCategory    string `json:"dataCategory"`
    PatientId       string `json:"patientId"`
    DoctorId        string `json:"doctorId"`
    Right           string `json:"right"` // read/write
    From            string `json:"from"`
    To              string `json:"to"`
}
peer chaincode query -C mychannel -n permissions -c '{"Args":["ListDoctorPermissions", "doctor1"]}'

In the process of deploying the chaincode I run a query at the end to test if the chaincode is working but I get this error:

Error: endorsement failure during query. response: status:500 message:"Error handling success response. Value did not match schema:\n1. return: Invalid type. Expected: array, given: string" 

Here is my chaincode file and I use the function "ListDoctorPermissions" to display all permissions given to a doctor by all patients. When creating the permission a composite key is being created, consisting of the patientId the doctorId and the dataCategory.
For retrieving all the permissions given to a doctor I use the "GetStateByPartialCompositeKey" function and iterate over the response. At the end I want to append all the permissions to an array and return that array.

Here is the addressed function (you can also visit the github link):
func (s *SmartContract) ListDoctorPermissions(ctx contractapi.TransactionContextInterface, doctorId string) ([]byte, error) {
    doctorIterator, err := ctx.GetStub().GetStateByPartialCompositeKey("permissionId", []string{doctorId})
    if err != nil {
        return nil, err
    }
    fmt.Printf("the doctor Iterator is: %s", doctorIterator)

    defer doctorIterator.Close()

    var dataCategory string
    var patientId string
    var permissionId string

    var permissions []byte
    bArrayPermissionAlreadyWritten := false

    for doctorIterator.HasNext() {
        responseRange, err := doctorIterator.Next()
        if err != nil {
            return nil, err
        }

        objectType, compositeKeyParts, err := ctx.GetStub().SplitCompositeKey(responseRange.Key)
        if err != nil {
            return nil, err
        }
        fmt.Printf("the objectType is: %s", objectType)

        dataCategory = compositeKeyParts[1]
        patientId = compositeKeyParts[2]
        permissionId = doctorId + dataCategory + patientId
        fmt.Printf("the compositeKeyParts are: %s", compositeKeyParts[0], compositeKeyParts[1], compositeKeyParts[2])

        permissionAsBytes, err := ctx.GetStub().GetState(permissionId)
        if err != nil {
            return nil, err
        }

        if bArrayPermissionAlreadyWritten == true {
            newBytes := append([]byte(","), permissionAsBytes...)
            permissions = append(permissions, newBytes...)
        } else {
            permissions = append(permissions, permissionAsBytes...)
            fmt.Print(permissions)
        }

        fmt.Printf("Found a asset for index : %s asset id : ", objectType, compositeKeyParts[0], compositeKeyParts[1], compositeKeyParts[2])
        bArrayPermissionAlreadyWritten = true

    }

    permissions = append(permissions, []byte("]")...)
    fmt.Print(permissions)
    return permissions, nil
}

I laso published this question on Stackoverflow for clearer code samples: Stackoverflow
I hope that my explanation isn't too complicated and thanks for your efforts!


Matthew White
 

Thanks - Andy Hurt has replied to the comment on stack overflow.

Matthew White