我已经建立了一个超级账本网络,网络设置得很好。链码也已部署。现在,我想调用链码中的一个函数。如果我必须通过终端操作,那么它会像这样:
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"]}'
这工作得很好。但是,我想从shell脚本调用这个函数,其中函数的参数将是变量。该shell脚本文件可由另一个shell脚本调用。因此,我的shell脚本文件看起来像这样:
#!/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/Admin@org1.example.com/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
很明显:
'{"function":"StorePacketData","Args":["$arg1", "$arg2", "$arg3", "$arg4", "$arg5"]}'
作为一个完整的字符串,不能传递变量。因此,我尝试了一个变体:
#!/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/Admin@org1.example.com/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
这也给出了错误,也就是
Error: chaincode argument error: invalid character ''' looking for beginning of value
我知道我在第二种方法中出错了,但我不知道还能做什么。
请建议我在这里应该做什么来调用链码。如果还需要我提供其他信息,请告诉我。
提前感谢!
要使用任意命令行参数列表生成格式良好、语法有效的JSON,请使用jq
version 1.6和$ARGS.positional
:
#!/usr/bin/env bash
invokeCC() {
args=$(jq -n '{"function":"StorePacketData", "Args": $ARGS.positional}' --args "$@")
peer chaincode invoke ... --args "$args"
}
invokeCC "$@"
使用--arg
和$ARGS.named
也可以达到同样的目的:
invokeCC() {
local -a jq_args=( )
local arg idx=0 idx_str
for arg in "$@"; do
printf -v idx_str '%04d' "$idx"
jq_args+=( --arg "arg$idx_str" "$arg" )
(( ++idx ))
done
jq -nc "${jq_args[@]}" '{"function": "StorePacketData", "Args": [$ARGS.named | to_entries | sort_by(.key)[] | .value]}'
}
invokeCC "$@"
正如@Charles Duffy建议的那样,我使用jq
来传递参数。因此,我将shell脚本更改为:
#!/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/Admin@org1.example.com/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"
这工作得很好。然而,@Charles Duffy提出的解决方案要好得多。