Hyperledger Fabric 建立一個簡單網絡


Building you first network

網絡結構:

2Orgnizations(每個Org包含2peer節點)+1solo ordering service

打開fabric-sample下的示例first-network

其中byfn.sh為啟動這個網絡的啟動腳本,啟動腳本中除建立一個包含4個節點和1Order service的網絡外,還會啟動一個容器用來執行腳本在channel中加入節點,部署和初始化chaincode,以及在部署的chaincode上執行交易。


啟動腳本

第一步,生成必要文件,執行命令:

 

 

 

 

 

 

默認channel名稱為mychannel

上述是否繼續選擇y,腳本程序會給網絡實例生成數字證書和密鑰;生成genesis block用來啟動ordering service;一些用來配置channel的配置交易

1、生成數字證書和密鑰

2、生成genesis block

3、生成channel配置交易

4、生成anchor peer update for Org1MSP

5、生成anchor peer update for Org2MSP

執行上述命令后,查看證書目錄:

2、第二步,啟動網絡,執行命令./byfn.sh -m up

上圖顯示在一個節點上安裝chaincode所配置的環境變量,其中配置了節點所擁有的證書信息。

執行結束后,終端顯示如下:

上述命令會啟動所有的containers

上面通過腳本./byfn.sh生成了一個fabric網絡,接下來詳細說明腳本中所執行的命令信息:

1Crypto Generator

cryptogen工具會對網絡節點生成證書信息,證書信息可以代表每一個實例節點,用於節點間通信和交易。

cryptogen使用的配置文件為crypto-config.yaml。配置文件中描述了網絡的拓撲結構同時會為OrgnizationsOrgnizations下的節點生成一系列的證書。每個Orgnization會有一個根證書ca-cert用來綁定特定節點(peer或者order)到該Orgnization。通過對每個Orgnization頒發一個唯一的數字證書,我們可以模仿典型的區塊鏈網絡,每個加入鏈的成員使用自己的數字證書進行獲取授權。交易和通信使用節點的私鈅,驗證使用節點的公鑰(數字證書)。配置文件里的count參數用來指定每個Orgnization的節點數量,本例子中一個Orgnization下面包含兩個節點,所以count的值在本例中設定為2

在運行這個命令之前,我們快速的看一下crypto-config.yaml里的配置信息。特別關注OrderOrgs header下的Name,DomainSpecs幾個參數。

使用命令:

sed 's/^[ ]*#.*$//g' crypto-config.yaml > crypt.yaml

sed -i '/^$/d' crypt.yaml

去掉配置文件中的注釋部分如下:

網絡節點的命名規則為{Hostname}.{Domain}。以上述配置文件中order節點為例,order節點的命名為orderer.example.com,對應的MSP IdOrderer

運行cryptogen命令后,生成的數字證書和密鑰信息保存在crypto-config文件夾中。


Configuration Transaction Generation

配置交易生成工具:configtxgen 用來生成4個配置信息

orderer genesis block

fabric channel configuration transaction

2anchor peer transaction (每個Peer Org生成一個)

orderer blockordering service的起始blockchannel配置交易文件在channel創建時廣播到ordereranchor peer交易用來指定channel上每個OrgAnchor Peer

configxgen的配置文件為configtx.yaml,其中包含對我們所創建的示例網絡的定義。配置文件包含3個角色,一個Orderer OrgOrderOrg)和兩個Peer OrgsOrg1Org2)。配置文件也指定了一個組合SampleConsortium,包含2Peer Org。打開配置文件,配置文件頂部Profiles部分有兩個唯一的headers。其中TwoOrgsOrderedGenesis用來配置orderer genesis blockTwoOrgChannel用來配置我們的channel

上述配置文件中還包含兩個沒有特別意義的指定信息。第一個,我們為每一個Peer Org指定了Anchor Peerpeer0.org1.example.compeer0.org2.example.com)。第二點,我們指定了每個角色的MSP路徑,從而允許我們把每個Org的根證書存儲在orderer genesis block中。這是一個重要的概念。現在每個節點和ordering service通信都需要驗證通過他們的數字證書。


運行cryptogenconfigtxgen命令

