fabric链码可以安装peer上,却安装通道时报错(实例化时)

相信很多人都碰到这种问题,这里给出一种方案,并带你分析一下为什么出现这种问题。

问题描述

话不多说,直接上干货
先来张报错的图:

在这里插入图片描述
错误提示为:

Error: could not assemble transaction, err proposal response was not successful, error code 500, msg error starting container: error starting container: Failed to generate platform-specific docker build: Error returned from build: 1 "chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go/testChaincode/vendor/github.com/hyperledger/fabric-contract-api-go/internal/types/types.go:13:2: cannot find package "github.com/go-openapi/spec" in any of:
	/chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go/testChaincode/vendor/github.com/go-openapi/spec (vendor tree)
	/opt/go/src/github.com/go-openapi/spec (from $GOROOT)
	/chaincode/input/src/github.com/go-openapi/spec (from $GOPATH)
	/opt/gopath/src/github.com/go-openapi/spec
chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go/testChaincode/vendor/github.com/hyperledger/fabric-contract-api-go/metadata/a_metadata-packr.go:7:8: cannot find package "github.com/gobuffalo/packr" in any of:
	/chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go/testChaincode/vendor/github.com/gobuffalo/packr (vendor tree)
	/opt/go/src/github.com/gobuffalo/packr (from $GOROOT)
	/chaincode/input/src/github.com/gobuffalo/packr (from $GOPATH)
	/opt/gopath/src/github.com/gobuffalo/packr
chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go/testChaincode/vendor/github.com/hyperledger/fabric-contract-api-go/contractapi/contract_chaincode.go:14:2: cannot find package "github.com/hyperledger/fabric-chaincode-go/pkg/cid" in any of:
	/chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go/testChaincode/vendor/github.com/hyperledger/fabric-chaincode-go/pkg/cid (vendor tree)
	/opt/go/src/github.com/hyperledger/fabric-chaincode-go/pkg/cid (from $GOROOT)
	/chaincode/input/src/github.com/hyperledger/fabric-chaincode-go/pkg/cid (from $GOPATH)
	/opt/gopath/src/github.com/hyperledger/fabric-chaincode-go/pkg/cid
chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go/testChaincode/vendor/github.com/hyperledger/fabric-contract-api-go/contractapi/contract_chaincode.go:15:2: cannot find package "github.com/hyperledger/fabric-chaincode-go/shim" in any of:
	/chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go/testChaincode/vendor/github.com/hyperledger/fabric-chaincode-go/shim (vendor tree)
	/opt/go/src/github.com/hyperledger/fabric-chaincode-go/shim (from $GOROOT)
	/chaincode/input/src/github.com/hyperledger/fabric-chaincode-go/shim (from $GOPATH)
	/opt/gopath/src/github.com/hyperledger/fabric-chaincode-go/shim
chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go/testChaincode/vendor/github.com/hyperledger/fabric-contract-api-go/contractapi/contract_chaincode.go:20:2: cannot find package "github.com/hyperledger/fabric-protos-go/peer" in any of:
	/chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go/testChaincode/vendor/github.com/hyperledger/fabric-protos-go/peer (vendor tree)
	/opt/go/src/github.com/hyperledger/fabric-protos-go/peer (from $GOROOT)
	/chaincode/input/src/github.com/hyperledger/fabric-protos-go/peer (from $GOPATH)
	/opt/gopath/src/github.com/hyperledger/fabric-protos-go/peer
chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go/testChaincode/vendor/github.com/hyperledger/fabric-contract-api-go/internal/utils/utils.go:11:2: cannot find package "github.com/xeipuuv/gojsonschema" in any of:
	/chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go/testChaincode/vendor/github.com/xeipuuv/gojsonschema (vendor tree)
	/opt/go/src/github.com/xeipuuv/gojsonschema (from $GOROOT)
	/chaincode/input/src/github.com/xeipuuv/gojsonschema (from $GOPATH)
	/opt/gopath/src/github.com/xeipuuv/gojsonschema

根据图中可以看出执行 peer chaincode instantiate命令出现错误,在前面的peer chaincode install命令是成功的,到了实例化的时候出现问题。

其实我们可以看一下上面报错的log,可以发现是找不到对应的包
可以看到上面他们去了以下几个路径去找包:

/chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go/testChaincode/vendor/github.com/go-openapi/spec (vendor tree)
/opt/go/src/github.com/go-openapi/spec (from $GOROOT)
/chaincode/input/src/github.com/go-openapi/spec (from $GOPATH)
/opt/gopath/src/github.com/go-openapi/spec

现在进行一下一点验证:
1、在vendor tree$GOROOT$GOPATH这几个路径下面是否能够找到。方法很简单,上面路径不是给出了。直接通过命令docker exec -it cli bash 进入cli容器,看看这个容器下面是否存在上述的几个路径。
2、答案肯定是不存在的,如果存在也不至于找不到。问题到这里已经很明显了,因为容器cli中没有链码运行所需要的依赖包。
3、既然没有,那我们给cli容器依赖包就好啦。

