文章目录
一、准备工作
在安装fabric之前,需要在本地安装如下工具:
- docker Version 20.10.8
- docker-compose version 1.29.2
- go1.16.12
二、安装fabric
1、下载fabric源码
mkdir -p $GOPATH/src/github.com/hyperledger
cd $GOPATH/src/github.com/hyperledger
git clone https://github.com/hyperledger/fabric.git
git checkout release-2.2
2、拉取fabric镜像以及二进制文件
运行bootstrap.sh脚本,自动拉取镜像以及安装二进制文件、和fabric-samples样例
cd fabric/scripts
chmod +x bootstrap.sh
./bootstrap.sh
三、运行测试网络test-network
在fabric/scripts目录下会生成一个fabric-samples文件夹,这个文件夹下面存放着fabric的测试用例
同时可以看到与网络相关的配置文件夹config和存放相应工具的bin文件夹
1 网络启动
cd fabric/scripts/fabric-samples/test-network
#启动测试网络
./network.sh up
得到如下响应则说明启动成功
Starting nodes with CLI timeout of '5' tries and CLI delay of '3' seconds and using database 'leveldb'
LOCAL_VERSION=2.2.10
DOCKER_IMAGE_VERSION=2.2.10
Creating peer0.org2.example.com ... done
Creating orderer.example.com ... done
Creating peer0.org1.example.com ... done
Creating cli ... done
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c0535d21465 hyperledger/fabric-tools:latest "/bin/bash" 1 second ago Up Less than a second cli
e3869714cd5e hyperledger/fabric-peer:latest "peer node start" 2 seconds ago Up Less than a second 0.0.0.0:9051->9051/tcp, :::9051->9051/tcp, 7051/tcp, 0.0.0.0:9445->9445/tcp, :::9445->9445/tcp peer0.org2.example.com
d84d80b46572 hyperledger/fabric-orderer:latest "orderer" 2 seconds ago Up Less than a second 0.0.0.0:7050->7050/tcp, :::7050->7050/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp orderer.example.com
9a472a2a1bfc hyperledger/fabric-peer:latest "peer node start" 2 seconds ago Up Less than a second 0.0.0.0:7051->7051/tcp, :::7051->7051/tcp, 0.0.0.0:9444->9444/tcp, :::9444->9444/tcp peer0.org1.example.com
2 网络情况查看
#查看所有创建的容器
docker ps -a
#查看镜像列表
docker images
# 删除镜像
docker rm 容器ID
# 删除所有镜像
docker rm $(docker ps -a -q)
# 一次性删除多个容器
docker ps -a -q | xargs docker rm
四、test-network网络交互
如果网络当前为启动状态,需要执行./network.sh down
命令进行关闭网络,并清空之前创建的容器,防止容器之间造成干扰,
1. 创建通道
./network.sh up createChannel
得到如下响应则证明成功,从响应中可以看出,该命令会先启动一个网络,之后并将两个组织Org1MSP
和Org2MSP
分别加入到名为mychannel
的通道中
Creating channel 'mychannel'.
If network is not up, starting nodes with CLI timeout of '5' tries and CLI delay of '3' seconds and using database 'leveldb with crypto from 'cryptogen'
Bringing up network
LOCAL_VERSION=2.2.10
DOCKER_IMAGE_VERSION=2.2.10
/Users/hanallen/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/test-network/../bin/cryptogen
Generating certificates using cryptogen tool
Creating Org1 Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-org1.yaml --output=organizations
org1.example.com
+ res=0
Creating Org2 Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-org2.yaml --output=organizations
org2.example.com
+ res=0
Creating Orderer Org Identities
+ cryptogen generate --config=./organizations/cryptogen/crypto-config-orderer.yaml --output=organizations
+ res=0
Generating CCP files for Org1 and Org2
/Users/hanallen/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/test-network/../bin/configtxgen
Generating Orderer Genesis block
+ configtxgen -profile TwoOrgsOrdererGenesis -channelID system-channel -outputBlock ./system-genesis-block/genesis.block
2023-04-19 21:34:35.272 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2023-04-19 21:34:35.283 CST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 002 orderer type: etcdraft
2023-04-19 21:34:35.283 CST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 Orderer.EtcdRaft.Options unset, setting to tick_interval:"500ms" election_tick:10 heartbeat_tick:1 max_inflight_blocks:5 snapshot_interval_size:16777216
2023-04-19 21:34:35.283 CST [common.tools.configtxgen.localconfig] Load -> INFO 004 Loaded configuration: /Users/hanallen/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/test-network/configtx/configtx.yaml
2023-04-19 21:34:35.286 CST [common.tools.configtxgen] doOutputBlock -> INFO 005 Generating genesis block
2023-04-19 21:34:35.286 CST [common.tools.configtxgen] doOutputBlock -> INFO 006 Writing genesis block
+ res=0
Creating network "fabric_test" with the default driver
Creating volume "docker_orderer.example.com" with default driver
Creating volume "docker_peer0.org1.example.com" with default driver
Creating volume "docker_peer0.org2.example.com" with default driver
Creating orderer.example.com ... done
Creating peer0.org1.example.com ... done
Creating peer0.org2.example.com ... done
Creating cli ... done
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c3f38be43bf hyperledger/fabric-tools:latest "/bin/bash" 1 second ago Up Less than a second cli
3d9475d3187c hyperledger/fabric-peer:latest "peer node start" 2 seconds ago Up Less than a second 0.0.0.0:9051->9051/tcp, :::9051->9051/tcp, 7051/tcp, 0.0.0.0:9445->9445/tcp, :::9445->9445/tcp peer0.org2.example.com
7b29e0348159 hyperledger/fabric-peer:latest "peer node start" 2 seconds ago Up Less than a second 0.0.0.0:7051->7051/tcp, :::7051->7051/tcp, 0.0.0.0:9444->9444/tcp, :::9444->9444/tcp peer0.org1.example.com
b29588afbcfe hyperledger/fabric-orderer:latest "orderer" 2 seconds ago Up Less than a second 0.0.0.0:7050->7050/tcp, :::7050->7050/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp orderer.example.com
Generating channel create transaction 'mychannel.tx'
+ configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/mychannel.tx -channelID mychannel
2023-04-19 21:34:37.824 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2023-04-19 21:34:37.830 CST [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /Users/hanallen/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/test-network/configtx/configtx.yaml
2023-04-19 21:34:37.830 CST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 003 Generating new channel configtx
2023-04-19 21:34:37.834 CST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 004 Writing new channel tx
+ res=0
Creating channel mychannel
Using organization 1
+ peer channel create -o localhost:7050 -c mychannel --ordererTLSHostnameOverride orderer.example.com -f ./channel-artifacts/mychannel.tx --outputBlock ./channel-artifacts/mychannel.block --tls --cafile /Users/hanallen/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
+ res=0
2023-04-19 21:34:40.893 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2023-04-19 21:34:40.917 CST [cli.common] readBlock -> INFO 002 Expect block, but got status: &{NOT_FOUND}
2023-04-19 21:34:40.922 CST [channelCmd] InitCmdFactory -> INFO 003 Endorser and orderer connections initialized
2023-04-19 21:34:41.129 CST [cli.common] readBlock -> INFO 004 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2023-04-19 21:34:41.135 CST [channelCmd] InitCmdFactory -> INFO 005 Endorser and orderer connections initialized
2023-04-19 21:34:41.342 CST [cli.common] readBlock -> INFO 006 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2023-04-19 21:34:41.348 CST [channelCmd] InitCmdFactory -> INFO 007 Endorser and orderer connections initialized
2023-04-19 21:34:41.556 CST [cli.common] readBlock -> INFO 008 Expect block, but got status: &{SERVICE_UNAVAILABLE}
2023-04-19 21:34:41.561 CST [channelCmd] InitCmdFactory -> INFO 009 Endorser and orderer connections initialized
2023-04-19 21:34:41.768 CST [cli.common] readBlock -> INFO 00a Expect block, but got status: &{SERVICE_UNAVAILABLE}
2023-04-19 21:34:41.772 CST [channelCmd] InitCmdFactory -> INFO 00b Endorser and orderer connections initialized
2023-04-19 21:34:41.982 CST [cli.common] readBlock -> INFO 00c Received block: 0
Channel 'mychannel' created
Joining org1 peer to the channel...
Using organization 1
+ peer channel join -b ./channel-artifacts/mychannel.block
+ res=0
2023-04-19 21:34:45.039 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2023-04-19 21:34:45.066 CST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
Joining org2 peer to the channel...
Using organization 2
+ peer channel join -b ./channel-artifacts/mychannel.block
+ res=0
2023-04-19 21:34:48.115 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2023-04-19 21:34:48.135 CST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
Setting anchor peer for org1...
Using organization 1
Fetching channel config for channel mychannel
Using organization 1
Fetching the most recent configuration block for the channel
+ peer channel fetch config config_block.pb -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2023-04-19 13:34:48.557 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2023-04-19 13:34:48.559 UTC [cli.common] readBlock -> INFO 002 Received block: 0
2023-04-19 13:34:48.559 UTC [channelCmd] fetch -> INFO 003 Retrieving last config block: 0
2023-04-19 13:34:48.561 UTC [cli.common] readBlock -> INFO 004 Received block: 0
Decoding config block to JSON and isolating config to Org1MSPconfig.json
+ configtxlator proto_decode --input config_block.pb --type common.Block
+ jq '.data.data[0].payload.data.config'
+ jq '.channel_group.groups.Application.groups.Org1MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org1.example.com","port": 7051}]},"version": "0"}}' Org1MSPconfig.json
Generating anchor peer update transaction for Org1 on channel mychannel
+ configtxlator proto_encode --input Org1MSPconfig.json --type common.Config
+ configtxlator proto_encode --input Org1MSPmodified_config.json --type common.Config
+ configtxlator compute_update --channel_id mychannel --original original_config.pb --updated modified_config.pb
+ configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate
++ + jq cat config_update.json
.
+ echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":{' '"channel_id":' '"mychannel",' '"isolated_data":' '{},' '"read_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org1MSP":' '{' '"groups":' '{},' '"mod_policy":' '"",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '},' '"write_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org1MSP":' '{' '"groups":' '{},' '"mod_policy":' '"Admins",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"AnchorPeers":' '{' '"mod_policy":' '"Admins",' '"value":' '{' '"anchor_peers":' '[' '{' '"host":' '"peer0.org1.example.com",' '"port":' 7051 '}' ']' '},' '"version":' '"0"' '},' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '}}}}'
+ configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope
2023-04-19 13:34:48.879 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2023-04-19 13:34:48.897 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
Anchor peer set for org 'Org1MSP' on channel 'mychannel'
Setting anchor peer for org2...
Using organization 2
Fetching channel config for channel mychannel
Using organization 2
Fetching the most recent configuration block for the channel
+ peer channel fetch config config_block.pb -o orderer.example.com:7050 --ordererTLSHostnameOverride orderer.example.com -c mychannel --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
2023-04-19 13:34:49.284 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2023-04-19 13:34:49.287 UTC [cli.common] readBlock -> INFO 002 Received block: 1
2023-04-19 13:34:49.287 UTC [channelCmd] fetch -> INFO 003 Retrieving last config block: 1
2023-04-19 13:34:49.289 UTC [cli.common] readBlock -> INFO 004 Received block: 1
Decoding config block to JSON and isolating config to Org2MSPconfig.json
+ configtxlator proto_decode --input config_block.pb --type common.Block
+ jq '.data.data[0].payload.data.config'
Generating anchor peer update transaction for Org2 on channel mychannel
+ jq '.channel_group.groups.Application.groups.Org2MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org2.example.com","port": 9051}]},"version": "0"}}' Org2MSPconfig.json
+ configtxlator proto_encode --input Org2MSPconfig.json --type common.Config
+ configtxlator proto_encode --input Org2MSPmodified_config.json --type common.Config
+ configtxlator compute_update --channel_id mychannel --original original_config.pb --updated modified_config.pb
+ configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate
+ jq .
++ cat config_update.json
+ echo '{"payload":{"header":{"channel_header":{"channel_id":"mychannel", "type":2}},"data":{"config_update":{' '"channel_id":' '"mychannel",' '"isolated_data":' '{},' '"read_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org2MSP":' '{' '"groups":' '{},' '"mod_policy":' '"",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '},' '"write_set":' '{' '"groups":' '{' '"Application":' '{' '"groups":' '{' '"Org2MSP":' '{' '"groups":' '{},' '"mod_policy":' '"Admins",' '"policies":' '{' '"Admins":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Endorsement":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Readers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '},' '"Writers":' '{' '"mod_policy":' '"",' '"policy":' null, '"version":' '"0"' '}' '},' '"values":' '{' '"AnchorPeers":' '{' '"mod_policy":' '"Admins",' '"value":' '{' '"anchor_peers":' '[' '{' '"host":' '"peer0.org2.example.com",' '"port":' 9051 '}' ']' '},' '"version":' '"0"' '},' '"MSP":' '{' '"mod_policy":' '"",' '"value":' null, '"version":' '"0"' '}' '},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"1"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '}}}}'
+ configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope
2023-04-19 13:34:49.544 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
export NVM_DIR="$HOME/.nvm"
2023-04-19 13:34:49.562 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
Anchor peer set for org 'Org2MSP' on channel 'mychannel'
Channel 'mychannel' joined
2.链码打包
首先设置环境变量,将fabric-samples/bin目录下的命令添加到环境变量中来
export PATH=${PWD}/../bin:$PATH
export FABRIC_CFG_PATH=$PWD/../config/
检查当前的peer版本
peer version
得到如下输出
peer:
Version: 2.2.10
Commit SHA: 8eef196
Go version: go1.18.7
OS/Arch: darwin/amd64
Chaincode:
Base Docker Label: org.hyperledger.fabric
Docker Namespace: hyperledger
链码在安装之前先要对待安装的链码进行打包,管理员可以使用peer lifecycle chaincode package
子命令打包链码,并在当前路径下会生成一个名为fabcar.tar.gz
的文件。
# --path 表示待打包链码的存放位置,
# --label 表示为链码打标签,以便后续使用该标签引用这个链码包
peer lifecycle chaincode package fabcar.tar.gz --path ../chaincode/fabcar/java/build/install/fabcar --lang java --label fabcar_1
3 安装链码
该网络一共有两个组织,需要分别在每个组织的节点上完成链码的安装工作,同时安装操作需要是Peer认可的组织管理员身份来运行(证书在Peer的admincerts目录下存在)。
3.1 Org1安装链码
首先在Org1中的peer节点上安装链码,需要设置环境变量以 Org1 管理员用户身份操作
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
在org1中的peer0节点上安装链码
peer lifecycle chaincode install fabcar.tar.gz
得到如下的响应
2023-04-20 09:01:32.468 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nIfabcar_1:30dc7e3588549452fccb2a4fca5db2c268e0177d3f25b1b81d015fe0b0234a08\022\010fabcar_1" >
2023-04-20 09:01:32.472 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: fabcar_1:30dc7e3588549452fccb2a4fca5db2c268e0177d3f25b1b81d015fe0b0234a08
3.2 Org2安装链码
设置环境变量以 Org12管理员用户身份操作
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
在org2中的peer0节点上安装链码
peer lifecycle chaincode install fabcar.tar.gz
得到如下响应
2023-04-20 09:06:43.998 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nIfabcar_1:30dc7e3588549452fccb2a4fca5db2c268e0177d3f25b1b81d015fe0b0234a08\022\010fabcar_1" >
2023-04-20 09:06:43.998 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: fabcar_1:30dc7e3588549452fccb2a4fca5db2c268e0177d3f25b1b81d015fe0b0234a08
3.3 查询当前节点已经安装的链码
peer lifecycle chaincode queryinstalled
得到如下响应
Installed chaincodes on peer:
Package ID: fabcar_1:30dc7e3588549452fccb2a4fca5db2c268e0177d3f25b1b81d015fe0b0234a08, Label: fabcar_1
4 链码认证
链码安装完成之后需要被组织认证,认证通过之后才能将链码提交并运行,该过程又可以称为合约定义,定义了合约的名称、版本、序列号,后续合约升级即修改版本或序列号,重新定义合约。
注意,之前的操作中一共是开了两个终端,一个终端是Org1,一个终端是Org2,分别在每个终端中进行了环境变量的设置,接下来的操作,在哪个终端中执行,就代表是哪个组中在进行链码的认证,如果在一个终端中执行上述所有操作,需要频繁切换身份并设置环境变量,因此建议有几个节点就开几个终端,然后设置一次环境变量就可以了,无需反复设置。在这里面由于我上面开了两个终端,
因此在这个下面的过程中,我无需再去设置3.1 和3.2 安装链码时所进行的环境变量的操作
,如果你是一个终端在进行,那么接下来仍旧需要设置环境变量,以进行节点身份的切换。
4.1 Org1进行链码认证
首先设置环境变量Package ID
export CC_PACKAGE_ID=fabcar_1:30dc7e3588549452fccb2a4fca5db2c268e0177d3f25b1b81d015fe0b0234a08
然后执行peer lifecycle chaincode approveformyorg
子命令,代表所在机构审批链码
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
得到如下响应
2023-04-20 09:44:07.240 CST [chaincodeCmd] ClientWait -> INFO 001 txid [9049f47ef4f3c1f62349e15d59a3c6f24c8ebf8502c756fa44d8419cbfeef8d2] committed with status (VALID) at localhost:7051
最后查看链码认证结果,执行如下命令:
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.2 Org2进行链码认证
设置环境变量Package ID
export CC_PACKAGE_ID=fabcar_1:30dc7e3588549452fccb2a4fca5db2c268e0177d3f25b1b81d015fe0b0234a08
执行peer lifecycle chaincode approveformyorg
子命令审批链码
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
得到如下响应
2023-04-20 09:43:03.697 CST [chaincodeCmd] ClientWait -> INFO 001 txid [c394ad7530dc5d0f9a0dc0ac98aac0513918b548dbfd4b241da04806de8663de] committed with status (VALID) at localhost:9051
最后查看链码认证结果,具体步骤同4.1则在这里不在进行赘述。
5 提交链码
通道内链码得到足够多的组织批准后,将成为可以合法运行的链码,此时,任意通道内组织可以使用commit子命令发起提交操作。链码定义被成功提交到通道后,通道内成员可以调用链码。
使用peer lifecycle chaincode 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
得到的响应为
2023-04-20 09:49:33.684 CST [chaincodeCmd] ClientWait -> INFO 001 txid [7811a2a283f10357b2bc66df2920eedbc249b9e5733fe27c255114dc0df88427] committed with status (VALID) at localhost:9051
2023-04-20 09:49:33.684 CST [chaincodeCmd] ClientWait -> INFO 002 txid [7811a2a283f10357b2bc66df2920eedbc249b9e5733fe27c255114dc0df88427] committed with status (VALID) at localhost:7051
通过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]
6 调用链码
以Org1中俄peer节点为例调用链码
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":[]}'
得到的响应为
2023-04-20 09:50:16.754 CST [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
使用查询函数来读取由链码创建的汽车集
peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'
得到的响应为
[{"key":"CAR1","record":{"color":"red","make":"Ford","model":"Mustang","owner":"Brad"}},{"key":"CAR2","record":{"color":"green","make":"Hyundai","model":"Tucson","owner":"Jin Soo"}},{"key":"CAR3","record":{"color":"yellow","make":"Volkswagen","model":"Passat","owner":"Max"}},{"key":"CAR4","record":{"color":"black","make":"Tesla","model":"S","owner":"Adrian"}},{"key":"CAR5","record":{"color":"purple","make":"Peugeot","model":"205","owner":"Michel"}},{"key":"CAR6","record":{"color":"white","make":"Chery","model":"S22L","owner":"Aarav"}},{"key":"CAR7","record":{"color":"violet","make":"Fiat","model":"Punto","owner":"Pari"}},{"key":"CAR8","record":{"color":"indigo","make":"Tata","model":"nano","owner":"Valeria"}},{"key":"CAR9","record":{"color":"brown","make":"Holden","model":"Barina","owner":"Shotaro"}}]
五 环境变量总结
为了方便可以将直接将fabric-samples/bin目录添加到环境变量,并写入到 /etc/profile中
vi /etc/profile
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin:/root/fabric-samples/bin
source /etc/profile
或者在命令行设置环境变量
$ export PATH=${PWD}/../bin:$PATH
$ export FABRIC_CFG_PATH=$PWD/../config/
# Environment variables for Org1
$ 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
总结
该文是对fabric环境部署以及测试网络搭建的一个简要说明,为后续通过caliper对fabric的性能测试实验做准备。