简介
在上一节,我们已经以 docker 容器的方式成功启动了 fabric 网络的几个核心服务,接下来我们进入 cli 容器中进行下一步操作,使用下面的命令进入容器内部:
docker exec -it cli bash
成功的话你会看到类似下面的输出:
root@0d78bb69300d:/opt/gopath/src/github.com/hyperledger/fabric/peer#
如果你对刚才的配置文件还有印象的话,进入 cli 容器的目录就是我们在配置文件中设置的 working_dir 的值。
节点身份
如果我们想通过 cli 与 fabric 网络交互,那么发起请求者必须是联盟中的用户,即发起请求时需要提供身份证明,我们在配置文件中已经默认设置了登录用户的身份是联盟中组织 1 的 peer0 用户,所以如果我们想要以这个节点的身份发送请求的话就无需再设置了。
但是,如果你想要使用其他 peer 节点身份又或者是排序节点发送调用,那么就需要使用下面的四个命令覆盖之前设置的用于证明身份的环境变量值(这实际上也告诉我们:我们可以在一个 cli 中使用 4 个不同身份发起请求调用,这在以后的静态多机部署中十分有用,这里不做介绍了)。
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
CORE_PEER_ADDRESS=peer0.org1.example.com:7051
CORE_PEER_LOCALMSPID="Org1MSP"
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
上面这四个命令就将当前客户端发起请求的用户身份设置为组织 1 的 peer0 节点。
创建通道
接下来,我们会把之前创建好的通道配置交易(channel.tx)作为创建通道请求的一部分传递给排序节点。
我们使用 -c 标志指定通道的名称,-f 标志指定通道配置交易文件路径,在这个例子中它是 channel.tx,当然你也可以使用不同的名称挂载你自己的交易配置。
例如,我们上面讲过,在三个组织的场景,我们在 Profiles 中增加了一个通道配置ThreeOrg3Channel,那么我们完全可以使用 configtxgen 工具再生成一个新的通道配置交易newchannel.tx,从而创建了一个可用于 org2 和 org3 隔离通信的通道,只不过我们还没有在联盟中增加 org3,所以这里先不生成这个通道配置交易。
我们使用下面的命令创建一个名为 mychannel 的通道
peer channel create -o orderer.example.com:7050 -c mychannel -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
--tls 表示允许TLS加密通信,
--cafile 是排序节点的根证书的本地路径,允许我们去验证 TLS 握手。
这个命令执行完成后将返回一个区块(名称与我们定义的通道 ID 有关,<channel-ID.block>)。在 fabric 中,所有的操作都是通过交易来体现的,因此当我们执行完这个命令成功发起请求后,最终会以交易的形式上链(存储到某个区块中),这个区块中包含了 channel.tx 中的配置信息,所以我们可以使用它来将节点加入到该通道中。
如果你没有修改默认的通道名称,该命令会默认返回一个名为 mychannel.block 的区块文件。
将节点加入通道
- 我们先把 peer0.org1.example.com 加入通道,使用下面的命令:
peer channel join -b mychannel.block
- 接下来我们将 peer0.org2.example.com 加入通道(需要先切换身份)
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
CORE_PEER_ADDRESS=peer0.org2.example.com:9051
CORE_PEER_LOCALMSPID="Org2MSP"
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
peer channel join -b mychannel.block
- 将 peer1.org1.example.com 加入通道
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
CORE_PEER_ADDRESS=peer1.org1.example.com:8051
CORE_PEER_LOCALMSPID="Org1MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
peer channel join -b mychannel.block
将peer1.org2.example.com 加入通道
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer1.org2.example.com:10051 CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt
peer channel join -b mychannel.block
通道加入规则
我们可以发现,我们在通道中仅加入了组织 1 和组织 2 的节点,而没有加入其他组织的节点,这个原因可以从下面的配置图中找到答案:
我们在第 6 节使用 TwoOrgsChannel 配置生成了通道配置交易 channel.tx ,然后我们刚才又使用 channel.tx 创建了一个名为 mychannel 的通道,这正是我们刚才操作的通道。所以 mychannel 通道也需要遵守 TwoOrgsChannel 中的配置,即服务于联盟 Sampleconsortium 的 org1 和 org2,因此我们在通道中只可以加入属于 org1 和 org2 的节点,否则会因为身份验证失败而加入失败。
到此为止,我们已经将分别属于 org1 和 org2 的 4 个 peer 节点加入了通道 mychannel 中,但是并不是说我们必须将每个组织定义的所有 peer 都加入到通道中,在此只是演示一下如何通过修改环境变量来操作不同组织的不同 peer。在一般情况下,您可以将您想设为锚节点的那个节点加入通道即可,因为节点之间可以通过 Gossip 协议通信交换信息。
Gossip 协议
简单介绍一下 Gossip 协议:Gossip 协议是用来确保在不同组织中的 Peer 节点可以知道彼此。
具体来说,当提交一个包含锚节点更新的配置区块时,Peer 节点会联系锚节点并从锚节点那里获取该节点所知道的所有 Peer 节点的信息。一旦每个组织中至少有一个 Peer 节点已经联系到一个或者多个锚节点的话,锚节点就会知道这个通道中的每个 Peer 节点。
因为 Gossip 通信是不变的,并且 Peer 节点总是会获悉它们不知道的 Peer 节点信息,这样就建立起了一个通道成员的通用视图(可以类比计算机网络中的RIP路由协议)。
举个例子,假设通道中有三个组织:A、B 和 C,组织 C 定义的锚节点为 peer0.orgC,当 peer1.orgA 与 peer0.orgC 通信的时候,它会告诉 peer0.orgC 同一个组织中peer0.orgA 的信息。然后当 peer1.orgB 与 peer0.orgC 通信的时候,peer0.orgC 会告诉 peer1.orgB 关于 peer0.orgA 的信息。这样 B 就知道了 A 的信息,之后组织 A 和 B 就可以直接的通信并交换成员信息而不需要任何来自 peer0.orgC 的帮助了。
由于组织间的通信要基于 Gossip 来工作,所以在通道配置中至少要定义一个锚节点,建议每个组织提供它们自己的一组锚节点。
查看节点加入的通道信息
您可以使用命令来查看当前操作的节点加入了哪些通道
peer channel list
总结
我们在本篇文章中介绍了如何根据通道配置交易创建一个通道,也介绍了如何根据创建通道返回的区块将所有节点加入通道中,顺便讲了一下通道的准入规则,最后简单介绍了一下 gossip 协议的工作原理。
接下来我们需要对通道进行更新(需要将配置变更上链)。