Hyberledger-Fabric 1.00 RPC學習(2)嘗試創建一個network

本文參考:http://hyperledger-fabric.readthedocs.io/en/latest/build_network.htmlhtml

這裏咱們學習創建第一個Hyperledger Fabric network,包括兩個organization(每一個包括2個peer節點),以及一個「solo」的ordering service。node

前提條件:安裝docker、docker compose、go環境、npm、node.js,下載並安裝好了Hyberledger Fabric Samples。git

安裝Hyberledger Fabric Samples簡介:github

  • 創建一個目錄
mkdir hyberledger-fabric
cd hyberledger-fabric
  • 克隆一個倉庫
git clone https://github.com/hyperledger/fabric-samples.git
  • 下載特定的二進制文件
curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap-1.0.0-rc1.sh | bash

上述命令會下載自動化部署腳本,同時也會下載平臺特定使用的二進制文件cryptogen,configtxgen,configtxlator, 以及peer,把他們放到上述倉庫的bin目錄下docker

 接下來把bin目錄加入到PATH環境變量中npm

vi /etc/profile

打開profile而後把下面語句添加進去便可bootstrap

  export PATH=/home/parallels/hyberledger-fabric/bin:$PATHbash

1.嘗試run first-network網絡

cd  fabric-samples/first-network

這裏提供了一個腳本,byfn.sh,咱們能夠查看其的使用方法app

若是你沒有指定channel的名稱,則該腳本則會使用默認的channel名稱(mychannel)

CLI的超時參數(-t flag)能夠選擇,若是不選擇,那麼CLI容器將在腳本結束後退出。

2.生成network artifacts

執行以下命令:

./byfn.sh -m generate

遇到須要選擇的地方選擇y,會看到以下日誌

這一步生成了network entity所須要的certificates以及keys,genesis block用於獲取用於配置channel的ordering service以及transaction配置的集合。

3.啓動network

接下來輸入如下命令啓動network,回覆y

./byfn.sh -m up

能夠看到以下輸出結果

./byfn.sh -m up
Starting with channel 'mychannel' and CLI timeout of '10000'
Continue (y/n)?y
proceeding ...
Creating network "net_byfn" with the default driver
Creating peer0.org1.example.com
Creating peer1.org1.example.com
Creating peer0.org2.example.com
Creating orderer.example.com
Creating peer1.org2.example.com
Creating cli


 ____    _____      _      ____    _____
/ ___|  |_   _|    / \    |  _ \  |_   _|
\___ \    | |     / _ \   | |_) |   | |
 ___) |   | |    / ___ \  |  _ <    | |
|____/    |_|   /_/   \_\ |_| \_\   |_|

Channel name : mychannel
Creating channel...

日誌從這裏開始,這將啓動全部的容器,造成這個完整的P2P的應用場景。

啓動成功後會打印以下日誌:

2017-05-16 17:08:01.366 UTC [msp] GetLocalMSP -> DEBU 004 Returning existing local MSP
2017-05-16 17:08:01.366 UTC [msp] GetDefaultSigningIdentity -> DEBU 005 Obtaining default signing identity
2017-05-16 17:08:01.366 UTC [msp/identity] Sign -> DEBU 006 Sign: plaintext: 0AB1070A6708031A0C08F1E3ECC80510...6D7963631A0A0A0571756572790A0161
2017-05-16 17:08:01.367 UTC [msp/identity] Sign -> DEBU 007 Sign: digest: E61DB37F4E8B0D32C9FE10E3936BA9B8CD278FAA1F3320B08712164248285C54
Query Result: 90
2017-05-16 17:08:15.158 UTC [main] main -> INFO 008 Exiting.....
===================== Query on PEER3 on channel 'mychannel' is successful =====================

===================== All GOOD, BYFN execution completed =====================


 _____   _   _   ____
| ____| | \ | | |  _ \
|  _|   |  \| | | | | |
| |___  | |\  | | |_| |
|_____| |_| \_| |____/

經過上述日誌可以看到不一樣的transaction。

4.關閉network

輸入以下命令

./byfn.sh -m down

可以看到輸出日誌以下:

./byfn.sh -m down
Stopping with channel 'mychannel' and CLI timeout of '10000'
Continue (y/n)?y
proceeding ...
WARNING: The CHANNEL_NAME variable is not set. Defaulting to a blank string.
WARNING: The TIMEOUT variable is not set. Defaulting to a blank string.
Removing network net_byfn
468aaa6201ed
...
Untagged: dev-peer1.org2.example.com-mycc-1.0:latest
Deleted: sha256:ed3230614e64e1c83e510c0c282e982d2b06d148b1c498bbdcc429e2b2531e91
...

若是您想了解有關底層工具和引導機制的更多信息,請繼續閱讀。 在接下來的章節中,咱們將介紹構建功能齊全的Hyperledger Fabric網絡的各類步驟和要求。

5.Crypto生成器

咱們使用crytogen工具給咱們不一樣的network entity生成加密證書(X509 certs)。這些證書表明了身份,當咱們的entity在進行通訊以及transact的時候進行簽名與驗證身份。

Cryptogen有一個配置文件crypto-config.yaml,包括了網絡拓撲,同時容許咱們給organization以及component(隸屬於organization)生成一個證書與私鑰的集合。每個organization被分配一個惟一的根證書(綁定了隸屬於Org的具體的component,包括peers與orderers)。經過給每一個organization分配一個惟一的CA證書,咱們正在模仿一個典型的網絡,參與的成員將使用本身的證書頒發機構頒發的證書。Hyperledger Fabric的transaction與通訊均被entity的私鑰(keystore)進行簽名,截止被公鑰進行驗證(signcerts)。

這個配置文件中有一個計數(count)的變量,咱們使用其定義organization中peer的數量,在本例中咱們定義每個Org有兩個peer。這裏不會深刻討論X.509證書以及公鑰框架。

在run這個工具以前,咱們回顧一下crypto-config.yaml,請注意在ordererOrgs頭下面的「Name」, 「Domain」 以及 「Specs」這三個參數。

OrdererOrgs:
#---------------------------------------------------------
# Orderer
# --------------------------------------------------------
- Name: Orderer
  Domain: example.com
  # ------------------------------------------------------
  # "Specs" - See PeerOrgs below for complete description
# -----------------------------------------------------
  Specs:
    - Hostname: orderer
# -------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ------------------------------------------------------
PeerOrgs:
# -----------------------------------------------------
# Org1
# ----------------------------------------------------
- Name: Org1
  Domain: org1.example.com

network entity的命名規則約定以下:「{{.Hostname}}.{{.Domain}}」。所以,使用咱們的ordering node做爲參考,咱們能看到一個名稱爲 - orderer.example.com的ordering node,該node與Orderer的MSP ID關聯。 您還能夠參考會員 Membership Service Providers (MSP)文檔,以便更深刻地瞭解MSP。

咱們運行cryptogen工具以後,生成的證書與祕鑰將會保存到crypto-config文件夾中。

6.配置transaction生成器

configtxgen tool用於建立以下配置項:

genesis block:是一個配置block用於初始化blockchain網絡以及channel的,一樣能夠做爲鏈上的第一個block

  • orderer genesis block,
  • channel channel configuration transaction
  • 兩個anchor peer transactions,其中每個對應一個peer org

如何使用該工具請查看, Channel Configuration (configtxgen) 

orderer block是ordering service的genesis block,channel transaction file在channel建立時廣播給orderer。anchor peer transactions在channel定義了一個Org Anchor Peer。

Configtxgen有一個配置文件configtx.yaml,包括了sample network的定義。現有3個成員:一個Orderer Org以及兩個Peer Orgs(Org1 Org2,每一個包括2個peer節點)。這個文件定義了一個聯合consortium,包括兩個Peer Org。注意該文件的頂部profile section。你會發現有兩個惟一的headers。一個用做orderer Genesis block  - TwoOrgsOrdererGenesis -,一個用做channel - TwoOrgsChannel。

後續咱們在來看這些headers。

注意:sampleConsortium被定義在system-level profile中,接下來被channel-level profile引用。Channels存在在consortium的範圍內,全部的consortium都在network的範圍內。

這個配置文件包括了兩個附加的定義。一個就是每一個Peer Org(peer0.org1.example.com & peer0.org2.example.com)的anchor節點,另一個就是指向每一個成員的MSP目錄的位置,基於此,咱們能夠將每一個Org的根證書存放在orderer Genesis block中,這是一個很重要的概念。如今任意network entity與ordering service通訊時就能對起數字簽名進行驗證。

7.運行tool

能夠經過configtxgen and cryptogen手動生成證書/密鑰以及各項配置文件。一樣,能夠參考byfn.sh腳本實現。

接下來咱們嘗試手動生成。

能夠參考byfn.sh腳本中的generateCerts函數用來生成證書(這些證書被定義在crypto-config.yaml中的網絡配置所使用)所須要的命令。爲了方便起見,咱們提供一個參考以下。

首先,先跑起來cryptogen工具,咱們的二進制文件都在bin目錄下,所以咱們須要cd到tool所在的目錄下.

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

接下來,咱們會告訴configtxgen工具去哪找到須要調用的configtx.yaml文件。

首先,咱們須要設置一個環境變量,用於告知configtxgen根據去哪找configtx.yaml配置文件。接下來,咱們調用configtxgen工具建立orderer Genesis block

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

接着,咱們建立channel transaction artifact(channel.tx)。而後,確保替換$CHANNEL_NAME(這裏我用zeychannel替換的)或設置環境變量,語句以下:

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上定義Org1的anchor節點。而後,確保替換$CHANNEL_NAME(這裏我用zeychannel替換的)或設置環境變量,語句以下:

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

而後,咱們在相同的channel上定義Org2的anchor節點。

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

8.啓動network

咱們利用docker-compose腳原本啓動咱們的network。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

若是沒有註釋掉上面的命令的話,在network啓動的時候,其將執行全部的CLI命令,具體請見 What’s happening behind the scenes?節。咱們須要分析每一步的功能及句法,所以咱們一步步執行命令。

timeout的變量適合使用較高的數值,默認是60s。

啓動network,注意$CHANNEL_NAME,<pick_a_value>本身設定

CHANNEL_NAME=$CHANNEL_NAME TIMEOUT=<pick_a_value> docker-compose -f docker-compose-cli.yaml up -d

若是想看到實時日誌,則不要加-d標示。若是須要日誌流,則須要打開第二個終端進行操做。

9.環境變量

對於如下針對peer0.org1.example.com的CLI命令,咱們須要使用如下給出的四個環境變量來介紹咱們的命令。這些peer0.org1.example.com變量都被包含在CLI容器裏,所以咱們能夠不用傳遞的操做它們。然而!,若是你想發送calls到其餘peers或者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

10.建立並進入Channel

接下來進入到剛建立的CLI容器裏面,

docker exec -it cli bash

若是成功則能看到以下信息

請回憶下咱們使用configtxgen工具生成channel配置artifact-channel.tx。咱們將把artifact做爲建立channel的請求的一部分發送給orderer。

注意到在接下來的命令中咱們發送了-- cafile做爲命令的一部分。這個是orderer證書的本地路徑,使得咱們能夠驗證TLS握手。

咱們使用-c flag 標註出咱們的channel名稱,用-f flag標註出咱們的channel 配置transaction。在本例中是channel.tx,然而你可使用不一樣的名稱用於掛載配置transaction。使用下面建立channel的語句的時候注意channel-name。

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> -咱們能夠經過這個id進入到channel。它包含channel.tx中指定的配置信息,建立成功後有以下輸出:

接下來的操做都須要在CLI容器中進行,在操做peer0.org1.example.com以外的peer時,須要記得相關環境變量的命令。

接下來咱們把peer0.org1.example.com加入到channel中去,channel-ID.block是以前生成的,這裏個人是zeychannel.block。

# 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>

如下是成功的顯示

你可把其餘的peer加入到該channel上,可是須要設置上述的四個環境變量。

11.安裝並實例化chaincode

咱們這裏只是使用已經存在的chaincode。

application經過chaincode與blockchain ledger進行交互。咱們把chaincode安裝到execute與endorse咱們transaction的peer上,接下來在channel上初始化chaincode。

首先,安裝sample go代碼到4個peer之一的peer上。如下命令把chaincode的源代碼放到了peer節點的文件系統上。

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

