Centos7.6部署fabric以及链码

urlyy

参考
Fabric学习
Fabric2.2 全面学习

如果是最小化安装

1
2
3
4
遇到找不到命令时,自行用yum安装

yum install vim
yum install wget

环境

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
yum -y install git 		
git --version


yum -y install curl
curl --version


sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo


sudo yum install docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
sudo systemctl enable docker
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://ppztf0yr.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker


curl -L https://get.daocloud.io/docker/compose/releases/download/1.26.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
docker-compose version

cd /usr/local
wget https://studygolang.com/dl/golang/go1.14.7.linux-amd64.tar.gz
tar -zxvf go1.14.7.linux-amd64.tar.gz


vim /etc/profile
# 添加如下
#export GOROOT=/usr/local/go
#export GOPATH=$HOME/go
#export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
source /etc/profile

go version
go env -w GO111MODULE=on
go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/

安装fabric-samples

1
2
3
4
cd /usr/local
mkdir hyperledger
cd hyperledger
touch bootstrap.sh

我这里给出bootstrap.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
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#!/bin/bash
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

# if version not passed in, default to latest released version
VERSION=2.2.0
# if ca version not passed in, default to latest released version
CA_VERSION=1.4.8
ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m |sed 's/x86_64/amd64/g')" |sed 's/darwin-arm64/darwin-amd64/g')
MARCH=$(uname -m)
: ${CONTAINER_CLI:="docker"}

printHelp() {
echo "Usage: bootstrap.sh [version [ca_version]] [options]"
echo
echo "options:"
echo "-h : this help"
echo "-d : bypass docker image download"
echo "-s : bypass fabric-samples repo clone"
echo "-b : bypass download of platform-specific binaries"
echo
echo "e.g. bootstrap.sh 2.4.6 1.5.5 -s"
echo "will download docker images and binaries for Fabric v2.4.6 and Fabric CA v1.5.5"
}

# dockerPull() pulls docker images from fabric and chaincode repositories
# note, if a docker image doesn't exist for a requested release, it will simply
# be skipped, since this script doesn't terminate upon errors.

dockerPull() {
#three_digit_image_tag is passed in, e.g. "1.4.7"
three_digit_image_tag=$1
shift
#two_digit_image_tag is derived, e.g. "1.4", especially useful as a local tag for two digit references to most recent baseos, ccenv, javaenv, nodeenv patch releases
two_digit_image_tag=$(echo "$three_digit_image_tag" | cut -d'.' -f1,2)
while [[ $# -gt 0 ]]
do
image_name="$1"
echo "====> hyperledger/fabric-$image_name:$three_digit_image_tag"
${CONTAINER_CLI} pull "hyperledger/fabric-$image_name:$three_digit_image_tag"
${CONTAINER_CLI} tag "hyperledger/fabric-$image_name:$three_digit_image_tag" "hyperledger/fabric-$image_name"
${CONTAINER_CLI} tag "hyperledger/fabric-$image_name:$three_digit_image_tag" "hyperledger/fabric-$image_name:$two_digit_image_tag"
shift
done
}

cloneSamplesRepo() {
# clone (if needed) hyperledger/fabric-samples and checkout corresponding
# version to the binaries and docker images to be downloaded
if [ -d test-network ]; then
# if we are in the fabric-samples repo, checkout corresponding version
echo "==> Already in fabric-samples repo"
elif [ -d fabric-samples ]; then
# if fabric-samples repo already cloned and in current directory,
# cd fabric-samples
echo "===> Changing directory to fabric-samples"
cd fabric-samples
else
echo "===> Cloning hyperledger/fabric-samples repo"
git clone -b main https://github.com/hyperledger/fabric-samples.git && cd fabric-samples
fi

if GIT_DIR=.git git rev-parse v${VERSION} >/dev/null 2>&1; then
echo "===> Checking out v${VERSION} of hyperledger/fabric-samples"
git checkout -q v${VERSION}
else
echo "fabric-samples v${VERSION} does not exist, defaulting to main. fabric-samples main branch is intended to work with recent versions of fabric."
git checkout -q main
fi
}

# This will download the .tar.gz
download() {
local BINARY_FILE=$1
local URL=$2
echo "===> Downloading: " "${URL}"
curl -L --retry 5 --retry-delay 3 "${URL}" | tar xz || rc=$?
if [ -n "$rc" ]; then
echo "==> There was an error downloading the binary file."
return 22
else
echo "==> Done."
fi
}

pullBinaries() {
echo "===> Downloading version ${FABRIC_TAG} platform specific fabric binaries"
download "${BINARY_FILE}" "https://github.com/hyperledger/fabric/releases/download/v${VERSION}/${BINARY_FILE}"
if [ $? -eq 22 ]; then
echo
echo "------> ${FABRIC_TAG} platform specific fabric binary is not available to download <----"
echo
exit
fi

echo "===> Downloading version ${CA_TAG} platform specific fabric-ca-client binary"
download "${CA_BINARY_FILE}" "https://github.com/hyperledger/fabric-ca/releases/download/v${CA_VERSION}/${CA_BINARY_FILE}"
if [ $? -eq 22 ]; then
echo
echo "------> ${CA_TAG} fabric-ca-client binary is not available to download (Available from 1.1.0-rc1) <----"
echo
exit
fi
}

pullDockerImages() {
command -v ${CONTAINER_CLI} >& /dev/null
NODOCKER=$?
if [ "${NODOCKER}" == 0 ]; then
FABRIC_IMAGES=(peer orderer ccenv tools)
case "$VERSION" in
2.*)
FABRIC_IMAGES+=(baseos)
shift
;;
esac
echo "FABRIC_IMAGES:" "${FABRIC_IMAGES[@]}"
echo "===> Pulling fabric Images"
dockerPull "${FABRIC_TAG}" "${FABRIC_IMAGES[@]}"
echo "===> Pulling fabric ca Image"
CA_IMAGE=(ca)
dockerPull "${CA_TAG}" "${CA_IMAGE[@]}"
echo "===> List out hyperledger docker images"
${CONTAINER_CLI} images | grep hyperledger
else
echo "========================================================="
echo "${CONTAINER_CLI} not installed, bypassing download of Fabric images"
echo "========================================================="
fi
}

DOCKER=true
SAMPLES=true
BINARIES=true

# Parse commandline args pull out
# version and/or ca-version strings first
if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
VERSION=$1;shift
if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
CA_VERSION=$1;shift
if [ -n "$1" ] && [ "${1:0:1}" != "-" ]; then
THIRDPARTY_IMAGE_VERSION=$1;shift
fi
fi
fi

# prior to 1.2.0 architecture was determined by uname -m
if [[ $VERSION =~ ^1\.[0-1]\.* ]]; then
export FABRIC_TAG=${MARCH}-${VERSION}
export CA_TAG=${MARCH}-${CA_VERSION}
export THIRDPARTY_TAG=${MARCH}-${THIRDPARTY_IMAGE_VERSION}
else
# starting with 1.2.0, multi-arch images will be default
: "${CA_TAG:="$CA_VERSION"}"
: "${FABRIC_TAG:="$VERSION"}"
: "${THIRDPARTY_TAG:="$THIRDPARTY_IMAGE_VERSION"}"
fi

BINARY_FILE=hyperledger-fabric-${ARCH}-${VERSION}.tar.gz
CA_BINARY_FILE=hyperledger-fabric-ca-${ARCH}-${CA_VERSION}.tar.gz

# then parse opts
while getopts "h?dsb" opt; do
case "$opt" in
h|\?)
printHelp
exit 0
;;
d) DOCKER=false
;;
s) SAMPLES=false
;;
b) BINARIES=false
;;
esac
done

if [ "$SAMPLES" == "true" ]; then
echo
echo "Clone hyperledger/fabric-samples repo"
echo
cloneSamplesRepo
fi
if [ "$BINARIES" == "true" ]; then
echo
echo "Pull Hyperledger Fabric binaries"
echo
pullBinaries
fi
if [ "$DOCKER" == "true" ]; then
echo
echo "Pull Hyperledger Fabric docker images"
echo
pullDockerImages
fi

