本章咱們從
fabric v1.0
的e2e_cli
示例開始分析整個啓動過程以及在過程當中的一些配置文件html
首先呢,仍是確保你的基本環境已經搭建完成,v1.0源碼和鏡像也都下載完畢git
在源碼目錄下的network_setup.sh
文件是官方提供的快速部署測試的一個自動化腳本,接下來咱們看一下在啓動這個文件時都作了什麼:
在上圖中咱們只是截取了啓動函數,在這個函數中能夠清楚的看出在啓動中調用了generateArtifacts.sh
和docker-compose-cli.yaml
兩個文件,這兩個文件的做用分別是:github
generateArtifacts.sh:生成所需的證書(crypto-config文件夾)和通道相關的配置文件(channel-artifacts文件夾) docker-compose-cli.yaml:描述的是這個示例網絡的拓撲結構
咱們繼續分析在network_setup.sh
中調用generateArtifacts.sh
文件具體又作了什麼呢
在generateArtifacts.sh
中一共有3個函數:replacePrivateKey()
、generateCerts()
和generateChannelArtifacts()
generateCerts():
在上圖中能夠看到這個函數使用工具cryptogen和crypto-config.yaml
文件來生成所需的證書文件和公私鑰。
咱們能夠看一下crypto-config.yaml
文件:
Name和Domain是指該org的名字和域名,Template.Count是指該org中的節點數量,Users.Count是指該org中包含的user數量.docker
OrdererOrgs: - Name: Orderer Domain: example.com Specs: - Hostname: orderer # --------------------------------------------------------------------------- PeerOrgs: - Name: Org1 Domain: org1.example.com Template: Count: 2 Users: Count: 1 # --------------------------------------------------------------------------- - Name: Org2 Domain: org2.example.com Template: Count: 2 Users: Count: 1
generateChannelArtifacts():
在上圖中能夠看到這個函數使用工具configtxgen和configtx.yaml文件來生成創世區塊以及通道相關的配置文件。而configtx.yaml文件裏主要是一些org的配置項信息,如ID、Host、Port等,除此以外還指明瞭orderer的共識方式爲solo等一些的基礎的配置項信息。bash
docker-compose-cli.yaml
文件描述了這個示例網絡的拓撲結構,以下,包含:網絡
#command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT'
文件中上面這一行是筆者故意註釋掉的,使docker-compose-cli.yaml
文件啓動時不會自動去執行script.sh
腳本,而這個腳本就是自動建立、加入通道以及鏈碼相關操做的自動化腳本,而在下面,咱們將本身動手來一步步完成這些步驟,從而加深對fabric啓動過程的理解。函數
version: '2' services: orderer.example.com: extends: file: base/docker-compose-base.yaml service: orderer.example.com container_name: orderer.example.com peer0.org1.example.com: container_name: peer0.org1.example.com extends: file: base/docker-compose-base.yaml service: peer0.org1.example.com peer1.org1.example.com: container_name: peer1.org1.example.com extends: file: base/docker-compose-base.yaml service: peer1.org1.example.com peer0.org2.example.com: container_name: peer0.org2.example.com extends: file: base/docker-compose-base.yaml service: peer0.org2.example.com peer1.org2.example.com: container_name: peer1.org2.example.com extends: file: base/docker-compose-base.yaml service: peer1.org2.example.com cli: container_name: cli image: hyperledger/fabric-tools tty: true environment: - GOPATH=/opt/gopath - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - CORE_LOGGING_LEVEL=DEBUG - CORE_PEER_ID=cli - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 - CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_TLS_ENABLED=true - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key - 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 working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer #command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT' volumes: - /var/run/:/host/var/run/ - ../chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/ - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts depends_on: - orderer.example.com - peer0.org1.example.com - peer1.org1.example.com - peer0.org2.example.com - peer1.org2.example.com
接下來咱們將實際動手啓動一下官方提供的示例:工具
首先咱們進入下載的fabric源碼目錄/root/go/src/github.com/hyperledger/fabric
,執行make cryptogen
命令,生成cryptogen
可執行程序,若有報錯,則在文章最後一部分有筆者本身遇到的錯誤,可自行查看;
接下來進入cd examples/e2e_cli/
目錄執行../../build/bin/cryptogen generate --config=./crypto-config.yaml
,則會在本目錄下生成crypto-config
文件夾,存放生成公私鑰和證書。
測試
返回到fabric
目錄,執行make configtxgen
命令,生成configtxgen
可執行程序
接下來仍是進入cd examples/e2e_cli/
目錄
生成創世區塊:ui
../../build/bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
生成通道相關的配置文件:
../../build/bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel
生成org1和org2錨節點所需的配置文件:
../../build/bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP ../../build/bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP
執行完上述命令後,再執行tree channel-artifacts/
(需安裝tree命令yum install tree
),能夠看見以下圖生成的文件的目錄結構:
啓動所需的一切都準備完畢,接下來咱們啓動fabric網絡
docker-compose -f docker-compose-cli.yaml up
另起一個終端,執行docker ps
,能夠看到以下圖,啓動了1個orderer,4個peer(分屬2個org),1個cli
進入cli容器:docker exec -it cli bash
爲了方便接下來咱們的操做,先設置一些環境變量:
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
建立通道:
peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls true --cafile $ORDERER_CA
執行完該命令後系統會打印出下圖,而且會在cli中生成1個mychannel.block
文件,在後續中,其餘的節點想要加入咱們建立的這個通道,就必須使用這個文件。
docker-compose-cli.yaml
文件中其實指明瞭啓動時就默認鏈接的是org1.peer0
節點,因此直接將其加入通道便可peer channel join -b $CHANNEL_NAME.block
執行結果以下:
org1.peer0
節點加入了mychannel
這個通道,一樣咱們再將org1.peer1
節點也加入通道,不過這裏就須要修改環境變量,使其指向咱們須要加入通道的節點後,再將節點加入通道。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/Admin\@org1.example.com/msp export CORE_PEER_ADDRESS=peer1.org1.example.com:7051 peer channel join -b $CHANNEL_NAME.block
執行結果以下:
org2.peer0
節點加入通道: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/Admin\@org2.example.com/msp export CORE_PEER_ADDRESS=peer0.org2.example.com:7051 peer channel join -b $CHANNEL_NAME.block
執行結果以下:
org2.peer1
節點加入通道: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/Admin\@org2.example.com/msp export CORE_PEER_ADDRESS=peer1.org2.example.com:7051 peer channel join -b $CHANNEL_NAME.block
執行結果以下:
錨節點的做用是爲了方便組織(org)之間的通訊,1個組織(org)能夠擁有1個或多個錨節點負責與其餘組織進行通訊,而後將結果同步到其餘節點。
更新org1
的錨節點org1.peer0
,首先鏈接到org1.peer0
再執行更新
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/Admin\@org1.example.com/msp export CORE_PEER_ADDRESS=peer0.org1.example.com:7051 peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org1MSPanchors.tx --tls true --cafile $ORDERER_CA
更新org2
的錨節點org2.peer0
,首先鏈接到org2.peer0
再執行更新
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/Admin\@org2.example.com/msp export CORE_PEER_ADDRESS=peer0.org2.example.com:7051 peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org2MSPanchors.tx --tls true --cafile $ORDERER_CA
在上上一步中咱們已經將org1和org2的一共4個peer都加入名爲mychannel
的這個通道,接下來咱們開始安裝鏈碼,此時咱們在上一步命令執行結束後仍鏈接的是org2.pee1
節點,由於鏈碼安裝時並無產生交易,所以是不會影響通道內的其餘節點,能夠說鏈碼安裝實際上是一個本地化操做,因此,若是咱們想在不一樣的節點中調用鏈碼的話,就須要安裝4次鏈碼(由於咱們目前只有4個節點)
peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
執行結果以下:
peer chaincode instantiate -o orderer.example.com:7050 --tls true --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 query -C $CHANNEL_NAME -n mycc -c '{"Args":["query", "a"]}'
執行結果以下:
接下來咱們調用鏈碼使a給b轉帳50元
peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke", "a","b","50"]}'
執行結果以下:
如今咱們須要在另外1個節點org1.peer0
上查詢org2.peer1
節點上發生的交易是否成功
須要先鏈接到org1.peer0
上,須要再一次安裝鏈碼,但不須要實例化
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/Admin\@org1.example.com/msp export CORE_PEER_ADDRESS=peer0.org1.example.com:7051 peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
再一次安裝完鏈碼後咱們調用鏈碼查詢a的餘額
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query", "a"]}'
執行結果以下:
最後咱們查看正在運行中的容器,能夠看到以下:
make cryptogen
命令若有報錯yum install libtool-ltdl-devel
最後呢,說明一下,做者也是剛入坑的小白,這篇文章也就是分享一下我的的理解,方便之後查看。若是對你有幫助的話,很是榮幸,若是有不對的地方,歡迎留言指正!