Hyperledger Fabric 2.2 学习笔记:测试网络test-network
写在前面
最近被Hyperledger Fabric折磨,归根结底还是因为自己太菜了qwq。学习路漫漫,笔记不能少。下面的步骤均是基于已经成功搭建了Fabric2.2环境,并且拉取fabric-samples文件夹了。
一、启动测试网络
打开终端进入test-network目录下。我的具体目录是: /workspace/fabric-samples/test-network,因此有命令:
cd /workspace/fabric-samples/test-network
在使用./network.sh命令前,可以先查看选项说明。
./network.sh -h
要是不想看问题也不大,跟着我走就好。(๑>ڡ<)☆
下面正式开始!
首先启动网络。注意下面这个命令只是启动网络并没有创建通道。
./network.sh up
启动网络后,接着创建通道。由于这里并没有指定通道的名字,此时默认为mychannel.
./network.sh createChannel
其实上述两步可以用一条命令实现,那就是:
./network.sh up createChannel
之后,将bin目录中二进制文件添加到 CLI 路径。
export PATH=${PWD}/../bin:$PATH
设置FABRIC_CFG_PATH为指向fabric-samples中的core.yaml文件。
export FABRIC_CFG_PATH=$PWD/../config/
二、安装链码
根据官方文档可以知道,Fabric链码生命周期需要组织同意定义一个链码的参数,比如说名称、版本以及链码背书策略。通道成员通过以下四步达成共识。不是通道上的每一个组织都需要完成每一步。
1.打包链码。这一步可以被一个或者每一个组织完成。
2.安装链码在你的peer节点上。每一个用链码的组织都需要完成。
3.为你的组织批准链码定义。使用链码的每一个组织都需要完成这一步。链码能够在通道上运行之前,链码定义需要被足够多的组织批准来满足通道的生命周期背书(LifecycleEndorsement)策略(默认为大多数组织)。
4.提交链码定义到链上。一旦通道所需数量的组织已经同意,提交交易需要被提交。提交者首先从已同意组织中的足够的peer节点中收集背书,然后通过提交链码声明。
显然,下面要进行的第一步是打包链码。链码需要被打包成一个tar文件。
1.打包链码
下面使用peer lifecycle chaincode package命令创建链码包
peer lifecycle chaincode package fabcar.tar.gz --path ../chaincode/fabcar/go/ --lang golang --label fabcar_1
说明:① 命令中--path指的是 将指定目录(../chaincode/fabcar/go/)的源码打包成fabcar.tar.gz.
② --label 后面是标签,当日后链码包升级的时候,可以设置不同的标签。
2.安装链码
此时网络有两个组织,所以需要先后在Org1、Org2的peer节点上安装链码。
(1)Org1 peer节点安装链码
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=localhost:7051
peer lifecycle chaincode install fabcar.tar.gz
当看到status:200即为成功。具体成功返回如下:
2022-04-20 10:03:14.293 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nIfabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506\022\010fabcar_1" >
2022-04-20 10:03:14.294 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: fabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506
但过程总是曲折的,显然我没有那么顺利成功。在安转链码的时候,我得到如下返回:
Error: chaincode install failed with status: 500 - failed to invoke backing implementation of 'InstallChaincode': could
not build chaincode: docker build failed: docker image build failed: docker build failed: Error returned from build: 1
"go: github.com/hyperledger/fabric-contract-api-go@v1.1.0: Get "https://proxy.golang.org/github.com/hyperledger
/fabric-contract-api-go/@v/v1.1.0.mod": dial tcp: lookup proxy.golang.org on 172.20.10.1:53: read udp 172.17.0.2:53395
->172.20.10.1:53: i/o timeout “
解决方案如下:
到../chaincode/fabcar/go/目录下打开终端执行命令。
go env -w GOPROXY=https://goproxy.io,direct
go env -w GO111MODULE=on
go mod vendor
之后重新执行peer lifecycle chaincode install fabcar.tar.gz即可成功。
(2)Org2 peer节点安装链码
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051
peer lifecycle chaincode install fabcar.tar.gz
3.批准链码定义
下面需要把链码发布到通道上去。首先查询链码包ID
peer lifecycle chaincode queryinstalled
得到返回如下:
Installed chaincodes on peer:
Package ID: fabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506, Label: fabcar_1
因此我的包ID为:
fabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506.
通过链码时,我们将使用包ID,因此,将包ID保存为环境变量。将返回的包ID粘贴到下面的命令中。
export CC_PACKAGE_ID=
在这里就是:
export CC_PACKAGE_ID=fabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506
之后,Org2通过链码定义
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name fabcar --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --waitForEvent
返回如下即为成功。
2022-04-20 10:20:59.307 CST [chaincodeCmd] ClientWait -> INFO 001 txid [f688ddff60056af56e96784d253695e9fbb056e5244058fb30b2d05977214c1c] committed with status (VALID) at localhost:9051
设置以下环境变量以Org1管理员身份运行:
Org1通过链码定义
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:7051
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name fabcar --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --waitForEvent
返回:
2022-04-20 10:25:23.828 CST [chaincodeCmd] ClientWait -> INFO 001 txid [9178a978646d4b010a61677488532af88b7393ba898341168fc627c0953a9884] committed with status (VALID) at localhost:7051
使用 peer lifecycle chaincode checkcommitreadiness 命令来检查通道成员是否已批准相同的链码定义:
peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name fabcar --version 1.0 --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json
返回:
{
"approvals": {
"Org1MSP": true,
"Org2MSP": true
}
}
返回的结果说明这两个节点批准了这个链码的定义。
4.将链码提交到通道
使用 peer lifecycle chaincode commit 命令将链码定义提交到通道。commit命令还需要由组织管理员提交。
peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name fabcar --version 1.0 --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
返回:
2022-04-20 10:45:05.973 CST [chaincodeCmd] ClientWait -> INFO 001 txid [c93e2e79e2da09f04654d30630959d9e80d2576aefdf4be16e3b281d48a011a4] committed with status (VALID) at localhost:7051
2022-04-20 10:45:06.019 CST [chaincodeCmd] ClientWait -> INFO 002 txid [c93e2e79e2da09f04654d30630959d9e80d2576aefdf4be16e3b281d48a011a4] committed with status (VALID) at localhost:9051
使用 peer lifecycle chaincode querycommitted 命令来确认链码定义已经提交给通道。
peer lifecycle chaincode querycommitted --channelID mychannel --name fabcar --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
返回:
Committed chaincode definition for chaincode 'fabcar' on channel 'mychannel':
Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
看到此返回信息后可以知道我们提交的链码已经提交到通道myChannel中。
三、调用链码
① 调用链码
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n fabcar --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"initLedger","Args":[]}'
返回如下即为成功。
2022-04-20 15:49:24.590 CST [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
显然,我并没有一下就成功。我得到如下返回:
Error: endorsement failure during invoke. response: status:500 message:"error in simulation:failed to execute transaction 5e72e85cea510ecc198412f2f7df406b8fbcff8adf97d052d6b165413ed85854:
could not launch chaincode fabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506:error starting container: error starting container: API error (404): network _test not found"
错误原因:
fabric-samples/test-network/docker/docker-compose-test-net.yaml的配置文件中有一个
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_test
${COMPOSE_PROJECT_NAME}在智能合约启动时,此值获取到的会是空值,从而导致标题的错误提示。这个也被官方收录进issue中,并在fabric-samples的main分支中已经改为固定值,如下:
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric_test
需要注意的是使用docker-compse启动时,创建的network名字会在前边加上当前docker-compse文件的目录名字。所以如果我们在使用老版本的fabric-sample时,自己可修改${COMPOSE_PROJECT_NAME}值为当前你存放compose文件的文件夹名称。
查看创建的docker network可以使用docker network ls查看。
此时查看到名字是:docker_test
因此将文件中的
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_test
改为
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=docker_test
注意文件有两处需要改。
②调用链码
peer chaincode query --channelID mychannel --name fabcar -c '{"Args":["queryAllCars"]}'
得到返回:
[{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR10","Record":{"make":"VW","model":"Polo","colour":"Grey","owner":"Archie"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]
到这测试网络也就跑通了。(๑╹◡╹)ノ"""
参考
[1] Hyperledger Fabric2中文文档-链码部署
[2] Error starting container: API error (404): {“message“:“network _byfn not found“}
[3] error starting container: API error (404): network fabric_test not found“
[4] hyperledger-fabric【1】运行测试网络
Hyperledger Fabric 2.2 学习笔记:测试网络test-network的更多相关文章
- python3.4学习笔记(十七) 网络爬虫使用Beautifulsoup4抓取内容
python3.4学习笔记(十七) 网络爬虫使用Beautifulsoup4抓取内容 Beautiful Soup 是用Python写的一个HTML/XML的解析器,它可以很好的处理不规范标记并生成剖 ...
- python3.4学习笔记(十三) 网络爬虫实例代码,使用pyspider抓取多牛投资吧里面的文章信息,抓取政府网新闻内容
python3.4学习笔记(十三) 网络爬虫实例代码,使用pyspider抓取多牛投资吧里面的文章信息PySpider:一个国人编写的强大的网络爬虫系统并带有强大的WebUI,采用Python语言编写 ...
- Hyperledger Fabric 1.0 学习搭建 (五)--- 启动Fabric多节点集群
5.1.启动orderer节点服务 上述操作完成后,此时各节点的compose配置文件及证书验证目录都已经准备完成,可以开始尝试启动多机Fabric集群. 首先启动orderer节点,切换至order ...
- Hyperledger Fabric 1.0 学习搭建 (四)--- 创建Fabric多节点集群
4.1.配置说明 首先可以根据官方Fabric自带的e2e_cli列子中的集群方案来生成我们自己的集群,与案例不同的是我们需要把容器都分配到不同的服务器上,彼此之间通过网络来进行通信,网络构建完成后则 ...
- Hyperledger Fabric 1.0 学习搭建 (三)--- 运行测试e2e-Fabric
3.1.运行fabric-samples的问题说明 该问题说明能够解决6.1.平台特定使用的二进制文件配置第一步的问题.可以选择继续阅读该说明,或者等参考到6.1小节时再反向阅读本说明,具体在6.1中 ...
- Hyperledger Fabric 1.0 学习搭建 (二)--- 源码及镜像文件处理
2.1下载Fabric源码下载Fabric源码是因为要用到源码中提到的列子和工具, 工具编译需要用到go语言环境, 因此需要把源码目录放到$GOPATH下. 通过1.3中go的安装配置, $GOPAT ...
- Hyperledger Fabric:最简单的方式测试你的链码
一直以来,写完链码进行测试都要先搭建一个Fabric环境,然后安装链码进行测试,实际上Fabric提供了最为简单的方式可以允许我们对编写的应用链码进行功能测试,不需要搭建一个完整的Fabeic环境.而 ...
- 学习笔记-ResNet网络
ResNet网络 ResNet原理和实现 总结 一.ResNet原理和实现 神经网络第一次出现在1998年,当时用5层的全连接网络LetNet实现了手写数字识别,现在这个模型已经是神经网络界的“hel ...
- Hyperledger Fabric 1.0 学习搭建 (一)--- 基础环境搭建
1: 环境构建在本文中用到的宿主机环境是Centos ,版本为Centos.x86_64 7.2, 一定要用7版本以上, 要不然会安装出错. 通过Docker 容器来运行Fabric的节点,版本为v1 ...
随机推荐
- Java基础 - 泛型详解
2022-03-24 09:55:06 @GhostFace 泛型 什么是泛型? 来自博客 Java泛型这个特性是从JDK 1.5才开始加入的,因此为了兼容之前的版本,Java泛型的实现采取了&quo ...
- 什么是LSA,在OSPF中LSA是什么
什么是LSA:链路状态通告,它存在于LSU(链路状态更新包) Type 1 LSA:路由器LSA 每个OSPF路由器都会产生路由器LSA,描述了对应设备的物理接口所连接的链路和接口,并指明 ...
- 用腾讯云Gogs搭建私有git服务器
前言 经常有需要写不能公开代码的项目,所以只好自己搭建一个私人的git服务器 Gogs的好处在于比Gitlib轻量化了好多,而且是国人写的,官方主页也是中文的 Gogs首页 腾讯云服务器配置: Ubu ...
- Java思考——如何使用Comparable按照我们指定的规则排序?
练习: 存储学生对象并遍历,创建TreeSet集合使用无参构造方法,并按照年龄从小到大的顺序排序,若年龄相同再按照姓名的字母顺序排序 分析: 1.创建学生类,成员变量name,age;无参构造,带参构 ...
- 100行代码实现HarmonyOS“画图”应用,eTS开发走起!
本期我们给大家带来的是"画图"应用开发者Rick的分享,希望能给你的HarmonyOS开发之旅带来启发~ 介绍 2021年的华为开发者大会(HDC2021)上,HarmonyOS ...
- idea在新窗口中打开
IntelliJ IDEA 2018.1.4 x64版本同时打开多个窗口可以进行如下设置,找到file--Settings...,然后会弹出下面的窗口:然后注意红框里的勾选项,最后确定Apply,OK ...
- XSS攻击和CSRF攻击
一.什么是XSS攻击 XSS(Cross Site Scripting),即跨站脚本攻击,是一种常见于web应用程序中的计算机安全漏洞.XSS通过在用户端注入恶意的可运行脚本,若服务器端对用户输入不进 ...
- Redis的安装与启动(一)
Redis是c语言开发的. 安装redis需要c语言的编译环境.如果没有gcc需要在线安装.yum install gcc-c++ 安装步骤: 第一步:redis的源码包上传到linux系统.--源码 ...
- Dubbo telnet 命令能做什么?
dubbo 服务发布之后,我们可以利用 telnet 命令进行调试.管理. Dubbo2.0.5 以上版本服务提供端口支持 telnet 命令 连接服务 telnet localhost 20880 ...
- 记录md的偏好设置