1

I am a little bit confused here and although I have searched a lot on this, something is clearly missing from my knowledge and I am asking your help.

I have created a Hyperledger Fabric Network and installed a chaincode in it. And I want to make a function that retrieves all the World State inputs about the Keys. I have done it already with the bytes.Buffer and it worked. But what I want to do is to do it with a struct.

So, I created the following struct that has only the key:

type WSKeys struct {
    Key             string `json: "key"`
    Namespace       string `json: "Namespace"`
}

And this is my code function:

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

    var keyArrayStr []WSKeys

    resultsIterator, err := APIstub.GetQueryResult("{\"selector\":{\"_id\":{\"$ne\": null }} }")
    if err != nil {
        return shim.Error("Error occured when trying to fetch data: "+err.Error())
    }

    for resultsIterator.HasNext()  {
        // Get the next record
        queryResponse, err := resultsIterator.Next()
        if err != nil {
            return shim.Error(err.Error())
        }
        fmt.Println(queryResponse)

        var qry_key_json WSKeys
        
        json.Unmarshal([]byte(queryResponse), &qry_key_json)
        
        keyArray = append(keyArray, qry_key_json)

    }
    defer resultsIterator.Close()

    all_bytes, _ := json.Marshal(keyArray)
    fmt.Println(keyArray)
    return shim.Success(all_bytes)
}

When executing the above I get the following error:

cannot convert queryResponse (type *queryresult.KV) to type []byte

I can get the results correctly if I, for example do this:

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

    var keyArray []string

    resultsIterator, err := APIstub.GetQueryResult("{\"selector\":{\"_id\":{\"$ne\": null }} }")
    if err != nil {
        return shim.Error("Error occured when trying to fetch data: "+err.Error())
    }

    for resultsIterator.HasNext()  {
        // Get the next record
        queryResponse, err := resultsIterator.Next()
        if err != nil {
            return shim.Error(err.Error())
        }
        fmt.Println(queryResponse)
        
        
        keyArray = append(keyArray, queryResponse.Key)

    }
    defer resultsIterator.Close()

    all_bytes, _ := json.Marshal(keyArray)
    fmt.Println(keyArray)
    return shim.Success(all_bytes)
}

But, why I get the above error when trying to add the queryResponse into a custom struct? Do I need to add it to a struct that is only its type?

Please someone can explain what I am missing here?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Rafail K.
  • 365
  • 3
  • 14
  • 1
    `type *queryresult.KV` is a type struct as indicated in https://pkg.go.dev/github.com/hyperledger/fabric-protos-go/ledger/queryresult#KV , you cannot peform `[]byte()` on a struct type – Inian Oct 29 '21 at 11:56
  • Did you intend to do `json.Unmarshal([]byte(queryResponse.Key), &qry_key_json)` ? – Inian Oct 29 '21 at 11:57
  • Yes, I did that and it works. But I want to know how can I unmarshal the whole structure. Is this even possible? Or not – Rafail K. Oct 29 '21 at 12:02
  • What do you mean the whole structure? your destination struct `WSKeys` has only field for storing `Keys`. If you have more fields in your JSON, I suggest defining the appropriate struct and unmarshal into it – Inian Oct 29 '21 at 12:05
  • I edited the struct and added one more field. Now lets say that I want to unmarshal the response in the struct with the two fields. I get the same error. Do I have to define a variable with the KV struct in order to be correct? Or, can I do this with my custom struct? – Rafail K. Oct 29 '21 at 12:09
  • With your current code, its impossible to test and provide a solution. Do you have a playground link that this can be uploaded? – Inian Oct 29 '21 at 12:10
  • No, I don't have a playground. :/ – Rafail K. Oct 29 '21 at 12:12
  • Look at https://github.com/hyperledger/fabric-protos-go/blob/main/ledger/queryresult/kv_query_result.pb.go to get more idea on this – Inian Oct 29 '21 at 12:17
  • 1
    Okay great, I will keep looking. You gave some ideas. Thanks for your time! – Rafail K. Oct 29 '21 at 12:18

1 Answers1

1

The error statement is verbose enough to indicate, that your []byte conversion failed for the type queryResponse which, with a bit of lookup seems to be a struct type. In Go you cannot natively convert a struct instance to its constituent bytes without encoding using gob or other means.

Perhaps your intention was to use the Key record in the struct for un-marshalling

json.Unmarshal([]byte(queryResponse.Key), &qry_key_json)
Inian
  • 80,270
  • 14
  • 142
  • 161