Hyperledger Fabric 之部署网络、详解first-network操作

一 .下载Samples

操作版本v1.0.0
Fabric更新很快,但是基本的流程还是如本文详解的流程。
本人能力有限,如有错误的地方,还望不吝指教。

注意 先搭建好基础环境,再执行下面的步骤。

git clone https://github.com/hyperledger/fabric-samples.git
cd fabric-samples

下载完成后,会有如下文件,这次我们使用first-network来部署网络:

这里写图片描述

二.部署网络

cd first-network
./byfn.sh -m up

看到下面输出,就说明网络启动成功了。它会自动执行了如下几个操作:1. 创建区块链网络(4个peer+1个order)2. 创建channel 把peer加入到channel中 3. 部署/ 执行chaincode 。

.......

========= All GOOD, BYFN execution completed ===========


 _____   _   _   ____
| ____| | \ | | |  _ \
|  _|   |  \| | | | | |
| |___  | |\  | | |_| |
|_____| |_| \_| |____/

三.自动化脚本都做了什么

byfn.sh是demo中封装好的自动化部署脚本,我们来一步一步分析它都执行了哪些操作。

1.启动区块链网络

./byfn.sh -m up最终会执行networkUp


function networkUp () {
    
  if [ ! -d "crypto-config" ]; then
    generateCerts  # 1 
    replacePrivateKey    #2  
    generateChannelArtifacts  # 3   
  fi
  
  CHANNEL_NAME=$CHANNEL_NAME TIMEOUT=$CLI_TIMEOUT docker-compose -f $COMPOSE_FILE up -d 2>&1    #4
  if [ $? -ne 0 ]; then
    echo "ERROR !!!! Unable to start network"
    docker logs -f cli
    exit 1
  fi
  docker logs -f cli   
}

它都做了什么:

  1. 使用cryptogen根据crypto-config.yaml文件,为网络中的每个节点以及组织生成证书/秘钥。
  2. 这里使用到一个模板文件, 把模板里的私钥换成 上面生成的私钥。
  3. 使用configtxgen根据configtx.yaml文件,生成通道所需资料 。
  4. 使用docker-compose运行docker-compose-cli.yaml里面定义的服务,每个服务都是运行在独立的docker容器中。

此时网络就启动了,通过docker ps查看下当前的网络 :

fa5e433e52d3        hyperledger/fabric-tools              "/bin/bash -c './s..."   31 minutes ago      Up 31 minutes                                                          cli
5f767fa25e10        hyperledger/fabric-orderer            "orderer"                31 minutes ago      Up 31 minutes       0.0.0.0:7050->7050/tcp                             orderer.example.com
2d4c09ceed5f        hyperledger/fabric-peer               "peer node start"        31 minutes ago      Up 31 minutes       0.0.0.0:8051->7051/tcp, 0.0.0.0:8053->7053/tcp     peer1.org1.example.com
6d865dbcc698        hyperledger/fabric-peer               "peer node start"        31 minutes ago      Up 31 minutes       0.0.0.0:9051->7051/tcp, 0.0.0.0:9053->7053/tcp     peer0.org2.example.com
e1f2ebe3f527        hyperledger/fabric-peer               "peer node start"        31 minutes ago      Up 31 minutes       0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp     peer0.org1.example.com
b74aed9e23f2        hyperledger/fabric-peer               "peer node start"        31 minutes ago      Up 31 minutes       0.0.0.0:10051->7051/tcp, 0.0.0.0:10053->7053/tcp   peer1.org2.example.com

2.执行/scripts/script.sh脚本

