Building a Hyperledger Fabric Network from Scratch

Install Dependencies for Fabric

yum install epel-release –y
yum clean all
yum list
yum install docker-io –y
systemctl start docker
docker info
sudo curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
brew install docker
yum install go -y
export GOPATH=/usr/local/go
export PATH=$PATH:$GOPATH/bin
brew install go
vi /etc/profile
source /etc/profile
Write the following code to the profile:
export GOROOT=/usr/local/Cellar/go/1.10
export GOPATH=/Users/Your user name/go #All external libraries and code downloaded by Go commands are stored in this directory by default.
export GOBIN=$GOPATH/bin
export PATH=$PATH:$GOBIN

Install Fabric

curl -sSL https://goo.gl/6wtTN5 | bash -s 1.1.0
touch fabric_download.sh
vi fabric_download.sh #Paste the content.
chmod +x fabric_download.sh
./fabric_download.sh
yum install git
DOCKER=true
SAMPLES=true
BINARIES=true
docker image ls

Official Fabric sample

(1) Official Sample: Build Your First Network (BYFN)

[root@fabric-test-01 first-network]# cd /usr/local/fabric-samples/first-network
[root@fabric-test-01 first-network]# ./byfn.sh up
[root@fabric-test-01 first-network]# ./byfn down
[root@fabric-test-01 first-network]# vi docker-compose-cli.yaml
[root@fabric-test-01 first-network]# ./byfn up -t 10000 #Set the timeout duration to 10s.
Add - GODEBUG=netdns=go.
[root@fabric-test-01 first-network]# ./byfn.sh down
[root@fabric-test-01 first-network]# vi /etc/resolv.conf
[root@fabric-test-01 first-network]# ./byfn.sh up -t 10000

(2) BYFN Startup Process

