美文网首页Hyperledger Fabric 专题
5.1 Hyperledger Fabric 专题 - 构建第一

5.1 Hyperledger Fabric 专题 - 构建第一

作者: furnace | 来源:发表于2019-12-05 19:48 被阅读0次

    Hyperledger Fabric 专题 - 构建第一个 Hyperledger Fabric 网络

    Hyperledger Fabric 最新的文档基于版本是 v2.0 Alpha release。由于示例中相关的 docker 镜像的版本是 v1.4.3,因为相关文档需要参考的版本为 v1.4.3。这些文档链接在本文的 Reference 部分都有涉及。

    1. 本文目的

    参考文档 Building Your First Network 搭建第一个 Hyperledger Fabric 网络。本示例 fabric-samples 需要的 hyperledger fabric 相关的二进制程序安装参考文档 Install Samples, Binaries and Docker Images。而安装 hyperledger fabric 相关的二进制程序所需要的一些前置软件需求,请参考文档 Prerequisites

    2. 构建 Hyperledger Fabric 网络

    根据 fabric-samples/first-network 示例搭建第一个 Hyperledger Fabric 网络。这里,主要是基于提供的脚本 byfn.sh 来快速搭建。脚本 byfn.sh 提供了许多可配置的参数,如果不提供则使用默认值。这里为了简化,先使用默认值。

    需要注意的是,下面的命令需要在 first-network 目录下运行,但是调用的 hyperledger fabric 相关的二进制程序却是在 fabric-samples/bin 目录。

    2.1 脚本 byfn.sh 的详细说明

    Usage:
    byfn.sh <mode> [-c <channel name>] [-t <timeout>] [-d <delay>] [-f <docker-compose-file>] [-s <dbtype>] [-l <language>] [-o <consensus-type>] [-i <imagetag>] [-v]"
      <mode> - one of 'up', 'down', 'restart', 'generate' or 'upgrade'"
        - 'up' - bring up the network with docker-compose up"
        - 'down' - clear the network with docker-compose down"
        - 'restart' - restart the network"
        - 'generate' - generate required certificates and genesis block"
        - 'upgrade'  - upgrade the network from version 1.3.x to 1.4.0"
      -c <channel name> - channel name to use (defaults to \"mychannel\")"
      -t <timeout> - CLI timeout duration in seconds (defaults to 10)"
      -d <delay> - delay duration in seconds (defaults to 3)"
      -f <docker-compose-file> - specify which docker-compose file use (defaults to docker-compose-cli.yaml)"
      -s <dbtype> - the database backend to use: goleveldb (default) or couchdb"
      -l <language> - the chaincode language: golang (default), node, or java"
      -o <consensus-type> - the consensus-type of the ordering service: solo (default), kafka, or etcdraft"
      -i <imagetag> - the tag to be used to launch the network (defaults to \"latest\")"
      -v - verbose mode"
    byfn.sh -h (print this message)"
    
    Typically, one would first generate the required certificates and
    genesis block, then bring up the network. e.g.:"
    
      byfn.sh generate -c mychannel"
      byfn.sh up -c mychannel -s couchdb"
      byfn.sh up -c mychannel -s couchdb -i 1.4.0"
      byfn.sh up -l node"
      byfn.sh down -c mychannel"
      byfn.sh upgrade -c mychannel"
    
    Taking all defaults:"
          byfn.sh generate"
          byfn.sh up"
          byfn.sh down"
    

    2.2 使用脚本 byfn.sh 构建 Fabric 网络的详细步骤

    Step 1. Generate Network Artifacts

    $ ./byfn.sh generate
    

    Step 2. Bring Up the Network

    $ sudo ./byfn.sh up
    

    Step 3. Bring Down the Network

    $ sudo ./byfn.sh down
    

    3. 拓展

    在这一部分,将把上述通过脚本 byfn.sh 构建的过程每一个关键步骤进行详细解构,并通过手动执行命令的方式来构建 hyperledger fabric 网络。

    3.0 前置操作

    下面的操作需要将容器 cli 的 FABRIC_LOGGING_SPEC 日志级别从 INFO 调整为 DEBUG。

    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
        - FABRIC_LOGGING_SPEC=DEBUG
        #- FABRIC_LOGGING_SPEC=INFO
    

    3.1 Crypto Generator

    • cryptogen
      • 生成密码组件的工具
      • 文件位置为 fabric-samples/bin/cryptogen
    • crypto-config.yaml
      • 配置文件,用于说明示例 first-network 需要生成的密码组件
      • 文件位置为 first-network/crypto-config.yaml
    • crypto-config
      • 示例 first-network 生成的密码组件
      • 文件位置为 first-network/crypto-config

    3.2 Configuration Transaction Generator

    • configtxgen
      • 生成构件,如
        • orderer genesis block,
        • channel configuration transaction,
        • and two anchor peer transactions - one for each Peer Org.
      • 文件位置为 fabric-samples/bin/configtxgen
    • configtx.yaml.yaml
      • 配置文件,用于说明示例 first-network 需要的构件,一个 Orderer Org (OrdererOrg),和两个 Peer Orgs (Org1 & Org2)。
      • 文件位置为 first-network/configtx.yaml
    • channel-artifacts
      • 示例 first-network 生成构件
        • channel.tx
        • genesis.block
        • Org1MSPanchors.tx
        • Org2MSPanchors.tx
      • 文件位置为 first-network/channel-artifacts

    3.3 通过工具独立运行上述命令

    下面,我们通过命令 cryptogen 和 configtxgen 手动生成上述的密码组件和示例构件。

    3.3.1 手动生成密码组件

    参考脚本 byfn.sh 中的函数 generateCerts().

    $ ../bin/cryptogen generate --config=./crypto-config.yaml
    org1.example.com
    org2.example.com
    

    最终的密码组件会生成到目录 first-network/crypto-config 中。

    3.3.2 手动生成示例构件

    参考脚本 byfn.sh 中的函数 generateChannelArtifacts().

    $ export FABRIC_CFG_PATH=$PWD
    $ ../bin/configtxgen -profile TwoOrgsOrdererGenesis -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block
    

    最终的示例构件会生成到目录 first-network/channel-artifacts 中,如 first-network/channel-artifacts/genesis.block。

    3.3.3 Create a Channel Configuration Transaction

    注意,需要设置环境变量 CHANNEL_NAME。

    创建 first-network/channel-artifacts/channel.tx
    # The channel.tx artifact contains the definitions for our sample channel
    
    $ export CHANNEL_NAME=mychannel  && ../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME
    
    创建 first-network/channel-artifacts/Org1MSPanchors.tx
    $ ../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP
    
    创建 first-network/channel-artifacts/Org2MSPanchors.tx
    $ ../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP
    

    3.4 Start the network

    如果之前利用脚本 byfn.sh 启动了测试网络,需要先关闭,如执行下列命令

    $ sudo ./byfn.sh down
    

    3.4.1 Start the network

    $ sudo docker-compose -f docker-compose-cli.yaml up -d
    

    或通过下面的命令启动,能够立刻显示日志,但需要另启一个窗口运行下面的 cli 容器。

    $ sudo docker-compose -f docker-compose-cli.yaml up
    

    3.4.2 Create & Join Channel

    $ sudo docker exec -it cli bash
    root@33ab5acc5622:/opt/gopath/src/github.com/hyperledger/fabric/peer#
    

    在容器 cli 中需要设置的环境变量。

    # Environment variables for PEER0
    
    $ 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
    
    $ export CHANNEL_NAME=mychannel
    
    # the channel.tx file is mounted in the channel-artifacts directory within your CLI container
    # as a result, we pass the full path for the file
    # we also pass the path for the orderer ca-cert in order to verify the TLS handshake
    # be sure to export or replace the $CHANNEL_NAME variable appropriately
    
    $ 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
    

    上述命令将会生成文件 <CHANNEL_NAME.block>,这里是 mychannel.block

    将 peer0.org1.example.com 加入到 channel
    # By default, this joins ``peer0.org1.example.com`` only
    # the <CHANNEL_NAME.block> was returned by the previous command
    # if you have not modified the channel name, you will join with mychannel.block
    # if you have created a different channel name, then pass in the appropriately named block
    
    $ peer channel join -b mychannel.block
    
    将 peer0.org2.example.com 加入到 channel
    $ 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
    

    3.4.3 Update the anchor peers

    将 Org1 定义为 peer0.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=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
    $ 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
    
    将 Org2 定义为 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 update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org2MSPanchors.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
    

    3.4.4 Install & Instantiate Chaincode

    Chaincode 代码支持 golang, node, java 语言,默认为 golang,本示例中全部使用默认值。

    Install peer0 in Org1

    首先设置 Org1 相关的环境变量。

    $ 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
    
    # this installs the Go chaincode. For go chaincode -p takes the relative path from $GOPATH/src
    $ peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/
    
    Install peer0 in Org2

    首先设置 Org2 相关的环境变量。

    # Environment variables for PEER0 in Org2
    
    $ 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
    
    # this installs the Go chaincode. For go chaincode -p takes the relative path from $GOPATH/src
    $ peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/
    
    Instantiate the chaincode on the channel
    # be sure to replace the $CHANNEL_NAME environment variable if you have not exported it
    # if you did not install your chaincode with a name of mycc, then modify that argument as well
    $ export CHANNEL_NAME=mychannel
    $ 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 "AND ('Org1MSP.peer','Org2MSP.peer')"
    

    注意,-P "AND ('Org1MSP.peer','Org2MSP.peer')" 中的 AND 可以改为 OR,这意味着只需要 Org1 或 Org2 其中一个组织背书就可以了。

    3.4.5 Query

    # be sure to set the -C and -n flags appropriately
    
    $ peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
    

    3.4.6 Invoke

    # be sure to set the -C and -n flags appropriately
    
    $ peer chaincode invoke -o orderer.example.com:7050 --tls true --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 --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}'
    

    3.4.7 Query

    # be sure to set the -C and -n flags appropriately
    
    $ peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
    

    返回结果

    Query Result: 90
    

    3.4.8 Install peer1 in Org2

    首先设置好环境变量。

    # Environment variables for PEER1 in Org2
    
    $ 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
    
    # this installs the Go chaincode. For go chaincode -p takes the relative path from $GOPATH/src
    $ peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/
    

    3.4.9 Query by peer1 in Org2

    首先需要将 peer1 in Org2 加入到 channel,之后才能响应查询。

    $ 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
    
    # be sure to set the -C and -n flags appropriately
    
    $ peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
    

    返回结果

    Query Result: 90
    

    3.4.10 How do I see these transactions?

    $ sudo docker logs -f cli
    

    3.4.11 How can I see the chaincode logs?

    $ sudo docker logs dev-peer0.org2.example.com-mycc-1.0
    ex02 Init
    Aval = 100, Bval = 200
    ex02 Invoke
    Query Response:{"Name":"a","Amount":"100"}
    ex02 Invoke
    Aval = 90, Bval = 210
    ex02 Invoke
    Query Response:{"Name":"a","Amount":"90"}
    
    $ sudo docker logs dev-peer0.org1.example.com-mycc-1.0
    ex02 Invoke
    Aval = 90, Bval = 210
    
    $ sudo docker logs dev-peer1.org2.example.com-mycc-1.0
    ex02 Invoke
    Query Response:{"Name":"a","Amount":"90"}
    

    3.5 Using CouchDB

    $ sudo docker-compose -f docker-compose-cli.yaml -f docker-compose-couch.yaml up -d
    

    Reference

    项目源代码

    项目源代码会逐步上传到 Github,地址为 https://github.com/windstamp

    Contributor

    1. Windstamp, https://github.com/windstamp

    相关文章

      网友评论

        本文标题:5.1 Hyperledger Fabric 专题 - 构建第一

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