本篇是笔者在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菜鸟进阶攻略》