运行下载程序
注意最后这三个if...fi,分别是克隆fabric-samples文件夹、获得bin和config文件夹、拉取镜像的作用
其中pullBinaries耗时最长,最易出错,最易搞心态,建议单独执行(或者往下面看)
即可以先将137行的BINARIES=true改为BINARIES=false,执行bootstrap.sh,再重新设BINARIES=true,并将其他两个设为false,再执行bootstrap.sh,并将第二次获得到的bin和config目录移入fabric-samples文件夹内
如果出现

可以出现/bin/bash^M: 坏的解释器: 没有那个文件或目录,解决方案如下:
在这里插入图片描述

如果克隆fabric-samples失败,即设SAMPLES=true并运行后无fabric-samples文件夹出现,则自己手动安装(因为这个也挺花时间的)

1
2
3
4
git clone -b main https://github.com/hyperledger/fabric-samples.git
cd fabric-samples
git checkout -q v2.2.0
git checkout -b branch

如果下载二进制文件的时间很长很长,可以考虑在windows上通过Github直接下好再上传到服务器上,因为shell里下载的方法就是git。将这两个文件在/usr/local/hyperledger/下载并解压

1
2
3
4
5
6
第一个下载的
wget https://github.com/hyperledger/fabric/releases/download/v2.2.0/hyperledger-fabric-linux-amd64-2.2.0.tar.gz
第二个下载的
wget https://github.com/hyperledger/fabric-ca/releases/download/v1.4.8/hyperledger-fabric-ca-linux-amd64-1.4.8.tar.gz
tar -zxvf hyperledger-fabric-linux-amd64-2.2.0.tar.gz
tar -zxvf hyperledger-fabric-ca-linux-amd64-1.4.8.tar.gz

我们继续放命令

1
2
3
4
5
6
7
8
9
chmod +X bootstrap.sh
./bootstrap.sh
mv config/ fabric-samples/
mv bin/ fabric-samples/
vim /etc/profile
# 添加如下
#export PATH=$PATH:/usr/local/hyperledger/fabric-samples/bin
source /etc/profile
fabric-ca-client version

使用测试网络

1
2
cd /usr/local/hyperledger/fabric-samples/test-network
./network.sh up createChannel

注意上面有可能报错,无报错的 跳转

1
2
3
4
ERROR: The Compose file './docker/docker-compose-test-net.yaml' is invalid because:
networks.test value Additional properties are not allowed ('name' was unexpected)
ERROR: The Compose file './addOrg3/docker/docker-compose-couch-org3.yaml' is invalid because:
networks.test value Additional properties are not allowed ('name' was unexpected)

此时需要将
/usr/local/hyperledger/fabric-samples/test-network/docker/docker-compose-test-net.yaml

的13、14、15行改为
在这里插入图片描述

并将59、96行的fabric_test改为docker_test
在这里插入图片描述
再将文件夹/usr/local/hyperledger/fabric-samples/test-network/下的

1
2
3
4
5
docker/docker-compose-couch.yaml
docker/docker-compose-ca.yaml
addOrg3/docker/docker-compose-org3.yaml
addOrg3/docker/docker-compose-couch-org3.yaml
addOrg3/docker/docker-compose-ca-org3.yaml

的第一个networks也改成
在这里插入图片描述
然后再

1
2
./network.sh down
./network.sh up createChannel

就行了

正常后我们继续,当前路径为/usr/local/hyperledger/fabric-samples/test-network

1
2
# 部署链码
./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go

可能会有下面的报错,此时要去这个链码包下删除mod并重新tidy
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
cd ../asset-transfer-basic/chaincode-go
rm -f go.sum
go env -w GOSUMDB=off
go mod tidy
go env -w GOSUMDB=GOSUMDB="sum.golang.org"

# 重新开启
./network.sh down
./network.sh up createChannel
./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl 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
vim /etc/profile
# 添加如下
# export PATH=/usr/local/hyperledger/fabric-samples/bin:$PATH
# export FABRIC_CFG_PATH=/usr/local/hyperledger/fabric-samples/config/
source /etc/profile


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 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":[]}'
# 输出
#-> 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}
#]


# 测试网络搭建成功
# 关闭网络
./network.sh down

编写自己的链码

1
2
3
4
cd /usr/local/hyperledger/fabric-samples/asset-transfer-basic
mkdir atcc && cd atcc
go mod init atcc
touch atcc.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
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
package main

