fabric-sdk-go的简单使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了fabric-sdk-go的简单使用相关的知识,希望对你有一定的参考价值。

参考技术A

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

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

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

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

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

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

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

配置docker-compose文件:

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

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

restart.sh 文件:

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

修改后的sdk配置文件:

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

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

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

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

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

实例化链码

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

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

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

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

错误原因: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 文件中,查看结构体内容:

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

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

总是提示
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 就好了!!

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

fabric-SDK-go初探

1. 环境安装

本教程不会详细解释 Hyperledger Fabric ,可访问其官方文档

本文参照CHAINHERO,在Mac OS上实践,Hyperledger Fabric 框架与 Mac OS X、Windows 和其他 Linux 发行版兼容。

环境安装可参考fabric2.x环境搭建
请确保安装好了docker,go,git等环境

2.打造咱们的第一个区块链网络

为了docker构建区块链网络,我们将使用构建将处理不同角色的虚拟计算机。Hyperledger Fabric 需要大量证书来确保整个端到端流程(TSL、身份验证、签名块……)的加密。这些文件的创建需要一点时间,为了直接解决问题的核心,本文参考的教程已经fixtures在此存储库的文件夹中为准备好了所有这些。

按照我们的存储库命名,src在您的文件夹中创建一个新目录GOPATH:

mkdir -p $GOPATH/src/github.com/chainHero/heroes-service && \\
cd $GOPATH/src/github.com/chainHero/heroes-service

要获取fixtures文件夹,您可以遵循此命令行,它将安装并使用 subversion 从该存储库中获取文件夹。或者从 Github下载zip 文件并仅提取fixtures文件夹。

brew install subversion 

cd $GOPATH/src/github.com/chainHero/heroes-service 

svn checkout https://github.com/chainHero/heroes-service/branches/v1.1.0/fixtures 

rm -rf fixtures/.svn

注:如果是Linux

apt -y subversion && \\
cd $GOPATH/src/github.com/chainHero/heroes-service && \\
svn checkout https://github.com/chainHero/heroes-service/branches/v1.1.0/fixtures &&
rm -rf fixtures/.svn

为了检查网络是否工作,我们将使用docker-compose同时启动或停止所有容器。进入fixtures文件夹,然后运行:

cd $GOPATH/src/github.com/chainHero/heroes-service/fixtures && \\
docker-compose up -d

此时能看到fabric网络已经启动

打开一个新终端运行:
docker ps

可以看到:两个对等节点,一个排序节点和一个 CA 容器。您已经成功地创建了一个新网络,可以与 SDK 一起使用。要停止网络返回上一个终端,按下Ctrl+C并等待所有容器停止。

  • 提示:当网络停止时,所有使用的容器仍然可以访问。例如,这对于检查日志非常有用。您可以使用docker ps -a. 为了清理这些容器,您需要删除它们,docker rm $(docker ps -aq)或者如果您使用了一个docker-compose文件,请转到该文件所在的位置并运行docker-compose down.

  • 提示:您可以docker-compose在后台运行该命令以保持提示。要做到这一点,使用参数-d,像这样:docker-compose up -d。要停止容器,请在所在的同一文件夹中运行docker-compose.yaml命令:(docker-compose stop或docker-compose down在所有容器停止后进行清理)。

3.使用Fabric SDK Go

3.1 配置文件

我们的应用程序需要很多参数,尤其是 Fabric 组件的地址来进行通信。我们将把所有东西都放在一个新的配置文件中,Fabric SDK Go 配置和我们的自定义参数。目前,我们只会尝试使 Fabric SDK Go 使用默认链码:

cd $GOPATH/src/github.com/chainHero/heroes-service && \\
vi config.yaml
name: "heroes-service-network"
#
# Schema version of the content. Used by the SDK to apply the corresponding parsing rules.
#
version: 1.0.0

#
# The client section used by GO SDK.
#
client:

  # Which organization does this application instance belong to? The value must be the name of an org
  # defined under "organizations"
  organization: org1

  logging:
    level: info

  # Global configuration for peer, event service and orderer timeouts
  # if this this section is omitted, then default values will be used (same values as below)