[root@fabric-test-01 first-network]# cryptogen generate --config=./crypto-config.yaml
org1.example.com
org2.example.com
[root@fabric-test-01 first-network]# yum install tree
[root@fabric-test-01 first-network]# tree -L 4 crypto-config
crypto-config
├── ordererOrganizations
│ └── example.com
│ ├── ca
│ │ ├── 16cdf940fba55b97f3cdf71eb44ed39bc08ff7149757ac34d7596707c97b18b8_sk
│ │ └── ca.example.com-cert.pem
│ ├── msp
│ │ ├── admincerts
│ │ ├── cacerts
│ │ └── tlscacerts
│ ├── orderers
│ │ └── orderer.example.com
│ ├── tlsca
│ │ ├── b38e560de1aa8138923ad0d2797b8b8f16ed082b8a14381190a0dea1829e749a_sk
│ │ └── tlsca.example.com-cert.pem
│ └── users
│ └── Admin@example.com
└── peerOrganizations
├── org1.example.com
│ ├── ca
│ │ ├── 0f7e3c534db8811228222fc7b16d2105e59b1002981745ca75d9c16a64e32287_sk
│ │ └── ca.org1.example.com-cert.pem
│ ├── msp
│ │ ├── admincerts
│ │ ├── cacerts
│ │ ├── config.yaml
│ │ └── tlscacerts
│ ├── peers
│ │ ├── peer0.org1.example.com
│ │ └── peer1.org1.example.com
│ ├── tlsca
│ │ ├── 4d4a78f0c71d4a1247867f7d9e389cde56869dec283eb2555fd0825441fba0c3_sk
│ │ └── tlsca.org1.example.com-cert.pem
│ └── users
│ ├── Admin@org1.example.com
│ └── User1@org1.example.com
└── org2.example.com
├── ca
│ ├── 83b3d4ce5fb3877c76817da2a50329ddb4f4c4bc9f5cdbc9b7cf0fa44aa6fa17_sk
│ └── ca.org2.example.com-cert.pem
├── msp
│ ├── admincerts
│ ├── cacerts
│ ├── config.yaml
│ └── tlscacerts
├── peers
│ ├── peer0.org2.example.com
│ └── peer1.org2.example.com
├── tlsca
│ ├── 12e7338b1321c4660fbebf42dac0adc38ec6fd6e1b972bd6c13b27f5798cf95f_sk
│ └── tlsca.org2.example.com-cert.pem
└── users
├── Admin@org2.example.com
└── User1@org2.example.com
39 directories, 14 files
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
# ---------------------------------------------------------------------------
# "OrdererOrgs" - Definition of organizations managing orderer nodes
# ---------------------------------------------------------------------------
OrdererOrgs: #Orderer organization
# ---------------------------------------------------------------------------
# Orderer
# ---------------------------------------------------------------------------
- Name: Orderer #Organization name
Domain: example.com #Organization's domain name
# ---------------------------------------------------------------------------
# "Specs" - See PeerOrgs below for complete description
# ---------------------------------------------------------------------------
Specs:
- Hostname: orderer #Generate an additional orderer.example.com.
#The function of Spec is to personalize a domain name and exempt the domain name from being affected by the following template generation rules.
# ---------------------------------------------------------------------------
# "PeerOrgs" - Definition of organizations managing peer nodes
# ---------------------------------------------------------------------------
PeerOrgs: #Network node organization
# ---------------------------------------------------------------------------
# Org1
# ---------------------------------------------------------------------------
- Name: Org1 #Name of Org1
Domain: org1.example.com #Domain name of Org1
EnableNodeOUs: true #It is supported by Node.js, and is commented out in the Java SDK by default.
# ---------------------------------------------------------------------------
# "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: #Generate two sets of public and private keys as well as certificates based on the preceding template. The default generation rule is based on peers 0 to 9.organization domain name.
Count: 2 #Generate the public and private keys as well as certificates for the peer0.org1.example.com and peer1.org1.example.com nodes.
# Start: 5
# Hostname: {{.Prefix}}{{.Index}} # default
# ---------------------------------------------------------------------------
# "Users"
# ---------------------------------------------------------------------------
# Count: The number of user accounts _in addition_ to Admin
# ---------------------------------------------------------------------------
Users: #In addition to the admin account, a User1 account is generated.
Count: 1
# ---------------------------------------------------------------------------
# Org2: See "Org1" for full specification
# ---------------------------------------------------------------------------
- Name: Org2
Domain: org2.example.com
EnableNodeOUs: true
Template:
Count: 2
Users:
Count: 1
[root@fabric-test-01 first-network]# export FABRIC_CFG_PATH=$PWD
[root@fabric-test-01 first-network]# configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
[root@fabric-test-01 first-network]# configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID mychannel
[root@fabric-test-01 first-network]# configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID mychannel -asOrg Org1MSP
[root@fabric-test-01 first-network]# configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID mychannel -asOrg Org2MSP
[root@fabric-test-01 first-network]# docker-compose -f docker-compose-cli.yaml up -d
Creating network "net_byfn" 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_peer1.org1.example.com" with default driver
Creating volume "net_peer0.org2.example.com" with default driver
Creating volume "net_peer1.org2.example.com" with default driver
Creating orderer.example.com ... done
Creating peer1.org1.example.com ... done
Creating peer0.org2.example.com ... done
Creating peer1.org2.example.com ... done
Creating peer0.org1.example.com ... done
Creating cli ... done
[root@fabric-test-01 first-network]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2f3af7e64868 hyperledger/fabric-tools:latest "/bin/bash" 18 seconds ago Up 17 seconds cli
dfea53b15138 hyperledger/fabric-peer:latest "peer node start" 19 seconds ago Up 17 seconds 0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp peer0.org1.example.com
3eac41603863 hyperledger/fabric-peer:latest "peer node start" 19 seconds ago Up 17 seconds 0.0.0.0:10051->7051/tcp, 0.0.0.0:10053->7053/tcp peer1.org2.example.com
ea1ef950b845 hyperledger/fabric-peer:latest "peer node start" 19 seconds ago Up 17 seconds 0.0.0.0:9051->7051/tcp, 0.0.0.0:9053->7053/tcp peer0.org2.example.com
ec49121fbdd5 hyperledger/fabric-peer:latest "peer node start" 19 seconds ago Up 17 seconds 0.0.0.0:8051->7051/tcp, 0.0.0.0:8053->7053/tcp peer1.org1.example.com
11ecb9d115f2 hyperledger/fabric-orderer:latest "orderer" 19 seconds ago Up 17 seconds 0.0.0.0:7050->7050/tcp orderer.example.com
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2'services: #Orderer and transaction nodes provided orderer.example.com: #Orderer service
container_name: orderer.example.com #Container name
image: hyperledger/fabric-orderer:$IMAGE_TAG #Use the Fabric Docker image generation container.
environment: #Environment variable configuration
- ORDERER_GENERAL_LOGLEVEL=INFO #Log level
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 #Listening address segment. 0.0.0.0 indicates that requests from all terminals on the network are accepted.
- ORDERER_GENERAL_GENESISMETHOD=file #Generate a file block.
- ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
- ORDERER_GENERAL_LOCALMSPID=OrdererMSP #Member management ID
- ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp #Member management directory in the Docker container
# enabled TLS
- ORDERER_GENERAL_TLS_ENABLED=true #Indicates whether TLS is enabled at the network layer. The following lists the paths of files in the Docker container.
- 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: #Map the directories generated on the local Linux terminal to the directories in the Docker container.
- ../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
- orderer.example.com:/var/hyperledger/production/orderer
ports: #Map the port of the local Linux terminal to the port of the Docker container.
- 7050:7050
peer0.org1.example.com: #Transaction node peer0.org1. The following peer1.org1 has basically the same configuration.
container_name: peer0.org1.example.com #Container name
Extends:#:#Inherit the peer-base configuration.
file: peer-base.yaml
service: peer-base
Environment:#:#Environment variables
- CORE_PEER_ID=peer0.org1.example.com #Node network address and listening port
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:7051 #Gossip protocol configuration
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP #Member management name configured
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
- peer0.org1.example.com:/var/hyperledger/production
ports:
- 7051:7051
- 7053:7053
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2'services:
peer-base:
image: hyperledger/fabric-peer:$IMAGE_TAG #Use the fabric-peer image generation container.
environment: #Environment variables
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
# the following setting starts chaincode containers on the same
# bridge network as the peers
# https://docs.docker.com/compose/networking/
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_byfn
- CORE_LOGGING_LEVEL=INFO # Log level
#- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_TLS_ENABLED=true #Indicates whether TLS is enabled.
- CORE_PEER_GOSSIP_USELEADERELECTION=true #Enable leader election.
- CORE_PEER_GOSSIP_ORGLEADER=false
- CORE_PEER_PROFILE_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt #TLS node certificate
- CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key #TLS public key
- CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt #TLS root certificate
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
[root@fabric-test-01 first-network]# docker exec -it cli bash
root@2f3af7e64868:/opt/gopath/src/github.com/hyperledger/fabric/peer#
root@2f3af7e64868:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer channel create -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/channel.tx --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
root@2f3af7e64868:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer channel join -b mychannel.block
root@2f3af7e64868:/opt/gopath/src/github.com/hyperledger/fabric/peer# CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp CORE_PEER_ADDRESS=peer1.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org1MSP" 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 peer channel join -b mychannel.block
root@2f3af7e64868:/opt/gopath/src/github.com/hyperledger/fabric/peer# CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer0.org2.example.com:7051 CORE_PEER_LOCALMSPID="Org2MSP" 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 peer channel join -b mychannel.block
root@2f3af7e64868:/opt/gopath/src/github.com/hyperledger/fabric/peer# CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer1.org2.example.com:7051 CORE_PEER_LOCALMSPID="Org2MSP" 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 peer channel join -b mychannel.block
root@2f3af7e64868:/opt/gopath/src/github.com/hyperledger/fabric/peer# CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org1MSP" 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 peer channel update -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org1MSPanchors.tx --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
root@2f3af7e64868:/opt/gopath/src/github.com/hyperledger/fabric/peer# CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer0.org2.example.com:7051 CORE_PEER_LOCALMSPID="Org2MSP" 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 peer channel update -o orderer.example.com:7050 -c mychannel -f ./channel-artifacts/Org2MSPanchors.tx --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
root@2f3af7e64868:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/
root@2f3af7e64868:/opt/gopath/src/github.com/hyperledger/fabric/peer# CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp CORE_PEER_ADDRESS=peer1.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org1MSP" 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 peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/
root@2f3af7e64868:/opt/gopath/src/github.com/hyperledger/fabric/peer# CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer0.org2.example.com:7051 CORE_PEER_LOCALMSPID="Org2MSP" 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 peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/
root@2f3af7e64868:/opt/gopath/src/github.com/hyperledger/fabric/peer# CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer1.org2.example.com:7051 CORE_PEER_LOCALMSPID="Org2MSP" 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 peer chaincode install -n mycc -v 1.0 -p github.com/chaincode/chaincode_example02/go/
root@2f3af7e64868:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode instantiate -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 mychannel -n mycc -l golang -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P 'OR   ('\''Org1MSP.peer'\'','\''Org2MSP.peer'\'')'
[root@fabric-test-01 ~]# docker logs -f peer0.org1.example.com
[root@fabric-test-01 ~]# docker ps -a
root@2f3af7e64868:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
2018-06-07 09:15:04.862 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2018-06-07 09:15:04.862 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
Query Result: 100
2018-06-07 09:15:04.866 UTC [main] main -> INFO 003 Exiting.....
root@2f3af7e64868:/opt/gopath/src/github.com/hyperledger/fabric/peer# 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 mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}'
2018-06-07 09:18:33.697 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2018-06-07 09:18:33.697 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
2018-06-07 09:18:33.704 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 003 Chaincode invoke successful. result: status:200
2018-06-07 09:18:33.704 UTC [main] main -> INFO 004 Exiting.....
root@2f3af7e64868:/opt/gopath/src/github.com/hyperledger/fabric/peer# peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
2018-06-07 09:18:47.068 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 001 Using default escc
2018-06-07 09:18:47.068 UTC [chaincodeCmd] checkChaincodeCmdParams -> INFO 002 Using default vscc
Query Result: 90
2018-06-07 09:18:47.073 UTC [main] main -> INFO 003 Exiting.....
[root@fabric-test-01 ~]# docker logs --tail 200 dev-peer0.org1.example.com-mycc-1.0
ex02 Init
Aval = 100, Bval = 200
ex02 Invoke
Query Response:{"Name":"a","Amount":"100"}
ex02 Invoke
Aval = 90, Bval = 210
ex02 Invoke
Query Response:{"Name":"a","Amount":"90"}
ex02 Invoke
Query Response:{"Name":"a","Amount":"90"}

Obtain fabric-sdk-java

IntelliJ->-> Preferences -> Plugins-> Browse repositories-> Search and Install Protobuf Support
brew install libtool
git clone https://github.com/hyperledger/fabric-sdk-java.git
git checkout --track remotes/origin/release-1.1
maven install

Get Started with Mac and End2EndIT

cd src/test/fixture/sdkintegration
./fabric.sh up
(1) The script commands are as follows:
./fabric.sh up: used to forcibly reestablish a network, which is enabled by default)
./fabric.sh start: used to start
./fabric.sh stop: used to stop
./fabric.sh clean: used to clear the generated Docker container
In fact, the fabric.sh script is a simple encapsulation of docker-compose commands. Therefore, you can directly use docker-compose instead.
(2) After each use, if you need to run the script again, you must run the clean command to clear the generated Docker container and other temporary files.
docker ps -a
docker logs --tail 200 "Container ID/name"

Use Case: Running the fabric-sdk-java Project

Detailed Project Directory

End2EndIT Code Details

@Before
public void checkConfig() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, MalformedURLException, org.hyperledger.fabric_ca.sdk.exception.InvalidArgumentException {
out("\n\n\nRUNNING: %s.\n", testName);
resetConfig();//Reset the org.hyperledger.fabric.sdk.helper.Config file, which mainly contains the configuration items required by Fabric.
configHelper.customizeConfig();//Call the specified variables entered in the command lines to overwrite the configurations in the preceding configuration file.
testSampleOrgs = testConfig.getIntegrationTestsSampleOrgs();//Obtain the organizations configured in testConfig, which has been created in End2endIT and contains a large number of test configuration items.
for (SampleOrg sampleOrg : testSampleOrgs) {////Set the CA that issues certificates.
String caName = sampleOrg.getCAName();
if (caName != null && !caName.isEmpty()) {
sampleOrg.setCAClient(HFCAClient.createNewInstance(caName, sampleOrg.getCALocation(), sampleOrg.getCAProperties()));
} else {
sampleOrg.setCAClient(HFCAClient.createNewInstance(sampleOrg.getCALocation(), sampleOrg.getCAProperties()));
}
}
}
@Test
public void setup() throws Exception {
if (sampleStoreFile.exists()) {
sampleStoreFile.delete();//Simulate that the database storage uses the HFCSampletest.properties file.
}
sampleStore = new SampleStore(sampleStoreFile);//Initialize the storage.
enrollUsersSetup(sampleStore);// Use CA for initialization.
runFabricTest(sampleStore);//Core method
}public void runFabricTest(final SampleStore sampleStore) throws Exception {
////////////////////////////
// Setup client
//Create instance of client.
HFClient client = HFClient.createNewInstance();//Initialize a link client similar to Cli.
client.setCryptoSuite(CryptoSuite.Factory.getCryptoSuite());//Set an encryption algorithm. ////////////////////////////
//Construct and run the channels.
//Obtain peer Org1.
SampleOrg sampleOrg = testConfig.getIntegrationTestsSampleOrg("peerOrg1");
//Construct a channel and add Org1 to this channel.
Channel fooChannel = constructChannel(FOO_CHANNEL_NAME, client, sampleOrg);
//Save the channel name to the database (to the preceding method file in this example).
sampleStore.saveChannel(fooChannel);
//Install and instantiate the chain code, and perform a query test.
runChannel(client, fooChannel, true, sampleOrg, 0);
assertFalse(fooChannel.isShutdown());
fooChannel.shutdown(true); // Force foo channel to shutdown clean up resources.
assertTrue(fooChannel.isShutdown());
assertNull(client.getChannel(FOO_CHANNEL_NAME));
out("\n");
//The following code is related to Org2, which is similar to that of Org1.
sampleOrg = testConfig.getIntegrationTestsSampleOrg("peerOrg2");
Channel barChannel = constructChannel(BAR_CHANNEL_NAME, client, sampleOrg);
assertTrue(barChannel.isInitialized());
/**
* sampleStore.saveChannel uses {@link Channel#serializeChannel()}
*/
sampleStore.saveChannel(barChannel);
assertFalse(barChannel.isShutdown());
runChannel(client, barChannel, true, sampleOrg, 100); //run a newly constructed bar channel with different b value!
//let bar channel just shutdown so we have both scenarios.
out("\nTraverse the blocks for chain %s ", barChannel.getName());
//Run various queries on block information, including block read and write sets and block height.
blockWalker(client, barChannel);
assertFalse(barChannel.isShutdown());
assertTrue(barChannel.isInitialized());
out("That's all folks!");
}

