Hyperledger Fabric 1.2系列 -- 将组织添

2018-10-16  本文已影响0人  沙漠中的猴

前提条件

请看上篇内容的配置: 通过脚本方式将组织添加进通道

介绍

我们将向first-network网络添加一个新的Org3组织,原本该网络内存在着Org1Org2两个组织。

确认关闭网络

请确认你已经将网络关闭。如果你执行过eyfn.sh脚本,请关闭网络。

./byfn.sh down

这将关闭网络,删除所有的容器,撤销org3相关的内容。

开始

设置日志级别

cliOrg3cli容器的日志级别设定为DEBUG
对于cli容器可以修改/first-network/docker-compose-cli.yaml文件来设置。例如:

cli:
    container_name: cli
    image: hyperledger/fabric-tools:$IMAGE_TAG
    tty: true
    stdin_open: true
    environment:
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - CORE_LOGGING_LEVEL=DEBUG
      # - CORE_LOGGING_LEVEL=INFO
      - CORE_PEER_ID=cli

对于Org3cli容器,通过修改/first-network/docker-compose-org3.yaml文件来设置。例如:

Org3cli:
    container_name: Org3cli
    image: hyperledger/fabric-tools:$IMAGE_TAG
    tty: true
    stdin_open: true
    environment:
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      #- CORE_LOGGING_LEVEL=INFO
      - CORE_LOGGING_LEVEL=DEBUG
      - CORE_PEER_ID=Org3cli

启动网络

生成证书及MSP等内容:

./byfn.sh generate

启动网络:

./byfn.sh up

你将会看到:

2018-10-12 09:04:26.859 UTC [msp/identity] Sign -> DEBU 046 Sign: digest: 2B28A4F9085F9AB6F93C54E5E6C099740FD7862F14B6268DFA3F5F7A6CCBE2A6
90
===================== Query successful on peer1.org2 on channel 'mychannel' =====================

========= All GOOD, BYFN execution completed ===========


 _____   _   _   ____
| ____| | \ | | |  _ \
|  _|   |  \| | | | | |
| |___  | |\  | | |_| |
|_____| |_| \_| |____/

接下来我们将要手动添加Org3。

生成Org3 加密材料

进入first-network目录下的org3-artifacts

cd org3-artifacts

这里有两个配置文件:

VirtualBox:~/code/fabric/src/fabric-samples/first-network/org3-artifacts$ ls
configtx.yaml  org3-crypto.yaml

首先为Org3生成加密材料:

VirtualBox:~/code/fabric/src/fabric-samples/first-network/org3-artifacts$ cryptogen generate --config=./org3-crypto.yaml
org3.example.com

这个命令会读取org3-crypto.yaml文件,并利用cryptogen工具为Org3组织的两个 peer 生成秘钥和证书。并存放在当前目录的crypto-config文件夹下。

确保你已经将二进制文件添加环境变量下。可以参考上一篇内容添加。

使用configtxgen工具,读取configtx.yaml文件生成org3.json文件,并存放在/first-network/channel-artifacts/目录下。

export FABRIC_CFG_PATH=$PWD && configtxgen -printOrg Org3MSP > ../channel-artifacts/org3.json

这个文件包含了Org3的策略定义,已经base64编码格式的三个重要证书:管理员用户证书(稍后充当Org3的管理员),CA根证书和TLS根目录证书。在稍后的步骤中,我们会将此JSON文件附加到通道配置。

最后,我们要将Orderer OrgMSP材料移植到Org3crypto-config目录中。 我们需要特别关注的是OrdererTLS根证书,它将允许Org3实体与网络对等节点之间的安全通信。

cd ../ && cp -r crypto-config/ordererOrganizations org3-artifacts/crypto-config/

准备CLI环境

配置翻译工具configtxlator可以简化Fabric网络中的配置任务,可以在不同的等效数据格式之间轻松转换(比如:在 protobufs 和 JSON 之间)。

首先,进入 CLI 容器。在这个容器中,我们可以访问crypto-config目录中的两个组织和Orderer组织的MSP资料。

docker exec -it cli bash

导出ORDERER_CACHANNEL_NAME变量:

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  && export CHANNEL_NAME=mychannel

检查时候设置成功:

echo $ORDERER_CA && echo $CHANNEL_NAME

如果你重新启动了 CLI 容器,你就需要重新导出 ORDERER_CACHANNEL_NAME

获取配置

获取channel的配置块

我们需要获取配置的最新版本,因为通道配置元素是版本化的。版本控制可以防止重复或重放配置更改。此外,还有助于确保并发性(比如说删除通道中的某个组织,版本控制有助于防止删除两个组织,不仅仅是要删除的组织)。

peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA

此命令将二进制 protobuf 通道配置块保存到config_block.pb

当你执行完peer channel fetch 后,请注意打印信息的最后一行。

2018-10-15 07:31:44.191 UTC [cli/common] readBlock -> INFO 048 Received block: 2