安裝成功打印以下日誌

 

接下來,在channel上實例化chaincode。這將在channel上初始化chaincode,同時設置chaincode的endorsement的策略,而後在目標peer上啓動chaincode容器。請注意-P參數,咱們經過設置這個參數,來指定transaction的endorsement的需求level,用於驗證chaincode。

在下面的命令,咱們定義了endorsement策略爲-P "OR ('Org0MSP.member','Org1MSP.member')"。這表示咱們須要隸屬於Org1或者Org2的peer進行「endorsement」(也就是說,只有一個endorsement)。若是把or改成and則說明咱們須要兩個endorsement。

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

請在 endorsement policies中查看更詳細的策略說明。

12.查詢

首先查詢a的值,確保chaincode已經正常的實例化,同時確保state DB已經被填充

# be sure to set the -C and -n flags appropriately

peer chaincode query -C zeychannel -n zeychaincode -c '{"Args":["query","a"]}'

13.調用

讓咱們從a帳戶轉移10個到b帳戶,這個命令將會建立新的block同時更新state DB。

# 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 zeychannel -n zeychaincode -c '{"Args":["invoke","a","b","10"]}'

而後查詢

# be sure to set the -C and -n flags appropriately

peer chaincode query -C zeychannel -n zeychaincode -c '{"Args":["query","a"]}'

14.上述調用過程解析

  • script.sh腳本在CLI容器內部執行,該腳本執行了createChannel命令,提供了channel名稱,同時使用channel.tx進行channel配置
  • createChannel的輸出是一個genesis block,使用channel名稱命名的block,例如zeychannel.block,該block在peers的文件系統上存儲(我的理解就在chain上做爲一個block存儲的),該block包括channel.tx指定的channel配置信息。
  • 加入channel的命令對全部4個peer進行執行,把以前生成的genesis block做爲輸入。這個join命令使得peers加入到了zeychannel(我本身建立的)裏面,同時建立了一個以zeychannel.block做爲開始的chain。
  • 接着,咱們擁有了由4個peer,兩個organization組成的channel。這都在咱們TwoOrgsChannel profile.裏面。
  • peer0.org1.example.com 與 peer1.org1.example.com 隸屬於 Org1; peer0.org2.example.com 以及 peer1.org2.example.com 隸屬於 Org2。這些關係在crypto-config.yaml中定義,同時在咱們的docker compose中指定了MSP的路徑。
  • Org1MSP (peer0.org1.example.com) 以及 Org2MSP (peer0.org2.example.com)的anchor節點接下來被更新了。咱們基於創建的channel把Org1MSPanchors.tx 與 Org2MSPanchors.tx 的artifacts,發送給orderering service,以實現上述的更新。
  • chaincode_example02被安裝在了peer0.org1.example.com 與 peer0.org2.example.com
  • 接着chaincode在peer0.org2.example.com被實例化。實例化把chaincode加到channel上,並啓動目標peer的容器,接着初始化chaincode有關的鍵-值對( [「a」,」100」 「b」,」200」])。實例化的過程致使了dev-peer0.org2.example.com-zeychaincode-1.0的啓動。
  • 實例化須要有endorsement策略的參數,這裏設置爲-P "OR    ('Org1MSP.member','Org2MSP.member')",表示任意transaction必須被Org1 或者 Org2的一個peer進行endorsed。
  • 接下來把對「a」的查詢發送給peer0.org1.example.com,即在peer0.org1.example.com查詢a的值。chaincode以前已經安裝在了peer0.org1.example.com上,所以這個查詢將會針對Org1 peer0 啓動一個容器(dev-peer0.org1.example.com-zeychaincode-1.0),而後查詢結果獲得返回,沒有任何寫的操做發生,所以返回值是100
  • 接着調用請求發送給peer0.org1.example.com,把10個從a轉移到b。
  • 而後chaincode在peer1.org2.example.com進行安裝。
  • 而後一個查詢a的餘額的請求發送到peer1.org2.example.com。這個啓動了第三個chaincode容器(dev-peer1.org2.example.com-mycc-1.0),90被返回。正確的反應了上述transaction,a的值被改成了10。
相關文章
相關標籤/搜索