美文网首页
Hyperledger Fabric 1.2系列 -- 将组织添

Hyperledger Fabric 1.2系列 -- 将组织添

作者: 沙漠中的猴 | 来源:发表于2018-10-16 15:28 被阅读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。

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

    • block 0:创世块
    • block 1:Org1 锚节点更新
    • block 2: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

    总结

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

    • 生成新组织的加密材料
    • 进入cli 容器,通过peer channel fetch命令获取通道的配置,并生成protobuf格式的config_block.pb文件。
    • 使用configtxlator工具将protobuf 格式的config_block.pb文件转化成 JSON 文件,并删除一些头部信息。
    • 向生成的JSON 文件中添加进新组织的内容。
    • 将两个JSON 文件转化为两个protobuf 格式的文件。
    • 使用configtxlator工具来计算两个protobuf文件的增量,并生成一个新的protobuf二进制文件。
    • 将新生成的protobuf二进制文件,转化成json文件。
    • 向这个json文件添加进原本删除掉的头部信息。
    • 再将该json文件转化成一个新的protobuf文件。
    • 使用管理员身份执行peer channel signconfigtx来对这个新的protobuf文件进行签名。
    • 切换为另一个组织的管理员来进行签名。
    • 发送peer channel update命令,来进行更新调用。
    • 配置新组织的动态选举规则
    • 启动新组织的Cli容器,导出ORDERER_CACHANNEL_NAME环境变量
    • 执行peer channel fetch来获取创世区块。
    • 使用peer channel join命令来加入区块。
    • 在新的组织容器中执行peer chaincode install安装链码
    • 进入原来的CLI容器,安装链码。切换环境变量到另一个组织管理员,来安装链码。
    • 调用peer chaincode upgrade命令,来升级链码。并指定新的背书策略。
    • 之后就可以进入新组织的容器内部,进行链码调用了。

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

    相关文章

      网友评论

          本文标题:Hyperledger Fabric 1.2系列 -- 将组织添

          本文链接:https://www.haomeiwen.com/subject/abugaftx.html