fabric环境搭建2.2.0-单机

0 前言

Fabric1.4是第一个LTS版本,而2.2是第二个LTS版本,本人尝试搭建2.2.0的单机环境,操作系统是Ubuntu18.04,apt已经更新。

1 环境准备

1.1 go版本要求

fabric 2.2.0官方要求go版本要大于1.13,建议使用最新版,当前(2020-09-24)最新版是1.15.2

注意:

  • go的环境变量只需要配置PATH即可,GOROOT和GOPATH默认好了,不需要配置,可以使用go env命令查看,GOPATH默认是$HOME/go,这个存放go mod下载下来的包,和maven的本地仓库类似;
  • 2.2.0版本不必严格放在$GOPATH/src/github/hyperledger/下面,随机放在一个目录下就行,使用的是go mod,不要求$GOPATH。

网上安装go的教程很多,找一个时间最近的,照着安装。安装完后,执行以下操作:

1
2
3
4
# 强制使用go mod模式
go env -w GO111MODULE=on
# 设置go代理 方便下载包
go env -w GOPROXY=https://goproxy.cn,direct

1.2 其余环境准备

docker、docker-compose,直接就安装最新版,网上都有安装过程,也可以参考我写的:

注意:一定要给docker设置镜像加速,否则后面下载镜像极慢。

2 下载代码

主要是三部分代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
cd $HOME
# 这个路径可以随意更改,不必强求和这个一样,后面对照好就行
mkdir -p go/fabric
cd go/fabric

git clone https://github.com/hyperledger/fabric.git -b v2.2.0
git checkout -b 2.2.0

# 这个最好也是用2.2.0版本 没有的话,那就选择最近的tag
# 但是我clone时,最新的tag是2.1.1的,fabric 2.2.0是刚出来的,因此我就直接用了master
# 后期,一定要切换tag,否则master和2.2.0相差是很大的,容易出问题
git clone https://github.com/hyperledger/fabric-samples.git

# fabric2.2版本使用的ca版本是1.4.7
git clone https://github.com/hyperledger/fabric-ca.git -b v1.4.7
git checkout -b 1.4.7

# github下载可能非常慢,可以使用gitee镜像(镜像满足2.2.0测试条件):
git cloen https://gitee.com/mirrors/hyperledger-fabric.git -b v2.2.0
git clone https://gitee.com/zhanglonglong12/fabric-samples.git
git clone https://gitee.com/zhanglonglong12/fabric-ca.git -b v1.4.7

3 下载镜像和依赖

3.0 正常下载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
cd $HOME/go/fabric/fabric/scripts
./bootstrap.sh -h

# 结果 从这里可以看到,ca用的版本是1.4.7
Usage: bootstrap.sh [version [ca_version]] [options]

options:
-h : this help
-d : bypass docker image download
-s : bypass fabric-samples repo clone
-b : bypass download of platform-specific binaries

e.g. bootstrap.sh 2.2.0 1.4.7 -s
will download docker images and binaries for Fabric v2.2.0 and Fabric CA v1.4.7

# 分析:这个文件实际干了三个活:下载镜像、下载二进制文件、下载fabric-samples;
# 其中fabric-samples已经下载好了,只需要下载镜像和二进制文件即可。

# 下载镜像
./bootstrap.sh -bs

# 这个下载时间很长,看网络了,有错误,就重新运行。

# 下载平台二进制文件
./bootstrap.sh -ds

# 这个是从github下载的,我测试很慢

# 结果是当前文件夹下面,多了两个目录,bin和config目录。
# 把这俩目录,放到fabric-samples下面
mv bin ../fabric-samples/
mv config ../fabric-samples/

3.1 ./bootstrap.sh -ds 下载很慢,怎么解决?手动!

下载的bin和config目录,实际上都可以在本地找到。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cd $HOME/go/fabric/fabric
git status
# 确认是2.2.0的版本

# 编译
make release
# 这个一般不会出什么错,前面1.1的go代理设置好了,很快的。

# bin目录好了
cp -r release/linux-amd64/bin ../fabric-samples/

# 具体make有哪些指令,可以查看目录下的Makefile文件

# config目录下三个yaml文件,实际上就是fabric下面sampleconfig里面的,我仔细对比过,一摸一样
mkdir ../fabric-samples/config
cp sampleconfig/*.yaml ../fabric-samples/config/

3.2 fabric-ca依赖

后面的示例网络启动时,需要fabric-ca-client和fabric-ca-server这两个依赖。

3.2.1 直接下载

下载地址:https://github.com/hyperledger/fabric-ca/releases/tag/v1.4.7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cd $HOME

# 从github上下载的,看网络情况
wget https://github.com/hyperledger/fabric-ca/releases/download/v1.4.7/hyperledger-fabric-ca-linux-amd64-1.4.7.tar.gz

tar -zxvf hyperledger-fabric-ca-linux-amd64-1.4.7.tar.gz

# 把加压后的两个可执行程序放到fabric-samples/bin中
mv bin/* go/fabric/fabric-samples/bin/

# 剩下的可以删了
rm -r bin
# 也可以把这个备份一下,说不定后来会用到
rm hyperledger-fabric-ca-linux-amd64-1.4.7.tar.gz

3.2.2 编译

除了直接下载,当然还可以编译,主要是在fabric-ca中编译。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
cd $HOME/go/fabric/fabric-ca
# 确定一下tag,一定是要在v1.4.7上
git status

# 直接release就行
make release

# 有错误 不要慌张 去解决它
Building release/linux-amd64/bin/fabric-ca-client for linux-amd64
mkdir -p release/linux-amd64/bin
GOOS=linux GOARCH=amd64 go build -o /home/zll/go/fabric/test/fabric-ca/release/linux-amd64/bin/fabric-ca-client -tags "caclient" -ldflags "-X github.com/hyperledger/fabric-ca/lib/metadata.Version=1.4.7" github.com/hyperledger/fabric-ca/cmd/fabric-ca-client
cannot find module providing package github.com/hyperledger/fabric-ca/cmd/fabric-ca-client: working directory is not part of a module
Makefile:264: recipe for target 'release/linux-amd64/bin/fabric-ca-client' failed
make: *** [release/linux-amd64/bin/fabric-ca-client] Error 1

# 从提示信息来看,是因为当前目录不是go modle目录,目录中有vendor文件夹
# vendor实际上也是go的模块管理方式,但是我们前面强制使用了go modle模式,因此vendor在这里无效
# 需要把go vendor模式转为go modle模式

# 打开看看
vi vendor/vendor.json
# 里面都是依赖,直接ctrl+end,到最后
# "rootPath": "github.com/hyperledger/fabric-ca"
:wq 退出vendor.json

# 开启go mod,后面的参数和rootPath对应
go mod init github.com/hyperledger/fabric-ca

# 模块会自动的扫描vendor.json中的依赖,然后写入go.mod文件中
# 可能会由于网络的原因,有些依赖不行

# 开始的几行是这样的:
go: creating new go.mod: module github.com/hyperledger/fabric-ca
go: copying requirements from vendor/vendor.json
go: converting vendor/vendor.json: stat golang.org/x/text/encoding@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2: unrecognized import path "golang.org/x/text/encoding": https fetch: Get "https://golang.org/x/text/encoding?go-get=1": dial tcp 216.239.37.1:443: connect: connection refused
go: converting vendor/vendor.json: stat golang.org/x/sys/unix@c200b10b5d5e122be351b67af224adc6128af5bf: unrecognized import path "golang.org/x/sys/unix": https fetch: Get "https://golang.org/x/sys/unix?go-get=1": dial tcp 216.239.37.1:443: connect: connection refused
# 。。。。。后面的省略

# 这是正常现象,这个命令会耗时间,慢慢等
# 执行完后,仔细看输出结果,会发现只有以golang.org/x开头的和google.golang.org开头的,不行

# 对比vendor.json和go.mod文件,会发现确实这些依赖都没加上
cat vendor/vendor.json
cat go.mod

# 那就只好手动添加了

以google.golang.org开头的只有一个,但是以golang.org/x开头的有好多啊,手动执行命令得麻烦死了,写个辅助脚本main.py,位于目录$HOME/go/fabric/fabric-ca下面:

main.py
1
2
3
4
5
6
7
8
9
10
11
12
import json

path = "./vendor/vendor.json"

with open(path, 'r', encoding='utf8')as fp:
json_data = json.load(fp)
data = json_data["package"]

for te in data:
if(te["path"].startswith("golang.org/x") or te["path"].startswith("google.golang.org")):
print("go get -d {}@{}".format(te["path"], te["revision"]))

然后是执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cd $HOME/go/fabric/fabric-ca
vi command.sh

# 第一行写入:
#!/bin/bash

# 回车换行,之后保存退出
:wq

# 执行脚本,将结果追加到文件中
python3 main.py >> command.sh

# 赋予执行的权限
sudo chmod +x command.sh

我这里也有生成好的command.sh文件,直接复制就行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#!/bin/bash
go get -d golang.org/x/crypto/bcrypt@f70185d77e8278766928032ee1355e3da47e7181
go get -d golang.org/x/crypto/blowfish@f70185d77e8278766928032ee1355e3da47e7181
go get -d golang.org/x/crypto/cryptobyte@f70185d77e8278766928032ee1355e3da47e7181
go get -d golang.org/x/crypto/cryptobyte/asn1@f70185d77e8278766928032ee1355e3da47e7181
go get -d golang.org/x/crypto/curve25519@f70185d77e8278766928032ee1355e3da47e7181
go get -d golang.org/x/crypto/ed25519@f70185d77e8278766928032ee1355e3da47e7181
go get -d golang.org/x/crypto/ed25519/internal/edwards25519@f70185d77e8278766928032ee1355e3da47e7181
go get -d golang.org/x/crypto/internal/chacha20@f70185d77e8278766928032ee1355e3da47e7181
go get -d golang.org/x/crypto/ocsp@f70185d77e8278766928032ee1355e3da47e7181
go get -d golang.org/x/crypto/pkcs12@f70185d77e8278766928032ee1355e3da47e7181
go get -d golang.org/x/crypto/pkcs12/internal/rc2@f70185d77e8278766928032ee1355e3da47e7181
go get -d golang.org/x/crypto/poly1305@f70185d77e8278766928032ee1355e3da47e7181
go get -d golang.org/x/crypto/sha3@f70185d77e8278766928032ee1355e3da47e7181
go get -d golang.org/x/crypto/ssh@f70185d77e8278766928032ee1355e3da47e7181
go get -d golang.org/x/net/context@b336a971b799939dd16ae9b1df8334cb8b977c4d
go get -d golang.org/x/net/context/ctxhttp@b129b8e0fbeb39c8358e51a07ab6c50ad415e72e
go get -d golang.org/x/net/html@adae6a3d119ae4890b46832a2e88a95adc62b8e7
go get -d golang.org/x/net/html/atom@adae6a3d119ae4890b46832a2e88a95adc62b8e7
go get -d golang.org/x/net/html/charset@adae6a3d119ae4890b46832a2e88a95adc62b8e7
go get -d golang.org/x/sys/unix@c200b10b5d5e122be351b67af224adc6128af5bf
go get -d golang.org/x/text/encoding@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2
go get -d golang.org/x/text/encoding/charmap@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2
go get -d golang.org/x/text/encoding/htmlindex@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2
go get -d golang.org/x/text/encoding/internal@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2
go get -d golang.org/x/text/encoding/internal/identifier@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2
go get -d golang.org/x/text/encoding/japanese@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2
go get -d golang.org/x/text/encoding/korean@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2
go get -d golang.org/x/text/encoding/simplifiedchinese@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2
go get -d golang.org/x/text/encoding/traditionalchinese@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2
go get -d golang.org/x/text/encoding/unicode@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2
go get -d golang.org/x/text/internal/gen@a8b38433e35b65ba247bb267317037dee1b70cea
go get -d golang.org/x/text/internal/language@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2
go get -d golang.org/x/text/internal/language/compact@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2
go get -d golang.org/x/text/internal/tag@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2
go get -d golang.org/x/text/internal/triegen@a8b38433e35b65ba247bb267317037dee1b70cea
go get -d golang.org/x/text/internal/ucd@a8b38433e35b65ba247bb267317037dee1b70cea
go get -d golang.org/x/text/internal/utf8internal@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2
go get -d golang.org/x/text/language@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2
go get -d golang.org/x/text/runes@6f44c5a2ea40ee3593d98cdcc905cc1fdaa660e2
go get -d golang.org/x/text/transform@a8b38433e35b65ba247bb267317037dee1b70cea
go get -d golang.org/x/text/unicode/cldr@a8b38433e35b65ba247bb267317037dee1b70cea
go get -d golang.org/x/text/unicode/norm@a8b38433e35b65ba247bb267317037dee1b70cea
go get -d golang.org/x/tools/go/gcexportdata@1edc8e83c8971a61ace316267a21e03f34f687e6
go get -d golang.org/x/tools/go/internal/gcimporter@1edc8e83c8971a61ace316267a21e03f34f687e6
go get -d golang.org/x/tools/go/internal/packagesdriver@1edc8e83c8971a61ace316267a21e03f34f687e6
go get -d golang.org/x/tools/go/packages@1edc8e83c8971a61ace316267a21e03f34f687e6
go get -d golang.org/x/tools/internal/fastwalk@1edc8e83c8971a61ace316267a21e03f34f687e6
go get -d golang.org/x/tools/internal/gopathwalk@1edc8e83c8971a61ace316267a21e03f34f687e6
go get -d golang.org/x/tools/internal/semver@1edc8e83c8971a61ace316267a21e03f34f687e6
go get -d google.golang.org/grpc/grpclog@1f1a4999ca75ba4fd6d5c91233383a170034a1a5

解释一下:go get命令是下载并安装包,-d参数表示只下载不安装,目录内有go.mod文件时,go get的操作会记录在go.mod文件中,下载的包放在$GOPATH/pkg中。

继续接着上面编译的活:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
cd $HOME/go/fabric/fabric-ca

# 执行脚本
./command.sh

# 再看一下,里面依赖内容多了
cat go.mod

# go mod依赖都准备好,可以正式编译了
# 两种选择,结果都是一样的

# 法一:
# 删除vendor目录,不在使用了,因为我们用的是go modle
rm -r vendor

# 编译 这次没有问题了
make release

# 法二:
# 覆盖vedor目录
go modle vendor

# 编译 这次没有问题了
make release

# 转移
cp release/linux-amd64/bin/* ../fabric-samples/bin/

3.3 概览

1
2
3
4
5
6
7
cd ~/go/fabric/fabric-samples

ls bin
configtxgen configtxlator cryptogen discover fabric-ca-client fabric-ca-server idemixgen orderer peer

ls config
configtx.yaml core.yaml orderer.yaml

依赖整完了,可以开启后续了。

4 启动网络

本人对2.2.0的网络机制,研究的还不是很清楚,只能写一个大概的流程,仅供参考。

4.1 示例一:test-network

2.2.0版本没有传统的first-network了,换成了test-network,官方推荐,研究研究,了解流程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
cd ~/go/fabric/test/fabric-samples/test-network

# 三步走:启动网络,创建通道,部署链码
./network.sh up
./network.sh createChannel
./network.sh deployCC

# 注意部署链码这一步,查看network.sh,找到下面的代码:
function deployCC() {

scripts/deployCC.sh $CHANNEL_NAME $CC_NAME $CC_SRC_PATH $CC_SRC_LANGUAGE $CC_VERSION $CC_SEQUENCE $CC_INIT_FCN $CC_END_POLICY $CC_COLL_CONFIG $CLI_DELAY $MAX_RETRY $VERBOSE

if [ $? -ne 0 ]; then
fatalln "Deploying chaincode failed"
fi

exit 0
}
# 实际上,调用了scripts/deployCC.sh,注意传入的参数:$CC_NAME,是有定义的,CC_NAME="basic"
# 打开scripts/deployCC.sh,找到下面的两段代码:
if [ "$CC_NAME" = "basic" ]; then
println $'\e[0;32m'asset-transfer-basic$'\e[0m' chaincode
CC_SRC_PATH="../asset-transfer-basic"

if [ "$CC_SRC_LANGUAGE" = "go" ]; then
CC_SRC_PATH="$CC_SRC_PATH/chaincode-go/"
# 可以看到,部署的链码名称是basic,路径是../asset-transfer-basic/chaincode-go/

# 找到链码,就可以进行实例化、查询、修改操作了
# 没有CLI容器,需要手动设置主机的环境变量
# 注意:CORE_PEER_TLS_ROOTCERT_FILE和CORE_PEER_MSPCONFIGPATH必须是在test-network目录!!!
# organizations文件夹只在这个目录有!!
# 在test-network目录:
export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/
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 chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'

# 结果是空的,说明没有实例化

# 实例化 参数名需要到链码中查看 InitLedger在链码中定义了一组数据
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 basic --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":[]}'

# 结果
2020-09-25 09:15:33.282 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200

# 再查询
peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'

# 结果 这个就是在链码中定义的
[{"ID":"asset1","color":"blue","size":5,"owner":"Tomoko","appraisedValue":300},{"ID":"asset2","color":"red","size":5,"owner":"Brad","appraisedValue":400},{"ID":"asset3","color":"green","size":10,"owner":"Jin Soo","appraisedValue":500},{"ID":"asset4","color":"yellow","size":10,"owner":"Max","appraisedValue":600},{"ID":"asset5","color":"black","size":15,"owner":"Adriana","appraisedValue":700},{"ID":"asset6","color":"white","size":15,"owner":"Michel","appraisedValue":800}]

# 查询
peer chaincode query -C mychannel -n basic -c '{"Args":["ReadAsset","asset6"]}'

# 结果
{"ID":"asset6","color":"white","size":15,"owner":"Michel","appraisedValue":800}

# 由于资产转移(基本)链码的背书策略要求交易必须由Org1和Org2签名,因此chaincode invoke命令需要使用peer0.org1.example.com和peer0.org2.example.com,-peerAddresses标志。 由于已为网络启用TLS,因此该命令还需要使用--tlsRootCertFiles标志为每个对等方引用TLS证书。
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 basic --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":"TransferAsset","Args":["asset6","Christopher"]}'

# 结果
2020-09-25 09:20:48.086 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200

# 转换连接的节点
export CORE_PEER_TLS_ENABLED=true
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 chaincode query -C mychannel -n basic -c '{"Args":["ReadAsset","asset6"]}'

# 结果 拥有者改变了
{"ID":"asset6","color":"white","size":15,"owner":"Christopher","appraisedValue":800}

# 更多操作,请查看链码,路径前面已给出

# 关闭网络
./network.sh down

4.2 示例二:

fabcar这个示例程序,经久不衰,我最开始接触是1.0版本,2.2.0版本里面还有,自然得跑一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
cd ~/go/fabric/test/fabric-samples/fabcar
ls
go java javascript networkDown.sh startFabric.sh typescript

# 其中,重要的是startFabric.sh
# 打开简单看一下
vi startFabric.sh

# 核心代码
# 实际上调用了同目录test-network下的脚本
# 注意:./network.sh up,后面加了-ca参数,因此如果没有fabric-ca-client依赖,会提示找不到
# 具体是怎么用到bin目录下面的可执行文件的,可以研究test-network/network.sh,里面写的很清楚
# 部署链码的时候,已经执行实例化函数initLedger,后面就不需要实例化了,直接查询就行
pushd ../test-network
./network.sh down
./network.sh up createChannel -ca -s couchdb
./network.sh deployCC -ccn fabcar -ccv 1 -cci initLedger -ccl ${CC_SRC_LANGUAGE} -ccp ${CC_SRC_PATH}
popd

# 找到以下代码
# 如果$1存在且不为空,CC_SRC_LANGUAGE就是$1,如果$1不存在或为空,那么CC_SRC_LANGUAGE就是go
CC_SRC_LANGUAGE=${1:-"go"}
# startFabric.sh执行时,没有传入参数的话,默认执行go版本的链码
if [ "$CC_SRC_LANGUAGE" = "go" -o "$CC_SRC_LANGUAGE" = "golang" ]; then
CC_SRC_PATH="../chaincode/fabcar/go/"
# 链码路径 ../chaincode/fabcar/go/

# 退出
:q

# 跑一下
./startFabric.sh

# 基本上就是按照前面的三条核心命令执行的
# 慢慢等

结果:
执行结果

下来,就是按照提示走了,以go为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
cd go
go run fabcar.go

# 结果
[fabsdk/core] 2020/09/25 04:29:52 UTC - cryptosuite.GetDefault -> INFO No default cryptosuite found, using default SW implementation
[{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"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"}}]

{"make":"VW","model":"Polo","colour":"Grey","owner":"Mary"}
{"make":"VW","model":"Polo","colour":"Grey","owner":"Archie"}


cd ../../test-network/

# 设置环境变量
# 其余环境变量可以在fabcar目录下执行
# 但是CORE_PEER_TLS_ROOTCERT_FILE和CORE_PEER_MSPCONFIGPATH这两条必须在test-network目录下
# organizations里面的身份证书配置,只在test-network里面有,必须明确指定路径
export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/
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 chaincode query -C mychannel -n 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"}}]

# 更多操作,请查看链码

# 关闭网络
cd ../fabcar/
./networkDown.sh

5 参考

这两个过程,都写得极烂!一点都不舒服!

https://blog.csdn.net/qq_43681877/article/details/107399250
https://hyperledger-fabric.readthedocs.io/zh_CN/release-2.2/test_network.html

这个作为参考很好:

https://hyperledger-fabric.readthedocs.io/en/latest/test_network.html

6 提示

  • 环境变量设置,是临时有效,退出当前终端,环境变量失效,需要重新设置;也可以写在.bashrc、profile等文件中;
  • 研究好样例程序的shell脚本,可以学习到很多知识,包括shell语法、shell格式等,都让人受益匪浅;研究透了脚本,自然也就明白了fabric的搭建过程,以后就可以脱离脚本,手动搭建自己想要的网络。
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2020-2024 zhanglonglong
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信