fabric机器名:xjcc-30-70
wget https://studygolang.com/dl/golang/go1.16.linux-amd64.tar.gz
tar -xzf go1.16.linux-amd64.tar.gz
rm go1.16.linux-amd64.tar.gz
sudo mv go /usr/local
sudo useradd -d /home/fabric -m fabric
sudo passwd fabric
echo "fabric ALL = (root) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/fabric
sudo chmod 0440 /etc/sudoers.d/fabric
usermod -s /bin/bash fabric #指定新建用户的shell
export PATH=$PATH:/usr/local/go/bin
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$PATH:$HOME/go/bin
go env -w GOPROXY=https://goproxy.io,direct
go env -w GO111MODULE=on
cd ~
mkdir -p go/src/github.com/hyperledger/
sudo chmod -R 775 go
安装docker-ce
# 1. 安装必要工具
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
# 2. 安装GPG证书
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# 3. 写入软件源信息
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# 4. 更新并安装docker-ce
sudo apt-get update
sudo apt-get install docker-ce
将fabric用户添加到docker用户组
# 1. 创建docker用户组
sudo groupadd docker
# 2. 将fabric用户添加到docker用户组
sudo usermod -aG docker $USER
# 3. 需退出终端重新连接
exit
将docker镜像换为中科大镜像
# 编辑/etc/docker/daemon.json文件,如果没有则自行创建,添加以下内容:
{
"registry-mirrors" : [
"https://nqr0dgc3.mirror.aliyuncs.com",
"http://registry.docker-cn.com",
"http://docker.mirrors.ustc.edu.cn",
"http://hub-mirror.c.163.com"
],
"insecure-registries" : [
"registry.docker-cn.com",
"docker.mirrors.ustc.edu.cn"
],
"debug" : true,
"experimental" : true
}
重启服务
sudo systemctl daemon-reload
sudo systemctl restart docker
# 查看docker版本信息
docker -v
# 查看镜像是否配置成功
docker info
sudo apt-get install python3-pip
sudo pip3 install docker-compose
# 查看版本
docker-compose -version
git clone "git://github.com/hyperledger/fabric.git"
cd fabric/
# checkout到要编译的的分支
git checkout release-2.3
# 下载官方给的例子和Docker镜像
# 较慢,出现错误remake即可
cd scripts/
sudo ./bootstrap.sh
若上述下载过慢,可以对源码进行编译
# 进入fabric文件夹
cd ~/go/src/github.com/hyperledger/fabric/
# 编译
make release
# 查看生成的文件
cd release/linux-amd64/bin
# 如果文件夹内有如下文件的话说明编译成功
# configtxgen configtxlator cryptogen discover idemixgen orderer peer
vim ~/.profile
# 追加以下内容
export PATH=$PATH:$GOPATH/src/github.com/hyperledger/fabric/release/linux-amd64/bin
# 更新
source ~/.profile
# 进入test-network文件夹
cd ~/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/test-network
./network.sh -h # 查看help
sudo ./network.sh up # 启动
sudo ./network.sh down # 关闭
四台主机,四个组织org1-4,四个个peer:peer0@org1、peer1@org2、peer2@org3和peer3@org4
IP | 主机名 | 描述 | 备注 |
---|---|---|---|
10.10.9.20 | node0 | peer0@org1 orderer | 证书生成节点 orderer0/[email protected] |
10.10.9.21 | node1 | peer0@org2 orderer | orderer1/[email protected] |
10.10.9.22 | node2 | peer0@org3 orderer | orderer2/[email protected] |
10.10.9.23 | node3 | peer0@org4 | [email protected] |
# orderers
10.10.9.20 orderer0.demo.com
10.10.9.21 orderer1.demo.com
10.10.9.22 orderer2.demo.com
# peers
10.10.9.20 peer0.org1.demo.com
10.10.9.20 peer1.org1.demo.com
10.10.9.21 peer0.org2.demo.com
10.10.9.21 peer1.org2.demo.com
10.10.9.22 peer0.org3.demo.com
10.10.9.22 peer1.org3.demo.com
10.10.9.23 peer0.org4.demo.com
10.10.9.23 peer1.org4.demo.com
mkdir -p ~/go/src/github.com/hyperledger/
cd ~/go/src/github.com/hyperledger/
sudo chmod -R 775 ~/go
OrdererOrgs:
- Name: Orderer
Domain: demo.com
Specs:
- Hostname: orderer0
- Hostname: orderer1
- Hostname: orderer2
PeerOrgs:
- Name: Org1
Domain: org1.demo.com
EnableNodeOUs: true
Template:
Count: 2
Users:
Count: 1
- Name: Org2
Domain: org2.demo.com
EnableNodeOUs: true
Template:
Count: 2
Users:
Count: 1
- Name: Org3
Domain: org3.demo.com
EnableNodeOUs: true
Template:
Count: 2
Users:
Count: 1
- Name: Org4
Domain: org4.demo.com
EnableNodeOUs: true
Template:
Count: 2
Users:
Count: 1
在node0执行cryptogen,生成证书
cryptogen generate --config=crypto-config.yaml --output ./crypto-config
cp -r /home/fabric/mycluster/certs/ordererOrganizations/example.com/orderers/orderer.example.com/ /home/fabric/mycluster/
scp -r /home/fabric/mycluster/certs/peerOrganizations/org1.example.com/peers/peer0.org1.example.com [email protected]:/home/fabric/mycluster/
scp -r /home/fabric/mycluster/certs/peerOrganizations/org1.example.com/peers/peer1.org1.example.com [email protected]:/home/fabric/mycluster/
scp -r /home/fabric/mycluster/certs/peerOrganizations/org2.example.com/peers/peer0.org2.example.com [email protected]:/home/fabric/mycluster/
scp -r /home/fabric/mycluster/certs/peerOrganizations/org2.example.com/peers/peer1.org2.example.com [email protected]:/home/fabric/mycluster/
...
BootstrapFile: ./genesisblock
LocalMSPDir: ./msp
LocalMSPID: OrdererMSP
...
FileLedger:
# Location: The directory to store the blocks in.
Location: /home/fabric/mycluster/orderer/data
...
还需要用到一个文件夹存放orderer的数据
mkdir ~/cluster/orderer.example.com/data
peer:
# The peer id provides a name for this peer instance and is used when
# naming docker resources.
id: peer0.org1.example.com
...
# Path on the file system where peer will store data (eg ledger). This
# location must be access control protected to prevent unintended
# modification that might corrupt the peer operations.
fileSystemPath: /home/fabric/mycluster/peer/data
...
# Identifier of the local MSP
# ----!!!!IMPORTANT!!!-!!!IMPORTANT!!!-!!!IMPORTANT!!!!----
# Deployers need to change the value of the localMspId string.
# In particular, the name of the local MSP ID of a peer needs
# to match the name of one of the MSPs in each of the channel
# that this peer is a member of. Otherwise this peer's messages
# will not be identified as valid by other nodes.
localMspId: Org1MSP
...
还需要用到一个文件夹存放peer的数据
mkdir ~/cluster/peer0.org1.example.com/data
scp /home/fabric/mycluster/peer0.org1.example.com/core.yaml [email protected]:/home/fabric/mycluster/peer1.org1.example.com
修改core.yaml中的peer0.org1.example.com为peer1.org1.example.com
sed -i "s/peer0.org1.example.com/peer1\.org1\.example.com/g" core.yaml
还需要用到一个文件夹存放peer的数据
mkdir ~/cluster/peer1.org1.example.com/data
scp /home/fabric/mycluster/peer0.org1.example.com/core.yaml [email protected]:/home/fabric/mycluster/peer0.org2.example.com
修改core.yaml中的peer0.org1.example.com为peer0.org2.example.com
sed -i "s/peer0.org1.example.com/peer0\.org2\.example.com/g" core.yaml
将配置文件中Org1MSP替换成Org2MSP
sed -i "s/Org1MSP/Org2MSP/g" core.yaml
还需要用到一个文件夹存放peer的数据
mkdir ~/cluster/peer0.org2.example.com/data
scp /home/fabric/mycluster/peer0.org1.example.com/core.yaml [email protected]:/home/fabric/mycluster/peer1.org2.example.com
修改core.yaml中的peer0.org1.example.com为peer1.org2.example.com
sed -i "s/peer0.org1.example.com/peer1\.org2\.example.com/g" core.yaml
将配置文件中Org1MSP替换成Org2MSP
sed -i "s/Org1MSP/Org2MSP/g" core.yaml
还需要用到一个文件夹存放peer的数据
mkdir ~/cluster/peer1.org2.example.com/data
Organizations:
- &OrdererOrg
Name: OrdererOrg
SkipAsForeign: false
ID: OrdererMSP
MSPDir: /home/fabric/config/certs/ordererOrganizations/example.com/msp
Policies: &OrdererOrgPolicies
Readers:
Type: Signature
Rule: "OR('OrdererOrg.member')"
Writers:
Type: Signature
Rule: "OR('OrdererOrg.member')"
Admins:
Type: Signature
Rule: "OR('OrdererOrg.admin')"
Endorsement:
Type: Signature
Rule: "OR('OrdererOrg.member')"
OrdererEndpoints:
- "127.0.0.1:7050"
AnchorPeers:
- Host: 127.0.0.1
Port: 7051
- &Org1
Name: Org1MSP
ID: Org1MSP
MSPDir: /home/fabric/config/certs/peerOrganizations/org1.example.com/msp
AnchorPeers:
- Host: peer0.org1.example.com
Port: 7051
Policies: &Org1Policies
Readers:
Type: Signature
Rule: "OR('Org1.member')"
Writers:
Type: Signature
Rule: "OR('Org1.member')"
Admins:
Type: Signature
Rule: "OR('Org1.admin')"
Endorsement:
Type: Signature
Rule: "OR('Org1.member')"
- &Org2
Name: Org2MSP
ID: Org2MSP
MSPDir: /home/fabric/config/certs/peerOrganizations/org2.example.com/msp
AnchorPeers:
- Host: peer0.org2.example.com
Port: 7051
Policies: &Org2Policies
Readers:
Type: Signature
Rule: "OR('Org2.member')"
Writers:
Type: Signature
Rule: "OR('Org2.member')"
Admins:
Type: Signature
Rule: "OR('Org2.admin')"
Endorsement:
Type: Signature
Rule: "OR('Org2.member')"
Capabilities:
Channel: &ChannelCapabilities
V2_0: true
Orderer: &OrdererCapabilities
V2_0: true
Application: &ApplicationCapabilities
V2_0: true
Application: &ApplicationDefaults
ACLs: &ACLsDefault
_lifecycle/CheckCommitReadiness: /Channel/Application/Writers
_lifecycle/CommitChaincodeDefinition: /Channel/Application/Writers
_lifecycle/QueryChaincodeDefinition: /Channel/Application/Writers
_lifecycle/QueryChaincodeDefinitions: /Channel/Application/Writers
lscc/ChaincodeExists: /Channel/Application/Readers
lscc/GetDeploymentSpec: /Channel/Application/Readers
lscc/GetChaincodeData: /Channel/Application/Readers
lscc/GetInstantiatedChaincodes: /Channel/Application/Readers
qscc/GetChainInfo: /Channel/Application/Readers
qscc/GetBlockByNumber: /Channel/Application/Readers
qscc/GetBlockByHash: /Channel/Application/Readers
qscc/GetTransactionByID: /Channel/Application/Readers
qscc/GetBlockByTxID: /Channel/Application/Readers
cscc/GetConfigBlock: /Channel/Application/Readers
cscc/GetChannelConfig: /Channel/Application/Readers
peer/Propose: /Channel/Application/Writers
peer/ChaincodeToChaincode: /Channel/Application/Writers
event/Block: /Channel/Application/Readers
event/FilteredBlock: /Channel/Application/Readers
Organizations:
Policies: &ApplicationDefaultPolicies
LifecycleEndorsement:
Type: ImplicitMeta
Rule: "MAJORITY Endorsement"
Endorsement:
Type: ImplicitMeta
Rule: "MAJORITY Endorsement"
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
Capabilities:
<<: *ApplicationCapabilities
Orderer: &OrdererDefaults
OrdererType: solo
Addresses:
- orderer.example.com:7050
BatchTimeout: 2s
BatchSize:
MaxMessageCount: 500
AbsoluteMaxBytes: 10 MB
PreferredMaxBytes: 2 MB
MaxChannels: 0
Kafka:
Brokers:
- kafka0:9092
- kafka1:9092
- kafka2:9092
EtcdRaft:
Consenters:
- Host: raft0.example.com
Port: 7050
ClientTLSCert: path/to/ClientTLSCert0
ServerTLSCert: path/to/ServerTLSCert0
- Host: raft1.example.com
Port: 7050
ClientTLSCert: path/to/ClientTLSCert1
ServerTLSCert: path/to/ServerTLSCert1
- Host: raft2.example.com
Port: 7050
ClientTLSCert: path/to/ClientTLSCert2
ServerTLSCert: path/to/ServerTLSCert2
Options:
TickInterval: 500ms
ElectionTick: 10
HeartbeatTick: 1
MaxInflightBlocks: 5
SnapshotIntervalSize: 16 MB
Organizations:
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
BlockValidation:
Type: ImplicitMeta
Rule: "ANY Writers"
Capabilities:
<<: *OrdererCapabilities
Channel: &ChannelDefaults
Policies:
Readers:
Type: ImplicitMeta
Rule: "ANY Readers"
Writers:
Type: ImplicitMeta
Rule: "ANY Writers"
Admins:
Type: ImplicitMeta
Rule: "MAJORITY Admins"
Capabilities:
<<: *ChannelCapabilities
Profiles:
SampleSingleMSPSolo:
<<: *ChannelDefaults
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
SampleSingleMSPChannel:
<<: *ChannelDefaults
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
使用下列命令生成创世块
configtxgen -profile SampleSingleMSPSolo -outputBlock ./genesisblock -channelID mychannel
将创世块复制到orderer节点/home/fabric/mycluster/orderer.example.com目录下
mv genesisblock orderer.example.com/
orderer $ # &表示后台运行
为了方便查看输出的日志,可以将输出重定向到log文件
orderer 2>&1 | tee log & # &表示后台运行
peer node start $ # &表示后台运行
为了方便查看输出的日志,可以将输出重定向到log文件
peer node start 2>&1 | tee log & # &表示后台运行
为了解决没有权限创建/var/hyperledger的问题,首先创建该文件夹并赋予操作权限
sudo mkdir -p /var/hyperledger/production
sudo chown -R $(whoami):$(whoami) /var/hyperledger
cd ~
mkdir users
cp -r ~/config/certs/peerOrganizations/org1.example.com/users/Admin@org1
.example.com/ ~/users/Admin\@org1.example.com
scp [email protected]:/home/fabric/mycluster/peer0.org1.example.com/core.yaml ~/users/[email protected]
#!/bin/bash
PATH=`pwd`/../bin:$PATH
export FABRIC_CFG_PATH=`pwd`
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_TLS_CERT_FILE=./tls/client.crt
export CORE_PEER_TLS_KEY_FILE=./tls/client.key
export CORE_PEER_MSPCONFIGPATH=./msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051
export CORE_PEER_LOCALMSPID=Org1MSP
export CORE_PEER_TLS_ROOTCERT_FILE=./tls/ca.crt
export CORE_PEER_ID=cli
export CORE_LOGGING_LEVEL=INFO
peer $*
chmod 777 peer.sh
其他用户的创建类似,下面给出相应的命令
# 拷贝相应的证书
cp -r ~/config/certs/peerOrganizations/org1.example.com/users/[email protected]/ ~/users/User1\@org1.example.com
cp -r ~/config/certs/peerOrganizations/org2.example.com/users/[email protected]/ ~/users/Admin\@org2.example.com
cp -r ~/config/certs/peerOrganizations/org2.example.com/users/[email protected]/ ~/users/User1\@org2.example.com
# 拷贝相应的core.yaml
scp [email protected]:/home/fabric/mycluster/peer1.org1.example.com/core.yaml ~/users/[email protected]
scp [email protected]:/home/fabric/mycluster/peer0.org2.example.com/core.yaml ~/users/[email protected]
scp [email protected]:/home/fabric/mycluster/peer1.org2.example.com/core.yaml ~/users/[email protected]
configtxgen -profile SampleSingleMSPChannel -outputCreateChannelTx mychannel.tx -channelID mychannel
configtxgen -profile SampleSingleMSPChannel -outputAnchorPeersUpdate Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP
configtxgen -profile SampleSingleMSPChannel -outputAnchorPeersUpdate Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP
cp -r /home/fabric/config/certs/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem ~/users/[email protected]
cp -r /home/fabric/config/certs/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem ~/users/[email protected]
cp -r /home/fabric/config/certs/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem ~/users/[email protected]
cp -r /home/fabric/config/certs/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem ~/users/[email protected]
./peer.sh channel create -o orderer.example.com:7050 -c mychannel -f ../mychannel.tx --tls true --cafile tlsca.example.com-cert.pem