1. 程式人生 > >Fabric網路下如何為通道新增新的組織

Fabric網路下如何為通道新增新的組織

首先要明確新增通道應該要做哪些事!一要通知orderering service伺服器,新組織加入到通道,驗證過的建議交易封裝後是要提交給orderering service伺服器,由它分發到commit peer節點。二是通道配置要改變,新組織極有可能成為背書策略貢獻者。

一、生成Org3金鑰資料

進入/first-network/org3-artifacts/目錄,該目錄有2個檔案:org3-crypto.yaml和configtx.yaml,執行下列命令

../../bin/cryptogen generate --config=./org3-crypto.yaml

通過org3-crypto.yaml為org3 CA及兩個與之繫結的peer節點生成金鑰和證書,這些檔案儲存在
 org3-artifacts目錄下。

再使用configtxgen以JSON格式打印出Org3-specific配置資料,這個過程用到了 configtx.yaml檔案,命令如下:

export FABRIC_CFG_PATH=$PWD && ../../bin/configtxgen -printOrg Org3MSP > ../channel-artifacts/org3.json

生成org3.json檔案,儲存在/first-network/channel-artifacts/目錄下。這個檔案包含了org3的策略定義和以base-64編碼格式的3個重要證書:admin、CA根證書、TLS根證書,這些資訊將會被追加到通道配置檔案中去。

最後一項任務是把Orderer Org’s MSP資料匯入到Org3的crypto-config目錄。我們主要關注Orderer’s TLS 根證書,用來保證Org3組織與ordering節點通訊。命令如下:

cd ../ && cp -r crypto-config/ordererOrganizations org3-artifacts/crypto-config/

現在我們可以更新通道配置了。

二、準備CLI環境

首先進入CLI容器,這個容器是執行BYFN啟動的,可獲取2個peer組織和orderer組織的MSP資料,可由org1 admin使用者引導。命令如下:

docker exec -it cli bash

Export the ORDERER_CA and CHANNEL_NAME variables:

export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem  && export CHANNEL_NAME=mychannel

檢查確認變更配置是否正確:

echo $ORDERER_CA && echo $CHANNEL_NAME

需要注意的是如果重啟CLI容器,你必須要重複上面的命令。

三、獲取配置

現在我們有了2個關鍵環境變數的CLI容器: ORDERER_CA和CHANNEL_NAME。接下來要從mychannel通道獲取最近的配置區塊。

為什麼要拉取最新版本的配置檔案呢?這是因為通道配置元素是版本化的。版本化的原因有幾個,可以防止配置更改,另外還可以確保一致性。(例如當新組織加入到通道後,如果你想將一個組織從通道中移出,版本化可以防止你將這兩個組織同時移出),命令如下所述:

peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA

 將二進位制通道配置塊寫入到config_block.pb檔案中 ,檔名及字尾有助於識別檔案型別。

以上命令列執行結果如下:

2017-11-07 17:17:57.383 UTC [channelCmd] readBlock -> DEBU 011 Received block: 2

這句話告訴我們最近mychannel配置塊是block 2而不是創世紀塊。因此塊序列如下描述:

  • block 0: genesis block

  • block 1: Org1 anchor peer update

  • block 2: Org2 anchor peer update

四、轉換格式(由pb轉為JSON並進行裁減)

現在要用configtxlator工具解碼通道配置塊至JSON格式。同時將頭、元資料、建立者簽名無關修改的資訊去掉,這可以用jq工具來完成,命令如下:

configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config > config.json

生成config.json檔案,位於/fabric-samples/first-network/目錄下。

五、新增Org3加密資料

我們將用jq工具把Org3配置定義(org3.json)追加到通道應用組域中並命名為 modified_config.json。命令如下:

jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' config.json ./channel-artifacts/org3.json > modified_config.json

現在CLI容器有2個JSON檔案:config.json和modified_config.json。第一個檔案只包含 Org1和Org2資料,而 “modified”檔案則包含3個Org。先把config.json轉換成 config.pb檔案,命令如下:

configtxlator proto_encode --input config.json --type common.Config --output config.pb

接著將modified_config.json檔案編碼轉成modified_config.pb檔案。命令如下:

configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb

使用configtxlator工具計算兩pb檔案的delta。命令如下並輸出org3_update.pb檔案:

configtxlator compute_update --channel_id $CHANNEL_NAME --original config.pb --updated modified_config.pb --output org3_update.pb

org3_update.pb檔案包含Org3定義和指向Org1和Org2資料的連結。我們現在可以放棄org1和org2的擴充套件MSP資料和修改策略。因為這個資料已在通道創世紀塊中了。我們只需要兩個配置之間的差異了。

在提交通道更新之前,我們需要執行最後幾步。前行解碼org3_update.pb轉成JSON格式org3_update.json。命令如下:

configtxlator proto_decode --input org3_update.pb --type common.ConfigUpdate | jq . > org3_update.json

org3_update.json檔案再進行封裝,加入早先去掉的頭域等資訊。最終生成檔案:org3_update_in_envelope.json,命令列如下:

echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":'$(cat org3_update.json)'}}}' | jq . > org3_update_in_envelope.json

再利用configtxlator工具將org3_update_in_envelope.json轉成org3_update_in_envelope.pb檔案,命令列如下:

configtxlator proto_encode --input org3_update_in_envelope.json --type common.Envelope --output org3_update_in_envelope.pb

六、簽署和提交配置更新

org3_update_in_envelope.pb檔案是在CLI容器中的。在寫入到賬本之前還需要Admin簽名。通道應用組修改策略設定為預設  “MAJORITY”表示需要存在的組管理員主體簽名。此處則為Org1和Org2都要簽名。否則ordering伺服器將拒絕交易。 

第一步由Org1 Admin簽名,CLI容器是基於Org1 MSP資料啟動的,可直接在CLI中使用signconfigtx工具,命令如下:

peer channel signconfigtx -f org3_update_in_envelope.pb

第二步切換到Org2 Admin身份,通過輸出四個環境變數來實現,命令如下:

export CORE_PEER_LOCALMSPID="Org2MSP"

export 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

export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp

export CORE_PEER_ADDRESS=peer0.org2.example.com:7051

同樣也要執行如下命令:

peer channel signconfigtx -f org3_update_in_envelope.pb

注意:向orderering伺服器申請的即將更新呼叫將會經歷一系列簽名、策略檢驗等動作,可以通過如下命令來觀察:

docker logs -f orderer.example.com

現在可以傳送更新命令:

peer channel update -f org3_update_in_envelope.pb -c $CHANNEL_NAME -o orderer.example.com:7050 --tls --cafile $ORDERER_CA

出現以下顯示錶明更新成功:

2018-02-24 18:56:33.499 UTC [msp/identity] Sign -> DEBU 00f Sign: digest: 3207B24E40DE2FAB87A2E42BC004FEAA1E6FDCA42977CB78C64F05A88E556ABA

你也會看到配置交易的提交:

2018-02-24 18:56:33.499 UTC [channelCmd] update -> INFO 010 Successfully submitted channel update

通道更新成功會返回新的區塊block 5,並通知到通道中的每個peer節點。blocks 0-2是初始通道配置,blocks 3和4是鏈碼的初始化與呼叫,block 5則是包含org3的通道配置交易。

可以登入到peer0.org1.example.com檢視日誌:

docker logs -f peer0.org1.example.com

如果想檢查內容,則按演示過程提取、解碼新的配置區塊。

七、配置選擇策略

注意:

這部分主要描述當完成通道配置初始化後,當加入新的組織時選擇策略的設定問題。這個例子預設針對的是動態策略,該策略是對網路中所有的peer節點,內容在peer-base.yaml檔案中。 

