美文网首页区块链
fabric-sdk-go的简单使用

fabric-sdk-go的简单使用

作者: 小李飞刀无情剑 | 来源:发表于2018-12-17 14:13 被阅读439次

    使用fabric-sdk-go之前,需要安装好go环境,docker以及docker compose环境,还有 hyperledger fabric 环境.

    一. 创建crypto-config.yaml

    使用fabric提供的cryptogen工具生成文件模板
    $ cryptogen showtemplate > crypto-config.yaml
    进行修改,添加一个组织,一个orderer节点.

    OrdererOrgs:
    
      - Name: Orderer
        Domain: xq.com
        Specs:
          - Hostname: orderer
    
    PeerOrgs:
    
      - Name: Travle
        Domain: travle.xq.com
        EnableNodeOUs: false
    
        Template:
          Count: 2
    
        Users:
          Count: 2
    

    根据crypto-config.yaml文件生成证书文件:
    $ cryptogen generate --config=crypto-config.yaml

    查看生成的证书文件夹结构:

    .
    ├── ordererOrganizations
    │   └── xq.com
    │       ├── ca
    │       │   ├── 1d8deec1977f7abf81692e72c06861e811c00b34278b48c9fe44dc51238d8621_sk
    │       │   └── ca.xq.com-cert.pem
    │       ├── msp
    │       │   ├── admincerts
    │       │   ├── cacerts
    │       │   └── tlscacerts
    │       ├── orderers
    │       │   └── orderer.xq.com
    │       ├── tlsca
    │       │   ├── 5b189397d9390ae07146a411f0e7b6c5bf1fdb809d4b4d51b6f25b739a7cc127_sk
    │       │   └── tlsca.xq.com-cert.pem
    │       └── users
    │           └── Admin@xq.com
    └── peerOrganizations
        └── travle.xq.com
            ├── ca
            │   ├── 8ae1b694ae88d19d07fd698b0990b8d4f3bc46782fbfb3620e3e6e3fb0263e1c_sk
            │   └── ca.travle.xq.com-cert.pem
            ├── msp
            │   ├── admincerts
            │   ├── cacerts
            │   └── tlscacerts
            ├── peers
            │   ├── peer0.travle.xq.com
            │   └── peer1.travle.xq.com
            ├── tlsca
            │   ├── d6e2633fe6f35345eca10bc0231a2b34f127c2b9ebc8a86b582b412e875e513c_sk
            │   └── tlsca.travle.xq.com-cert.pem
            └── users
                ├── Admin@travle.xq.com
                ├── User1@travle.xq.com
                └── User2@travle.xq.com
    

    二. 生成创世区块文件和 通道

    需要从fabric的源码案例中拷贝configtx.yaml文件
    $ cp $GOPATH/src/github.com/hyperledger/fabric-samples/first-network/configtx.yaml ./
    对configtx.yaml文件进行修改.
    修改之前,创建一个文件夹,来保存即将创建的创世区块文件

    $ mkdir channel-artifacts
    

    将创建区块文件和通道的命令写到一个脚本中! generate.sh

    rm -rf ./channel-artifacts/*
    rm -rf ./crypto-config/*
    
    #根据crypto-config.yaml文件生成证书
    cryptogen generate --config=./crypto-config.yaml
    
    # 生成创始块文件
    echo "---------------- Create genesis.block file BEGIN --------------------"
    configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
    echo "---------------- Create genesis.block file END --------------------"
    
    # 生成 travlechannel 文件
    echo "---------------- Create travlechannel.tx file BEGIN -------------------"
    configtxgen -profile TravleOrgsChannel -outputCreateChannelTx ./channel-artifacts/travlechannel.tx -channelID travlechannel
    echo "---------------- Create travlechannel.tx file END -------------------"
    
    # 生成更新锚节点文件
    echo "---------------- Create TravleMSPanchors.tx file BEGIN -------------------"
    configtxgen -profile TravleOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/TravleMSPanchors.tx -channelID travlechannel -asOrg TravleMSP
    echo "---------------- Create TravleMSPanchors.tx file END -------------------"
    
    

    脚本文件和配置文件的目录结构:

    ├── channel-artifacts
    ├── configtx.yaml
    ├── crypto-config
    │   ├── ordererOrganizations
    │   └── peerOrganizations
    ├── crypto-config.yaml
    └── generate.sh
    
    

    执行generate.sh文件生成创世区块文件和通道,其实只有一个组织,也没必要生成锚节点更新文件..
    $ ./generate.sh

    三. 通过 docker-compose 启动容器

    配置docker-compose文件:

    version: '2'
    
    networks:
      xq_travle:
    
    services:
      orderer.xq.com:
        image: hyperledger/fabric-orderer:latest
        container_name: orderer.xq.com
        environment:
          - ORDERER_GENERAL_LOGLEVEL=debug
          - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
          - ORDERER_GENERAL_LISTENPORT=7050
          - ORDERER_GENERAL_GENESISPROFILE=Orderer
          - ORDERER_GENERAL_GENESISMETHOD=file
          - ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
          - ORDERER_GENERAL_LOCALMSPID=xq.com
          - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
          - ORDERER_GENERAL_TLS_ENABLED=true
          - ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
          - ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
          - ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
    
        working_dir: /opt/gopath/src/github.com/hyperledger/fabric
        command: orderer
        volumes:
          - ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
          - ./crypto-config/ordererOrganizations/xq.com/orderers/orderer.xq.com/msp:/var/hyperledger/orderer/msp
          - ./crypto-config/ordererOrganizations/xq.com/orderers/orderer.xq.com/tls:/var/hyperledger/orderer/tls
        ports:
          - 7050:7050
        networks:
          - xq_travle
    
      peer0.travle.xq.com:
        image: hyperledger/fabric-peer:latest
        container_name: peer0.travle.xq.com
        environment:
          - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
          - CORE_VM_DOCKER_ATTACHSTDOUT=true
          - CORE_LOGGING_LEVEL=DEBUG
          - CORE_PEER_PROFILE_ENABLED=true
          - CORE_PEER_TLS_ENABLED=true
          - CORE_PEER_TLS_CERT_FILE=/var/hyperledger/tls/server.crt
          - CORE_PEER_TLS_KEY_FILE=/var/hyperledger/tls/server.key
          - CORE_PEER_TLS_ROOTCERT_FILE=/var/hyperledger/tls/ca.crt
          - CORE_PEER_ID=peer0.travle.xq.com
          - CORE_PEER_ADDRESSAUTODETECT=true
          - CORE_PEER_ADDRESS=peer0.travle.xq.com:7051
          - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.travle.xq.com:7051
          - CORE_PEER_GOSSIP_USELEADERELECTION=true
          - CORE_PEER_GOSSIP_ORGLEADER=false
          - CORE_PEER_GOSSIP_SKIPHANDSHAKE=true
          - CORE_PEER_LOCALMSPID=travle.xq.com
          - CORE_PEER_MSPCONFIGPATH=/var/hyperledger/msp
          - CORE_PEER_TLS_SERVERHOSTOVERRIDE=peer0.travle.xq.com
        working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
        command: peer node start
        volumes:
          - /var/run/:/host/var/run/
          - ./crypto-config/peerOrganizations/travle.xq.com/peers/peer0.travle.xq.com/msp:/var/hyperledger/msp
          - ./crypto-config/peerOrganizations/travle.xq.com/peers/peer0.travle.xq.com/tls:/var/hyperledger/tls
        ports:
          - 7051:7051
          - 7053:7053
        depends_on:
          - orderer.xq.com
        links:
          - orderer.xq.com
        networks:
          - xq_travle
    
      peer1.travle.xq.com:
        image: hyperledger/fabric-peer:latest
        container_name: peer1.travle.xq.com
        environment:
          - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
          - CORE_VM_DOCKER_ATTACHSTDOUT=true
          - CORE_LOGGING_LEVEL=DEBUG
          - CORE_PEER_PROFILE_ENABLED=true
          - CORE_PEER_TLS_ENABLED=true
          - CORE_PEER_TLS_CERT_FILE=/var/hyperledger/tls/server.crt
          - CORE_PEER_TLS_KEY_FILE=/var/hyperledger/tls/server.key
          - CORE_PEER_TLS_ROOTCERT_FILE=/var/hyperledger/tls/ca.crt
          - CORE_PEER_ID=peer1.travle.xq.com
          - CORE_PEER_ADDRESSAUTODETECT=true
          - CORE_PEER_ADDRESS=peer1.travle.xq.com:7051
          - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.travle.xq.com:7051
          - CORE_PEER_GOSSIP_USELEADERELECTION=true
          - CORE_PEER_GOSSIP_ORGLEADER=false
          - CORE_PEER_GOSSIP_SKIPHANDSHAKE=true
          - CORE_PEER_LOCALMSPID=travle.xq.com
          - CORE_PEER_MSPCONFIGPATH=/var/hyperledger/msp
          - CORE_PEER_TLS_SERVERHOSTOVERRIDE=peer1.travle.xq.com
        working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
        command: peer node start
        volumes:
          - /var/run/:/host/var/run/
          - ./crypto-config/peerOrganizations/travle.xq.com/peers/peer1.travle.xq.com/msp:/var/hyperledger/msp
          - ./crypto-config/peerOrganizations/travle.xq.com/peers/peer1.travle.xq.com/tls:/var/hyperledger/tls
        ports:
          - 8051:7051
          - 8053:7053
        depends_on:
          - orderer.xq.com
        links:
          - orderer.xq.com
        networks:
          - xq_travle
    

    启动容器, 启动后查看容器运行情况
    $ docker-compose up -d
    $ docker-compose ps

           Name               Command       State                       Ports                     
    ----------------------------------------------------------------------------------------------
    orderer.xq.com        orderer           Up      0.0.0.0:7050->7050/tcp                        
    peer0.travle.xq.com   peer node start   Up      0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp
    peer1.travle.xq.com   peer node start   Up      0.0.0.0:8051->7051/tcp, 0.0.0.0:8053->7053/tcp
    

    在这里,创建两个脚本文件,用于docker容器的管理
    clear_docker.sh 文件:

    sudo docker rm -f $(sudo docker ps -aq) # 清除容器们
    sudo docker network prune # 来清理没有再被任何容器引用的networks
    sudo docker volume prune  # 清理挂载卷
    

    restart.sh 文件:

    ./clear_docker.sh    # 执行clear_docker.sh脚本文件
    docker-compose up -d
    

    四. 创建sdk配置文件

    创建配置文件的时候,有两个文件可以进行参考...

    $GOPATH/src/github.com/hyperledger/fabric-sdk-go/test/fixtures/config/config_test.yaml
    
    $GOPATH/src/github.com/hyperledger/fabric-sdk-go/pkg/core/config/testdata/template/config.yaml
    

    修改后的sdk配置文件:

    name: "driver-service-network"
    
    version: 1.1.0
    
    client:
      organization: Travle
      logging:
        level: info
      cryptoconfig:
        path: /Users/xq_mac/Go/src/driverFabricDemo/conf/crypto-config
      credentialStore:
        path: /tmp/driverStore
    
      BCCSP:
        security:
          enabled: true
          default:
            provider: "SW"
          hashAlgorithm: "SHA2"
          softVerify: true
          level: 256
    
      tlsCerts:
        systemCertPool: true
        client:
          keyfile: /Users/xq_mac/Go/src/driverFabricDemo/conf/crypto-config/peerOrganizations/travle.xq.com/users/User1@travle.xq.com/tls/client.key
          certfile: /Users/xq_mac/Go/src/driverFabricDemo/conf/crypto-config/peerOrganizations/travle.xq.com/users/User1@travle.xq.com/tls/client.crt
    
    channels:
      travlechannel:
        orderers:
          - orderer.xq.com
    
        peers:
          peer0.travle.xq.com:
            endorsingPeer: true
            chaincodeQuery: true
            ledgerQuery: true
            eventSource: true
    
          peer1.travle.xq.com:
            endorsingPeer: true
            chaincodeQuery: true
            ledgerQuery: true
            eventSource: true
    
        policies:
          queryChannelConfig:
            minResponses: 1
            maxTargets: 1
            retryOpts:
              attempts: 5
              initialBackoff: 500ms
              maxBackoff: 5s
              backoffFactor: 2.0
    
    organizations:
      travle:
        # configtx.yaml organizations -> ID
        mspid: travle.xq.com
    
        cryptoPath: /Users/xq_mac/Go/src/driverFabricDemo/conf/crypto-config/peerOrganizations/travle.xq.com/users/{username}@travle.xq.com/msp
        peers:
        - peer0.travle.xq.com
        - peer1.travle.xq.com
    
      ordererorg:
        mspID: xq.com
        cryptoPath: /Users/xq_mac/Go/src/driverFabricDemo/conf/crypto-config/ordererOrganizations/xq.com/users/Admin@xq.com/msp
    
    orderers:
      orderer.xq.com:
        url: localhost:7050
        grpcOptions:
          ssl-target-name-override: orderer.xq.com
          keep-alive-time: 0s
          keep-alive-timeout: 20s
          keep-alive-permit: false
          fail-fast: false
          allow-insecure: false
    
        tlsCACerts:
          path: /Users/xq_mac/Go/src/driverFabricDemo/conf/crypto-config/ordererOrganizations/xq.com/tlsca/tlsca.xq.com-cert.pem
    peers:
      peer0.travle.xq.com:
        url: grpcs://localhost:7051
        eventUrl: localhost:7053
        grpcOptions:
          ssl-target-name-override: peer0.travle.xq.com
          keep-alive-time: 0s
          keep-alive-timeout: 20s
          keep-alive-permit: false
          fail-fast: false
          allow-insecure: false
        tlsCACerts:
          path: /Users/xq_mac/Go/src/driverFabricDemo/conf/crypto-config/peerOrganizations/travle.xq.com/tlsca/tlsca.travle.xq.com-cert.pem
    
      peer1.travle.xq.com:
        url: grpcs://localhost:8051
        eventUrl: localhost:8053
        grpcOptions:
          ssl-target-name-override: peer1.travle.xq.com
          keep-alive-time: 0s
          keep-alive-timeout: 20s
          keep-alive-permit: false
          fail-fast: false
          allow-insecure: false
        tlsCACerts:
          path: /Users/xq_mac/Go/src/driverFabricDemo/conf/crypto-config/peerOrganizations/travle.xq.com/tlsca/tlsca.travle.xq.com-cert.pem
    

    五. 实例化sdk

    • 5.1 在工程中定义一个模型,来维护实例化sdk所需要的变量
    type FabricModel struct {
        ConfigFile  string //sdk的配置文件路径
        ChainCodeID string // 链码名称
        ChaincodePath string  // 链码在工程中的存放目录
        ChaincodeGoPath string  // GOPATH
        OrgAdmin string // 组织的管理员用户
        OrgName  string // config.yaml ---> organizations ---> travle
        OrgID    string // 组织id
        UserName string // 组织的普通用户
        ChannelID string // 通道id
        ChannelConfigPath string //组织的通道文件路径
        OrdererName string  // config.yaml ---> orderers ---> orderer.xq.com // 将组织添加到通道时候使用!
        Sdk        *fabsdk.FabricSDK // 保存实例化后的sdk
        ResMgmtCli *resmgmt.Client // 资源管理客户端,也需要在安装链码时候的使用
        Channelclient     *channel.Client // 通道客户端
        HasInit  bool // 是否已经初始化了sdk
    }
    

    创建出一个模型对象,给其赋值,并开始初始化sdk

    func init() {
        fs := FabricModel{
            OrdererName: "orderer.xq.com",
            ChannelID:     "travlechannel",
            ChannelConfigPath: os.Getenv("GOPATH") + "/src/driverFabricDemo/conf/channel-artifacts/travlechannel.tx",
            ChainCodeID:     "mycc",
            ChaincodeGoPath: os.Getenv("GOPATH"),
            ChaincodePath:   "driverFabricDemo/chaincode",
            OrgAdmin:        "Admin",
            OrgName:         "travle",
            ConfigFile:      "conf/config.yaml",
            UserName: "User1",
        }
        // 实例化SDK  创建通道, 将组织节点加入到通道
        fs.Initialization()
    }
    

    使用 pkg/fabsdk/fabsdk.go中的New()方法进行实例化

    sdk, err := fabsdk.New(config.FromFile(this.ConfigFile))
    
    
    • 5.2 根据实例创建资源管理客户端
    resCliProvider := sdk.Context(fabsdk.WithUser(this.OrgAdmin),fabsdk.WithOrg(this.OrgName))
    resClient, err := resmgmt.New(resCliProvider)
    
    • 5.3 创建channel. 得到一个操作链代码的客户端
      使用pkg/client/resmgmt/resmgmt.go文件中的方法
    // 先创建一个 创建channel的请求
    chanReq := resmgmt.SaveChannelRequest{
            ChannelID: this.ChannelID,
            ChannelConfigPath: this.ChannelConfigPath,
    }
    // 利用 resClient 创建 channel
    chanRsp, err := resClient.SaveChannel(chanReq)
    
    • 5.4 把组织添加到 channel 中, 一般制定一些重试的策略,和指定 orderer节点的网络位置
    err = resClient.JoinChannel(
            this.ChannelID,
            resmgmt.WithRetry(retry.DefaultResMgmtOpts),
            resmgmt.WithOrdererEndpoint(this.OrdererName),
    )
    

    六. 安装链码,实例化链码

    • 6.1 在工程中创建一个chaincode文件夹,用来存在链码,写一个最简单的链码,实现写入数据和读取数据的功能
    package main
    
    import (
        "github.com/hyperledger/fabric/core/chaincode/shim"
        pb "github.com/hyperledger/fabric/protos/peer"
        "fmt"
    )
    
    type ChaincodeXQ struct {
    
    }
    
    func (this * ChaincodeXQ)Init(stub shim.ChaincodeStubInterface) pb.Response  {
    
        return shim.Success([]byte("初始化成功"))
    }
    
    func (this * ChaincodeXQ)Invoke(stub shim.ChaincodeStubInterface) pb.Response  {
    
        // 获取方法和参数
        fname, params := stub.GetFunctionAndParameters()
        if fname == "set" { // 插入操作
            return set(stub,params[0],params[1])
        }else if fname == "get" { //获取操作
    
            return get(stub,params[0])
        }
        return shim.Error("Invoke 操作失败!!")
    }
    
    func set(stub shim.ChaincodeStubInterface, key string, value string) pb.Response {
    
        err := stub.PutState(key,[]byte(value))
        if err != nil {
            return shim.Error("PutState 操作失败!!")
        }
        return shim.Success([]byte("PutState 操作成功!!"))
    }
    
    func get(stub shim.ChaincodeStubInterface, key string) pb.Response {
    
        data, err := stub.GetState(key)
        if err != nil {
            return shim.Error("GetState 操作失败!!")
        }
        // If the key does not exist in the state database, (nil, nil) is returned.
        if data == nil {
            return shim.Error("GetState 操作失败!!, data == nil")
        }
        return shim.Success(data)
    }
    
    func main()  {
    
        err := shim.Start(new(ChaincodeXQ))
        if err != nil {
            fmt.Println("开启链码失败,err:",err)
            return
        }
        fmt.Println("开启链码成功")
    }
    
    • 6.2 安装链码
      安装链码之前需要创建请求
    InstallCCRequest := resmgmt.InstallCCRequest{
            Name:this.ChainCodeID, // 链码名称
            Path:this.ChaincodePath, //链码在工程中的路径
            Version:"0",
            Package:ccp,
    }
    

    创建请求之前,需要使用 gopackager.NewCCPackage 方法生成一个resource.CCPackage 对象,传递两个参数,一个是链码的路径(相对于工程的路径), 一个是GOPATH的路径.

    ccp, err := gopackager.NewCCPackage(this.ChaincodePath,this.ChaincodeGoPath)
    

    安装链码,使用pkg/client/resmgmt/resmgmt.go文件中的方法

    req2Arr, err := this.ResMgmtCli.InstallCC(InstallCCRequest)
    
    • 6.3 实例化链码
      实例化链码之前需要创建请求
    rsp1 := resmgmt.InstantiateCCRequest{
            Name:this.ChainCodeID,// 链码名称
            Path:this.ChaincodeGoPath,//链码在工程中的路径
            Version:"0",
            Args:nil,
            Policy:ccpolity,
    }
    

    创建请求之前,需要生成一个*cb.SignaturePolicyEnvelope类型的对象,使用 third_party/github.com/hyperledger/fabric/common/cauthdsl/cauthdsl_builder.go 文件中的方法即可,提供了好几个方法, 使用任意一个即可.这里使用 SignedByAnyMember 方法: 需要传入所属组织ID

    ccpolity := cauthdsl.SignedByAnyMember([]string{this.OrgID})
    

    实例化链码

    txID,err := this.ResMgmtCli.InstantiateCC(this.ChannelID,rsp1)
    
    • 6.4 再创建一个通道的客户端,后面的调用链码需要使用这个客户端
      使用的是 pkg/client/channel/chclient.go 中的方法
    // 创建上下文
    clientContext := this.Sdk.ChannelContext(this.ChannelID, fabsdk.WithUser(this.UserName))
    // 创建channel客户端
    channelclient, err := channel.New(clientContext)
    

    七. 调用链码

    使用 pkg/client/channel/chclient.go 中的 Execute()方法,来进行数据写入的操作:
    rsp, err := model.Channelclient.Execute(req)
    写入之前,要创建请求:

    req := channel.Request{
            ChaincodeID:model.ChainCodeID, // 链码名称
            Fcn:args[0], // 方法名:  get
            Args:tempArgs, // 传递的参数,是一个二维字符切片  [[49] [49 49 49 49]]  
    }
    

    tempArgs是要传给链码的参数,可以做下封装,就不受参数个数的限制了

    var tempArgs [][]byte
        for i := 1; i < len(args); i++ {
            tempArgs = append(tempArgs, []byte(args[i]))
    }
    

    使用 pkg/client/channel/chclient.go 中的 Query()方法,来进行数据查询的操作: 查询之前,同样需要创建请求.

    req := channel.Request{
            ChaincodeID: model.ChainCodeID, 
            Fcn: args[0], 
            Args: tempArgs,
        }
    rsp, err := model.Channelclient.Query(req)
    

    遇到的问题

    1 链码路径错误

    Chaincode status Code: (500) UNKNOWN. Description: error starting container: error starting container: Failed to generate platform-specific docker build: Error returned from build: 1 "can't load package: package chaincode: cannot find package "chaincode" in any of:
            /opt/go/src/chaincode (from $GOROOT)
            /chaincode/input/src/chaincode (from $GOPATH)
            /opt/gopath/src/chaincode
    

    链码在工程中的路径应该是 工程名/chaincode文件夹
    比如:
    driverFabricDemo/chaincode
    而不应该省略掉工程名这样写:chaincode

    2 go版本的问题

    Failed to build the application: # github.com/cloudflare/cfssl/csr
    ../github.com/cloudflare/cfssl/csr/csr.go:272:26: cert.URIs undefined (type *x509.Certificate has no field or method URIs)
    ../github.com/cloudflare/cfssl/csr/csr.go:387:7: tpl.URIs undefined (type x509.CertificateRequest has no field or method URIs)
    

    错误原因:cert.URIs 和 tpl.URIs 这两个字段没有被定义.
    进入tpl对象中,/usr/local/go/src/crypto/x509/x509.go 是个结构体,并没有发现URIs字段

    对go版本进行升级,从1.9.3升级到1.11.3, 再次进入 /usr/local/go/src/crypto/x509/x509.go 文件中,查看结构体内容:

     // Subject Alternate Name values.
       DNSNames       []string
       EmailAddresses []string
       IPAddresses    []net.IP
       URIs           []*url.URL
    

    3 写入数据到区块链时错误

    Transaction processing for endorser [localhost:7051]: Chaincode status Code: (500) UNKNOWN. 
    Description: Received unknow function invocatio
    

    在执行sdk的Excute()方法时报错.
    方法不存在,一般是由于链码的Invoke方法中的方法名和Excute()方法传入的方法名不一样.
    但是可以肯定的是,链码的Invoke方法中的方法名和,项目中执行Excute()方法时传入的方法名是完全一样的! 但是很奇怪了,为什么会出现这个错误呢? 使用docker rmi 删除掉dev-peerx.travle.xq.com 的镜像,再重新运行即可.

    4 Cannot use str (type *cb.SignaturePolicyEnvelope) as type *common.SignaturePolicyEnvelope

    在创建实例化链码请求的时候

    ccpolity := cauthdsl.SignedByAnyMember([]string{this.OrgID})
    rsp1 := resmgmt.InstantiateCCRequest{
       Name:this.ChainCodeID,
       Path:this.ChaincodeGoPath,
       Version:"1.0",
       Args:nil,
       Policy:ccpolity,
    }
    

    总是提示
    Cannot use str (type *cb.SignaturePolicyEnvelope) as type *common.SignaturePolicyEnvelope less... (⌘F1) Inspection info: Reports composite literals with incompatible types and values
    明明是相同的类型,却总是报错,应该是IDE的问题.把vendor文件夹删除后,就不会有提示了. 再使用vendor对工程进行init 和 add +external 就好了!!

    5 CONNECTION_ Description: dialing connection timed out

    出现这个错误,一般都是配置文件哪个地方写错了,需要细心检查

    相关文章

      网友评论

        本文标题:fabric-sdk-go的简单使用

        本文链接:https://www.haomeiwen.com/subject/jguxkqtx.html