Fabric SDK GO 的使用

a. 配置

应用程序需要很多参数,特别是Fabric组件的通信地址。 现在把所有内容放入新的配置文件中(Fabric SDK Go配置和自定义参数)。

$ cd $GOPATH/src/github.com/kongyixueyuan.com/bill

$ vim config.yaml

源文件地址,可以下载替换 config.yaml

b. 初始化

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

$ mkdir blockchain

现在,添加一个名为startInit.go的go文件:

$ vim blockchain/startInit.go 
package blockchain

import (
	"fmt"
	"github.com/hyperledger/fabric-sdk-go/api/apitxn/chmgmtclient"
	"github.com/hyperledger/fabric-sdk-go/api/apitxn/resmgmtclient"
	"github.com/hyperledger/fabric-sdk-go/pkg/config"
	"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
	"time"
)

// FabricSetup implementation
type FabricSetup struct {
	ConfigFile      string
	ChannelID       string
	initialized     bool
	ChannelConfig   string
	OrgAdmin        string
	OrgName         string
	admin           resmgmtclient.ResourceMgmtClient
	sdk             *fabsdk.FabricSDK
}

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

	fmt.Println("开始初始化......")

	if setup.initialized {
		return fmt.Errorf("sdk已初始化完毕\n")
	}

	// 使用指定的配置文件创建SDK
	sdk, err := fabsdk.New(config.FromFile(setup.ConfigFile))
	if err != nil {
		return fmt.Errorf("SDK创建失败: %v\n", err)
	}
	setup.sdk = sdk

	// 根据指定的具有特权的用户创建用于管理通道的客户端API
	chMgmtClient, err := setup.sdk.NewClient(fabsdk.WithUser(setup.OrgAdmin), fabsdk.WithOrg(setup.OrgName)).ChannelMgmt()
	if err != nil {
		return fmt.Errorf("SDK添加管理用户失败: %v\n", err)
	}

	// 获取客户端的会话用户(目前只有session方法能够获取)
	session, err := setup.sdk.NewClient(fabsdk.WithUser(setup.OrgAdmin), fabsdk.WithOrg(setup.OrgName)).Session()
	if err != nil {
		return fmt.Errorf("获取会话用户失败 %s, %s: %s\n", setup.OrgName, setup.OrgAdmin, err)
	}
	orgAdminUser := session

	// 指定用于创建或更新通道的参数
	req := chmgmtclient.SaveChannelRequest{ChannelID: setup.ChannelID, ChannelConfig: setup.ChannelConfig, SigningIdentity: orgAdminUser}
	// 使用指定的参数创建或更新通道
	err = chMgmtClient.SaveChannel(req)
	if err != nil {
		return fmt.Errorf("创建通道失败: %v\n", err)
	}

	time.Sleep(time.Second * 5)

	// 创建一个用于管理系统资源的客户端API。
	setup.admin, err = setup.sdk.NewClient(fabsdk.WithUser(setup.OrgAdmin)).ResourceMgmt()
	if err != nil {
		return fmt.Errorf("创建资源管理客户端失败: %v\n", err)
	}

	// 将peer加入通道
	if err = setup.admin.JoinChannel(setup.ChannelID); err != nil {
		return fmt.Errorf("peer加入通道失败: %v\n", err)
	}

	fmt.Println("初始化成功")
	setup.initialized = true
	return nil
}

在这个阶段,我们只初始化一个客户端,它将与 peer,CA 和 orderer进行通信。 还创建了一个新通道, 并将Peer节点加入到此通道中

C. 测试

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

$ vim main.go
package main

import (
	"fmt"
	"github.com/kongyixueyuan.com/bill/blockchain"
	"os"
)

func main() {
	// 定义SDK属性
	fSetup := blockchain.FabricSetup{
		OrgAdmin:        "Admin", 
		OrgName:         "Org1", 
		ConfigFile:      "config.yaml",
		
		// 通道相关 
		ChannelID:       "mychannel",
		ChannelConfig:   os.Getenv("GOPATH") + "/src/github.com/kongyixueyuan.com/bill/fixtures/artifacts/channel.tx",
	}

	// 初始化SDK
	err := fSetup.Initialize()
	if err != nil {
		fmt.Printf("无法初始化Fabric SDK: %v\n", err)
	}
}

指定了环境的GOPATH,用来编译链码

