docker - Hyperledger Fabric:在不同的物理机器上设置相同组织的两个对等点
问题描述
我在 Ubuntu 20.04 机器上建立了区块链测试网络。该网络是根据 fabric-samples Repo https://github.com/hyperledger/fabric-samples建立和设置的。Fabric 版本为 2.3.0,Fabric CA 版本为 1.4.9。我现在的目标是在另一台机器上为同一个组织设置第二个对等点,以将对等点集成到我现有的网络中。这样我也可以在那里安装我的智能合约/链代码,并在第二个对等方上测试我的查询。
简短的摘要:
Ubuntu 20.04 机器,具有一个 peer、一个 orderer 和一个 ca 服务器,每个用于 peer 和 orderer。在互联网提供商处运行
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 的初学者......我已经确定我在某处犯了一个或多个配置错误。不幸的是,我已经到了无法再进一步的地步。也许有人可以帮助我。如果您对上述尝试之一有任何疑问,或者您需要配置文件,请告诉我。
解决方案
对于第一次尝试,如何使用 Docker Swarm 来实现位于不同主机中的容器之间的通信?
推荐阅读
- python - Python 3 中未初始化默认函数参数
- python - Python:将数组元素与浮点数进行比较,得到一个布尔列表
- c# - 列表及其所有嵌套列表值的 Linq 平均值
- php - Laravel:对多个图像进行图像验证不起作用
- dart - 如何在 Flutter 的 TextField 中添加遮罩?
- azure - 在 Azure 中基于 Web 发起创建 IaaS
- google-sheets - 基于 if/then 在多个字段上的条件格式
- wix - 使用自定义操作的 REG_MULTI_SZ 的 MsiSetProperty
- javascript - 以后是否可以将值绑定到函数中的 Vue 元素?
- plot - Jzy3d 3d插值图不渲染