摘要

本周在上周搭建的区块链网络及智能合约基础上进行了开发,成功的解决了上周在客户端容器上无法实例化链码的问题,并在客户端容器上实现了调用链码的操作,但客户端容器是在linux系统的命令行上进行操作的,不方便进行应用开发。于是学习了fabric-go-sdk,并用其创建了资源管理客户端、通道管理客户端,用这两个客户端实现了将节点加入通道、在节点上安装链码、实例化链码的操作。但在调用链码时遇到了问题:
在这里插入图片描述
目前在解决该问题中,解决该问题后,就可马上写好基于区块链的后端服务器了。(由于区块链资源较少,大多数参考资料版本也不完全一样,需要花时间摸索,所以这周就只学了区块链)


一、智能合约在区块链上的部署步骤

  1. 按照配置文件启动区块链网络的各个节点。(若需要在命令行与区块链进行交互,还需要启动客户端容器,也可使用fabric-go-sdk代替客户端容器与区块链忘记交互);
  2. 创建通道文件;
  3. 将各个节点加入通道,在同一通道下的成员,共享同一个账本;
  4. 在需要执行交易及背书的节点上安装链码;
  5. 初始化链码;
  6. 调用链码。

二、用docker容器创建的客户端在命令行上与区块链网络进行交互

2.1 容器内创建通道

peer channel create -o orderer.trace.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/trace.com/msp/tlscacerts/tlsca.trace.com-cert.pem -c mychannel -f ./channel-artifacts/channel.tx 

2.2 加入通道

peer channel join -b mychannel.block

2.3 安装链码

peer chaincode install -n testcc -v 1.0 -p github.com/chaincode/go

2.4 初始化链码

 peer chaincode instantiate -o orderer.trace.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/trace.com/msp/tlscacerts/tlsca.trace.com-cert.pem -C mychannel -n testcc -l golang -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "AND ('OrgGenerateMSP.member')"

2.5 调用链码

  1. 发送交易

    tls: false

    peer chaincode invoke -o orderer.example.com:7050 --tls false --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/trace.com/msp/tlscacerts/tlsca.trace.com-cert.pem -C mychannel -n testcc -c '{"Args":["invoke","a","b","10"]}'
    

    tls: true

    peer chaincode invoke -o orderer.trace.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/trace.com/msp/tlscacerts/tlsca.trace.com-cert.pem -C mychannel -n testcc -c '{"Args":["invoke","a","b","10"]}'
    
  2. 查询

    peer chaincode query -o orderer.trace.com:7050 /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/trace.com/msp/tlscacerts/tlsca.trace.com-cert.pem -C mychannel -n mycc -c '{"Args":["query","a"]}'
    

三、fabric-go-sdk与区块链网络交互

fabric-go-sdk是用来创建客户端,与区块链网络进行交互的。

3.1 步骤

  1. 编写config.yaml配置文件;
  2. 创建fabric-sdk实例;
  3. 创建资源管理客户端,对一系列客户端进行管理,如:创建通道,加入通道,安装链码,实例化链码等;
  4. 创建通道客户端,用来执行调用链码等操作。

3.2 config.yaml配置文件

在该文件中,主要写明白:

  1. 每个客户端的信息,如:所属组织,密钥和证书文件;
  2. fabric网络的结构信息,如orderer组织证书、节点等; 并不需要所有fabric网络的信息,只需要当前client进行通信的那部分网络的配置信息。
# file:config.yaml
name: "trace-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: OrgGenerate

  logging:
    level: info

  # Root of the MSP directories with keys and certs.
  cryptoconfig:
    path: /root/trace/crypto-config

  # Some SDKs support pluggable KV stores, the properties under "credentialStore"
  # are implementation specific
  credentialStore:
    path: /tmp/trace-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/trace-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:
      key:
        path: /root/trace/crypto-config/peerOrganizations/generate.trace.com/users/User1@generate.trace.com/tls/client.key
      cert:
        path: /root/trace/crypto-config/peerOrganizations/generate.trace.com/users/User1@generate.trace.com/tls/client.crt