import (
"encoding/json"
"fmt"
"log"
"github.com/hyperledger/fabric-contract-api-go/contractapi"
)

// SmartContract provides functions for managing an Asset
type SmartContract struct {
contractapi.Contract
}

// Asset describes basic details of what makes up a simple asset
type Asset struct {
ID string `json:"ID"`
Owner string `json:"owner"`
Value int `json:"Value"`
}

// InitLedger adds a base set of assets to the ledger
func (s *SmartContract) InitLedger(ctx contractapi.TransactionContextInterface) error {
assets := []Asset{
{ID: "asset1", Owner: "ZhangSan", Value: 300},
{ID: "asset2", Owner: "LiSi", Value: 400},
{ID: "asset3", Owner: "Klay", Value: 500},
}

for _, asset := range assets {
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}

err = ctx.GetStub().PutState(asset.ID, assetJSON)
if err != nil {
return fmt.Errorf("failed to put to world state. %v", err)
}
}

return nil
}

// CreateAsset issues a new asset to the world state with given details.
func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, id string, owner string, Value int) error {
exists, err := s.AssetExists(ctx, id)
if err != nil {
return err
}
if exists {
return fmt.Errorf("the asset %s already exists", id)
}

asset := Asset{
ID: id,
Owner: owner,
Value: Value,
}
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}

return ctx.GetStub().PutState(id, assetJSON)
}

// ReadAsset returns the asset stored in the world state with given id.
func (s *SmartContract) ReadAsset(ctx contractapi.TransactionContextInterface, id string) (*Asset, error) {
assetJSON, err := ctx.GetStub().GetState(id)
if err != nil {
return nil, fmt.Errorf("failed to read from world state: %v", err)
}
if assetJSON == nil {
return nil, fmt.Errorf("the asset %s does not exist", id)
}

var asset Asset
err = json.Unmarshal(assetJSON, &asset)
if err != nil {
return nil, err
}

return &asset, nil
}

// UpdateAsset updates an existing asset in the world state with provided parameters.
func (s *SmartContract) UpdateAsset(ctx contractapi.TransactionContextInterface, id string, owner string, Value int) error {
exists, err := s.AssetExists(ctx, id)
if err != nil {
return err
}
if !exists {
return fmt.Errorf("the asset %s does not exist", id)
}

// overwriting original asset with new asset
asset := Asset{
ID: id,
Owner: owner,
Value: Value,
}
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}

return ctx.GetStub().PutState(id, assetJSON)
}

// DeleteAsset deletes an given asset from the world state.
func (s *SmartContract) DeleteAsset(ctx contractapi.TransactionContextInterface, id string) error {
exists, err := s.AssetExists(ctx, id)
if err != nil {
return err
}
if !exists {
return fmt.Errorf("the asset %s does not exist", id)
}

return ctx.GetStub().DelState(id)
}

// AssetExists returns true when asset with given ID exists in world state
func (s *SmartContract) AssetExists(ctx contractapi.TransactionContextInterface, id string) (bool, error) {
assetJSON, err := ctx.GetStub().GetState(id)
if err != nil {
return false, fmt.Errorf("failed to read from world state: %v", err)
}

return assetJSON != nil, nil
}

// TransferAsset updates the owner field of asset with given id in world state.
func (s *SmartContract) TransferAsset(ctx contractapi.TransactionContextInterface, id string, newOwner string) error {
asset, err := s.ReadAsset(ctx, id)
if err != nil {
return err
}

asset.Owner = newOwner
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}

return ctx.GetStub().PutState(id, assetJSON)
}

// GetAllAssets returns all assets found in world state
func (s *SmartContract) GetAllAssets(ctx contractapi.TransactionContextInterface) ([]*Asset, error) {
// range query with empty string for startKey and endKey does an
// open-ended query of all assets in the chaincode namespace.
resultsIterator, err := ctx.GetStub().GetStateByRange("", "")
if err != nil {
return nil, err
}
defer resultsIterator.Close()

var assets []*Asset
for resultsIterator.HasNext() {
queryResponse, err := resultsIterator.Next()
if err != nil {
return nil, err
}

var asset Asset
err = json.Unmarshal(queryResponse.Value, &asset)
if err != nil {
return nil, err
}
assets = append(assets, &asset)
}

return assets, nil
}

