Hyperledger Fabric 之部署v1.0.0网络

来源:互联网 发布:淘宝模特小白 编辑:程序博客网 时间:2024/05/07 03:06

    • 一 下载Samples
    • 二部署网络
    • 三自动化脚本都做了什么
      • 启动区块链网络
      • 执行scriptsscriptsh脚本
    • 四自己执行channelchaincode相关操作
      • 启动网络
      • 进入cli容器
      • 创建channel
      • 加入到channel
      • 安装chaincode
      • 初始化chaincode
      • chaincode之query方法
      • chaincode之invoke方法
      • chaincode其他方法

一 .下载Samples

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

git clone https://github.com/hyperledger/fabric-samples.gitcd 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                                                          cli5f767fa25e10        hyperledger/fabric-orderer            "orderer"                31 minutes ago      Up 31 minutes       0.0.0.0:7050->7050/tcp                             orderer.example.com2d4c09ceed5f        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.com6d865dbcc698        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.come1f2ebe3f527        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.comb74aed9e23f2        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.创建channelecho "Creating channel..."createChannel## 2.把所有的peer加入到channel中echo "Having all peers join the channel..."joinChannel## 3.设置每个组织中的锚点peerecho "Updating anchor peers for org1..."updateAnchorPeers 0echo "Updating anchor peers for org2..."updateAnchorPeers 2## 4.在peer0 peer2节点上安装chaincodeecho "Installing chaincode on org1/peer0..."installChaincode 0echo "Install chaincode on org2/peer2..."installChaincode 2# 5. 在peer2节点上初始化chaincodeecho "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上安装chaincodeecho "Installing chaincode on org2/peer3..."installChaincode 3# 9.在Peer3上执行查询操作,查看结果是否为90echo "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                                      NAMES91203e17dff2        hyperledger/fabric-tools     "/bin/bash"         37 seconds ago      Up 35 seconds                                      cli50eed8db37e5        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.comfccc67250e79        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.com04ba77fe9c07        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.come2a14716ff5b        hyperledger/fabric-orderer   "orderer"           46 seconds ago      Up 37 seconds       0.0.0.0:7050->7050/tcp                             orderer.example.comb88215b96968        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 版本

    这里写图片描述

  4. 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 换成你定义的方法,后面带上合适的参数即可。

原创粉丝点击