Fabric多通道网络实战

别来无恙 提交于 2020-03-17 22:25:45

某厂面试归来,发现自己落伍了!>>>

Hyperledger Fabric支持在一组相同的机构之间的多通道部署,每个通道都相当于一个单独的区块链。Fabric的多通道特性不仅可以满足机构之间不同的数据共享需求,同时也可以提高整个Fabric网络的吞吐量。本文将演示如何使用Hyperledger Fabric 1.4.3搭建一个多通道的区块链网络、部署并访问链码。

1、Hyperledger Fabric多通道网络实验环境概述

我们将构造一个包含3个机构的Hyperledger Fabric网络:Org1、Org2和Org3,每个机构中包含一个节点Peer0。网络包含两个通道:由Org1、Org2和Org3组成的ChannelAll,以及由Org1和Org2组成的Channel12,因此这个Fabric网络是多通道的配置。在这两个Fabric通道上我们将部署同样的链码,即Fabrc-Samples中提供的Simple Asset链码:

在这里插入图片描述

2、Hyperledger Fabric多通道网络实验环境搭建

Step 1:在Hyperledger官方提供的fabric-samples目录下克隆本教程提供的示例代码:

cd fabric-samples
git clone https://github.com/kctam/3org2ch_143.git
cd 3org2ch_143

Step 2:为参与Fabric通道的机构生成所需的密码学资料

../bin/cryptogen generate --config=./crypto-config.yaml

Step 3:生成Fabric通道素材

mkdir channel-artifacts && export FABRIC_CFG_PATH=$PWD

../bin/configtxgen -profile OrdererGenesis \
  -outputBlock ./channel-artifacts/genesis.block

export CHANNEL_ONE_NAME=channelall
export CHANNEL_ONE_PROFILE=ChannelAll
export CHANNEL_TWO_NAME=channel12
export CHANNEL_TWO_PROFILE=Channel12

../bin/configtxgen -profile ${CHANNEL_ONE_PROFILE} \
  -outputCreateChannelTx ./channel-artifacts/${CHANNEL_ONE_NAME}.tx \
  -channelID $CHANNEL_ONE_NAME

../bin/configtxgen -profile ${CHANNEL_TWO_PROFILE} \
  -outputCreateChannelTx ./channel-artifacts/${CHANNEL_TWO_NAME}.tx \
  -channelID $CHANNEL_TWO_NAME

../bin/configtxgen -profile ${CHANNEL_ONE_PROFILE} \
  -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors_${CHANNEL_ONE_NAME}.tx \
  -channelID $CHANNEL_ONE_NAME -asOrg Org1MSP

../bin/configtxgen -profile ${CHANNEL_ONE_PROFILE} \
  -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors_${CHANNEL_ONE_NAME}.tx \
  -channelID $CHANNEL_ONE_NAME -asOrg Org2MSP

../bin/configtxgen -profile ${CHANNEL_ONE_PROFILE} \
  -outputAnchorPeersUpdate ./channel-artifacts/Org3MSPanchors_${CHANNEL_ONE_NAME}.tx \
  -channelID $CHANNEL_ONE_NAME -asOrg Org3MSP

../bin/configtxgen -profile ${CHANNEL_TWO_PROFILE} \
  -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors_${CHANNEL_TWO_NAME}.tx \
  -channelID $CHANNEL_TWO_NAME -asOrg Org1MSP

../bin/configtxgen -profile ${CHANNEL_TWO_PROFILE} \
  -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors_${CHANNEL_TWO_NAME}.tx \
  -channelID $CHANNEL_TWO_NAME -asOrg Org2MSP

Step 4:启动所有的容器,最后应当看到有5个容器

docker-compose up -d
docker ps

Step 5:为了便于演示,开启3个终端,并设置排序节点的CA

Org1

docker exec -it cli bash 

export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

Org2

docker exec -e "CORE_PEER_LOCALMSPID=Org2MSP" \
  -e "CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" \
  -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp" \
  -e "CORE_PEER_ADDRESS=peer0.org2.example.com:7051" \
  -it cli bash

export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

Org3

docker exec -e "CORE_PEER_LOCALMSPID=Org3MSP" \
  -e "CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt" \
  -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp" \
  -e "CORE_PEER_ADDRESS=peer0.org3.example.com:7051" \
  -it cli bash

export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

