本文已更新,請移步Hyperledger Fabric(五)手動搭建Fabric網絡V2.0(基於first-network案例)
基於byfn.sh腳本文件的自動化部署過程如下:
① 進入fabric-samples/first-network目錄
cd fabric-samples/first-network
② 為各種網絡實體生成所需的證書及密鑰,引導排序服務的genesis塊,配置通道所需的配置事務,以及錨節點更新事務
./byfn.sh generate #可通過如 -c alwayschannel 指定通道名稱,默認為mychannel
③ 啟動網絡,創建通道,安裝、定義並調用鏈碼
byfn.sh up #用默認值啟動網絡,可通過-c mychannel指定通道名稱,-s couchdb指定使用couchdb而不是leveldb,指定參數-n以不安裝abstore智能合約(該腳本默認安裝該合約),-l java指定安裝腳本的語言為java
④ 銷毀網絡
./byfn.sh down #停止並刪除所有容器,刪除chaincode鏡像,刪除證書及密鑰(crypto-config目錄下),以及四個通道文件(channel-artifacts目錄下,分別為:genesis.block,channel.tx,Org1MSPanchors.tx,Org2MSPanchors.tx,genesis.block為系統通道的創世區塊,后三者分別為創建通道,設置組織一、組織二的錨節點的事務,這些配置操作作為系統事務提交到系統通道中)
純手動搭建Fabric網絡(基於first-network),過程如下:
首先將first-network目錄下的docker-compose-cli.yaml文件中cli容器配置信息中的FABRIC_LOGGING_SPEC=INFO修改為FABRIC_LOGGING_SPEC=DEBUG以看到更多的執行過程信息
使用cryptogen(密碼生成器)和configtxgen(配置事務生成器)手動生成證書/密鑰和各種配置構件(等同於執行./byfn.sh generate -c $CHANNEL_NAME):
① 進入fabric-samples/first-network目錄
cd fabric-samples/first-network
② 使用cryptogen工具為各種網絡實體生成x509證書和簽名密鑰,配置文件為crypto-config.yaml,生成的證書及密鑰存放在crypto-config目錄下
cryptogen generate --config=./crypto-config.yaml
③ 使用configtxgen工具生成系統通道的創世區塊,並將系統的配置操作(創建通道,設置某組織的錨節點等)作為系統事務生成提交到系統通道的事務文件(.tx),配置文件為configtx.yaml,生成的配置組件位於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 #創建 通道配置 事務
Ⅴ configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP #創建 更新組織Org1在該通道上的錨節點(錨節點為某組織對order可見的節點) 的事務
configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP #創建 更新組織Org2在該通道上的錨節點 的事務
啟動網絡,創建並加入通道,更新組織錨節點,安裝、定義並調用一個鏈代碼(等同於執行./byfn.sh up):
① 啟動網絡(該過程使用genesis.block文件)
docker-compose -f docker-compose-cli.yaml -f docker-compose-etcdraft2.yaml up -d #-d用於不顯示網絡的實時日志,若想查看日志流,則后續命令需要打開另一個終端來執行
② 創建並加入通道,並指定(更新)組織的錨節點(錨節點代表整個組織和order節點進行通信,而不是組織的所有節點,以減少通訊量)
Ⅰ docker exec -it cli bash #進入CLI(命令行)容器
Ⅱ 配置CLI容器作為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
Ⅲ export CHANNEL_NAME=mychannel #以環境變量形式設定通道名稱,必須全部小寫,長度小於250個字符,並與正則表達式[a-z][a-z0-9.-]*匹配
Ⅳ 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 #將通道配置事務發送給order節點以創建通道,指定order節點的證書以進行TLS握手,執行結束后該節點將收到來自order節點的對應於所創建通道的創世區塊$CHANNEL_NAME.block
peer channel join -b mychannel.block #將peer0.org1.example.com加入通道,注意命令中的$CHANNEL_NAME.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 #指定peer0.org1.example.com作為組織Org1的錨節點
Ⅴ 配置CLI容器作為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
Ⅵ peer channel join -b mychannel.block #將peer0.org2.example.com加入通道,注意命令中的$CHANNEL_NAME.block,根據通道名稱而變化
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 #指定peer0.org2.example.com作為組織Org2的錨節點
③ 安裝並定義一個鏈代碼(2.0版本中引入了新的Fabric chaincode生命周期,通道的成員組織需要就chaincode定義達成一致。)
Ⅰ 將chaincode安裝到對等節點之前,我們需要對它進行打包,生成的打包文件mycc.tar.gz位於/opt/gopath/src/github.com/hyperledger/fabric/peer目錄,node鏈碼打包命令與java相同,只需修改語言為--lang node,而go鏈碼略有不同,以下為java版本鏈碼的打包命令
peer lifecycle chaincode package mycc.tar.gz --path /opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode/abstore/java/ --lang java --label mycc_1
Ⅱ 安裝鏈碼
peer lifecycle chaincode install mycc.tar.gz
java版本鏈碼報錯(嘗試go版本沒有任何問題):Error: failed to endorse chaincode install: rpc error: code = Unavailable desc = transport is closing
解決:校網環境下,第一次報錯后稍等幾分鍾,再次執行,成功。總之,不斷嘗試吧。
Ⅲ 查詢已安裝的鏈碼
peer lifecycle chaincode queryinstalled #可看到已安裝鏈碼包的ID以及標簽(lable)
Ⅳ 后續命令將需要鏈碼包的ID,因此我們將它保存為一個環境變量,這個ID是動態的,不要直接復制此命令
CC_PACKAGE_ID=mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173
Ⅴ 更改CLI容器的環境變量后,在其它節點上安裝鏈碼(不需要再次打包):
peer lifecycle chaincode install mycc.tar.gz
Ⅵ 通道中的組織需要就鏈碼的定義達成一致,以下命令用於批准一個chaincode定義,--init-required用於初始化chaincode時使init函數被調用,--package-id指定鏈碼包的ID,我們還可以提供--signature-policy或--channel-config-policy參數來設置chaincode背書策略,若未提供將使用默認設置-大多數通道成員背書,這種情況下若在該渠道中添加或刪除新組織,背書策略將自動更新,以要求更多或更少的背書。在本例中,默認策略將需要來自屬於Org1和Org2的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
所有組織都需要對定義達成一致,更改CLI容器的環境變量,繼續
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
一旦足夠多的通道成員組織批准了chaincode定義,一個成員組織就可以將定義提交給通道。可以通過發出以下查詢來檢查chaincode定義是否已准備好提交,並查看當前組織的批准情況
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 #查看各組織對chaincode定義的批准狀況
一旦就鏈碼定義達成一致,則可將chaincode定義提交到通道,可以以Org1或Org2的形式發出此命令
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
④ 調用chaincode
Ⅰ 將--isInit標志傳遞給鏈碼的第一次調用,並將參數提供給Init函數。第一個調用將啟動chaincode容器。我們可能需要等待容器啟動。(確保通道名稱和鏈碼名稱正確)
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
Ⅱ 查詢chaincode
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
Ⅲ 調用鏈碼的invoke函數,a向b轉賬十元
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
注:若通道成員組織的其它節點想和區塊鏈網絡進行交互,只需要加入通道並安裝鏈碼包即可,而不需要提交鏈碼定義(每個組織批准一次鏈碼定義即可)。
至此,手動搭建Fabric網絡基本完成