这里告诉我们mychannel的最新配置块实际上是块2,而不是创世块。默认情况下,该命令返回目标通道的最新配置块,在本例中为第三个块。这是因为 BYFN 脚本定义了两个组织的锚节点,org1 和 org2。

所以,我们有了如下的配置块:

将配置块转化成JSON

我们使用configtxlator工具将通道的配置块解码为 JSON 格式。我们还要删除一些无关的标头,元数据,创建者签名等内容。我们需要通过 jq 工具实现这一目标。

configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config > config.json

这里会生成一个 config.json 的 JSON 文件。

你可以研究一下这个文件,它揭示了底层配置结构和可以进行的其他类型的通道更新。

jq命令允许直接在命令行下对JSON进行操作,包括分片、过滤、转换等。详细的介绍可以参考:https://blog.csdn.net/u011641885/article/details/45559031

添加 Org3 加密资料

我们将再次使用jq工具来配置ORG3。将org3.json附加到通道的应用程序组字段,输出为modified_config.json

jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' config.json ./channel-artifacts/org3.json > modified_config.json

现在,在CLI容器中,我们有了两个JSON文件,config.json 和 modified_config.json。 config.json文件中仅包含 Org1 和 Org2 相关配置,而modified 文件包含所有三个Orgs的配置。此时,我们只需重新编码这两个JSON文件并计算增量即可。

首先, 转换 config.json 回一个名为 protobuf 的config.pb文件:

configtxlator proto_encode --input config.json --type common.Config --output config.pb

接下来,编码modified_config.jsonmodified_config.pb:

configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb

现在configtxlator用来计算这两个配置protobuf之间的增量。此命令将输出一个名为的新protobuf二进制文件org3_update.pb

configtxlator compute_update --channel_id $CHANNEL_NAME --original config.pb --updated modified_config.pb --output org3_update.pb

这个新的配置org3_update.pb包含了 Org3 、 Org1 和 Org2的内容。我们没有包含 Org1 和 Org2 的 MSP和修改策略信息,是因为这些数据已经存在于通道的创世区块中了。因此我们只需要两种配置间的增量。

org3_update.pb 转化成org3_update.json

configtxlator proto_decode --input org3_update.pb --type common.ConfigUpdate | jq . > org3_update.json

现在我们有了一个JSON格式的更新文件org3_update.json,我们需要将原来剥离的标题字段增加上。并命名文件为org3_update_in_envelope.json

echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":'$(cat org3_update.json)'}}}' | jq . > org3_update_in_envelope.json

我们再次使用configtxlator工具,将org3_update_in_envelope.json文件转化成protobuf格式的org3_update_in_envelope.pb文件:

configtxlator proto_encode --input org3_update_in_envelope.json --type common.Envelope --output org3_update_in_envelope.pb

签名并提交配置更新

在我们的 CLI 容器中,存在了一个protobuf 格式的org3_update_in_envelope.pb文件。在将配置写入到账本前,我们需要用Admin用户进行签名。我们通道的应用组策略默认是MAJORITY,也就是需要大多数存在的组织管理员来进行签名。由于我们只有Org1 和 Org2 两个组织,因此我们需要他们的共同签名。如果没有他们共同的签名,排序服务会拒绝该交易的发生。

我们先让Org1的管理员进行签名。由于CLI容器是由Org1 MSP信息来引导启动的,所以我们可以直接使用peer channel signconfigtx命令进行签名。

peer channel signconfigtx -f org3_update_in_envelope.pb

你会看到如下信息:

2018-10-15 09:50:08.824 UTC [msp/identity] Sign -> DEBU 03f Sign: plaintext: 0AF1060A1508021A0608D0C591DE0522...34F5CE5B01E9A6728D8AAB754FF9B771
2018-10-15 09:50:08.824 UTC [msp/identity] Sign -> DEBU 040 Sign: digest: F8CB98C85AA8ADD71B834E3ED813D589591DAC75BAFB71F64CF8C786628A8973

最后一步是切换CLI容器的身份为Org2 Admin用户,我们通过导出特定的四个环境变量来达到目的。导出Org2的环境变量:

export CORE_PEER_LOCALMSPID="Org2MSP"

export 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

export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp

export CORE_PEER_ADDRESS=peer0.org2.example.com:7051

最后我们执行peer channel update命令。这个命令会自动将Org2的签名附着在上面,我们不需要再手动执行签名操作了。

排序服务的更新操作会进行一系列的系统签名和策略检查。会输出一些流式日志,你可以分析他们。打开一个新的终端,输入docker logs -f orderer.example.com

发送更新调用:

peer channel update -f org3_update_in_envelope.pb -c $CHANNEL_NAME -o orderer.example.com:7050 --tls --cafile $ORDERER_CA

你将会看到如下消息摘要:

2018-10-15 10:02:02.417 UTC [channelCmd] update -> INFO 04d Successfully submitted channel update

我们重新打开一个终端,输入docker logs -f peer0.org1.example.com来查看日志信息。
通道更新成功之后,会产生一个新的区块-block 5,并在所以的节点上广播。如果你还记得0-2区块是通道初始化配置,3 和 4 是mycc 链码的实例化和调用。块5是关于Org3的最新通道配置。