Step 5:在Fabric网络中创建多通道,并将各peer节点分别加入多个通道

首先创建channelall通道,并将3个机构的节点都加入该通道:

Org1

peer channel create -o orderer.example.com:7050 -c channelall \
  -f /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/channelall.tx \
  --tls --cafile $ORDERER_CA

peer channel join -b channelall.block --tls --cafile $ORDERER_CA

peer channel update -o orderer.example.com:7050 -c channelall \
  -f /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/Org1MSPanchors_channelall.tx \
  --tls --cafile $ORDERER_CA

Org2

peer channel join -b channelall.block --tls --cafile $ORDERER_CA

peer channel update -o orderer.example.com:7050 -c channelall \
  -f /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/Org2MSPanchors_channelall.tx \
  --tls --cafile $ORDERER_CA

Org3

peer channel join -b channelall.block --tls --cafile $ORDERER_CA

peer channel update -o orderer.example.com:7050 -c channelall \
  -f /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/Org3MSPanchors_channelall.tx \
  --tls --cafile $ORDERER_CA

然后创建channel12,并将Org1和Org2都加入该通道:

Org1

peer channel create -o orderer.example.com:7050 -c channel12 \
  -f /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/channel12.tx \
  --tls --cafile $ORDERER_CA

peer channel join -b channel12.block --tls --cafile $ORDERER_CA

peer channel update -o orderer.example.com:7050 -c channel12 \
  -f /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/Org1MSPanchors_channel12.tx \
  --tls --cafile $ORDERER_CA

Org2

peer channel join -b channel12.block --tls --cafile $ORDERER_CA

peer channel update -o orderer.example.com:7050 -c channel12 \
  -f /opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts/Org2MSPanchors_channel12.tx \
  --tls --cafile $ORDERER_CA

Step 6:检查各节点已经加入的Fabric通道

在各节点对应的终端中使用如下命令查看当前节点加入的通道:

peer channel list

你应当可以看到org1和org2分别加入了两个通道,而org3则只加入了一个通道。

如果一切顺利,现在你就有了一个包含3个机构的多通道Fabric网络,可以用于测试 任何链码了。

Step 7:在测试完毕后记得清理实验环境,命令如下:

docker-compose down -v
docker rm $(docker ps -aq)
docker rmi $(docker images dev-* -q)

3、Fabric多通道安装Simple Asset链码(SACC)

现在我们的Fabric多通道实验网络已经起来了,可以开始部署链码了。

我们使用fabric-samples内置的SACC链码,其内容如下:

/*
 * Copyright IBM Corp All Rights Reserved
 *
 * SPDX-License-Identifier: Apache-2.0
 */

package main

import (
	"fmt"

	"github.com/hyperledger/fabric/core/chaincode/shim"
	"github.com/hyperledger/fabric/protos/peer"
)

// SimpleAsset implements a simple chaincode to manage an asset
type SimpleAsset struct {
}

// Init is called during chaincode instantiation to initialize any
// data. Note that chaincode upgrade also calls this function to reset
// or to migrate data.
func (t *SimpleAsset) Init(stub shim.ChaincodeStubInterface) peer.Response {
	// Get the args from the transaction proposal
	args := stub.GetStringArgs()
	if len(args) != 2 {
		return shim.Error("Incorrect arguments. Expecting a key and a value")
	}

	// Set up any variables or assets here by calling stub.PutState()

	// We store the key and the value on the ledger
	err := stub.PutState(args[0], []byte(args[1]))
	if err != nil {
		return shim.Error(fmt.Sprintf("Failed to create asset: %s", args[0]))
	}
	return shim.Success(nil)
}

// Invoke is called per transaction on the chaincode. Each transaction is
// either a 'get' or a 'set' on the asset created by Init function. The Set
// method may create a new asset by specifying a new key-value pair.
func (t *SimpleAsset) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
	// Extract the function and args from the transaction proposal
	fn, args := stub.GetFunctionAndParameters()

	var result string
	var err error
	if fn == "set" {
		result, err = set(stub, args)
	} else { // assume 'get' even if fn is nil
		result, err = get(stub, args)
	}
	if err != nil {
		return shim.Error(err.Error())
	}

	// Return the result as success payload
	return shim.Success([]byte(result))
}

// Set stores the asset (both key and value) on the ledger. If the key exists,
// it will override the value with the new one
func set(stub shim.ChaincodeStubInterface, args []string) (string, error) {
	if len(args) != 2 {
		return "", fmt.Errorf("Incorrect arguments. Expecting a key and a value")
	}

	err := stub.PutState(args[0], []byte(args[1]))
	if err != nil {
		return "", fmt.Errorf("Failed to set asset: %s", args[0])
	}
	return args[1], nil
}

// Get returns the value of the specified asset key
func get(stub shim.ChaincodeStubInterface, args []string) (string, error) {
	if len(args) != 1 {
		return "", fmt.Errorf("Incorrect arguments. Expecting a key")
	}

	value, err := stub.GetState(args[0])
	if err != nil {
		return "", fmt.Errorf("Failed to get asset: %s with error: %s", args[0], err)
	}
	if value == nil {
		return "", fmt.Errorf("Asset not found: %s", args[0])
	}
	return string(value), nil
}

// main function starts up the chaincode in the container during instantiate
func main() {
	if err := shim.Start(new(SimpleAsset)); err != nil {
		fmt.Printf("Error starting SimpleAsset chaincode: %s", err)
	}
}

Fabric Samples提供的SACC链码的逻辑很简单:

  • 当链码实例化时就会执行Init()函数,该函数需要两个参数,分别对应键和值
  • 将传入Init()函数的键/值对使用PutState方法保存到账本中
  • 在链码实例化之后,对交易的处理是由Invoke()函数来负责的。 该函数的参数 包括一个方法名以及若干参数。
  • 如果调用Invoke()函数时方法名为set,那么就需要传入两个参数,分别表示要 设置的键和值
  • 如果调用Invoke()函数时方法名为get,那么就需要一个参数,表示要读取的键

通过链码安装操作,就可以在各节点上启动链码。注意在链码实例化之前还不可用。

在各节点对应的终端中使用如下命令安装链码:

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

我们应当可以看到如下的输出结果:

在这里插入图片描述

现在所有的节点上都安装了SACC链码,我们可以实例化这个链码了。

4、Fabric多通道实验1:ChannelAll通道上Fabric链码的实例化与访问

首先我们看包含所有三个机构的ChannelAll通道。

在Org1对应的终端中,在ChannelAll通道上实例化链码:

peer chaincode instantiate -o orderer.example.com:7050 --tls \
  --cafile $ORDERER_CA -C channelall -c '{"Args":["a", "100"]}' \
  -n sacc -v 1.0 -P "OR('Org1MSP.peer', 'Org2MSP.peer', 'Org3MSP.peer')"

我们设置了初始的键/值对为a/100。此外我们设置了背书策略:OR表示只需要3个机构中的任何一个背书即可。

现在让我们在通道ChannelAll上查询键a的值。

进入Org1对应的终端,运行如下命令:

peer chaincode query -C channelall -n sacc -c '{"Args":["get","a"]}'

结果如下:

在这里插入图片描述

现在在Org2对应的终端中运行如下命令:

peer chaincode query -C channelall -n sacc -c '{"Args":["get","a"]}'

结果如下:

在这里插入图片描述

现在在Org3对应的终端中运行如下命令:

peer chaincode query -C channelall -n sacc -c '{"Args":["get","a"]}'

结果如下:

在这里插入图片描述

现在我们可以看到在三个节点上得到了相同的值,它们共享同一个账本。

5、Fabric多通道实验2:在Channel12通道上SACC链码的实例化与交互

现在让我们在通道Channel12上实例化这个SACC链码。

在Org1对应的终端中,运行如下命令:

peer chaincode instantiate -o orderer.example.com:7050 \
  --tls --cafile $ORDERER_CA -C channel12 \
  -c '{"Args":["b", "200"]}' -n sacc -v 1.0 \
  -P "OR('Org1MSP.peer', 'Org2MSP.peer')"

这次我们将初始的键/值对设置为b/200,背书策略为任一机构完成背书即可。

还是从Org1开始:

peer chaincode query -C channel12 -n sacc -c '{"Args":["get","b"]}'

结果如下:

在这里插入图片描述 然后进入Org2对应的终端:

peer chaincode query -C channel12 -n sacc -c '{"Args":["get","b"]}'

结果如下:

在这里插入图片描述

如果我们在Org3对应的终端运行同样的命令,就会看到提示禁止访问。这是 因为Org3没有加入通道Channel12:

peer chaincode query -C channel12 -n sacc -c '{"Args":["get","b"]}'

结果如下:

在这里插入图片描述 如果我们尝试在通道Channel12上读取键a的值,会发现提示没有定义a。 在Hyperledger Fabric中,每个通道都有自己的账本,不同通道的状态是不共享的。

在Org1和Org2的终端中运行如下命令:

peer chaincode query -C channel12 -n sacc -c '{"Args":["get","a"]}'

结果如下:

在这里插入图片描述

6、Fabric多通道实验小节

在本教程中,我们介绍了如何搭建一个多通道Fabric网络,并展示了不同通道的数据隔离能力。如果你需要下载实验中的源代码,可以访问这里

分享一些比特币、以太坊、EOS、Fabric等区块链相关的交互式在线编程实战教程:

  • java比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Java代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Java工程师不可多得的比特币开发学习课程。
  • php比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在Php代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是Php工程师不可多得的比特币开发学习课程。
  • c#比特币开发教程,本课程面向初学者,内容即涵盖比特币的核心概念,例如区块链存储、去中心化共识机制、密钥与脚本、交易与UTXO等,同时也详细讲解如何在C#代码中集成比特币支持功能,例如创建地址、管理钱包、构造裸交易等,是C#工程师不可多得的比特币开发学习课程。
  • java以太坊开发教程,主要是针对java和android程序员进行区块链以太坊开发的web3j详解。
  • python以太坊,主要是针对python工程师使用web3.py进行区块链以太坊开发的详解。
  • php以太坊,主要是介绍使用php进行智能合约开发交互,进行账号创建、交易、转账、代币开发以及过滤器和交易等内容。
  • 以太坊入门教程,主要介绍智能合约与dapp应用开发,适合入门。
  • 以太坊开发进阶教程,主要是介绍使用node.js、mongodb、区块链、ipfs实现去中心化电商DApp实战,适合进阶。
  • ERC721以太坊通证实战,课程以一个数字艺术品创作与分享DApp的实战开发为主线,深入讲解以太坊非同质化通证的概念、标准与开发方案。内容包含ERC-721标准的自主实现,讲解OpenZeppelin合约代码库二次开发,实战项目采用Truffle,IPFS,实现了通证以及去中心化的通证交易所。
  • C#以太坊,主要讲解如何使用C#开发基于.Net的以太坊应用,包括账户管理、状态与交易、智能合约开发与交互、过滤器和交易等。
  • EOS入门教程,本课程帮助你快速入门EOS区块链去中心化应用的开发,内容涵盖EOS工具链、账户与钱包、发行代币、智能合约开发与部署、使用代码与智能合约交互等核心知识点,最后综合运用各知识点完成一个便签DApp的开发。
  • 深入浅出玩转EOS钱包开发,本课程以手机EOS钱包的完整开发过程为主线,深入学习EOS区块链应用开发,课程内容即涵盖账户、计算资源、智能合约、动作与交易等EOS区块链的核心概念,同时也讲解如何使用eosjs和eosjs-ecc开发包访问EOS区块链,以及如何在React前端应用中集成对EOS区块链的支持。课程内容深入浅出,非常适合前端工程师深入学习EOS区块链应用开发。
  • Hyperledger Fabric Nodejs 区块链开发详解,本课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、nodejs链码与应用开发的操作实践,是Nodejs工程师学习Fabric区块链开发的最佳选择。
  • Hyperledger Fabric java 区块链开发详解,课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、java链码与应用开发的操作实践,是java工程师学习Fabric区块链开发的最佳选择。
  • Hyperledger Fabric Go 区块链开发详解,课程面向初学者,内容即包含Hyperledger Fabric的身份证书与MSP服务、权限策略、信道配置与启动、链码通信接口等核心概念,也包含Fabric网络设计、Go链码与应用开发的操作实践,是Go语言工程师学习Fabric区块链开发的最佳选择。
  • tendermint区块链开发详解,本课程适合希望使用tendermint进行区块链开发的工程师,课程内容即包括tendermint应用开发模型中的核心概念,例如ABCI接口、默克尔树、多版本状态库等,也包括代币发行等丰富的实操代码,是go语言工程师快速入门区块链开发的最佳选择。

原文链接:Hyperledger Fabric 1.4 多通道实验 — 汇智网

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!