浅试Hyperledger Fabric go 小项目之应用应用代码

Posted codeookie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅试Hyperledger Fabric go 小项目之应用应用代码相关的知识,希望对你有一定的参考价值。

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

上一篇记录了如何利用Hyperledger Fabric官方test-network运行自己的Chaincode流程,
链接这里
本文记录一个,参考官方 go fabcar示例编写自己的应用代码,并与cc交互。

一、fabcar示例

官方地址
go 语言 fabcar 项目目录结构

fabcar.go 主要的应用代码,runfabcar.sh 一个shell脚本,主要设置环境变量以及启动应用代码。

fabcar.go

主要包含三个功能:

注册和登记应用程序用户

//这个程序使用一个 证书签名请求 (CSR)——现在本地生成公钥和私钥,然后把公钥发送到 CA ,CA 会发布会一个让应用程序使用的证书。这三个证书会保存在钱包中,以便于我们以管理员的身份使用 CA 。
os.Setenv("DISCOVERY_AS_LOCALHOST", "true")
	wallet, err := gateway.NewFileSystemWallet("wallet")
	if err != nil 
		fmt.Printf("Failed to create wallet: %s\\n", err)
		os.Exit(1)
	
// 创建一个新的应用程序用户,它将被用于与区块链交互。
// populateWallet 拿到用户的证书凭据
	if !wallet.Exists("appUser") 
		err = populateWallet(wallet)
		if err != nil 
			fmt.Printf("Failed to populate wallet contents: %s\\n", err)
			os.Exit(1)
		
	
//代码中存在路径定义 要换成自己的路径
ccpPath := filepath.Join(
		"..",
		"..",
		"test-network",
		"organizations",
		"peerOrganizations",
		"org1.example.com",
		"connection-org1.yaml",
	)

连接通道和cc

gw, err := gateway.Connect(
//身份认证		gateway.WithConfig(config.FromFile(filepath.Clean(ccpPath))),
		gateway.WithIdentity(wallet, "appUser"),
	)
	if err != nil 
		fmt.Printf("Failed to connect to gateway: %s\\n", err)
		os.Exit(1)
	
	defer gw.Close()
// 连接通道
// 改成自己的名称
	network, err := gw.GetNetwork("mychannel")
	if err != nil 
		fmt.Printf("Failed to get network: %s\\n", err)
		os.Exit(1)
	
//连接智能合约
// 改成自己的名称
	contract := network.GetContract("fabcar")

测试与cc交互功能,也就是访问cc的函数

//测试创建
result, err = contract.SubmitTransaction("createCar", "CAR10", "VW", "Polo", "Grey", "Mary")
//查询
result, err = contract.EvaluateTransaction("queryCar", "CAR10")
//修改
_, err = contract.SubmitTransaction("changeCarOwner", "CAR10", "Archie")	

runfabcar.sh

ENV_DAL=`echo $DISCOVERY_AS_LOCALHOST`

echo "ENV_DAL:"$DISCOVERY_AS_LOCALHOST

if [ "$ENV_DAL" != "true" ]
then
	export DISCOVERY_AS_LOCALHOST=true
fi

echo "DISCOVERY_AS_LOCALHOST="$DISCOVERY_AS_LOCALHOST

echo "run fabcar..."
# 修改此处改为自己的启动代码名称即可
go run fabcar.go

二、我的示例

应用程序 项目 目录结构

1.连接

封装了一中功能,函数直接调用,标注修改处,需要改成自己的
代码如下:

func Getcontract1() *gateway.Contract 
	err := os.Setenv("DISCOVERY_AS_LOCALHOST", "flase")
	if err != nil 
		log.Fatalf("Error setting DISCOVERY_AS_LOCALHOST environemnt variable: %v", err)
	
	wallet, err := gateway.NewFileSystemWallet("wallet")
	if err != nil 
		log.Fatalf("Failed to create wallet: %v", err)
	
	if !wallet.Exists("appUser") 
		err = populateWallet1(wallet)
		if err != nil 
			log.Fatalf("Failed to populate wallet contents: %v", err)
		
	