可以手動運行上述兩個命令生成數字證書/密鑰或者生成配置交易。也可以通過修改腳本byfn.sh腳本實現上述目標。


手動生成證書和配置交易

可以參考byfn.sh腳本中的generateCerts函數理解生成網絡配置中數字證書的命令。為了便利,這里我們也提供了一種參考方法。

首先運行cryptogen工具。cryptogen命令在first network子目錄的bin目錄下,下面運行命令使用了該命令所在位置的相對路徑。

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

也許你會遇到提示如下警告,直接忽略就可以

[bccsp] GetDefault -> WARN 001 Before using BCCSP, please call InitFactories(). Falling back to bootBCCSP.
接下來,我們需要告訴configtxgen工具引用哪里的配置文件configtx.yaml。這里我們通過設置環境變量來設定配置文件的路徑。
export FABRIC_CFG_PATH=$PWD
../bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block

你可以忽略掉關於intermediate certificates, certificate revocation lists (crls) and MSP configurations的警告信息,在本例中的網絡中,我們不會用到上述信息。

接下來,我們創建channel交易。確保替換$CHANNEL_NAME的值或者設置CHANNEL_NAME作為一個環境變量。創建命令如下:

export CHANNEL_NAME=mychannel

# this file contains the definitions for our sample channel
../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME

接下來,在我們創建的channel上定義Org1Anchor Peer節點。執行命令為:

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

channel上定義Org2Anchor Peer節點:

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


啟動網絡

我們引用一個docker-compose腳本啟動網絡,docker-compose文件引用了我們之前下載的鏡像文件同時根據之前生成的genesis.block引導orderer

working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
# command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT'
volumes
如果去掉注釋部分,網絡啟動時腳本會執行所有的CLI命令。這里我們手動的執行每一條命令,以便於我們了解命令的語法和功能。
TIMEOUT參數傳遞一個相對較大的值(單位為秒);否則CLI容器默認會在60s后退出。
啟動網絡:
CHANNEL_NAME=$CHANNEL_NAME 
TIMEOUT=<pick_a_value> 
docker-compose -f docker-compose-cli.yaml up -d
如果你想實時查看執行上述命令的日志信息,那么去掉上面的-d選項(后台運行)。如果打開了上述日志流,那么你需要另外再打開一個終端用來執行CLI命令。
環境變量
為了在peer0.org1.example.com上執行下面的CLI命令,需要先配置下面4個環境變量。peer0.org1.example.com的這些變量我們已經在CLI容器中配置了,因此我們可以不用傳遞這些環境變量的值了。但是,如果你想發送命令到其他peer或者orderer,你需要提供這些變量相應的值。檢查docker-compose-base.yaml查看那指定的路徑。
# Environment variables for PEER0

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
創建和加入channel
執行docker exec命令進入CLI容器
docker exec -it cli bash
成功執行后,出現如下提示:
root@0d78bb69300d:/opt/gopath/src/github.com/hyperledger/fabric/peer#
之前,我們使用configtxgen工具生成了配置交易channel.tx。我們將會傳遞這個交易到orderer作為創建channel請求的一部分。
注意:--cafile選項是orderer的根證書存放在本地的路徑,該信息可以用來驗證TLS握手過程。
我們使用-c選項指定channel的名字,使用-f選項指定配置交易。在本例中為channel.tx,你也可以mount配置交易為一個不同的名字。(配置交易通過本地路徑mount到容器中)
export CHANNEL_NAME=mychannel

# the channel.tx file is mounted in the channel-artifacts directory within your CLI container
# as a result, we pass the full path for the file
# we also pass the path for the orderer ca-cert in order to verify the TLS handshake
# be sure to replace the $CHANNEL_NAME variable appropriately

peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -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
這條命令返回一個genesis block <channel-ID.block>。該block可以用來加入channel時使用,block中包含了channel.tx中指定的配置信息。
你需要留在CLI容器中執行剩余的手動命令。如果發送命令的目標不是peer0.org1.example.com,那么要重新設置相應的環境變量。現在我們加入peer0.org1.example.comchannel
# By default, this joins ``peer0.org1.example.com`` only
# the <channel-ID>.block was returned by the previous command

 peer channel join -b <channel-ID.block>