最新加入的peer節點是基於創世紀塊啟動的,它不包含通新組織加入後的道配置更新資訊。所以新的peer節點不能利用gossip協議,正如它們也不能驗證來自於同組織提交的塊,除非它們獲得已將組織加入到通道的配置交易後。因此新加入的peer節點必須有下列的其中一個配置才能接收來自ordering伺服器的區塊:

1. 利用靜態選舉策略,將peer配置為一個組織的leader:

CORE_PEER_GOSSIP_USELEADERELECTION=false CORE_PEER_GOSSIP_ORGLEADER=true

注意這個配置對加入通道的所有新peer節點必須相同

2. 利用動態選舉策略,將peer節點配置為使用選舉策略:

CORE_PEER_GOSSIP_USELEADERELECTION=true CORE_PEER_GOSSIP_ORGLEADER=false

注意:

新加組織的peer節點不能構建成員檢視,這個選項類似於靜態配置,每個peer將自主宣告為leader。等到更新後這個組織只有一個啟用的leader。因此建議利用這一選項。

八、將Org3加入到通道

此時通道配置已更新到包含新組織Org3,這意味著該組織的peer節點可以加入到通道中去。

首先啟動Org3組織的CLI:Org3-specific CLI。命令如下:

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

這個新的組織檔案配置用來連線初始網路。2個peer節點1個CLI容器和已存在的peer節點及ordering節點能解決問題了。進入org3-cli容器,命令如下:

docker exec -it Org3cli bash

輸出2個重要環境變數:ORDERER_CA 和 CHANNEL_NAME:

export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem && export CHANNEL_NAME=mychannel

檢查確認變數已設定:

echo $ORDERER_CA && echo $CHANNEL_NAME

現在傳送請求給ordering伺服器獲取創世紀塊。 利用如下命令獲取返回塊: 

peer channel fetch 0 mychannel.block -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA

以上將0引數傳入表明獲取第一個區塊。如果沒有0則將獲得5個區塊。 然而我們以順流的方式開始我們的賬本,而只能從0區塊開始。通過以下命令讓peer加入到通道:

peer channel join -b mychannel.block

輸出TLSADDRESS變數,將其它peer節點加入到通道: 

export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer1.org3.example.com/tls/ca.crt && export CORE_PEER_ADDRESS=peer1.org3.example.com:7051

peer channel join -b mychannel.block

九、升級並呼叫鏈碼

最後的任務是升級鏈碼版本和更新包括org3的背書策略。

 在Org3 CLI容器進行如下操作:

peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/

修改環境變數重複以上命令將org3的第二個peer節點裝上鍊碼。第二個不是必須的。你只需要將負責背書或與賬本有介面的peer節點裝上鍊碼就可以了。 無需鏈碼容器,peer節點仍執行驗證邏輯並提交服務。

現在回到初始的CLI容器,在org1和org2上安裝新版本鏈碼。命令如下: 

peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/

切換到peer0.org1:

export CORE_PEER_LOCALMSPID="Org1MSP"

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

export CORE_PEER_ADDRESS=peer0.org1.example.com:7051

再次安裝 :

peer chaincode install -n mycc -v 2.0 -p github.com/chaincode/chaincode_example02/go/

鏈碼安裝完畢,現在要例項化,這一過程將org3包含到背書策略之中。執行如下命令:

peer chaincode upgrade -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 2.0 -c '{"Args":["init","a","90","b","210"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')"

升級呼叫新增block 6區塊至賬本。切回到Org3 CLI容器進行query查詢。 

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

結果為: Query Result: 90.

呼叫從a轉移b10支付過程:

peer chaincode invoke -o orderer.example.com:7050  --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}'

查詢

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

結果為:Query Result: 80

十、總結

通道配置更新過程是複雜的。但每一步都有其嚴格的邏輯, 最後的階段是構建protobuf二進位制的delta交易物件,獲取簽名,完成通道策略的修改。

configtxlatorjq、peer channel命令為我們完成任務提供了很好的幫助。