peer channel
peer channel 命令允许管理员在 Peer 上执行通道相关的操作,比如加入通道,或者列出当前 Peer 加入的通道。
Joins the peer to a channel.
Usage:
peer channel join [flags]
Flags:
-b, --blockpath string Path to file containing genesis block
-h, --help help for join
Global Flags:
--cafile string Path to file containing PEM-encoded trusted certificate(s) for the ordering endpoint
--certfile string Path to file containing PEM-encoded X509 public key to use for mutual TLS communication with the orderer endpoint
--clientauth Use mutual TLS when communicating with the orderer endpoint
--connTimeout duration Timeout for client to connect (default 3s)
--keyfile string Path to file containing PEM-encoded private key to use for mutual TLS communication with the orderer endpoint
-o, --orderer string Ordering service endpoint
--ordererTLSHostnameOverride string The hostname override to use when validating the TLS connection to the orderer.
--tls Use TLS when communicating with the orderer endpoint
peer channel 命令允许管理员在 Peer 上执行通道相关的操作,比如加入通道,或者列出当前 Peer 加入的通道。
cryptogen
cryptogen 用于生成 Hyperledger Fabric 的密钥材料,包括各种证书和密钥;
它为测试提供了一种预配置网络的工具。通常它不应使用在生产环境中。
Fabric网络-crypto-config&configtx详解
Hyperledger Fabric配置文件解析(一)——crypto-config.yaml
hyperledge工具-cryptogen
crypto-config.yaml
usage: cryptogen [<flags>] <command> [<args> ...]
生成 Hyperledger Fabric 密钥材料的工具。
Flags:
--help 查看完整的帮助(可以尝试 --help-long 和 --help-man)。
Commands:
help [<command>...]
显示帮助。
generate [<flags>]
生成密钥材料。
showtemplate
显示默认配置模板。
version
显示版本信息。
extend [<flags>]
扩展现有网络。
usage: cryptogen generate [<flags>]
生成密钥材料
Flags:
--help 查看完整的帮助(可以尝试 --help-long 和 --help-man)。
--output="crypto-config" 用来存放构件的输出目录。
--config=CONFIG.yaml 用于生成密钥材料的配置文件
# 使用配置文件 crypto-config.yaml 生成密钥材料
../bin/cryptogen generate --config=./crypto-config.yaml
configtxgen
configtxgen 命令允许用户创建和查看通道配置相关构件。所生成的构件取决于 configtx.yaml 的内容。
configtxgen 工具没有子命令,但是支持标识(flag),通过设置标识可以完成不同的任务。
Usage of configtxgen:
-asOrg string
以特定组织(按名称)执行配置生成,仅包括组织(可能)有权设置的写集中的值。
-channelCreateTxBaseProfile string
指定要视为排序系统通道当前状态的轮廓(profile),以允许在通道创建交易生成期间修改非应用程序参数。仅在与 “outputCreateChannelTX” 结合时有效。
-channelID string
配置交易中使用的通道 ID。
-configPath string
包含所用的配置的路径。(如果设置的话)
-inspectBlock string
打印指定路径的区块中包含的配置。
-inspectChannelCreateTx string
打印指定路径的交易中包含的配置。
-outputAnchorPeersUpdate string
创建一个更新锚节点的配置更新(仅在默认通道创建时有效,并仅用于第一次更新)。
-outputBlock string
写入创世区块的路径。(如果设置的话)
-outputCreateChannelTx string
写入通道创建交易的路径。(如果设置的话)
-printOrg string
以 JSON 方式打印组织的定义。(手动向通道中添加组织时很有用)
-profile string
configtx.yaml 中用于生成的轮廓。默认(“SampleInsecureSolo”)
-version
显示版本信息。
使用configtx.yaml创建通道配置
configtx.yaml中文注解 原
1.3 Fabric应用开发-配置文件(2)configtx.yaml
Channel 配置(configtxgen)
configtx.yaml中文详解
# 将通道 orderer-system-channel 和轮廓(Profile) SampleSingleMSPSoloV1_1 的创世区块写入 genesis_block.pb
configtxgen -outputBlock genesis_block.pb -profile SampleSingleMSPSoloV1_1 -channelID orderer-system-channel
# 将轮廓 TwoOrgsOrdererGenesis 和通道 byfn-sys-channel 写入创世区块 ./channel-artifacts/genesis.block
../bin/configtxgen -profile TwoOrgsOrdererGenesis -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block
# 将创世区块 genesis.block 以 JSON 格式打印到屏幕上
configtxgen -inspectBlock ./channel-artifacts/genesis.block
# 将轮廓 SampleSingleMSPChannelV1_1 的通道创建交易写入 create_chan_tx.pb
configtxgen -outputCreateChannelTx create_chan_tx.pb -profile SampleSingleMSPChannelV1_1 -channelID application-channel-1
# 将轮廓 TwoOrgsChannel 的通道创建交易写入 ./channel-artifacts/channel.tx
export CHANNEL_NAME=mychannel && ../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME
# 将通道创建交易 create_chan_tx.pb 以 JSON 的格式打印到屏幕上。
configtxgen -inspectChannelCreateTx create_chan_tx.pb
#
configtxgen -inspectChannelCreateTx channel-artifacts/channel.tx
# 基于 configtx.yaml 的配置项(比如 MSPdir)来构建组织并以 JSON 格式打印到屏幕。(常用于创建通道时的重新配置,例如添加成员)
configtxgen -printOrg Org1
# 将配置更新交易输出到 anchor_peer_tx.pb,就是将组织 Org1 的锚节点设置成 configtx.yaml 中轮廓 SampleSingleMSPChannelV1_1 所定义的。
configtxgen -outputAnchorPeersUpdate anchor_peer_tx.pb -profile SampleSingleMSPChannelV1_1 -asOrg Org1
在区块链网络中,证书主要有两个作用:
节点是构成区块链网络的基础;
节点用于托管账本和链码的副本;
一个节点保存多个账本。节点保存一个或多个账本,并且每个账本都具有零个或多个适用于它们的链码。
在这个例子中,我们可以看到节点 P1 保存着账本 L1 和 L2。要访问账本 L1需使用链码 S1 。
而要访问账本 L2 可使用链码 S1 和 S2 。
上面这个例子显示的是一个节点保存了多个链码。每个账本可被多个链码访问。
在这个示例中,我们可以看到节点 P1 保存着账本 L1 和 L2,其中 L1 由链码 S1 和 S2 访问,而 L2 由 S1 和 S3 访问。
我们可以看到 S1 既可以访问 L1 也可以访问 L2。
锚节点
构建你的第一个网络
在构建你的第一个网络(BYFN)场景中,提供了一个包含两个组织的 Hyperledger Fabric 网络,每个组织包含两个 Peer 节点,一个 “Solo” 模式的排序服务。
如何解决类似 curl: (7) Failed to connect to raw.githubusercontent.com port 443: Connection refused 的问题 #10
成功解决:curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to bit.ly:443
已解决)curl: (56) Recv failure: 连接被对方重设
【解决】could not find an available, non-overlapping IPv4 address pool among the defaults to assign t…
ERROR: manifest for hyperledger/fabric-orderer:latest not found
Cannot compile chaincode
克隆 hyperledger/fabric-samples 仓库,并切换分支到 release-1.4 分支
下载 fabric-samples 1.4 版本的相关工具,即下载 bin/、config/ 两个目录及相应的 docker 镜像
curl -sSL https://bit.ly/2ysbOFE | bash -s -- 1.4.4 1.4.4 0.4.15
该脚本实际执行的是 bootstrap.sh 脚本的内容
#!/bin/bash
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
# if version not passed in, default to latest released version
VERSION=2.3.1
# if ca version not passed in, default to latest released version
CA_VERSION=1.4.9
ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')")
MARCH=$(uname -m)
printHelp() {
echo "Usage: bootstrap.sh [version [ca_version]] [options]"
echo
echo "options:"
echo "-h : this help"
echo "-d : bypass docker image download"
echo "-s : bypass fabric-samples repo clone"
echo "-b : bypass download of platform-specific binaries"
echo
echo "e.g. bootstrap.sh 2.3.1 1.4.9 -s"
echo "will download docker images and binaries for Fabric v2.3.1 and Fabric CA v1.4.9"
}
# dockerPull() pulls docker images from fabric and chaincode repositories
# note, if a docker image doesn't exist for a requested release, it will simply
# be skipped, since this script doesn't terminate upon errors.
dockerPull() {
#three_digit_image_tag is passed in, e.g. "1.4.7"
three_digit_image_tag=$1
shift
#two_digit_image_tag is derived, e.g. "1.4", especially useful as a local tag for two digit references to most recent baseos, ccenv, javaenv, nodeenv patch releases
two_digit_image_tag=$(echo "$three_digit_image_tag" | cut -d'.' -f1,2)
while [[ $# -gt 0 ]]
do
image_name="$1"
echo "====> hyperledger/fabric-$image_name:$three_digit_image_tag"
docker pull "hyperledger/fabric-$image_name:$three_digit_image_tag"
docker tag "hyperledger/fabric-$image_name:$three_digit_image_tag" "hyperledger/fabric-$image_name"
docker tag "hyperledger/fabric-$image_name:$three_digit_image_tag" "hyperledger/fabric-$image_name:$two_digit_image_tag"
shift
done
}
cloneSamplesRepo() {
# clone (if needed) hyperledger/fabric-samples and checkout corresponding
# version to the binaries and docker images to be downloaded
if [ -d first-network ]; then
# if we are in the fabric-samples repo, checkout corresponding version
echo "==> Already in fabric-samples repo"
elif [ -d fabric-samples ]; then
# if fabric-samples repo already cloned and in current directory,
# cd fabric-samples
echo "===> Changing directory to fabric-samples"
cd fabric-samples
else
echo "===> Cloning hyperledger/fabric-samples repo"
git clone -b master https://github.com/hyperledger/fabric-samples.git && cd fabric-samples
fi
if GIT_DIR=.git git rev-parse v${VERSION} >/dev/null 2>&1; then
echo "===> Checking out v${VERSION} of hyperledger/fabric-samples"
git checkout -q v${VERSION}
else
echo "fabric-samples v${VERSION} does not exist, defaulting master"
git checkout -q master
fi
}
# This will download the .tar.gz
download() {
local BINARY_FILE=$1
local URL=$2
echo "===> Downloading: " "${URL}"
curl -L --retry 5 --retry-delay 3 "${URL}" | tar xz || rc=$?
if [ -n "$rc" ]; then
echo "==> There was an error downloading the binary file."
return 22
else
echo "==> Done."
fi
}
pullBinaries() {
echo "===> Downloading version ${FABRIC_TAG} platform specific fabric binaries"
download "${BINARY_FILE}" "https://github.com/hyperledger/fabric/releases/download/v${VERSION}/${BINARY_FILE}"
if [ $? -eq 22 ]; then
echo
echo "------> ${FABRIC_TAG} platform specific fabric binary is not available to download <----"
echo
exit
fi
echo "===> Downloading version ${CA_TAG} platform specific fabric-ca-client binary"
download "${CA_BINARY_FILE}" "https://github.com/hyperledger/fabric-ca/releases/download/v${CA_VERSION}/${CA_BINARY_FILE}"
if [ $? -eq 22 ]; then
echo
echo "------> ${CA_TAG} fabric-ca-client binary is not available to download (Available from 1.1.0-rc1) <----"
echo
exit
fi
}
pullDockerImages() {
command -v docker >& /dev/null
NODOCKER=$?
if [ "${NODOCKER}" == 0 ]; then
FABRIC_IMAGES=(peer orderer ccenv tools)
case "$VERSION" in
2.*)
FABRIC_IMAGES+=(baseos)
shift
;;
esac
echo "FABRIC_IMAGES:" "${FABRIC_IMAGES[@]}"
echo "===> Pulling fabric Images"
dockerPull "${FABRIC_TAG}" "${FABRIC_IMAGES[@]}"
echo "===> Pulling fabric ca Image"
CA_IMAGE=(ca)
dockerPull "${CA_TAG}" "${CA_IMAGE[@]}"
echo "===> List out hyperledger docker images"
docker images | grep hyperledger
else
echo "========================================================="
echo "Docker not installed, bypassing download of Fabric images"
echo "========================================================="
fi
}
DOCKER=true
SAMPLES=true
BINARIES=true
# Parse commandline args pull out
# version and/or ca-version strings first
if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
VERSION=$1;shift
if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
CA_VERSION=$1;shift
if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
THIRDPARTY_IMAGE_VERSION=$1;shift
fi
fi
fi
# prior to 1.2.0 architecture was determined by uname -m
if [[ $VERSION =~ ^1\.[0-1]\.* ]]; then
export FABRIC_TAG=${MARCH}-${VERSION}
export CA_TAG=${MARCH}-${CA_VERSION}
export THIRDPARTY_TAG=${MARCH}-${THIRDPARTY_IMAGE_VERSION}
else
# starting with 1.2.0, multi-arch images will be default
: "${CA_TAG:="$CA_VERSION"}"
: "${FABRIC_TAG:="$VERSION"}"
: "${THIRDPARTY_TAG:="$THIRDPARTY_IMAGE_VERSION"}"
fi
BINARY_FILE=hyperledger-fabric-${ARCH}-${VERSION}.tar.gz
CA_BINARY_FILE=hyperledger-fabric-ca-${ARCH}-${CA_VERSION}.tar.gz
# then parse opts
while getopts "h?dsb" opt; do
case "$opt" in
h|\?)
printHelp
exit 0
;;
d) DOCKER=false
;;
s) SAMPLES=false
;;
b) BINARIES=false
;;
esac
done
if [ "$SAMPLES" == "true" ]; then
echo
echo "Clone hyperledger/fabric-samples repo"
echo
cloneSamplesRepo
fi
if [ "$BINARIES" == "true" ]; then
echo
echo "Pull Hyperledger Fabric binaries"
echo
pullBinaries
fi
if [ "$DOCKER" == "true" ]; then
echo
echo "Pull Hyperledger Fabric docker images"
echo
pullDockerImages
fi
export PATH=<path to download location>/bin:$PATH
#!/bin/bash
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
# This script will orchestrate a sample end-to-end execution of the Hyperledger
# Fabric network.
#
# The end-to-end verification provisions a sample Fabric network consisting of
# two organizations, each maintaining two peers, and a “solo” ordering service.
#
# This verification makes use of two fundamental tools, which are necessary to
# create a functioning transactional network with digital signature validation
# and access control:
#
# * cryptogen - generates the x509 certificates used to identify and
# authenticate the various components in the network.
# * configtxgen - generates the requisite configuration artifacts for orderer
# bootstrap and channel creation.
#
# Each tool consumes a configuration yaml file, within which we specify the topology
# of our network (cryptogen) and the location of our certificates for various
# configuration operations (configtxgen). Once the tools have been successfully run,
# we are able to launch our network. More detail on the tools and the structure of
# the network will be provided later in this document. For now, let's get going...
# prepending $PWD/../bin to PATH to ensure we are picking up the correct binaries
# this may be commented out to resolve installed version of tools if desired
export PATH=${PWD}/../bin:${PWD}:$PATH
export FABRIC_CFG_PATH=${PWD}
export VERBOSE=false
# Print the usage message
function printHelp() {
echo "Usage: "
echo " byfn.sh [-c ] [-t ] [-d ] [-f ] [-s ] [-l ] [-o ] [-i ] [-a] [-n] [-v]"
echo " - one of 'up', 'down', 'restart', 'generate' or 'upgrade'"
echo " - 'up' - bring up the network with docker-compose up"
echo " - 'down' - clear the network with docker-compose down"
echo " - 'restart' - restart the network"
echo " - 'generate' - generate required certificates and genesis block"
echo " - 'upgrade' - upgrade the network from version 1.3.x to 1.4.0"
echo " -c - channel name to use (defaults to \"mychannel\")"
echo " -t - CLI timeout duration in seconds (defaults to 10)"
echo " -d - delay duration in seconds (defaults to 3)"
echo " -f - specify which docker-compose file use (defaults to docker-compose-cli.yaml)"
echo " -s - the database backend to use: goleveldb (default) or couchdb"
echo " -l - the chaincode language: golang (default) or node"
echo " -o - the consensus-type of the ordering service: solo (default), kafka, or etcdraft"
echo " -i - the tag to be used to launch the network (defaults to \"latest\")"
echo " -a - launch certificate authorities (no certificate authorities are launched by default)"
echo " -n - do not deploy chaincode (abstore chaincode is deployed by default)"
echo " -v - verbose mode"
echo " byfn.sh -h (print this message)"
echo
echo "Typically, one would first generate the required certificates and "
echo "genesis block, then bring up the network. e.g.:"
echo
echo " byfn.sh generate -c mychannel"
echo " byfn.sh up -c mychannel -s couchdb"
echo " byfn.sh up -c mychannel -s couchdb -i 1.4.0"
echo " byfn.sh up -l node"
echo " byfn.sh down -c mychannel"
echo " byfn.sh upgrade -c mychannel"
echo
echo "Taking all defaults:"
echo " byfn.sh generate"
echo " byfn.sh up"
echo " byfn.sh down"
}
# Ask user for confirmation to proceed
function askProceed() {
read -p "Continue? [Y/n] " ans
case "$ans" in
y | Y | "")
echo "proceeding ..."
;;
n | N)
echo "exiting..."
exit 1
;;
*)
echo "invalid response"
askProceed
;;
esac
}
# Obtain CONTAINER_IDS and remove them
# TODO Might want to make this optional - could clear other containers
function clearContainers() {
CONTAINER_IDS=$(docker ps -a | awk '($2 ~ /dev-peer.*.mycc.*/) {
print $1}')
if [ -z "$CONTAINER_IDS" -o "$CONTAINER_IDS" == " " ]; then
echo "---- No containers available for deletion ----"
else
docker rm -f $CONTAINER_IDS
fi
}
# Delete any images that were generated as a part of this setup
# specifically the following images are often left behind:
# TODO list generated image naming patterns
function removeUnwantedImages() {
DOCKER_IMAGE_IDS=$(docker images | awk '($1 ~ /dev-peer.*.mycc.*/) {print $3}')
if [ -z "$DOCKER_IMAGE_IDS" -o "$DOCKER_IMAGE_IDS" == " " ]; then
echo "---- No images available for deletion ----"
else
docker rmi -f $DOCKER_IMAGE_IDS
fi
}
# Versions of fabric known not to work with this release of first-network
BLACKLISTED_VERSIONS="^1\.0\. ^1\.1\.0-preview ^1\.1\.0-alpha"
# Do some basic sanity checking to make sure that the appropriate versions of fabric
# binaries/images are available. In the future, additional checking for the presence
# of go or other items could be added.
function checkPrereqs() {
# Note, we check configtxlator externally because it does not require a config file, and peer in the
# docker image because of FAB-8551 that makes configtxlator return 'development version' in docker
LOCAL_VERSION=$(configtxlator version | sed -ne 's/ Version: //p')
DOCKER_IMAGE_VERSION=$(docker run --rm hyperledger/fabric-tools:$IMAGETAG peer version | sed -ne 's/ Version: //p' | head -1)
echo "LOCAL_VERSION=$LOCAL_VERSION"
echo "DOCKER_IMAGE_VERSION=$DOCKER_IMAGE_VERSION"
if [ "$LOCAL_VERSION" != "$DOCKER_IMAGE_VERSION" ]; then
echo "=================== WARNING ==================="
echo " Local fabric binaries and docker images are "
echo " out of sync. This may cause problems. "
echo "==============================================="
fi
for UNSUPPORTED_VERSION in $BLACKLISTED_VERSIONS; do
echo "$LOCAL_VERSION" | grep -q $UNSUPPORTED_VERSION
if [ $? -eq 0 ]; then
echo "ERROR! Local Fabric binary version of $LOCAL_VERSION does not match this newer version of BYFN and is unsupported. Either move to a later version of Fabric or checkout an earlier version of fabric-samples."
exit 1
fi
echo "$DOCKER_IMAGE_VERSION" | grep -q $UNSUPPORTED_VERSION
if [ $? -eq 0 ]; then
echo "ERROR! Fabric Docker image version of $DOCKER_IMAGE_VERSION does not match this newer version of BYFN and is unsupported. Either move to a later version of Fabric or checkout an earlier version of fabric-samples."
exit 1
fi
done
}
# Generate the needed certificates, the genesis block and start the network.
function networkUp() {
checkPrereqs
# generate artifacts if they don't exist
if [ ! -d "crypto-config" ]; then
generateCerts
replacePrivateKey
generateChannelArtifacts
fi
COMPOSE_FILES="-f ${COMPOSE_FILE}"
if [ "${CERTIFICATE_AUTHORITIES}" == "true" ]; then
COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_CA}"
export BYFN_CA1_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org1.example.com/ca && ls *_sk)
export BYFN_CA2_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org2.example.com/ca && ls *_sk)
fi
if [ "${CONSENSUS_TYPE}" == "kafka" ]; then
COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_KAFKA}"
elif [ "${CONSENSUS_TYPE}" == "etcdraft" ]; then
COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_RAFT2}"
fi
if [ "${IF_COUCHDB}" == "couchdb" ]; then
COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_COUCH}"
fi
IMAGE_TAG=$IMAGETAG docker-compose ${COMPOSE_FILES} up -d 2>&1
docker ps -a
if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to start network"
exit 1
fi
if [ "$CONSENSUS_TYPE" == "kafka" ]; then
sleep 1
echo "Sleeping 10s to allow $CONSENSUS_TYPE cluster to complete booting"
sleep 9
fi
if [ "$CONSENSUS_TYPE" == "etcdraft" ]; then
sleep 1
echo "Sleeping 15s to allow $CONSENSUS_TYPE cluster to complete booting"
sleep 14
fi
# now run the end to end script
docker exec cli scripts/script.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE $NO_CHAINCODE
if [ $? -ne 0 ]; then
echo "ERROR !!!! Test failed"
exit 1
fi
}
# Upgrade the network components which are at version 1.3.x to 1.4.x
# Stop the orderer and peers, backup the ledger for orderer and peers, cleanup chaincode containers and images
# and relaunch the orderer and peers with latest tag
function upgradeNetwork() {
if [[ "$IMAGETAG" == *"1.4"* ]] || [[ $IMAGETAG == "latest" ]]; then
docker inspect -f '{
{.Config.Volumes}}' orderer.example.com | grep -q '/var/hyperledger/production/orderer'
if [ $? -ne 0 ]; then
echo "ERROR !!!! This network does not appear to start with fabric-samples >= v1.3.x?"
exit 1
fi
LEDGERS_BACKUP=./ledgers-backup
# create ledger-backup directory
mkdir -p $LEDGERS_BACKUP
export IMAGE_TAG=$IMAGETAG
COMPOSE_FILES="-f ${COMPOSE_FILE}"
if [ "${CERTIFICATE_AUTHORITIES}" == "true" ]; then
COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_CA}"
export BYFN_CA1_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org1.example.com/ca && ls *_sk)
export BYFN_CA2_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org2.example.com/ca && ls *_sk)
fi
if [ "${CONSENSUS_TYPE}" == "kafka" ]; then
COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_KAFKA}"
elif [ "${CONSENSUS_TYPE}" == "etcdraft" ]; then
COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_RAFT2}"
fi
if [ "${IF_COUCHDB}" == "couchdb" ]; then
COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_COUCH}"
fi
# removing the cli container
docker-compose $COMPOSE_FILES stop cli
docker-compose $COMPOSE_FILES up -d --no-deps cli
echo "Upgrading orderer"
docker-compose $COMPOSE_FILES stop orderer.example.com
docker cp -a orderer.example.com:/var/hyperledger/production/orderer $LEDGERS_BACKUP/orderer.example.com
docker-compose $COMPOSE_FILES up -d --no-deps orderer.example.com
for PEER in peer0.org1.example.com peer1.org1.example.com peer0.org2.example.com peer1.org2.example.com; do
echo "Upgrading peer $PEER"
# Stop the peer and backup its ledger
docker-compose $COMPOSE_FILES stop $PEER
docker cp -a $PEER:/var/hyperledger/production $LEDGERS_BACKUP/$PEER/
# Remove any old containers and images for this peer
CC_CONTAINERS=$(docker ps | grep dev-$PEER | awk '{print $1}')
if [ -n "$CC_CONTAINERS" ]; then
docker rm -f $CC_CONTAINERS
fi
CC_IMAGES=$(docker images | grep dev-$PEER | awk '{print $1}')
if [ -n "$CC_IMAGES" ]; then
docker rmi -f $CC_IMAGES
fi
# Start the peer again
docker-compose $COMPOSE_FILES up -d --no-deps $PEER
done
docker exec cli scripts/upgrade_to_v14.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE
if [ $? -ne 0 ]; then
echo "ERROR !!!! Test failed"
exit 1
fi
else
echo "ERROR !!!! Pass the v1.4.x image tag"
fi
}
# Tear down running network
function networkDown() {
# stop org3 containers also in addition to org1 and org2, in case we were running sample to add org3
# stop kafka and zookeeper containers in case we're running with kafka consensus-type
docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH -f $COMPOSE_FILE_KAFKA -f $COMPOSE_FILE_RAFT2 -f $COMPOSE_FILE_CA -f $COMPOSE_FILE_ORG3 down --volumes --remove-orphans
# Don't remove the generated artifacts -- note, the ledgers are always removed
if [ "$MODE" != "restart" ]; then
# Bring down the network, deleting the volumes
#Delete any ledger backups
docker run -v $PWD:/tmp/first-network --rm hyperledger/fabric-tools:$IMAGETAG rm -Rf /tmp/first-network/ledgers-backup
#Cleanup the chaincode containers
clearContainers
#Cleanup images
removeUnwantedImages
# remove orderer block and other channel configuration transactions and certs
rm -rf channel-artifacts/*.block channel-artifacts/*.tx crypto-config ./org3-artifacts/crypto-config/ channel-artifacts/org3.json
# remove the docker-compose yaml file that was customized to the example
rm -f docker-compose-e2e.yaml
fi
}
# Using docker-compose-e2e-template.yaml, replace constants with private key file names
# generated by the cryptogen tool and output a docker-compose.yaml specific to this
# configuration
function replacePrivateKey() {
# sed on MacOSX does not support -i flag with a null extension. We will use
# 't' for our back-up's extension and delete it at the end of the function
ARCH=$(uname -s | grep Darwin)
if [ "$ARCH" == "Darwin" ]; then
OPTS="-it"
else
OPTS="-i"
fi
# Copy the template to the file that will be modified to add the private key
cp docker-compose-e2e-template.yaml docker-compose-e2e.yaml
# The next steps will replace the template's contents with the
# actual values of the private key file names for the two CAs.
CURRENT_DIR=$PWD
cd crypto-config/peerOrganizations/org1.example.com/ca/
PRIV_KEY=$(ls *_sk)
cd "$CURRENT_DIR"
sed $OPTS "s/CA1_PRIVATE_KEY/${PRIV_KEY}/g" docker-compose-e2e.yaml
cd crypto-config/peerOrganizations/org2.example.com/ca/
PRIV_KEY=$(ls *_sk)
cd "$CURRENT_DIR"
sed $OPTS "s/CA2_PRIVATE_KEY/${PRIV_KEY}/g" docker-compose-e2e.yaml
# If MacOSX, remove the temporary backup of the docker-compose file
if [ "$ARCH" == "Darwin" ]; then
rm docker-compose-e2e.yamlt
fi
}
# We will use the cryptogen tool to generate the cryptographic material (x509 certs)
# for our various network entities. The certificates are based on a standard PKI
# implementation where validation is achieved by reaching a common trust anchor.
#
# Cryptogen consumes a file - ``crypto-config.yaml`` - that contains the network
# topology and allows us to generate a library of certificates for both the
# Organizations and the components that belong to those Organizations. Each
# Organization is provisioned a unique root certificate (``ca-cert``), that binds
# specific components (peers and orderers) to that Org. Transactions and communications
# within Fabric are signed by an entity's private key (``keystore``), and then verified
# by means of a public key (``signcerts``). You will notice a "count" variable within
# this file. We use this to specify the number of peers per Organization; in our
# case it's two peers per Org. The rest of this template is extremely
# self-explanatory.
#
# After we run the tool, the certs will be parked in a folder titled ``crypto-config``.
# Generates Org certs using cryptogen tool
function generateCerts() {
which cryptogen
if [ "$?" -ne 0 ]; then
echo "cryptogen tool not found. exiting"
exit 1
fi
echo
echo "##########################################################"
echo "##### Generate certificates using cryptogen tool #########"
echo "##########################################################"
if [ -d "crypto-config" ]; then
rm -Rf crypto-config
fi
set -x
cryptogen generate --config=./crypto-config.yaml
res=$?
set +x
if [ $res -ne 0 ]; then
echo "Failed to generate certificates..."
exit 1
fi
echo
}
# The `configtxgen tool is used to create four artifacts: orderer **bootstrap
# block**, fabric **channel configuration transaction**, and two **anchor
# peer transactions** - one for each Peer Org.
#
# The orderer block is the genesis block for the ordering service, and the
# channel transaction file is broadcast to the orderer at channel creation
# time. The anchor peer transactions, as the name might suggest, specify each
# Org's anchor peer on this channel.
#
# Configtxgen consumes a file - ``configtx.yaml`` - that contains the definitions
# for the sample network. There are three members - one Orderer Org (``OrdererOrg``)
# and two Peer Orgs (``Org1`` & ``Org2``) each managing and maintaining two peer nodes.
# This file also specifies a consortium - ``SampleConsortium`` - consisting of our
# two Peer Orgs. Pay specific attention to the "Profiles" section at the top of
# this file. You will notice that we have two unique headers. One for the orderer genesis
# block - ``TwoOrgsOrdererGenesis`` - and one for our channel - ``TwoOrgsChannel``.
# These headers are important, as we will pass them in as arguments when we create
# our artifacts. This file also contains two additional specifications that are worth
# noting. Firstly, we specify the anchor peers for each Peer Org
# (``peer0.org1.example.com`` & ``peer0.org2.example.com``). Secondly, we point to
# the location of the MSP directory for each member, in turn allowing us to store the
# root certificates for each Org in the orderer genesis block. This is a critical
# concept. Now any network entity communicating with the ordering service can have
# its digital signature verified.
#
# This function will generate the crypto material and our four configuration
# artifacts, and subsequently output these files into the ``channel-artifacts``
# folder.
#
# If you receive the following warning, it can be safely ignored:
#
# [bccsp] GetDefault -> WARN 001 Before using BCCSP, please call InitFactories(). Falling back to bootBCCSP.
#
# You can ignore the logs regarding intermediate certs, we are not using them in
# this crypto implementation.
# Generate orderer genesis block, channel configuration transaction and
# anchor peer update transactions
function generateChannelArtifacts() {
which configtxgen
if [ "$?" -ne 0 ]; then
echo "configtxgen tool not found. exiting"
exit 1
fi
echo "##########################################################"
echo "######### Generating Orderer Genesis block ##############"
echo "##########################################################"
# Note: For some unknown reason (at least for now) the block file can't be
# named orderer.genesis.block or the orderer will fail to launch!
echo "CONSENSUS_TYPE="$CONSENSUS_TYPE
set -x
if [ "$CONSENSUS_TYPE" == "solo" ]; then
configtxgen -profile TwoOrgsOrdererGenesis -channelID $SYS_CHANNEL -outputBlock ./channel-artifacts/genesis.block
elif [ "$CONSENSUS_TYPE" == "kafka" ]; then
configtxgen -profile SampleDevModeKafka -channelID $SYS_CHANNEL -outputBlock ./channel-artifacts/genesis.block
elif [ "$CONSENSUS_TYPE" == "etcdraft" ]; then
configtxgen -profile SampleMultiNodeEtcdRaft -channelID $SYS_CHANNEL -outputBlock ./channel-artifacts/genesis.block
else
set +x
echo "unrecognized CONSESUS_TYPE='$CONSENSUS_TYPE'. exiting"
exit 1
fi
res=$?
set +x
if [ $res -ne 0 ]; then
echo "Failed to generate orderer genesis block..."
exit 1
fi
echo
echo "#################################################################"
echo "### Generating channel configuration transaction 'channel.tx' ###"
echo "#################################################################"
set -x
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME
res=$?
set +x
if [ $res -ne 0 ]; then
echo "Failed to generate channel configuration transaction..."
exit 1
fi
echo
echo "#################################################################"
echo "####### Generating anchor peer update for Org1MSP ##########"
echo "#################################################################"
set -x
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP
res=$?
set +x
if [ $res -ne 0 ]; then
echo "Failed to generate anchor peer update for Org1MSP..."
exit 1
fi
echo
echo "#################################################################"
echo "####### Generating anchor peer update for Org2MSP ##########"
echo "#################################################################"
set -x
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate \
./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP
res=$?
set +x
if [ $res -ne 0 ]; then
echo "Failed to generate anchor peer update for Org2MSP..."
exit 1
fi
echo
}
# Obtain(获取) the OS and Architecture string that will be used to select the correct
# native binaries for your platform, e.g., darwin-amd64 or linux-amd64
OS_ARCH=$(echo "$(uname -s | tr '[:upper:]' '[:lower:]' | sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')" | awk '{print tolower($0)}')
# timeout duration - the duration the CLI should wait for a response from
# another container before giving up
CLI_TIMEOUT=10
# default for delay between commands
CLI_DELAY=3
# system channel name defaults to "byfn-sys-channel"
SYS_CHANNEL="byfn-sys-channel"
# channel name defaults to "mychannel"
CHANNEL_NAME="mychannel"
# use this as the default docker-compose yaml definition
COMPOSE_FILE=docker-compose-cli.yaml
#
COMPOSE_FILE_COUCH=docker-compose-couch.yaml
# org3 docker compose file
COMPOSE_FILE_ORG3=docker-compose-org3.yaml
# kafka and zookeeper compose file
COMPOSE_FILE_KAFKA=docker-compose-kafka.yaml
# two additional etcd/raft orderers
COMPOSE_FILE_RAFT2=docker-compose-etcdraft2.yaml
# certificate authorities compose file
COMPOSE_FILE_CA=docker-compose-ca.yaml
#
# use golang as the default language for chaincode
LANGUAGE=golang
# default image tag
IMAGETAG="latest"
# default consensus type
CONSENSUS_TYPE="solo"
# Parse commandline args 用户输入参数判定
if [ "$1" = "-m" ]; then # supports old usage, muscle memory is powerful!
shift
fi
MODE=$1
shift
# Determine whether starting, stopping, restarting, generating or upgrading
if [ "$MODE" == "up" ]; then
EXPMODE="Starting"
elif [ "$MODE" == "down" ]; then
EXPMODE="Stopping"
elif [ "$MODE" == "restart" ]; then
EXPMODE="Restarting"
elif [ "$MODE" == "generate" ]; then
EXPMODE="Generating certs and genesis block"
elif [ "$MODE" == "upgrade" ]; then
EXPMODE="Upgrading the network"
else
printHelp
exit 1
fi
while getopts "h?c:t:d:f:s:l:i:o:anv" opt; do
case "$opt" in
h | \?)
printHelp
exit 0
;;
c)
CHANNEL_NAME=$OPTARG
;;
t)
CLI_TIMEOUT=$OPTARG
;;
d)
CLI_DELAY=$OPTARG
;;
f)
COMPOSE_FILE=$OPTARG
;;
s)
IF_COUCHDB=$OPTARG
;;
l)
LANGUAGE=$OPTARG
;;
i)
IMAGETAG=$(go env GOARCH)"-"$OPTARG
;;
o)
CONSENSUS_TYPE=$OPTARG
;;
a)
CERTIFICATE_AUTHORITIES=true
;;
n)
NO_CHAINCODE=true
;;
v)
VERBOSE=true
;;
esac
done
# Announce what was requested 用户操作提示
if [ "${IF_COUCHDB}" == "couchdb" ]; then
echo
echo "${EXPMODE} for channel '${CHANNEL_NAME}' with CLI timeout of '${CLI_TIMEOUT}' seconds and CLI delay of '${CLI_DELAY}' seconds and using database '${IF_COUCHDB}'"
else
echo "${EXPMODE} for channel '${CHANNEL_NAME}' with CLI timeout of '${CLI_TIMEOUT}' seconds and CLI delay of '${CLI_DELAY}' seconds"
fi
# ask for confirmation to proceed 用户操作确认
askProceed
#Create the network using docker compose
if [ "${MODE}" == "up" ]; then
networkUp
elif [ "${MODE}" == "down" ]; then ## Clear the network
networkDown
elif [ "${MODE}" == "generate" ]; then ## Generate Artifacts
generateCerts
replacePrivateKey
generateChannelArtifacts
elif [ "${MODE}" == "restart" ]; then ## Restart the network
networkDown
networkUp
elif [ "${MODE}" == "upgrade" ]; then ## Upgrade the network from version 1.2.x to 1.3.x
upgradeNetwork
else
printHelp
exit 1
fi
如何解决类似 curl: (7) Failed to connect to raw.githubusercontent.com port 443: Connection refused 的问题 #10
成功解决:curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to bit.ly:443
已解决)curl: (56) Recv failure: 连接被对方重设
【解决】could not find an available, non-overlapping IPv4 address pool among the defaults to assign t…
ERROR: manifest for hyperledger/fabric-orderer:latest not found
Cannot compile chaincode
克隆 hyperledger/fabric-samples 仓库,并切换分支到 release-1.4 分支
下载 fabric-samples 1.4 版本的相关工具,即下载 bin/、config/ 两个目录及相应的 docker 镜像
curl -sSL https://bit.ly/2ysbOFE | bash -s -- 1.4.4 1.4.4 0.4.15
该脚本实际执行的是 bootstrap.sh 脚本的内容
#!/bin/bash
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
# if version not passed in, default to latest released version
VERSION=2.3.1
# if ca version not passed in, default to latest released version
CA_VERSION=1.4.9
ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')")
MARCH=$(uname -m)
printHelp() {
echo "Usage: bootstrap.sh [version [ca_version]] [options]"
echo
echo "options:"
echo "-h : this help"
echo "-d : bypass docker image download"
echo "-s : bypass fabric-samples repo clone"
echo "-b : bypass download of platform-specific binaries"
echo
echo "e.g. bootstrap.sh 2.3.1 1.4.9 -s"
echo "will download docker images and binaries for Fabric v2.3.1 and Fabric CA v1.4.9"
}
# dockerPull() pulls docker images from fabric and chaincode repositories
# note, if a docker image doesn't exist for a requested release, it will simply
# be skipped, since this script doesn't terminate upon errors.
dockerPull() {
#three_digit_image_tag is passed in, e.g. "1.4.7"
three_digit_image_tag=$1
shift
#two_digit_image_tag is derived, e.g. "1.4", especially useful as a local tag for two digit references to most recent baseos, ccenv, javaenv, nodeenv patch releases
two_digit_image_tag=$(echo "$three_digit_image_tag" | cut -d'.' -f1,2)
while [[ $# -gt 0 ]]
do
image_name="$1"
echo "====> hyperledger/fabric-$image_name:$three_digit_image_tag"
docker pull "hyperledger/fabric-$image_name:$three_digit_image_tag"
docker tag "hyperledger/fabric-$image_name:$three_digit_image_tag" "hyperledger/fabric-$image_name"
docker tag "hyperledger/fabric-$image_name:$three_digit_image_tag" "hyperledger/fabric-$image_name:$two_digit_image_tag"
shift
done
}
cloneSamplesRepo() {
# clone (if needed) hyperledger/fabric-samples and checkout corresponding
# version to the binaries and docker images to be downloaded
if [ -d first-network ]; then
# if we are in the fabric-samples repo, checkout corresponding version
echo "==> Already in fabric-samples repo"
elif [ -d fabric-samples ]; then
# if fabric-samples repo already cloned and in current directory,
# cd fabric-samples
echo "===> Changing directory to fabric-samples"
cd fabric-samples
else
echo "===> Cloning hyperledger/fabric-samples repo"
git clone -b master https://github.com/hyperledger/fabric-samples.git && cd fabric-samples
fi
if GIT_DIR=.git git rev-parse v${VERSION} >/dev/null 2>&1; then
echo "===> Checking out v${VERSION} of hyperledger/fabric-samples"
git checkout -q v${VERSION}
else
echo "fabric-samples v${VERSION} does not exist, defaulting master"
git checkout -q master
fi
}
# This will download the .tar.gz
download() {
local BINARY_FILE=$1
local URL=$2
echo "===> Downloading: " "${URL}"
curl -L --retry 5 --retry-delay 3 "${URL}" | tar xz || rc=$?
if [ -n "$rc" ]; then
echo "==> There was an error downloading the binary file."
return 22
else
echo "==> Done."
fi
}
pullBinaries() {
echo "===> Downloading version ${FABRIC_TAG} platform specific fabric binaries"
download "${BINARY_FILE}" "https://github.com/hyperledger/fabric/releases/download/v${VERSION}/${BINARY_FILE}"
if [ $? -eq 22 ]; then
echo
echo "------> ${FABRIC_TAG} platform specific fabric binary is not available to download <----"
echo
exit
fi
echo "===> Downloading version ${CA_TAG} platform specific fabric-ca-client binary"
download "${CA_BINARY_FILE}" "https://github.com/hyperledger/fabric-ca/releases/download/v${CA_VERSION}/${CA_BINARY_FILE}"
if [ $? -eq 22 ]; then
echo
echo "------> ${CA_TAG} fabric-ca-client binary is not available to download (Available from 1.1.0-rc1) <----"
echo
exit
fi
}
pullDockerImages() {
command -v docker >& /dev/null
NODOCKER=$?
if [ "${NODOCKER}" == 0 ]; then
FABRIC_IMAGES=(peer orderer ccenv tools)
case "$VERSION" in
2.*)
FABRIC_IMAGES+=(baseos)
shift
;;
esac
echo "FABRIC_IMAGES:" "${FABRIC_IMAGES[@]}"
echo "===> Pulling fabric Images"
dockerPull "${FABRIC_TAG}" "${FABRIC_IMAGES[@]}"
echo "===> Pulling fabric ca Image"
CA_IMAGE=(ca)
dockerPull "${CA_TAG}" "${CA_IMAGE[@]}"
echo "===> List out hyperledger docker images"
docker images | grep hyperledger
else
echo "========================================================="
echo "Docker not installed, bypassing download of Fabric images"
echo "========================================================="
fi
}
DOCKER=true
SAMPLES=true
BINARIES=true
# Parse commandline args pull out
# version and/or ca-version strings first
if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
VERSION=$1;shift
if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
CA_VERSION=$1;shift
if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
THIRDPARTY_IMAGE_VERSION=$1;shift
fi
fi
fi
# prior to 1.2.0 architecture was determined by uname -m
if [[ $VERSION =~ ^1\.[0-1]\.* ]]; then
export FABRIC_TAG=${MARCH}-${VERSION}
export CA_TAG=${MARCH}-${CA_VERSION}
export THIRDPARTY_TAG=${MARCH}-${THIRDPARTY_IMAGE_VERSION}
else
# starting with 1.2.0, multi-arch images will be default
: "${CA_TAG:="$CA_VERSION"}"
: "${FABRIC_TAG:="$VERSION"}"
: "${THIRDPARTY_TAG:="$THIRDPARTY_IMAGE_VERSION"}"
fi
BINARY_FILE=hyperledger-fabric-${ARCH}-${VERSION}.tar.gz
CA_BINARY_FILE=hyperledger-fabric-ca-${ARCH}-${CA_VERSION}.tar.gz
# then parse opts
while getopts "h?dsb" opt; do
case "$opt" in
h|\?)
printHelp
exit 0
;;
d) DOCKER=false
;;
s) SAMPLES=false
;;
b) BINARIES=false
;;
esac
done
if [ "$SAMPLES" == "true" ]; then
echo
echo "Clone hyperledger/fabric-samples repo"
echo
cloneSamplesRepo
fi
if [ "$BINARIES" == "true" ]; then
echo
echo "Pull Hyperledger Fabric binaries"
echo
pullBinaries
fi
if [ "$DOCKER" == "true" ]; then
echo
echo "Pull Hyperledger Fabric docker images"
echo
pullDockerImages
fi
export PATH=<path to download location>/bin:$PATH
使用 cryptogen 工具为当前网络中的各个组织生成证书和密钥;
../bin/cryptogen generate --config=./crypto-config.yaml
证书和秘钥(例如 MSP 材料)将会保存在 first-network 目录的 crypto-config 文件夹中;
区块链网络中的各个构建包括:创世区块、通道、锚节点
FABRIC_CFG_PATH 环境变量用于指定 configtx.yaml 文件所在目录,configtxgen 工具需要依赖该文件来生成区块链网络中的各个组件;
export FABRIC_CFG_PATH=$PWD
使用 configtxgen 工具生成创世区块,TwoOrgsOrdererGenesis 在 configtx.yaml 文件中配置;
../bin/configtxgen -profile TwoOrgsOrdererGenesis -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block
排序通道创世区块和其他生成的构件都保存在当前项目根目录中的 channel-artifacts 文件夹。
使用 configtxgen 工具执行生成通道配置的交易,注意此处 CHANNEL_NAME 环境变量的设置
export CHANNEL_NAME=mychannel && ../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME
排序通道创世区块和其他生成的构件都保存在当前项目根目录中的 channel-artifacts 文件夹。
使用 configtxgen 工具为构建的通道上的 Org1 定义锚节点,注意此处 CHANNEL_NAME 环境变量的设置
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP
使用 configtxgen 工具为构建的通道上的 Org2 定义锚节点,注意此处 CHANNEL_NAME 环境变量的设置
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP
排序通道创世区块和其他生成的构件都保存在当前项目根目录中的 channel-artifacts 文件夹。
使用 docker-compose 启动一个 docker 网络
docker-compose -f docker-compose-cli.yaml up # 显示实时日志
docker-compose -f docker-compose-cli.yaml up -d # 不显示实时日志
docker exec -it cli bash # 进入 cli 容器
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/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 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
peer channel join -b mychannel.block
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/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
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
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/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
peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/
设置环境变量
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/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 chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/
排序服务
交易流程
账本
账本可以理解为我们日常生活中所用的账本;
账本主要有两部分组成:世界状态 + 交易日志
账本
创世区块——创世区块用于引导排序服务,是区块链网络中的第一个节点