简介 以Hyperldger2.0为例,链码的安装主要分为以下几部分: package :打包源代码 install: 安装链码 approveformyorg: 节点所在组织审批链码 commit: 提交链码 在完成之后可以执行链码的查询和调用 package首先需要对合约进行编译,首先把我们写的go语言合约放到chaincode下新建的test文件夹下。 root@lamaxiya:/opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode/test# pwd /opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode/test root@lamaxiya:/opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode/test# ls CaAndFakeName.go root@lamaxiya:/opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode/test# 执行命令 go mod init 生成go.modroot@lamaxiya:/opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode/test# go mod init go: creating new go.mod: module github.com/hyperledger/fabric-samples/chaincode/test root@lamaxiya:/opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode/test# ls CaAndFakeName.go go.mod 执行命令 go run CaAndFakeName.go 生成go.sumroot@lamaxiya:/opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode/test# go run CaAndFakeName.go Error starting UserCA chaincode: "CORE_CHAINCODE_ID_NAME" must be setroot@lamaxiya:/opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode/test# ls CaAndFakeName.go go.mod go.sum 上述的 CORE_CHAINCODE_ID_NAME 不设置不影响链码部署和执行。执行命令 GO111MODULE=on go mod vendor 生成vendor包root@lamaxiya:/opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode/test# GO111MODULE=on go mod vendor root@lamaxiya:/opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode/test# ls CaAndFakeName.go go.mod go.sum vendor 将我们编译好的智能合约打包到容器内,执行命令如下: docker exec cli peer lifecycle chaincode package $1.tar.gz --path github.com/hyperledger/fabric-samples/chaincode/$3 --label $1_$2 上述参数定义为(下面的参数与此相同): $1 表示我们自定义的合约打包的名字如(mycc.tar.gz 则参数1为mycc)。$2 代表我们链码的版本开始时一般为1,后续如果需要升级合约可依次为2、3、4……。$3 代表我们链码放的位置(对应上文编译时为test文件夹,则参数2为test)。install 在完成打包后执行安装命令(安装到示例网络的两个组织的节点上)如下: 节点1,msp配置文件、address、tls配置文件默认为peer0.org1不用添加 docker exec cli peer lifecycle chaincode install $1.tar.gz 节点2,因为时在cli容器执行需要添加指定的文件路径 docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt cli peer lifecycle chaincode install $1.tar.gz 上述安装成功的话会输出链码的package_id如下: 3cd7767df34500f3d72faf7efd9774fbd72da4be0696b37 22 07mycc_1" > 2022-01-04 14:13:44.443 UTC [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: mycc_1:cb23fa9b0bace2c353cd7767df34500f3d72faf7efd9774fbd72da4be0696b37 此 package identifier: mycc_1:cb23fa9b0bace2c353cd7767df34500f3d72faf7efd9774fbd72da4be0696b37 我们下文需要使用.approveformyorg 在完成安装命令之后需要组织进行同意命令如下: peer0.org1执行命令 docker exec cli peer lifecycle chaincode approveformyorg --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name $1 --version $2 --init-required --sequence $2 --waitForEvent --package-id $4 peer0.org2执行命令 docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt cli peer lifecycle chaincode approveformyorg --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID $4 --name $3 --version $2 --init-required --sequence $2 --waitForEvent --package-id $1 上述参数 $4 就是上文中生成的package identifier。commit 在完成组织审批之后,需要执行链码向orderer节点进行提交执行如下命令: docker exec cli peer lifecycle chaincode commit -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --channelID $4 --name $3 --version $2 --sequence $2 --init-required 上述命令成功执行完输出如下表明链码安装成功。 2022-01-04 14:20:56.239 UTC [cli.lifecycle.chaincode] setOrdererClient -> INFO 001 Retrieved channel (mychannel) orderer endpoint: orderer.example.com:7050 2022-01-04 14:20:58.526 UTC [chaincodeCmd] ClientWait -> INFO 002 txid [4e000545094b9b09c359a6f54d00e7a8efddf78e125e75ad25a3b14eb5d98885] committed with status (VALID) at approced on org2 successful 2022-01-04 14:21:01.520 UTC [chaincodeCmd] ClientWait -> INFO 001 txid [5243ea90c3bc104e3998707e5859857f01fb360e38d3d325d8761c84ae455f6c] committed with status (VALID) at peer0.org1.example.com:7051 2022-01-04 14:21:01.522 UTC [chaincodeCmd] ClientWait -> INFO 002 txid [5243ea90c3bc104e3998707e5859857f01fb360e38d3d325d8761c84ae455f6c] committed with status (VALID) at peer0.org2.example.com:9051 commit successful 2022-01-04 14:21:05.637 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200 以上就是fabric2.0中安装一个链码的正常步骤。 半自动化安装链码 下面是我封装的安装链码的两个sh文件,可以简化终端输入 文件1是对步骤 package和install 的命令封装。function help(){ echo "para1-----package_name" echo "para2-----chaincode_id" echo "para3-----chaincode_dir" } if [ $1 == "help" -o $1 == "h" -o $1 == "-h" -o $1 == "-help" ]; then help exit 1 fi if [ $# -ne 3 ]; then echo "You need to enter three para3" exit 1 fi #打包 docker exec cli peer lifecycle chaincode package $1.tar.gz --path github.com/hyperledger/fabric-samples/chaincode/$3 --label $1_$2 if [ $? -ne 0 ]; then echo "package error" exit 1 fi docker exec cli ls docker exec cli peer lifecycle chaincode install $1.tar.gz if [ $? -ne 0 ]; then echo "install on org1 error" exit 1 fi echo "install on org1 successful" docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt cli peer lifecycle chaincode install $1.tar.gz if [ $? -ne 0 ]; then echo "install on org2 error" exit 1 fi linux执行命令为如下: sh 文件名.sh $1 $2 $3 需要注意将输出的package identifier使用变量记录下来,文件2需要使用此参数文件2是对步骤 approveformyorg和commit 的命令封装。function help(){ echo "para1-----package_id" echo "para2-----chaincode_id" echo "para3-----chaincode_name" echo "para4-----channel_name" } if [ $1 == "help" -o $1 == "h" -o $1 == "-h" -o $1 == "-help" ]; then help exit 1 fi docker exec cli peer lifecycle chaincode approveformyorg --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID $4 --name $3 --version $2 --init-required --sequence $2 --waitForEvent --package-id $1 if [ $? -ne 0 ]; then echo "approve failed for org1" exit 1 fi echo "approved on org1 successful " docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" -e CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt cli peer lifecycle chaincode approveformyorg --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID $4 --name $3 --version $2 --init-required --sequence $2 --waitForEvent --package-id $1 if [ $? -ne 0 ]; then echo "approve failed for org2" exit 1 fi echo "approced on org2 successful" docker exec cli peer lifecycle chaincode commit -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --channelID $4 --name $3 --version $2 --sequence $2 --init-required if [ $? -ne 0 ]; then echo "commit failed" exit 1 fi echo "commit successful" linux执行命令为如下 sh 文件名.sh 参数1 参数2 参数3 参数4 参数1为上文输出的package identifier。 Hyperledger中文文档