Constructing a Channel

client.setUserContext(sampleOrg.getPeerAdmin());
SampleUser peerOrgAdmin = sampleStore.getMember(sampleOrgName + "Admin", sampleOrgName, sampleOrg.getMSPID(),
Util.findFileSk(Paths.get(testConfig.getTestChannelPath(), "crypto-config/peerOrganizations/",
sampleOrgDomainName, format("/users/Admin@%s/msp/keystore", sampleOrgDomainName)).toFile()),
Paths.get(testConfig.getTestChannelPath(), "crypto-config/peerOrganizations/", sampleOrgDomainName,
format("/users/Admin@%s/msp/signcerts/Admin@%s-cert.pem", sampleOrgDomainName, sampleOrgDomainName)).toFile());
sampleOrg.setPeerAdmin(peerOrgAdmin); //A special user that can create channels, join peers and install chaincode
Collection<Orderer> orderers = new LinkedList<>();        for (String orderName : sampleOrg.getOrdererNames()) {            Properties ordererProperties = testConfig.getOrdererProperties(orderName);            //example of setting keepAlive to avoid timeouts on inactive http2 connections.
// Under 5 minutes would require changes to server side to accept faster ping rates.
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTime", new Object[] {5L, TimeUnit.MINUTES});
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveTimeout", new Object[] {8L, TimeUnit.SECONDS});
ordererProperties.put("grpc.NettyChannelBuilderOption.keepAliveWithoutCalls", new Object[] {true});
orderers.add(client.newOrderer(orderName, sampleOrg.getOrdererLocation(orderName),
ordererProperties));
}
defaultProperty(INTEGRATIONTESTS_ORG + "peerOrg1.orderer_locations", "orderer.example.com@grpc://" + LOCALHOST + ":7050");
//Just pick the first orderer in the list to create the channel.        Orderer anOrderer = orderers.iterator().next();
orderers.remove(anOrderer);
ChannelConfiguration channelConfiguration = new ChannelConfiguration(new File(TEST_FIXTURES_PATH + "/sdkintegration/e2e-2Orgs/" + TestConfig.FAB_CONFIG_GEN_VERS + "/" + name + ".tx")); //Create channel that has only one signer that is this orgs peer admin. If channel creation policy needed more signature they would need to be added too.
Channel newChannel = client.newChannel(name, anOrderer, channelConfiguration, client.getChannelConfigurationSignature(channelConfiguration, sampleOrg.getPeerAdmin()));
out("Created channel %s", name);
boolean everyother = true; //test with both cases when doing peer eventing.
for (String peerName : sampleOrg.getPeerNames()) {
String peerLocation = sampleOrg.getPeerLocation(peerName);
Properties peerProperties = testConfig.getPeerProperties(peerName); //test properties for peer.. if any.
if (peerProperties == null) {
peerProperties = new Properties();
}
//Example of setting specific options on grpc's NettyChannelBuilder
peerProperties.put("grpc.NettyChannelBuilderOption.maxInboundMessageSize", 9000000);
Peer peer = client.newPeer(peerName, peerLocation, peerProperties);
if (doPeerEventing && everyother) {
newChannel.joinPeer(peer, createPeerOptions()); //Default is all roles.
} else {
// Set peer to not be all roles but eventing.
newChannel.joinPeer(peer, createPeerOptions().setPeerRoles(PeerRole.NO_EVENT_SOURCE));
}
out("Peer %s joined channel %s", peerName, name);
everyother = !everyother;
}
defaultProperty(INTEGRATIONTESTS_ORG + "peerOrg1.peer_locations", "peer0.org1.example.com@grpc://" + LOCALHOST + ":7051, peer1.org1.example.com@grpc://" + LOCALHOST + ":7056");
for (String eventHubName : sampleOrg.getEventHubNames()) {            final Properties eventHubProperties = testConfig.getEventHubProperties(eventHubName);            eventHubProperties.put("grpc.NettyChannelBuilderOption.keepAliveTime", new Object[] {5L, TimeUnit.MINUTES});
eventHubProperties.put("grpc.NettyChannelBuilderOption.keepAliveTimeout", new Object[] {8L, TimeUnit.SECONDS});
EventHub eventHub = client.newEventHub(eventHubName, sampleOrg.getEventHubLocation(eventHubName),
eventHubProperties);
newChannel.addEventHub(eventHub);
}
newChannel.initialize();

