1. 程式人生 > >Hyperledger fabri 部署網路(單機環境)

Hyperledger fabri 部署網路(單機環境)


title: Hyperledger fabri 部署網路(單機環境)
tags: Hyperledger, fabric ,區塊鏈


安裝預置環境

下載專案

        首先我們需要配置好Hyperledger Fabric開發環境,然後下載並安裝Hyperledger Fabric Samples。你會注意到fabric-samples資料夾中包含了許多示例。我們將使用first-network這個例子。

        你如果你不知道環境配置和Samlpes

的下載安裝,可以看我之前的文章:

https://blog.csdn.net/yang731227/article/details/83868333

使用指令碼自動部署

         Hyperledger Fabric Samples提供一個完全註釋的指令碼byfn.sh,利用這些Docker映象可以快速引導一個由4個代表2個不同組織的peer節點以及一個排序服務節點的Hyperledger fabric網路。它還將啟動一個容器來執行一個將peer節點加入channel、部署例項化鏈碼服務以及驅動已經部署的鏈碼執行交易的指令碼。

        為了使用byfn.sh 我們先切換到 first-network目錄
```cd /home/go/src/fabric-samples/first-network`

1.檢視byfn.sh幫助文件

./byfn.sh -h

注意:如果你選擇不提供channel名稱,則指令碼將使用預設名稱mychannel

  1. 生成配置

        第一步先生成成我們各種網路實體的所有證書和金鑰。

./byfn.sh -m generate -i 1.0.0

只截取了部分資訊

注意:1.0.0是映象標籤 ,使用 -i可以指定標籤,如果不指定預設標籤為latest, 下面命令中的1.0.0類同。

  1. 啟動網路
            現在我們開始使用命令啟動網路

./byfn.sh -m up -i 1.0.0

  1. 關閉網路
            當然我們也可以關閉網路,使用下面的命令會將關閉你的容器,移除加密材料和4個配置資訊,並且從Docker倉庫刪除chaincode映象

./byfn.sh -m down -i 1.0.0

使用工具手動部署

瞭解工具

  • 證書生成器

        fabric使用cryptogen工具,讀取描述了網路的拓撲結構crypto-config.yaml的配置檔案,來為網路中的實體生成證書(certificates)。這些證書是身份的代表,它們允許在我們的網路實體進行交流和交易時進行簽名/驗證身份驗證。

        通過對每個組織分配唯一的CA證書,每個鏈成員通過自己的證書獲取許可權。Hyperledger Fabric中的交易和通訊是通過儲存在keystore中的實體的私鑰簽名,然後通過公鑰手段進行驗證(signcerts)。

        crypto-config.yaml檔案裡的count引數用來指指定每個組織中peer的數量。

有興趣的小夥伴可以自己看本機的crypto-config.yaml檔案。

  • 配置交易生成器

`configtxgen是Hyperledger Fabric提供的用於通道配置的實用程式,主要生成以下3種檔案:

  • order genesis block :排序服務(ordering service)的創世區塊。
  • channel configuration transaction : 通道配置交易,會在channel建立時廣播給orderer。
  • 以及兩個anchor peer transactions :指定通道上兩個組織的錨節點(Anchor Peer)。

        Configtxgen使用一個包含簡單網路的定義的configtx.yaml檔案。該檔案還指定了一個SampleConsortium的聯盟,2個節點組織構成。

請注意,我們SampleConsortium在系統級配置檔案中定義,然後由我們的通道級配置檔案引用。渠道存在於一個聯盟的範圍內,所有聯盟必須在整個網路的範圍內定義。

手動生成配置檔案

        我們可以用configtxgencryptogen命令來手動生成證書/金鑰和各種配置檔案。

注意:cryptogenconfigtxgen 都是需要我們手動編譯生成的,並且存放在$GOPATH/bin/
如何生成,可以檢視我之前的文章
https://blog.csdn.net/yang731227/article/details/83868333

  1. 生成證書
            首先我們執行crytyogen工具,我們的二進位制檔案位於bin 目錄中. 我們可以通過修改crypto-config.yaml檔案來生成我們需要的證書。

首先進入存放crypto-config.yaml的目錄

cd  fabric-samples/first-network

然後執行工具生成證書

$GOPATH/bin/cryptogen generate --config=./crypto-config.yaml

執行命令返回資訊:

org1.example.com
org2.example.com

執行命令後,證書和金鑰(也就是MSP material)將輸出到crypto-config目錄中,裡面是各個組織的安全檔案。

  1. 生成創世區塊

        接下來,我們需要告訴configtxgen去哪找到需要的配置檔案configtx.yaml,所以我們先先設定一個環境變數。
必須在fabric-samples/first-network 目錄下使用
export FABRIC_CFG_PATH=$PWD

然後,我們將呼叫configtxgen工具去建立orderer genesis block

$GOPATH/bin/configtxgen -profile TwoOrgsOrdererGenesis -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block

注意: orderer genesis塊和我們即將建立的後續工件將輸出到channel-artifacts該專案根目錄的目錄中。上述命令中的channelID是系統通道的名稱。

  1. 建立channel transaction配置(channel.tx)

        接下來,我們需要建立channel transaction配置。執行命令前需要設定$CHANNEL_NAME環境變數。

export CHANNEL_NAME=mychannel`
$GOPATH/bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME`

        接下來,在我們建立的channel上定義兩個Anchor Peer節點 Org1Org2。執行命令為:

$GOPATH/bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP`

