1. 程式人生 > >Hyperledger Fabric v1.3入門學習

Hyperledger Fabric v1.3入門學習

目錄

4.問題

1.準備環境

  • VMware Workstation
  • ubuntu 16.04 LTS 
  • 安裝Go,安裝方法可以參考《Golang入門學習
  • 安裝docker compose

2.下載Fabric原始碼

[email protected]:/opt/go-pkg/src/github.com# mkdir hyperledger
[email protected]:/opt/go-pkg/src/github.com# cd hyperledger
# 開始下載
[email protected]:/opt/go-pkg/src/github.com/hyperledger# git clone https://github.com/hyperledger/fabric.git
[email protected]
:/opt/go-pkg/src/github.com/hyperledger# cd fabric [email protected]:/opt/go-pkg/src/github.com/hyperledger/fabric# git checkout v1.3.0

3.官網入門程式

鏈碼目錄:github.com/hyperledger/fabric/examples/chaincode/go 

3.1.下載映象

# 啟動docker服務
[email protected]:/opt/go-pkg/src/github.com/hyperledger/fabric/examples/e2e_cli# systemctl start docker
# 執行download-dockerimages.sh指令碼下載相關映象
[email protected]
:/opt/go-pkg/src/github.com/hyperledger/fabric/examples/e2e_cli# source download-dockerimages.sh -c latest -f latest

如果下載失敗,可以修改指令碼指定具體映象Tag,文章寫作時最新版本,fabric-peer/tags:1.3.0,fabric-kafka/tags:0.4.14。映象詳情可以參考:https://hub.docker.com/r/hyperledger/

download-dockerimages.sh指令碼內容如下:

#!/bin/bash -eu
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#


##################################################
# This script pulls docker images from hyperledger
# docker hub repository and Tag it as
# hyperledger/fabric-<image> latest tag
##################################################

dockerFabricPull() {
  local FABRIC_TAG=$1
  for IMAGES in peer orderer couchdb ccenv javaenv kafka tools zookeeper; do
      echo "==> FABRIC IMAGE: $IMAGES"
      echo
      docker pull hyperledger/fabric-$IMAGES:$FABRIC_TAG
      docker tag hyperledger/fabric-$IMAGES:$FABRIC_TAG hyperledger/fabric-$IMAGES
  done
}

dockerCaPull() {
      local CA_TAG=$1
      echo "==> FABRIC CA IMAGE"
      echo
      docker pull hyperledger/fabric-ca:$CA_TAG
      docker tag hyperledger/fabric-ca:$CA_TAG hyperledger/fabric-ca
}
usage() {
      echo "Description "
      echo
      echo "Pulls docker images from hyperledger dockerhub repository"
      echo "tag as hyperledger/fabric-<image>:latest"
      echo
      echo "USAGE: "
      echo
      echo "./download-dockerimages.sh [-c <fabric-ca tag>] [-f <fabric tag>]"
      echo "      -c fabric-ca docker image tag"
      echo "      -f fabric docker image tag"
      echo
      echo
      echo "EXAMPLE:"
      echo "./download-dockerimages.sh -c 1.1.1 -f 1.1.0"
      echo
      echo "By default, pulls the 'latest' fabric-ca and fabric docker images"
      echo "from hyperledger dockerhub"
      exit 0
}

while getopts "\?hc:f:" opt; do
  case "$opt" in
     c) CA_TAG="$OPTARG"
        echo "Pull CA IMAGES"
        ;;

     f) FABRIC_TAG="$OPTARG"
        echo "Pull FABRIC TAG"
        ;;
     \?|h) usage
        echo "Print Usage"
        ;;
  esac
done

: ${CA_TAG:="latest"}
: ${FABRIC_TAG:="latest"}

echo "===> Pulling fabric Images"
dockerFabricPull ${FABRIC_TAG}