#  peer:
#    timeout:
#      connection: 10s
#      response: 180s
#      discovery:
#        # Expiry period for discovery service greylist filter
#        # The channel client will greylist peers that are found to be offline
#        # to prevent re-selecting them in subsequent retries.
#        # This interval will define how long a peer is greylisted
#        greylistExpiry: 10s
#  eventService:
#    # Event service type (optional). If not specified then the type is automatically
#    # determined from channel capabilities.
#    type: (deliver|eventhub)
    # the below timeouts are commented out to use the default values that are found in
    # "pkg/fab/endpointconfig.go"
    # the client is free to override the default values by uncommenting and resetting
    # the values as they see fit in their config file
#    timeout:
#      connection: 15s
#      registrationResponse: 15s
#  orderer:
#    timeout:
#      connection: 15s
#      response: 15s
#  global:
#    timeout:
#      query: 180s
#      execute: 180s
#      resmgmt: 180s
#    cache:
#      connectionIdle: 30s
#      eventServiceIdle: 2m
#      channelConfig: 30m
#      channelMembership: 30s
#      discovery: 10s
#      selection: 10m

  # Root of the MSP directories with keys and certs.
  cryptoconfig:
    path: $GOPATH/src/github.com/chainHero/heroes-service/fixtures/crypto-config

  # Some SDKs support pluggable KV stores, the properties under "credentialStore"
  # are implementation specific
  credentialStore:
    path: /tmp/heroes-service-store

    # [Optional]. Specific to the CryptoSuite implementation used by GO SDK. Software-based implementations
    # requiring a key store. PKCS#11 based implementations does not.
    cryptoStore:
      path: /tmp/heroes-service-msp

   # BCCSP config for the client. Used by GO SDK.
  BCCSP:
    security:
     enabled: true
     default:
      provider: "SW"
     hashAlgorithm: "SHA2"
     softVerify: true
     level: 256

  tlsCerts:
    # [Optional]. Use system certificate pool when connecting to peers, orderers (for negotiating TLS) Default: false
    systemCertPool: false

    # [Optional]. Client key and cert for TLS handshake with peers and orderers
    client:
      keyfile:
      certfile:

#
# [Optional]. But most apps would have this section so that channel objects can be constructed
# based on the content below. If an app is creating channels, then it likely will not need this
# section.
#
channels:
  # name of the channel
  chainhero:
    # Required. list of orderers designated by the application to use for transactions on this
    # channel. This list can be a result of access control ("org1" can only access "ordererA"), or
    # operational decisions to share loads from applications among the orderers.  The values must
    # be "names" of orgs defined under "organizations/peers"
    # deprecated: not recommended, to override any orderer configuration items, entity matchers should be used.
    # orderers:
    #  - orderer.example.com

    # Required. list of peers from participating orgs
    peers:
      peer0.org1.hf.chainhero.io:
        # [Optional]. will this peer be sent transaction proposals for endorsement? The peer must
        # have the chaincode installed. The app can also use this property to decide which peers
        # to send the chaincode install request. Default: true
        endorsingPeer: true

        # [Optional]. will this peer be sent query proposals? The peer must have the chaincode
        # installed. The app can also use this property to decide which peers to send the
        # chaincode install request. Default: true
        chaincodeQuery: true

        # [Optional]. will this peer be sent query proposals that do not require chaincodes, like
        # queryBlock(), queryTransaction(), etc. Default: true
        ledgerQuery: true

        # [Optional]. will this peer be the target of the SDK's listener registration? All peers can
        # produce events but the app typically only needs to connect to one to listen to events.
        # Default: true
        eventSource: true

      peer1.org1.hf.chainhero.io:

    policies:
      #[Optional] options for retrieving channel configuration blocks
      queryChannelConfig:
        #[Optional] min number of success responses (from targets/peers)
        minResponses: 1
        #[Optional] channel config will be retrieved for these number of random targets
        maxTargets: 1
        #[Optional] retry options for query config block
        retryOpts:
          #[Optional] number of retry attempts
          attempts: 5
          #[Optional] the back off interval for the first retry attempt
          initialBackoff: 500ms
          #[Optional] the maximum back off interval for any retry attempt
          maxBackoff: 5s
          #[Optional] he factor by which the initial back off period is exponentially incremented
          backoffFactor: 2.0


