基础环境搭建
操作系统:阿里云Ubuntu16.04
Git、Golang、Nodejs
Docker环境支持:docker、docker-compose
Fabric组件Docker镜像
fabric-samples源码库
Nodejs: 8.9.4
#先看这个搭建Hyperledger Fabric基础环境
https://www.jianshu.com/p/7ff74cfc7125
#(看到安装docker-compose完成即可,接下来看此篇)
安装Node.js
1. 首先,使用下面的命令来安装 nvm(第一种方式,两种选其一即可)
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
- 下载并安装完成后用户退出重新登录或者重新 source 一下环境变量
source ~/.bashrc
- 查看当前的版本
nvm ls
- 首次安装没有版本,使用
nvm install
安装指定版本的 node
nvm install v8.9.4
- 再次查看 node 版本信息
nvm list
- 博主之前已经安装
v6.9.5
,目前->
所指是v6.9.5
版本,需要切换成v8.9.4
版本
nvm use v8.9.4
2. 手动安装Node.js(第二种方式)
wget wget https://nodejs.org/dist/v8.9.4/node-v8.9.4-linux-x64.tar.gz
tar -zxvf node-v8.9.4-linux-x64.tar.gz
sudo mv node-v8.9.4-linux-x64 /usr/local/node
sudo ln -s /usr/local/node/bin/node /usr/local/bin/node
sudo ln -s /usr/local/node/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm
3. 测试是否安装成功,以及Node.js
并设置镜像加速
node -v
npm -v
npm config set registry https://registry.npm.taobao.org
构建网络
- 创建
fabric-samples
目录
mkdir -p github.com/hyperledger/fabric-samples
- 进入
fabric-samples
下
git clone https://github.com/hyperledger/fabric-samples.git
- 查看版本分支
git tag
- 切换项目版本
git checkout v1.1.0
- 查看当前项目的版本
git branch
- 如果你要删除已命名的分支,执行下方代码
git branch -d v1.1.0
- 打开下方网址(下载
fabric-samples
目录下bin
目录中所需要的文件)
https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fabric
- 下载
hyperledger-fabric-linux-amd64-1.1.0.tar.gz
压缩包
image.png
wget https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fabric/linux-amd64-1.1.0/hyperledger-fabric-linux-amd64-1.1.0.tar.gz
- 解压到
fabric-samples
目录下
tar -zxvf hyperledger-fabric-darwin-amd64-1.1.0.tar.gz -C /home/go/src/github.com/hyperledger/fabric-samples/
- 打开fabcia-ca下载网址
https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric-ca/hyperledger-fabric-ca/
下载hyperledger-fabric-ca-linux-amd64-1.1.0.tar.gz
安装包
wget https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric-ca/hyperledger-fabric-ca/linux-amd64-1.1.0/hyperledger-fabric-ca-linux-amd64-1.1.0.tar.gz
- 解压到
fabric-samples
目录下
tar -zxvf hyperledger-fabric-ca-linux-amd64-1.1.0.tar.gz -C /home/go/src/github.com/hyperledger/fabric-samples/
- 下载fabric相关镜像
第一种方式:(推荐)
- 下载
bootstrap.sh
wget https://github.com/hyperledger/fabric/blob/release-1.1/scripts/bootstrap.sh
- 编辑
bootstrap.sh
并注释以下代码(目的是不重复下载上述已经下载好的fabric
和fabric-ca
)
编辑`bootstrap.sh`并注释以下代码
echo "===> Downloading platform specific fabric binaries"
#curl https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fabric/${ARCH}-${VERSION}/hyperledger-fabric-${ARCH}-${VERSION}.tar.gz | tar xz
echo "===> Downloading platform specific fabric-ca-client binary"
#curl https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric-ca/hyperledger-fabric-ca/${ARCH}-${VERSION}/hyperledger-fabric-ca-${ARCH}-${VERSION}.tar.gz | tar xz
第二种方式:
curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh | bash -s 1.1.0
第三种方式:(需要kx上网)
curl -sSL https://goo.gl/6wtTN5 | sudo bash -s 1.1.0
- 进入
first-network
目录中
cd first-network
- 目录分析
- .env:存储一些环境变量
- base:存储docker-compose的一些公共服务
- byfn.sh:执行脚本
- configtx.yaml和crypto-config.yaml:根据之前生成的2个工具,生成相应的配置文件,用来启动网络,放到当前目录的channel-artifacts和crypto-config里面
- dockper-compose:用于启动网络
- scripts:存放测试脚本,做的事:创建通道、加入通道,安装链码,实例化链码,链码交互
创建first-network
第一种方式:自动创建
- 执行以下命令构建网络
- 关闭网络,自动清除配置和docker进程
./byfn.sh -m down
./byfn.sh -m generate
./byfn.sh -m up
第二种方式:手动创建
- 首先关闭网络,自动清除配置和docker进程
./byfn.sh -m down
- 生成创世区块
- 指定按照yaml文件生成配置(
crypto-config.yaml
:用于配置组织节点的个数)
image.png
../bin/cryptogen generate --config=./crypto-config.yaml
- 在
first-network
目录下设置变量:(设置工作目录)
export FABRIC_CFG_PATH=$PWD
- 生成系统链的创世区块:(
-profile
指定联盟配置,outputBlock
指定存放的位置,genesis.block
指整个网络的创世区块)
../bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
-
生成应用通道的配置信息
生成应用通道的配置信息
- 生成通道的创世交易:
-profile
指定业务联盟,-outputCreateChannelTx
指存放的路径,创建的名字叫mychannel
export CHANNEL_NAME=mychannel
../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channelID $CHANNEL_NAME
- 生成锚节点配置更新文件
-
生成两个组织锚节点的交易信息
生成两个组织锚节点的交易信息
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP
../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP
操作网络
编辑docker-compose-cli.yaml
,注释command
命令
vim docker-compose-cli.yaml
运行
docker-compose-cli.yaml
CHANNEL_NAME=$CHANNEL_NAME TIMEOUT=600 docker-compose -f docker-compose-cli.yaml up -d
1. 创建和加入通道
- 与客户端交互操作
docker exec -it cli bash
- 创建通道(
-o
指定与哪个orderer节点通信,-c
指定创建的通道名称,-f
指定使用的文件)
peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
- 查看orderer节点的运行日志
docker logs orderer.example.com
- 加入通道
peer channel join -b mychannel.block
- 查看peer加入的通道列表
peer channel list
2. 安装并实例化链码
- 安装链码(
-n
指定链码安装的名字,-v
指定version,-l
指定使用语言,-p
指定安装链码的所在路径)
peer chaincode install -n mycc -v 1.0 -l golang -p github.com/chaincode/chaincode_example02/go/
- 实例化链码
peer chaincode instantiate -o orderer.example.com:7050 --tls true --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 mychannel -n mycc -l golang -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P 'OR ('\''Org1MSP.peer'\'','\''Org2MSP.peer'\'')'
- 查询
peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
- 转账
peer chaincode invoke -o orderer.example.com:7050 --tls true --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 mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}'
- 重新查询
peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
输入exit
退出docker
容器并关闭网络
exit
./byfn.sh -m down
参数说明:
- -o:指定order服务节点地址
- --tls:是否开启TLS验证
- --cafile:指定TLS_CA证书的所在路径
- -C:指定通道名称
- -n:指定链码名称
- -c:指定调用链码的所需参数
- -p:指定安装链码的所在路径
- -P:指定背书策略
Node.js和fabcar交互
- 参考链接
https://hyperledger-fabric.readthedocs.io/en/release-1.1/write_first_app.html
- 进入
fabric-samples
目录下的fabcar
目录中
cd fabric-samples/fabcar
查看package.json
文件
cat package.json
Fabcar启动
- 进入first-network中执行
./byfn.sh -m down
- 关闭活跃容器
docker rm -f $(docker ps -aq)
- 清理缓存的网络
docker network prune
- 删除fabcar智能合约的底层链码图像,如果是第一次运行这个项目可以不执行(可以通过 docker images来查询需要删除的镜像)
docker rmi dev-peer0.org1.example.com-fabcar-1.0-5c906e402ed29f20260ae42283216aa75549c571e2e380f3615826365d8269ba
- 在
fabcar
目录中安装客户端
npm install
-
启动网络
./startFabric.sh node
./startFabric.sh node
-
执行完成后,注册管理用户(首先应用的admin用户应该向ca-server发送一个证书登记请求,接受一个对于这个user的登记证书(eCert),后续我们会根据使用这个admin注册和认证一个新的user)
node enrollAdmin.js
node enrollAdmin.js
-
实现registerUser.js,生成用户账户(创建一个普通用户user1,这个用户用来查询和更新账本。admin用户身份用来创建user1用户)
node registerUser
node registerUser
查询账本
-
现在我们可以运行JavaScript程序。首先,运行query.js 程序,返回账本上所有汽车列表。应用程序中预先加载了一个queryAllCars函数,用于查询所有车辆,因此我们可以简单地运行程序:
node query.js
node query.js
- 如果想返回某个车辆信息,编辑query.js,我们将函数
queryAllCars
更改为queryCar
并将特定的“Key” 传递给args参数。在这里,我们使用CAR4
。 所以我们编辑后的query.js程序现在应该包含以下内容:
编辑query.js - 重新运行query.js
node query.js
更新账本
- 你可以通过编辑invoke.js调用
createCar
创建一辆新车或者调用changeCarOwner
更改车的拥有者
比如创建一个新的车辆 - 编辑invoke.js
vim invoke.js
找到下方代码
// createCar chaincode function - requires 5 args, ex: args: ['CAR12', 'Honda', 'Accord', 'Black', 'Tom'],
// changeCarOwner chaincode function - requires 2 args , ex: args: ['CAR10', 'Barry'],
// must send the proposal to endorsing peers
var request = {
//targets: let default to the peer assigned to the client
chaincodeId: 'fabcar',
fcn: '',
args: [''],
chainId: 'mychannel',
txId: tx_id
};
将上方代码更改为以下代码
var request = {
//targets: let default to the peer assigned to the client
chaincodeId: 'fabcar',
fcn: 'createCar',
args: ['CAR10', 'Chevy', 'Volt', 'Red', 'Nick'],
chainId: 'mychannel',
txId: tx_id
};
-
执行invoke.js
node invoke.js运行成功图
node invoke.js
- 编辑
query.js
,将args中的参数改为CAR10
,然后重新执行query.js
将args中的参数改为`CAR10`
vim query.js
node query.js
FAQ
- 运行
./byfn.sh -m down
出现错误的解决方法:
https://segmentfault.com/a/1190000014221967
- 执行
node registerUser.js
出现错误:Failed to register: Error: fabric-ca request register failed with errors [[{"code":0,"message":"No identity type provided. Please provide identity type"}]]
执行`node registerUser.js `出现错误
- 大概的意思是需要我们提供一个可验证的type。 只需编辑
node registerUser.js
文件
vim registerUser.js
- 把
returnfabric_ca_client.register({enrollmentID: 'user1', affiliation:'org1.department1'}, admin_user);
替换为下方代码
returnfabric_ca_client.register({enrollmentID: 'user1', affiliation:'org1.department1',role: 'client'}, admin_user);
- 点击保存重新运行即可
- 创建通道失败,出现以下几种问题:
Error on outputChannelCreateTx: config update generation failure: could not parse application to application group:
setting up the MSP manager failed: the supplied identity is not valid: x509:
certificate signed by unknown authority (possibly because of "x509: ECDSA verification failure"
while trying to verify candidate authority certificate "ca.org1.example.com")
如果遇到此错误,说明生成的证书有问题(要么没有生成,要么生成的证书不符合x509标准),请重新生成。Error:got unexpected status: FORBIDDEN -- Failed to reach implicit threshold of 1 sub-policies, required 1 remaining: permission denied
从错误中可以看到是因为权限而造成,请检查生成的文件对应的所属访问权限。hdr.format undefined (type *tar.header has no field or method format) ......
如果遇到此错误,则检查go语言的版本是否符合官方指定的 Hyperledger Fabric 版本要求。Error: got unexpected status: BAD_REQUEST -- error authorizing update: error validating ReadSet: readset expected key [Group] /Channel/Application at version 0, but got version 1
出现如上错误,说明指定的通道名称已经在当前处于运行状态的 Fabric 网络中存在。
- 设置
marbles . step 4 error error: Caught exception: TypeError: Cannot read property 'getConnectivityState' of undefined
出错
npm uninstall grpc
rm -rf node_modules/
npm install
-
node registerUser.js
image.png
参考文档
https://github.com/IBM-Blockchain/marbles/blob/master/docs/use_local_hyperledger.md
https://hyperledger-fabric.readthedocs.io/en/release-1.0/chaincode4noah.html
https://hyperledger-fabric.readthedocs.io/en/release-1.1/write_first_app.html
https://github.com/hyperledger/fabric-samples/tree/release-1.1