diff --git a/hyperledger_fabric/1.0.4/Makefile b/hyperledger_fabric/1.0.4/Makefile index 4f80b5ee..1e07dba0 100644 --- a/hyperledger_fabric/1.0.4/Makefile +++ b/hyperledger_fabric/1.0.4/Makefile @@ -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" diff --git a/hyperledger_fabric/1.0.4/README.md b/hyperledger_fabric/1.0.4/README.md index 3ce334cd..9a3ce5f1 100644 --- a/hyperledger_fabric/1.0.4/README.md +++ b/hyperledger_fabric/1.0.4/README.md @@ -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... ... diff --git a/hyperledger_fabric/1.0.4/docker-compose-2orgs-4peers-solo-be.yaml b/hyperledger_fabric/1.0.4/docker-compose-2orgs-4peers-solo-be.yaml new file mode 100644 index 00000000..4de101c1 --- /dev/null +++ b/hyperledger_fabric/1.0.4/docker-compose-2orgs-4peers-solo-be.yaml @@ -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 diff --git a/hyperledger_fabric/1.0.4/docker-compose-2orgs-4peers-solo.yaml b/hyperledger_fabric/1.0.4/docker-compose-2orgs-4peers-solo.yaml index 5bfe6236..16d739b3 100644 --- a/hyperledger_fabric/1.0.4/docker-compose-2orgs-4peers-solo.yaml +++ b/hyperledger_fabric/1.0.4/docker-compose-2orgs-4peers-solo.yaml @@ -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: diff --git a/hyperledger_fabric/1.0.4/kafka/configtx.yaml b/hyperledger_fabric/1.0.4/kafka/configtx.yaml index 92ca5448..64d830b4 100644 --- a/hyperledger_fabric/1.0.4/kafka/configtx.yaml +++ b/hyperledger_fabric/1.0.4/kafka/configtx.yaml @@ -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 diff --git a/hyperledger_fabric/1.0.4/kafka/run_configtxlator.sh b/hyperledger_fabric/1.0.4/kafka/test_configtxlator.sh similarity index 94% rename from hyperledger_fabric/1.0.4/kafka/run_configtxlator.sh rename to hyperledger_fabric/1.0.4/kafka/test_configtxlator.sh index c2d13bb4..e9a6b33f 100644 --- a/hyperledger_fabric/1.0.4/kafka/run_configtxlator.sh +++ b/hyperledger_fabric/1.0.4/kafka/test_configtxlator.sh @@ -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 diff --git a/hyperledger_fabric/1.0.4/scripts/func.sh b/hyperledger_fabric/1.0.4/scripts/func.sh index f8b46e49..b548b62d 100644 --- a/hyperledger_fabric/1.0.4/scripts/func.sh +++ b/hyperledger_fabric/1.0.4/scripts/func.sh @@ -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 \ diff --git a/hyperledger_fabric/1.0.4/scripts/init_chaincode_dev.sh b/hyperledger_fabric/1.0.4/scripts/init_chaincode_dev.sh index 632e2f06..a6e08f50 100644 --- a/hyperledger_fabric/1.0.4/scripts/init_chaincode_dev.sh +++ b/hyperledger_fabric/1.0.4/scripts/init_chaincode_dev.sh @@ -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..." diff --git a/hyperledger_fabric/1.0.4/scripts/test_cc_all.sh b/hyperledger_fabric/1.0.4/scripts/test_cc_all.sh index 3e76c915..17b7abaf 100644 --- a/hyperledger_fabric/1.0.4/scripts/test_cc_all.sh +++ b/hyperledger_fabric/1.0.4/scripts/test_cc_all.sh @@ -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..." diff --git a/hyperledger_fabric/1.0.4/scripts/test_lscc.sh b/hyperledger_fabric/1.0.4/scripts/test_lscc.sh index 761a8cdb..04541c69 100644 --- a/hyperledger_fabric/1.0.4/scripts/test_lscc.sh +++ b/hyperledger_fabric/1.0.4/scripts/test_lscc.sh @@ -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 \ diff --git a/hyperledger_fabric/1.0.4/scripts/test_qscc.sh b/hyperledger_fabric/1.0.4/scripts/test_qscc.sh index 3d7ccdd9..c466ac72 100644 --- a/hyperledger_fabric/1.0.4/scripts/test_qscc.sh +++ b/hyperledger_fabric/1.0.4/scripts/test_qscc.sh @@ -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!" \ No newline at end of file +echo_g "QSCC testing done!" \ No newline at end of file diff --git a/hyperledger_fabric/1.0.4/scripts/variables.sh b/hyperledger_fabric/1.0.4/scripts/variables.sh index 74cc0685..bf8f32e4 100644 --- a/hyperledger_fabric/1.0.4/scripts/variables.sh +++ b/hyperledger_fabric/1.0.4/scripts/variables.sh @@ -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" diff --git a/hyperledger_fabric/1.0.4/solo/channel-artifacts/block_0.block b/hyperledger_fabric/1.0.4/solo/channel-artifacts/block_0.block new file mode 100644 index 00000000..3083c345 Binary files /dev/null and b/hyperledger_fabric/1.0.4/solo/channel-artifacts/block_0.block differ diff --git a/hyperledger_fabric/1.0.4/solo/channel-artifacts/block_1.block b/hyperledger_fabric/1.0.4/solo/channel-artifacts/block_1.block new file mode 100644 index 00000000..09e67e56 Binary files /dev/null and b/hyperledger_fabric/1.0.4/solo/channel-artifacts/block_1.block differ diff --git a/hyperledger_fabric/1.0.4/solo/channel-artifacts/block_2.block b/hyperledger_fabric/1.0.4/solo/channel-artifacts/block_2.block new file mode 100644 index 00000000..60420491 Binary files /dev/null and b/hyperledger_fabric/1.0.4/solo/channel-artifacts/block_2.block differ diff --git a/hyperledger_fabric/1.0.4/solo/channel-artifacts/block_3.block b/hyperledger_fabric/1.0.4/solo/channel-artifacts/block_3.block new file mode 100644 index 00000000..74417b45 Binary files /dev/null and b/hyperledger_fabric/1.0.4/solo/channel-artifacts/block_3.block differ diff --git a/hyperledger_fabric/1.0.4/solo/examples/chaincode/go/foodchain/foodchain.cc.go b/hyperledger_fabric/1.0.4/solo/examples/chaincode/go/foodchain/foodchain.cc.go new file mode 100644 index 00000000..92961ecf --- /dev/null +++ b/hyperledger_fabric/1.0.4/solo/examples/chaincode/go/foodchain/foodchain.cc.go @@ -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) +} diff --git a/hyperledger_fabric/1.0.4/solo/test_configtxlator.sh b/hyperledger_fabric/1.0.4/solo/test_configtxlator.sh new file mode 100644 index 00000000..e9a6b33f --- /dev/null +++ b/hyperledger_fabric/1.0.4/solo/test_configtxlator.sh @@ -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 diff --git a/hyperledger_fabric/docs/artifacts_generation.md b/hyperledger_fabric/docs/artifacts_generation.md index 59345df4..01657c5f 100644 --- a/hyperledger_fabric/docs/artifacts_generation.md +++ b/hyperledger_fabric/docs/artifacts_generation.md @@ -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`