#
# list of participating organizations in this network
#
organizations:
  org1:
    mspid: org1.hf.chainhero.io
    cryptoPath: peerOrganizations/org1.hf.chainhero.io/users/userName@org1.hf.chainhero.io/msp
    peers:
      - peer0.org1.hf.chainhero.io
      - peer1.org1.hf.chainhero.io

    # [Optional]. Certificate Authorities issue certificates for identification purposes in a Fabric based
    # network. Typically certificates provisioning is done in a separate process outside of the
    # runtime network. Fabric-CA is a special certificate authority that provides a REST APIs for
    # dynamic certificate management (enroll, revoke, re-enroll). The following section is only for
    # Fabric-CA servers.
    certificateAuthorities:
      - ca.org1.hf.chainhero.io

#
# List of orderers to send transaction and channel create/update requests to. For the time
# being only one orderer is needed. If more than one is defined, which one get used by the
# SDK is implementation specific. Consult each SDK's documentation for its handling of orderers.
#
orderers:
  orderer.hf.chainhero.io:
    url: localhost:7050

    # these are standard properties defined by the gRPC library
    # they will be passed in as-is to gRPC client constructor
    grpcOptions:
      ssl-target-name-override: orderer.hf.chainhero.io
      # These parameters should be set in coordination with the keepalive policy on the server,
      # as incompatible settings can result in closing of connection.
      # When duration of the 'keep-alive-time' is set to 0 or less the keep alive client parameters are disabled
      keep-alive-time: 0s
      keep-alive-timeout: 20s
      keep-alive-permit: false
      fail-fast: false
      # allow-insecure will be taken into consideration if address has no protocol defined, if true then grpc or else grpcs
      allow-insecure: false

    tlsCACerts:
      # Certificate location absolute path
      path: $GOPATH/src/github.com/chainHero/heroes-service/fixtures/crypto-config/ordererOrganizations/hf.chainhero.io/tlsca/tlsca.hf.chainhero.io-cert.pem
#
# List of peers to send various requests to, including endorsement, query
# and event listener registration.
#
peers:
  peer0.org1.hf.chainhero.io:
    # this URL is used to send endorsement and query requests
    url: localhost:7051
    # eventUrl is only needed when using eventhub (default is delivery service)
    eventUrl: localhost:7053

    grpcOptions:
      ssl-target-name-override: peer0.org1.hf.chainhero.io
      # These parameters should be set in coordination with the keepalive policy on the server,
      # as incompatible settings can result in closing of connection.
      # When duration of the 'keep-alive-time' is set to 0 or less the keep alive client parameters are disabled
      keep-alive-time: 0s
      keep-alive-timeout: 20s
      keep-alive-permit: false
      fail-fast: false
      # allow-insecure will be taken into consideration if address has no protocol defined, if true then grpc or else grpcs
      allow-insecure: false

    tlsCACerts:
      # Certificate location absolute path
      path: $GOPATH/src/github.com/chainHero/heroes-service/fixtures/crypto-config/peerOrganizations/org1.hf.chainhero.io/tlsca/tlsca.org1.hf.chainhero.io-cert.pem

  peer1.org1.hf.chainhero.io:
    # this URL is used to send endorsement and query requests
    url: localhost:8051
    # eventUrl is only needed when using eventhub (default is delivery service)
    eventUrl: localhost:8053

    grpcOptions:
      ssl-target-name-override: peer1.org1.hf.chainhero.io
      # These parameters should be set in coordination with the keepalive policy on the server,
      # as incompatible settings can result in closing of connection.
      # When duration of the 'keep-alive-time' is set to 0 or less the keep alive client parameters are disabled
      keep-alive-time: 0s
      keep-alive-timeout: 20s
      keep-alive-permit: false
      fail-fast: false
      # allow-insecure will be taken into consideration if address has no protocol defined, if true then grpc or else grpcs
      allow-insecure: false

    tlsCACerts:
      # Certificate location absolute path
      path: $GOPATH/src/github.com/chainHero/heroes-service/fixtures/crypto-config/peerOrganizations/org1.hf.chainhero.io/tlsca/tlsca.org1.hf.chainhero.io-cert.pem

