超级账本学习之三:创建超级账本网络

超级账本网络的创建主要包含四个步骤:

  • 创建网络拓扑结构,创建MSP相关资料并签名
  • 创建通道配置信息
  • 启动网络,并创建通道
  • 安装并实例化链码
超级账本的学习资料Build Your First Network详细讲述了上面几个步骤是怎么完成的。在示例代码中,更多的是使用已经写好的脚本来完成上面的步骤。在这里我们将完全脱离脚本,手动的创建一个超级账本网络。

特别注意:在需要重新执行下面步骤以前,先执行一下[docker-compose -f $COMPOSE_FILE down --volumes],以确保前次执行结果被清空。否则可能出现权限不正确的问题。


创建网络拓扑结构,初始化MSP信息并签名

工具cryptogen用来创建网络的拓扑结构,初始化MSP信息,并对所有组织和节点进行签名。cryptogen位于fabric/build/bin目录下,它使用了crypto-config.yaml作为配置文件,我们可以使用[cryptogen showtemplate]查看配置文件模板。实际上,示例代码的crypto-config.yaml就是基于这个模板修改的。具体的配置方法参加模板说明。示例配置文件生产力如下所在的拓扑网络:


如果,包含了两种类型的组织:OrdererOrgs和PeerOrgs。一个Orderer组织下面有一个节点;而Peers有两个组织,每个组织通过Template创建了两个Peers。因此,根据该配置文件,cryptogen将会生成5个节点:

-    orderer.example.com

-    peer0.org1.example.com

-    peer1.org1.example.com

-    peer0.org2.example.com

-    peer1.org2.example.com

可以使用下面的命令来创建拓扑网络:

cd /opt/gopath/src/github.com/hyperledger/fabric-samples/first-network
../../fabric/build/bin/cryptogen generate --config=./crypto-config.yaml

命令将会在在当前目录下生成crypto-config目录。使用命令[tree crypto-config]命令可以查看目录的整体结构。简单的说,cryptogen完成了以下工作:

  • 为每个组织生成了签名,包括orderer组织和peer组织。
  • 为每个组织生成了MSP信息,包括orderer组织和peer组织。
  • 为组织内的每个成员生成了签名。
  • 为每个组织定了用一个管理员和一个用户。

至此,网络的拓扑结构生成完毕。MSP模块将使用这些内容对节点进行安全管理和认证。

创建通道配置信息

通道配置信息包括三个方面的内容:创世区块、通道配置信息和各个组织的Anchor Peer。使用configtxgen来完成通道配置信息的创建。可以使用[configtxgen --help]查看工具的使用方法。和cryptogen不同,configtxgen指定使用configtx.yaml。

  • configtx.yaml主要定义了两个profile:TwoOrgsOrdererGenesisTwoOrgsChannel。
  • TwoOrgsOrdererGenesis主要用于Orderer节点的定义;TwoOrgsChannel主要用于Peer节点的定义。
  • 每个profile都定义了capability和组织的内部信息;
  • 组织信息都包括Name(节点名字);ID(用来标识该节点);MSPDir(指定msp信息地址,有上面cryptogen工具生成)。
  • 对于Peer节点,还需要定义Anchor Peer的信息。

从这个意义来说,超级账本的分布式更像是基于组织的分布式,这和我们通常理解的分布式和去中心化有很大不同。

创建创世块

创世块的创建可以使用下面的命令完成

export FABRIC_CFG_PATH=$PWD
../../fabric/build/bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block

它使用了TwoOrgsOrdererGenesis的profile,生成了genesis.block区块,因此区块应该是一个和排序服务相关的概念。需要注意的是,这里不能修改区块的名字,在我们创建好通道后区块名字会被修改成为[通道名].block。

创建通道配置信息

通道配置信息可以通过下面的命令创建:

export CHANNEL_NAME=shimzhaochnl
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME

它使用了TwoOrgsChannel的profile,生成了名外shimzhaochnl的通道。通道配置信息保存在了channel.tx文件中。

配置Anchor Peer

Anchor Peer是一个组织内负责与其他组织打交道的门户节点,通常情况它也是背书节点。一个组织可以有多个节点加入到区块链网络,但是必须有至少一个Anchor Peer。Anchor Peer的配置可以使用下面的命令完成:

configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP
由于Anchor Peer定义在TwoOrgsChannelprofile中,上面分别的命令用到了TwoOrgsChannel profile。上面分别为Org1MSP和OrgMSP定义了Anchor Peer。


至此,通道配置信息创建完毕。生成的文件保存在了当前目录的[channel-artifacts]下面。可以使用下面的命令查看创建的区块信息:

../../fabric/build/bin/configtxgen -inspectBlock ./channel-artifacts/genesis.block

也可以使用下面的信息查看通道信息:

../../fabric/build/bin/configtxgen -inspectChannelCreateTx ./channel-artifacts/channel.tx

除此之外,还可以查看组织信息:

../../fabric/build/bin/configtxgen -printOrg Org1MSP

启动网络,创建通道

通道交易信息和创世块准备完毕后就可以启动区块链网络了。在这里我们使用docker-compose-cli.yaml文件启动网络:

vagrant@ubuntu-xenial:first-network$ docker-compose -f docker-compose-cli.yaml up -d
Creating network "net_byfn" with the default driver
Creating peer1.org1.example.com ... 
Creating orderer.example.com ... 
Creating peer0.org2.example.com ... 
Creating peer1.org2.example.com ... 
Creating peer0.org1.example.com ... 
Creating orderer.example.com
Creating peer1.org1.example.com
Creating peer0.org2.example.com
Creating peer1.org2.example.com
Creating peer1.org2.example.com ... done
Creating cli ... 
Creating cli ... done

去掉[-d]可以查看更多的log信息,启动完成后可以使用[docker ps -a]查看所有节点是否正确启动。

网络启动后我们还需要创建通道、加入通道、更新通道的Anchor Peer配置。

创建通道

创建通道以前我们需要进入到cli节点,cli相当于超级账本的一个application,每次在操作peer的时候它都会去读取下面的环境变量以确定要操作哪一个Peer。cli是通过读取下面的配置文件来确定它连接的是哪个Peer节点。当操作的Peer发送变化的时候都需要重新备注这些环境变量,以确保操作的是正确的Peer节点。这些环境变量包括:

  • CORE_PEER_MSPCONFIGPATH:用来指定MSP信息路径,有cryptogen生成
  • CORE_PEER_ADDRESS:用来指定节点的网络地址
  • CORE_PEER_TLS_ROOTCERT_FILE:用来指定数字签名文件路径
  • CORE_PEER_LOCALMSPID:用来指定组织MSPID

因此,首先我们要指定peer0.org1.example.com节点作为cli的连接节点,然后进入cli docker:

vagrant@ubuntu-xenial: first-network$ export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
vagrant@ubuntu-xenial: first-network$ export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
vagrant@ubuntu-xenial: first-network$ export CORE_PEER_LOCALMSPID="Org1MSP"
vagrant@ubuntu-xenial: first-network$ export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

vagrant@ubuntu-xenial: first-network$ docker exec -it cli bash
root@bfe07b081e03:/opt/gopath/src/github.com/hyperledger/fabric/peer#

注意,接下来我们的操作就会在cli docker内部进行了。为了使用方便,先定义一个全局变量:

root@bfe07b081e03:/opt/gopath/src/github.com/hyperledger/fabric/peer#export CHANNEL_NAME=shimzhaochnl

然后,使用下面的命令创建通道:

root@bfe07b081e03:/opt/gopath/src/github.com/hyperledger/fabric/peer#peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

需要说明的是,创建通道本身也是超级账本的一个交易,因此首先交易信息会被发送到Orderder排序节点,Orderer排序服务会将交易信息广播到整个网络的所有节点。上面的命令中指定的channel.tx来自configtxgen创建的通道配置信息;而公钥则是排序节点的公钥。

通道创建完成后我们还需要将每个Peer节点加入到通道中。

加入通道

加入通道需要借助cli容器。比如下面的操作允许我们将peer0.org1.example.com加入到通道:

#设置环境变量
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

#下面的代码在容器内执行,将当期Peer加入通道
peer channel join -b shimzhaochnl.block   #注意通道名

#退出
exit

依次将其余的三个Peer都加入到通道中。可以使用[peer channel list]查看当前Peer加入了哪些通道。

更新通道的Anchor Peer配置

接下来需要制定每个Org的Anchor Peer。这个过程也是通过cli容器来实现的:

#设置环境变量
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

#设置当前连接的Peer为组织的Anchor Peer
peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org1MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

#退出
exit

通过上面的命令设置了peer0.org1.example.com为Org1的Anchor Peer。可以使用同样的方法设置peer0.Org2.example.com为Org2的Anchor Peer。

在进入容器[docker exec -it cli bash]后,可以使用peer命令查看当前链接节点的各种信息。参看[peer --help]了解更多。

安装并实例化链码

链码(即智能合约)是超级账本的重要组成部分。所有的外部程序(application)对账本的访问都是通过链码实现的。对链码的操作包括安装、实例化、查询和更新。

安装链码

链码的安装也需要进入到cli容易,连接到需要安装的Peer节点,然后执行安装命令。下面的命令用于为peer0.org1.example.com安装链码:

#设置环境变量
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

#为当前Peer安装链码
peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/

#退出
exit

链码安装完成后可以使用[peer chaincode list --installed]的命令查看是否已经安装成功。接下来,还需要为其它Peer安装链码,通常我们只需要为Anchor Peer安装链码即可。

实例化链码

链码在安装完成后还需要实例化才能起作用,可以使用下面的方法实例化链码:

#设置环境变量
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

#实例化链码
peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer')"

#退出
exit

需要注意的是:

  • [-p]参数用来指定背书策略。比如[-P "OR('Org1MSP.peer','Org2MSP.peer')"]只需要一个节点背书即可;[-P "AND('Org1MSP.peer','Org2MSP.peer')"]则需要两个节点都背书才可以。
  • 链码的实例化主要是给超级账本的区块付初值。
  • 链码的实例化只需要在任意一个节点完成即可。不需要所有节点都实例化。

查询链码

链码的查询首先需要制定Peer,然后进入cli,再执行查询语句:

#设置环境变量
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

#设置通道名
export CHANNEL_NAME=shimzhaochnl

#调用链码查询
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

#退出
exit

更新链码

同理,链码的更新操作类似如下:

#设置环境变量
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt

#设置通道名
export CHANNEL_NAME=shimzhaochnl

#调用链码更新账本
peer chaincode invoke -o orderer.example.com:7050  --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem  -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}'

#退出
exit

逻辑上来说,所有Peer保存的账本应该是一致的。可以通过切换Peer来验证所有账本是不是同步更新了。

猜你喜欢

转载自blog.csdn.net/JueJingZhiKe/article/details/80060090
今日推荐