你可以修改上邊4個環境變量的值為其他peer節點信息配置加入其他節點到channel中。
安裝和實例化chaincode
我們利用一個簡單的已寫好的chaincode。應用通過chaincode和區塊鏈的賬本進行交互,因此我們需要首先在每個peer節點上安裝chaincode用來執行交易和背書交易,然后在channel上實例化chaincode
首先安裝例子go代碼到4peer節點中的一個。這個命令會把go源碼放在peer節點的文件系統中。
peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
接下來,在channel上實例化chaincode。這將會在channel上初始化chaincode,為chaincode設置背書策略,為目標peer啟動一個chaincode容器。注意-P參數,這個參數指定了在該chaincode上一個交易被認可需要的背書級別。
接下來的命令中,我們設置-P參數為
-P "OR ('Org0MSP.member','Org1MSP.member')" 。這表示我們需要Org1或者Org2中一個peer節點的背書。如果改變語法為AND,那么就需要兩個背書。# be sure to replace the $CHANNEL_NAME environment variable
# if you did not install your chaincode with a name of mycc, then modify that argument as well

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')"
上述命令中的mycc為上文中peer上安裝的chaincode的名稱。
下面查詢a的值,確認chaincode被正確的實例化,stateDB正常的運行。查詢的語法如下:
# be sure to set the -C and -n flags appropriately

peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
現在從a轉移10b。這個交易會產生一個新的區塊並更新stateDB。調用的語法是:
# be sure to set the -C and -n flags appropriately

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"]}'
現在再次查詢,查看上述轉移10的命令是否已經成功執行,執行的命令是:
# be sure to set the -C and -n flags appropriately

peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
正常執行,會輸出如下提示:
Query Result: 90
下面描述docker-compose-cli.yaml文件中沒有注釋script.sh時的執行情況。去掉包含script.sh腳本執行的注釋,然后使用docker-compose命令再次啟動網絡。
1Script.sh腳本在CLI容器里已經備份過,腳本執行createChannel命令根據設定的channel名字,使用channel.tx文件作為channel配置交易。
2createChannel執行的輸出是一個genesis block-<your channel name>.block。輸出存儲在peer節點的文件系統上包含了channel.tx所指定的channel配置信息。
3joinChannel命令被執行(4peer節點),joinChannel命令使用上文生成的genesis block作為參數,該命令引導peer節點加入到<your channel name>並且建立一個以<your channel name>.block為起始的鏈。
4、目前我們建立了一個包含4個節點的channel,channel包含兩個orgnizations。類似TwoOrgsChannel文件的配置。
5peer0.org1.example.compeer1.org1.example.com屬於Org1peer0.org2.example.compeer1.org2.example.com屬於Org2
6、這些關系在crypto-config.yaml里定義,MSP的路徑在docker compose中指定
7Org1MSPAnchor Peer(peer0.org1.example.com)Org2MSPAnchor peerpeer0.org2.example.com)被更新。我們通過傳遞Org1MSPanchor.txOrg2MSPanchor.tx以及channel的名字到ordering service來實現這一步。
8、將編寫好的chaincode_example02安裝在peer0.org1.example.compeer0.org2.example.com上(這里並沒有安裝在所有peer上,而是僅安裝在anchor peer節點上,anchor peer節點之前每個Org設置了一個)
9chaincodepeer0.org2.example.com上實例化。實例化過程添加chaincodechannel中,為目標peer啟動容器,同時初始化與chaincode相關的key-value鍵值對。本例中初始化的值為[“a”,”100” “b”,”200”]。實例化后會啟動一個容器dev-peer0.org2.example.com-mycc-1.0。(實例化過程發送至peer0.org2.example.com上執行
10、實例化過程也傳遞了一個背書策略的參數。背書策略類似形式:-P "OR    ('Org1MSP.member','Org2MSP.member')",代表任何交易必須被Org1Org2的一個peer背書。
11、在peer0.org1.example.com上執行查詢a的值。chaincode之前已經安裝在peer0.org1.example.com上了,因此查詢操作會為Org1peer0節點啟動一個容器dev-peer0.org1.example.com-mycc-1.0。查詢結果也會返回回來,這個過程中沒有任何寫操作發生,所以a的值還是100
12、發送一個轉移賬戶金額的調用到peer0.org1.example.com,從a賬戶轉移10單位至b賬戶
13chaincode然后安裝在peer1.org2.example.com
14、發送查詢a賬戶操作至peer1.org2.example.com。這將啟動第三個chaincode容器dev-peer1.org2.example.com-mycc-1.0。返回金額90,說明之前帳號金額的轉移操作成功執行。
這說明了什么
為了在賬本上成功的執行讀寫操作,chaincode必須安裝在peer上。另外,chaincode容器直到實例化或者傳統交易-讀寫執行的時候(例:查詢a賬戶的值),chaincode容器才會啟動。channel中的每個節點都維護了賬本的完全復制,存儲了不可改變的、序列化的記錄區塊以及state database用於保存當前的fabric狀態。即便是那些沒有安裝chaincode的節點(例如peer1.org1.example.com)也會同步賬本。最終chaincode在安裝到peer1.org1.example.com后就可以被調用了,因為chaincode已經完成了實例化。
怎樣查看交易信息
查看CLI docker容器的日志信息
docker logs -f cli
可以看到交易的詳細過程
怎樣查看chaincode的日志
在每個chaincode container上可以查看當前container里所執行過的交易。具體查看命令如下:
docker logs dev-peer0.org2.example.com-mycc-1.0
docker logs dev-peer0.org1.example.com-mycc-1.0
docker logs dev-peer1.org2.example.com-mycc-1.0
理解docker-compose拓撲結構
BYFN例子提供了兩種docker-compose文件配置,每一種都是由docker-compose-base.yaml(文件存放在base文件夾中)文件拓展而來。第一個配置文件是docker-compose-cli.yaml,該配置文件配置了一個CLI容器,一個orderer4peer節點。使用該配置文件啟動可以實現本文中的所有操作指令。第二種配置文件docker-compose-e2e.yaml是配置啟動一個使用Node.js SDK的點對點測試。這個配置文件的主要區別是包含了fabric-ca-servers容器。因此,我們可以使用REST接口實現向CA組織注冊和登記用戶。
如果你想使用docker-compose-e2e.yaml並且不先運行byfn.sh腳本,那么我們需要做4個微改動。我們需要設定Organization CA的私鈅。你可以設定這些值為你的crypto-config文件夾。例如設置Org1的私鈅路徑為:crypto-config/peerOrganizations/org1.example.com/ca/。私鈅文件是一個長hash值加上_sk組成。設定Org2的私鈅為crypto-config/peerOrganizations/org2.example.com/ca/
另外2出改動是修改docker-compose-e2e.yamlca0ca1配置中的FABRIC_CA_SERVER_TLS_KEYFILE變量對應的值。需要指定tls證書所在的路徑。
按照一個簡單區塊鏈網絡的生成過程,制作執行過程如下:

執行步驟

執行命令和前置條件

生成必要信息

1、網路節點的證書文件

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

2、生成gensis block

export FABRIC_CFG_PATH=$PWD
../bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block

3、生成channel.tx

../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME

4、生成anchor peer

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

創建channel

peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx

創建channel的命令由peer節點發起,使用上文生成的channel.tx,上述命令生成<channel_name>.block在當前文件夾中,該block中保存了channel.tx的信息。節點加入channel后,該區塊作為節點區塊鏈的第一個區塊。

加入peer節點到channel

peer channel join -b $CHANNEL_NAME.block

peer加入channel時使用創建channel時生成的block文件

加入哪個peer節點到channel中,需要通過在CLI容器中設置如下環境變量指定:

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

設置上述環境變量,加入peer0節點到channel

更新Anchor peer

peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx

使用configtxgen生成的anchor.tx文件

安裝chaincode

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

CLI容器中設置環境變量指定在哪個peer節點上安裝chaincode

channel上實例化chaincode

peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"

需要設定環境變量指定在哪個peer節點上執行實例化chaincode命令

執行chaincode調用





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM