本篇是筆者在Ubuntu18下配置部署hyperledger fabric的過程步驟(血淚史),同時這也是我畢業設計的一個環節,在此記錄下來這一階段我踩過的坑和一些心得體會,希望對后來的小伙伴有幫助。關於hyperledger項目的具體介紹,移步官方網站https://cn.hyperledger.org/
目錄如下:
- 實驗環境
- 基礎工具下載
- fabric核心模塊簡介
- 編譯配置fabric環境
- 檢查環境
- 實驗總結
- 附參考資料、推薦學習資料
上篇說到fabric各個模塊的編譯結束,下面根據編譯后的fabric模塊,快速運行一個簡單的fabric網絡,雖然簡單,但是“麻雀雖小,五臟俱全”,一起瞅瞅成果。
四. 編譯配置fabric環境(配置fabric相關配置文件)
1. 工作目錄
首先選擇一個目錄來存放命令執行過程中存放的文件,目錄可以是任意的位置,我選擇的是/var/hyperledger。之后在這個文件夾下,會生成相關的fabric五大模塊各自的配置文件,隨着程序的運行,該目錄下的數據會越來越多,所以選擇工作文件夾時要考慮到數據的增長。
# mkdir /var/hyperledger/ # cd /var/hyperledger
2. 生成fabric需要的證書文件
證書是貫穿於fabric系統運行始終的文件,幾乎所有的實體和交易都需要證書,包括peer結點、orderer結點、交易、用戶、SDK客戶端等等,證書就相當於fabric網絡中的通行證,表示了數據的身份和合法性,因為聯盟鏈需要有准入機制,不如公鏈開放,所以需要對每個網絡中的身份進行嚴格登記與追蹤,保證及時發現惡意結點並且可以快速的排除惡意結點。
上文介紹到,fabric系統中,cryptogen模塊負責生成證書文件,生成的證書文件存放在一個單獨的文件夾fabricconfig中。
創建文件夾
# mkdir -p /var/hyperledger/fabricconfig
fabric自帶有cryptogen生成證書所需要的配置文件的模板,輸入cryptogen showtemplate命令即可看到模板文件,經過修改參數,配置文件如下圖所示:
OrdererOrgs: //定義orderer結點組織 - Name: Orderer Domain: linya.com //這個是項目根域名,用戶可以自己設定 Specs: - Hostname: orderer //主機名稱 PeerOrgs: //定義peer結點的組織 - Name: Org1 //組織一名為Org1 Domain: org1.linya.com //組織一的根域名 Template: Count: 2 //組織一的節點數量 Users: Count: 3 //組織一的用戶數量 - Name: Org2 Domain: org2.linya.com Template: Count: 2 Users: Count: 2
文件中的相關參數在文中已經注明含義,配置文件采用的是yaml格式,不了解yaml文件的請移步這里。將上述文件保存為名稱crypto-config.yaml,存放在fabricconfig文件夾中。
接着執行如下命令,生成證書文件:
# cd /var/hyperledger/fabricconfig
# cryptogen generate --config=crypto-config.yaml --output ./crypto-config
執行命令后,在fabricconfig文件夾下生成了一個子文件夾crypto-config,里面存放着生成的證書文件,具體文件夾結構大家可以使用tree命令查看。
在測試階段,fabric網絡中運行的所有節點和用戶都是本機充當,所以要將peer結點的主機域名和orderer節點的主機域名,與本機的ip相互映射,打開/etc/hosts文件,在文件末尾添加以下幾行:
192.168.199.131 orderer.example.com //192.168.199.131是我的本機IP,可以使用ifconfig命令查看本機IP地址 192.168.199.131 peer0.org1.example.com 192.168.199.131 peer1.org1.example.com 192.168.199.131 peer2.org1.example.com 192.168.199.131 peer0.org2.example.com 192.168.199.131 peer1.org2.example.com
3. 創始塊的生成
創始塊不包含交易數據,它存放的是系統的配置文件,它是需要手動生成的,configtxgen是負責生成系統初始塊和channel(通道、賬本)初始塊的模塊,同樣的fabric也自帶了配置文件的模板,該配置文件在fabric源碼目錄中,下面將這個配置文件復制到工作目錄中,修改參數再使用。文件名字是configtx.yaml
# mkdir -p /var/hyperledger/order/ # cp -r $GOPATH/src/github.com/hyperledger/fabric/sampleconfig/configtx.yaml /opt/hyperledger/order # cd /var/hyperledger/order
隨后對configtx.yaml文件進行修改,修改之后的內容如下所示:
Organizations: - &OrdererOrg Name: OrdererOrg ID: OrdererMsp MSPDir: /var/hyperledger/fabricconfig/crypto-config/ordererOrganizations/example.com/msp - &Org1 Name: Org1MSP ID: Org1MSP MSPDir: /var/hyperledger/fabricconfig/crypto-config/peerOrganizations/org1.example.com/msp AnchorPeers: - Host: peer0.org1.example.com Port: 7051 - &Org2 Name: Org2MSP ID: Org2MSP MSPDir: /var/hyperledger/fabricconfig/crypto-config/peerOrganizations/org2.example.com/msp AnchorPeers: - Host: peer0.org2.example.com Port: 7051 Application: &ApplicationDefaults Organizations: Orderer: &OrdererDefaults OrdererType: solo Addresses: - orderer.example.com:7050 BatchTimeout: 2s BatchSize: MaxMessageCount: 10 AbsoluteMaxBytes: 98 MB PreferredMaxBytes: 512 KB Kafka: Brokers: - 127.0.0.1:9092 Organizations: Profiles: TestTwoOrgsChannel: Consortium: SampleConsortium Application: <<: *ApplicationDefaults Organizations: - *Org1 - *Org2 TestTwoOrgsOrdererGenesis: Orderer: <<: *OrdererDefaults Organizations: - *OrdererOrg Consortiums: SampleConsortium: Organizations: - *Org1 - *Org2
配置完成后,執行如下命令生成初始塊
# cd /var/hyperledger
# configtxgen -profile TestTwoOrgsOrdererGenesis -outputBlock ./orderer.genesis.block
然后創建channel通道的初始塊,也是使用configtxgen模塊完成的:
# configtxgen -profile TestTwoOrgsChannel -outputCreateChannelTx ./testchannel.tx -channelID testchannel
上述命令執行后會生成testchannel.tx文件,用來生成channel配置。接着生成相關的錨點文件,需要執行以下命令:
# configtxgen -profile TestTwoOrgsChannel -outputAnchorPeersUpdate ./Org1MSPanchors.tx -channelID testchannel -asOrg Org1MSP
# configtxgen -profile TestTwoOrgsChannel -outputAnchorPeersUpdate ./Org2MSPanchors.tx -channelID testchannel -asOrg Org2MSP
執行上述兩條命令后會生成Org1MSPanchors.tx和Org2MSPanchors.tx。
4. Orderer結點的啟動
同上述文件類似,首先將fabric自帶的相關配置文件復制到工作目錄下:
# cp $GOPATH/src/github.com/hyperledger/fabric/sampleconfig/orderer.yaml /opt/hyperledger/order
接着將文件進行修改,修改之后為:
General: LedgerType: file ListenAddress: 0.0.0.0 ListenPort: 7050 TLS: Enabled: false PrivateKey: /var/hyperledger/fabricconfig/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key Certificate: /var/hyperledger/fabricconfig/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt RootCAs: - /var/hyperledger/fabricconfig/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt ClientAuthEnabled: false ClientRootCAs: LogLevel: debug LogFormat: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}' GenesisMethod: file GenesisProfile: TestTwoOrgsOrdererGenesis GenesisFile: /var/hyperledger/order/orderer.genesis.block LocalMSPDir: /var/hyperledger/fabricconfig/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp LocalMSPID: OrdererMSP Profile: Enabled: false Address: 0.0.0.0:6060 BCCSP: Default: SW SW: Hash: SHA2 Security: 256 FileKeyStore: KeyStore: ############################################################################### FileLedger: Location: /var/hyperledger/order/production/orderer Prefix: hyperledger-fabric-ordererledger ############################################################################### RAMLedger: HistorySize: 1000 ############################################################################### Kafka: Retry: ShortInterval: 5s ShortTotal: 10m LongInterval: 5m LongTotal: 12h NetworkTimeouts: DialTimeout: 10s ReadTimeout: 10s WriteTimeout: 10s Metadata: RetryBackoff: 250ms RetryMax: 3 Producer: RetryBackoff: 100ms RetryMax: 3 Consumer: RetryBackoff: 2s Verbose: false TLS: Enabled: false PrivateKey: Certificate: RootCAs: Version:
接下來啟動orderer結點:
# orderer start
5. peer結點的啟動
同上述文件類似,首先將fabric自帶的相關配置文件復制到工作目錄下:
# cp $GOPATH/src/github.com/hyperledger/fabric/sampleconfig/core.yaml /opt/hyperledger/peer
修改后的文件如下所示:
# Copyright IBM Corp. All Rights Reserved. # # SPDX-License-Identifier: Apache-2.0 # ############################################################################### # # LOGGING section # ############################################################################### logging: peer: debug cauthdsl: warning gossip: warning ledger: info msp: warning policies: warning grpc: error # Message format for the peer logs format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}' ############################################################################### # # Peer section # ############################################################################### peer: id: peer0.org1.example.com networkId: dev listenAddress: 0.0.0.0:7051 address: peer0.org1.example.com:7051 addressAutoDetect: false gomaxprocs: -1 gossip: bootstrap: 127.0.0.1:7051 useLeaderElection: true orgLeader: false endpoint: maxBlockCountToStore: 100 maxPropagationBurstLatency: 10ms maxPropagationBurstSize: 10 propagateIterations: 1 propagatePeerNum: 3 pullInterval: 4s pullPeerNum: 3 requestStateInfoInterval: 4s publishStateInfoInterval: 4s stateInfoRetentionInterval: publishCertPeriod: 10s skipBlockVerification: false dialTimeout: 3s connTimeout: 2s recvBuffSize: 20 sendBuffSize: 200 digestWaitTime: 1s requestWaitTime: 1s responseWaitTime: 2s # Alive check interval(unit: second) aliveTimeInterval: 5s # Alive expiration timeout(unit: second) aliveExpirationTimeout: 25s # Reconnect interval(unit: second) reconnectInterval: 2s # This is an endpoint that is published to peers outside of the organization. # If this isn't set, the peer will not be known to other organizations. externalEndpoint: peer0.org1.example.com:7051 # Leader election service configuration election: # Longest time peer waits for stable membership during leader election startup (unit: second) startupGracePeriod: 15s # Interval gossip membership samples to check its stability (unit: second) membershipSampleInterval: 1s # Time passes since last declaration message before peer decides to perform leader election (unit: second) leaderAliveThreshold: 10s # Time between peer sends propose message and declares itself as a leader (sends declaration message) (unit: second) leaderElectionDuration: 5s # EventHub related configuration events: # The address that the Event service will be enabled on the peer address: 0.0.0.0:7053 buffersize: 100 timeout: 10ms tls: enabled: false cert: file: /var/hyperledger/fabricconfig/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt key: file: /var/hyperledger/fabricconfig/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key rootcert: file: /var/hyperledger/fabricconfig/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt # The server name use to verify the hostname returned by TLS handshake serverhostoverride: fileSystemPath: /var/hyperledger/peer/production BCCSP: Default: SW SW: Hash: SHA2 Security: 256 # Location of Key Store FileKeyStore: KeyStore: # Path on the file system where peer will find MSP local configurations mspConfigPath: /var/hyperledger/fabricconfig/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp localMspId: Org1MSP profile: enabled: false listenAddress: 0.0.0.0:6060 ############################################################################### # # VM section # ############################################################################### vm: endpoint: unix:///var/run/docker.sock # settings for docker vms docker: tls: enabled: false ca: file: docker/ca.crt cert: file: docker/tls.crt key: file: docker/tls.key # Enables/disables the standard out/err from chaincode containers for # debugging purposes attachStdout: false hostConfig: NetworkMode: host Dns: # - 192.168.0.1 LogConfig: Type: json-file Config: max-size: "50m" max-file: "5" Memory: 2147483648 ############################################################################### # # Chaincode section # ############################################################################### chaincode: # This is used if chaincode endpoint resolution fails with the # chaincodeListenAddress property peerAddress: id: path: name: # Generic builder environment, suitable for most chaincode types builder: $(DOCKER_NS)/fabric-ccenv:$(ARCH)-$(PROJECT_VERSION) golang: # golang will never need more than baseos runtime: $(BASE_DOCKER_NS)/fabric-baseos:$(ARCH)-$(BASE_VERSION) car: # car may need more facilities (JVM, etc) in the future as the catalog # of platforms are expanded. For now, we can just use baseos runtime: $(BASE_DOCKER_NS)/fabric-baseos:$(ARCH)-$(BASE_VERSION) java: Dockerfile: | from $(DOCKER_NS)/fabric-javaenv:$(ARCH)-$(PROJECT_VERSION) # Timeout duration for starting up a container and waiting for Register # to come through. 1sec should be plenty for chaincode unit tests startuptimeout: 300s executetimeout: 30s mode: dev keepalive: 0 system: cscc: enable lscc: enable escc: enable vscc: enable qscc: enable logging: level: info shim: warning format: '%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message}' ############################################################################### # # Ledger section - ledger configuration encompases both the blockchain # and the state # ############################################################################### ledger: blockchain: state: stateDatabase: goleveldb couchDBConfig: couchDBAddress: 127.0.0.1:5984 # This username must have read and write authority on CouchDB username: password: # Number of retries for CouchDB errors maxRetries: 3 # Number of retries for CouchDB errors during peer startup maxRetriesOnStartup: 10 # CouchDB request timeout (unit: duration, e.g. 20s) requestTimeout: 35s # Limit on the number of records to return per query queryLimit: 10000 history: enableHistoryDatabase: true
接着在core.yaml所在的文件夾中執行以下命令,用來啟動orderer結點:
# export set FABRIC_CFG_PATH=/opt/hyperledger/peer # peer node start >> log_peer.log 2>&1 &
6. 創建通道
首先創建通道:
# export set CORE_PEER_LOCALMSPID=Org1MSP # export set CORE_PEER_MSPCONFIGPATH=/var/hyperledger/fabricconfig/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp # peer channel create -t 50 -o orderer.linya.com:7050 -c testchannel -f /opt/hyperledger/order/testchannel.tx
然后讓已經運行的peer模塊加入通道:
export set CORE_PEER_LOCALMSPID=Org1MSP export set CORE_PEER_ADDRESS=peer0.org1.example.com:7051 export set CORE_PEER_MSPCONFIGPATH=/var/hyperledger/fabricconfig/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
peer channel join -b /opt/hyperledger/order/testchannel.block
然后更新錨節點:
export set CORE_PEER_LOCALMSPID=Org1MSP export set CORE_PEER_ADDRESS=peer0.org1.example.com:7051 export set CORE_PEER_MSPCONFIGPATH=/var/hyperledger/fabricconfig/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp peer channel update -o orderer.linya.com:7050 -c testchannel -f /var/hyperledger/order/Org1MSPanchors.tx
五. 檢察環境
下面通過fabric項目自帶的鏈碼,來測試相關模塊的編譯安裝是否正確,一共有四個步驟,如下所示:
首先,部署chaincode鏈碼:
export set CORE_PEER_LOCALMSPID=Org1MSP export set CORE_PEER_ADDRESS=peer0.org1.example.com:7051 export set CORE_PEER_MSPCONFIGPATH=/var/hyperledger/fabricconfig/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp peer chaincode install -n r_test_cc6 -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
然后,實例化chaincode鏈碼:
export set CORE_PEER_LOCALMSPID=Org1MSP export set CORE_PEER_ADDRESS=peer0.org1.example.com:7051 export set CORE_PEER_MSPCONFIGPATH=/var/hyperledger/fabricconfig/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp peer chaincode instantiate -o orderer.linya.com:7050 -C testchannel -n r_test_cc6 -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
然后,通過chaincode寫入數據:
export set CORE_PEER_LOCALMSPID=Org1MSP export set CORE_PEER_ADDRESS=peer0.org1.example.com:7051 export set CORE_PEER_MSPCONFIGPATH=/var/hyperledger/fabricconfig/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp peer chaincode invoke -o orderer.linya.com:7050 -C testchannel -n r_test_cc6 -c '{"Args":["invoke","a","b","1"]}'
最后,通過chaincode查詢數據:
export set CORE_PEER_LOCALMSPID=Org1MSP export set CORE_PEER_ADDRESS=peer0.org1.example.com:7051 export set CORE_PEER_MSPCONFIGPATH=/var/hyperledger/fabricconfig/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp peer chaincode query -C testchannel -n r_test_cc6 -c '{"Args":["query","a"]}'
上述命令如果正確執行,則成功安裝配置fabric。
六. 實驗總結
最大的總結就是寫博客比做實驗還要慢emmmm。。為了督促畢設進度還是老老實實寫吧hhhhhh。
fabric基本環境的搭建過程如上述所示,具體的參考資料參見附錄。
fabric搭建還是有點復雜的,但是多踩幾次坑就漸漸明白了,看官方文檔不順利的娃娃可以看看中文技術博客,百度能搜到不少相關的中文博客,大伙兒一起加油呀^_^,我有寫的不對的地方,歡迎大家在評論區留言討論,有啥不懂得也可以評論,大家一起集思廣益~~~~~
七. 附參考資料、推薦學習資料
《區塊鏈開發實戰:Hyperledger Fabric關鍵技術與案例分析》
《Hyperledger Fabric菜鳥進階攻略》
https://blog.csdn.net/liruizi/article/details/84998364#commentBox
https://blog.csdn.net/sinat_36742186/article/details/88390019