Home > OS >  Invoking a chaincode function inside a shell script
Invoking a chaincode function inside a shell script

Time:10-19

I have built a Hyperledger Fabric Network and the network is set up fine. The chaincode has also been deployed. Now, I want to call a function of the chaincode. If I have to do it via terminal, then it goes like:

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"StorePacketData","Args":["a0", "b0", "c0", "d0", "e0"]}'

This works perfectly fine. However, I want to call this function from a shell script where the arguments of the functions would be variables. This shell script file be called by another shell script. Hence, my shell script file looks like this:

#!/bin/bash

invokeCC() {

   arg1=$1
   arg2=$2
   arg3=$3
   arg4=$4
   arg5=$5

   export PATH=${PWD}/../bin:$PATH
   export FABRIC_CFG_PATH=$PWD/../config/
   export CORE_PEER_TLS_ENABLED=true
   export CORE_PEER_LOCALMSPID="Org1MSP"
   export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
   export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp
   export CORE_PEER_ADDRESS=localhost:7051

   peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"StorePacketData","Args":["$arg1", "$arg2", "$arg3", "$arg4", "$arg5"]}'
}

invokeCC $1 $2 $3 $4 $5

It is eveident the term:

'{"function":"StorePacketData","Args":["$arg1", "$arg2", "$arg3", "$arg4", "$arg5"]}'

is taken as a whole string and the variables can't be passed. Therefore, I tried a variant:

#!/bin/bash

invokeCC() {

   arg1=$1
   arg2=$2
   arg3=$3
   arg4=$4
   arg5=$5

   export PATH=${PWD}/../bin:$PATH
   export FABRIC_CFG_PATH=$PWD/../config/
   export CORE_PEER_TLS_ENABLED=true
   export CORE_PEER_LOCALMSPID="Org1MSP"
   export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
   export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp
   export CORE_PEER_ADDRESS=localhost:7051
   QUOTE="'"
   args="{\"function\":\"StorePacketData\",\"Args\":[\"$arg1\", \"$arg2\", \"$arg3\", \"$arg4\", \"$arg5\"]}"

   peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c $QUOTE$args$QUOTE
}

invokeCC $1 $2 $3 $4 $5

This gives error as well which is

Error: chaincode argument error: invalid character '\'' looking for beginning of value

I know that I am going wrong in the second method but I don't know what else can be done.

Please suggest what I should do here to invoke the chaincode. Let me know if I need to provide any other information.

Thanks in advance!

CodePudding user response:

To generate well-formed, syntactically-valid JSON with an arbitrary list of command-line arguments, use jq version 1.6 with $ARGS.positional:

#!/usr/bin/env bash

invokeCC() {
  args=$(jq '{"function":"StorePacketData", "Args": $ARGS.positional}' --args "$@")
  peer chaincode invoke ... --args "$args"
}

invokeCC "$@"

CodePudding user response:

As @Charles Duffy suggested, I used jq for passing the argument. So, I changed my shell script to this:

#!/bin/bash

invokeCC() {

   arg1=$1
   arg2=$2
   arg3=$3
   arg4=$4
   arg5=$5

   export PATH=${PWD}/../bin:$PATH
   export FABRIC_CFG_PATH=$PWD/../config/
   export CORE_PEER_TLS_ENABLED=true
   export CORE_PEER_LOCALMSPID="Org1MSP"
   export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
   export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/[email protected]/msp
   export CORE_PEER_ADDRESS=localhost:7051

   echo hello

   args=$(jq \
  -n --arg val1 "$arg1" \
  -n --arg val2 "$arg2" \
  -n --arg val3 "$arg3" \
  -n --arg val4 "$arg4" \
  -n --arg val5 "$arg5" \
  '{"function":"StorePacketData", "Args": [$val1, $val2, $val3, $val4, $val5]}'
  )
   echo $args

   peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c "$args"
}

invokeCC "$1" "$2" "$3" "$4" "$5"

This worked absolutely fine. However, the solution suggested by @Charles Duffy is a much better one.

  • Related