其中cli服务是最后启动的,启动成功后会自动执行/scripts/script.sh这个脚本(cli服务中配置了 command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT' )。

脚本了主要做了如下操作:


## 1.创建channel
echo "Creating channel..."
createChannel

## 2.把所有的peer加入到channel中
echo "Having all peers join the channel..."
joinChannel

## 3.设置每个组织中的锚点peer
echo "Updating anchor peers for org1..."
updateAnchorPeers 0
echo "Updating anchor peers for org2..."
updateAnchorPeers 2

## 4.在peer0 peer2节点上安装chaincode
echo "Installing chaincode on org1/peer0..."
installChaincode 0
echo "Install chaincode on org2/peer2..."
installChaincode 2

# 5. 在peer2节点上初始化chaincode
echo "Instantiating chaincode on org2/peer2..."
instantiateChaincode 2

# 6.在Peer0节点上执行chaincode的查询操作
echo "Querying chaincode on org1/peer0..."
chaincodeQuery 0 100

# 7.在Peer0节点上执行chaincode的invoke操作
echo "Sending invoke transaction on org1/peer0..."
chaincodeInvoke 0

## 8. 在peer3上安装chaincode
echo "Installing chaincode on org2/peer3..."
installChaincode 3

# 9.在Peer3上执行查询操作,查看结果是否为90
echo "Querying chaincode on org2/peer3..."
chaincodeQuery 3 90

四.自己执行channel/chaincode相关操作

如果要自己执行channel/chaincode相关操作该如何操作呢? 先执行./byfn.sh -m down 关闭网络,再禁止自动执行/scripts/script.sh脚本。

这里写图片描述

启动网络

 ./byfn.sh -m  up

完成后,在另外一个命令面板里 docker ps查看网络(两个组织,每个组织两个peer):

CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS                                      NAMES
91203e17dff2        hyperledger/fabric-tools     "/bin/bash"         37 seconds ago      Up 35 seconds                                      cli
50eed8db37e5        hyperledger/fabric-peer      "peer node start"   46 seconds ago      Up 38 seconds       0.0.0.0:10051->7051/tcp, 0.0.0.0:10053->7053/tcp   peer1.org2.example.com
fccc67250e79        hyperledger/fabric-peer      "peer node start"   46 seconds ago      Up 38 seconds       0.0.0.0:8051->7051/tcp, 0.0.0.0:8053->7053/tcp     peer1.org1.example.com
04ba77fe9c07        hyperledger/fabric-peer      "peer node start"   46 seconds ago      Up 37 seconds       0.0.0.0:9051->7051/tcp, 0.0.0.0:9053->7053/tcp     peer0.org2.example.com
e2a14716ff5b        hyperledger/fabric-orderer   "orderer"           46 seconds ago      Up 37 seconds       0.0.0.0:7050->7050/tcp                             orderer.example.com
b88215b96968        hyperledger/fabric-peer      "peer node start"   46 seconds ago      Up 39 seconds       0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp     peer0.org1.example.com

进入cli容器

docker exec -it cli bash

执行结果:

这里写图片描述

在cli里设置org1的peer0的环境变量,直接复制到命令面板中:

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		

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp		

CORE_PEER_ADDRESS=peer0.org1.example.com:7051

执行结果:

这里写图片描述

创建channel

在org1的peer0节点上创建channel:

peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 

执行结果:

这里写图片描述

加入到channel

把4个peer加入到channel中,因为每个peer节点的环境变量是不一样的,所以先要配置正确的环境变量,再执行加入命令。

设置org1-peer0的环境变量:

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		

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp		

CORE_PEER_ADDRESS=peer0.org1.example.com:7051

加入到channel:

peer channel join -b mychannel.block

执行结果:

这里写图片描述

其他节点的操作也是如此,其他节点环境变量如下:

org1-peer1:

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		

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp		

CORE_PEER_ADDRESS=peer1.org1.example.com:7051

org2-peer0:

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		

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp		

CORE_PEER_ADDRESS=peer0.org2.example.com:7051

org2-peer1:

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		

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp		

CORE_PEER_ADDRESS=peer1.org2.example.com:7051

安装chaincode

我们使用demo中的chaincode,需要指定chaincode的名字 /版本/路径

peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 

结果:

这里写图片描述

chaincode文件是这么映射的:

这里写图片描述

初始化chaincode

peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n mycc -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"

结果:

这里写图片描述

注意以下几点:

  1. -c '{"Args":["init","a", "100", "b","200"]}'
    这里会触发chaincode的Init方法,分别向a账户/b账户存入100/200元。
  2. -P "OR ('Org1MSP.member','Org2MSP.member')"
    这个涉及到了背书策略(endorsement),它是由-p 参数来指定的。这句话的意思是交易时必须通过org1或者org2的一个成员的支持(背书),更多语法详情看这里
  3. 初始化完成后,会多出一个运行chaincode的容器,容器名字的规则:dev-节点-chaincode名称-chaincode 版本

这里写图片描述
5. chaincode的初始化只需要一次,但是chaincode需要在channel内的所有peer上进行安装。目前我们只是在org2-peer1节点上安装了chaincode,按照前面的环境变量,切换到其他对应的节点,来执行chaincode的安装。

chaincode之query方法

查询a的余额:

peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}' 

查询结果:

这里写图片描述

chaincode之invoke方法

b向a转账50元:

peer chaincode invoke -o orderer.example.com:7050  --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n mycc -c '{"Args":["invoke","b","a","50"]}' 

执行结果:

这里写图片描述

再次查询余额:

这里写图片描述

chaincode其他方法

从v1.0.0开始,我们写的chaincode只要实现ChaincodeStubInterface 接口即可:

type Chaincode interface {
	// 初始化 或者 更新chaincode的时候 会执行这个操作
	Init(stub ChaincodeStubInterface) pb.Response
	// 定义 CURD的方法
	Invoke(stub ChaincodeStubInterface) pb.Response
	// 旧版本有个 Query 方法,现在整合到了Invoke里面
}

我们看下chaincode_example02.go 是怎么实现的:


func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
	fmt.Println("ex02 Init")
	_, args := stub.GetFunctionAndParameters()
	
	.......
	
	return shim.Success(nil)
}
//  定义了三个方法
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
	fmt.Println("ex02 Invoke")
	function, args := stub.GetFunctionAndParameters()
	if function == "invoke" {
		//a-转账->b  x元
		return t.invoke(stub, args)
	} else if function == "delete" {
		// 删除
		return t.delete(stub, args)
	} else if function == "query" {
		// 查询
		return t.query(stub, args)
	}

	return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"")
}
......

所有的逻辑都最终会进入Invoke来分发,比如删除b账户的操作:

peer chaincode invoke -o orderer.example.com:7050  --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n mycc -c '{"Args":["delete","b"]}' 

其他方法的演示只需要把'{"Args":["delete","b"]}' 里面的delelete 换成你定义的方法,后面带上合适的参数即可。

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页