搭建区块链浏览器——基于hyperledger fabric 1.0,MySQL容器
Contents
区块链浏览器是hyperledger官方项目,能够可视化的查看区块链的详细信息,包括区块信息/详情,交易信息/详情,节点信息,链码信息等...本文介绍如何搭建区块链浏览器
环境要求
- nodejs 6.9.x (Note that v7.x is not yet supported)
- mysql 5.7 or greater
- Hyperledger Fabric 1.0
- docker 17.06.2-ce [https://www.docker.com/community-edition]
- docker-compose 1.14.0 [https://docs.docker.com/compose/]
分支选择
- 注意根据自己部署的fabric版本以及数据库类型来选择不同的分支。目前支持的数据库类型有两种:
- PostgreSQL
- MySQL
因为感觉MySQL相对普遍一些,所以我选择的是MySQL。查看各个分支的README文件,reactbranch这个分支符合我的要求(fabric1.0+MySQL)
克隆仓库
# 进入自己开发的目录(这里只是例子,可以改成自己想要的目录)
$ cd /home/chy
# 克隆仓库
$ git clone https://github.com/hyperledger/blockchain-explorer.git
# 切换到合适的分支
$ git checkout reactbranch
- 仓库中README文件已经讲述了基本的部署步骤。这些部分我就不再赘述,主要是介绍我实际搭建过程中与他的步骤不同的地方。
- 我并没有直接安装MySQL在宿主机,而是使用docker容器
- 我使用的是自己之前搭建好的网络,而不是他提供的sample网络
数据库搭建
- 作为一个web应用,区块链浏览器需要连接单独的数据库,用于存储一些运行产生的数据。
- 本着不折腾的原则,我这里单独开了一个Mysql的docker容器,通过端口映射的方式访问。
# 拉取MySQL镜像,版本号>=5.7
$ docker pull MySQL:5.7
# 启动MySQL容器
# -v 挂载目录,将刚才克隆的目录挂载到docker容器下
# -p 将docker的3306端口映射到宿主机的33060端口
# -d 后台运行
$ docker run --name MySQL-Explorer -e MYSQL_ROOT_PASSWORD=password -v /home/chy/blockchain-explorer:/explore -p 33060:3306 -d mysql
- 启动数据库容器后,进入容器,导入数据库
# 进入容器终端
$ docker exec -it MySQL-Explorer bash
# 导入数据库(用户名,密码,sql文件路径换成自己的)
$ mysql -u<username> -p < db/fabricexplorer.sql
修改配置文件
-
在项目目录中,有一个
config.json
文件,这个文件规定了区块链网络各种参数- 每个节点,组织,用户的tls,msp凭证
- 各节点的地址grpcs://IP:port
-
这个config.json要根据自己创建网络之初的那些配置文件来写,必须完全对应起来,才能跑通

一个节点的配置示例
-
连接数据库的配置
- 在config.json里边的mysql字段修改
- mysql字段
-
我所遇到的一个问题
db/mysqlservice.js
中端口号默认是3306,所以没有连上我的容器- 解决:以下是我的修改方式,仅供参考
- 我的修改方式
运行服务
$ npm install
$ ./start.sh
访问本机的8080端口,最终结果如图

运行效果
附录:我的配置文件
仅供参考
{
"network-config": {
"org1": {
"name": "sy_org1",
"mspid": "SyOrg1MSP",
"peer1": {
"requests": "grpcs://127.0.0.1:7051",
"events": "grpcs://127.0.0.1:7053",
"server-hostname": "peer0.org1.qklszzngsy.com",
"tls_cacerts": "../MilkTrace/crypto-config/peerOrganizations/org1.qklszzngsy.com/peers/peer0.org1.qklszzngsy.com/tls/ca.crt"
},
"peer2": {
"requests": "grpcs://127.0.0.1:8051",
"events": "grpcs://127.0.0.1:8053",
"server-hostname": "peer1.org1.qklszzngsy.com",
"tls_cacerts": "../MilkTrace/crypto-config/peerOrganizations/org1.qklszzngsy.com/peers/peer1.org1.qklszzngsy.com/tls/ca.crt"
},
"peer3": {
"requests": "grpcs://127.0.0.1:8054",
"events": "grpcs://127.0.0.1:8056",
"server-hostname": "peer2.org1.qklszzngsy.com",
"tls_cacerts": "../MilkTrace/crypto-config/peerOrganizations/org1.qklszzngsy.com/peers/peer2.org1.qklszzngsy.com/tls/ca.crt"
},
"admin": {
"key": "../MilkTrace/crypto-config/peerOrganizations/org1.qklszzngsy.com/users/Admin@org1.qklszzngsy.com/msp/keystore",
"cert": "../MilkTrace/crypto-config/peerOrganizations/org1.qklszzngsy.com/users/Admin@org1.qklszzngsy.com/msp/signcerts"
}
},
"org2": {
"name": "sy_org2",
"mspid": "SyOrg2MSP",
"peer1": {
"requests": "grpcs://127.0.0.1:9051",
"events": "grpcs://127.0.0.1:9053",
"server-hostname": "peer0.org2.qklszzngsy.com",
"tls_cacerts": "../MilkTrace/crypto-config/peerOrganizations/org2.qklszzngsy.com/peers/peer0.org2.qklszzngsy.com/tls/ca.crt"
},
"peer2": {
"requests": "grpcs://127.0.0.1:10051",
"events": "grpcs://127.0.0.1:10053",
"server-hostname": "peer1.org2.qklszzngsy.com",
"tls_cacerts": "../MilkTrace/crypto-config/peerOrganizations/org2.qklszzngsy.com/peers/peer1.org2.qklszzngsy.com/tls/ca.crt"
},
"peer3": {
"requests": "grpcs://127.0.0.1:10073",
"events": "grpcs://127.0.0.1:10075",
"server-hostname": "peer2.org2.qklszzngsy.com",
"tls_cacerts": "../MilkTrace/crypto-config/peerOrganizations/org2.qklszzngsy.com/peers/peer2.org2.qklszzngsy.com/tls/ca.crt"
},
"admin": {
"key": "../MilkTrace/crypto-config/peerOrganizations/org2.qklszzngsy.com/users/Admin@org2.qklszzngsy.com/msp/keystore",
"cert": "../MilkTrace/crypto-config/peerOrganizations/org2.qklszzngsy.com/users/Admin@org2.qklszzngsy.com/msp/signcerts"
}
},
"org3": {
"name": "sy_org3",
"mspid": "SyOrg3MSP",
"peer1": {
"requests": "grpcs://127.0.0.1:10054",
"events": "grpcs://127.0.0.1:10066",
"server-hostname": "peer0.org3.qklszzngsy.com",
"tls_cacerts": "../MilkTrace/crypto-config/peerOrganizations/org3.qklszzngsy.com/peers/peer0.org3.qklszzngsy.com/tls/ca.crt"
},
"peer2": {
"requests": "grpcs://127.0.0.1:10067",
"events": "grpcs://127.0.0.1:10069",
"server-hostname": "peer1.org3.qklszzngsy.com",
"tls_cacerts": "../MilkTrace/crypto-config/peerOrganizations/org3.qklszzngsy.com/peers/peer1.org3.qklszzngsy.com/tls/ca.crt"
},
"peer3": {
"requests": "grpcs://127.0.0.1:10070",
"events": "grpcs://127.0.0.1:10072",
"server-hostname": "peer2.org3.qklszzngsy.com",
"tls_cacerts": "../MilkTrace/crypto-config/peerOrganizations/org3.qklszzngsy.com/peers/peer2.org3.qklszzngsy.com/tls/ca.crt"
},
"admin": {
"key": "../MilkTrace/crypto-config/peerOrganizations/org3.qklszzngsy.com/users/Admin@org3.qklszzngsy.com/msp/keystore",
"cert": "../MilkTrace/crypto-config/peerOrganizations/org3.qklszzngsy.com/users/Admin@org3.qklszzngsy.com/msp/signcerts"
}
}
},
"host":"localhost",
"port":"8080",
"channel": "mychannel",
"GOPATH":"../artifacts",
"keyValueStore":"/tmp/fabric-client-kvs",
"eventWaitTime":"30000",
"mysql":{
"host":"localhost",
"port":"33060",
"database":"fabricexplorer",
"username":"root",
"passwd":"password"
}
}