Search code examples
hyperledger-fabrichyperledger-chaincodechaincodevendoring

Vendored Chaincode has false dependencies


I have chaincode with the following directory structure

$GOPATH/myproject/chaincode/mycc/go
├── mycc.go
├── chaincode
│   └── chaincode.go
└── vendor
    ├── github.com
    ├── ...

Because of my usage of hyperledgers cid package, I use vendoring and have the vendor directory next to the chaincode. Now for testablitiy, mycc.go only includes the main function:

package main

import (
    "myproject/chaincode/mycc/go/chaincode"
    "github.com/hyperledger/fabric/core/chaincode/shim"
)

func main() {
    err := shim.Start(new(chaincode.MyChaincode))
    if err != nil {
        logger.Error(err.Error())
    }
}

The chaincode.go implements the rest of the chaincode, including the MyChaincode struct with Init, Invoke, etc. The relevant imports are identical to the one in the mycc.go:

"github.com/hyperledger/fabric/core/chaincode/shim"

During the instantiation of the chaincode, something with the dependencies seems to be mixed up, because I receive the error message:

*chaincode.MyChaincode does not implement "chaincode/mycc/go/vendor/github.com/hyperledger/fabric/core/chaincode/shim".Chaincode (wrong type for Init method)
    have Init("chaincode/mycc/go/vendor/myproject/chaincode/mycc/go/vendor/github.com/hyperledger/fabric/core/chaincode/shim".ChaincodeStubInterface) "chaincode/approvalcc/go/vendor/ma/chaincode/approvalcc/go/vendor/github.com/hyperledger/fabric/protos/peer".Response
    want Init("chaincode/mycc/go/vendor/github.com/hyperledger/fabric/core/chaincode/shim".ChaincodeStubInterface) "chaincode/mycc/go/vendor/github.com/hyperledger/fabric/protos/peer".Response

So clearly it seems that the import in the inner chaincode package is resolved wrongly with the vendor directory appearing twice in the path.


Solution

  • The fabric-ccenv container which builds chaincode attempts to be "helpful" but including shim in the GOPATH inside the container. It also ends up including the shim/ext/... folders as well but unfortunately does not actually properly include their transitive dependencies.

    When you combine this with how the chaincode install/package commands also attempt to be helpful and your attempt to vendor, things got ugly.

    I actually just pushed a fix targeted for 1.4.2 to address the fabric-ccenv issue.