首页 > 解决方案 > Hyperledger Fabric:在不同的物理机器上设置相同组织的两个对等点

问题描述

我在 Ubuntu 20.04 机器上建立了区块链测试网络。该网络是根据 fabric-samples Repo https://github.com/hyperledger/fabric-samples建立和设置的。Fabric 版本为 2.3.0,Fabric CA 版本为 1.4.9。我现在的目标是在另一台机器上为同一个组织设置第二个对等点,以将对等点集成到我现有的网络中。这样我也可以在那里安装我的智能合约/链代码,并在第二个对等方上测试我的查询。

简短的摘要:

  1. Ubuntu 20.04 机器,具有一个 peer、一个 orderer 和一个 ca 服务器,每个用于 peer 和 orderer。在互联网提供商处运行

  2. ubuntu 20.04 机器与一个同行。只能通过我们公司的 VPN 访问,因为机器在我们公司的网络中。

我现在进行了 3 次不同的尝试来构建或扩展网络。

1.尝试

在第一次尝试中,我在第一台 Ubuntu 机器上设置了上面已经描述的网络,创建了一个通道并安装/部署了我的链码/智能合约。同时,我还通过组织“Org 1”的 Fabric-CA 服务器为第二个对等点生成了“加密材料”。

然后我将先前生成的“加密材料”复制到第二个 Ubuntu 服务器。之后,使用我的 docker-compose,我启动了第二个对等点。然后我尝试使用以下命令让对等方进入通道:

#!/bin/bash

joinChannel() {
    ##### Umgebungvariablen setzen #####

    # Frage wo die configtx.yaml liegt und setze die Umgebungvariable FABRIC_CFG_PATH
    #read -p "Wo liegt die core.yaml für den peer der dem Channel hinzugefügt werden soll: " configtxpath

export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=$PWD/organizations/peerOrganizations/org1.actiware.com/peers/peer1.org1.actiware.com/tls/ca.cert
export CORE_PEER_MSPCONFIGPATH=$PWD/organizations/peerOrganizations/org1.actiware.com/users/Admin@org1.actiware.com/msp
export CORE_PEER_ADDRESS=localhost:8051
export FABRIC_CFG_PATH=$PWD/newPeer/config

BLOCKFILE=$PWD/channel-artifacts/awchannel.block

echo "use core.yaml from: $FABRIC_CFG_PATH"
echo "Use core peer localmspid: $CORE_PEER_LOCALMSPID"
echo "USe tls rootcertfiel: $CORE_PEER_TLS_ROOTCERT_FILE"
echo "Use Mspconfigpath: $CORE_PEER_MSPCONFIGPATH"
echo "Use adress: $CORE_PEER_ADDRESS"

echo "channel fetch genesis block"
peer channel fetch config -o [IP OF 1. Ubuntu Machine]:7050 --ordererTLSHostnameOverride orderer.actiware.com -c awchannel --tls --cafile $PWD/organizations/ordererOrganizations/actiware.com/orderers/orderer.actiware.com/msp/tlscacerts/tlsca.actiware.com-cert.pem

##### peer dem channel hinzufügen #####

    # Frage wo die block datei ist
    #read -p "Wo liegt die channel_name.block Datei?: " blockfile

    DELAY=3
    MAX_RETRY=5
    local rc=1
    local COUNTER=1
    ## Sometimes Join takes time, hence retry
    while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ]; do
        sleep $DELAY
        peer channel join -b $BLOCKFILE
        res=$?
        let rc=$res
        COUNTER=$(expr $COUNTER + 1)
    done
}

joinChannel

之后在 orderer docker 容器上出现以下错误: Logs of Orderer Docker Container

2. Ubuntu Maschine: Logs of Peer Container

我没有解决这个错误。我猜是因为 Docker 再次为容器提供了自己的 IP,所以来自第一台 Ubuntu 机器上的 orderer 的 Docker 容器和来自第二台 Ubuntu 机器的对等方无法直接相互通信。

2.尝试

在第二次尝试中,我尝试在服务器上本地设置它。然后用第一台 Ubuntu 机器重新启动,而不是通过环境变量设置配置参数。我直接在为其提供的文件(core.yaml、orderer.yaml 和 config.tx)中设置这些。当然,我只设置了在 docker-compose 文件中也设置为环境变量的那些。当然,fabric-ca 服务器及其各自的配置文件也是如此。然后我本地启动了 fabric-ca 服务器并使用 registerEnroll.sh 脚本生成了“加密材料”。然后我使用环境变量 FABRIC_CFG_PATH 启动了 orderer 和 peer。最后但并非最不重要的一点是,我想创建通道并安装链代码,就像在 Docker 尝试中一样。我能够在 orderer 上成功创建通道,并且 peer 能够加入它。但是,当我尝试通过具有对等链码生命周期的 CLI 命令安装链码时,出现错误: Ubuntu机器1上的CC安装错误

3.尝试

然后在最后一次尝试中,如果不是由于某些配置错误,我想弄清楚。所以我决定做所有与fabric-sample相同的事情,只是我不将它安装在docker容器中,而是再次本地安装。为此,我从结构示例中获取了所有配置文件,并编写或复制/粘贴了以下脚本:

完整的NativeScript.sh

#!/bin/bash
#

. utils.sh

export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=${PWD}/config
export VERBOSE=false

#### Start Fabric-CA ####
echo "Start CA-Org1"
set -x
export FABRIC_CA_HOME=$PWD/organizations/fabric-ca/org1
export FABRIC_CA_SERVER_CA_NAME=ca-org1
export FABRIC_CA_SERVER_TLS_ENABLED=true
export FABRIC_CA_SERVER_PORT=7054

fabric-ca-server start -b admin:adminpw -d & >logs/CaOrg1Logs.txt
{ set +x; } 2>/dev/null

sleep 10

echo "Start CA-Orderer"
set -x
export FABRIC_CA_HOME=$PWD/organizations/fabric-ca/ordererOrg
export FABRIC_CA_SERVER_CA_NAME=ca-orderer
export FABRIC_CA_SERVER_TLS_ENABLED=true
export FABRIC_CA_SERVER_PORT=9054

fabric-ca-server start -b admin:adminpw -d & >logs/CaOrdererlogs.txt
{ set +x; } 2>/dev/null

sleep 10

echo "Creating Org1 and Orderer Identities"

. organizations/fabric-ca/registerEnroll.sh

createOrg1

createOrderer

echo "Generating CCP files for Org1"
./organizations/ccp-generate.sh

##### Start Orderer und Peer #####
echo "Start Orderer and Peer"
set -x
export FABRIC_LOGGING_SPEC=INFO
export ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
export ORDERER_GENERAL_LISTENPORT=7050
export ORDERER_GENERAL_LOCALMSPID=OrdererMSP
export ORDERER_GENERAL_LOCALMSPDIR=$PWD/organizations/ordererOrganizations/actiware.com/orderers/orderer.actiware.com/msp
export ORDERER_GENERAL_TLS_ENABLED=true
export ORDERER_GENERAL_TLS_PRIVATEKEY=$PWD/organizations/ordererOrganizations/actiware.com/orderers/orderer.actiware.com/tls/server.key
export ORDERER_GENERAL_TLS_CERTIFICATE=$PWD/organizations/ordererOrganizations/actiware.com/orderers/orderer.actiware.com/tls/server.crt
export ORDERER_GENERAL_TLS_ROOTCAS=[$PWD/organizations/ordererOrganizations/actiware.com/orderers/orderer.actiware.com/tls/server.crt]
export ORDERER_KAFKA_TOPIC_REPLICATIONFACTOR=1
export ORDERER_KAFKA_VERBOSE=true
export ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=$PWD/organizations/ordererOrganizations/actiware.com/orderers/orderer.actiware.com/tls/server.crt
export ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=$PWD/organizations/ordererOrganizations/actiware.com/orderers/orderer.actiware.com/tls/server.key
export ORDERER_GENERAL_CLUSTER_ROOTCAS=[$PWD/organizations/ordererOrganizations/actiware.com/orderers/orderer.actiware.com/tls/server.crt]
export ORDERER_GENERAL_BOOTSTRAPMETHOD=none
export ORDERER_CHANNELPARTICIPATION_ENABLED=true
export ORDERER_ADMIN_TLS_ENABLED=true
export ORDERER_ADMIN_TLS_CERTIFICATE=$PWD/organizations/ordererOrganizations/actiware.com/orderers/orderer.actiware.com/tls/server.crt
export ORDERER_ADMIN_TLS_PRIVATEKEY=$PWD/organizations/ordererOrganizations/actiware.com/orderers/orderer.actiware.com/tls/server.key
export ORDERER_ADMIN_TLS_ROOTCAS=[$PWD/organizations/ordererOrganizations/actiware.com/orderers/orderer.actiware.com/tls/server.crt]
export ORDERER_ADMIN_TLS_CLIENTROOTCAS=[$PWD/organizations/ordererOrganizations/actiware.com/orderers/orderer.actiware.com/tls/server.crt]
export ORDERER_ADMIN_LISTENADDRESS=0.0.0.0:7053

orderer & >logs/ordererlogs.txt

sleep 10

export FABRIC_LOGGING_SPEC=INFO
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_PROFILE_ENABLED=true
export CORE_PEER_TLS_CERT_FILE=$PWD/organizations/peerOrganizations/org1.actiware.com/peers/peer0.org1.actiware.com/tls/server.crt
export CORE_PEER_TLS_KEY_FILE=$PWD/organizations/peerOrganizations/org1.actiware.com/peers/peer0.org1.actiware.com/tls/server.key
export CORE_PEER_TLS_ROOTCERT_FILE=$PWD/organizations/peerOrganizations/org1.actiware.com/peers/peer0.org1.actiware.com/tls/server.crt
export CORE_PEER_ID=peer0.org1.actiware.com
export CORE_PEER_ADDRESS=localhost:7051
export CORE_PEER_LISTENADDRESS=0.0.0.0:7051
export CORE_PEER_CHAINCODEADDRESS=localhost:7052
export CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
export CORE_PEER_GOSSIP_BOOTSTRAP=localhost:7051
export CORE_PEER_GOSSIP_EXTERNALENDPOINT=localhost:7051
export CORE_PEER_LOCALMSPID=Org1MSP

peer node start & >logs/peer0logs.txt
{ set +x; } 2>/dev/null

sleep 10

CREATE_CHANNEL=$(getUserInput "Soll ein Channel erstellt werden? (y/n) ")

if [ $CREATE_CHANNEL == "y" ]; then
    ##### Create Gensisblock, Create and Join Channel #####
    echo "Start to generate the channel"
    CHANNEL_NAME="awchannel"

    set -x
    export FABRIC_CFG_PATH=$PWD/config
    configtxgen -profile TwoOrgsApplicationGenesis -outputBlock ./channel-artifacts/${CHANNEL_NAME}.block -channelID $CHANNEL_NAME

    export ORDERER_CA=${PWD}/organizations/ordererOrganizations/actiware.com/orderers/orderer.actiware.com/msp/tlscacerts/tlsca.actiware.com-cert.pem
    export PEER0_ORG1_CA=${PWD}/organizations/peerOrganizations/org1.actiware.com/peers/peer0.org1.actiware.com/tls/ca.crt
    export ORDERER_ADMIN_TLS_SIGN_CERT=${PWD}/organizations/ordererOrganizations/actiware.com/orderers/orderer.actiware.com/tls/server.crt
    export ORDERER_ADMIN_TLS_PRIVATE_KEY=${PWD}/organizations/ordererOrganizations/actiware.com/orderers/orderer.actiware.com/tls/server.key

    export CORE_PEER_LOCALMSPID="Org1MSP"
    export CORE_PEER_TLS_ENABLED=true
    export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.actiware.com/users/Admin@org1.actiware.com/msp
    export CORE_PEER_ADDRESS=localhost:7051

    osnadmin channel join --channelID $CHANNEL_NAME --config-block ./channel-artifacts/${CHANNEL_NAME}.block -o localhost:7053 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY"

    peer channel join -b ./channel-artifacts/${CHANNEL_NAME}.block
    { set +x; } 2>/dev/null

    CREATE_ANCHOR_PEERS=$(getUserInput "Sollen die Anchor Peers erstellt werden? (y/n)")

    if [ $CREATE_ANCHOR_PEERS == "y" ]; then
        #### Set Anchor Peers ####
        echo "fetch channel config"

        set -x 
        peer channel fetch config_block.pb -o localhost:7050 --ordererTLSHostnameOverride orderer.actiware.com -c $CHANNEL_NAME --tls --cafile "$ORDERER_CA"
        { set +x; } 2>/dev/null

        OUTPUT=${CORE_PEER_LOCALMSPID}config.json
        echo "Decoding config block to json and isolating config to $OUTPUT"
        set -x
        configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config >"${OUTPUT}"
        { set +x; } 2>/dev/null

        echo "Modify the configuration to append the anchor peer "
        set -x
        jq '.channel_group.groups.Application.groups.'${CORE_PEER_LOCALMSPID}'.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "localhost","port": "7051"}]},"version": "0"}}' ${CORE_PEER_LOCALMSPID}config.json > ${CORE_PEER_LOCALMSPID}modified_config.json
        { set +x; } 2>/dev/null

        echo "Create Config Update"

        ORIGINAL=${CORE_PEER_LOCALMSPID}config.json
        MODIFIED=${CORE_PEER_LOCALMSPID}modified_config.json
        OUTPUT=${CORE_PEER_LOCALMSPID}anchors.tx

        set -x
        configtxlator proto_encode --input "${ORIGINAL}" --type common.Config >original_config.pb
        configtxlator proto_encode --input "${MODIFIED}" --type common.Config >modified_config.pb
        configtxlator compute_update --channel_id "${CHANNEL_NAME}" --original original_config.pb --updated modified_config.pb >config_update.pb
        configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate >config_update.json
        echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CHANNEL_NAME'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . >config_update_in_envelope.json
        configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope >"${OUTPUT}"
        { set +x; } 2>/dev/null

        echo "Update Anchor Peer"
        peer channel update -o localhost:7050 --ordererTLSHostnameOverride orderer.actiware.com -c $CHANNEL_NAME -f ${CORE_PEER_LOCALMSPID}anchors.tx --tls --cafile "$ORDERER_CA"

        DEPLOY_CC=$(getUserInput "Soll der Chaincode deployed werden?(y/n)")
        if [ $DEPLOY_CC == "y" ]; then
            ##### deploy Chaincode #####
            echo "deploy chaincode"
            CC_SRC_PATH=$PWD/StandardContract

            set -x
            export FABRIC_CFG_PATH=$PWD/config

            pushd $CC_SRC_PATH
            GO111MODULE=on go mod vendor
            popd

            peer lifecycle chaincode package packaged_chaincode.tar.gz --path ${CC_SRC_PATH} --lang golang --label ${CHANNEL_NAME}_1.0

            peer lifecycle chaincode install packaged_chaincode.tar.gz

            peer lifecycle chaincode queryinstalled
        fi
    fi
fi

实用程序.sh

#!/bin/bash

function getUserInput() {
    read -p "$1" USER_INPUT
    
    while [ -z "$USER_INPUT" ] || [ "$USER_INPUT" = "NA" ]
    do
        echo "Keine Eingabe erfasst. Bitte versuchen Sie es erneut." >&2
        read -p "$1" USER_INPUT
    done

    echo $USER_INPUT
}

# println echos string
function println() {
  echo -e "$1"
}

# errorln echos i red color
function errorln() {
  println "${C_RED}${1}${C_RESET}"
}

# successln echos in green color
function successln() {
  println "${C_GREEN}${1}${C_RESET}"
}

# infoln echos in blue color
function infoln() {
  println "${C_BLUE}${1}${C_RESET}"
}

# warnln echos in yellow color
function warnln() {
  println "${C_YELLOW}${1}${C_RESET}"
}

# fatalln echos in red color and exits with fail status
function fatalln() {
  errorln "$1"
  exit 1
}

export -f errorln
export -f successln
export -f infoln
export -f warnln

脚本 registerEnroll.sh 和 create-ccp.sh 与 fabric-sample repo 中的脚本相同。

但是我在订购者上创建频道时遇到了问题。我收到错误“证书错误”。然后我只是为了好玩而尝试安装链代码并且它起作用了......不幸的是我不能将其用作解决方案,因为我需要通道。但同样的问题是,这怎么可能?

我仍然是 Hyperledger Fabric 的初学者......我已经确定我在某处犯了一个或多个配置错误。不幸的是,我已经到了无法再进一步的地步。也许有人可以帮助我。如果您对上述尝试之一有任何疑问,或者您需要配置文件,请告诉我。

标签: dockerubuntuhyperledger-fabric

解决方案


对于第一次尝试,如何使用 Docker Swarm 来实现位于不同主机中的容器之间的通信?


推荐阅读