如果要检查其内容,请按照演示过程获取和解码配置块。

配置领导者选举

此事例默认是动态的领导者选举,在peer-base.yaml文件中配置的。

新加入的节点使用创世区块来进行配置,不会包含有关在通道配置更新中添加的组织的信息。因此,新的peer 不能使用gossip 服务,因为他们没有办法验证其他peer发送的区块的有效性,直到他们获得将组织添加到channel的配置事务。因此,新加入的peer 必须具有以下配置中的一个,以便他们从orderer服务接收区块。

  1. 静态领导模式:
CORE_PEER_GOSSIP_USELEADERELECTION=false
CORE_PEER_GOSSIP_ORGLEADER=true

对于新添加到通道的peer节点,此配置必须相同。

  1. 动态选举模式:
CORE_PEER_GOSSIP_USELEADERELECTION=true
CORE_PEER_GOSSIP_ORGLEADER=false

将Org3加入通道

此时,通道的配置已经包含了我们新的组织Org3。意味着与其关联的对等节点现在可以加入mychannel

首先,启动Org3的节点和特定的CLI容器。

打开一个新的终端,从first-network目录中启动 Org3 docker compose:

docker-compose -f docker-compose-org3.yaml up -d

下面进入Org3cli 容器:

docker exec -it Org3cli bash

就像我们使用初始CLI容器一样,导出两个关键的环境变量:ORDERER_CA和CHANNEL_NAME:

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 && export CHANNEL_NAME=mychannel

检查是否配置正确:

echo $ORDERER_CA && echo $CHANNEL_NAME

现在我们向排序服务询问创世块。由于我们成功的频道更新,排序服务能够验证Org3的有效性。如果Org3的配置没有被更新,则排序服务会拒绝此请求。

你也可以打开一个新的终端来查看排序服务节点的日志信息

使用peer channel fetch命令来检索区块:

peer channel fetch 0 mychannel.block -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA

注意,我们使用0表示我们想要第0个区块,也就是创世区块。如果我们只是简单的使用peer channel fetch config 命令,我们会收到第5个区块,也就是Org3配置更新的区块。我们也就没有办法获取后续区块了。所以我们应该指定参数0

使用peer channel join命令来加入创世区块。

peer channel join -b mychannel.block

如果你想加入Org3的第二个节点,就要导出TLSADDRESS变量,并且执行peer channel join command命令。

export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer1.org3.example.com/tls/ca.crt && export CORE_PEER_ADDRESS=peer1.org3.example.com:7051

peer channel join -b mychannel.block

升级并调用chaincode

最后一个难题是增加链码的版本并认可Org3的策略。由于要升级链码的版本,所以我们可以放弃之前低版本的链码。所以我们关注升级Org3的链码。

进入Org3 CLI 容器,执行:

peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/

如果想在Org3组织的第二个节点上安装链码,你需要修改相应的环境变量。这个操作不是必须的。你只需要在背书节点或者负责通信的主节点上安装链码即可。

现在我们回到 CLI 容器并在Org1和Org2的节点上安装新版本链码(注意:不是Org3cli容器了)。 之前我们在CLI 容器中修改了环境变量,使用的是Org2管理员身份提交的频道更新事务,因此我们再执行下面命令的时候,代表的是peer0.Org2

如果你不确定当前CLI 具体代表的Org1 还是 Org2 。你可以在CLI 容器内部输入env | grep CORE_PEER_LOCALMSPID来查看。同样需要查看一下是否指定了ORDERER_CACHANNEL_NAME这两个环境变量。

安装链码:

peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/

切换环境变量,作为peer0.org1身份:

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 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp

export CORE_PEER_ADDRESS=peer0.org1.example.com:7051

然后重新执行安装链码命令:

peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/

现在我们准备升级链码。我们并没有对链码的源代码进行修改,只是在mychannelmycc上增加了Org3的背书策略。

支持链码实例化策略的身份,同样也支持链码的升级操作。默认是组织的管理员。

调用链码升级命令

peer chaincode upgrade -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 2.0 -c '{"Args":["init","a","90","b","210"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')"

上面的命令中。v指定新的链码版本,并且链码升级时的背书策略也做了改变-P "OR ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')", 增加了Org3的内容。用c参数表示调用的函数和参数。

与实例化链码一样,链码升级同样调用init方法,可以传递参数。

升级调用会将心产生的区块-块6,添加到账本,并允许Org3节点在背书阶段执行交易。

我们进入Org3cli 容器来查询a 的结果。这个过程可能需要一会儿时间,因为会构建一个新的chaincode容器。

peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

将会返回90

现在我们调用invokeab转移10

peer chaincode invoke -o orderer.example.com:7050  --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}'

最后我们再查询一下a

peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'

你将会得到80

总结

手动添加组织,我们进行了如下步骤:

我只能说,这一顿操作,真的很复杂。

上一篇下一篇

猜你喜欢

热点阅读