#
# Fabric-CA is a special kind of Certificate Authority provided by Hyperledger Fabric which allows
# certificate management to be done via REST APIs. Application may choose to use a standard
# Certificate Authority instead of Fabric-CA, in which case this section would not be specified.
#
certificateAuthorities:
  ca.org1.hf.chainhero.io:
    url: http://localhost:7054
    # Fabric-CA supports dynamic user enrollment via REST APIs. A "root" user, a.k.a registrar, is
    # needed to enroll and invoke new users.
    httpOptions:
      verify: false
    registrar:
      enrollId: admin
      enrollSecret: adminpw
    # [Optional] The optional name of the CA.
    caName: ca.org1.hf.chainhero.io
    tlsCACerts:
      # Certificate location absolute path
      path: $GOPATH/src/github.com/chainHero/heroes-service/fixtures/crypto-config/peerOrganizations/org1.hf.chainhero.io/ca/ca.org1.hf.chainhero.io-cert.pem

entityMatchers:
  peer:
    - pattern: (\\w*)peer0.org1.hf.chainhero.io(\\w*)
      urlSubstitutionExp: localhost:7051
      eventUrlSubstitutionExp: localhost:7053
      sslTargetOverrideUrlSubstitutionExp: peer0.org1.hf.chainhero.io
      mappedHost: peer0.org1.hf.chainhero.io

    - pattern: (\\w*)peer1.org1.hf.chainhero.io(\\w*)
      urlSubstitutionExp: localhost:8051
      eventUrlSubstitutionExp: localhost:8053
      sslTargetOverrideUrlSubstitutionExp: peer1.org1.hf.chainhero.io
      mappedHost: peer1.org1.hf.chainhero.io

  orderer:
    - pattern: (\\w*)orderer.hf.chainhero.io(\\w*)
      urlSubstitutionExp: localhost:7050
      sslTargetOverrideUrlSubstitutionExp: orderer.hf.chainhero.io
      mappedHost: orderer.hf.chainhero.io

  certificateAuthorities:
    - pattern: (\\w*)ca.org1.hf.chainhero.io(\\w*)
      urlSubstitutionExp: http://localhost:7054
      mappedHost: ca.org1.hf.chainhero.io

配置文件也可以在这里找到: config.yaml

3.2初始化

我们添加一个名为的新文件夹blockchain,该文件夹将包含与网络通信的整个接口。我们将仅在此文件夹中看到 Fabric SDK Go。

mkdir $GOPATH/src/github.com/chainHero/heroes-service/blockchain

现在,我们添加一个名为的新 go 文件setup.go:

vi $GOPATH/src/github.com/chainHero/heroes-service/blockchain/setup.go
package blockchain

import (
	"fmt"
	mspclient "github.com/hyperledger/fabric-sdk-go/pkg/client/msp"
	"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt"
	"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry"
	"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp"
	"github.com/hyperledger/fabric-sdk-go/pkg/core/config"
	"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
	"github.com/pkg/errors"
)

// FabricSetup implementation
type FabricSetup struct 
	ConfigFile      string
	OrgID           string
	OrdererID	string
	ChannelID       string
	ChainCodeID     string
	initialized     bool
	ChannelConfig   string
	ChaincodeGoPath string
	ChaincodePath   string
	OrgAdmin        string
	OrgName         string
	UserName        string
	admin           *resmgmt.Client
	sdk             *fabsdk.FabricSDK


