本篇是笔者在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