一、安装go,node,docker,docker-compose环境
二、安装fabric源码及相关docker镜像,执行下面命令:
# mkdir -p $GOPATH/src/github.com/hyperledger
#cd $GOPATH/src/github.com/hyperledger
#git clone https://github.com/hyperledger/fabric.git
#cd fabric/scripts
# ./bootstrap.sh
镜像:mysql请忽略
之后可以用first-network进行测试,看是否正常。接下来就手动建一个网络,手动执行各个步骤。
三、手动建my-network网络
1、_cryptogen的配置(定义谁是谁)
#cd $GOPATH/src/github.com/hyperledger/fabric/scripts/fabric-samples/
#mkdir my-network
#cd my-network
#touch crypto-config.yaml
#vi crypto-config.yaml
里面创建1个order节点,2个org;每个org有2个peer,1个管理员用户。
把上一级bin目录设置成环境变量,bin里面是一些生成工具
#export PATH=${PWD}/../bin:${PWD}:$PATH
#cryptogen generate --config=./crypto-config.yaml
生成crypto-config文件夹 里面是组织节点信息
2、在创世区块里面声明orderer和peer所在的org:创建创世区块写入节点信息
首先把first-network中configtx.yaml 复制到当前目录my-network
#cp ../first-network/configtx.yaml ./
在configtx.yaml中定义了当前网络所有参与者的组织信息,包括每个org的排序节点是谁和节点ID、端口、证书的地址(管理员证书,ca证书,tls网络通信证书)、谁是锚节点(anchor peer)以及锚节点相关信息、排序节点类型(solo\kafka\etcdraft)、排序服务器地址及相关参数(性能优化)、kafka
下面是排序节点参数:
BatchTimeout:2s产生区块时间(可以根据业务需求调整)
Batchsize:
MaxMessageCount:10最大消息数量(达到10条就发送去生成区块)
AbsoluteMaxByte:99MB最大区块大小(达到99MB就生成)
PreferencedMaxByte:521KB偏向的区块大小
order节点有几个这里就用几个,我这里只有一个所以其他都注释了
创建存放创世区块文件夹:
#mkdir channel-artifacts
生成创世区块:
#configtxgen -profile SampleMultiNodeEtcdRaft -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block
创建channel名字叫mychannel:
#configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel
下图可以看到生成的创世区块genesis.block和channel文件channel.tx
3、更新通讯的锚节点信息、
生成org1锚节点文件Org1MSPanchors.tx:
#configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP
生成org2锚节点文件Org2MSPanchors.tx:
#configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP
4、启动网络需要的节点机器:用docker启动
首先从first-network复制相关docker-compose文件到本文件夹
#cp -r ../first-network/base ./
#cp ../first-network/docker-compose-cli.yaml ./
指定docker镜像文件版本号latest
#export IMAGE_TAG=latest
指定形目名称-net
#export COMPOSE_PROJECT_NAME=net
启动网络:
#docker-compose -f docker-compose-cli.yaml up -d
如果order节点没启动起来,那把channel-artifacts和crypto-config都清除,以上步骤重新来一遍。
5、我把上面所有命令放到一个my-network.sh脚本里执行脚本就可以了
./my-network.sh start 是网络初始化启动 ./my-network.sh stop 网络停止并清除容器以及之前生成的文件。
#!/bin/sh
if [ "$1" = "start" ];then
#生成节点信息
$(cryptogen generate --config=./crypto-config.yaml)
#生成创世区块
$(configtxgen -profile SampleMultiNodeEtcdRaft -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block)
#生成channel
$(configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID myChannel)
#生成锚节点
$(configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP)
$(configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP)
#设置镜像文件版本
export IMAGE_TAG=latest
#compose定义项目名
export COMPOSE_PROJECT_NAME=net
#启动节点容器
docker-compose -f docker-compose-cli.yaml up -d
elif [ "$1" = "stop" ];then
#停止和删除节点容器
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
#清空之前生成的数据
$(rm -rf ./crypto-config/*)
$(rm -rf ./channel-artifacts/*)
else
echo "please input one arg[start/stop]"
fi
启动后的docker 容器
注意:如果order启动后挂掉,有可能有证书等数据之前没有清干净
可以在first-network文件夹下执行 下面命令,因为官方脚本清理的比较彻底,包括数据卷都会清除。
#./byfn.sh -m down
四、手动安装(创建通道、连码、执行连码等操作)
1、进入到cli客户端命令行
#docker exec -it cli bash
默认进入cli路径是
bash-5.0# pwd
/opt/gopath/src/github.com/hyperledger/fabric/peer
2、进行相关操作
#!/bin/bash
#创建通道
echo "创建通道..."
export CORE_PEER_LOCALMSPID="Org1MSP"
export ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx --tls --cafile $ORDERER_CA
echo "创建通道finish..."
#加入通道
#·Org1.peer0加入通道
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
peer channel join -b mychannel.block
echo "Org1.peer0加入通道finish..."
#·Org1.peer1加入通道
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_ADDRESS=peer1.org1.example.com:8051
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
peer channel join -b mychannel.block
echo "Org1.peer1加入通道finish..."
#·Org2.peer0加入通道
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_ADDRESS=peer0.org2.example.com:9051
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
peer channel join -b mychannel.block
echo "Org2.peer0加入通道finish..."
#·Org2.peer1加入通道
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_ADDRESS=peer1.org2.example.com:10051
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
peer channel join -b mychannel.block
echo "Org2.peer1加入通道finish..."
#更新锚节点
#org1
export CHANNEL_NAME="mychannel"
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org1MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
echo "Org1.更新锚节点finish..."
#org2
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_ADDRESS=peer0.org2.example.com:9051
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org2MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
echo "Org2.更新锚节点finish..."
#打包连码
cd /opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode/abstore/go
go env -w GO111MODULE=on
go env -w GOPROXY=https://goproxy.cn,direct
peer lifecycle chaincode package mycc.tar.gz --path github.com/hyperledger/fabric-samples/chaincode/abstore/go/ --lang golang --label mycc_1
echo "打包连码finish..."
#安装连码
#org1
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
peer lifecycle chaincode install mycc.tar.gz
echo "org1安装连码finish..."
#org2
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_ADDRESS=peer0.org2.example.com:9051
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
peer lifecycle chaincode install mycc.tar.gz
echo "org2安装连码finish..."
#获取有关已安装软件包的信息来找到链码软件包标识符.
peer lifecycle chaincode queryinstalled
#返回结果:
#Installed chaincodes on peer:Package ID: mycc_1:71109bcb5ce417e8d5affdc113ec4005223079454baef0949b154535181a2b82, Label: mycc_1
#截取CC_PACKAGE_ID 添加到环境变量
a=$(peer lifecycle chaincode queryinstalled)
b=${a#*ID: }
#CC_PACKAGE_ID=mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173
export CC_PACKAGE_ID=${b%%,*}
#org1
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
peer lifecycle chaincode approveformyorg --channelID $CHANNEL_NAME --name mycc --version 1.0 --init-required --package-id $CC_PACKAGE_ID --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
echo "连码分配org1给组织内的peer finish..."
#org2
export CORE_PEER_LOCALMSPID="Org2MSP"
export CORE_PEER_ADDRESS=peer0.org2.example.com:9051
export CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
peer lifecycle chaincode approveformyorg --channelID $CHANNEL_NAME --name mycc --version 1.0 --init-required --package-id $CC_PACKAGE_ID --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
echo "连码分配org2给组织内的peer finish..."
#按组织查看当前的批准
peer lifecycle chaincode checkcommitreadiness --channelID $CHANNEL_NAME --name mycc --version 1.0 --init-required --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json
#结果:
#{
# "approvals": {
# "Org1MSP": true,
# "Org2MSP": true
# }
#}
#连码提交给通道:由于两个渠道成员都批准了该定义,因此我们现在可以使用以下命令将其提交给渠道。您可以以Org1或Org2的形式发出此命令。请注意,该交易针对Org1和Org2中的同级收集签注。
peer lifecycle chaincode commit -o orderer.example.com:7050 --channelID $CHANNEL_NAME --name mycc --version 1.0 --sequence 1 --init-required --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
echo "连码提交给通道 finish..."
#调用链码
echo "链码操作start..."
#发出以下命令来初始化链码并将初始数据放在分 类帐中
peer chaincode invoke -o orderer.example.com:7050 --isInit --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["Init","a","100","b","100"]}' --waitForEvent
echo "链码init finish..."
#让我们查询链码 query
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
#结果:100
echo "查询链码 query finish..."
#现在让我们10从a移至b Invoke
peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}' --waitForEvent
echo "链码 Invoke finish..."
#再次查询a的值
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
#结果:90
echo "查询链码 query finish..."