在开始编译之前,最后一件事是使用一个vendor目录来包含我们所有的依赖关系。 在我们的GOPATH中,我们有Fabric SDK Go和其他项目。 当尝试编译应用程序时,Golang会在GOPATH中搜索依赖项,但首先会检查项目中是否存在vendor文件夹。 如果依赖性得到满足,那么Golang就不会去看GOPATH或GOROOT。 这在使用几个不同版本的依赖关系时非常有用(可能会发生一些冲突,比如在例子中有多个BCCSP定义,通过使用像dep这样的工具来处理这些依赖关系在vendor目录中。

当您安装SDK依赖关系时,DEP会自动安装。 如果不是这种情况,您可以阅读以下说明安装它: dep安装

创建一个名为Gopkg.toml的文件并将其复制到里面:

$ vim Gopkg.toml
[[constraint]]
  name = "github.com/hyperledger/fabric"
  revision = "014d6befcf67f3787bb3d67ff34e1a98dc6aec5f"

[[constraint]]
  name = "github.com/hyperledger/fabric-sdk-go"
  revision = "614551a752802488988921a730b172dada7def1d"

这是dep一个限制,以便在 vendor 中指定希望SDK转到特定版本。

保存该文件,然后执行此命令将vendor目录与项目的依赖关系同步(这可能需要一段时间):

下面命令需要命令行翻墙


$ dep ensure

提醒:dep ensure由于时间久,执行一次后即可,在后面的Makefile中可注释@dep ensure命令。

编译应用程序

$ go build

一段时间后,一个名为 bill的新二进制文件将出现在项目的根目录下。 尝试像这样启动二进制文件:

$ ./bill

./bill命令执行失败

此时,它将无法工作,因为没有可以与SDK进行通信的网络。 须先启动网络,然后再次启动应用程序:

$ cd fixtures
$ docker-compose up -d
$ cd ..
$ ./bill

注意 :需要看到“初始化成功”。 如果没有看到则说明出现问题。

现在只用本地网络初始化SDK。 在下一步中,将与链码进行交互。

d. 清理和Makefile

Fabric SDK生成一些文件,如证书,二进制文件和临时文件。 关闭网络不会完全清理环境,当需要重新启动时,这些文件将被重复使用以避免构建过程。 对于开发,可以快速测试,但对于真正的测试,需要清理所有内容并从头开始。

如何清理环境

  • 关闭你的网络: cd $GOPATH/src/github.com/kongyixueyuan.com/bill/fixtures && docker-compose down

  • 删除证书存储(在配置文件中,client.credentialStore中定义): rm -rf /tmp/bill-*

  • 删除一些不是由docker-compose命令生成的docker容器和docker镜像:

    docker rm -f -v `docker ps -a --no-trunc | grep "bill" | cut -d ' ' -f 1` 2>/dev/null
    和 
    docker rmi `docker images --no-trunc | grep "bill" | cut -d ' ' -f 1` 2>/dev/null
      
    

如何更有效率?

可以在一个步骤中自动完成所有这些任务。 构建和启动过程也可以自动化。 为此,将创建一个Makefile。 首先,确保 make 工具:

make --version

如果没有安装make (Ubuntu):

sudo apt install make 

然后使用以下内容在项目的根目录下创建一个名为Makefile的文件:

$ cd $GOPATH/src/github.com/kongyixueyuan.com/bill
$ vim Makefile
.PHONY: all dev clean build env-up env-down run

all: clean build env-up run

dev: build run

##### BUILD
build:
	@echo "Build ..."
	@dep ensure
	@go build
	@echo "Build done"

##### ENV
env-up:
	@echo "Start environment ..."
	@cd fixtures && docker-compose up --force-recreate -d
	@echo "Sleep 15 seconds in order to let the environment setup correctly"
	@sleep 15
	@echo "Environment up"

env-down:
	@echo "Stop environment ..."
	@cd fixtures && docker-compose down
	@echo "Environment down"

##### RUN
run:
	@echo "Start app ..."
	@./bill

##### CLEAN
clean: env-down
	@echo "Clean up ..."
	@rm -rf /tmp/bill-* bill
	@docker rm -f -v `docker ps -a --no-trunc | grep "bill" | cut -d ' ' -f 1` 2>/dev/null || true
	@docker rmi `docker images --no-trunc | grep "bill" | cut -d ' ' -f 1` 2>/dev/null || true
	@echo "Clean up done"

现在完成任务:

  1. 整个环境将被清理干净,
  2. go程序将被编译,
  3. 之后将部署网络
  4. 最后该应用程序将启动并运行。

要使用它,请进入项目的根目录并使用make命令:

  • 任务allmakemake all
  • 任务clean :清理一切并释放网络( make clean
  • 任务build :只需构建应用程序( make build
  • 任务env-up :只需建立网络( make env-up

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