$GOPATH/bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP `

order genesis block 和 channel transaction artifacts都將輸出到channel-artifacts目錄下。最終目錄包含4個檔案:genesis.block,channel.tx,Org1MSPanchors.tx和Org2MSPanchors.tx。

啟動網路

注意:如果你之前使用 byfn.sh指令碼開啟了網路,請確保在繼續操作之前已關閉測試網路。

        我們將利用docker-compose指令碼來啟動我們的區塊鏈網路。docker-compose檔案利用我們之前下載的映象,並用以前生成的genesis.block來引導orderer。

        在執行之前,需要修改docker-compose-cli.yaml檔案,使用#註釋掉下面的程式碼:

#command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME} ${DELAY}; sleep $TIMEOUT'

        該行程式碼會使cli容器執行的時候自動執行指令碼script.sh,會進行建立channel,加入節點等等一系列操作,此時如果再進行手動執行,並把CHANNEL_NAME設定為mychannel,就會出現channel名稱重複問題,從而報錯 Error: got unexpected status: BAD_REQUEST

1.執行docker-compose命令啟動網路:

docker-compose -f docker-compose-cli.yaml up -d

CLI容器處於空閒狀態時只會會停留1000秒。你可以使用以下命令再次啟動它:

docker start cli

2.設定環境變數
        下面是peer0.org1.example.com的環境變數。每當在CLI命令中需要執行節點操作時,都要確認當前處於哪個節點下。

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/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

        CLI容器針對peer0.org1.example.com操作所需要的環境變數已經設定好了,但如果需要對其他peer或者orderer節點進行操作,則需要提供這些變數值。

        例如,要切換至peer1.org1節點,就需要將peer0.org1.example.com在環境變數中進行替換。同理,如果切換到其他節點,需要對應的修改環境變數。

3.建立&加入通道

我們使用configtxgen工具建立channel transaction配置 。你可以重複使用相同或不同的configtx.yaml檔案,在你的網路建立其他的通道。

        我首先進入CLI容器中:

docker exec -it cli bash

        如果執行成功,你將看到下列資訊:opt/gopath/src/github.com/hyperledger/fabric/peer#

        我們使用-c標誌指定channel的名字,-f標誌指定channel配置檔案。在這個例子中它是channel.tx,當然你也可以使用不同的名稱,掛載你自己的channel配置。再一次,我們將在CLI容器裡設定了CHANNEL_NAME環境變數,所以不需要明確傳遞這個引數。

export CHANNEL_NAME=mychannel

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

注意:-- cafile會作為命令的一部分。這是orderer的root cert的本地路徑,允許我們去驗證TLS握手。

        此命令返回一個創世區塊<channel-ID.block>,我們將使用它加入通道。它包含了channel.tx中的配置資訊。如果你沒有修改過channel.tx檔案中預設的通道名稱,上面的命令會返回mychannel.block

        現在讓我們將peer0.org1.example.com加入channel。

peer channel join -b mychannel.block

        前面我們說過,當需要加入其他節點的時候,需要設定環境變數

CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
CORE_PEER_ADDRESS=peer0.org2.example.com:7051 
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 

我們繼續加入peer0.org2.example.com

peer channel join -b mychannel.block

你可以修改環境變數來讓別的節點加入通道,這裡我就不演示了。

  1. 更新錨節點(anchor peers)

        我最後新增到節點是peer1.org2.example.com,所以執行完成後我們的命令列現在處於peer1.org2下。而現在我們需要為Org1設定錨節點peer0.org1,所以命令列需要先切回到peer0.org1

設定當前操作節點為peer0.org1

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/[email protected]/msp 
CORE_PEER_ADDRESS=peer0.org1.example.com:7051

然後更新Org1錨節點為peer0.org1

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

接下來為Org2設定錨節點peer0.org2

設定當前操作節點為peer0.org2:

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/[email protected]/msp 
CORE_PEER_ADDRESS=peer0.org2.example.com:7051

然後更新Org2錨節點為peer0.org2

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

安裝和例項化鏈碼

        我們將利用一個現有的簡單鏈碼,應用程式和區塊鏈賬本會相互影響通過chaincode。因此,我們需要在每個會執行以及背書我們交易的peer節點安裝chaincode,然後在通道上例項化chaincode

chaincode 支援很多語言,如Gland ,Node.js ,Java 。

安裝

在這裡我們使用Golang版本的,現在我們來安裝下

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

        接下來,在通道上例項化chaincode。這將初始化通道上的鏈碼,設定鏈碼的背書策略,為目標peer節點啟動一個chaincode容器注意-P引數。這是我們需要指定的當這個chaincode的交易需要被驗證的時侯的背書策略。

        在下面的命令中,你會注意到我們指定-P "OR ('Org0MSP.member','Org1MSP.member')"作為背書策略。這意味著我們需要Org1或者Org2組織中的其中一個的節點的背書即可(即只有一個背書)。如果我們改變語法為AND那麼我們就需要2個背書者。

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 $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"

例項化

現在我們來進行實戰

1.查詢(Query)
讓我們查詢一下a的值,以確保鏈碼被正確例項化,state DB被填充。查詢的語法如下:

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

2.呼叫(Invoke)
現在讓我們從a賬戶轉10到b賬戶。這個交易將建立一個新的區塊並更新state DB。呼叫語法如:

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 $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}'

3.我們再次查詢

讓我們確認下我們之前的呼叫被正確地執行了。我們初始化了a的值為100,在上一次呼叫的時侯轉移了10給b。因此,查詢a應該展示90。查詢的語法如下:

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

執行過程分析

以下是通過./byfn.sh -m up啟動網路時,執行script.sh指令碼所進行步驟

  • script.sh指令碼被拷貝到CLI容器中。這個指令碼驅動了使用提供的channel name以及通道配置的channel.tx檔案的 createChannel命令。

  • createChannel命令的產出是一個創世區塊- <your_channel_name>.block-這個創世區塊被儲存在peer節點的檔案系統中同時包含了在channel.tx的通道配置。

  • joinChannel命令被4個peer節點執行,作為之前產生的genesis block的輸入。這個命令介紹了peer節點加入 <your_channel_name>以及利用 <your_channel_name>.block去建立一條鏈。

  • 現在我們有了由4個peer節點以及2個組織構成的通道。這是我們的 TwoOrgsChannel配置檔案。

  • peer0.org1.example.compeer1.org1.example.com屬於Org1; peer0.org2.example.compeer1.org2.example.com屬於Org2

  • 這些關係是通過crypto-config.yaml定義的,MSP路徑在docker-compose檔案中被指定。

  • Org1MSP( peer0.org1.example.com)和Org2MSP( peer0.org2.example.com)的anchor peers將在後續被更新。我們通過攜帶channel的名字傳遞 Org1MSPanchors.txOrg2MSPanchors.tx配置到排序服務來實現anchor peer的更新。

  • 一個鏈碼- chaincode_example02被安裝在 peer0.org1.example.compeer0.org2.example.com

  • 這個鏈碼在 peer0.org2.example.com被例項化。例項化過程將鏈碼新增到通道上,並啟動peer節點對應的容器,並且初始化和鏈碼服務有關的鍵值對。示例的初始化的值是 [”a“,”100“,”b“,”200“]。例項化的結果是一個名為 dev-peer0.org2.example.com-mycc-1.0的容器啟動了。

  • 例項化過程同樣為背書策略傳遞相關引數。策略被定義為 -P "OR ('Org1MSP.member','Org2MSP.member')",意思是任何交易必須被Org1或者Org2背書。

  • 一個針對 a的查詢發往 peer0.org1.example.com。鏈碼服務已經被安裝在了 peer0.org1.example.com,因此這次查詢將啟動一個名為 dev-peer0.org1.example.com-mycc-1.0的容器。查詢的結果也將被返回。沒有寫操作出現,因此查詢的結果的值將為 100

  • 一次 invoke被髮往 peer0.org1.example.com,從 a轉移 10b

  • 然後鏈碼服務被安裝到 peer1.org2.example.com

  • 一個 query請求被髮往 peer1.org2.example.com用於查詢 a的值。這將啟動第三個鏈碼服務名為 dev-peer1.org2.example.com-mycc-1.0。返回 a的值為90,正確地反映了之前的交易, a的值被轉移了10。