echo "===> Pulling fabric ca Image"
dockerCaPull ${CA_TAG}
echo
echo "===> List out hyperledger docker images"
docker images | grep hyperledger*

3.2.建立公私鑰、證書、創世區塊及通道配置

# 執行示例指令碼
[email protected]:/opt/go-pkg/src/github.com/hyperledger/fabric/examples/e2e_cli# source generateArtifacts.sh mychannel

執行結果:

  • ./channel-artifacts目錄下會生成channel.tx、genesis.block、Org1MSPanchors.tx、Org2MSPanchors.tx檔案。
  • 生成crypto-config目錄及子目錄和檔案。
  • 由docker-compose-e2e-template.yaml模板生成docker-compose-e2e.yaml檔案並自動填充CA1_PRIVATE_KEY和CA2_PRIVATE_KEY內容。

具體相關命令及說明可以參考generateArtifacts.sh指令碼,內容如下:

#!/bin/bash +x
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#


#set -e

CHANNEL_NAME=$1
: ${CHANNEL_NAME:="mychannel"}
echo $CHANNEL_NAME

export FABRIC_ROOT=$PWD/../..
export FABRIC_CFG_PATH=$PWD
echo

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)}')

## Using docker-compose template replace private key file names with constants
function replacePrivateKey () {
	ARCH=`uname -s | grep Darwin`
	if [ "$ARCH" == "Darwin" ]; then
		OPTS="-it"
	else
		OPTS="-i"
	fi

	cp docker-compose-e2e-template.yaml docker-compose-e2e.yaml

        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
}

## Generates Org certs using cryptogen tool
function generateCerts (){
	CRYPTOGEN=$FABRIC_ROOT/release/$OS_ARCH/bin/cryptogen

	if [ -f "$CRYPTOGEN" ]; then
            echo "Using cryptogen -> $CRYPTOGEN"
	else
	    echo "Building cryptogen"
	    make -C $FABRIC_ROOT release
	fi

	echo
	echo "##########################################################"
	echo "##### Generate certificates using cryptogen tool #########"
	echo "##########################################################"
	$CRYPTOGEN generate --config=./crypto-config.yaml
	echo
}

function generateIdemixMaterial (){
	IDEMIXGEN=$FABRIC_ROOT/release/$OS_ARCH/bin/idemixgen
	CURDIR=`pwd`
	IDEMIXMATDIR=$CURDIR/crypto-config/idemix

	if [ -f "$IDEMIXGEN" ]; then
            echo "Using idemixgen -> $IDEMIXGEN"
	else
	    echo "Building idemixgen"
	    make -C $FABRIC_ROOT release
	fi

	echo
	echo "####################################################################"
	echo "##### Generate idemix crypto material using idemixgen tool #########"
	echo "####################################################################"

	mkdir -p $IDEMIXMATDIR
	cd $IDEMIXMATDIR

	# Generate the idemix issuer keys
	$IDEMIXGEN ca-keygen

	# Generate the idemix signer keys
	$IDEMIXGEN signerconfig -u OU1 -e OU1 -r 1

	cd $CURDIR
}

## Generate orderer genesis block , channel configuration transaction and anchor peer update transactions
function generateChannelArtifacts() {

	CONFIGTXGEN=$FABRIC_ROOT/release/$OS_ARCH/bin/configtxgen
	if [ -f "$CONFIGTXGEN" ]; then
            echo "Using configtxgen -> $CONFIGTXGEN"
	else
	    echo "Building configtxgen"
	    make -C $FABRIC_ROOT release
	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!
	$CONFIGTXGEN -profile TwoOrgsOrdererGenesis -channelID e2e-orderer-syschan -outputBlock ./channel-artifacts/genesis.block

	echo
	echo "#################################################################"
	echo "### Generating channel configuration transaction 'channel.tx' ###"
	echo "#################################################################"
	$CONFIGTXGEN -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME

	echo
	echo "#################################################################"
	echo "#######    Generating anchor peer update for Org1MSP   ##########"
	echo "#################################################################"
	$CONFIGTXGEN -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP

	echo
	echo "#################################################################"
	echo "#######    Generating anchor peer update for Org2MSP   ##########"
	echo "#################################################################"
	$CONFIGTXGEN -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP
	echo
}

generateCerts
generateIdemixMaterial
replacePrivateKey
generateChannelArtifacts

3.3.修改docker-compose-cli.yaml

# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

version: '2'

services:

  cli:
    container_name: cli
    image: hyperledger/fabric-tools
    tty: true
    environment:
      - GOPATH=/opt/gopath
      - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
      - CORE_LOGGING_LEVEL=DEBUG
      - CORE_PEER_ID=cli
      - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
      - CORE_PEER_LOCALMSPID=Org1MSP
      - CORE_PEER_LOCALMSPTYPE=bccsp
      - CORE_PEER_TLS_ENABLED=true
      - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
      - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
      - 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
      - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
    #command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT'
    volumes:
        - /var/run/:/host/var/run/
        - ../chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go
        - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
        - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
        - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
    extra_hosts:
      - "orderer.example.com:192.168.108.132"
      - "peer0.org1.example.com:192.168.108.132"
      - "peer1.org1.example.com:192.168.108.132"
      - "peer0.org2.example.com:192.168.108.132"
      - "peer1.org2.example.com:192.168.108.132"
      - "ca.org1.example.com:192.168.108.132"
      - "ca.org2.example.com:192.168.108.132"
      - "ca_peerOrg1:192.168.108.132"
      - "ca_peerOrg2:192.168.108.132"

修改內容:

  • 去除了zookeepr、kafka、orderer、peer依賴配置。
  • 註釋了command命令。
  • 新增extra_hosts屬性

3.4.配置虛擬機器Host

192.168.108.132 orderer.example.com
192.168.108.132 ca.org1.example.com
192.168.108.132 ca.org2.example.com
192.168.108.132 ca.example.com
192.168.108.132 ca_peerOrg1
192.168.108.132 ca_peerOrg2

192.168.108.132 peer1.org1.example.com
192.168.108.132 peer0.org2.example.com
192.168.108.132 peer1.org1.example.com
192.168.108.132 peer1.org2.example.com

3.5.啟動Fabric網路

3.5.1.啟動zookeepr、kafka、orderer、peer、ca容器

# 啟動zookeepr、kafka、orderer、peer、ca容器
[email protected]:/opt/go-pkg/src/github.com/hyperledger/fabric/examples/e2e_cli# docker-compose -f docker-compose-e2e.yaml up

3.5.2.啟動cli容器 

# 啟動cli容器
[email protected]:/opt/go-pkg/src/github.com/hyperledger/fabric/examples/e2e_cli# docker-compose -f docker-compose-cli.yaml up

 3.5.3.進入cli容器

# 進入cli容器
[email protected]:/opt/go-pkg/src/github.com/hyperledger/fabric/examples/e2e_cli# docker exec -it cli bash
# cli容器
[email protected]:/opt/gopath/src/github.com/hyperledger/fabric/peer#

3.5.4.通過指令碼操作Chaincode

# cli容器
[email protected]:/opt/gopath/src/github.com/hyperledger/fabric/peer# ./scripts/script.sh

./scripts/script.sh內容如下:

#!/bin/bash
# Copyright London Stock Exchange Group All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
echo
echo " ____    _____      _      ____    _____           _____   ____    _____ "
echo "/ ___|  |_   _|    / \    |  _ \  |_   _|         | ____| |___ \  | ____|"
echo "\___ \    | |     / _ \   | |_) |   | |    _____  |  _|     __) | |  _|  "
echo " ___) |   | |    / ___ \  |  _ <    | |   |_____| | |___   / __/  | |___ "
echo "|____/    |_|   /_/   \_\ |_| \_\   |_|           |_____| |_____| |_____|"
echo

CHANNEL_NAME="$1"
: ${CHANNEL_NAME:="mychannel"}
: ${TIMEOUT:="60"}
COUNTER=1
MAX_RETRY=5
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
PEER0_ORG1_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
PEER0_ORG2_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
ORDERER_SYSCHAN_ID=e2e-orderer-syschan

echo "Channel name : "$CHANNEL_NAME

verifyResult () {
	if [ $1 -ne 0 ] ; then
		echo "!!!!!!!!!!!!!!! "$2" !!!!!!!!!!!!!!!!"
                echo "================== ERROR !!! FAILED to execute End-2-End Scenario =================="
		echo
   		exit 1
	fi
}

setGlobals () {
	PEER=$1
	ORG=$2
	if [ $ORG -eq 1 ] ; then
		CORE_PEER_LOCALMSPID="Org1MSP"
		CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
		CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
		if [ $PEER -eq 0 ]; then
			CORE_PEER_ADDRESS=peer0.org1.example.com:7051
		else
			CORE_PEER_ADDRESS=peer1.org1.example.com:8051
		fi
	elif [ $ORG -eq 3 ] ; then
		CORE_PEER_LOCALMSPID="Org3MSP"
		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
		CORE_PEER_ADDRESS=peer0.org1.example.com:7051
		CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/idemix/idemix-config
		CORE_PEER_LOCALMSPTYPE=idemix
	else
		CORE_PEER_LOCALMSPID="Org2MSP"
		CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA
		CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
		if [ $PEER -eq 0 ]; then
			CORE_PEER_ADDRESS=peer0.org2.example.com:9051
		else
			CORE_PEER_ADDRESS=peer1.org2.example.com:10051
		fi
	fi

	env |grep CORE
}

checkOSNAvailability() {
	# Use orderer's MSP for fetching system channel config block
	CORE_PEER_LOCALMSPID="OrdererMSP"
	CORE_PEER_TLS_ROOTCERT_FILE=$ORDERER_CA
	CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp

	local rc=1
	local starttime=$(date +%s)

	# continue to poll
	# we either get a successful response, or reach TIMEOUT
	while test "$(($(date +%s)-starttime))" -lt "$TIMEOUT" -a $rc -ne 0
	do
		 sleep 3
		 echo "Attempting to fetch system channel '$ORDERER_SYSCHAN_ID' ...$(($(date +%s)-starttime)) secs"
		 if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
			 peer channel fetch 0 -o orderer.example.com:7050 -c "$ORDERER_SYSCHAN_ID" >&log.txt
		 else
			 peer channel fetch 0 0_block.pb -o orderer.example.com:7050 -c "$ORDERER_SYSCHAN_ID" --tls --cafile $ORDERER_CA >&log.txt
		 fi
		 test $? -eq 0 && VALUE=$(cat log.txt | awk '/Received block/ {print $NF}')
		 test "$VALUE" = "0" && let rc=0
	done
	cat log.txt
	verifyResult $rc "Ordering Service is not available, Please try again ..."
	echo "===================== Ordering Service is up and running ===================== "
	echo
}

createChannel() {
	setGlobals 0 1
	if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
		peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx >&log.txt
	else
		peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls --cafile $ORDERER_CA >&log.txt
	fi
	res=$?
	cat log.txt
	verifyResult $res "Channel creation failed"
	echo "===================== Channel '$CHANNEL_NAME' created ===================== "
	echo
}

updateAnchorPeers() {
	PEER=$1
	ORG=$2
	setGlobals $PEER $ORG

	if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
		peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx >&log.txt
	else
		peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx --tls --cafile $ORDERER_CA >&log.txt
	fi
	res=$?
	cat log.txt
	verifyResult $res "Anchor peer update failed"
	echo "===================== Anchor peers updated for org '$CORE_PEER_LOCALMSPID' on channel '$CHANNEL_NAME' ===================== "
	sleep 5
	echo
}

## Sometimes Join takes time hence RETRY atleast for 5 times
joinChannelWithRetry () {
	PEER=$1
	ORG=$2
	setGlobals $PEER $ORG

	peer channel join -b $CHANNEL_NAME.block  >&log.txt
	res=$?
	cat log.txt
	if [ $res -ne 0 -a $COUNTER -lt $MAX_RETRY ]; then
		COUNTER=` expr $COUNTER + 1`
		echo "peer${PEER}.org${ORG} failed to join the channel, Retry after 2 seconds"
		sleep 2
		joinChannelWithRetry $1
	else
		COUNTER=1
	fi
	verifyResult $res "After $MAX_RETRY attempts, peer${PEER}.org${ORG} has failed to join channel '$CHANNEL_NAME' "
}

joinChannel () {
	for org in 1 2; do
	    for peer in 0 1; do
		    joinChannelWithRetry $peer $org
		    echo "===================== peer${peer}.org${org} joined channel '$CHANNEL_NAME' ===================== "
		    sleep 2
		    echo
        done
	done
}

installChaincode () {
	PEER=$1
	ORG=$2
	setGlobals $PEER $ORG
	peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/example02/cmd >&log.txt
	res=$?
	cat log.txt
	verifyResult $res "Chaincode installation on peer peer${PEER}.org${ORG} has Failed"
	echo "===================== Chaincode is installed on peer${PEER}.org${ORG} ===================== "
	echo
}

instantiateChaincode () {
	PEER=$1
	ORG=$2
	setGlobals $PEER $ORG
	# while 'peer chaincode' command can get the orderer endpoint from the peer (if join was successful),
	# lets supply it directly as we know it using the "-o" option
	if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
		peer chaincode instantiate -o orderer.example.com:7050 -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')" >&log.txt
	else
		peer chaincode instantiate -o orderer.example.com:7050 --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')" >&log.txt
	fi
	res=$?
	cat log.txt
	verifyResult $res "Chaincode instantiation on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' failed"
	echo "===================== Chaincode is instantiated on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' ===================== "
	echo
}

chaincodeQuery () {
	PEER=$1
	ORG=$2
	setGlobals $PEER $ORG
	EXPECTED_RESULT=$3
	echo "===================== Querying on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME'... ===================== "
	local rc=1
	local starttime=$(date +%s)

	# continue to poll
	# we either get a successful response, or reach TIMEOUT
	while test "$(($(date +%s)-starttime))" -lt "$TIMEOUT" -a $rc -ne 0
	do
        	sleep 3
        	echo "Attempting to Query peer${PEER}.org${ORG} ...$(($(date +%s)-starttime)) secs"
        	peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' >&log.txt
        	test $? -eq 0 && VALUE=$(cat log.txt | egrep '^[0-9]+$')
        	test "$VALUE" = "$EXPECTED_RESULT" && let rc=0
	done
	echo
	cat log.txt
	if test $rc -eq 0 ; then
		echo "===================== Query successful on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' ===================== "
    	else
		echo "!!!!!!!!!!!!!!! Query result on peer${PEER}.org${ORG} is INVALID !!!!!!!!!!!!!!!!"
        	echo "================== ERROR !!! FAILED to execute End-2-End Scenario =================="
		echo
		exit 1
    	fi
}

# parsePeerConnectionParameters [email protected]
# Helper function that takes the parameters from a chaincode operation
# (e.g. invoke, query, instantiate) and checks for an even number of
# peers and associated org, then sets $PEER_CONN_PARMS and $PEERS
parsePeerConnectionParameters() {
	# check for uneven number of peer and org parameters
	if [ $(( $# % 2 )) -ne 0 ]; then
        	exit 1
	fi

	PEER_CONN_PARMS=""
	PEERS=""
	while [ "$#" -gt 0 ]; do
		PEER="peer$1.org$2"
		PEERS="$PEERS $PEER"
		PEER_CONN_PARMS="$PEER_CONN_PARMS --peerAddresses $PEER.example.com:7051"
		if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "true" ]; then
        		TLSINFO=$(eval echo "--tlsRootCertFiles \$PEER$1_ORG$2_CA")
        		PEER_CONN_PARMS="$PEER_CONN_PARMS $TLSINFO"
        	fi
		# shift by two to get the next pair of peer/org parameters
        	shift; shift
	done
	# remove leading space for output
	PEERS="$(echo -e "$PEERS" | sed -e 's/^[[:space:]]*//')"
}

# chaincodeInvoke <peer> <org> ...
# Accepts as many peer/org pairs as desired and requests endorsement from each
chaincodeInvoke () {
	parsePeerConnectionParameters [email protected]
	res=$?
	verifyResult $res "Invoke transaction failed on channel '$CHANNEL_NAME' due to uneven number of peer and org parameters "

	# while 'peer chaincode' command can get the orderer endpoint from the
	# peer (if join was successful), let's supply it directly as we know
	# it using the "-o" option
	if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
		peer chaincode invoke -o orderer.example.com:7050 -C $CHANNEL_NAME -n mycc $PEER_CONN_PARMS -c '{"Args":["invoke","a","b","10"]}' >&log.txt
	else
        peer chaincode invoke -o orderer.example.com:7050  --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc $PEER_CONN_PARMS -c '{"Args":["invoke","a","b","10"]}' >&log.txt
	fi
	res=$?
	cat log.txt
	verifyResult $res "Invoke execution on PEER$PEER failed "
	echo "===================== Invoke transaction successful on $PEERS on channel '$CHANNEL_NAME' ===================== "
	echo
}

# Check for orderering service availablility
echo "Check orderering service availability..."
checkOSNAvailability

# Create channel
echo "Creating channel..."
createChannel

# Join all the peers to the channel
echo "Having all peers join the channel..."
joinChannel

# Set the anchor peers for each org in the channel
echo "Updating anchor peers for org1..."
updateAnchorPeers 0 1
echo "Updating anchor peers for org2..."
updateAnchorPeers 0 2

# Install chaincode on peer0.org1 and peer2.org2
echo "Installing chaincode on peer0.org1..."
installChaincode 0 1
echo "Install chaincode on peer0.org2..."
installChaincode 0 2

# Instantiate chaincode on peer0.org2
echo "Instantiating chaincode on peer0.org2..."
instantiateChaincode 0 2

# Query on chaincode on peer0.org1
echo "Querying chaincode on peer0.org1..."
chaincodeQuery 0 1 100

# Invoke on chaincode on peer0.org1 and peer0.org2
echo "Sending invoke transaction on peer0.org1 and peer0.org2..."
chaincodeInvoke 0 1 0 2

# Install chaincode on peer1.org2
echo "Installing chaincode on peer1.org2..."
#installChaincode 1 2

# Query on chaincode on peer1.org2, check if the result is 90
echo "Querying chaincode on peer1.org2..."
#chaincodeQuery 1 2 90

#Query on chaincode on peer1.org3 with idemix MSP type, check if the result is 90
echo "Querying chaincode on peer1.org3..."
#chaincodeQuery 1 3 90

echo
echo "===================== All GOOD, End-2-End execution completed ===================== "
echo

echo
echo " _____   _   _   ____            _____   ____    _____ "
echo "| ____| | \ | | |  _ \          | ____| |___ \  | ____|"
echo "|  _|   |  \| | | | | |  _____  |  _|     __) | |  _|  "
echo "| |___  | |\  | | |_| | |_____| | |___   / __/  | |___ "
echo "|_____| |_| \_| |____/          |_____| |_____| |_____|"
echo

說明:

注意修改下面埠,因為cli跟e2e不在一個docker compose裡,需要通過容器對映宿主機埠訪問,詳情可以檢視examples/e2e_cli/base/docker-compose-base.yaml:

CORE_PEER_ADDRESS=peer1.org1.example.com:8051

CORE_PEER_ADDRESS=peer0.org2.example.com:9051

CORE_PEER_ADDRESS=peer1.org2.example.com:10051

  • 為了方便測試註釋掉了後面3個方法呼叫。
  • 主要方法和步驟,建立Channel、更新Anchor、加入Channel、安裝Chaincode、例項化Chaincode、Chaincode查詢、交易

執行完上面指令碼後,通過用下面命令直接查詢:

[email protected]:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'

輸出結果:

說明:指令碼執行時查詢a=100,因為例項初始值a=100。交易後a向b轉了10,所以上面查詢結果a=90。b=210,這裡不在貼圖可以自己測試體驗。

4.問題

  • 操作中可能遇到許可權異常錯誤,可以考慮停止並刪除所有容器後刪除channel-artifacts和crypto-config目錄內容,重新按步驟操作。
  • 注意宿主機使用者跟容器使用者操作許可權,這裡都是用的root使用者。

5.Docker命令

# 停止並刪除所有容器
$ docker rm -f $(docker ps -a -q)

相關推薦

Hyperledger Fabric v1.3入門學習

目錄 4.問題 1.準備環境 VMware Workstation ubuntu 16.04 LTS  安裝Go,安裝方法可以參考《Golang入門學習》 安裝docker compose 2.下載Fabri

區塊鏈學習——HyperLedger-Fabric v1.0環境搭建詳細教程

相對與v0.6版本來說,1.0版本改變較大,此處不多說,只是將小白自己搭建1.0環境的過程分享給大家。希望對大家能有所幫助! 這一篇可能對前面的環境搭建會寫的有些粗略,如有疑問,可閱讀上一篇V0.6版本的環境搭建詳細步驟。 一.環境準備 雲伺服器(CentOS7.2) Go語言環境 docker安裝 d

區塊鏈學習——HyperLedger-Fabric v1.0 啟動過程分析

本章我們從fabric v1.0的e2e_cli示例開始分析整個啟動過程以及在過程中的一些配置檔案 首先呢,還是確保你的基本環境已經搭建完成,v1.0原始碼和映象也都下載完畢 fabric啟動過程中的相關指令碼檔案解析 network_setup.sh指令碼檔案 在原始碼目錄下的network_set

Installing Hyperledger Fabric v1.1 on Ubuntu 16.04?—?Part I

enter eight ecif into repos terminal rac ould imageload There is an entire library of Blockchain APIs which you can select according

Hyperledger Fabric v1.1 單機多節點叢集環境搭建

Fabric v1.1 1.環境安裝 1).安裝go 1.9.x 下載地址 http://golang.org/dl/ 配置環境 #go的安裝根目錄 export GOROOT=/usr/local/go #go的工作路徑根目錄 export GOPAT

Hyperledger Fabric-v1.1多節點叢集

Fabric v1.1 1.環境安裝 1).安裝go 1.9.x 下載地址 http://golang.org/dl/ 配置環境 #go的安裝根目錄 export GOROOT=/usr/local/go #go的工作路徑根目錄 export GOPAT

Hyperledger Fabric 1.3新特性

使用Identity Mixer實現MSP:通過使用零知識證明來保持身份匿名和不可連結的方法。有一種工具可以在稱為 idexmigen的測試環境中生成Identity Mixer憑證,其文件可以在 Identity Mixer MSP配置生成器(idemixgen)中找到。 &n

區塊鏈 Hyperledger Fabric v1.0.0 環境搭建

  前言:最近專案涉及到超級賬本,在有些理論知識的基礎上,需要整一套環境來。 這是一個特別要注意的事情,筆者之前按照網路上推薦,大部分都是推薦ubuntu系統的,於是下載Ubuntu系統(16.04.5和18.04都試試),遇到各種問題,一直不能成功,大概花了好多天,一直不成功,後來都要放棄了,

Hyperledger Fabric 1.3 官方文件翻譯(三)關鍵概念 (Key Concepts)

身份(Identity) 什麼是身份(What is an Identity)? The different actors in a blockchain network include peers, orderers, client applications,

Hyperledger Fabric 1.3 官方文件翻譯(五)教程 (Tutorials)

構建你的第一個網路(Building Your First Network) These instructions have been verified to work against the latest stable Docker images and t

Hyperledger Fabric v1.1.0 + Ubuntu 16.04

1、go安裝(v1.9) ①下載並解壓 wget https://storage.googleapis.com/golang/go1.9.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go1.9.linux-amd

Hyperledger fabric 1.3安裝記錄

一、環境 主機:阿里雲輕量應用伺服器 系統:Ubuntu 16.04(基於4.4核心) 二、先決條件 2.1 go 用此時最新的1.11.2版本 下載: wget https://dl.google.com/go/go1.11.2.linux-amd64.ta

HyperLedger Fabric v1.1.0-alpha 版本原始碼編譯及單節點網路搭建

本文主要參考:https://blog.csdn.net/honganboy/article/details/78714578 的介紹,十分感謝作者。但是安裝版本和環境不同,安裝過程也遇到了一些小問題,因此也再寫一篇供大家參考。安裝環境:作業系統-64位Centos7.2,F

【我的區塊鏈之路】- Hyperledger fabric的簡單入門(三)fabric主要配置檔案細講

fabric的各個配置檔案做講解 Peer 配置剖析         本例子是拿fabric-samples 來說的,【如果是 fabric 的話,在 fabric/的根目錄下有一個 core.yaml 】在 fabric-samples/config 目錄下有

阿里雲容器服務區塊鏈解決方案全新升級 支援Hyperledger Fabric v1.1

作為全球開源區塊鏈領域影響最為廣泛的專案之一,超級賬本近日宣佈了Hyperledger Fabric v1.1的正式釋出。此次升級帶來了一系列豐富的新功能以及在安全性、效能與擴充套件性等諸多方面的顯著提升。更多詳情可參考下述資料: 與此同時,作為對開源區塊鏈生態的支援,

Hyperledger Fabric-CA學習

運行 -1 lba haproxy i2c media lsi 體系架構 mos p { margin-bottom: 0.25cm; line-height: 120% } a:link { } Hyperleder Fabric系統架構核心邏輯包括MemberShip、

python入門學習--2017.9.3

lin 漂亮 用戶輸入 事先 pan 加減乘 更改 web 表白 一 編程與編程語言 python是一門編程語言,作為學習python的開始,需要事先搞明白:編程的目的是什麽?什麽是編程語言?什麽是編程? 編程的目的: #計算機的發明,是為了用機器取代/解

java入門學習3)—循環,選擇,基礎算法,API概念

思想 冒泡 方法 就是 最大的 接口 兩個 循環控制 得到 1、順序結構:也就是順著程序的前後關系,依次執行。2、選擇分支:利用if..else , / switch(){case [ 這個必須是常量]:}; / if..else if….. ….else..等語句讓程序在

實戰:區塊鏈hyperledger fabric 初體驗 - 3: 鏈碼實例安裝、實例化、調用及代碼

區塊鏈 hyperledger fabric blockchain 本文鏈碼實例為Fabric 官方實例examples/chaincode/go/chaincode_example02,實現簡單的轉賬功能進入到cli容器裏面$ docker exec -it fabric-cli bash1

區塊鏈之Hyperledger(超級賬本)Fabric v1.0 的環境搭建(更新)

mirror linu stat iyu wget glob 保存 url oba 參考鏈接:https://blog.csdn.net/so5418418/article/details/78355868 https://blog.csdn.net/wgh101539