如果還不具備Hyperledger Fabric V2.0的完整環境,請參考:Hyperledger Fabric(一)V2.0基礎環境搭建。在具備基礎環境后,便可進行Fabric網絡的部署工作。可以參照官網文檔關於first-network案例的部分,使用提供的腳本文件快速啟動區塊鏈網絡。但為了搭建自定義的Fabric網絡,需要掌握腳本所執行的具體操作。
腳本部署Fabric網絡的方式如下(啟用CAs,使用couchdb):
Ⅰ cd fabric-samples/first-network #進入fabric-samples/first-network目錄
Ⅱ ./byfn.sh down #若已經進行過部署,則銷毀已有網絡;若第一次部署,則忽略該步驟
Ⅲ ./byfn.sh up -a -n -s couchdb #參數-a啟動證書頒發機構,-n不部署abstore鏈碼(腳本默認部署該鏈碼),-s使用couchdb數據庫而不是goleveldb ,關於該腳本的詳細使用幫助可通過./byfn.sh -h查看
等效的手動部署Fabric網絡的方式如下(啟用CAs,使用couchdb):
Ⅰ 為網絡中的實體生成證書及密鑰,生成聯盟通道配置組件,啟動Fabric網絡
cd fabric-samples/first-network #進入fabric-samples/first-network目錄
① 使用cryptogen工具生成證書及密鑰,放置於crypto-config目錄下
cryptogen generate --config=./crypto-config.yaml #byfn.sh腳本中的generateCerts()函數調用cryptogen工具后,還調用了同一目錄下的ccp-generate.sh腳本為Org1和Org2生成CCP文件(供后期SDK使用),在此先忽略
② 使用configtxgen工具生成4個配置組件(genesis.block,channel.tx,Org1MSPanchors.tx,Org2MSPanchors.tx),放置於 channel-artifacts目錄下
export FABRIC_CFG_PATH=$PWD #告訴configtxgen從哪里尋找configtx.yaml文件
configtxgen -profile SampleMultiNodeEtcdRaft -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block #生成系統通道創世區塊genesis.block
export CHANNEL_NAME=mychannel #通過環境變量指定通道名稱
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME #創建 通道配置 事務channel.tx
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP #創建 更新組織Org1在該通道上的錨節點 的事務Org1MSPanchors.tx
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP #創建 更新組織Org2在該通道上的錨節點 的事務Org2MSPanchors.tx
結果如下:
③ 使用docker compose基於yaml配置文件啟動容器,建立Fabric網絡(使用CAs與couchdb)
export BYFN_CA1_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org1.example.com/ca && ls *_sk) #以環境變量的形式指定每個組織的CA的私鑰,CA節點的yaml配置文件中會使用該變量
export BYFN_CA2_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org2.example.com/ca && ls *_sk)
docker-compose -f docker-compose-cli.yaml -f docker-compose-etcdraft2.yaml -f docker-compose-ca.yaml -f docker-compose-couch.yaml up -d #參數-d用於不顯示實時日志,若想查看日志流,后續命令則需要打開另一個終端來執行
docker ps #查看已啟動容器的基本信息,包括一個cli,四個peer,四個couchdb,五個order,兩個ca
docker network inspect net_byfn #可查看網絡信息
Ⅱ 創建通道,將peer節點加入通道,並更新組織的錨節點
docker exec -it cli bash #進入CLI(命令行)容器
配置環境變量,以使CLI容器作為peer0.org1.example.com節點執行命令,后續很多操作需要不斷地切換這組環境變量,以作為不同的peer節點執行相關操作,節點peer0.org1.example.com的環境變量如下:
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
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
為了便於查看,在此也先給出節點peer0.org2.example.com的環境變量:
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: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
① 將通道配置事務發送給order節點以創建通道
export CHANNEL_NAME=mychannel #以環境變量形式指定通道名稱,必須全部小寫
peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem #若通道創建成功,將接收到來自order節點的通道的創世區塊,以通道名稱命名
② 切換peer節點的環境變量,多次執行以下命令,將節點加入通道
peer channel join -b $CHANNEL_NAME.block #命令中的$CHANNEL_NAME.block,根據通道名稱而變化
③ 切換peer節點的環境變量,多次執行以下命令,為每個組織指定其在當前通道中的錨節點,每個組織至少有一個錨節點
peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem #為組織指定錨節點
至此./byfn.sh up -a -n -s couchdb所執行的所有工作均通過手動操作實現,若去掉參數-n,該腳本將會繼續執行abstore鏈碼的部署與測試工作,同樣可以純手動完成任何鏈碼的部署與測試。
Ⅲ 鏈碼的打包、安裝、定義、提交與調用測試等部署過程如下(在此以abstore為例,也可使用自己編寫的鏈碼):
① 打包鏈碼(以java語言為例,node可通過--lang node指定,go語言稍有不同,請參考官網文檔)。腳本中命令格式為peer lifecycle chaincode package mycc.tar.gz --path ${CC_SRC_PATH} --lang ${CC_RUNTIME_LANGUAGE} --label mycc_${VERSION}),mycc為鏈碼名稱(可自定義),參數--lang指定鏈碼使用的編程語言,--label指定鏈碼標簽(通常采用 名稱_版本 的格式),--path指定鏈碼的存儲路徑,docker-compose-cli.yaml文件中有卷的映射關系./../chaincode/:/opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode,因此主機的fabric-samples/chaincode目錄對應着peer容器的/opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode目錄
peer lifecycle chaincode package mycc.tar.gz --path /opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode/abstore/java/ --lang java --label mycc_1 #一定要根據自己鏈碼的實際存儲位置,修改 --path的值,目錄對應關系見上述
② 切換peer節點的環境變量,多次執行以下命令,在不同節點安裝鏈碼
peer lifecycle chaincode install mycc.tar.gz #注意鏈碼包名稱mycc.tar.gz與前一條命令保持一致,該命令執行期間很容易報錯Error: failed to endorse chaincode install: rpc error: code = Unavailable desc = transport is closing,原因未知。解決方案:稍等兩分鍾,再次執行命令(高頻率重復執行命令將引起其它錯誤),一般第二次就會成功
③ 查詢節點上已安裝的鏈碼,將鏈碼ID設置為環境變量(后續命令會用到)
peer lifecycle chaincode queryinstalled #可看到已安裝鏈碼包的ID以及標簽
CC_PACKAGE_ID=mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173 #這個ID是動態的,不要直接復制此命令
④ 切換peer節點的環境變量,多次執行以下命令,所有組織就鏈碼定義達成一致(只需要每個組織的某個peer執行一次)
peer lifecycle chaincode approveformyorg --channelID $CHANNEL_NAME --name mycc --version 1.0 --init-required --package-id $CC_PACKAGE_ID --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem #官方腳本中--version和--sequence的值一致,不太清楚兩個值的差別
⑤ 檢查組織是否就鏈碼定義已經達成一致
peer lifecycle chaincode checkcommitreadiness --channelID $CHANNEL_NAME --name mycc --version 1.0 --init-required --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json #查看各組織對鏈碼定義的批准狀況
⑥ 將鏈碼定義提交到通道(任何組織的某個節點執行一次即可)
peer lifecycle chaincode commit -o orderer.example.com:7050 --channelID $CHANNEL_NAME --name mycc --version 1.0 --sequence 1 --init-required --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
⑦ 查詢鏈碼定義
peer lifecycle chaincode querycommitted --channelID $CHANNEL_NAME --name mycc
⑧ 調用鏈碼的初始化函數
peer chaincode invoke -o orderer.example.com:7050 --isInit --tls true --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 $CHANNEL_NAME -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["Init","a","100","b","100"]}' --waitForEvent #-c指定調用鏈碼函數的參數,請根據自己的鏈碼進行修改(第一個參數為函數名)
⑨ 調用鏈碼的查詢(query)函數
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' #-c指定調用鏈碼函數的參數,請根據自己的鏈碼進行修改(第一個參數為函數名)
⑩ 調用鏈碼的invoke函數,a向b轉賬十元,該事務提交后,再次查詢a的值將為90
peer chaincode invoke -o orderer.example.com:7050 --tls true --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 $CHANNEL_NAME -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}' --waitForEvent #-c指定調用鏈碼函數的參數,請根據自己的鏈碼進行修改(第一個參數為函數名)
至此,Fabric網絡已經通過手動方式完成部署,可通過執行./byfn.sh down來銷毀該網絡。若想根據具體實際需求自定義網絡的成員組織或組織中節點的數量,則需要修改crypto-config.yaml、configtx.yaml以及啟動docker容器的yaml配置文件。關於first-network案例使用到的配置文件的簡介,請參照Hyperledger Fabric(四)first-network案例中的主要配置文件及主要腳本。