多個主機上的Hyperledger Fabric
Hyperledger Fabric是由Linux Foundation託管的業務區塊鏈專案。它是一個“分散式總賬解決方案平臺,以模組化架構為基礎,提供高度機密性,彈性好,靈活性和可擴充套件性。它旨在支援不同元件的可插拔實現,並適應整個經濟生態系統中存在的複雜性和複雜性。“
我開始研究這項技術,作為探索區塊鏈解決方案的PoC的一部分。Hyperledger Fabric有很好的文件,並有詳細的入門教程。但是,它錯過了分散式系統實現(在多個主機上部署)的最重要指南,這是分散式系統的本質。
是的,沒有教程或指南可以幫助你跨多個主機部署網路。許多人在同一問題上圍繞不同的論壇掙扎。我決定首先研究現有的樣本,以瞭解超級分類網路的不同元件如何能夠在單個主機上進行通訊。
先決條件
本教程要求你首先從Hyperledger教程中關注Build You First Network。這是瞭解它如何連線並在單一主機模式下工作的重要步驟。此外,它還安裝了對本教程非常重要的所有必要的先決條件和依賴項。
如果你想跳過上述教程並想要嘗試這一點,則必須安裝以下所述的所有先決條件:
在我們開始之前,如果你還沒有這樣做,你可能希望檢查你是否已在將要開發區塊鏈應用程式和/或執行Hyperledger Fabric的平臺上安裝了所有先決條件。
你還需要下載並安裝Hyperledger Fabric Samples。你會注意到fabric-samples儲存庫中包含了許多樣本。我們將使用第一個網路樣本。我們現在開啟那個子目錄。
在安裝了上述先決條件之後,在繼續之前,讓我們瞭解網路如何在單個主機上執行…
它如何在單個主機上執行…
Hyperledger Fabric依賴於基於docker的架構,超級分類網路的所有元件都在單獨的容器中執行,而不能看到相鄰的容器。為了使它們彼此通訊,它們建立了一個網路,每個容器都附加到它上面。你可以在 fabric-samples repo 中“First Network”下的 docker-compose-cli.yml 中找到它。你會發現在 docker-compse-cli.yml 檔案的開頭,建立了網路 byfn
,然後所有容器都將自己附加到剛剛建立的網路上。
預設情況下,Compose為你的應用設定單個網路。服務的每個容器都加入預設網路,並且該網路上的其他容器都可以訪問它們,並且它們可以在與容器名稱相同的主機名上發現。
它將如何適用於多主機…
但是當我們跨多個主機工作時,容器無法相互通訊。簡而言之,我們需要找到一種方法來跨多個主機(PC)共享此網路(所有容器連線到的網路)。我猜測它可以通過使用docker swarm來實現。我找到了:
覆蓋網路驅動程式在多個Docker守護程式主機之間建立分散式網路。該網路位於(覆蓋)頂部,特定於主機的網路允許連線到它的容器(包括群服務容器)安全地通訊。Docker透明地處理每個資料包與正確的Docker守護程式主機和正確的目標容器的路由。然後我的著眼點落在 這裡 。
我開始合併這些碎片並經過一些反覆試驗,我能夠把它拉下來。要做到這一點,你需要
manager
由於這是一個分散式系統,因此你需要多個主機(在我們的示例中為兩臺計算機)來驗證該技術的分散式特性。假設你有兩臺PC,即PC1和PC2。
本教程僅適用於Linux,為什麼?
目前,你無法單獨使用Docker for Mac或Docker for Windows來測試多節點群。
網路拓撲結構
因此,我們要構建的網路將具有以下元件。對於這個例子,我們使用兩臺PC(PC1和PC2):
-
- 證書頒發機構(CA)—— PC1
-
- Orderer —— PC1
-
- 1 PEER(peer0)on —— PC1
-
- 1 PEER(peer1)on —— PC2
-
- CLI on —— PC2
在拓撲圖裡:
在你開始之前
- 初始化一個群:( docker swarm文件獲取更多資訊)
$ docker swarm init
- 加入swarm與其他主機作為經理(PC1將建立swarm,PC2將加入它)
PC1:
$ docker swarm join-token manager
它會輸出這樣的內容:
docker swarm join — token SWMTKN-1–3as8cvf3yxk8e7zj98954jhjza3w75mngmxh543llgpo0c8k7z-61zyibtaqjjimkqj8p6t9lwgu 172.16.0.153:2377
我們將複製它(終端上的那個,而不是上面的那個)並在PC2終端上執行它以使其加入PC1
在PC2上使用上一個命令的輸出命令
- 建立一個網路(在我的情況下為
my-net
)——PC1
$ docker network create --attachable --driver overlay my-net
- 在兩臺PC上克隆這個repo,即PC1和PC2。
$ git clone https://github.com/wahabjawed/Build-Multi-Host-Network-Hyperledger.git
- 生成網路工件(加密資源)——PC1
$ cd Build-Multi-Host-Network-Hyperledger/ $ ./bmhn.sh
這將在 crypto-config
和 channel-artifacts
資料夾中為你生成網路工件。你必須在PC2上覆制這些資料夾,以便兩個專案都具有相同的加密資源。重要的是,兩臺PC必須具有相同的加密資源,否則網路將無法通訊。
設定網路
在PC1上:
以下指令碼將在PC1上執行。在單獨的終端中執行每個命令。
在執行任何指令碼之前,還要確保你處於 Build-Multi-Host-Network-Hyperledger/
資料夾中。指令碼使用 Build-Multi-Host-Network-Hyperledger
資料夾中的檔案,如果無法找到它,則會丟擲錯誤。
1.CA伺服器:
你將在PC1上執行此命令。在執行此操作之前,將 {put the secret of secret key}
替換為金鑰的名稱。你可以在 /crypto-config/peerOrganizations/org1.example.com/ca/
下找到它。
docker run --rm -it --network="my-net" --name ca.example.com -p 7054:7054 -e FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server -e FABRIC_CA_SERVER_CA_NAME=ca.example.com -e FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem -e FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/{put the name of secret key} -v $(pwd)/crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config -e CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=hyp-net hyperledger/fabric-ca sh -c 'fabric-ca-server start -b admin:adminpw -d'
2.Orderer
執行此命令以在PC1上生成Orderer:
docker run --rm -it --network="my-net" --name orderer.example.com -p 7050:7050 -e ORDERER_GENERAL_LOGLEVEL=debug -e ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 -e ORDERER_GENERAL_LISTENPORT=7050 -e ORDERER_GENERAL_GENESISMETHOD=file -e ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block -e ORDERER_GENERAL_LOCALMSPID=OrdererMSP -e ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp -e ORDERER_GENERAL_TLS_ENABLED=false -e CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=my-net -v $(pwd)/channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block -v $(pwd)/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp -w /opt/gopath/src/github.com/hyperledger/fabric hyperledger/fabric-orderer orderer
3.CouchDB 0 —— Peer 0
此命令將生成一個couchDB例項,peer0將使用該例項儲存對等分類帳。
docker run --rm -it --network="my-net" --name couchdb0 -p 5984:5984 -e COUCHDB_USER= -e COUCHDB_PASSWORD= -e CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=my-net hyperledger/fabric-couchdb
4.Peer 0
現在我們執行此命令來生成peer0
docker run --rm -it --link orderer.example.com:orderer.example.com --network="my-net" --name peer0.org1.example.com -p 8051:7051 -p 8053:7053 -e CORE_LEDGER_STATE_STATEDATABASE=CouchDB -e CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0:5984 -e CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME= -e CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD= -e CORE_PEER_ADDRESSAUTODETECT=true -e CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock -e CORE_LOGGING_LEVEL=DEBUG -e CORE_PEER_NETWORKID=peer0.org1.example.com -e CORE_NEXT=true -e CORE_PEER_ENDORSER_ENABLED=true -e CORE_PEER_ID=peer0.org1.example.com -e CORE_PEER_PROFILE_ENABLED=true -e CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer.example.com:7050 -e CORE_PEER_GOSSIP_IGNORESECURITY=true -e CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=my-net -e CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051 -e CORE_PEER_TLS_ENABLED=false -e CORE_PEER_GOSSIP_USELEADERELECTION=false -e CORE_PEER_GOSSIP_ORGLEADER=true -e CORE_PEER_LOCALMSPID=Org1MSP -v /var/run/:/host/var/run/ -v $(pwd)/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp -w /opt/gopath/src/github.com/hyperledger/fabric/peer hyperledger/fabric-peer peer node start
在PC2上:
以下命令將在PC2上執行。
在執行任何指令碼之前,請確保你處於 Build-Multi-Host-Network-Hyperledger
資料夾中。指令碼使用 Build-Multi-Host-Network-Hyperledger
資料夾中的檔案,如果無法找到它,則會丟擲錯誤。
5.CouchDB 1 —— for Peer 1
此命令將生成一個couchDB例項,peer1將使用該例項儲存對等分類帳。 我們將在PC2上的一個單獨終端中執行此操作
docker run --rm -it --network="my-net" --name couchdb1 -p 6984:5984 -e COUCHDB_USER= -e COUCHDB_PASSWORD= -e CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=my-net hyperledger/fabric-couchdb
6.Peer 1
我們將在PC2上的一個單獨終端中執行此操作以生成peer1。
docker run --rm -it --network="my-net" --link orderer.example.com:orderer.example.com --link peer0.org1.example.com:peer0.org1.example.com --name peer1.org1.example.com -p 9051:7051 -p 9053:7053 -e CORE_LEDGER_STATE_STATEDATABASE=CouchDB -e CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb1:5984 -e CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME= -e CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD= -e CORE_PEER_ADDRESSAUTODETECT=true -e CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock -e CORE_LOGGING_LEVEL=DEBUG -e CORE_PEER_NETWORKID=peer1.org1.example.com -e CORE_NEXT=true -e CORE_PEER_ENDORSER_ENABLED=true -e CORE_PEER_ID=peer1.org1.example.com -e CORE_PEER_PROFILE_ENABLED=true -e CORE_PEER_COMMITTER_LEDGER_ORDERER=orderer.example.com:7050 -e CORE_PEER_GOSSIP_ORGLEADER=true -e CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.example.com:7051 -e CORE_PEER_GOSSIP_IGNORESECURITY=true -e CORE_PEER_LOCALMSPID=Org1MSP -e CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=my-net -e CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051 -e CORE_PEER_GOSSIP_USELEADERELECTION=false -e CORE_PEER_TLS_ENABLED=false -v /var/run/:/host/var/run/ -v $(pwd)/crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp:/etc/hyperledger/fabric/msp -w /opt/gopath/src/github.com/hyperledger/fabric/peer hyperledger/fabric-peer peer node start
7. CLI
在PC2上的不同終端中執行以下指令碼以生成CLI。
docker run --rm -it --network="my-net" --name cli --link orderer.example.com:orderer.example.com --link peer0.org1.example.com:peer0.org1.example.com --link peer1.org1.example.com:peer1.org1.example.com -p 12051:7051 -p 12053:7053 -e GOPATH=/opt/gopath -e CORE_PEER_LOCALMSPID=Org1MSP -e CORE_PEER_TLS_ENABLED=false -e CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock -e CORE_LOGGING_LEVEL=DEBUG -e CORE_PEER_ID=cli -e CORE_PEER_ADDRESS=peer0.org1.example.com:7051 -e CORE_PEER_NETWORKID=cli -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp -e CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=my-net-v /var/run/:/host/var/run/ -v $(pwd)/chaincode/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go -v $(pwd)/crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ -v $(pwd)/scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/ -v $(pwd)/channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts -w /opt/gopath/src/github.com/hyperledger/fabric/peer hyperledger/fabric-tools /bin/bash -c './scripts/script.sh'
如果你看到這一點,則表示該指令碼已被執行:
這將安裝CLI容器並將執行指令碼:
'./scripts/script.sh'
該指令碼將:
mychannel
現在我們的網路正在執行,讓我們測試一下。現在我們將從PC2呼叫和查詢兩個對等體上的區塊鏈程式碼。
我們開始做吧。
測試網路
Step 1. Bin/Bash CLI——PC2
我們將再次在PC2上生成cli容器,但這次我們將執行它:
docker run --rm -it --network="my-net" --name cli --link orderer.example.com:orderer.example.com --link peer0.org1.example.com:peer0.org1.example.com --link peer1.org1.example.com:peer1.org1.example.com -p 12051:7051 -p 12053:7053 -e GOPATH=/opt/gopath -e CORE_PEER_LOCALMSPID=Org1MSP -e CORE_PEER_TLS_ENABLED=false -e CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock -e CORE_LOGGING_LEVEL=DEBUG -e CORE_PEER_ID=cli -e CORE_PEER_ADDRESS=peer0.org1.example.com:7051 -e CORE_PEER_NETWORKID=cli -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp -e CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=my-net-v /var/run/:/host/var/run/ -v $(pwd)/chaincode/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go -v $(pwd)/crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ -v $(pwd)/scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/ -v $(pwd)/channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts -w /opt/gopath/src/github.com/hyperledger/fabric/peer hyperledger/fabric-tools /bin/bash
執行命令後必須看到這一點:
root@a14d67c2dbb5:/opt/gopath/src/github.com/hyperledger/fabric/peer#
現在你已進入CLI容器,我們將執行命令以例項化,呼叫和查詢此容器中的區塊鏈程式碼。
Step 2.在Peer0上例項化Chaincode
要在peer0上例項化鏈程式碼,我們需要先設定一些環境變數。將以下行貼上在cli終端中。
# Environment variables for PEER0 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp 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_ADDRESS=peer0.org1.example.com:7051
之後我們將初始化區塊鏈碼。執行以下命令以例項化作為步驟1的一部分安裝的區塊鏈程式碼。
$ peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n mycc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
這將例項化chiancode並用 a=100
和 b=200
填充它。
此時,隨著你的分類帳的填充,你可以檢視(在PC1上的瀏覽器上開啟它):
Peer0(PC 1): http://localhost:5984/_utils/#/database/mychannel/_all_docs
Peer1(PC 2): http://localhost:5984/_utils/#/database/mychannel/_all_docs
以上是couchDB Web介面端點。由於資料以二進位制形式儲存,因此你無法找到確切的值(而是會找到雜湊值),但會看到包含 myacc
的鍵的記錄。
OR
讓我們查詢它並檢視結果。我們將在peer1上查詢它。
Step 3.查詢Peer1上的Chaincode
要查詢peer1上的區塊鏈程式碼,我們首先需要設定一些環境變數。將以下行貼上在PC2上的cli終端中:
# Environment variables for PEER1 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp 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_ADDRESS=peer1.org1.example.com:7051
讓我們查詢 a
的值,以確保區塊鏈程式碼已正確例項化並且沙發資料庫已填充。查詢的語法如下:(在cli終端中執行)並等待一段時間:
$ peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
它會帶來:
Query Result: 100
Step 4.在Peer0上呼叫Chaincode
要在peer0上呼叫鏈程式碼,我們需要先設定一些環境變數。將以下行貼上在PC2上的cli終端中:
# Environment variables for PEER0 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp 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_ADDRESS=peer0.org1.example.com:7051
現在讓我們從 a
到 b
移動 10
。此交易將刪除一個新塊並更新couch資料庫。呼叫的語法如下:(在PC2上的cli終端中執行):
$ peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}'
Step 5.查詢Chaincode
讓我們確認我們之前的呼叫是否正確執行。我們使用值 100
初始化了鍵 a
,並在之前的呼叫中刪除了 10
。因此,對 a
的查詢應該顯示 90
。查詢的語法如下(我們在peer0上查詢所以不需要更改環境變數):
# be sure to set the -C and -n flags appropriately peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
我們應該看到以下內容:
Query Result: 90
隨意重新開始並操縱鍵值對和後續呼叫。
下一步是什麼…
在超級賬本結構教程上實現區塊鏈程式碼執行仍然處於開發模式,這就是為什麼我一直在使用HProxy來實現負載平衡區塊鏈程式碼執行以使其生產就緒。
此外,我一直在使用區塊鏈資源管理器來監控網路中不同的矩陣,即區塊,交易,吞吐量,活動節點等。
我會盡快釋出。
快樂區塊鏈:)
======================================================================
分享一些以太坊、EOS、比特幣等區塊鏈相關的互動式線上程式設計實戰教程:
- java以太坊開發教程,主要是針對java和android程式設計師進行區塊鏈以太坊開發的web3j詳解。
- php以太坊,主要是介紹使用php進行智慧合約開發互動,進行賬號建立、交易、轉賬、代幣開發以及過濾器和交易等內容。
- python以太坊,主要是針對python工程師使用web3.py進行區塊鏈以太坊開發的詳解。
- 以太坊入門教程,主要介紹智慧合約與dapp應用開發,適合入門。
- 以太坊開發進階教程,主要是介紹使用node.js、mongodb、區塊鏈、ipfs實現去中心化電商DApp實戰,適合進階。
- C#以太坊,主要講解如何使用C#開發基於.Net的以太坊應用,包括賬戶管理、狀態與交易、智慧合約開發與互動、過濾器和交易等。
- EOS教程,本課程幫助你快速入門EOS區塊鏈去中心化應用的開發,內容涵蓋EOS工具鏈、賬戶與錢包、發行代幣、智慧合約開發與部署、使用程式碼與智慧合約互動等核心知識點,最後綜合運用各知識點完成一個便籤DApp的開發。
- java比特幣開發教程,本課程面向初學者,內容即涵蓋比特幣的核心概念,例如區塊鏈儲存、去中心化共識機制、金鑰與指令碼、交易與UTXO等,同時也詳細講解如何在Java程式碼中整合比特幣支援功能,例如建立地址、管理錢包、構造裸交易等,是Java工程師不可多得的比特幣開發學習課程。
- php比特幣開發教程,本課程面向初學者,內容即涵蓋比特幣的核心概念,例如區塊鏈儲存、去中心化共識機制、金鑰與指令碼、交易與UTXO等,同時也詳細講解如何在Php程式碼中整合比特幣支援功能,例如建立地址、管理錢包、構造裸交易等,是Php工程師不可多得的比特幣開發學習課程。
- tendermint區塊鏈開發詳解 ,本課程適合希望使用tendermint進行區塊鏈開發的工程師,課程內容即包括tendermint應用開發模型中的核心概念,例如ABCI介面、默克爾樹、多版本狀態庫等,也包括代幣發行等豐富的實操程式碼,是go語言工程師快速入門區塊鏈開發的最佳選擇。
匯智網原創翻譯,轉載請標明出處。這裡是 多個主機上的Hyperledger Fabric