解决办法

那么怎么给cli容器依赖包呢?有以下几个方法:
1、直接在cli容器中go get所需要的依赖包。(效率最低的方式,每次重启网络都需要进入cli容器中go get一波)极其不推荐这种方式。
2、我们看一下vendor tree这个路径,这个路径在cli容器中不存在的。那么为什么会有这个路径呢?可能是你在链码的目录下进行过govendor或者go mod vendor等操作。会先去链码依赖包所在的位置,也就是vendor tree中去找。在vendor tree中找不到,再去GOROOT找,找不到再去GOPAHT中找,如果都找不到,那就报找不到包的错误。解决的办法很简单,就是让cli容器的/chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go存在就好啦!那么怎么让他存在呢,就是把本地项目的链码路径挂载在这个路径下面就ok了。

现在我们只需要完成挂载这个路径到cli就好,那么如何挂载呢?首先要明白cli这个容器是根据什么启动呢?那当然是你配置的yaml文件。
在我的容器启动配置文件中,关于cli的文件配置是这样的(此处是粘贴的我自己的,大家可以根据自己的配置文件动态调整一下):

  cli:
    container_name: cli
    image: hyperledger/fabric-tools:$IMAGE_TAG
    tty: true
    stdin_open: true
    environment:
      - SYS_CHANNEL=$SYS_CHANNEL
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      #- FABRIC_LOGGING_SPEC=DEBUG
      - FABRIC_LOGGING_SPEC=INFO
      - CORE_PEER_ID=cli
      - CORE_PEER_ADDRESS=peer0.org1.fabric-iot.edu:7051
      - CORE_PEER_LOCALMSPID=Org1MSP
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.fabric-iot.edu/peers/peer0.org1.fabric-iot.edu/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.fabric-iot.edu/peers/peer0.org1.fabric-iot.edu/tls/server.key
      - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.fabric-iot.edu/peers/peer0.org1.fabric-iot.edu/tls/ca.crt
      - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.fabric-iot.edu/users/Admin@org1.fabric-iot.edu/msp
      - GO111MODULE=on
      - GOPROXY=https://goproxy.io,direct
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    command: /bin/bash
    volumes:
        - /var/run/:/host/var/run/
        - ./../../chaincode/:/opt/gopath/src/github.com/yjzhu1106/fabric-single/chaincode
        # - ./../../../../../../src/github.com/ethereum/go-ethereum:/opt/gopath/src/github.com/ethereum/go-ethereum
        - ./../../../../../../src/:/opt/gopath/src/
        # - ./../../chaincode/go/pdpc/vendor/github.com:/opt/gopath/src/github.com
        - ./../crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
        - ./../scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
        - ./../channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
    depends_on:
      - orderer.fabric-iot.edu
      - peer0.org1.fabric-iot.edu
      - peer1.org1.fabric-iot.edu
      - peer0.org2.fabric-iot.edu
      - peer1.org2.fabric-iot.edu
    networks:
      - bc_net

接下来讲一下如何挂载(完成下述目标):

  • 让cli容器的/chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go存在就好啦!那么怎么让他存在呢,就是把本地项目的链码路径挂载在这个路径下面就ok了。

1、大家可以看到cli的volumes属性,就在volumes属性下面添加一个挂在路径的配置就好。
2、可以看到,我现在挂载了6个路径,还有两个注释掉的路径。
3、本地和容器之间的挂载关系为: - 本地路径:容器的路径。现在我本地链码所在的位置为:/root/go/src/github.com/yjzhu1106/fabric-single/chaincode/go,我想把这个链码的位置挂载在/chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go

- /root/go/src/github.com/yjzhu1106/fabric-single/chaincode/go:/chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go

4、上面就实现了挂载,那么问题是,如果我的项目换了个电脑,本地的路径发生了改变,是不是就要再次更改挂载的路径。那么我们就用相对路径来挂载。首先呢,我的配置文件yaml所在的位置为:/root/go/src/github.com/yjzhu1106/fabric-single/network/compose-files,那么链码所在路径相对与配置文件的位置应该是:../chaincode/go/,将步骤3中的更新为:

- ./../../chaincode/go:/chaincode/input/src/github.com/yjzhu1106/fabric-single/chaincode/go

5、最重要的一步,你需要重新启动你的网络,然后再安装试一下,这个问题应该是解决的。

tip:你要保证你链码的vendor中有所有的依赖,据我所知,依赖包的依赖,是无法下载到vendor中的,所以再出现找不到包的问题,就去你链码的vendor中,把缺少的依赖直接git clonevendor里面就可以啦。git clone的时候注意路径问题,该在哪个文件夹下就在哪个文件夹下。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值