// Initialize reads the configuration file and sets up the client, chain and event hub
func (setup *FabricSetup) Initialize() error 

	// Add parameters for the initialization
	if setup.initialized 
		return errors.New("sdk already initialized")
	

	// Initialize the SDK with the configuration file
	sdk, err := fabsdk.New(config.FromFile(setup.ConfigFile))
	if err != nil 
		return errors.WithMessage(err, "failed to create SDK")
	
	setup.sdk = sdk
	fmt.Println("SDK created")

	// The resource management client is responsible for managing channels (create/update channel)
	resourceManagerClientContext := setup.sdk.Context(fabsdk.WithUser(setup.OrgAdmin), fabsdk.WithOrg(setup.OrgName))
	if err != nil 
		return errors.WithMessage(err, "failed to load Admin identity")
	
	resMgmtClient, err := resmgmt.New(resourceManagerClientContext)
	if err != nil 
		return errors.WithMessage(err, "failed to create channel management client from Admin identity")
	
	setup.admin = resMgmtClient
	fmt.Println("Ressource management client created")

	// The MSP client allow us to retrieve user information from their identity, like its signing identity which we will need to save the channel
	mspClient, err := mspclient.New(sdk.Context(), mspclient.WithOrg(setup.OrgName))
	if err != nil 
		return errors.WithMessage(err, "failed to create MSP client")
	
	adminIdentity, err := mspClient.GetSigningIdentity(setup.OrgAdmin)
	if err != nil 
		return errors.WithMessage(err, "failed to get admin signing identity")
	
	req := resmgmt.SaveChannelRequestChannelID: setup.ChannelID, ChannelConfigPath: setup.ChannelConfig, SigningIdentities: []msp.SigningIdentityadminIdentity
	txID, err := setup.admin.SaveChannel(req, resmgmt.WithOrdererEndpoint(setup.OrdererID))
	if err != nil || txID.TransactionID == "" 
		return errors.WithMessage(err, "failed to save channel")
	
	fmt.Println("Channel created")

	// Make admin user join the previously created channel
	if err = setup.admin.JoinChannel(setup.ChannelID, resmgmt.WithRetry(retry.DefaultResMgmtOpts), resmgmt.WithOrdererEndpoint(setup.OrdererID)); err != nil 
		return errors.WithMessage(err, "failed to make admin join channel")
	
	fmt.Println("Channel joined")

	fmt.Println("Initialization Successful")
	setup.initialized = true
	return nil


func (setup *FabricSetup) CloseSDK() 
	setup.sdk.Close()

该文件可在此处获得: blockchain/setup.go
在这个阶段,只初始化了一个将与对等方、CA 和排序者通信的客户端。还创建了一个新频道并将这个对等点连接到这个频道。有关更多信息,请参阅代码中的注释。

3.3测试

为了确保客户端成功初始化了他的所有组件,我们将在启动网络的情况下进行一个简单的测试。为了做到这一点,我们需要构建 go 代码。由于我们没有任何主文件,我们必须添加一个:

cd $GOPATH/src/github.com/chainHero/heroes-service && \\
vi main.go
package main

import (
	"fmt"
	"github.com/chainHero/heroes-service/blockchain"
	"os"
)

func main() 
	// Definition of the Fabric SDK properties
	fSetup := blockchain.FabricSetup
		// Network parameters 
		OrdererID: "orderer.hf.chainhero.io",

		// Channel parameters
		ChannelID:     "chainhero",
		ChannelConfig: os.Getenv("GOPATH") + "/src/github.com/chainHero/heroes-service/fixtures/artifacts/chainhero.channel.tx",

		// Chaincode parameters
		ChainCodeID:     "heroes-service",
		ChaincodeGoPath: os.Getenv("GOPATH"),
		ChaincodePath:   "github.com/chainHero/heroes-service/chaincode/",
		OrgAdmin:        "Admin",
		OrgName:         "org1",
		ConfigFile:      "config.yaml",

		// User parameters
		UserName: "User1",
	

	// Initialization of the Fabric SDK from the previously set properties
	err := fSetup.Initialize()
	if err != nil 
		fmt.Printf("Unable to initialize the Fabric SDK: %v\\n", err)
		return
	
	// Close SDK
	defer fSetup.CloseSDK()	

该文件可在此处获得: main.go

使用如下命令确保安装依赖

go mod init
go mod vendor

待依赖下载完成后,即可开始编译

cd $GOPATH/src/github.com/chainHero/heroes-service && \\
go build

编译完成后会生成一个可执行的文件

输入命令

./heroes-service

此时就可看到

以上是关于fabric-sdk-go的简单使用的主要内容,如果未能解决你的问题,请参考以下文章

fabric-SDK-go初探

fabric-SDK-go初探

即使配置了GOPTH,也无法下载fabric-sdk-go

Fabric1.4 编写链码

HyperLeger Fabric SDK开发——event

HyperLeger Fabric SDK开发——msp