#
# [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
  mychannel:
    # 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.kevin.kongyixueyuan.com

    # Required. list of peers from participating orgs
    peers:
      peer0.generate.trace.com:
        # [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.generate.trace.com:
        endorsingPeer: true
        chaincodeQuery: true
        ledgerQuery: true
        eventSource: true

    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
      #[Optional] options for retrieving discovery info
      discovery:
        #[Optional] discovery info will be retrieved for these number of random targets
        maxTargets: 2
        #[Optional] retry options for retrieving discovery info
        retryOpts:
          #[Optional] number of retry attempts
          attempts: 4
          #[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
      #[Optional] options for the event service
      eventService:
        # [Optional] resolverStrategy specifies the peer resolver strategy to use when connecting to a peer
        # Possible values: [PreferOrg (default), MinBlockHeight, Balanced]
        #
        # PreferOrg:
        #   Determines which peers are suitable based on block height lag threshold, although will prefer the peers in the
        #   current org (as long as their block height is above a configured threshold). If none of the peers from the current org
        #   are suitable then a peer from another org is chosen.
        # MinBlockHeight:
        #   Chooses the best peer according to a block height lag threshold. The maximum block height of all peers is
        #   determined and the peers whose block heights are under the maximum height but above a provided "lag" threshold are load
        #   balanced. The other peers are not considered.
        # Balanced:
        #   Chooses peers using the configured balancer.
        resolverStrategy: PreferOrg
        # [Optional] balancer is the balancer to use when choosing a peer to connect to
        # Possible values: [Random (default), RoundRobin]
        balancer: Random
        # [Optional] blockHeightLagThreshold sets the block height lag threshold. This value is used for choosing a peer
        # to connect to. If a peer is lagging behind the most up-to-date peer by more than the given number of
        # blocks then it will be excluded from selection.
        # If set to 0 then only the most up-to-date peers are considered.
        # If set to -1 then all peers (regardless of block height) are considered for selection.
        # Default: 5
        blockHeightLagThreshold: 5
        # [Optional] reconnectBlockHeightLagThreshold - if >0 then the event client will disconnect from the peer if the peer's
        # block height falls behind the specified number of blocks and will reconnect to a better performing peer.
        # If set to 0 then this feature is disabled.
        # Default: 10
        # NOTES:
        #   - peerMonitorPeriod must be >0 to enable this feature
        #   - Setting this value too low may cause the event client to disconnect/reconnect too frequently, thereby
        #     affecting performance.
        reconnectBlockHeightLagThreshold: 10
        # [Optional] peerMonitorPeriod is the period in which the connected peer is monitored to see if
        # the event client should disconnect from it and reconnect to another peer.
        # Default: 0 (disabled)
        peerMonitorPeriod: 5s

#
# list of participating organizations in this network
#
organizations:
  OrgGenerate:
    mspid: OrgGenerateMSP
    cryptoPath: peerOrganizations/generate.trace.com/users/{username}@generate.trace.com/msp
    peers:
      - peer0.generate.trace.com
      - peer1.generate.trace.com

    # [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.generate.trace.com
      - tlsca.generate.trace.com

#
# 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.trace.com:
    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.trace.com
      # 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: /root/trace/crypto-config/ordererOrganizations/trace.com/tlsca/tlsca.trace.com-cert.pem

#
# List of peers to send various requests to, including endorsement, query
# and event listener registration.
#
peers:
  peer0.generate.trace.com:
    # 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.generate.trace.com
      # 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: /root/trace/crypto-config/peerOrganizations/generate.trace.com/tlsca/tlsca.generate.trace.com-cert.pem

  peer1.generate.trace.com:
    # 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.generate.trace.com
      # 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: /root/trace/crypto-config/peerOrganizations/generate.trace.com/tlsca/tlsca.generate.trace.com-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.generate.trace.com:
    url: http://localhost:7054
    tlsCACerts:
      # Certificate location absolute path
      path: /root/trace/crypto-config/peerOrganizations/generate.trace.com/ca/ca.generate.trace.com-cert.pem

    # Fabric-CA supports dynamic user enrollment via REST APIs. A "root" user, a.k.a registrar, is
    # needed to enroll and invoke new users.
    registrar:
      enrollId: admin
      enrollSecret: adminpw
    # [Optional] The optional name of the CA.
    caName: ca.generate.trace.com