func main() {
assetChaincode, err := contractapi.NewChaincode(&SmartContract{})
if err != nil {
log.Panicf("Error creating asset-transfer-basic chaincode: %v", err)
}

if err := assetChaincode.Start(); err != nil {
log.Panicf("Error starting asset-transfer-basic chaincode: %v", err)
}
}

处理项目依赖

1
2
go mod tidy
go mod vendor

使用测试网络进行链码部署

当前位置:/usr/local/hyperledger/fabric-samples/test-network

1
2
3
4
5
6
7
8
9
10
11
12
./network.sh down
./network.sh up createChannel

# 注意下面那个尖括号的玩意要替换为自定义的链码文件夹名,设为环境变量只是为了方便操作,比如我这里就要换为export CHAINCODE_NAME=atcc
export CHAINCODE_NAME=<chaincode-name>

peer lifecycle chaincode package 打包后的压缩包名.tar.gz --path ../asset-transfer-basic/$CHAINCODE_NAME/ --lang golang --label atcc_1.0

peer lifecycle chaincode package $CHAINCODE_NAME.tar.gz \
--path ../asset-transfer-basic/$CHAINCODE_NAME/ \ #注意替换链码文件路径
--lang golang \
--label <chaincode-name>_1.0 #注意替换<chaincode-name>内容
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
./network.sh down
./network.sh up createChannel



export CHAINCODE_NAME=flower_fabric


peer lifecycle chaincode package $CHAINCODE_NAME.tar.gz --path $CHAINCODE_NAME/ --lang golang --label flower_fabric_1.0


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 $CHAINCODE_NAME.tar.gz


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_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 $CHAINCODE_NAME.tar.gz




# 查询包ID
peer lifecycle chaincode queryinstalled


export CC_PACKAGE_ID=<Package ID> #注意替换这里的链码包ID
export CC_PACKAGE_ID=atcc_1.0:5657426d49d01aadeaabfd8ea13fa7f431931702f534120335ead5acd107e8cd


peer lifecycle chaincode approveformyorg \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name $CHAINCODE_NAME \
--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


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 $CHAINCODE_NAME \
--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

peer lifecycle chaincode checkcommitreadiness \
--channelID mychannel \
--name $CHAINCODE_NAME \
--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

peer lifecycle chaincode commit \
-o localhost:7050 \
--ordererTLSHostnameOverride orderer.example.com \
--channelID mychannel \
--name $CHAINCODE_NAME \
--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

peer lifecycle chaincode querycommitted \
--channelID mychannel \
--name $CHAINCODE_NAME \
--cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem


echo "链码安装完毕,下面为测试代码"


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 $CHAINCODE_NAME \
--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":[]}'


peer chaincode query \
-C mychannel \
-n $CHAINCODE_NAME \
-c '{"Args":["getAllAssets"]}'

记录一下我自己的链码的测试代码

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
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 $CHAINCODE_NAME \
--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":"CreateWallet","Args":["1"]}'




peer chaincode query \
-C mychannel \
-n $CHAINCODE_NAME \
-c '{"Args":["getAllWallets"]}'


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 $CHAINCODE_NAME \
--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":"UpdateWalletIntegral","Args":["1","20","a"]}'




peer chaincode query \
-C mychannel \
-n $CHAINCODE_NAME \
-c '{"Args":["getAllWallets"]}'

peer chaincode query \
-C mychannel \
-n $CHAINCODE_NAME \
-c '{"Args":["ReadWallet","1"]}'

peer chaincode query \
-C mychannel \
-n $CHAINCODE_NAME \
-c '{"Args":["ReadHistory","1"]}'





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 $CHAINCODE_NAME \
--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":[]}'
  • 标题: Centos7.6部署fabric以及链码
  • 作者: urlyy
  • 创建于 : 2022-09-14 12:56:58
  • 更新于 : 2023-06-19 13:31:16
  • 链接: https://urlyy.github.io/2022/09/14/Centos7-6部署fabric以及链码/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。