1 Introduction
Based on the basic environment of the previous article, we then prepare the relevant components of Fabric and start a stand-alone network.
2. Fabric component installation
Hyperledger is a set of open source tools designed to build a powerful, business-driven blockchain framework. Hyperledger (super ledger) is one of the largest projects in the blockchain industry, which consists of a set of open source tools and multiple sub-projects. The project is a global collaboration hosted by the Linux Foundation, which includes leaders from different fields, whose goal is to build a strong, business-driven blockchain framework.
Hyperledger Fabric is the cornerstone of the Hyperledger project. It is a permissioned blockchain, or more precisely a distributed ledger technology (DLT), originally created by IBM Corporation and Digital Asset. Distributed ledger technology is designed as a modular framework with different components (outlined below). It is also a flexible solution to provide a pluggable consensus model, although it currently only provides voting-based permissioned consensus.
2.1 Download source code
Download the relevant source code through git and switch to the corresponding branch, the V1.4.0 used this time:
# 准备文件夹
sudo mkdir -p $GOPATH/src/github.com/hyperledger/
cd $GOPATH/src/github.com/hyperledger/
# 从github仓库下载源码
sudo git clone https://github.com/hyperledger/fabric.git
cd fabric
# 切换到对应的分支
sudo git checkout v1.4.0
# 检查当前分支
sudo git branch -v
main 687fa1e0a Create HashedIndex in Pvtdata Store retroactively
* (头指针分离于 v1.4.0) d700b4347 Merge "[FAB-13555] Release fabric v1.4.0" into release-1.4
2.2 Compile the source code
Obtain the tools needed to build the network through the make tool:
make release
# bin目录下的工具是我们需要的
cd release/linux-amd64/bin/
ll
total 139160
drwxr-xr-x 2 root root 4096 Mar 27 16:59 ./
drwxr-xr-x 3 root root 4096 Mar 27 16:59 ../
-rwxr-xr-x 1 root root 18382880 Mar 27 16:59 configtxgen*
-rwxr-xr-x 1 root root 20274424 Mar 27 16:59 configtxlator*
-rwxr-xr-x 1 root root 11929624 Mar 27 16:59 cryptogen*
-rwxr-xr-x 1 root root 19367224 Mar 27 16:59 discover*
-rwxr-xr-x 1 root root 829 Mar 27 16:59 get-docker-images.sh*
-rwxr-xr-x 1 root root 10738976 Mar 27 16:59 idemixgen*
-rwxr-xr-x 1 root root 27215424 Mar 27 16:59 orderer*
-rwxr-xr-x 1 root root 34562296 Mar 27 16:59 peer*
2.3 Prepare to build
Copy the tools in the bin directory to the corresponding location, and grant execution permission:
cd /opt/gopath/src/github.com/hyperledger/fabric
mkdir singlepeer
cp -r ./release/linux-amd64/bin/ ./singlepeer
cd singlepeer
sudo chmod -R 755 ./bin/*
2.4 Download mirror
Since Fabric runs components in a containerized way, we need to use docker to download the corresponding image:
# 拉取镜像
sudo docker pull hyperledger/fabric-peer:1.4
sudo docker pull hyperledger/fabric-orderer:1.4
sudo docker pull hyperledger/fabric-tools:1.4
sudo docker pull hyperledger/fabric-ccenv:1.4
sudo docker pull hyperledger/fabric-baseos:0.4
sudo docker pull hyperledger/fabric-kafka:latest
sudo docker pull hyperledger/fabric-zookeeper:latest
sudo docker pull hyperledger/fabric-couchdb:latest
3. Write the configuration file
Prepare three configuration files under the singlepeer directory for building a blockchain network. The network we built has an ordering node and a peer node. The tools used to build the network are:
- cryptogen: Build tools related to identity authentication, mainly to generate the CA certificate required by each peer in the entire network;
- configtxgen: The tool used to build the genesis block, mainly including the configuration of the entire network.
The configuration files required to build the network are usually modified according to the sample configuration officially provided by HyperLedger Fabric. It is not recommended to write manually by individuals to avoid format errors.
file name | illustrate |
---|---|
crypto-config.yaml | Build tools related to identity authentication, mainly to generate CA certificates and keys required by each peer in the entire network |
configtx.yaml | The tools used to build the genesis block mainly include the configuration of the entire network |
docker-compose-node.yaml | Configure the parameters of the started container and use docker-compose to start quickly |
3.1 crypto-config.yaml
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
# ---------------------------------------------------------------------------
# "OrdererOrgs" - Definition of organizations managing orderer nodes
# ---------------------------------------------------------------------------
OrdererOrgs:
# ---------------------------------------------------------------------------
# Orderer
# ---------------------------------------------------------------------------
- Name: Orderer
Domain: example.com
# ---------------------------------------------------------------------------
# "Specs" - See PeerOrgs below for complete description
# ---------------------------------------------------------------------------
Specs:
- Hostname: orderer
# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
PeerOrgs:
# ---------------------------------------------------------------------------
# Org1
# ---------------------------------------------------------------------------
- Name: Org1
Domain: org1.example.com
EnableNodeOUs: true
# ---------------------------------------------------------------------------
# "Specs"
# ---------------------------------------------------------------------------
# Uncomment this section to enable the explicit definition of hosts in your
# configuration. Most users will want to use Template, below
#
# Specs is an array of Spec entries. Each Spec entry consists of two fields:
# - Hostname: (Required) The desired hostname, sans the domain.
# - CommonName: (Optional) Specifies the template or explicit override for
# the CN. By default, this is the template:
#
# "{
{.Hostname}}.{
{.Domain}}"
#
# which obtains its values from the Spec.Hostname and
# Org.Domain, respectively.
# ---------------------------------------------------------------------------
# Specs:
# - Hostname: foo # implicitly "foo.org1.example.com"
# CommonName: foo27.org5.example.com # overrides Hostname-based FQDN set above
# - Hostname: bar
# - Hostname: baz
# ---------------------------------------------------------------------------
# "Template"
# ---------------------------------------------------------------------------
# Allows for the definition of 1 or more hosts that are created sequentially
# from a template. By default, this looks like "peer%d" from 0 to Count-1.
# You may override the number of nodes (Count), the starting index (Start)
# or the template used to construct the name (Hostname).
#
# Note: Template and Specs are not mutually exclusive. You may define both
# sections and the aggregate nodes will be created for you. Take care with
# name collisions
# ---------------------------------------------------------------------------
Template:
Count: 1
# Start: 5
# Hostname: {
{.Prefix}}{
{.Index}} # default
# ---------------------------------------------------------------------------
# "Users"
# ---------------------------------------------------------------------------
# Count: The number of user accounts _in addition_ to Admin
# ---------------------------------------------------------------------------
Users:
Count: 1
3.2 configtx.yaml
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
---
Organizations:
- &OrdererOrg
Name: OrdererOrg
ID: OrdererMSP
MSPDir: crypto-config/ordererOrganizations/example.com/msp
Policies:
Readers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Writers:
Type: Signature
Rule: "OR('OrdererMSP.member')"
Admins:
Type: Signature
Rule: "OR('OrdererMSP.admin')"
- &Org1
Name: Org1MSP
ID: Org1MSP
MSPDir: crypto-config/peerOrganizations/org1.example.com/msp
Policies:
Readers:
Type: Signature
Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')"
Writers:
Type: Signature
Rule: "OR('Org1MSP.admin', 'Org1MSP.client')"
Admins:
Type: Signature
Rule: "OR('Org1MSP.admin')"
AnchorPeers:
- Host: peer0.org1.example.com
Port: 7051
Capabilities:
Global: &ChannelCapabilities
V1_1: true
Orderer: &OrdererCapabilities
V1_1: true
Application: &ApplicationCapabilities
V1_2: true
Application: &ApplicationDefaults
Organizations:
Policies:
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: 10
AbsoluteMaxBytes: 98 MB
PreferredMaxBytes: 512 KB
Kafka:
Brokers:
- 127.0.0.1:9092
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:
OneOrgsOrdererGenesis:
<<: *ChannelDefaults
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Consortiums:
SampleConsortium:
Organizations:
- *Org1
OneOrgsChannel:
Consortium: SampleConsortium
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
3.4 docker-compose-node.yaml
version: '2'
services:
orderer.example.com:
container_name: orderer.example.com
image: hyperledger/fabric-orderer:1.4
environment:
- ORDERER_GENERAL_LOGLEVEL=debug
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
# enabled TLS
- ORDERER_GENERAL_TLS_ENABLED=false
- ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
- ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
- ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]
working_dir: /opt/gopath/src/github.com/hyperledger/fabric
command: orderer
volumes:
- ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block
- ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp
- ./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls
ports:
- 7050:7050
peer0.org1.example.com:
container_name: peer0.org1.example.com
image: hyperledger/fabric-peer:1.4
environment:
- CORE_PEER_ID=peer0.org1.example.com
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052
- CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=singlepeer_default
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_TLS_ENABLED=false
- CORE_PEER_GOSSIP_USELEADERELECTION=true
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt
volumes:
- /var/run/:/host/var/run/
- ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp
- ./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
ports:
- 7051:7051
- 7052:7052
- 7053:7053
cli:
container_name: cli
image: hyperledger/fabric-tools:1.4
tty: true
environment:
- GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_TLS_ENABLED=false
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key
- 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
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
volumes:
- /var/run/:/host/var/run/
- ./chaincode/go/:/opt/gopath/src/github.com/hyperledger/fabric/singlepeer/chaincode/go
- ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts
depends_on:
- peer0.org1.example.com
4. Start the network
After completing the above steps, you can use the tools in /bin to start building a stand-alone network
4.1 Generate certificate and key
cd $GOPATH/src/github.com/hyperledger/fabric/singlepeer
# 生成证书
./bin/cryptogen generate --config=./crypto-config.yaml
# 查看结果,crypto-config/下有完整的证书体系
ll
drwxr-xr-x 4 root root 4096 12月 10 15:44 ./
drwxr-xr-x 5 root root 4096 12月 10 11:34 ../
drwxrwxrwx 2 root root 4096 12月 10 14:21 bin/
drwxr-xr-x 4 root root 4096 12月 10 15:44 crypto-config/
-rw-r--r-- 1 root root 870 12月 10 15:44 crypto-config.yaml
4.2 Generate Genesis Block
mkdir channel-artifacts
# 生产创世区块
./bin/configtxgen -profile OneOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
# 生产区块配置
./bin/configtxgen -profile OneOrgsChannel -outputBlock ./channel-artifacts/mychannel.tx -channelID mychannel
# 查看结果
cd channel-artifacts
ll
total 44
drwxr-xr-x 2 root root 4096 12月 10 16:40 ./
drwxr-xr-x 5 root root 4096 12月 10 16:40 ../
-rw-r--r-- 1 root root 16955 12月 10 16:33 genesis.block
-rw-r--r-- 1 root root 14544 12月 10 16:40 mychannel.tx
4.3 Start the node
docker-compose -f docker-compose-node.yaml up -d
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ba1f0697b8ee hyperledger/fabric-tools:1.4 "/bin/bash" 3 days ago Up 6 seconds cli
3f57e37c324f hyperledger/fabric-peer:1.4 "peer node start" 3 days ago Up 4 seconds 0.0.0.0:7051-7053->7051-7053/tcp, :::7051-7053->7051-7053/tcp peer0.org1.example.com
a99d8a4b5fee hyperledger/fabric-orderer:1.4 "orderer" 3 days ago Up 3 seconds 0.0.0.0:7050->7050/tcp, :::7050->7050/tcp orderer.example.com
The cli is the operation container of peer0, through which peer0 can be managed.
4.4 Using chaincode
# 首先需要进入cli容器
docker exec -it cli bash
# 加入通道
peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/mychannel.tx
# 在通道上安装链码
peer chaincode install -n mycc11 -p github.com/hyperledger/fabric/singlepeer/chaincode/go/example02/cmd/ -v 1.0
2022-03-27 09:35:16.294 UTC [main] SetOrdererEnv -> WARN 002 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2022-03-27 09:35:16.297 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 003 Using default escc
2022-03-27 09:35:16.297 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 004 Using default vscc
2022-03-27 09:35:16.417 UTC [chaincodeCmd] install -> INFO 005 Installed remotely response:<status:200 payload:"OK">
# 实例化链码,没有报错即成功
peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n mycc11 -v 1.0 -c '{"Args":["init","a","100","b","200"]}'
# query函数:a的值为100
peer chaincode query -o orderer.example.com:7050 -C mychannel -n mycc11 -c '{"Args":["query","a"]}'
2022-03-27 09:39:47.283 UTC [main] InitCmd -> WARN 001 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2022-03-27 09:39:47.286 UTC [main] SetOrdererEnv -> WARN 002 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
100
# invoke函数:a向b转账20
peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n mycc11 -c '{"Args":["invoke","a","b","20"]}'
2022-03-27 09:41:24.508 UTC [main] InitCmd -> WARN 001 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2022-03-27 09:41:24.511 UTC [main] SetOrdererEnv -> WARN 002 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2022-03-27 09:41:24.518 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 003 Chaincode invoke successful. result: status:200
# 查询a的值:80
peer chaincode query -o orderer.example.com:7050 -C mychannel -n mycc11 -c '{"Args":["query","a"]}'
2022-03-27 09:41:52.079 UTC [main] InitCmd -> WARN 001 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
2022-03-27 09:41:52.083 UTC [main] SetOrdererEnv -> WARN 002 CORE_LOGGING_LEVEL is no longer supported, please use the FABRIC_LOGGING_SPEC environment variable
80