entityMatchers:
  peer:
    - pattern: (\w*)peer0.generate.trace.com(\w*)
      urlSubstitutionExp: localhost:7051
      eventUrlSubstitutionExp: localhost:7053
      sslTargetOverrideUrlSubstitutionExp: peer0.generate.trace.com
      mappedHost: peer0.generate.trace.com

    - pattern: (\w*)peer1.generate.trace.com(\w*)
      urlSubstitutionExp: localhost:8051
      eventUrlSubstitutionExp: localhost:8053
      sslTargetOverrideUrlSubstitutionExp: peer1.generate.trace.com
      mappedHost: peer1.generate.trace.com

  orderer:
    - pattern: (\w*)orderer.trace.com(\w*)
      urlSubstitutionExp: localhost:7050
      sslTargetOverrideUrlSubstitutionExp: orderer.trace.com
      mappedHost: orderer.trace.com

  certificateAuthorities:
    - pattern: (\w*)ca.generate.trace.com(\w*)
      urlSubstitutionExp: http://localhost:7054
      mappedHost: ca.geberate.trace.com

3.2 实例化go sdk函数

输入config.yaml配置文件地址,返回实例化后的sdk。
该函数主要是使用fabric-go-sdk中的fabsdk.New(config.FromFile(configFile))其中configFilePath就是config.yaml的文件路径。

// 输入config.yaml配置文件地址,返回实例化后的sdk。
func SetupSDK(configFilePath string) (*fabsdk.FabricSDK, error) {
	sdk, err := fabsdk.New(config.FromFile(configFilePath))
	if err != nil {
		return nil, fmt.Errorf("create sdk failed: %v", err)
	}
	fmt.Println("create sdk sucessful")
	return sdk, nil
}

3.3 创建资源管理客户端

输入sdk、管理员名、组织名,返回实例化后的资源管理客户端。
该函数主要是用sdk.Context(fabsdk.WithUser(admin), fabsdk.WithOrg(orgName))创建服务请求req,再用resmgmt.New(req)根据请求创建资源管理客户端sourceClient,可用该客户端进行通道创建、链码安装、实例化链码等操作。

// 输入sdk、管理员名、组织名,返回实例化后的资源管理客户端
func SetupResmg(sdk *fabsdk.FabricSDK, admin string, orgName string) (*resmgmt.Client, error) {
	req := sdk.Context(fabsdk.WithUser(admin), fabsdk.WithOrg(orgName))
	sourceClient, err := resmgmt.New(req)
	if err != nil {
		return nil, fmt.Errorf("create source management failed: %v", err)
	}
	return sourceClient, nil
}

3.4 创建通道管理客户端

输入sdk、通道ID、用户名,返回通道管理客户端。
该函数主要利用sdk.ChannelContext(channelID, fabsdk.WithUser(user))创建请求req,再用channel.New(req)创建通道管理客户端ChannelClient,可用该客户端对链码进行调用操作。

func SetupChannelMg(sdk *fabsdk.FabricSDK, channelID string, user string) (*channel.Client, error) {
	req := sdk.ChannelContext(channelID, fabsdk.WithUser(user))
	ChannelClient, err := channel.New(req)
	if err != nil {
		return nil, fmt.Errorf("create channel client failed: %v", err)
	}
	return ChannelClient, nil
}

四、问题汇总

  1. 初始化链码失败

    找不到网络名

    问题原因
    启动服务配置中,网络名设置错误。
    解决办法在这里插入图片描述
    docker容器启动后,会创建一个以根目录文件夹_default的网络,所以需要修改此处的trace必须为项目根目录的文件夹名称

  2. 调用链码失败

    error: error sending transaction for invoke: could not send: EOF -
    proposal response: version:1 response: payload:"\n
    \242tu\327\261\372F\2679&\205\027\010\255\323\025]\300~\273`\202\316\031zx\316\237\035\333\364\022\356\007\n\327\007\0227\n\n

    问题原因:采用了tls加密通信,但是调用链码时没有指定tls证书
    解决办法:通信时指定证书,例如:

    peer chaincode invoke -o orderer.trace.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/trace.com/msp/tlscacerts/tlsca.trace.com-cert.pem -C mychannel -n testcc -c '{"Args":["invoke","a","b","10"]}'
    
  3. 调用链码成功,但是查询发现数据没有写入账本。
    问题原因
    一般情况下是由于背书策略不满足导致数据没写入账本造成的。
    解决办法:修改背书策略,或者在需要背书的节点也按照链码。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