Running the Channel

if (installChaincode) {
//Write a large piece of code to configure information about the chain code to be installed.
//Send a transaction proposal to install the chain code.
responses = client.sendInstallProposal(installProposalRequest, peers);
}
///////////////
//// Instantiate chaincode.
InstantiateProposalRequest instantiateProposalRequest = client.newInstantiationProposalRequest();
instantiateProposalRequest.setProposalWaitTime(testConfig.getProposalWaitTime());
instantiateProposalRequest.setChaincodeID(chaincodeID);
instantiateProposalRequest.setChaincodeLanguage(CHAIN_CODE_LANG);
instantiateProposalRequest.setFcn("init");
instantiateProposalRequest.setArgs(new String[] {"a", "500", "b", "" + (200 + delta)});
Map<String, byte[]> tm = new HashMap<>();
tm.put("HyperLedgerFabric", "InstantiateProposalRequest:JavaSDK".getBytes(UTF_8));
tm.put("method", "InstantiateProposalRequest".getBytes(UTF_8));
instantiateProposalRequest.setTransientMap(tm);
/*
policy OR(Org1MSP.member, Org2MSP.member) meaning 1 signature from someone in either Org1 or Org2
See README.md Chaincode endorsement policies section for more details.
*/
ChaincodeEndorsementPolicy chaincodeEndorsementPolicy = new ChaincodeEndorsementPolicy();
chaincodeEndorsementPolicy.fromYamlFile(new File(TEST_FIXTURES_PATH + "/sdkintegration/chaincodeendorsementpolicy.yaml"));
instantiateProposalRequest.setChaincodeEndorsementPolicy(chaincodeEndorsementPolicy);
out("Sending instantiateProposalRequest to all peers with arguments: a and b set to 100 and %s respectively", "" + (200 + delta));
successful.clear();
failed.clear();
if (isFooChain) { //Send responses both ways with specifying peers and by using those on the channel.
responses = channel.sendInstantiationProposal(instantiateProposalRequest, channel.getPeers());
} else {
responses = channel.sendInstantiationProposal(instantiateProposalRequest);
}
channel.sendTransaction(successful, createTransactionOptions()
.userContext(client.getUserContext())
.shuffleOrders(false)
.orderers(channel.getOrderers())
.nOfEvents(nOfEvents)
).thenApply(transactionEvent -> {
Call the move method in the example_cc.go file to transfer some dollars from a to b.
}.thenApply(transactionEvent -> {
Query the account balance of b.
try {
}).exceptionally(e -> {
//Exception handling
}

--

--

Follow me to keep abreast with the latest technology news, industry insights, and developer trends. Alibaba Cloud website:https://www.alibabacloud.com

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store