Fabric区块链

Fabric Go SDK 开发

2018-06-14  本文已影响748人  kamiSDY

下载与构建Fabric Go SDK

首先,自从官方获取fabric-sdk-go的源码,有两种方式:

需要注意的是,如果使用git,最好保持go的安装路径。因为如果想进行频繁修改或者debug,直接使用GOPATH的目录结构会很有用,安装也比较方便。

然后,直接根据需求进行编译即可。如果只是想安装依赖,并在sample引用。则可以到项目下执行安装命令。

# In the Fabric SDK Go directory
cd $GOPATH/src/github.com/hyperledger/fabric-sdk-go/

# Optional - Automatically install Go tools used by test suite
make depend-install
可能会遇到的问题
go get github.com/axw/gocov/...
go get github.com/AlekSi/gocov-xml

错误:

go get -v github.com/axw/gocov/...
Fetching https://golang.org/x/tools/cover?go-get=1
https fetch failed: Get https://golang.org/x/tools/cover?go-get=1: dial tcp 216.
239.37.1:443: connectex: A connection attempt failed because the connected party
did not properly respond after a period of time, or established connection fail
ed because connected host has failed to respond.
package golang.org/x/tools/cover: unrecognized import path "golang.org/x/tools/c
over" (https fetch: Get https://golang.org/x/tools/cover?go-get=1: dial tcp 216.
239.37.1:443: connectex: A connection attempt failed because the connected party
did not properly respond after a period of time, or established connection fail
ed because connected host has failed to respond.)

解决方案:
在GOPATH的目录下,按照目录结构创建文件夹,然后手动git克隆项目,直接在执行go get或者直接安装即可。

mkdir -p $GOPATH/src/golang.org/x
cd $GOPATH/src/golang.org/x
git clone https://github.com/golang/net.git
git clone https://github.com/golang/tools.git
# github.com/hyperledger/fabric-sdk-go/pkg/client/common/discovery/greylist
../../go/src/github.com/hyperledger/fabric-sdk-go/pkg/client/common/discovery/greylist/greylist.go:26: undefined: sync.Map
# github.com/hyperledger/fabric-sdk-go/pkg/util/concurrent/lazycache
../../go/src/github.com/hyperledger/fabric-sdk-go/pkg/util/concurrent/lazycache/lazycache.go:46: undefined: sync.Map

发现这个包时Go1.9的feature。所以必须升级。我的版本是1.8.1。
然后删除了/usr/local/go的路径,重新解压新的go放进去。然后出现错误:

bash: /usr/local/go/bin/go: /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory

发现下错了版本,换成64位的就OK了。

sample

如果安装成功,就会发现在GOPATH目录的bin中有很多依赖的组件已经安装成功了。
Fabric Go SDK开发主要有两个注意点:Fabric网络配置和代码编写。

首先,修改配置文件。这里我们直接参考在官方代码中的end2end项目。
配置文件位于$GOPATH/src/github.com/hyperledger/fabric-sdk-go/test/fixtures/config中,我们选用config_test.yaml作为参考。
具体的源码直接大家在项目里找到就行,这里简单说下几个注意的:

organizations:
  org1:
    mspid: org1.org
    cryptoPath:  "peer\\msp"
    peers:
      - peer0
    users:
      Admin:
        cert:
          pem: |
            -----BEGIN CERTIFICATE----
            -----END CERTIFICATE-----

同时在翻看源码的关于初始化过程中,发现了一个关于证书命名的细节。在pkg/msp/certfileuserstore.go中,调用load方法,然后其中调用storeKeyFromUserIdentifier方法。其获取的cert文件名(默认)格式是:key.ID + "@" + key.MSPID + "-cert.pem"

然后,简单的代码例子:

package main

import (
    "encoding/binary"
    "fmt"
    "time"

    "github.com/hyperledger/fabric-sdk-go/pkg/client/channel"
    "github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry"
    "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core"
    "github.com/hyperledger/fabric-sdk-go/pkg/core/config"
    "github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
)

const (
    channelID      = "default"
    orgName        = "bcs06071508"
    orgAdmin       = "Admin"
    ordererOrgName = "bcs06071508"
    ccID           = "obcs-example02"
)

// ExampleCC query and transaction arguments
var queryArgs = [][]byte{[]byte("query"), []byte("b")}
var txArgs = [][]byte{[]byte("move"), []byte("a"), []byte("b"), []byte("1")}

func setupAndRun(configOpt core.ConfigProvider, sdkOpts ...fabsdk.Option) {
    //Init the sdk config
    sdk, err := fabsdk.New(configOpt, sdkOpts...)
    if err != nil {
        fmt.Println("Failed to create new SDK: %s", err)
    }
    defer sdk.Close()
    // ************ setup complete ************** //

    //prepare channel client context using client context
    clientChannelContext := sdk.ChannelContext(channelID, fabsdk.WithUser("Admin"), fabsdk.WithOrg(orgName))

    // Channel client is used to query and execute transactions (Org1 is default org)
    client, err := channel.New(clientChannelContext)

    if err != nil {
        fmt.Println("Failed to create new channel client: %s", err)
    }

    value := queryCC(client)
    fmt.Println("value is d%", int64(binary.BigEndian.Uint64(value)))

    eventID := "test([a-zA-Z]+)"

    // Register chaincode event (pass in channel which receives event details when the event is complete)
    reg, notifier, err := client.RegisterChaincodeEvent(ccID, eventID)
    if err != nil {
        fmt.Println("Failed to register cc event: %s", err)
    }
    defer client.UnregisterChaincodeEvent(reg)

    // Move funds
    executeCC(client)

    select {
    case ccEvent := <-notifier:
        fmt.Println("Received CC event: %#v\n", ccEvent)
    case <-time.After(time.Second * 20):
        fmt.Println("Did NOT receive CC event for eventId(%s)\n", eventID)
    }
}

func executeCC(client *channel.Client) {
    _, err := client.Execute(channel.Request{ChaincodeID: ccID, Fcn: "invoke", Args: txArgs},
        channel.WithRetry(retry.DefaultChannelOpts))
    if err != nil {
        fmt.Println("Failed to move funds: %s", err)
    }
}

func queryCC(client *channel.Client) []byte {
    response, err := client.Query(channel.Request{ChaincodeID: ccID, Fcn: "invoke", Args: queryArgs},
        channel.WithRetry(retry.DefaultChannelOpts))
    if err != nil {
        fmt.Println("Failed to query funds: %s", err)
    }
    fmt.Println(response)

    return response.Payload
}

func main() {
    configPath := "./config.yaml"
    //End to End testing
    setupAndRun(config.FromFile(configPath))
}

核心步骤就是三步:

  1. 初始化SDK对象。
  2. 创建需要的channelContext或者clientContext
  3. 调用相关接口。

简单说几个文件:

参考链接

上一篇下一篇

猜你喜欢

热点阅读