教程
一.注意事项
确保通道名称应用以下限制:
- 仅包含小写 ASCII 字母数字、点“.”和破折号“-”
- 少于 250 个字符
- 以字母开头
## 安装telnet
#[fabric@localhost test-network]$ rpm -qa |grep telnet
#[fabric@localhost test-network]$ sudo yum -y install telnet telnet-server
## 关闭防火墙
[fabric@localhost test-network]$ sudo systemctl stop firewalld.service
# [fabric@localhost test-network]$ sudo systemctl stop firewalld
## 禁止开机自启动
[fabric@localhost test-network]$ sudo systemctl disable firewalld.service
## 查看状态
[fabric@localhost test-network]$ systemctl status firewalld.service
## docker 重启
[fabric@localhost test-network]$ sudo systemctl restart docker
############## hyperledger fabric 2.3.3 测试网络 ############
[fabric@localhost ~] cd /home/fabric/go/src/github.com/hyperledger/fabric-samples/test-network
## 1.启动网络
[fabric@localhost test-network]$ ./network.sh up
## 2.创建通道
[fabric@localhost test-network]$ ./network.sh createChannel
## 上述步骤可合并
#[fabric@localhost test-network]$ ./network.sh up createChannel
## 创建名为channel1的通道
[fabric@localhost test-network]$ ./network.sh createChannel -c channel1
## 创建名为channel2的通道
[fabric@localhost test-network]$ ./network.sh createChannel -c channel2
## 3.在通道上启动链码
[fabric@localhost test-network]$ ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go
## 4.网络交互
# 设置环境变量
[fabric@localhost 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
## 5.运行以下命令以使用资产初始化分类帐
[fabric@localhost test-network]$ 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":[]}'
## 6. CLI 查询分类帐资产列表
[fabric@localhost test-network]$ peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'
## 7.转移或更改分类帐上的资产
[fabric@localhost test-network]$ 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"]}'
## 资产转移(基本)链码的背书策略要求交易由 Org1 和 Org2 签名,所以链码调用命令需要针对两者 peer0.org1.example.com并peer0.org2.example.com使用--peerAddresses 标志。由于为网络启用了 TLS,因此该命令还需要使用该--tlsRootCertFiles标志为每个对等方引用 TLS 证书
[fabric@localhost test-network]$ 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
## 8.查询运行在peer0.org2.example.com的资产转移(基本)链码
[fabric@localhost test-network]$ peer chaincode query -C mychannel -n basic -c '{"Args":["ReadAsset","asset6"]}'
## 9.关闭网络
[fabric@localhost test-network]$ ./network.sh down
三.日志信息
1.启动网络
[fabric@localhost test-network]$ ./network.sh up Starting nodes with CLI timeout of '5' tries and CLI delay of '3' seconds and using database 'leveldb' with crypto from 'cryptogen' LOCAL_VERSION=2.3.3 DOCKER_IMAGE_VERSION=2.3.3 /home/fabric/go/src/github.com/hyperledger/fabric-samples/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 Creating network "net_test" with the default driver Creating volume "net_orderer.example.com" with default driver Creating volume "net_peer0.org1.example.com" with default driver Creating volume "net_peer0.org2.example.com" with default driver Creating peer0.org1.example.com ... done Creating peer0.org2.example.com ... done Creating orderer.example.com ... done Creating cli ... done CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 411f54b12472 hyperledger/fabric-tools:latest "/bin/bash" 1 second ago Up Less than a second cli 3a07afa008b5 hyperledger/fabric-peer:latest "peer node start" 3 seconds ago Up 1 second 7051/tcp, 0.0.0.0:9051->9051/tcp peer0.org2.example.com ef86495448a7 hyperledger/fabric-orderer:latest "orderer" 3 seconds ago Up 1 second 0.0.0.0:7050->7050/tcp, 0.0.0.0:7053->7053/tcp orderer.example.com 8e2e415f22d1 hyperledger/fabric-peer:latest "peer node start" 3 seconds ago Up 1 second 0.0.0.0:7051->7051/tcp peer0.org1.example.com2.创建通道
[fabric@localhost test-network]$ ./network.sh createChannel
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
Generating channel genesis block 'mychannel.block'
/home/fabric/go/src/github.com/hyperledger/fabric-samples/bin/configtxgen
+ configtxgen -profile TwoOrgsApplicationGenesis -outputBlock ./channel-artifacts/mychannel.block -channelID mychannel
2022-05-03 18:09:48.120 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2022-05-03 18:09:48.167 CST [common.tools.configtxgen.localconfig] completeInitialization -> INFO 002 orderer type: etcdraft
2022-05-03 18:09:48.167 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
2022-05-03 18:09:48.167 CST [common.tools.configtxgen.localconfig] Load -> INFO 004 Loaded configuration: /home/fabric/go/src/github.com/hyperledger/fabric-samples/test-network/configtx/configtx.yaml
2022-05-03 18:09:48.169 CST [common.tools.configtxgen] doOutputBlock -> INFO 005 Generating genesis block
2022-05-03 18:09:48.169 CST [common.tools.configtxgen] doOutputBlock -> INFO 006 Creating application channel genesis block
2022-05-03 18:09:48.170 CST [common.tools.configtxgen] doOutputBlock -> INFO 007 Writing genesis block
+ res=0
Creating channel mychannel
Using organization 1
+ osnadmin channel join --channelID mychannel --config-block ./channel-artifacts/mychannel.block -o localhost:7053 --ca-file /home/fabric/go/src/github.com/hyperledger/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --client-cert /home/fabric/go/src/github.com/hyperledger/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt --client-key /home/fabric/go/src/github.com/hyperledger/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key
+ res=0
Status: 201
{
"name": "mychannel",
"url": "/participation/v1/channels/mychannel",
"consensusRelation": "consenter",
"status": "active",
"height": 1
}
Channel 'mychannel' created
Joining org1 peer to the channel...
Using organization 1
+ peer channel join -b ./channel-artifacts/mychannel.block
+ res=0
2022-05-03 18:09:54.791 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2022-05-03 18:09:54.914 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
2022-05-03 18:09:57.978 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2022-05-03 18:09:58.066 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
2022-05-03 10:09:58.328 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2022-05-03 10:09:58.330 UTC [cli.common] readBlock -> INFO 002 Received block: 0
2022-05-03 10:09:58.330 UTC [channelCmd] fetch -> INFO 003 Retrieving last config block: 0
2022-05-03 10:09:58.332 UTC [cli.common] readBlock -> INFO 004 Received block: 0
+ configtxlator proto_decode --input config_block.pb --type common.Block
+ jq '.data.data[0].payload.data.config'
Decoding config block to JSON and isolating config to Org1MSPconfig.json
Generating anchor peer update transaction for Org1 on channel mychannel
+ 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
+ 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":' '"0"' '}' '},' '"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":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '}}}}'
+ configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope
2022-05-03 10:09:58.998 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2022-05-03 10:09:59.021 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
Anchor peer set for org 'Org1MSP' on channel 'mychannel'
Setting anchor peer for org2...
+ 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
Using organization 2
Fetching channel config for channel mychannel
Using organization 2
Fetching the most recent configuration block for the channel
2022-05-03 10:09:59.375 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2022-05-03 10:09:59.385 UTC [cli.common] readBlock -> INFO 002 Received block: 0
2022-05-03 10:09:59.385 UTC [channelCmd] fetch -> INFO 003 Retrieving last config block: 0
2022-05-03 10:09:59.387 UTC [cli.common] readBlock -> INFO 004 Received block: 0
+ configtxlator proto_decode --input config_block.pb --type common.Block
+ jq '.data.data[0].payload.data.config'
Decoding config block to JSON and isolating config to Org2MSPconfig.json
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":' '"0"' '}' '},' '"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":' '"0"' '}' '},' '"mod_policy":' '"",' '"policies":' '{},' '"values":' '{},' '"version":' '"0"' '}' '}}}}'
+ configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope
2022-05-03 10:09:59.721 UTC [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2022-05-03 10:09:59.757 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update
Anchor peer set for org 'Org2MSP' on channel 'mychannel'
Channel 'mychannel' joined
3.启动链码
[fabric@localhost test-network]$ ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go deploying chaincode on channel 'mychannel' executing with the following - CHANNEL_NAME: mychannel - CC_NAME: basic - CC_SRC_PATH: ../asset-transfer-basic/chaincode-go - CC_SRC_LANGUAGE: go - CC_VERSION: 1.0 - CC_SEQUENCE: 1 - CC_END_POLICY: NA - CC_COLL_CONFIG: NA - CC_INIT_FCN: NA - DELAY: 3 - MAX_RETRY: 5 - VERBOSE: false Vendoring Go dependencies at ../asset-transfer-basic/chaincode-go ~/go/src/github.com/hyperledger/fabric-samples/asset-transfer-basic/chaincode-go ~/go/src/github.com/hyperledger/fabric-samples/test-network go: downloading github.com/hyperledger/fabric-contract-api-go v1.1.0 go: downloading github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212 go: downloading github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e go: downloading github.com/stretchr/testify v1.5.1 go: downloading github.com/golang/protobuf v1.3.2 go: downloading google.golang.org/grpc v1.23.0 go: downloading github.com/xeipuuv/gojsonschema v1.2.0 go: downloading github.com/go-openapi/spec v0.19.4 go: downloading github.com/gobuffalo/packr v1.30.1 go: downloading github.com/davecgh/go-spew v1.1.1 go: downloading github.com/pmezard/go-difflib v1.0.0 go: downloading gopkg.in/yaml.v2 v2.2.8 go: downloading golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 go: downloading google.golang.org/genproto v0.0.0-20180831171423-11092d34479b go: downloading github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 go: downloading github.com/go-openapi/jsonpointer v0.19.3 go: downloading github.com/go-openapi/jsonreference v0.19.2 go: downloading github.com/go-openapi/swag v0.19.5 go: downloading github.com/gobuffalo/envy v1.7.0 go: downloading github.com/gobuffalo/packd v0.3.0 go: downloading golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542 go: downloading github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f go: downloading github.com/PuerkitoBio/purell v1.1.1 go: downloading github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e go: downloading github.com/joho/godotenv v1.3.0 go: downloading github.com/rogpeppe/go-internal v1.3.0 go: downloading github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 go: downloading golang.org/x/text v0.3.2 ~/go/src/github.com/hyperledger/fabric-samples/test-network Finished vendoring Go dependencies + peer lifecycle chaincode package basic.tar.gz --path ../asset-transfer-basic/chaincode-go --lang golang --label basic_1.0 + res=0 Chaincode is packaged Installing chaincode on peer0.org1... Using organization 1 + peer lifecycle chaincode install basic.tar.gz + res=0 2022-05-03 19:15:21.627 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:


