Fix while loop bug
parent
504a7ab857
commit
466e37cad0
|
@ -24,7 +24,9 @@ all:
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
||||||
make ready
|
make ready
|
||||||
make lscc qscc
|
make lscc # test lscc operations
|
||||||
|
make qscc # test qscc operations
|
||||||
|
make fetch_blocks # fetch block files
|
||||||
make stop clean
|
make stop clean
|
||||||
|
|
||||||
init: # initialize the fabric network
|
init: # initialize the fabric network
|
||||||
|
@ -99,18 +101,28 @@ test_cc_peer0: # test single peer
|
||||||
docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_peer0.sh"
|
docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_cc_peer0.sh"
|
||||||
|
|
||||||
qscc: # test qscc queries
|
qscc: # test qscc queries
|
||||||
|
@echo "Test QSCC query"
|
||||||
docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_qscc.sh"
|
docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_qscc.sh"
|
||||||
|
|
||||||
lscc: # test lscc quries
|
lscc: # test lscc quries
|
||||||
|
@echo "Test LSCC query"
|
||||||
docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_lscc.sh"
|
docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_lscc.sh"
|
||||||
|
|
||||||
fetch_blocks: # test channel fetch
|
# FIXME: docker doesn't support wildcard in cp right now
|
||||||
|
fetch_blocks: # test fetching channel blocks fetch
|
||||||
|
@echo "Test fetching block files"
|
||||||
docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_fetch.sh"
|
docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_fetch.sh"
|
||||||
docker cp fabric-cli:/tmp/block_0.block kafka/channel-artifacts/
|
if [ "$(HLF_MODE)" = "kafka" ]; then \
|
||||||
docker cp fabric-cli:/tmp/block_1.block kafka/channel-artifacts/
|
docker cp fabric-cli:/tmp/block_0.block kafka/channel-artifacts; \
|
||||||
docker cp fabric-cli:/tmp/block_2.block kafka/channel-artifacts/
|
docker cp fabric-cli:/tmp/block_1.block kafka/channel-artifacts; \
|
||||||
docker cp fabric-cli:/tmp/block_3.block kafka/channel-artifacts/
|
docker cp fabric-cli:/tmp/block_2.block kafka/channel-artifacts; \
|
||||||
|
docker cp fabric-cli:/tmp/block_3.block kafka/channel-artifacts; \
|
||||||
|
else \
|
||||||
|
docker cp fabric-cli:/tmp/block_0.block solo/channel-artifacts; \
|
||||||
|
docker cp fabric-cli:/tmp/block_1.block solo/channel-artifacts; \
|
||||||
|
docker cp fabric-cli:/tmp/block_2.block solo/channel-artifacts; \
|
||||||
|
docker cp fabric-cli:/tmp/block_3.block solo/channel-artifacts; \
|
||||||
|
fi
|
||||||
|
|
||||||
################## Env setup related, no need to see usually ################
|
################## Env setup related, no need to see usually ################
|
||||||
|
|
||||||
|
@ -158,7 +170,7 @@ gen_solo: # generate solo artifacts
|
||||||
gen_kafka: # generate kafka artifacts
|
gen_kafka: # generate kafka artifacts
|
||||||
cd kafka && bash gen_artifacts.sh
|
cd kafka && bash gen_artifacts.sh
|
||||||
|
|
||||||
configtxlator: # run configtxlator
|
test_configtxlator: # Test change config using configtxlator
|
||||||
cd kafka && bash run_configtxlator.sh
|
cd kafka && bash run_configtxlator.sh
|
||||||
|
|
||||||
download: # download required images
|
download: # download required images
|
||||||
|
@ -168,7 +180,6 @@ download: # download required images
|
||||||
docker pull hyperledger/fabric-baseos:x86_64-0.4.2
|
docker pull hyperledger/fabric-baseos:x86_64-0.4.2
|
||||||
docker tag yeasy/hyperledger-fabric:latest hyperledger/fabric-ccenv:x86_64-1.1.0
|
docker tag yeasy/hyperledger-fabric:latest hyperledger/fabric-ccenv:x86_64-1.1.0
|
||||||
|
|
||||||
|
|
||||||
################## chaincode dev mode ################
|
################## chaincode dev mode ################
|
||||||
chaincode_init: # start chaincode in dev mode and do install/instantiate
|
chaincode_init: # start chaincode in dev mode and do install/instantiate
|
||||||
@echo "Install and instantiate cc example02 on the fabric dev network"
|
@echo "Install and instantiate cc example02 on the fabric dev network"
|
||||||
|
|
|
@ -82,7 +82,7 @@ You should see result like the following if the initialization is successful.
|
||||||
==========initialize businesschannel==========
|
==========initialize businesschannel==========
|
||||||
==============================================
|
==============================================
|
||||||
|
|
||||||
Channel name : businesschannel
|
Channel name: businesschannel
|
||||||
Creating channel...
|
Creating channel...
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
# https://github.com/yeasy/docker-compose-files/tree/master/hyperledger
|
||||||
|
# This compose file will start a Hyperledger Fabric 1.0 MVE, including
|
||||||
|
# * 2 ca (not in use now)
|
||||||
|
# * 1 orderer
|
||||||
|
# * 4 peers in 2 orgs
|
||||||
|
# * cli for testing
|
||||||
|
# * blockchain-explorer
|
||||||
|
|
||||||
|
version: '2.0'
|
||||||
|
|
||||||
|
services:
|
||||||
|
# ca.org1.example.com:
|
||||||
|
# extends:
|
||||||
|
# file: base-solo.yaml
|
||||||
|
# service: ca.org1.example.com
|
||||||
|
|
||||||
|
# ca.org2.example.com:
|
||||||
|
# extends:
|
||||||
|
# file: base-solo.yaml
|
||||||
|
# service: ca.org2.example.com
|
||||||
|
|
||||||
|
cli:
|
||||||
|
extends:
|
||||||
|
file: base-solo.yaml
|
||||||
|
service: cli
|
||||||
|
|
||||||
|
orderer.example.com: # There can be multiple orderers
|
||||||
|
extends:
|
||||||
|
file: base-solo.yaml
|
||||||
|
service: orderer.example.com
|
||||||
|
|
||||||
|
peer0.org1.example.com:
|
||||||
|
extends:
|
||||||
|
file: base-solo.yaml
|
||||||
|
service: peer0.org1.example.com
|
||||||
|
|
||||||
|
peer1.org1.example.com:
|
||||||
|
extends:
|
||||||
|
file: base-solo.yaml
|
||||||
|
service: peer1.org1.example.com
|
||||||
|
|
||||||
|
peer0.org2.example.com:
|
||||||
|
extends:
|
||||||
|
file: base-solo.yaml
|
||||||
|
service: peer0.org2.example.com
|
||||||
|
|
||||||
|
peer1.org2.example.com:
|
||||||
|
extends:
|
||||||
|
file: base-solo.yaml
|
||||||
|
service: peer1.org2.example.com
|
||||||
|
|
||||||
|
explorer:
|
||||||
|
image: yeasy/blockchain-explorer:latest
|
||||||
|
container_name: explorer
|
||||||
|
hostname: explorer
|
||||||
|
depends_on:
|
||||||
|
- mysql
|
||||||
|
volumes:
|
||||||
|
- ./config.json:/blockchain-explorer/config.json
|
||||||
|
- ./solo/crypto-config:/blockchain-explorer/first-network/crypto-config
|
||||||
|
ports:
|
||||||
|
- "8080:8080" # HTTP port
|
||||||
|
command: bash -c 'node main.js'
|
||||||
|
|
||||||
|
mysql: # mysql service
|
||||||
|
image: mysql:8.0
|
||||||
|
container_name: mysql
|
||||||
|
hostname: mysql
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
- MYSQL_ROOT_PASSWORD=root
|
||||||
|
- MYSQL_DATABASE=fabricexplorer
|
||||||
|
volumes:
|
||||||
|
- ./fabricexplorer.sql:/docker-entrypoint-initdb.d/fabricexplorer.sql
|
||||||
|
expose:
|
||||||
|
- "3306"
|
||||||
|
#command: bash -c 'mysqld; sleep 1; mysql -uroot -proot < /tmp/fabricexplorer.sql; while true; do sleep 20171117; done'
|
||||||
|
#networks:
|
||||||
|
# default:
|
||||||
|
# external:
|
||||||
|
# name: hyperledger_fabric
|
|
@ -48,32 +48,6 @@ services:
|
||||||
file: base-solo.yaml
|
file: base-solo.yaml
|
||||||
service: peer1.org2.example.com
|
service: peer1.org2.example.com
|
||||||
|
|
||||||
explorer:
|
|
||||||
image: yeasy/blockchain-explorer:latest
|
|
||||||
container_name: explorer
|
|
||||||
hostname: explorer
|
|
||||||
depends_on:
|
|
||||||
- mysql
|
|
||||||
volumes:
|
|
||||||
- ./config.json:/blockchain-explorer/config.json
|
|
||||||
- ./solo/crypto-config:/blockchain-explorer/first-network/crypto-config
|
|
||||||
ports:
|
|
||||||
- "8080:8080" # HTTP port
|
|
||||||
command: bash -c 'node main.js'
|
|
||||||
|
|
||||||
mysql: # mysql service
|
|
||||||
image: mysql:8.0
|
|
||||||
container_name: mysql
|
|
||||||
hostname: mysql
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
- MYSQL_ROOT_PASSWORD=root
|
|
||||||
- MYSQL_DATABASE=fabricexplorer
|
|
||||||
volumes:
|
|
||||||
- ./fabricexplorer.sql:/docker-entrypoint-initdb.d/fabricexplorer.sql
|
|
||||||
expose:
|
|
||||||
- "3306"
|
|
||||||
#command: bash -c 'mysqld; sleep 1; mysql -uroot -proot < /tmp/fabricexplorer.sql; while true; do sleep 20171117; done'
|
|
||||||
#networks:
|
#networks:
|
||||||
# default:
|
# default:
|
||||||
# external:
|
# external:
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
Profiles:
|
Profiles:
|
||||||
|
|
||||||
TwoOrgsOrdererGenesis:
|
TwoOrgsOrdererGenesis: # Used to generate genesis block for system channel
|
||||||
Orderer:
|
Orderer:
|
||||||
<<: *OrdererDefaults
|
<<: *OrdererDefaults
|
||||||
Organizations:
|
Organizations:
|
||||||
|
@ -24,7 +24,8 @@ Profiles:
|
||||||
Organizations:
|
Organizations:
|
||||||
- *Org1
|
- *Org1
|
||||||
- *Org2
|
- *Org2
|
||||||
TwoOrgsChannel:
|
|
||||||
|
TwoOrgsChannel: # used for application channel
|
||||||
Consortium: SampleConsortium
|
Consortium: SampleConsortium
|
||||||
Application:
|
Application:
|
||||||
<<: *ApplicationDefaults
|
<<: *ApplicationDefaults
|
||||||
|
@ -32,6 +33,15 @@ Profiles:
|
||||||
- *Org1
|
- *Org1
|
||||||
- *Org2
|
- *Org2
|
||||||
|
|
||||||
|
ThreeOrgsChannel: # used for application channel
|
||||||
|
Consortium: SampleConsortium
|
||||||
|
Application:
|
||||||
|
<<: *ApplicationDefaults
|
||||||
|
Organizations:
|
||||||
|
- *Org1
|
||||||
|
- *Org2
|
||||||
|
- *Org3
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
# Section: Organizations
|
# Section: Organizations
|
||||||
|
@ -89,6 +99,23 @@ Organizations:
|
||||||
- Host: peer0.org2.example.com
|
- Host: peer0.org2.example.com
|
||||||
Port: 7051
|
Port: 7051
|
||||||
|
|
||||||
|
- &Org3
|
||||||
|
# DefaultOrg defines the organization which is used in the sampleconfig
|
||||||
|
# of the fabric.git development environment
|
||||||
|
Name: Org3MSP
|
||||||
|
|
||||||
|
# ID to load the MSP definition as
|
||||||
|
ID: Org2MSP
|
||||||
|
|
||||||
|
MSPDir: crypto-config/peerOrganizations/org3.example.com/msp
|
||||||
|
|
||||||
|
AnchorPeers:
|
||||||
|
# AnchorPeers defines the location of peers which can be used
|
||||||
|
# for cross org gossip communication. Note, this value is only
|
||||||
|
# encoded in the genesis block in the Application section context
|
||||||
|
- Host: peer0.org3.example.com
|
||||||
|
Port: 7051
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
#
|
#
|
||||||
# SECTION: Orderer
|
# SECTION: Orderer
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
# Demo to use configtxlator to modify orderer config
|
||||||
# More details about configtxlator, see http://hlf.readthedocs.io/en/latest/configtxlator.html
|
# More details about configtxlator, see http://hlf.readthedocs.io/en/latest/configtxlator.html
|
||||||
|
|
||||||
CONFIGTXLATOR_IMG=yeasy/hyperledger-fabric:latest
|
CONFIGTXLATOR_IMG=yeasy/hyperledger-fabric:latest
|
||||||
CONFIGTXLATOR_CONTAINER=configtxlator
|
CONFIGTXLATOR_CONTAINER=configtxlator
|
||||||
|
|
||||||
|
# Must run `make gen_kafka` to generate artifacts files first
|
||||||
ARTIFACTS_DIR=channel-artifacts
|
ARTIFACTS_DIR=channel-artifacts
|
||||||
|
|
||||||
ORDERER_GENESIS_BLOCK=${ARTIFACTS_DIR}/orderer.genesis.block
|
ORDERER_GENESIS_BLOCK=${ARTIFACTS_DIR}/orderer.genesis.block
|
|
@ -20,7 +20,7 @@ elif [ -f scripts/variables.sh ]; then
|
||||||
source scripts/variables.sh
|
source scripts/variables.sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Verify $1 is not 0, then output error msg $2
|
# Verify $1 is not 0, then output error msg $2 and exit
|
||||||
verifyResult () {
|
verifyResult () {
|
||||||
if [ $1 -ne 0 ] ; then
|
if [ $1 -ne 0 ] ; then
|
||||||
echo_b "$2"
|
echo_b "$2"
|
||||||
|
@ -107,23 +107,25 @@ channelCreateAction(){
|
||||||
}
|
}
|
||||||
|
|
||||||
# Use peer0/org1 to create a channel
|
# Use peer0/org1 to create a channel
|
||||||
|
# channelCreate channel_name
|
||||||
channelCreate() {
|
channelCreate() {
|
||||||
local channel=$1
|
local channel=$1
|
||||||
|
echo_b "=== Create Channel ${channel} === "
|
||||||
local counter=0
|
local counter=0
|
||||||
local res=1
|
|
||||||
echo_b "=== Create Channel ${channel}\" === "
|
|
||||||
setGlobals 0
|
setGlobals 0
|
||||||
while [ $counter -lt ${MAX_RETRY} -a ${res} -ne 0 ]; do
|
channelCreateAction ${channel}
|
||||||
res=$(channelCreateAction ${channel})
|
local res=$?
|
||||||
|
while [ ${counter} -lt ${MAX_RETRY} -a ${res} -ne 0 ]; do
|
||||||
|
echo_b "Failed to create channel $channel, retry after 3s"
|
||||||
|
sleep 3
|
||||||
|
channelCreateAction ${channel}
|
||||||
|
res=$?
|
||||||
let counter=${counter}+1
|
let counter=${counter}+1
|
||||||
#COUNTER=` expr $COUNTER + 1`
|
#COUNTER=` expr $COUNTER + 1`
|
||||||
echo_b "Fail to create channel ${channel}, Retry after 3 seconds"
|
|
||||||
sleep 3
|
|
||||||
done
|
done
|
||||||
cat log.txt
|
cat log.txt
|
||||||
verifyResult ${res} "Channel creation failed"
|
verifyResult ${res} "Channel ${channel} creation failed"
|
||||||
echo_g "=== Channel ${channel} is created successfully === "
|
echo_g "=== Channel ${channel} is created. === "
|
||||||
echo
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# called by channelJoinWithRetry
|
# called by channelJoinWithRetry
|
||||||
|
@ -138,22 +140,24 @@ channelJoinWithRetry () {
|
||||||
local channel=$1
|
local channel=$1
|
||||||
local peer=$2
|
local peer=$2
|
||||||
local counter=0
|
local counter=0
|
||||||
local res=1
|
channelJoinAction ${channel}
|
||||||
|
local res=$?
|
||||||
while [ ${counter} -lt ${MAX_RETRY} -a ${res} -ne 0 ]; do
|
while [ ${counter} -lt ${MAX_RETRY} -a ${res} -ne 0 ]; do
|
||||||
res=$(channelJoinAction ${channel})
|
echo_b "peer${peer} failed to join channel ${channel}, retry after 2s"
|
||||||
let counter=$counter+1
|
|
||||||
echo_b "peer${peer} failed to join the channel, Retry after 2 seconds"
|
|
||||||
sleep 2
|
sleep 2
|
||||||
|
channelJoinAction ${channel}
|
||||||
|
res=$?
|
||||||
|
let counter=${counter}+1
|
||||||
done
|
done
|
||||||
cat log.txt
|
cat log.txt
|
||||||
verifyResult $res "After $MAX_RETRY attempts, peer${peer} has failed to Join the Channel"
|
verifyResult ${res} "After $MAX_RETRY attempts, peer${peer} failed to Join the Channel"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Join given (by default all) peers into the channel
|
# Join given (by default all) peers into the channel
|
||||||
# channelJoin 0 1 2 3
|
# channelJoin 0 1 2 3
|
||||||
channelJoin () {
|
channelJoin () {
|
||||||
local channel=$1
|
local channel=$1
|
||||||
echo_b "=== Join peers into the channel ${channel} === "
|
echo_b "=== Join peers into channel ${channel} === "
|
||||||
peers_to_join=$(seq 0 3)
|
peers_to_join=$(seq 0 3)
|
||||||
if [ $# -gt 1 ]; then
|
if [ $# -gt 1 ]; then
|
||||||
peers_to_join=${@:2}
|
peers_to_join=${@:2}
|
||||||
|
@ -161,7 +165,7 @@ channelJoin () {
|
||||||
for i in $peers_to_join; do
|
for i in $peers_to_join; do
|
||||||
setGlobals $i
|
setGlobals $i
|
||||||
channelJoinWithRetry ${channel} $i
|
channelJoinWithRetry ${channel} $i
|
||||||
echo_g "=== peer$i joined into the channel \"${channel}\" === "
|
echo_g "=== peer$i joined into channel ${channel} === "
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
@ -191,7 +195,7 @@ updateAnchorPeers() {
|
||||||
res=$?
|
res=$?
|
||||||
cat log.txt
|
cat log.txt
|
||||||
verifyResult $res "Anchor peer update failed"
|
verifyResult $res "Anchor peer update failed"
|
||||||
echo_g "=== Anchor peers for org \"$CORE_PEER_LOCALMSPID\" on ${channel} is updated successfully === "
|
echo_g "=== Anchor peers for org \"$CORE_PEER_LOCALMSPID\" on ${channel} is updated. === "
|
||||||
sleep 2
|
sleep 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,19 +388,19 @@ chaincodeUpgrade () {
|
||||||
channelFetch () {
|
channelFetch () {
|
||||||
local channel=$1
|
local channel=$1
|
||||||
local peer=$2
|
local peer=$2
|
||||||
local blockNum=$3
|
local num=$3
|
||||||
echo_b "=== Fetch block $blockNum on peer$peer in channel '$channel' === "
|
echo_b "=== Fetch block $num on peer$peer in channel '$channel' === "
|
||||||
|
|
||||||
setGlobals $peer
|
setGlobals $peer
|
||||||
# while 'peer chaincode' command can get the orderer endpoint from the peer (if join was successful),
|
# while 'peer chaincode' command can get the orderer endpoint from the peer (if join was successful),
|
||||||
# lets supply it directly as we know it using the "-o" option
|
# lets supply it directly as we know it using the "-o" option
|
||||||
if [ -z "${CORE_PEER_TLS_ENABLED}" -o "${CORE_PEER_TLS_ENABLED}" = "false" ]; then
|
if [ -z "${CORE_PEER_TLS_ENABLED}" -o "${CORE_PEER_TLS_ENABLED}" = "false" ]; then
|
||||||
peer channel fetch $blockNum block_${blockNum}.block \
|
peer channel fetch $num ${channel}_block_${num}.block \
|
||||||
-o ${ORDERER_URL} \
|
-o ${ORDERER_URL} \
|
||||||
-c ${channel} \
|
-c ${channel} \
|
||||||
>&log.txt
|
>&log.txt
|
||||||
else
|
else
|
||||||
peer channel fetch $blockNum block_${blockNum}.block \
|
peer channel fetch $num block_${num}.block \
|
||||||
-o ${ORDERER_URL} \
|
-o ${ORDERER_URL} \
|
||||||
-c ${channel} \
|
-c ${channel} \
|
||||||
--tls \
|
--tls \
|
||||||
|
|
|
@ -14,7 +14,7 @@ echo " ==========initialize businesschannel========== "
|
||||||
echo " ============================================== "
|
echo " ============================================== "
|
||||||
echo
|
echo
|
||||||
|
|
||||||
echo_b "Channel name : "$CHANNEL_NAME
|
echo_b "Channel name: "$CHANNEL_NAME
|
||||||
|
|
||||||
## Create channel
|
## Create channel
|
||||||
echo_b "Creating channel..."
|
echo_b "Creating channel..."
|
||||||
|
|
|
@ -7,7 +7,7 @@ elif [ -f scripts/func.sh ]; then
|
||||||
source scripts/func.sh
|
source scripts/func.sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo_b "Channel name : "$CHANNEL_NAME
|
echo_b "Channel name: "$CHANNEL_NAME
|
||||||
|
|
||||||
#Query on chaincode on Peer0/Org1
|
#Query on chaincode on Peer0/Org1
|
||||||
echo_b "Querying chaincode on peer 3..."
|
echo_b "Querying chaincode on peer 3..."
|
||||||
|
|
|
@ -18,31 +18,31 @@ echo_b "LSCC testing"
|
||||||
|
|
||||||
setGlobals 0
|
setGlobals 0
|
||||||
|
|
||||||
echo_b "Get id"
|
echo_b "LSCC Get id"
|
||||||
peer chaincode query \
|
peer chaincode query \
|
||||||
-C "${CHANNEL_NAME}" \
|
-C "${CHANNEL_NAME}" \
|
||||||
-n lscc \
|
-n lscc \
|
||||||
-c '{"Args":["getid","'${CHANNEL_NAME}'", "mycc"]}'
|
-c '{"Args":["getid","'${CHANNEL_NAME}'", "'$CC_NAME'"]}'
|
||||||
|
|
||||||
echo_b "Get cc ChaincodeDeploymentSpec"
|
echo_b "LSCC Get cc ChaincodeDeploymentSpec"
|
||||||
peer chaincode query \
|
peer chaincode query \
|
||||||
-C "${CHANNEL_NAME}" \
|
-C "${CHANNEL_NAME}" \
|
||||||
-n lscc \
|
-n lscc \
|
||||||
-c '{"Args":["getdepspec","'${CHANNEL_NAME}'", "mycc"]}'
|
-c '{"Args":["getdepspec","'${CHANNEL_NAME}'", "'$CC_NAME'"]}'
|
||||||
|
|
||||||
echo_b "Get cc bytes"
|
echo_b "LSCC Get cc bytes"
|
||||||
peer chaincode query \
|
peer chaincode query \
|
||||||
-C "${CHANNEL_NAME}" \
|
-C "${CHANNEL_NAME}" \
|
||||||
-n lscc \
|
-n lscc \
|
||||||
-c '{"Args":["getccdata","'${CHANNEL_NAME}'", "mycc"]}'
|
-c '{"Args":["getccdata","'${CHANNEL_NAME}'", "'$CC_NAME'"]}'
|
||||||
|
|
||||||
echo_b "Get all chaincodes installed on the channel"
|
echo_b "LSCC Get all chaincodes installed on the channel"
|
||||||
peer chaincode query \
|
peer chaincode query \
|
||||||
-C "${CHANNEL_NAME}" \
|
-C "${CHANNEL_NAME}" \
|
||||||
-n lscc \
|
-n lscc \
|
||||||
-c '{"Args":["getinstalledchaincodes"]}'
|
-c '{"Args":["getinstalledchaincodes"]}'
|
||||||
|
|
||||||
echo_b "Get all chaincodes instantiated on the channel"
|
echo_b "LSCC Get all chaincodes instantiated on the channel"
|
||||||
peer chaincode query \
|
peer chaincode query \
|
||||||
-C "${CHANNEL_NAME}" \
|
-C "${CHANNEL_NAME}" \
|
||||||
-n lscc \
|
-n lscc \
|
||||||
|
|
|
@ -9,6 +9,8 @@ elif [ -f scripts/func.sh ]; then
|
||||||
source scripts/func.sh
|
source scripts/func.sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo_b "QSCC testing"
|
||||||
|
|
||||||
setGlobals 0
|
setGlobals 0
|
||||||
|
|
||||||
echo_b "QSCC GetChainInfo"
|
echo_b "QSCC GetChainInfo"
|
||||||
|
@ -23,4 +25,4 @@ peer chaincode query \
|
||||||
-n qscc \
|
-n qscc \
|
||||||
-c '{"Args":["GetBlockByNumber","'${CHANNEL_NAME}'","2"]}'
|
-c '{"Args":["GetBlockByNumber","'${CHANNEL_NAME}'","2"]}'
|
||||||
|
|
||||||
echo_g "Qscc testing done!"
|
echo_g "QSCC testing done!"
|
|
@ -19,7 +19,6 @@ ORG2_PEER0_TLS_ROOTCERT=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypt
|
||||||
ORG1_ADMIN_MSP=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
|
ORG1_ADMIN_MSP=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
|
||||||
ORG2_ADMIN_MSP=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
|
ORG2_ADMIN_MSP=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
|
||||||
|
|
||||||
|
|
||||||
# Node URLS
|
# Node URLS
|
||||||
ORDERER_URL="orderer.example.com:7050"
|
ORDERER_URL="orderer.example.com:7050"
|
||||||
ORG1_PEER0_URL="peer0.org1.example.com:7051"
|
ORG1_PEER0_URL="peer0.org1.example.com:7051"
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,871 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
//"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
//"strconv"
|
||||||
|
//"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/hyperledger/fabric/core/chaincode/shim"
|
||||||
|
pb "github.com/hyperledger/fabric/protos/peer"
|
||||||
|
)
|
||||||
|
|
||||||
|
//=============================================================================================================================================================================
|
||||||
|
|
||||||
|
// Structs
|
||||||
|
|
||||||
|
//=============================================================================================================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type SimpleChaincode struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type user struct {
|
||||||
|
|
||||||
|
Firstname string `json:"firstname"`
|
||||||
|
Lastname string `json:"lastname"`
|
||||||
|
userID string `json:"userid"`
|
||||||
|
DOB string `json:"dob"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Mobile string `json:"mobile"`
|
||||||
|
Class string `json:"class"`
|
||||||
|
ObjectType string `json:"docType"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RawMaterial struct {
|
||||||
|
|
||||||
|
RMID string `json:"rmid"`
|
||||||
|
Item string `json:"item"`
|
||||||
|
Creator string `json:"creator"`
|
||||||
|
Current_Owner string `json:"currentowner"`
|
||||||
|
ClaimTags string `json:"claimtags"`
|
||||||
|
Location string `json:"location"`
|
||||||
|
Date string `json:"date"`
|
||||||
|
CertID string `json:"certid"`
|
||||||
|
ObjectType string `json:"docType"`
|
||||||
|
// add quality
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type FinishedGood struct {
|
||||||
|
FPID string `json:"fpid"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Creator string `json:"creator"`
|
||||||
|
Current_Owner string `json:"currentowner"`
|
||||||
|
Ingredients string `json:"ingredients"`
|
||||||
|
//Previous_Owner string `json:"previousowner"`
|
||||||
|
Certificates string `json:"certificates"`
|
||||||
|
ClaimTags string `json:"claimtags"`
|
||||||
|
Location string `json:"location"`
|
||||||
|
Date string `json:"date"`
|
||||||
|
CertID string `json:"certid"`
|
||||||
|
ObjectType string `json:"docType"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PurchaseOrder struct{
|
||||||
|
|
||||||
|
PurchaseOrderID string `json:"purchaseorderid"`
|
||||||
|
Customer string `json:"customer"`
|
||||||
|
Vendor string `json:"vendor"`
|
||||||
|
ProductID string `json:"productid"`
|
||||||
|
Price string `json:"price"`
|
||||||
|
Date string `json:"date"`
|
||||||
|
// Status string `json:"status"`
|
||||||
|
ObjectType string `json:"docType"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Certificate struct {
|
||||||
|
|
||||||
|
CertID string `json:"certid"`
|
||||||
|
OrgName string `json:"orgname"`
|
||||||
|
Supplier string `json:"supplier"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Date_effective string `json:"dateeffective"`
|
||||||
|
Certifier string `json:"certifier"`
|
||||||
|
ProductList string `json:"productlist"`
|
||||||
|
OpDetails string `json:"opdetails"`
|
||||||
|
Location string `json:"location"`
|
||||||
|
ExpiryDate string `json:"expdate"`
|
||||||
|
ObjectType string `json:"docType"`
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =============================================================================================================================================================
|
||||||
|
|
||||||
|
// MAIN FUNCTIONS
|
||||||
|
|
||||||
|
// ==============================================================================================================================================================
|
||||||
|
func main() {
|
||||||
|
err := shim.Start(new(SimpleChaincode))
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error starting Simple chaincode: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init initializes chaincode
|
||||||
|
// ===========================
|
||||||
|
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
|
||||||
|
var err error
|
||||||
|
err = stub.PutState("status", []byte("Blockchain online")) //write the variable into the chaincode state
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return shim.Success(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke - Our entry point for Invocations
|
||||||
|
// ========================================
|
||||||
|
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
|
||||||
|
function, args := stub.GetFunctionAndParameters()
|
||||||
|
fmt.Println("invoke is running " + function)
|
||||||
|
|
||||||
|
// Handle different functions
|
||||||
|
if function == "Register" { //create a new user
|
||||||
|
return t.Register(stub, args)
|
||||||
|
} else if function == "RegisterRM" {
|
||||||
|
return t.RegisterRM(stub, args)
|
||||||
|
} else if function == "RegisterFP" {
|
||||||
|
return t.RegisterFP(stub, args)
|
||||||
|
} else if function == "makePurchaseOrder" {
|
||||||
|
return t.makePurchaseOrder(stub, args)
|
||||||
|
} else if function == "replyPurchaseOrder" {
|
||||||
|
return t.replyPurchaseOrder(stub, args)
|
||||||
|
} else if function == "transferRM" {
|
||||||
|
return t.transferRM(stub, args)
|
||||||
|
} else if function == "transferFP" {
|
||||||
|
return t.transferFP(stub, args)
|
||||||
|
} else if function == "awardCert" {
|
||||||
|
return t.awardCert(stub, args)
|
||||||
|
} else if function == "requestCert" {
|
||||||
|
return t.requestCert(stub, args)
|
||||||
|
} else if function == "read" {
|
||||||
|
return t.read(stub, args)
|
||||||
|
} else if function == "getHistory" {
|
||||||
|
return t.getHistory(stub, args)
|
||||||
|
} else if function == "modifyCert" {
|
||||||
|
return t.modifyCert(stub, args)
|
||||||
|
} else if function == "getHistoryFG" {
|
||||||
|
return t.getHistoryFG(stub, args)
|
||||||
|
}
|
||||||
|
fmt.Println("invoke did not find func: " + function) //error
|
||||||
|
return shim.Error("Received unknown function invocation")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================================================================================================================
|
||||||
|
|
||||||
|
// REGISTRATION CODE BELOW
|
||||||
|
|
||||||
|
//=============================================================================================================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (t *SimpleChaincode) Register(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// Firstname string `json:"firstname"` 0
|
||||||
|
// Lastname string `json:"lastname"` 1
|
||||||
|
// userID string `json:"userid"` 2
|
||||||
|
// DOB string `json:"dob"` 3
|
||||||
|
// Email string `json:"email"` 4
|
||||||
|
// Mobile string `json:"mobile"` 5
|
||||||
|
// Class string `json:"class"` 6
|
||||||
|
|
||||||
|
|
||||||
|
if len(args) != 7 {
|
||||||
|
return shim.Error("Incorrect number of arguments. Expecting 7")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==== Input sanitation ====
|
||||||
|
|
||||||
|
fname := args[0]
|
||||||
|
lname := args[1]
|
||||||
|
uid := args[2]
|
||||||
|
userdob := args[3]
|
||||||
|
useremail := args[4]
|
||||||
|
usermobile := args[5]
|
||||||
|
userclass := args[6]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ==== Check if user already exists ====
|
||||||
|
fnameAsBytes, err := stub.GetState(uid) //Change this to uid not fname
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error("Failed to get user: " + err.Error())
|
||||||
|
} else if fnameAsBytes != nil {
|
||||||
|
fmt.Println("This user already exists: " + fname)
|
||||||
|
return shim.Error("This user already exists: " + fname)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==== Create user object and marshal to JSON ====
|
||||||
|
objectType := "user"
|
||||||
|
user := &user{fname, lname, uid, userdob, useremail, usermobile, userclass, objectType}
|
||||||
|
userJSONasBytes, err := json.Marshal(user)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// === Save user to state ===
|
||||||
|
err = stub.PutState(uid, userJSONasBytes)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
//this should be uid based range query, needs to be tested
|
||||||
|
// Index
|
||||||
|
indexName := "uid~fname"
|
||||||
|
uidIndexKey, err := stub.CreateCompositeKey(indexName, []string{user.userID, user.Firstname})
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
// Save index entry to state. Only the key name is needed, no need to store a duplicate copy of the user.
|
||||||
|
// Note - passing a 'nil' value will effectively delete the key from state, therefore we pass null character as value
|
||||||
|
value := []byte{0x00}
|
||||||
|
stub.PutState(uidIndexKey, value)
|
||||||
|
|
||||||
|
// ==== user saved and indexed. Return success ====
|
||||||
|
fmt.Println("- end init user")
|
||||||
|
return shim.Success(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (t *SimpleChaincode) RegisterRM(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// RMID string `json:"rmid"` 0
|
||||||
|
// Item string `json:"item"` 1
|
||||||
|
// Creator string `json:"creator"` 2
|
||||||
|
// Current_Owner string `json:"currentowner"` 3
|
||||||
|
// ClaimTags string `json:"claimtags"` 4
|
||||||
|
// Location string `json:"location"` 5
|
||||||
|
// Date string `json:"date"` 6
|
||||||
|
// CertID string `json:"certid"` 7
|
||||||
|
// ObjectType string `json:"docType"` 8
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ==== Input sanitation ====
|
||||||
|
|
||||||
|
rawid := args[0]
|
||||||
|
item := args[1]
|
||||||
|
originalcreator := args[2]
|
||||||
|
cowner := args[3]
|
||||||
|
claimtags := args[4]
|
||||||
|
loc := args[5]
|
||||||
|
dates := args[6]
|
||||||
|
userclass := args[7]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ==== Check if RM already exists ====
|
||||||
|
rawidAsBytes, err := stub.GetState(rawid)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error("Failed to get user: " + err.Error())
|
||||||
|
} else if rawidAsBytes != nil {
|
||||||
|
fmt.Println("This user already exists: " + rawid)
|
||||||
|
return shim.Error("This user already exists: " + rawid)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==== Create RM object and marshal to JSON ====
|
||||||
|
objectType := "RawMaterial"
|
||||||
|
RawMaterial := &RawMaterial{rawid, item, originalcreator, cowner, claimtags, loc, dates, userclass, objectType}
|
||||||
|
RawMaterialJSONasBytes, err := json.Marshal(RawMaterial)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// === Save RM to state ===
|
||||||
|
err = stub.PutState(rawid, RawMaterialJSONasBytes)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Index
|
||||||
|
indexName := "rawid~cowner"
|
||||||
|
rawidIndexKey, err := stub.CreateCompositeKey(indexName, []string{RawMaterial.RMID, RawMaterial.Current_Owner})
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
// Save index entry to state. Only the key name is needed, no need to store a duplicate copy of the user.
|
||||||
|
// Note - passing a 'nil' value will effectively delete the key from state, therefore we pass null character as value
|
||||||
|
value := []byte{0x00}
|
||||||
|
stub.PutState(rawidIndexKey, value)
|
||||||
|
|
||||||
|
// ==== RM saved and indexed. Return success ====
|
||||||
|
fmt.Println("- end init user")
|
||||||
|
return shim.Success(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (t *SimpleChaincode) RegisterFP(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// ObjectType string `json:"docType"` 0
|
||||||
|
// FPID string `json:"fpid"` 1
|
||||||
|
// Name string `json:"name"` 2
|
||||||
|
// Creator string `json:"creator"` 3
|
||||||
|
// Current_Owner string `json:"currentowner"` 4
|
||||||
|
// Ingredients string `json:"ingredients"` 5
|
||||||
|
////Previous_Owner string `json:"previousowner"` 6
|
||||||
|
// Certificates string `json:"certificates"` 7
|
||||||
|
// ClaimTags string `json:"claimtags"` 8
|
||||||
|
// Location string `json:"location"` 9
|
||||||
|
// Date string `json:"date"` 10
|
||||||
|
// CertID string `json:"certid"` 11
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ==== Input sanitation ====
|
||||||
|
|
||||||
|
fpid_i := args[0]
|
||||||
|
name_i := args[1]
|
||||||
|
originalcreator_i := args[2]
|
||||||
|
cowner_i := args[3]
|
||||||
|
ingredients_i := args[4]
|
||||||
|
certificates_i := args[5]
|
||||||
|
claimtags_i := args[6]
|
||||||
|
loc_i := args[7]
|
||||||
|
dates_i := args[8]
|
||||||
|
certid_i := args[9]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ==== Check if FP already exists ====
|
||||||
|
fpid_iAsBytes, err := stub.GetState(fpid_i)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error("Failed to get user: " + err.Error())
|
||||||
|
} else if fpid_iAsBytes != nil {
|
||||||
|
fmt.Println("This user already exists: " + fpid_i)
|
||||||
|
return shim.Error("This user already exists: " + fpid_i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==== Create object and marshal to JSON ====
|
||||||
|
objectType := "FinishedGood"
|
||||||
|
FinishedGood := &FinishedGood{fpid_i, name_i, originalcreator_i, cowner_i, ingredients_i, certificates_i, claimtags_i, loc_i, dates_i, certid_i, objectType}
|
||||||
|
FinishedGoodJSONasBytes, err := json.Marshal(FinishedGood)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// === Save FP to state ===
|
||||||
|
err = stub.PutState(fpid_i, FinishedGoodJSONasBytes)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
//Index
|
||||||
|
indexName := "fpid_i~cowner"
|
||||||
|
fpiIndexKey, err := stub.CreateCompositeKey(indexName, []string{FinishedGood.FPID, FinishedGood.Current_Owner})
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
// Save index entry to state. Only the key name is needed, no need to store a duplicate copy of the user.
|
||||||
|
// Note - passing a 'nil' value will effectively delete the key from state, therefore we pass null character as value
|
||||||
|
value := []byte{0x00}
|
||||||
|
stub.PutState(fpiIndexKey, value)
|
||||||
|
|
||||||
|
// ==== FP saved and indexed. Return success ====
|
||||||
|
fmt.Println("- end init user")
|
||||||
|
return shim.Success(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================================================================================================================
|
||||||
|
|
||||||
|
// Purchase Orders
|
||||||
|
|
||||||
|
//=============================================================================================================================================================================
|
||||||
|
|
||||||
|
func (t *SimpleChaincode) makePurchaseOrder(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// PurchaseOrderID string `json:"purchaseorderid"` 0
|
||||||
|
// Customer string `json:"customer"` 1
|
||||||
|
// Vendor string `json:"vendor"` 2
|
||||||
|
// ProductID string `json:"productid"` 3
|
||||||
|
// Price string `json:"price"` 4
|
||||||
|
// Date string `json:"date"` 5
|
||||||
|
// Status string `json:"status"` Pending
|
||||||
|
// ObjectType string `json:"docType"` PurchaseOrder
|
||||||
|
|
||||||
|
// ==== Input sanitation ====
|
||||||
|
|
||||||
|
purchid := args[0]
|
||||||
|
cust := args[1]
|
||||||
|
vend := args[2]
|
||||||
|
prodid := args[3]
|
||||||
|
price:= args[4]
|
||||||
|
dat := args[5]
|
||||||
|
//stat := "Pending"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ==== Check if order already exists ====
|
||||||
|
purchAsBytes, err := stub.GetState(purchid)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error("Failed to get product: " + err.Error())
|
||||||
|
} else if purchAsBytes != nil {
|
||||||
|
fmt.Println("This product already exists: " + purchid)
|
||||||
|
return shim.Error("This product already exists: " + purchid)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==== Create object and marshal to JSON ====
|
||||||
|
objectType := "PurchaseOrder"
|
||||||
|
PurchaseOrder := &PurchaseOrder{purchid, cust, vend, prodid, price, dat, objectType}
|
||||||
|
prodJSONasBytes, err := json.Marshal(PurchaseOrder)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// === Save order to state ===
|
||||||
|
err = stub.PutState(purchid, prodJSONasBytes)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==== order saved and NOT indexed. Return success ====
|
||||||
|
fmt.Println("- end init user")
|
||||||
|
return shim.Success(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *SimpleChaincode) replyPurchaseOrder(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
var key, value string
|
||||||
|
|
||||||
|
|
||||||
|
var a = time.Now()
|
||||||
|
var b = a.Format("20060102150405")
|
||||||
|
key = args[0]
|
||||||
|
var body = args[2] //this will be the yes or no
|
||||||
|
value = args[1] + "-" + b +"-"+ key + " " + body
|
||||||
|
|
||||||
|
|
||||||
|
err = stub.PutState(key, []byte(value)) //write the variable into the chaincode state
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return shim.Success(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================================================================================================================
|
||||||
|
|
||||||
|
// Transferring
|
||||||
|
|
||||||
|
//===========================================================================================================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (t *SimpleChaincode) transferRM(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||||
|
|
||||||
|
// 0 1
|
||||||
|
// "name", "bob"
|
||||||
|
if len(args) < 2 {
|
||||||
|
return shim.Error("Incorrect number of arguments. Expecting 2")
|
||||||
|
}
|
||||||
|
|
||||||
|
prodid := args[0]
|
||||||
|
newOwner := args[1]
|
||||||
|
newLoc := args[2]
|
||||||
|
newDate := args[3]
|
||||||
|
|
||||||
|
|
||||||
|
assetAsBytes, err := stub.GetState(prodid)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error("Failed to get asset:" + err.Error())
|
||||||
|
} else if assetAsBytes == nil {
|
||||||
|
return shim.Error("Assest does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
assetToTransfer := RawMaterial{}
|
||||||
|
err = json.Unmarshal(assetAsBytes, &assetToTransfer) //unmarshal it aka JSON.parse()
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
assetToTransfer.Current_Owner = newOwner //change the owner
|
||||||
|
assetToTransfer.Location = newLoc
|
||||||
|
assetToTransfer.Date = newDate
|
||||||
|
|
||||||
|
|
||||||
|
assetJSONasBytes, _ := json.Marshal(assetToTransfer)
|
||||||
|
err = stub.PutState(prodid, assetJSONasBytes) //rewrite the asset
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("- end transferRM (success)")
|
||||||
|
return shim.Success(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *SimpleChaincode) transferFP(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||||
|
|
||||||
|
// 0 1
|
||||||
|
// "name", "bob"
|
||||||
|
if len(args) < 2 {
|
||||||
|
return shim.Error("Incorrect number of arguments. Expecting 2")
|
||||||
|
}
|
||||||
|
|
||||||
|
prodid := args[0]
|
||||||
|
newOwner := args[1]
|
||||||
|
newLoc := args[2]
|
||||||
|
newDate := args[3]
|
||||||
|
|
||||||
|
|
||||||
|
assetAsBytes, err := stub.GetState(prodid)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error("Failed to get asset:" + err.Error())
|
||||||
|
} else if assetAsBytes == nil {
|
||||||
|
return shim.Error("Assest does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
assetToTransfer := FinishedGood{}
|
||||||
|
err = json.Unmarshal(assetAsBytes, &assetToTransfer) //unmarshal it aka JSON.parse()
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
assetToTransfer.Current_Owner = newOwner //change the owner
|
||||||
|
assetToTransfer.Location = newLoc
|
||||||
|
assetToTransfer.Date = newDate
|
||||||
|
|
||||||
|
|
||||||
|
assetJSONasBytes, _ := json.Marshal(assetToTransfer)
|
||||||
|
err = stub.PutState(prodid, assetJSONasBytes) //rewrite the asset
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("- end transferRM (success)")
|
||||||
|
return shim.Success(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//===========================================================================================================================================================================
|
||||||
|
|
||||||
|
// Certifying
|
||||||
|
|
||||||
|
//===========================================================================================================================================================================
|
||||||
|
|
||||||
|
func (t *SimpleChaincode) awardCert(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// CertID string `json:"certid"` 0
|
||||||
|
// OrgName string `json:"orgname"` 1
|
||||||
|
// Supplier string `json:"supplier"` 2
|
||||||
|
// Status string `json:"status"` 3
|
||||||
|
// Date_effective string `json:"dateeffective"` 4
|
||||||
|
// Certifier string `json:"certifier"` 5
|
||||||
|
// ProductList string `json:"productlist"` 6
|
||||||
|
// OpDetails string `json:"opdetails"` 7
|
||||||
|
// Location string `json:"location"` 8
|
||||||
|
// ExpiryDate string `json:"expdate"` 9
|
||||||
|
// ObjectType string `json:"docType"` 10
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ==== Input sanitation ====
|
||||||
|
|
||||||
|
certid := args[0]
|
||||||
|
oname := args[1]
|
||||||
|
supplier := args[2]
|
||||||
|
stat := args[3]
|
||||||
|
dateeff := args[4]
|
||||||
|
certifierorg := args[5]
|
||||||
|
prodlist := args[6]
|
||||||
|
opdet := args[7]
|
||||||
|
loc := args[8]
|
||||||
|
expdat := args[9]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ==== Check if cert already exists ====
|
||||||
|
awardAsBytes, err := stub.GetState(certid)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error("Failed to get cert: " + err.Error())
|
||||||
|
} else if awardAsBytes != nil {
|
||||||
|
fmt.Println("This cert already exists: " + certid)
|
||||||
|
return shim.Error("This cert already exists: " + certid)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==== Create object and marshal to JSON ====
|
||||||
|
objectType := "Certificate"
|
||||||
|
Certificate := &Certificate{certid, oname, supplier, stat, dateeff, certifierorg, prodlist, opdet, loc, expdat, objectType}
|
||||||
|
|
||||||
|
CertJSONasBytes, err := json.Marshal(Certificate)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// === Save certificate to state ===
|
||||||
|
err = stub.PutState(certid, CertJSONasBytes)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==== certificate saved and NOT indexed. Return success ====
|
||||||
|
fmt.Println("- end init cert")
|
||||||
|
return shim.Success(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (t *SimpleChaincode) requestCert(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||||
|
var err error
|
||||||
|
var key, value string
|
||||||
|
//arg 0 is the certificate request id which will be UUID generated but for now just input
|
||||||
|
//arg 1 is the suppliers id who is requesting the certificate
|
||||||
|
//arg 2 is the name of the certificate
|
||||||
|
//arg 3 is the products
|
||||||
|
//arg 4 is the location
|
||||||
|
|
||||||
|
var a = time.Now()
|
||||||
|
var b = a.Format("20060102150405")
|
||||||
|
key = args[0]
|
||||||
|
var suppid = args[1]
|
||||||
|
var name = args[2]
|
||||||
|
var product = args[3]
|
||||||
|
var location = args[4]
|
||||||
|
value = key + "-" + b + " " + suppid + " " + name + " " + product + " " + location
|
||||||
|
|
||||||
|
|
||||||
|
err = stub.PutState(key, []byte(value)) //write the variable into the chaincode state
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return shim.Success(nil)
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// This function should be used to revoke certificates but because of its open input nature can be more flexible and be used for whatever really
|
||||||
|
//
|
||||||
|
func (t *SimpleChaincode) modifyCert(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||||
|
|
||||||
|
// 0 1
|
||||||
|
// "certid", "new status"
|
||||||
|
if len(args) < 2 {
|
||||||
|
return shim.Error("Incorrect number of arguments. Expecting 2")
|
||||||
|
}
|
||||||
|
|
||||||
|
certid := args[0] // assigning first input to certid
|
||||||
|
newStatus := args[1] // assigning second input to the new status of the certificate
|
||||||
|
|
||||||
|
|
||||||
|
certAsBytes, err := stub.GetState(certid) //retrieving the certificate from the blockchain using the getstate function
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error("Failed to get certificate:" + err.Error())
|
||||||
|
} else if certAsBytes == nil {
|
||||||
|
return shim.Error("Certificate does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
certToModify := Certificate{}
|
||||||
|
err = json.Unmarshal(certAsBytes, &certToModify) //unmarshal it aka JSON.parse()
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
certToModify.Status = newStatus //change the status
|
||||||
|
|
||||||
|
certJSONasBytes, _ := json.Marshal(certToModify)
|
||||||
|
err = stub.PutState(certid, certJSONasBytes) //rewrite the asset
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("- end revokeCert (success)")
|
||||||
|
return shim.Success(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================================================================================================================
|
||||||
|
|
||||||
|
// Reading
|
||||||
|
|
||||||
|
//===========================================================================================================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
func (t *SimpleChaincode) read(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||||
|
var A string // Entities
|
||||||
|
var err error
|
||||||
|
|
||||||
|
A = args[0]
|
||||||
|
|
||||||
|
// Get the state from the ledger
|
||||||
|
Avalbytes, err := stub.GetState(A)
|
||||||
|
if err != nil {
|
||||||
|
jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
|
||||||
|
return shim.Error(jsonResp)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
|
||||||
|
//fmt.Printf("Query Response:%s\n", jsonResp)
|
||||||
|
return shim.Success(Avalbytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
func (t *SimpleChaincode) queryRMByUID(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||||
|
|
||||||
|
// 0
|
||||||
|
// "bob"
|
||||||
|
if len(args) < 1 {
|
||||||
|
return shim.Error("Incorrect number of arguments. Expecting 1")
|
||||||
|
}
|
||||||
|
|
||||||
|
owner := args[0]
|
||||||
|
|
||||||
|
queryString := fmt.Sprintf("{\"selector\":{\"docType\":\"RawMaterial\",\"owner\":\"%s\"}}", owner)
|
||||||
|
|
||||||
|
queryResults, err := getQueryResultForQueryString(stub, queryString)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
return shim.Success(queryResults)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func getQueryResultForQueryString(stub shim.ChaincodeStubInterface, queryString string) ([]byte, error) {
|
||||||
|
|
||||||
|
fmt.Printf("- getQueryResultForQueryString queryString:\n%s\n", queryString)
|
||||||
|
|
||||||
|
resultsIterator, err := stub.GetQueryResult(queryString)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resultsIterator.Close()
|
||||||
|
|
||||||
|
// buffer is a JSON array containing QueryRecords
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
buffer.WriteString("[")
|
||||||
|
|
||||||
|
bArrayMemberAlreadyWritten := false
|
||||||
|
for resultsIterator.HasNext() {
|
||||||
|
queryResponse, err := resultsIterator.Next()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Add a comma before array members, suppress it for the first array member
|
||||||
|
if bArrayMemberAlreadyWritten == true {
|
||||||
|
buffer.WriteString(",")
|
||||||
|
}
|
||||||
|
buffer.WriteString("{\"Key\":")
|
||||||
|
buffer.WriteString("\"")
|
||||||
|
buffer.WriteString(queryResponse.Key)
|
||||||
|
buffer.WriteString("\"")
|
||||||
|
|
||||||
|
buffer.WriteString(", \"Record\":")
|
||||||
|
// Record is a JSON object, so we write as-is
|
||||||
|
buffer.WriteString(string(queryResponse.Value))
|
||||||
|
buffer.WriteString("}")
|
||||||
|
bArrayMemberAlreadyWritten = true
|
||||||
|
}
|
||||||
|
buffer.WriteString("]")
|
||||||
|
|
||||||
|
fmt.Printf("- getQueryResultForQueryString queryResult:\n%s\n", buffer.String())
|
||||||
|
|
||||||
|
return buffer.Bytes(), nil
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
func (t *SimpleChaincode) getHistory(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||||
|
type AuditHistory struct {
|
||||||
|
TxId string `json:"txId"`
|
||||||
|
Value RawMaterial `json:"value"`
|
||||||
|
}
|
||||||
|
var history []AuditHistory;
|
||||||
|
var rawmaterial RawMaterial
|
||||||
|
|
||||||
|
if len(args) != 1 {
|
||||||
|
return shim.Error("Incorrect number of arguments. Expecting 1")
|
||||||
|
}
|
||||||
|
|
||||||
|
RMId := args[0]
|
||||||
|
fmt.Printf("- start getHistoryForMarble: %s\n", RMId)
|
||||||
|
|
||||||
|
// Get History
|
||||||
|
resultsIterator, err := stub.GetHistoryForKey(RMId)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
defer resultsIterator.Close()
|
||||||
|
|
||||||
|
for resultsIterator.HasNext() {
|
||||||
|
historyData, err := resultsIterator.Next()
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx AuditHistory
|
||||||
|
tx.TxId = historyData.TxId //copy transaction id over
|
||||||
|
json.Unmarshal(historyData.Value, &rawmaterial) //un stringify it aka JSON.parse()
|
||||||
|
if historyData.Value == nil { //marble has been deleted
|
||||||
|
var emptyRM RawMaterial
|
||||||
|
tx.Value = emptyRM //copy nil marble
|
||||||
|
} else {
|
||||||
|
json.Unmarshal(historyData.Value, &rawmaterial) //un stringify it aka JSON.parse()
|
||||||
|
tx.Value = rawmaterial //copy marble over
|
||||||
|
}
|
||||||
|
history = append(history, tx) //add this tx to the list
|
||||||
|
}
|
||||||
|
fmt.Printf("- getHistoryForMarble returning:\n%s", history)
|
||||||
|
|
||||||
|
//change to array of bytes
|
||||||
|
historyAsBytes, _ := json.Marshal(history) //convert to array of bytes
|
||||||
|
return shim.Success(historyAsBytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *SimpleChaincode) getHistoryFG(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||||
|
type AuditHistory struct {
|
||||||
|
TxId string `json:"txId"`
|
||||||
|
Value FinishedGood `json:"value"`
|
||||||
|
}
|
||||||
|
var history []AuditHistory;
|
||||||
|
var finishedgood FinishedGood
|
||||||
|
|
||||||
|
if len(args) != 1 {
|
||||||
|
return shim.Error("Incorrect number of arguments. Expecting 1")
|
||||||
|
}
|
||||||
|
|
||||||
|
FGId := args[0]
|
||||||
|
fmt.Printf("- start getHistoryForMarble: %s\n", FGId)
|
||||||
|
|
||||||
|
// Get History
|
||||||
|
resultsIterator, err := stub.GetHistoryForKey(FGId)
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
defer resultsIterator.Close()
|
||||||
|
|
||||||
|
for resultsIterator.HasNext() {
|
||||||
|
historyData, err := resultsIterator.Next()
|
||||||
|
if err != nil {
|
||||||
|
return shim.Error(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
var tx AuditHistory
|
||||||
|
tx.TxId = historyData.TxId //copy transaction id over
|
||||||
|
json.Unmarshal(historyData.Value, &finishedgood) //un stringify it aka JSON.parse()
|
||||||
|
if historyData.Value == nil { //marble has been deleted
|
||||||
|
var emptyFG FinishedGood
|
||||||
|
tx.Value = emptyFG //copy nil marble
|
||||||
|
} else {
|
||||||
|
json.Unmarshal(historyData.Value, &finishedgood) //un stringify it aka JSON.parse()
|
||||||
|
tx.Value = finishedgood //copy marble over
|
||||||
|
}
|
||||||
|
history = append(history, tx) //add this tx to the list
|
||||||
|
}
|
||||||
|
fmt.Printf("- getHistoryForMarble returning:\n%s", history)
|
||||||
|
|
||||||
|
//change to array of bytes
|
||||||
|
historyAsBytes, _ := json.Marshal(history) //convert to array of bytes
|
||||||
|
return shim.Success(historyAsBytes)
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Demo to use configtxlator to modify orderer config
|
||||||
|
# More details about configtxlator, see http://hlf.readthedocs.io/en/latest/configtxlator.html
|
||||||
|
|
||||||
|
CONFIGTXLATOR_IMG=yeasy/hyperledger-fabric:latest
|
||||||
|
CONFIGTXLATOR_CONTAINER=configtxlator
|
||||||
|
|
||||||
|
# Must run `make gen_kafka` to generate artifacts files first
|
||||||
|
ARTIFACTS_DIR=channel-artifacts
|
||||||
|
|
||||||
|
ORDERER_GENESIS_BLOCK=${ARTIFACTS_DIR}/orderer.genesis.block
|
||||||
|
ORDERER_GENESIS_UPDATED_BLOCK=${ARTIFACTS_DIR}/orderer.genesis.updated.block
|
||||||
|
ORDERER_GENESIS_JSON=${ARTIFACTS_DIR}/orderer.genesis.json
|
||||||
|
ORDERER_GENESIS_UPDATED_JSON=${ARTIFACTS_DIR}/orderer.genesis.updated.json
|
||||||
|
MAXBATCHSIZEPATH=".data.data[0].payload.data.config.channel_group.groups.Orderer.values.BatchSize.value.max_message_count"
|
||||||
|
|
||||||
|
echo "Clean potential existing container $CONFIGTXLATOR_CONTAINER"
|
||||||
|
[ "$(docker ps -a | grep $CONFIGTXLATOR_CONTAINER)" ] && docker rm -f $CONFIGTXLATOR_CONTAINER
|
||||||
|
|
||||||
|
echo "Start configtxlator service and listen on port 7059"
|
||||||
|
docker run \
|
||||||
|
-d -it \
|
||||||
|
--name ${CONFIGTXLATOR_CONTAINER} \
|
||||||
|
-p 127.0.0.1:7059:7059 \
|
||||||
|
${CONFIGTXLATOR_IMG} \
|
||||||
|
configtxlator start
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
if [ -f ${ORDERER_GENESIS_BLOCK} ]; then
|
||||||
|
echo "Decoding the orderer genesis block to json"
|
||||||
|
curl -X POST \
|
||||||
|
--data-binary @${ORDERER_GENESIS_BLOCK} \
|
||||||
|
http://127.0.0.1:7059/protolator/decode/common.Block \
|
||||||
|
> ${ORDERER_GENESIS_JSON}
|
||||||
|
|
||||||
|
echo "Checking existing Orderer.BatchSize.max_message_count in the genesis json"
|
||||||
|
jq "$MAXBATCHSIZEPATH" channel-artifacts/orderer.genesis.json
|
||||||
|
|
||||||
|
echo "Creating new genesis json with updated Orderer.BatchSize.max_message_count"
|
||||||
|
jq "$MAXBATCHSIZEPATH=20" ${ORDERER_GENESIS_JSON} > ${ORDERER_GENESIS_UPDATED_JSON}
|
||||||
|
|
||||||
|
echo "Re-Encoding the orderer genesis json to block"
|
||||||
|
curl -X POST \
|
||||||
|
--data-binary @${ORDERER_GENESIS_UPDATED_JSON} \
|
||||||
|
http://127.0.0.1:7059/protolator/encode/common.Block \
|
||||||
|
>${ORDERER_GENESIS_UPDATED_BLOCK}
|
||||||
|
fi
|
||||||
|
|
||||||
|
for i in {0..9}
|
||||||
|
do
|
||||||
|
BLOCK_FILE=${ARTIFACTS_DIR}/block_${i}.block
|
||||||
|
if [ -f ${BLOCK_FILE} ]; then
|
||||||
|
echo "Decoding block $i of app channel to json"
|
||||||
|
curl -X POST \
|
||||||
|
--data-binary @${BLOCK_FILE} \
|
||||||
|
http://127.0.0.1:7059/protolator/decode/common.Block \
|
||||||
|
> ${BLOCK_FILE}.json
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
docker rm -f $CONFIGTXLATOR_CONTAINER
|
|
@ -152,7 +152,7 @@ This example will explain how to add a new org or peer with changed the basic to
|
||||||
|
|
||||||
##### all-in-one
|
##### all-in-one
|
||||||
|
|
||||||
We privide some instance in current directory, in this case we add a new organization `Org3` and new peer `peer0.org3.example.com`.
|
We provide some instance in current directory, in this case we add a new organization `Org3` and new peer `peer0.org3.example.com`.
|
||||||
|
|
||||||
* 1 Generate necessary config and certs
|
* 1 Generate necessary config and certs
|
||||||
|
|
||||||
|
@ -180,7 +180,8 @@ $ sudo docker-compose -f docker-compose-2orgs-4peers-event.yaml up
|
||||||
|
|
||||||
* 3 execute auto-test
|
* 3 execute auto-test
|
||||||
|
|
||||||
Throuth this script to test whether the network works.
|
Throuth this script to test whether the network works.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ root@cli: bash ./scripts/test-5-peers.sh newchannel
|
$ root@cli: bash ./scripts/test-5-peers.sh newchannel
|
||||||
```
|
```
|
||||||
|
@ -199,7 +200,7 @@ The final output may look like following
|
||||||
|
|
||||||
* 1 Modify config
|
* 1 Modify config
|
||||||
|
|
||||||
modify configtx.yaml, crypto-cnfig.yaml and docker-compose files to adapt new change. and replace old file.
|
modify configtx.yaml, crypto-cnfig.yaml and docker-compose files to adapt new change. and replace old file.
|
||||||
|
|
||||||
* 2 Bootstrap network with `docker-compose-2orgs-4peers-event.yaml`
|
* 2 Bootstrap network with `docker-compose-2orgs-4peers-event.yaml`
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue