Fix while loop bug
parent
504a7ab857
commit
466e37cad0
|
@ -24,7 +24,9 @@ all:
|
|||
sleep 1
|
||||
|
||||
make ready
|
||||
make lscc qscc
|
||||
make lscc # test lscc operations
|
||||
make qscc # test qscc operations
|
||||
make fetch_blocks # fetch block files
|
||||
make stop clean
|
||||
|
||||
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"
|
||||
|
||||
qscc: # test qscc queries
|
||||
@echo "Test QSCC query"
|
||||
docker exec -it fabric-cli bash -c "cd /tmp; bash scripts/test_qscc.sh"
|
||||
|
||||
lscc: # test lscc quries
|
||||
@echo "Test LSCC query"
|
||||
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 cp fabric-cli:/tmp/block_0.block kafka/channel-artifacts/
|
||||
docker cp fabric-cli:/tmp/block_1.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/
|
||||
|
||||
if [ "$(HLF_MODE)" = "kafka" ]; then \
|
||||
docker cp fabric-cli:/tmp/block_0.block kafka/channel-artifacts; \
|
||||
docker cp fabric-cli:/tmp/block_1.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 ################
|
||||
|
||||
|
@ -158,7 +170,7 @@ gen_solo: # generate solo artifacts
|
|||
gen_kafka: # generate kafka artifacts
|
||||
cd kafka && bash gen_artifacts.sh
|
||||
|
||||
configtxlator: # run configtxlator
|
||||
test_configtxlator: # Test change config using configtxlator
|
||||
cd kafka && bash run_configtxlator.sh
|
||||
|
||||
download: # download required images
|
||||
|
@ -168,7 +180,6 @@ download: # download required images
|
|||
docker pull hyperledger/fabric-baseos:x86_64-0.4.2
|
||||
docker tag yeasy/hyperledger-fabric:latest hyperledger/fabric-ccenv:x86_64-1.1.0
|
||||
|
||||
|
||||
################## chaincode dev mode ################
|
||||
chaincode_init: # start chaincode in dev mode and do install/instantiate
|
||||
@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==========
|
||||
==============================================
|
||||
|
||||
Channel name : businesschannel
|
||||
Channel name: businesschannel
|
||||
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
|
||||
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:
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
################################################################################
|
||||
Profiles:
|
||||
|
||||
TwoOrgsOrdererGenesis:
|
||||
TwoOrgsOrdererGenesis: # Used to generate genesis block for system channel
|
||||
Orderer:
|
||||
<<: *OrdererDefaults
|
||||
Organizations:
|
||||
|
@ -24,7 +24,8 @@ Profiles:
|
|||
Organizations:
|
||||
- *Org1
|
||||
- *Org2
|
||||
TwoOrgsChannel:
|
||||
|
||||
TwoOrgsChannel: # used for application channel
|
||||
Consortium: SampleConsortium
|
||||
Application:
|
||||
<<: *ApplicationDefaults
|
||||
|
@ -32,6 +33,15 @@ Profiles:
|
|||
- *Org1
|
||||
- *Org2
|
||||
|
||||
ThreeOrgsChannel: # used for application channel
|
||||
Consortium: SampleConsortium
|
||||
Application:
|
||||
<<: *ApplicationDefaults
|
||||
Organizations:
|
||||
- *Org1
|
||||
- *Org2
|
||||
- *Org3
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Section: Organizations
|
||||
|
@ -89,6 +99,23 @@ Organizations:
|
|||
- Host: peer0.org2.example.com
|
||||
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
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
#!/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
|
|
@ -20,7 +20,7 @@ elif [ -f scripts/variables.sh ]; then
|
|||
source scripts/variables.sh
|
||||
fi
|
||||
|
||||
# Verify $1 is not 0, then output error msg $2
|
||||
# Verify $1 is not 0, then output error msg $2 and exit
|
||||
verifyResult () {
|
||||
if [ $1 -ne 0 ] ; then
|
||||
echo_b "$2"
|
||||
|
@ -107,23 +107,25 @@ channelCreateAction(){
|
|||
}
|
||||
|
||||
# Use peer0/org1 to create a channel
|
||||
# channelCreate channel_name
|
||||
channelCreate() {
|
||||
local channel=$1
|
||||
echo_b "=== Create Channel ${channel} === "
|
||||
local counter=0
|
||||
local res=1
|
||||
echo_b "=== Create Channel ${channel}\" === "
|
||||
setGlobals 0
|
||||
while [ $counter -lt ${MAX_RETRY} -a ${res} -ne 0 ]; do
|
||||
res=$(channelCreateAction ${channel})
|
||||
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
|
||||
#COUNTER=` expr $COUNTER + 1`
|
||||
echo_b "Fail to create channel ${channel}, Retry after 3 seconds"
|
||||
sleep 3
|
||||
done
|
||||
cat log.txt
|
||||
verifyResult ${res} "Channel creation failed"
|
||||
echo_g "=== Channel ${channel} is created successfully === "
|
||||
echo
|
||||
verifyResult ${res} "Channel ${channel} creation failed"
|
||||
echo_g "=== Channel ${channel} is created. === "
|
||||
}
|
||||
|
||||
# called by channelJoinWithRetry
|
||||
|
@ -138,22 +140,24 @@ channelJoinWithRetry () {
|
|||
local channel=$1
|
||||
local peer=$2
|
||||
local counter=0
|
||||
local res=1
|
||||
channelJoinAction ${channel}
|
||||
local res=$?
|
||||
while [ ${counter} -lt ${MAX_RETRY} -a ${res} -ne 0 ]; do
|
||||
res=$(channelJoinAction ${channel})
|
||||
let counter=$counter+1
|
||||
echo_b "peer${peer} failed to join the channel, Retry after 2 seconds"
|
||||
echo_b "peer${peer} failed to join channel ${channel}, retry after 2s"
|
||||
sleep 2
|
||||
channelJoinAction ${channel}
|
||||
res=$?
|
||||
let counter=${counter}+1
|
||||
done
|
||||
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
|
||||
# channelJoin 0 1 2 3
|
||||
channelJoin () {
|
||||
local channel=$1
|
||||
echo_b "=== Join peers into the channel ${channel} === "
|
||||
echo_b "=== Join peers into channel ${channel} === "
|
||||
peers_to_join=$(seq 0 3)
|
||||
if [ $# -gt 1 ]; then
|
||||
peers_to_join=${@:2}
|
||||
|
@ -161,7 +165,7 @@ channelJoin () {
|
|||
for i in $peers_to_join; do
|
||||
setGlobals $i
|
||||
channelJoinWithRetry ${channel} $i
|
||||
echo_g "=== peer$i joined into the channel \"${channel}\" === "
|
||||
echo_g "=== peer$i joined into channel ${channel} === "
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
@ -191,7 +195,7 @@ updateAnchorPeers() {
|
|||
res=$?
|
||||
cat log.txt
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -384,19 +388,19 @@ chaincodeUpgrade () {
|
|||
channelFetch () {
|
||||
local channel=$1
|
||||
local peer=$2
|
||||
local blockNum=$3
|
||||
echo_b "=== Fetch block $blockNum on peer$peer in channel '$channel' === "
|
||||
local num=$3
|
||||
echo_b "=== Fetch block $num on peer$peer in channel '$channel' === "
|
||||
|
||||
setGlobals $peer
|
||||
# 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
|
||||
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} \
|
||||
-c ${channel} \
|
||||
>&log.txt
|
||||
else
|
||||
peer channel fetch $blockNum block_${blockNum}.block \
|
||||
peer channel fetch $num block_${num}.block \
|
||||
-o ${ORDERER_URL} \
|
||||
-c ${channel} \
|
||||
--tls \
|
||||
|
|
|
@ -14,7 +14,7 @@ echo " ==========initialize businesschannel========== "
|
|||
echo " ============================================== "
|
||||
echo
|
||||
|
||||
echo_b "Channel name : "$CHANNEL_NAME
|
||||
echo_b "Channel name: "$CHANNEL_NAME
|
||||
|
||||
## Create channel
|
||||
echo_b "Creating channel..."
|
||||
|
|
|
@ -7,7 +7,7 @@ elif [ -f scripts/func.sh ]; then
|
|||
source scripts/func.sh
|
||||
fi
|
||||
|
||||
echo_b "Channel name : "$CHANNEL_NAME
|
||||
echo_b "Channel name: "$CHANNEL_NAME
|
||||
|
||||
#Query on chaincode on Peer0/Org1
|
||||
echo_b "Querying chaincode on peer 3..."
|
||||
|
|
|
@ -18,31 +18,31 @@ echo_b "LSCC testing"
|
|||
|
||||
setGlobals 0
|
||||
|
||||
echo_b "Get id"
|
||||
echo_b "LSCC Get id"
|
||||
peer chaincode query \
|
||||
-C "${CHANNEL_NAME}" \
|
||||
-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 \
|
||||
-C "${CHANNEL_NAME}" \
|
||||
-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 \
|
||||
-C "${CHANNEL_NAME}" \
|
||||
-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 \
|
||||
-C "${CHANNEL_NAME}" \
|
||||
-n lscc \
|
||||
-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 \
|
||||
-C "${CHANNEL_NAME}" \
|
||||
-n lscc \
|
||||
|
|
|
@ -9,6 +9,8 @@ elif [ -f scripts/func.sh ]; then
|
|||
source scripts/func.sh
|
||||
fi
|
||||
|
||||
echo_b "QSCC testing"
|
||||
|
||||
setGlobals 0
|
||||
|
||||
echo_b "QSCC GetChainInfo"
|
||||
|
@ -23,4 +25,4 @@ peer chaincode query \
|
|||
-n qscc \
|
||||
-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
|
||||
ORG2_ADMIN_MSP=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
|
||||
|
||||
|
||||
# Node URLS
|
||||
ORDERER_URL="orderer.example.com:7050"
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
@ -180,7 +180,8 @@ $ sudo docker-compose -f docker-compose-2orgs-4peers-event.yaml up
|
|||
|
||||
* 3 execute auto-test
|
||||
|
||||
Throuth this script to test whether the network works.
|
||||
Throuth this script to test whether the network works.
|
||||
|
||||
```bash
|
||||
$ root@cli: bash ./scripts/test-5-peers.sh newchannel
|
||||
```
|
||||
|
@ -199,7 +200,7 @@ The final output may look like following
|
|||
|
||||
* 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`
|
||||
|
||||
|
|
Loading…
Reference in New Issue