[V9.0.4 Oct 2017]

Message formats for the IBM MQ Bridge to blockchain

Information on formatting of the messages that are sent and received by the IBM® MQ Bridge to blockchain.

An application requests that the IBM MQ Bridge to blockchain performs a query or update of information that is held on the blockchain. The application does this by placing a request message on the bridge request queue. The results of the query or the update are formatted by the bridge into a reply message. The bridge uses information that is contained in the ReplyToQ and ReplyToQMgr fields from the MQMD of the request message as the destination for the reply message.

The messages that are consumed and produced by the bridge are text (MQSTR) messages in JSON format. The input message is a simple JSON and programs can use string concatenation to generate it. All the fields except args are required, the argument list for that field requires knowledge of the functions of the stored chaincode.

Request Message Format

Input message format:

{ "function": functionName,
    "channel" : chainName,
    "chaincodeName" : codeName,
    "args" : [argument list]
}
For the local hyperledger network example with the working Fabcar sample.
  • To use the query message that calls the queryAllCars function in the fabcar chaincode that returns a list of JSON objects that represent the car details that are held in the blockchain, format the message as follows:
    
    { "function": "queryAllCars",
        "channel":"mychannel",
        "chaincodeName": "fabcar",
        "args":[]
    }
    
    Example reply:
    {
       "statusCode": 200,
       "statusType": "SUCCESS",
       "message": "OK",
       "data": [
      {"Record":{"owner":"Tomoko","colour":"blue","model":"Prius","make":"Toyota"},"Key":"CAR0"}, 
      {"Record":{"owner":"Brad","colour":"red","model":"Mustang","make":"Ford"},"Key":"CAR1"}, 
      {"Record":{"owner":"Jin Soo","colour":"green","model":"Tucson","make":"Hyundai"},"Key":"CAR2"}, 
      {"Record":{"owner":"Max","colour":"yellow","model":"Passat","make":"Volkswagen"},"Key":"CAR3"}, 
      {"Record":{"owner":"Adriana","colour":"black","model":"S","make":"Tesla"},"Key":"CAR4"}, 
      {"Record":{"owner":"Michel","colour":"purple","model":"205","make":"Peugeot"},"Key":"CAR5"}, 
      {"Record":{"owner":"Aarav","colour":"white","model":"S22L","make":"Chery"},"Key":"CAR6"}, 
      {"Record":{"owner":"Pari","colour":"violet","model":"Punto","make":"Fiat"},"Key":"CAR7"}, 
      {"Record":{"owner":"Valeria","colour":"indigo","model":"Nano","make":"Tata"},"Key":"CAR8"}, 
      {"Record":{"owner":"Shotaro","colour":"brown","model":"Barina","make":"Holden"},"Key":"CAR9"}
    ]}
    The reply message contains all the car records that are currently held in the blockchain.
  • To use the update message that calls the createCar function in the fabcar example chaincode that creates a new car entry in the blockchain ledger, format the message as follows:
    
    { "function":"createCar",
      "channel":"mychannel",
      "chaincodeName":"fabcar",
      "args":["CAR10", "Ford", "Mustang GT", "Blue", "Bob"]
    }
    Example reply:
    {
       "statusCode": 200,
       "statusType": "SUCCESS",
       "message": "OK",
       "data": ""
    }
    To check that the new car entry is added to the blockchain, you can use the initial message again that returns all the cars.
For the Kubernetes cluster network example with the working example02 demo.
  • To use the query message that calls the query function in the example02 chaincode that returns the value for entity "a" within the blockchain ledger, format the message as follows:
    { "function":"query",
      "channel":"channel1",
      "chaincodeName":"example02",
      "args":["a"]
    }
    Example reply:
    
    {
       "statusCode": 200,
       "statusType": "SUCCESS",
       "message": "OK",
       "data": "100"
    }
  • To use the message that calls the invoke function example02 chaincode that decrements the entity that is specified in the first argument and increments the entity that is specified in the second argument by the value that is specified in the third argument, format the message as follows:
    { "function":"invoke",
      "channel":"channel1",
      "chaincodeName":"example02",
      "args":["a", "b", "10"]
    }
    The values are as follows:
    • Before: a=100, b=200
    • After: a=90, b=210
    Example reply:
    {
       "statusCode": 200,
       "statusType": "SUCCESS",
       "message": "OK",
       "data": ""
    }
    To check the new values, submit a new message query message to look for values of "a" and "b".

Reply Message Format

Response messages have their correlation ID set to the message ID of the inbound message. Any user-defined properties are copied from the input to the output messages. The user ID in the reply is set to the originator's user ID through the set-identity context.

An example of successful processing:
{ "data": "500", "message": "OK", "statusCode": 200, "statusType": "SUCCESS" }
The response data in this message is whatever is generated from the chaincode response (bytes converted to a UTF-8 string).
All error responses have the same fields, regardless of whether they are generated by the bridge itself, from the calls to blockchain, or from the chaincode invocation. For example:
  • Bad channel name
    
    {
       "message": "Bad newest block expected status 200 got 404, Chain myUnknownChannel",
       "statusCode": 404,
       "statusType": "FAILURE"
    }
    
  • Bad JSON input message
    
    {
       "message": "Error: Cannot parse message contents.",
       "statusCode": 2110,
       "statusType": "FAILURE"
    }
    
  • Incorrect parameters to chaincode
    
    {
       "message": "Sending proposal to fabric-peer-1a failed because of gRPC failure=Status{code=UNKNOWN, description={\"Error\":\"Nil amount for c\"}, cause=null}",
       "statusCode": 500,
       "statusType": "FAILURE"
    }
    
Applications can tell whether the request succeeded or failed by either looking at the statusType string, or from the existence of the data field. When there is an error in processing the input message, and the bridge does not send it to blockchain, the value that is returned from the bridge is an MQRC value, usually MQRC_FORMAT_ERROR.