//修改
	ccpPath := filepath.Join(
		"..",
		"github.com",
		"fabric-samples",
		"test-network",
		"organizations",
		"peerOrganizations",
		"org1.example.com",
		"connection-org1.yaml",
	)

	gw, err := gateway.Connect(
		// lyj:使用ccpath 的路径 以及 appuser 的身份认证 通过使用Gateway类连接网络
		gateway.WithConfig(config.FromFile(filepath.Clean(ccpPath))),
		gateway.WithIdentity(wallet, "appUser"),
	)
	if err != nil 
		log.Fatalf("Failed to connect to gateway: %v", err)
	
	defer gw.Close()
//修改
	network, err1 := gw.GetNetwork("channeltest")
	if err != nil 
		log.Fatalf("Failed to get network: %v", err1)
	
//修改
	contract := network.GetContract("savelist")

	return contract

func populateWallet1(wallet *gateway.Wallet) error 
//修改
	credPath := filepath.Join(
		"..",
		// "src",
		"github.com",
		"fabric-samples",
		"test-network",
		"organizations",
		"peerOrganizations",
		"org1.example.com",
		"users",
		"User1@org1.example.com",
		"msp",
	)

	certPath := filepath.Join(credPath, "signcerts", "User1@org1.example.com-cert.pem")
	// read the certificate pem
	cert, err := ioutil.ReadFile(filepath.Clean(certPath))
	if err != nil 
		return err
	

	keyDir := filepath.Join(credPath, "keystore")
	// there's a single file in this dir containing the private key
	files, err := ioutil.ReadDir(keyDir)
	if err != nil 
		return err
	
	if len(files) != 1 
		return fmt.Errorf("keystore folder should have contain one file")
	
	keyPath := filepath.Join(keyDir, files[0].Name())
	key, err := ioutil.ReadFile(filepath.Clean(keyPath))
	if err != nil 
		return err
	

	identity := gateway.NewX509Identity("Org1MSP", string(cert), string(key))

	return wallet.Put("appUser", identity)

main 中调用

func main() 
	var contract *gateway.Contract
	contract = manufacture.Getcontract1()
	

2.与CC交互

交互函数 一 中示例,注意传参,参数1 CC中函数名,其他参数对应 CC 中函数的参数,只是string类型。
代码如下:

func (c *Contract) SubmitTransaction(name string, args ...string) ([]byte, error) 
	txn, err := c.CreateTransaction(name)

	if err != nil 
		return nil, err
	

	return txn.Submit(args...)


func (c *Contract) EvaluateTransaction(name string, args ...string) ([]byte, error) 
	txn, err := c.CreateTransaction(name)

	if err != nil 
		return nil, err
	

	return txn.Evaluate(args...)

但是 数据结构,有数组类型

type SvcInfo struct 
	SvcID            string   `json:"SvcID"`
	ManufacturerName string   `json:"ManufacturerName"`
	SvcName          string   `json:"SvcName"`
	SaveSvc          []string `json:"SaveSvc"`

传参

cc 端接收

还可以,整个结构体对象整体json序列化,传递。cc端设置对应参数接收后 反序列化。两端参数要对应起来。

三 运行

将 runfabcar.sh 中 go run fabcar.go 换为自己的代码名称即可。

sh runfabcar.sh

运行后如下所示:

总结

第一次写go和使用Hyperledger Fabric交互的代码,供新手参考理解,自己摸索多有不足,请各位大佬包含指正。

以上是关于浅试Hyperledger Fabric go 小项目之应用应用代码的主要内容,如果未能解决你的问题,请参考以下文章

Hyperledger Fabric 智能合约实战 go语言开发

Hyperledger Fabric 执行 assetTransfer.go 时出现 UNKNOWN: access denied: channel [mychannel] creator org [

Hyperledger Fabric 1.1安装部署-Fabric Samples

Hyperledger Fabric 1.0 公有云安装3--Go部分

Hyperledger Fabric 1.4环境搭建详尽

Hyperledger Fabric 1.4环境搭建详尽