javascriptcouchdbhyperledger-fabrichyperledger-chaincodehyperledger-fabric-sdk-js

Cannot get response from getStateByPartialCompositeKey


I cannot obtain a response from the getStateByPartialCompositeKey method. I can use putState and getState just fine, but cannot use getStateByPartialCompositeKey. I'm using NodeJS fabric-contract-api version of Fabric's chaincode.

For the development, I used this commercial-paper example. This example uses the test-network environment, which is working just fine.

This implementation offers some ledger API utility classes that I'm using also to interact with the ledger. It has two classes, state.js and stateList.js I added a method to stateliest called getAllStatesFromPartialCompositeKey to try and use getStateByPartialCompositeKey method.

Package.json

{
  "name": "informed-consent-form-contract",
  "version": "0.0.5",
  "description": "Papernet Contract",
  "main": "index.js",
  "engines": {
    "node": ">=8",
    "npm": ">=5"
  },
  "scripts": {
    "lint": "eslint .",
    "pretest": "npm run lint",
    "test": "nyc mocha test --recursive",
    "start": "fabric-chaincode-node start",
    "mocha": "mocha test --recursive"
  },
  "engineStrict": true,
  "author": "hyperledger",
  "license": "Apache-2.0",
  "dependencies": {
    "axios": "^0.19.2",
    "fabric-contract-api": "^2.0.0",
    "fabric-shim": "^2.0.0",
    "node-fetch": "^2.6.0",
    "nodemon": "^2.0.2"
  },
  "devDependencies": {
    "chai": "^4.1.2",
    "chai-as-promised": "^7.1.1",
    "eslint": "^4.19.1",
    "mocha": "^5.2.0",
    "nyc": "^12.0.2",
    "sinon": "^6.0.0",
    "sinon-chai": "^3.2.0"
  },
  "nyc": {
    "exclude": [
      "coverage/**",
      "test/**"
    ],
    "reporter": [
      "text-summary",
      "html"
    ],
    "all": true,
    "check-coverage": true,
    "statements": 100,
    "branches": 100,
    "functions": 100,
    "lines": 100
  }
}

Contract.js snippet:

/**
 * 
 * @param {*} ctx 
 * @param {*} partialKey - Piece of key to serch
 */
async getAllStates(ctx, partialKey) {
  let result = await ctx.informedConsentFormStateList.getStatesFromPartialCompositeKey(partialKey);
  console.log('================ Result inside getAllStates method ================');
  console.log(result);
  return result;
} // fin func

Insinde informedConsentFormStateList.js:

```
async getStatesFromPartialCompositeKey(partialKey) {
        return this.getAllStatesFromPartialCompositeKey(partialKey);
    }
```

Inside the modified stateList.js:

/**
* @function getAllStatesFromPartialCompositeKey
*/
async getAllStatesFromPartialCompositeKey(partialArgument) {
  console.log('================ Called from beginning of getAllStatesFromPartialCompositeKey ================');
  console.log('================ name => ' + this.name);
  let key = this.ctx.stub.createCompositeKey(this.name, [partialArgument]);
  console.log('================ created partial key .....');
  console.log(partialArgument);
  console.log(key);
  let response = await this.ctx.stub.getStateByPartialCompositeKey(this.name, [key]); //.toString('utf8')
  console.log('================ response below ================');
  console.log(response);
  let results = await this.getAllResults(response);
  return results;
} // fin getAllStatesFromPartialCompositeKey

Here is how I invoke it:

/home/ubilab/fabric2/fabric-samples/test-network$ peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name informed_consent_9 --tls true --cafile $ORDERER_CA --peerAddresses localhost:7051 --tlsRootCertFiles $ORG1_CA -c '{"Args":["csacmpcc:getAllStates","P03"]}'

Response:

chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200 payload:"[]"

Chaincode container logs:

================ Called from beginning of getAllStatesFromPartialCompositeKey ================
================ name => org.csa.informedconsentformstatelist
================ created partial key .....
P03
org.csa.informedconsentformstatelistP03
================ Result inside getAllStates method ================
[]

Couchdb Stored state:

{
  "id": "\u0000org.csa.informedconsentformstatelist\u0000\"P03\"\u0000\"R68\"\u0000",
  "key": "\u0000org.csa.informedconsentformstatelist\u0000\"P03\"\u0000\"R68\"\u0000",
  "value": {
    "rev": "1-74db76a10ad8251ce2ba49ad58710ad8"
  },
  "doc": {
    "_id": "\u0000org.csa.informedconsentformstatelist\u0000\"P03\"\u0000\"R68\"\u0000",
    "_rev": "1-74db76a10ad8251ce2ba49ad58710ad8",
    "class": "org.csa.informedconsentform",
    "consentStatus": "1",
    "currentState": null,
    "key": "\"P03\":\"R68\"",
    "patientID": "P03",
    "reserachID": "R68",
    "sensors": "{numberOfSensors:1,sensors:[{sensorID:s01,name:SPO2,startDate:5/12/2020,endDate:5/12/2021}]}",
    "~version": "CgMBZQA="
  }
}

If you need more information to be able to help me please do not hesitate to ask :). Thanks!


Solution

  • Given you are querying with a single attribute, try using the partialKey variable directly instead of building a composite key.

    let response = await this.ctx.stub.getStateByPartialCompositeKey(this.name, [partialKey]);
    

    API docs