This commit is contained in:
HalfWater 2018-06-08 13:05:29 +00:00 committed by GitHub
commit 190a1b7173
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 1355 additions and 321 deletions

23
.gitignore vendored
View file

@ -6,27 +6,6 @@
.*.sw* .*.sw*
# installed platform-specific binaries # installed platform-specific binaries
/bin /bin
/config
.DS_Store .DS_Store
.project .project
first-network/channel-artifacts/*.tx
first-network/channel-artifacts/*.block
first-network/crypto-config/*
first-network/docker-compose-e2e.yaml
first-network/ledgers
first-network/ledgers-backup
chaincode-docker-devmode/myc.block
chaincode-docker-devmode/chaincode/sacc/sacc
chaincode-docker-devmode/chaincode/chaincode_example02/chaincode_example02
# fabric sdk node modules
fabcar/node_modules/
fabcar/package-lock.json
fabcar/hfc-key-store/
# balance transfer sample
balance-transfer/.DS_Store
balance-transfer/node_modules/*
balance-transfer/package-lock.json
balance-transfer/fabric-client-kv-org*

5
.gitreview Normal file
View file

@ -0,0 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
[gerrit]
host=gerrit.hyperledger.org
port=29418
project=fabric-samples

View file

@ -1,10 +1,8 @@
## Hyperledger Fabric Samples Code of Conduct Guidelines
==========================
fabric-preload.sh will preload all of the requisite docker images for Hyperledger Fabric and tag them Please review the Hyperledger [Code of
with the 'latest' tag. Optionally, specify a specific version (e.g. 1.0.1). Default version is 1.0.0. Conduct](https://wiki.hyperledger.org/community/hyperledger-project-code-of-conduct)
before participating. It is important that we keep things civil.
```bash <a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.
./fabric-preload.sh [version]
```
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>

18
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,18 @@
## Contributing
We welcome contributions to the Hyperledger Fabric Project in many forms, and
there's always plenty to do!
Please visit the
[contributors guide](http://hyperledger-fabric.readthedocs.io/en/latest/CONTRIBUTING.html) in the
docs to learn how to make contributions to this exciting project.
## Code of Conduct Guidelines <a name="conduct"></a>
See our [Code of Conduct Guidelines](../blob/master/CODE_OF_CONDUCT.md).
## Maintainers <a name="maintainers"></a>
Should you have any questions or concerns, please reach out to one of the project's [Maintainers](../blob/master/MAINTAINERS.md).
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>.

View file

@ -1,7 +1,27 @@
[//]: # (SPDX-License-Identifier: CC-BY-4.0)
## Hyperledger Fabric Samples ## Hyperledger Fabric Samples
Please visit the [installation instructions](http://hyperledger-fabric.readthedocs.io/en/latest/samples.html). Please visit the [installation instructions](http://hyperledger-fabric.readthedocs.io/en/latest/install.html)
to ensure you have the correct prerequisites installed. Please use the
version of the documentation that matches the version of the software you
intend to use to ensure alignment.
## Download Binaries and Docker Images
The [`scripts/bootstrap.sh`](https://github.com/hyperledger/fabric-samples/blob/release-1.1/scripts/bootstrap.sh)
script will preload all of the requisite docker
images for Hyperledger Fabric and tag them with the 'latest' tag. Optionally,
specify a version for fabric, fabric-ca and thirdparty images. Default versions
are 1.1.0, 1.1.0 and 0.4.7 respectively.
```bash
./scripts/bootstrap.sh [version] [ca version] [thirdparty_version]
```
## License <a name="license"></a> ## License <a name="license"></a>
Hyperledger Project source code files are made available under the Apache License, Version 2.0 (Apache-2.0), located in the [LICENSE](LICENSE) file. Hyperledger Project documentation files are made available under the Creative Commons Attribution 4.0 International License (CC-BY-4.0), available at http://creativecommons.org/licenses/by/4.0/. Hyperledger Project source code files are made available under the Apache
License, Version 2.0 (Apache-2.0), located in the [LICENSE](LICENSE) file.
Hyperledger Project documentation files are made available under the Creative
Commons Attribution 4.0 International License (CC-BY-4.0), available at http://creativecommons.org/licenses/by/4.0/.

3
balance-transfer/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/node_modules/*
/package-lock.json
/fabric-client-kv-org*

View file

@ -4,34 +4,6 @@
# #
--- ---
################################################################################
#
# Profile
#
# - Different configuration profiles may be encoded here to be specified
# as parameters to the configtxgen tool
#
################################################################################
Profiles:
TwoOrgsOrdererGenesis:
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
TwoOrgsChannel:
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
################################################################################ ################################################################################
# #
# Section: Organizations # Section: Organizations
@ -89,6 +61,20 @@ Organizations:
- Host: peer0.org2.example.com - Host: peer0.org2.example.com
Port: 7051 Port: 7051
################################################################################
#
# SECTION: Application
#
# - This section defines the values to encode into a config transaction or
# genesis block for application related parameters
#
################################################################################
Application: &ApplicationDefaults
# Organizations is the list of orgs which are defined as participants on
# the application side of the network
Organizations:
################################################################################ ################################################################################
# #
# SECTION: Orderer # SECTION: Orderer
@ -136,14 +122,28 @@ Orderer: &OrdererDefaults
################################################################################ ################################################################################
# #
# SECTION: Application # Profile
# #
# - This section defines the values to encode into a config transaction or # - Different configuration profiles may be encoded here to be specified
# genesis block for application related parameters # as parameters to the configtxgen tool
# #
################################################################################ ################################################################################
Application: &ApplicationDefaults Profiles:
# Organizations is the list of orgs which are defined as participants on TwoOrgsOrdererGenesis:
# the application side of the network Orderer:
Organizations: <<: *OrdererDefaults
Organizations:
- *OrdererOrg
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
TwoOrgsChannel:
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2

View file

@ -154,7 +154,6 @@ orderers:
# they will be passed in as-is to gRPC client constructor # they will be passed in as-is to gRPC client constructor
grpcOptions: grpcOptions:
ssl-target-name-override: orderer.example.com ssl-target-name-override: orderer.example.com
grpc-max-send-message-length: 15
tlsCACerts: tlsCACerts:
path: artifacts/channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt path: artifacts/channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt

View file

@ -154,7 +154,6 @@ orderers:
# they will be passed in as-is to gRPC client constructor # they will be passed in as-is to gRPC client constructor
grpcOptions: grpcOptions:
ssl-target-name-override: orderer.example.com ssl-target-name-override: orderer.example.com
grpc-max-send-message-length: 15
tlsCACerts: tlsCACerts:
path: artifacts/channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt path: artifacts/channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt

View file

@ -170,7 +170,7 @@ TRX_ID=$(curl -s -X POST \
"fcn":"move", "fcn":"move",
"args":["a","b","10"] "args":["a","b","10"]
}') }')
echo "Transacton ID is $TRX_ID" echo "Transaction ID is $TRX_ID"
echo echo
echo echo

View file

@ -128,7 +128,7 @@ TRX_ID=$(curl -s -X POST \
"fcn":"move", "fcn":"move",
"args":["a","b","10"] "args":["a","b","10"]
}') }')
echo "Transacton ID is $TRX_ID" echo "Transaction ID is $TRX_ID"
echo echo
echo echo

View file

@ -4,32 +4,6 @@
# #
--- ---
################################################################################
#
# Profile
#
# - Different configuration profiles may be encoded here to be specified
# as parameters to the configtxgen tool
#
################################################################################
Profiles:
OneOrgOrdererGenesis:
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Consortiums:
SampleConsortium:
Organizations:
- *Org1
OneOrgChannel:
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
################################################################################ ################################################################################
# #
# Section: Organizations # Section: Organizations
@ -70,6 +44,20 @@ Organizations:
- Host: peer0.org1.example.com - Host: peer0.org1.example.com
Port: 7051 Port: 7051
################################################################################
#
# SECTION: Application
#
# - This section defines the values to encode into a config transaction or
# genesis block for application related parameters
#
################################################################################
Application: &ApplicationDefaults
# Organizations is the list of orgs which are defined as participants on
# the application side of the network
Organizations:
################################################################################ ################################################################################
# #
# SECTION: Orderer # SECTION: Orderer
@ -117,14 +105,27 @@ Orderer: &OrdererDefaults
################################################################################ ################################################################################
# #
# SECTION: Application # Profile
# #
# - This section defines the values to encode into a config transaction or # - Different configuration profiles may be encoded here to be specified
# genesis block for application related parameters # as parameters to the configtxgen tool
# #
################################################################################ ################################################################################
Application: &ApplicationDefaults Profiles:
OneOrgOrdererGenesis:
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Consortiums:
SampleConsortium:
Organizations:
- *Org1
OneOrgChannel:
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
# Organizations is the list of orgs which are defined as participants on
# the application side of the network
Organizations:

View file

@ -18,7 +18,7 @@ services:
- FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/4239aa0dcd76daeeb8ba0cda701851d14504d31aad1b2ddddbac6a57365e497c_sk - FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/4239aa0dcd76daeeb8ba0cda701851d14504d31aad1b2ddddbac6a57365e497c_sk
ports: ports:
- "7054:7054" - "7054:7054"
command: sh -c 'fabric-ca-server start -b admin:adminpw -d' command: sh -c 'fabric-ca-server start -b admin:adminpw'
volumes: volumes:
- ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config - ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config
container_name: ca.example.com container_name: ca.example.com
@ -29,7 +29,7 @@ services:
container_name: orderer.example.com container_name: orderer.example.com
image: hyperledger/fabric-orderer image: hyperledger/fabric-orderer
environment: environment:
- ORDERER_GENERAL_LOGLEVEL=debug - ORDERER_GENERAL_LOGLEVEL=info
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
- ORDERER_GENERAL_GENESISMETHOD=file - ORDERER_GENERAL_GENESISMETHOD=file
- ORDERER_GENERAL_GENESISFILE=/etc/hyperledger/configtx/genesis.block - ORDERER_GENERAL_GENESISFILE=/etc/hyperledger/configtx/genesis.block
@ -52,8 +52,8 @@ services:
environment: environment:
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_PEER_ID=peer0.org1.example.com - CORE_PEER_ID=peer0.org1.example.com
- CORE_LOGGING_PEER=debug - CORE_LOGGING_PEER=info
- CORE_CHAINCODE_LOGGING_LEVEL=DEBUG - CORE_CHAINCODE_LOGGING_LEVEL=info
- CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_LOCALMSPID=Org1MSP
- CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/peer/ - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/msp/peer/
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051 - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
@ -105,7 +105,7 @@ services:
environment: environment:
- GOPATH=/opt/gopath - GOPATH=/opt/gopath
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
- CORE_LOGGING_LEVEL=DEBUG - CORE_LOGGING_LEVEL=info
- CORE_PEER_ID=cli - CORE_PEER_ID=cli
- CORE_PEER_ADDRESS=peer0.org1.example.com:7051 - CORE_PEER_ADDRESS=peer0.org1.example.com:7051
- CORE_PEER_LOCALMSPID=Org1MSP - CORE_PEER_LOCALMSPID=Org1MSP

View file

@ -12,4 +12,3 @@ rm -rf ~/.hfc-key-store/*
# copy peer admin credentials into the keyValStore # copy peer admin credentials into the keyValStore
mkdir -p ~/.hfc-key-store mkdir -p ~/.hfc-key-store
cp creds/* ~/.hfc-key-store

View file

@ -14,6 +14,7 @@ docker-compose -f docker-compose.yml kill && docker-compose -f docker-compose.ym
rm -f ~/.hfc-key-store/* rm -f ~/.hfc-key-store/*
# remove chaincode docker images # remove chaincode docker images
docker rm $(docker ps -aq)
docker rmi $(docker images dev-* -q) docker rmi $(docker images dev-* -q)
# Your system is now clean # Your system is now clean

3
chaincode-docker-devmode/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/myc.block
/chaincode/sacc/sacc
/chaincode/chaincode_example02/chaincode_example02

View file

@ -13,7 +13,7 @@ of compiling chaincode and driving calls.
Install Fabric Samples Install Fabric Samples
---------------------- ----------------------
If you haven't already done so, please install the doc [samples](http://hyperledger-fabric.readthedocs.io/en/latest/samples.html). If you haven't already done so, please `install samples <http://hyperledger-fabric.readthedocs.io/en/latest/install.html>`_.
Navigate to the ``chaincode-docker-devmode`` directory of the ``fabric-samples`` Navigate to the ``chaincode-docker-devmode`` directory of the ``fabric-samples``
clone: clone:
@ -27,7 +27,7 @@ Download docker images
We need four docker images in order for "dev mode" to run against the supplied We need four docker images in order for "dev mode" to run against the supplied
docker compose script. If you installed the ``fabric-samples`` repo clone and docker compose script. If you installed the ``fabric-samples`` repo clone and
followed the instructions to [download-platform-specific-binaries](http://hyperledger-fabric.readthedocs.io/en/latest/samples.html#download-platform-specific-binaries), then followed the instructions to `install samples, binaries and docker images <http://hyperledger-fabric.readthedocs.io/en/latest/install.html>`_, then
you should have the necessary Docker images installed locally. you should have the necessary Docker images installed locally.
.. note:: If you choose to manually pull the images then you must retag them as .. note:: If you choose to manually pull the images then you must retag them as
@ -49,7 +49,7 @@ should see something similar to following:
hyperledger/fabric-ccenv latest 82489d1c11e8 9 days ago 1.35 GB hyperledger/fabric-ccenv latest 82489d1c11e8 9 days ago 1.35 GB
hyperledger/fabric-ccenv x86_64-1.1.0-preview 82489d1c11e8 9 days ago 1.35 GB hyperledger/fabric-ccenv x86_64-1.1.0-preview 82489d1c11e8 9 days ago 1.35 GB
.. note:: If you retrieved the images through the [download-platform-specific-binaries](http://hyperledger-fabric.readthedocs.io/en/latest/samples.html#download-platform-specific-binaries), .. note:: If you retrieved the images through the `install samples, binaries and docker images <http://hyperledger-fabric.readthedocs.io/en/latest/install.html>`_,
then you will see additional images listed. However, we are only concerned with then you will see additional images listed. However, we are only concerned with
these four. these four.

View file

@ -0,0 +1,16 @@
[
{
"name": "collectionMarbles",
"policy": "OR('Org1MSP.member', 'Org2MSP.member')",
"requiredPeerCount": 0,
"maxPeerCount": 3,
"blockToLive":1000000
},
{
"name": "collectionMarblePrivateDetails",
"policy": "OR('Org1MSP.member')",
"requiredPeerCount": 0,
"maxPeerCount": 3,
"blockToLive":3
}
]

View file

@ -0,0 +1 @@
{"index":{"fields":["docType","owner"]},"ddoc":"indexOwnerDoc", "name":"indexOwner","type":"json"}

View file

@ -0,0 +1,634 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
// ====CHAINCODE EXECUTION SAMPLES (CLI) ==================
// ==== Invoke marbles ====
// peer chaincode invoke -C mychannel -n marblesp -c '{"Args":["initMarble","marble1","blue","35","tom","99"]}'
// peer chaincode invoke -C mychannel -n marblesp -c '{"Args":["initMarble","marble2","red","50","tom","102"]}'
// peer chaincode invoke -C mychannel -n marblesp -c '{"Args":["initMarble","marble3","blue","70","tom","103"]}'
// peer chaincode invoke -C mychannel -n marblesp -c '{"Args":["transferMarble","marble2","jerry"]}'
// peer chaincode invoke -C mychannel -n marblesp -c '{"Args":["delete","marble1"]}'
// ==== Query marbles ====
// peer chaincode query -C mychannel -n marblesp -c '{"Args":["readMarble","marble1"]}'
// peer chaincode query -C mychannel -n marblesp -c '{"Args":["readMarblePrivateDetails","marble1"]}'
// peer chaincode query -C mychannel -n marblesp -c '{"Args":["getMarblesByRange","marble1","marble3"]}'
// Rich Query (Only supported if CouchDB is used as state database):
// peer chaincode query -C mychannel -n marblesp -c '{"Args":["queryMarblesByOwner","tom"]}'
// peer chaincode query -C mychannel -n marblesp -c '{"Args":["queryMarbles","{\"selector\":{\"owner\":\"tom\"}}"]}'
// INDEXES TO SUPPORT COUCHDB RICH QUERIES
//
// Indexes in CouchDB are required in order to make JSON queries efficient and are required for
// any JSON query with a sort. As of Hyperledger Fabric 1.1, indexes may be packaged alongside
// chaincode in a META-INF/statedb/couchdb/indexes directory. Or for indexes on private data
// collections, in a META-INF/statedb/couchdb/collections/<collection_name>/indexes directory.
// Each index must be defined in its own text file with extension *.json with the index
// definition formatted in JSON following the CouchDB index JSON syntax as documented at:
// http://docs.couchdb.org/en/2.1.1/api/database/find.html#db-index
//
// This marbles02_private example chaincode demonstrates a packaged index which you
// can find in META-INF/statedb/couchdb/collection/collectionMarbles/indexes/indexOwner.json.
// For deployment of chaincode to production environments, it is recommended
// to define any indexes alongside chaincode so that the chaincode and supporting indexes
// are deployed automatically as a unit, once the chaincode has been installed on a peer and
// instantiated on a channel. See Hyperledger Fabric documentation for more details.
//
// If you have access to the your peer's CouchDB state database in a development environment,
// you may want to iteratively test various indexes in support of your chaincode queries. You
// can use the CouchDB Fauxton interface or a command line curl utility to create and update
// indexes. Then once you finalize an index, include the index definition alongside your
// chaincode in the META-INF/statedb/couchdb/indexes directory or
// META-INF/statedb/couchdb/collections/<collection_name>/indexes directory, for packaging
// and deployment to managed environments.
//
// In the examples below you can find index definitions that support marbles02_private
// chaincode queries, along with the syntax that you can use in development environments
// to create the indexes in the CouchDB Fauxton interface.
//
//Example hostname:port configurations to access CouchDB.
//
//To access CouchDB docker container from within another docker container or from vagrant environments:
// http://couchdb:5984/
//
//Inside couchdb docker container
// http://127.0.0.1:5984/
// Index for docType, owner.
// Note that docType and owner fields must be prefixed with the "data" wrapper
//
// Index definition for use with Fauxton interface
// {"index":{"fields":["data.docType","data.owner"]},"ddoc":"indexOwnerDoc", "name":"indexOwner","type":"json"}
// Index for docType, owner, size (descending order).
// Note that docType, owner and size fields must be prefixed with the "data" wrapper
//
// Index definition for use with Fauxton interface
// {"index":{"fields":[{"data.size":"desc"},{"data.docType":"desc"},{"data.owner":"desc"}]},"ddoc":"indexSizeSortDoc", "name":"indexSizeSortDesc","type":"json"}
// Rich Query with index design doc and index name specified (Only supported if CouchDB is used as state database):
// peer chaincode query -C mychannel -n marblesp -c '{"Args":["queryMarbles","{\"selector\":{\"docType\":\"marble\",\"owner\":\"tom\"}, \"use_index\":[\"_design/indexOwnerDoc\", \"indexOwner\"]}"]}'
// Rich Query with index design doc specified only (Only supported if CouchDB is used as state database):
// peer chaincode query -C mychannel -n marblesp -c '{"Args":["queryMarbles","{\"selector\":{\"docType\":{\"$eq\":\"marble\"},\"owner\":{\"$eq\":\"tom\"},\"size\":{\"$gt\":0}},\"fields\":[\"docType\",\"owner\",\"size\"],\"sort\":[{\"size\":\"desc\"}],\"use_index\":\"_design/indexSizeSortDoc\"}"]}'
package main
import (
"bytes"
"encoding/json"
"fmt"
"strconv"
"strings"
"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
)
// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}
type marble struct {
ObjectType string `json:"docType"` //docType is used to distinguish the various types of objects in state database
Name string `json:"name"` //the fieldtags are needed to keep case from bouncing around
Color string `json:"color"`
Size int `json:"size"`
Owner string `json:"owner"`
}
type marblePrivateDetails struct {
ObjectType string `json:"docType"` //docType is used to distinguish the various types of objects in state database
Name string `json:"name"` //the fieldtags are needed to keep case from bouncing around
Price int `json:"price"`
}
// ===================================================================================
// Main
// ===================================================================================
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 {
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
switch function {
case "initMarble":
//create a new marble
return t.initMarble(stub, args)
case "readMarble":
//read a marble
return t.readMarble(stub, args)
case "readMarblePrivateDetails":
//read a marble private details
return t.readMarblePrivateDetails(stub, args)
case "transferMarble":
//change owner of a specific marble
return t.transferMarble(stub, args)
case "transferMarblesBasedOnColor":
//transfer all marbles of a certain color
return t.transferMarblesBasedOnColor(stub, args)
case "delete":
//delete a marble
return t.delete(stub, args)
case "queryMarblesByOwner":
//find marbles for owner X using rich query
return t.queryMarblesByOwner(stub, args)
case "queryMarbles":
//find marbles based on an ad hoc rich query
return t.queryMarbles(stub, args)
case "getMarblesByRange":
//get marbles based on range query
return t.getMarblesByRange(stub, args)
default:
//error
fmt.Println("invoke did not find func: " + function)
return shim.Error("Received unknown function invocation")
}
}
// ============================================================
// initMarble - create a new marble, store into chaincode state
// ============================================================
func (t *SimpleChaincode) initMarble(stub shim.ChaincodeStubInterface, args []string) pb.Response {
var err error
// 0-name 1-color 2-size 3-owner 4-price
// "asdf", "blue", "35", "bob", "99"
if len(args) != 5 {
return shim.Error("Incorrect number of arguments. Expecting 5")
}
// ==== Input sanitation ====
fmt.Println("- start init marble")
if len(args[0]) == 0 {
return shim.Error("1st argument must be a non-empty string")
}
if len(args[1]) == 0 {
return shim.Error("2nd argument must be a non-empty string")
}
if len(args[2]) == 0 {
return shim.Error("3rd argument must be a non-empty string")
}
if len(args[3]) == 0 {
return shim.Error("4th argument must be a non-empty string")
}
if len(args[4]) == 0 {
return shim.Error("5th argument must be a non-empty string")
}
marbleName := args[0]
color := strings.ToLower(args[1])
owner := strings.ToLower(args[3])
size, err := strconv.Atoi(args[2])
if err != nil {
return shim.Error("3rd argument must be a numeric string")
}
price, err := strconv.Atoi(args[4])
if err != nil {
return shim.Error("5th argument must be a numeric string")
}
// ==== Check if marble already exists ====
marbleAsBytes, err := stub.GetPrivateData("collectionMarbles", marbleName)
if err != nil {
return shim.Error("Failed to get marble: " + err.Error())
} else if marbleAsBytes != nil {
fmt.Println("This marble already exists: " + marbleName)
return shim.Error("This marble already exists: " + marbleName)
}
// ==== Create marble object and marshal to JSON ====
objectType := "marble"
marble := &marble{objectType, marbleName, color, size, owner}
marbleJSONasBytes, err := json.Marshal(marble)
if err != nil {
return shim.Error(err.Error())
}
//Alternatively, build the marble json string manually if you don't want to use struct marshalling
//marbleJSONasString := `{"docType":"Marble", "name": "` + marbleName + `", "color": "` + color + `", "size": ` + strconv.Itoa(size) + `, "owner": "` + owner + `"}`
//marbleJSONasBytes := []byte(str)
// === Save marble to state ===
err = stub.PutPrivateData("collectionMarbles", marbleName, marbleJSONasBytes)
if err != nil {
return shim.Error(err.Error())
}
// ==== Save marble private details ====
objectType = "marblePrivateDetails"
marblePrivateDetails := &marblePrivateDetails{objectType, marbleName, price}
marblePrivateDetailsBytes, err := json.Marshal(marblePrivateDetails)
if err != nil {
return shim.Error(err.Error())
}
err = stub.PutPrivateData("collectionMarblePrivateDetails", marbleName, marblePrivateDetailsBytes)
if err != nil {
return shim.Error(err.Error())
}
// ==== Index the marble to enable color-based range queries, e.g. return all blue marbles ====
// An 'index' is a normal key/value entry in state.
// The key is a composite key, with the elements that you want to range query on listed first.
// In our case, the composite key is based on indexName~color~name.
// This will enable very efficient state range queries based on composite keys matching indexName~color~*
indexName := "color~name"
colorNameIndexKey, err := stub.CreateCompositeKey(indexName, []string{marble.Color, marble.Name})
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 marble.
// Note - passing a 'nil' value will effectively delete the key from state, therefore we pass null character as value
value := []byte{0x00}
stub.PutPrivateData("collectionMarbles", colorNameIndexKey, value)
// ==== Marble saved and indexed. Return success ====
fmt.Println("- end init marble")
return shim.Success(nil)
}
// ===============================================
// readMarble - read a marble from chaincode state
// ===============================================
func (t *SimpleChaincode) readMarble(stub shim.ChaincodeStubInterface, args []string) pb.Response {
var name, jsonResp string
var err error
if len(args) != 1 {
return shim.Error("Incorrect number of arguments. Expecting name of the marble to query")
}
name = args[0]
valAsbytes, err := stub.GetPrivateData("collectionMarbles", name) //get the marble from chaincode state
if err != nil {
jsonResp = "{\"Error\":\"Failed to get state for " + name + "\"}"
return shim.Error(jsonResp)
} else if valAsbytes == nil {
jsonResp = "{\"Error\":\"Marble does not exist: " + name + "\"}"
return shim.Error(jsonResp)
}
return shim.Success(valAsbytes)
}
// ===============================================
// readMarblereadMarblePrivateDetails - read a marble private details from chaincode state
// ===============================================
func (t *SimpleChaincode) readMarblePrivateDetails(stub shim.ChaincodeStubInterface, args []string) pb.Response {
var name, jsonResp string
var err error
if len(args) != 1 {
return shim.Error("Incorrect number of arguments. Expecting name of the marble to query")
}
name = args[0]
valAsbytes, err := stub.GetPrivateData("collectionMarblePrivateDetails", name) //get the marble private details from chaincode state
if err != nil {
jsonResp = "{\"Error\":\"Failed to get private details for " + name + ": " + err.Error() + "\"}"
return shim.Error(jsonResp)
} else if valAsbytes == nil {
jsonResp = "{\"Error\":\"Marble private details does not exist: " + name + "\"}"
return shim.Error(jsonResp)
}
return shim.Success(valAsbytes)
}
// ==================================================
// delete - remove a marble key/value pair from state
// ==================================================
func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response {
var jsonResp string
var marbleJSON marble
if len(args) != 1 {
return shim.Error("Incorrect number of arguments. Expecting 1")
}
marbleName := args[0]
// to maintain the color~name index, we need to read the marble first and get its color
valAsbytes, err := stub.GetPrivateData("collectionMarbles", marbleName) //get the marble from chaincode state
if err != nil {
jsonResp = "{\"Error\":\"Failed to get state for " + marbleName + "\"}"
return shim.Error(jsonResp)
} else if valAsbytes == nil {
jsonResp = "{\"Error\":\"Marble does not exist: " + marbleName + "\"}"
return shim.Error(jsonResp)
}
err = json.Unmarshal([]byte(valAsbytes), &marbleJSON)
if err != nil {
jsonResp = "{\"Error\":\"Failed to decode JSON of: " + marbleName + "\"}"
return shim.Error(jsonResp)
}
err = stub.DelPrivateData("collectionMarbles", marbleName) //remove the marble from chaincode state
if err != nil {
return shim.Error("Failed to delete state:" + err.Error())
}
// maintain the index
indexName := "color~name"
colorNameIndexKey, err := stub.CreateCompositeKey(indexName, []string{marbleJSON.Color, marbleJSON.Name})
if err != nil {
return shim.Error(err.Error())
}
// Delete index entry to state.
err = stub.DelPrivateData("collectionMarbles", colorNameIndexKey)
if err != nil {
return shim.Error("Failed to delete state:" + err.Error())
}
// Delete private details of marble
err = stub.DelPrivateData("collectionMarblePrivateDetails", marbleName)
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(nil)
}
// ===========================================================
// transfer a marble by setting a new owner name on the marble
// ===========================================================
func (t *SimpleChaincode) transferMarble(stub shim.ChaincodeStubInterface, args []string) pb.Response {
// 0 1
// "name", "bob"
if len(args) < 2 {
return shim.Error("Incorrect number of arguments. Expecting 2")
}
marbleName := args[0]
newOwner := strings.ToLower(args[1])
fmt.Println("- start transferMarble ", marbleName, newOwner)
marbleAsBytes, err := stub.GetPrivateData("collectionMarbles", marbleName)
if err != nil {
return shim.Error("Failed to get marble:" + err.Error())
} else if marbleAsBytes == nil {
return shim.Error("Marble does not exist")
}
marbleToTransfer := marble{}
err = json.Unmarshal(marbleAsBytes, &marbleToTransfer) //unmarshal it aka JSON.parse()
if err != nil {
return shim.Error(err.Error())
}
marbleToTransfer.Owner = newOwner //change the owner
marbleJSONasBytes, _ := json.Marshal(marbleToTransfer)
err = stub.PutPrivateData("collectionMarbles", marbleName, marbleJSONasBytes) //rewrite the marble
if err != nil {
return shim.Error(err.Error())
}
fmt.Println("- end transferMarble (success)")
return shim.Success(nil)
}
// ===========================================================================================
// getMarblesByRange performs a range query based on the start and end keys provided.
// Read-only function results are not typically submitted to ordering. If the read-only
// results are submitted to ordering, or if the query is used in an update transaction
// and submitted to ordering, then the committing peers will re-execute to guarantee that
// result sets are stable between endorsement time and commit time. The transaction is
// invalidated by the committing peers if the result set has changed between endorsement
// time and commit time.
// Therefore, range queries are a safe option for performing update transactions based on query results.
// ===========================================================================================
func (t *SimpleChaincode) getMarblesByRange(stub shim.ChaincodeStubInterface, args []string) pb.Response {
if len(args) < 2 {
return shim.Error("Incorrect number of arguments. Expecting 2")
}
startKey := args[0]
endKey := args[1]
resultsIterator, err := stub.GetPrivateDataByRange("collectionMarbles", startKey, endKey)
if err != nil {
return shim.Error(err.Error())
}
defer resultsIterator.Close()
// buffer is a JSON array containing QueryResults
var buffer bytes.Buffer
buffer.WriteString("[")
bArrayMemberAlreadyWritten := false
for resultsIterator.HasNext() {
queryResponse, err := resultsIterator.Next()
if err != nil {
return shim.Error(err.Error())
}
// 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("- getMarblesByRange queryResult:\n%s\n", buffer.String())
return shim.Success(buffer.Bytes())
}
// ==== Example: GetStateByPartialCompositeKey/RangeQuery =========================================
// transferMarblesBasedOnColor will transfer marbles of a given color to a certain new owner.
// Uses a GetStateByPartialCompositeKey (range query) against color~name 'index'.
// Committing peers will re-execute range queries to guarantee that result sets are stable
// between endorsement time and commit time. The transaction is invalidated by the
// committing peers if the result set has changed between endorsement time and commit time.
// Therefore, range queries are a safe option for performing update transactions based on query results.
// ===========================================================================================
func (t *SimpleChaincode) transferMarblesBasedOnColor(stub shim.ChaincodeStubInterface, args []string) pb.Response {
// 0 1
// "color", "bob"
if len(args) < 2 {
return shim.Error("Incorrect number of arguments. Expecting 2")
}
color := args[0]
newOwner := strings.ToLower(args[1])
fmt.Println("- start transferMarblesBasedOnColor ", color, newOwner)
// Query the color~name index by color
// This will execute a key range query on all keys starting with 'color'
coloredMarbleResultsIterator, err := stub.GetPrivateDataByPartialCompositeKey("collectionMarbles", "color~name", []string{color})
if err != nil {
return shim.Error(err.Error())
}
defer coloredMarbleResultsIterator.Close()
// Iterate through result set and for each marble found, transfer to newOwner
var i int
for i = 0; coloredMarbleResultsIterator.HasNext(); i++ {
// Note that we don't get the value (2nd return variable), we'll just get the marble name from the composite key
responseRange, err := coloredMarbleResultsIterator.Next()
if err != nil {
return shim.Error(err.Error())
}
// get the color and name from color~name composite key
objectType, compositeKeyParts, err := stub.SplitCompositeKey(responseRange.Key)
if err != nil {
return shim.Error(err.Error())
}
returnedColor := compositeKeyParts[0]
returnedMarbleName := compositeKeyParts[1]
fmt.Printf("- found a marble from index:%s color:%s name:%s\n", objectType, returnedColor, returnedMarbleName)
// Now call the transfer function for the found marble.
// Re-use the same function that is used to transfer individual marbles
response := t.transferMarble(stub, []string{returnedMarbleName, newOwner})
// if the transfer failed break out of loop and return error
if response.Status != shim.OK {
return shim.Error("Transfer failed: " + response.Message)
}
}
responsePayload := fmt.Sprintf("Transferred %d %s marbles to %s", i, color, newOwner)
fmt.Println("- end transferMarblesBasedOnColor: " + responsePayload)
return shim.Success([]byte(responsePayload))
}
// =======Rich queries =========================================================================
// Two examples of rich queries are provided below (parameterized query and ad hoc query).
// Rich queries pass a query string to the state database.
// Rich queries are only supported by state database implementations
// that support rich query (e.g. CouchDB).
// The query string is in the syntax of the underlying state database.
// With rich queries there is no guarantee that the result set hasn't changed between
// endorsement time and commit time, aka 'phantom reads'.
// Therefore, rich queries should not be used in update transactions, unless the
// application handles the possibility of result set changes between endorsement and commit time.
// Rich queries can be used for point-in-time queries against a peer.
// ============================================================================================
// ===== Example: Parameterized rich query =================================================
// queryMarblesByOwner queries for marbles based on a passed in owner.
// This is an example of a parameterized query where the query logic is baked into the chaincode,
// and accepting a single query parameter (owner).
// Only available on state databases that support rich query (e.g. CouchDB)
// =========================================================================================
func (t *SimpleChaincode) queryMarblesByOwner(stub shim.ChaincodeStubInterface, args []string) pb.Response {
// 0
// "bob"
if len(args) < 1 {
return shim.Error("Incorrect number of arguments. Expecting 1")
}
owner := strings.ToLower(args[0])
queryString := fmt.Sprintf("{\"selector\":{\"docType\":\"marble\",\"owner\":\"%s\"}}", owner)
queryResults, err := getQueryResultForQueryString(stub, queryString)
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(queryResults)
}
// ===== Example: Ad hoc rich query ========================================================
// queryMarbles uses a query string to perform a query for marbles.
// Query string matching state database syntax is passed in and executed as is.
// Supports ad hoc queries that can be defined at runtime by the client.
// If this is not desired, follow the queryMarblesForOwner example for parameterized queries.
// Only available on state databases that support rich query (e.g. CouchDB)
// =========================================================================================
func (t *SimpleChaincode) queryMarbles(stub shim.ChaincodeStubInterface, args []string) pb.Response {
// 0
// "queryString"
if len(args) < 1 {
return shim.Error("Incorrect number of arguments. Expecting 1")
}
queryString := args[0]
queryResults, err := getQueryResultForQueryString(stub, queryString)
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(queryResults)
}
// =========================================================================================
// getQueryResultForQueryString executes the passed in query string.
// Result set is built and returned as a byte array containing the JSON results.
// =========================================================================================
func getQueryResultForQueryString(stub shim.ChaincodeStubInterface, queryString string) ([]byte, error) {
fmt.Printf("- getQueryResultForQueryString queryString:\n%s\n", queryString)
resultsIterator, err := stub.GetPrivateDataQueryResult("collectionMarbles", 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
}

3
fabcar/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/node_modules/
/package-lock.json
/hfc-key-store/

View file

@ -148,7 +148,7 @@ Fabric_Client.newDefaultKeyValueStore({ path: store_path
if (results && results[0] && results[0].status === 'SUCCESS') { if (results && results[0] && results[0].status === 'SUCCESS') {
console.log('Successfully sent transaction to the orderer.'); console.log('Successfully sent transaction to the orderer.');
} else { } else {
console.error('Failed to order the transaction. Error code: ' + response.status); console.error('Failed to order the transaction. Error code: ' + results[0].status);
} }
if(results && results[1] && results[1].event_status === 'VALID') { if(results && results[1] && results[1].event_status === 'VALID') {

View file

@ -71,7 +71,7 @@ Fabric_Client.newDefaultKeyValueStore({ path: store_path
return fabric_client.setUserContext(member_user); return fabric_client.setUserContext(member_user);
}).then(()=>{ }).then(()=>{
console.log('User1 was successfully registered and enrolled and is ready to intreact with the fabric network'); console.log('User1 was successfully registered and enrolled and is ready to interact with the fabric network');
}).catch((err) => { }).catch((err) => {
console.error('Failed to register: ' + err); console.error('Failed to register: ' + err);

View file

@ -81,7 +81,7 @@ with a value of "true". Note further that the chaincode used by this sample
requires this attribute be included in the certificate of the identity that requires this attribute be included in the certificate of the identity that
invokes its Init function. See the chaincode at *fabric-samples/chaincode/abac/abac.go*). invokes its Init function. See the chaincode at *fabric-samples/chaincode/abac/abac.go*).
For more information on Attribute-Based Access Control (ABAC), see For more information on Attribute-Based Access Control (ABAC), see
https://github.com/hyperledger/fabric/tree/release/core/chaincode/lib/cid/README.md. https://github.com/hyperledger/fabric/blob/master/core/chaincode/lib/cid/README.md.
4. The orderer and peer containers are started. The naming of these containers 4. The orderer and peer containers are started. The naming of these containers
is straight-forward as is their log files in the *data/logs* directory. is straight-forward as is their log files in the *data/logs* directory.

View file

@ -157,6 +157,14 @@ function chaincodeQuery {
logr "Query of channel '$CHANNEL_NAME' on peer '$PEER_HOST' was successful" logr "Query of channel '$CHANNEL_NAME' on peer '$PEER_HOST' was successful"
set -e set -e
return 0 return 0
else
# removed the string "Query Result" from peer chaincode query command result, as a result, have to support both options until the change is merged.
VALUE=$(cat log.txt | egrep '^[0-9]+$')
if [ $? -eq 0 -a "$VALUE" = "$1" ]; then
logr "Query of channel '$CHANNEL_NAME' on peer '$PEER_HOST' was successful"
set -e
return 0
fi
fi fi
echo -n "." echo -n "."
done done
@ -238,8 +246,8 @@ function createConfigUpdatePayloadWithCRL {
jq .data.data[0].payload.data.config config_block.json > config.json jq .data.data[0].payload.data.config config_block.json > config.json
# Update crl in the config json # Update crl in the config json
crl=$(cat $CORE_PEER_MSPCONFIGPATH/crls/crl*.pem | base64 | tr -d '\n') CRL=$(cat $CORE_PEER_MSPCONFIGPATH/crls/crl*.pem | base64 | tr -d '\n')
cat config.json | jq '.channel_group.groups.Application.groups.'"${ORG}"'.values.MSP.value.config.revocation_list = ["'"${crl}"'"]' > updated_config.json cat config.json | jq --arg org "$ORG" --arg crl "$CRL" '.channel_group.groups.Application.groups[$org].values.MSP.value.config.revocation_list = [$crl]' > updated_config.json
# Create the config diff protobuf # Create the config diff protobuf
curl -X POST --data-binary @config.json $CTLURL/protolator/encode/common.Config > config.pb curl -X POST --data-binary @config.json $CTLURL/protolator/encode/common.Config > config.pb
@ -266,6 +274,7 @@ function finish {
else else
logr "Tests did not complete successfully; see $RUN_LOGFILE for more details" logr "Tests did not complete successfully; see $RUN_LOGFILE for more details"
touch /$RUN_FAIL_FILE touch /$RUN_FAIL_FILE
exit 1
fi fi
} }

6
first-network/.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
/channel-artifacts/*.tx
/channel-artifacts/*.block
/crypto-config/*
/docker-compose-e2e.yaml
/ledgers
/ledgers-backup

View file

@ -30,13 +30,13 @@
# this may be commented out to resolve installed version of tools if desired # this may be commented out to resolve installed version of tools if desired
export PATH=${PWD}/../bin:${PWD}:$PATH export PATH=${PWD}/../bin:${PWD}:$PATH
export FABRIC_CFG_PATH=${PWD} export FABRIC_CFG_PATH=${PWD}
export VERBOSE=false
# Print the usage message # Print the usage message
function printHelp () { function printHelp () {
echo "Usage: " echo "Usage: "
echo " byfn.sh up|down|restart|generate|upgrade [-c <channel name>] [-t <timeout>] [-d <delay>] [-f <docker-compose-file>] [-s <dbtype>] [-i <imagetag>]" echo " byfn.sh <mode> [-c <channel name>] [-t <timeout>] [-d <delay>] [-f <docker-compose-file>] [-s <dbtype>] [-l <language>] [-i <imagetag>] [-v]"
echo " byfn.sh -h|--help (print this message)" echo " <mode> - one of 'up', 'down', 'restart', 'generate' or 'upgrade'"
echo " <mode> - one of 'up', 'down', 'restart' or 'generate'"
echo " - 'up' - bring up the network with docker-compose up" echo " - 'up' - bring up the network with docker-compose up"
echo " - 'down' - clear the network with docker-compose down" echo " - 'down' - clear the network with docker-compose down"
echo " - 'restart' - restart the network" echo " - 'restart' - restart the network"
@ -49,6 +49,8 @@ function printHelp () {
echo " -s <dbtype> - the database backend to use: goleveldb (default) or couchdb" echo " -s <dbtype> - the database backend to use: goleveldb (default) or couchdb"
echo " -l <language> - the chaincode language: golang (default) or node" echo " -l <language> - the chaincode language: golang (default) or node"
echo " -i <imagetag> - the tag to be used to launch the network (defaults to \"latest\")" echo " -i <imagetag> - the tag to be used to launch the network (defaults to \"latest\")"
echo " -v - verbose mode"
echo " byfn.sh -h (print this message)"
echo echo
echo "Typically, one would first generate the required certificates and " echo "Typically, one would first generate the required certificates and "
echo "genesis block, then bring up the network. e.g.:" echo "genesis block, then bring up the network. e.g.:"
@ -87,7 +89,7 @@ function askProceed () {
# Obtain CONTAINER_IDS and remove them # Obtain CONTAINER_IDS and remove them
# TODO Might want to make this optional - could clear other containers # TODO Might want to make this optional - could clear other containers
function clearContainers () { function clearContainers () {
CONTAINER_IDS=$(docker ps -aq) CONTAINER_IDS=$(docker ps -a |awk '($2 ~ /dev-peer.*.mycc.*/) {print $1}')
if [ -z "$CONTAINER_IDS" -o "$CONTAINER_IDS" == " " ]; then if [ -z "$CONTAINER_IDS" -o "$CONTAINER_IDS" == " " ]; then
echo "---- No containers available for deletion ----" echo "---- No containers available for deletion ----"
else else
@ -99,7 +101,7 @@ function clearContainers () {
# specifically the following images are often left behind: # specifically the following images are often left behind:
# TODO list generated image naming patterns # TODO list generated image naming patterns
function removeUnwantedImages() { function removeUnwantedImages() {
DOCKER_IMAGE_IDS=$(docker images | grep "dev\|none\|test-vp\|peer[0-9]-" | awk '{print $3}') DOCKER_IMAGE_IDS=$(docker images|awk '($1 ~ /dev-peer.*.mycc.*/) {print $3}')
if [ -z "$DOCKER_IMAGE_IDS" -o "$DOCKER_IMAGE_IDS" == " " ]; then if [ -z "$DOCKER_IMAGE_IDS" -o "$DOCKER_IMAGE_IDS" == " " ]; then
echo "---- No images available for deletion ----" echo "---- No images available for deletion ----"
else else
@ -163,7 +165,7 @@ function networkUp () {
exit 1 exit 1
fi fi
# now run the end to end script # now run the end to end script
docker exec cli scripts/script.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT docker exec cli scripts/script.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "ERROR !!!! Test failed" echo "ERROR !!!! Test failed"
exit 1 exit 1
@ -222,7 +224,7 @@ function upgradeNetwork () {
docker-compose $COMPOSE_FILES up -d --no-deps $PEER docker-compose $COMPOSE_FILES up -d --no-deps $PEER
done done
docker exec cli scripts/upgrade_to_v11.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT docker exec cli scripts/upgrade_to_v11.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "ERROR !!!! Test failed" echo "ERROR !!!! Test failed"
exit 1 exit 1
@ -232,8 +234,9 @@ function upgradeNetwork () {
# Tear down running network # Tear down running network
function networkDown () { function networkDown () {
docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH down --volumes # stop org3 containers also in addition to org1 and org2, in case we were running sample to add org3
docker-compose -f $COMPOSE_FILE down --volumes docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH -f $COMPOSE_FILE_ORG3 down --volumes --remove-orphans
# Don't remove the generated artifacts -- note, the ledgers are always removed # Don't remove the generated artifacts -- note, the ledgers are always removed
if [ "$MODE" != "restart" ]; then if [ "$MODE" != "restart" ]; then
# Bring down the network, deleting the volumes # Bring down the network, deleting the volumes
@ -440,6 +443,9 @@ CHANNEL_NAME="mychannel"
COMPOSE_FILE=docker-compose-cli.yaml COMPOSE_FILE=docker-compose-cli.yaml
# #
COMPOSE_FILE_COUCH=docker-compose-couch.yaml COMPOSE_FILE_COUCH=docker-compose-couch.yaml
# org3 docker compose file
COMPOSE_FILE_ORG3=docker-compose-org3.yaml
#
# use golang as the default language for chaincode # use golang as the default language for chaincode
LANGUAGE=golang LANGUAGE=golang
# default image tag # default image tag
@ -449,7 +455,7 @@ if [ "$1" = "-m" ];then # supports old usage, muscle memory is powerful!
shift shift
fi fi
MODE=$1;shift MODE=$1;shift
# Determine whether starting, stopping, restarting or generating for announce # Determine whether starting, stopping, restarting, generating or upgrading
if [ "$MODE" == "up" ]; then if [ "$MODE" == "up" ]; then
EXPMODE="Starting" EXPMODE="Starting"
elif [ "$MODE" == "down" ]; then elif [ "$MODE" == "down" ]; then
@ -465,7 +471,7 @@ else
exit 1 exit 1
fi fi
while getopts "h?m:c:t:d:f:s:l:i:" opt; do while getopts "h?c:t:d:f:s:l:i:v" opt; do
case "$opt" in case "$opt" in
h|\?) h|\?)
printHelp printHelp
@ -485,6 +491,8 @@ while getopts "h?m:c:t:d:f:s:l:i:" opt; do
;; ;;
i) IMAGETAG=`uname -m`"-"$OPTARG i) IMAGETAG=`uname -m`"-"$OPTARG
;; ;;
v) VERBOSE=true
;;
esac esac
done done

View file

@ -4,40 +4,6 @@
# #
--- ---
################################################################################
#
# Profile
#
# - Different configuration profiles may be encoded here to be specified
# as parameters to the configtxgen tool
#
################################################################################
Profiles:
TwoOrgsOrdererGenesis:
Capabilities:
<<: *ChannelCapabilities
Orderer:
<<: *OrdererDefaults
Organizations:
- *OrdererOrg
Capabilities:
<<: *OrdererCapabilities
Consortiums:
SampleConsortium:
Organizations:
- *Org1
- *Org2
TwoOrgsChannel:
Consortium: SampleConsortium
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
Capabilities:
<<: *ApplicationCapabilities
################################################################################ ################################################################################
# #
# Section: Organizations # Section: Organizations
@ -95,6 +61,69 @@ Organizations:
- Host: peer0.org2.example.com - Host: peer0.org2.example.com
Port: 7051 Port: 7051
################################################################################
#
# SECTION: Capabilities
#
# - This section defines the capabilities of fabric network. This is a new
# concept as of v1.1.0 and should not be utilized in mixed networks with
# v1.0.x peers and orderers. Capabilities define features which must be
# present in a fabric binary for that binary to safely participate in the
# fabric network. For instance, if a new MSP type is added, newer binaries
# might recognize and validate the signatures from this type, while older
# binaries without this support would be unable to validate those
# transactions. This could lead to different versions of the fabric binaries
# having different world states. Instead, defining a capability for a channel
# informs those binaries without this capability that they must cease
# processing transactions until they have been upgraded. For v1.0.x if any
# capabilities are defined (including a map with all capabilities turned off)
# then the v1.0.x peer will deliberately crash.
#
################################################################################
Capabilities:
# Channel capabilities apply to both the orderers and the peers and must be
# supported by both. Set the value of the capability to true to require it.
Global: &ChannelCapabilities
# V1.1 for Global is a catchall flag for behavior which has been
# determined to be desired for all orderers and peers running v1.0.x,
# but the modification of which would cause incompatibilities. Users
# should leave this flag set to true.
V1_1: true
# Orderer capabilities apply only to the orderers, and may be safely
# manipulated without concern for upgrading peers. Set the value of the
# capability to true to require it.
Orderer: &OrdererCapabilities
# V1.1 for Order is a catchall flag for behavior which has been
# determined to be desired for all orderers running v1.0.x, but the
# modification of which would cause incompatibilities. Users should
# leave this flag set to true.
V1_1: true
# Application capabilities apply only to the peer network, and may be safely
# manipulated without concern for upgrading orderers. Set the value of the
# capability to true to require it.
Application: &ApplicationCapabilities
# V1.2 for Application is a catchall flag for behavior which has been
# determined to be desired for all peers running v1.0.x, but the
# modification of which would cause incompatibilities. Users should
# leave this flag set to true.
V1_2: true
################################################################################
#
# SECTION: Application
#
# - This section defines the values to encode into a config transaction or
# genesis block for application related parameters
#
################################################################################
Application: &ApplicationDefaults
# Organizations is the list of orgs which are defined as participants on
# the application side of the network
Organizations:
################################################################################ ################################################################################
# #
# SECTION: Orderer # SECTION: Orderer
@ -142,63 +171,34 @@ Orderer: &OrdererDefaults
################################################################################ ################################################################################
# #
# SECTION: Application # Profile
# #
# - This section defines the values to encode into a config transaction or # - Different configuration profiles may be encoded here to be specified
# genesis block for application related parameters # as parameters to the configtxgen tool
# #
################################################################################ ################################################################################
Application: &ApplicationDefaults Profiles:
# Organizations is the list of orgs which are defined as participants on TwoOrgsOrdererGenesis:
# the application side of the network Capabilities:
Organizations: <<: *ChannelCapabilities
Orderer:
################################################################################ <<: *OrdererDefaults
# Organizations:
# SECTION: Capabilities - *OrdererOrg
# Capabilities:
# - This section defines the capabilities of fabric network. This is a new <<: *OrdererCapabilities
# concept as of v1.1.0 and should not be utilized in mixed networks with Consortiums:
# v1.0.x peers and orderers. Capabilities define features which must be SampleConsortium:
# present in a fabric binary for that binary to safely participate in the Organizations:
# fabric network. For instance, if a new MSP type is added, newer binaries - *Org1
# might recognize and validate the signatures from this type, while older - *Org2
# binaries without this support would be unable to validate those TwoOrgsChannel:
# transactions. This could lead to different versions of the fabric binaries Consortium: SampleConsortium
# having different world states. Instead, defining a capability for a channel Application:
# informs those binaries without this capability that they must cease <<: *ApplicationDefaults
# processing transactions until they have been upgraded. For v1.0.x if any Organizations:
# capabilities are defined (including a map with all capabilities turned off) - *Org1
# then the v1.0.x peer will deliberately crash. - *Org2
# Capabilities:
################################################################################ <<: *ApplicationCapabilities
Capabilities:
# Channel capabilities apply to both the orderers and the peers and must be
# supported by both. Set the value of the capability to true to require it.
Global: &ChannelCapabilities
# V1.1 for Global is a catchall flag for behavior which has been
# determined to be desired for all orderers and peers running v1.0.x,
# but the modification of which would cause incompatibilities. Users
# should leave this flag set to true.
V1_1: true
# Orderer capabilities apply only to the orderers, and may be safely
# manipulated without concern for upgrading peers. Set the value of the
# capability to true to require it.
Orderer: &OrdererCapabilities
# V1.1 for Order is a catchall flag for behavior which has been
# determined to be desired for all orderers running v1.0.x, but the
# modification of which would cause incompatibilities. Users should
# leave this flag set to true.
V1_1: true
# Application capabilities apply only to the peer network, and may be safely
# manipulated without concern for upgrading orderers. Set the value of the
# capability to true to require it.
Application: &ApplicationCapabilities
# V1.1 for Application is a catchall flag for behavior which has been
# determined to be desired for all peers running v1.0.x, but the
# modification of which would cause incompatibilities. Users should
# leave this flag set to true.
V1_1: true

View file

@ -82,6 +82,8 @@ services:
- /var/run/:/host/var/run/ - /var/run/:/host/var/run/
- ./../chaincode/:/opt/gopath/src/github.com/chaincode - ./../chaincode/:/opt/gopath/src/github.com/chaincode
- ./org3-artifacts/crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ - ./org3-artifacts/crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/
- ./crypto-config/peerOrganizations/org1.example.com:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com
- ./crypto-config/peerOrganizations/org2.example.com:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com
- ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/ - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/
depends_on: depends_on:
- peer0.org3.example.com - peer0.org3.example.com

View file

@ -14,6 +14,7 @@
# this may be commented out to resolve installed version of tools if desired # this may be commented out to resolve installed version of tools if desired
export PATH=${PWD}/../bin:${PWD}:$PATH export PATH=${PWD}/../bin:${PWD}:$PATH
export FABRIC_CFG_PATH=${PWD} export FABRIC_CFG_PATH=${PWD}
export VERBOSE=false
# Print the usage message # Print the usage message
function printHelp () { function printHelp () {
@ -32,6 +33,7 @@ function printHelp () {
echo " -s <dbtype> - the database backend to use: goleveldb (default) or couchdb" echo " -s <dbtype> - the database backend to use: goleveldb (default) or couchdb"
echo " -l <language> - the chaincode language: golang (default) or node" echo " -l <language> - the chaincode language: golang (default) or node"
echo " -i <imagetag> - the tag to be used to launch the network (defaults to \"latest\")" echo " -i <imagetag> - the tag to be used to launch the network (defaults to \"latest\")"
echo " -v - verbose mode"
echo echo
echo "Typically, one would first generate the required certificates and " echo "Typically, one would first generate the required certificates and "
echo "genesis block, then bring up the network. e.g.:" echo "genesis block, then bring up the network. e.g.:"
@ -80,7 +82,7 @@ function clearContainers () {
# specifically the following images are often left behind: # specifically the following images are often left behind:
# TODO list generated image naming patterns # TODO list generated image naming patterns
function removeUnwantedImages() { function removeUnwantedImages() {
DOCKER_IMAGE_IDS=$(docker images | grep "dev\|none\|test-vp\|peer[0-9]-" | awk '{print $3}') DOCKER_IMAGE_IDS=$(docker images|awk '($1 ~ /dev-peer.*.mycc.*/) {print $3}')
if [ -z "$DOCKER_IMAGE_IDS" -o "$DOCKER_IMAGE_IDS" == " " ]; then if [ -z "$DOCKER_IMAGE_IDS" -o "$DOCKER_IMAGE_IDS" == " " ]; then
echo "---- No images available for deletion ----" echo "---- No images available for deletion ----"
else else
@ -110,7 +112,7 @@ function networkUp () {
echo "###############################################################" echo "###############################################################"
echo "############### Have Org3 peers join network ##################" echo "############### Have Org3 peers join network ##################"
echo "###############################################################" echo "###############################################################"
docker exec Org3cli ./scripts/step2org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT docker exec Org3cli ./scripts/step2org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to have Org3 peers join network" echo "ERROR !!!! Unable to have Org3 peers join network"
exit 1 exit 1
@ -119,13 +121,13 @@ function networkUp () {
echo "###############################################################" echo "###############################################################"
echo "##### Upgrade chaincode to have Org3 peers on the network #####" echo "##### Upgrade chaincode to have Org3 peers on the network #####"
echo "###############################################################" echo "###############################################################"
docker exec cli ./scripts/step3org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT docker exec cli ./scripts/step3org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to add Org3 peers on network" echo "ERROR !!!! Unable to add Org3 peers on network"
exit 1 exit 1
fi fi
# finish by running the test # finish by running the test
docker exec Org3cli ./scripts/testorg3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT docker exec Org3cli ./scripts/testorg3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to run test" echo "ERROR !!!! Unable to run test"
exit 1 exit 1
@ -134,8 +136,7 @@ function networkUp () {
# Tear down running network # Tear down running network
function networkDown () { function networkDown () {
docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_ORG3 down --volumes docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_ORG3 -f $COMPOSE_FILE_COUCH down --volumes --remove-orphans
docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_ORG3 -f $COMPOSE_FILE_COUCH down --volumes
# Don't remove containers, images, etc if restarting # Don't remove containers, images, etc if restarting
if [ "$MODE" != "restart" ]; then if [ "$MODE" != "restart" ]; then
#Cleanup the chaincode containers #Cleanup the chaincode containers
@ -147,10 +148,6 @@ function networkDown () {
# remove the docker-compose yaml file that was customized to the example # remove the docker-compose yaml file that was customized to the example
rm -f docker-compose-e2e.yaml rm -f docker-compose-e2e.yaml
fi fi
# For some black-magic reason the first docker-compose down does not actually cleanup the volumes
docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_ORG3 down --volumes
docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_ORG3 -f $COMPOSE_FILE_COUCH down --volumes
} }
# Use the CLI container to create the configuration transaction needed to add # Use the CLI container to create the configuration transaction needed to add
@ -160,7 +157,7 @@ function createConfigTx () {
echo "###############################################################" echo "###############################################################"
echo "####### Generate and submit config tx to add Org3 #############" echo "####### Generate and submit config tx to add Org3 #############"
echo "###############################################################" echo "###############################################################"
docker exec cli scripts/step1org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT docker exec cli scripts/step1org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to create config tx" echo "ERROR !!!! Unable to create config tx"
exit 1 exit 1
@ -271,7 +268,7 @@ else
printHelp printHelp
exit 1 exit 1
fi fi
while getopts "h?c:t:d:f:s:l:i:" opt; do while getopts "h?c:t:d:f:s:l:i:v" opt; do
case "$opt" in case "$opt" in
h|\?) h|\?)
printHelp printHelp
@ -291,6 +288,8 @@ while getopts "h?c:t:d:f:s:l:i:" opt; do
;; ;;
i) IMAGETAG=$OPTARG i) IMAGETAG=$OPTARG
;; ;;
v) VERBOSE=true
;;
esac esac
done done

View file

@ -13,14 +13,15 @@ CHANNEL_NAME="$1"
DELAY="$2" DELAY="$2"
LANGUAGE="$3" LANGUAGE="$3"
TIMEOUT="$4" TIMEOUT="$4"
VERBOSE="$5"
: ${CHANNEL_NAME:="mychannel"} : ${CHANNEL_NAME:="mychannel"}
: ${DELAY:="3"} : ${DELAY:="3"}
: ${LANGUAGE:="golang"} : ${LANGUAGE:="golang"}
: ${TIMEOUT:="10"} : ${TIMEOUT:="10"}
: ${VERBOSE:="false"}
LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]`
COUNTER=1 COUNTER=1
MAX_RETRY=5 MAX_RETRY=5
ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/"
if [ "$LANGUAGE" = "node" ]; then if [ "$LANGUAGE" = "node" ]; then
@ -48,7 +49,7 @@ createChannel() {
fi fi
cat log.txt cat log.txt
verifyResult $res "Channel creation failed" verifyResult $res "Channel creation failed"
echo "===================== Channel \"$CHANNEL_NAME\" is created successfully ===================== " echo "===================== Channel '$CHANNEL_NAME' created ===================== "
echo echo
} }
@ -56,7 +57,7 @@ joinChannel () {
for org in 1 2; do for org in 1 2; do
for peer in 0 1; do for peer in 0 1; do
joinChannelWithRetry $peer $org joinChannelWithRetry $peer $org
echo "===================== peer${peer}.org${org} joined on the channel \"$CHANNEL_NAME\" ===================== " echo "===================== peer${peer}.org${org} joined channel '$CHANNEL_NAME' ===================== "
sleep $DELAY sleep $DELAY
echo echo
done done
@ -91,9 +92,9 @@ instantiateChaincode 0 2
echo "Querying chaincode on peer0.org1..." echo "Querying chaincode on peer0.org1..."
chaincodeQuery 0 1 100 chaincodeQuery 0 1 100
# Invoke chaincode on peer0.org1 # Invoke chaincode on peer0.org1 and peer0.org2
echo "Sending invoke transaction on peer0.org1..." echo "Sending invoke transaction on peer0.org1 peer0.org2..."
chaincodeInvoke 0 1 chaincodeInvoke 0 1 0 2
## Install chaincode on peer1.org2 ## Install chaincode on peer1.org2
echo "Installing chaincode on peer1.org2..." echo "Installing chaincode on peer1.org2..."

View file

@ -15,14 +15,15 @@ CHANNEL_NAME="$1"
DELAY="$2" DELAY="$2"
LANGUAGE="$3" LANGUAGE="$3"
TIMEOUT="$4" TIMEOUT="$4"
VERBOSE="$5"
: ${CHANNEL_NAME:="mychannel"} : ${CHANNEL_NAME:="mychannel"}
: ${DELAY:="3"} : ${DELAY:="3"}
: ${LANGUAGE:="golang"} : ${LANGUAGE:="golang"}
: ${TIMEOUT:="10"} : ${TIMEOUT:="10"}
: ${VERBOSE:="false"}
LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]`
COUNTER=1 COUNTER=1
MAX_RETRY=5 MAX_RETRY=5
ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/"
if [ "$LANGUAGE" = "node" ]; then if [ "$LANGUAGE" = "node" ]; then

View file

@ -18,14 +18,15 @@ CHANNEL_NAME="$1"
DELAY="$2" DELAY="$2"
LANGUAGE="$3" LANGUAGE="$3"
TIMEOUT="$4" TIMEOUT="$4"
VERBOSE="$5"
: ${CHANNEL_NAME:="mychannel"} : ${CHANNEL_NAME:="mychannel"}
: ${DELAY:="3"} : ${DELAY:="3"}
: ${LANGUAGE:="golang"} : ${LANGUAGE:="golang"}
: ${TIMEOUT:="10"} : ${TIMEOUT:="10"}
: ${VERBOSE:="false"}
LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]`
COUNTER=1 COUNTER=1
MAX_RETRY=5 MAX_RETRY=5
ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/"
if [ "$LANGUAGE" = "node" ]; then if [ "$LANGUAGE" = "node" ]; then
@ -43,17 +44,15 @@ set +x
cat log.txt cat log.txt
verifyResult $res "Fetching config block from orderer has Failed" verifyResult $res "Fetching config block from orderer has Failed"
echo "===================== Having peer0.org3 join the channel ===================== "
joinChannelWithRetry 0 3 joinChannelWithRetry 0 3
echo "===================== peer0.org3 joined the channel \"$CHANNEL_NAME\" ===================== " echo "===================== peer0.org3 joined channel '$CHANNEL_NAME' ===================== "
echo "===================== Having peer1.org3 join the channel ===================== "
joinChannelWithRetry 1 3 joinChannelWithRetry 1 3
echo "===================== peer1.org3 joined the channel \"$CHANNEL_NAME\" ===================== " echo "===================== peer1.org3 joined channel '$CHANNEL_NAME' ===================== "
echo "Installing chaincode 2.0 on peer0.org3..." echo "Installing chaincode 2.0 on peer0.org3..."
installChaincode 0 3 2.0 installChaincode 0 3 2.0
echo echo
echo "========= Got Org3 halfway onto your first network ========= " echo "========= Org3 is now halfway onto your first network ========= "
echo echo
exit 0 exit 0

View file

@ -19,14 +19,15 @@ CHANNEL_NAME="$1"
DELAY="$2" DELAY="$2"
LANGUAGE="$3" LANGUAGE="$3"
TIMEOUT="$4" TIMEOUT="$4"
VERBOSE="$5"
: ${CHANNEL_NAME:="mychannel"} : ${CHANNEL_NAME:="mychannel"}
: ${DELAY:="3"} : ${DELAY:="3"}
: ${LANGUAGE:="golang"} : ${LANGUAGE:="golang"}
: ${TIMEOUT:="10"} : ${TIMEOUT:="10"}
: ${VERBOSE:="false"}
LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]`
COUNTER=1 COUNTER=1
MAX_RETRY=5 MAX_RETRY=5
ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/"
if [ "$LANGUAGE" = "node" ]; then if [ "$LANGUAGE" = "node" ]; then

View file

@ -24,13 +24,14 @@ CHANNEL_NAME="$1"
DELAY="$2" DELAY="$2"
LANGUAGE="$3" LANGUAGE="$3"
TIMEOUT="$4" TIMEOUT="$4"
VERBOSE="$5"
: ${CHANNEL_NAME:="mychannel"} : ${CHANNEL_NAME:="mychannel"}
: ${TIMEOUT:="10"} : ${TIMEOUT:="10"}
: ${LANGUAGE:="golang"} : ${LANGUAGE:="golang"}
: ${VERBOSE:="false"}
LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]`
COUNTER=1 COUNTER=1
MAX_RETRY=5 MAX_RETRY=5
ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/"
if [ "$LANGUAGE" = "node" ]; then if [ "$LANGUAGE" = "node" ]; then
@ -42,10 +43,27 @@ echo "Channel name : "$CHANNEL_NAME
# import functions # import functions
. scripts/utils.sh . scripts/utils.sh
# Query chaincode on peer0.org3, check if the result is 90
echo "Querying chaincode on peer0.org3..."
chaincodeQuery 0 3 90 chaincodeQuery 0 3 90
chaincodeInvoke 0 3
# Invoke chaincode on peer0.org1, peer0.org2, and peer0.org3
echo "Sending invoke transaction on peer0.org1 peer0.org2 peer0.org3..."
chaincodeInvoke 0 1 0 2 0 3
# Query on chaincode on peer0.org3, peer0.org2, peer0.org1 check if the result is 80
# We query a peer in each organization, to ensure peers from all organizations are in sync
# and there is no state fork between organizations.
echo "Querying chaincode on peer0.org3..."
chaincodeQuery 0 3 80 chaincodeQuery 0 3 80
echo "Querying chaincode on peer0.org2..."
chaincodeQuery 0 2 80
echo "Querying chaincode on peer0.org1..."
chaincodeQuery 0 1 80
echo echo
echo "========= All GOOD, EYFN test execution completed =========== " echo "========= All GOOD, EYFN test execution completed =========== "
echo echo

View file

@ -13,14 +13,15 @@ CHANNEL_NAME="$1"
DELAY="$2" DELAY="$2"
LANGUAGE="$3" LANGUAGE="$3"
TIMEOUT="$4" TIMEOUT="$4"
VERBOSE="$5"
: ${CHANNEL_NAME:="mychannel"} : ${CHANNEL_NAME:="mychannel"}
: ${DELAY:="5"} : ${DELAY:="5"}
: ${LANGUAGE:="golang"} : ${LANGUAGE:="golang"}
: ${TIMEOUT:="10"} : ${TIMEOUT:="10"}
: ${VERBOSE:="false"}
LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]`
COUNTER=1 COUNTER=1
MAX_RETRY=5 MAX_RETRY=5
ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/"
if [ "$LANGUAGE" = "node" ]; then if [ "$LANGUAGE" = "node" ]; then

View file

@ -6,6 +6,10 @@
# This is a collection of bash functions used by different scripts # This is a collection of bash functions used by different scripts
ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
PEER0_ORG1_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
PEER0_ORG2_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
PEER0_ORG3_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt
# verify the result of the end-to-end test # verify the result of the end-to-end test
verifyResult () { verifyResult () {
@ -29,7 +33,7 @@ setGlobals () {
ORG=$2 ORG=$2
if [ $ORG -eq 1 ] ; then if [ $ORG -eq 1 ] ; then
CORE_PEER_LOCALMSPID="Org1MSP" CORE_PEER_LOCALMSPID="Org1MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
if [ $PEER -eq 0 ]; then if [ $PEER -eq 0 ]; then
CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_ADDRESS=peer0.org1.example.com:7051
@ -38,7 +42,7 @@ setGlobals () {
fi fi
elif [ $ORG -eq 2 ] ; then elif [ $ORG -eq 2 ] ; then
CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_LOCALMSPID="Org2MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
if [ $PEER -eq 0 ]; then if [ $PEER -eq 0 ]; then
CORE_PEER_ADDRESS=peer0.org2.example.com:7051 CORE_PEER_ADDRESS=peer0.org2.example.com:7051
@ -48,7 +52,7 @@ setGlobals () {
elif [ $ORG -eq 3 ] ; then elif [ $ORG -eq 3 ] ; then
CORE_PEER_LOCALMSPID="Org3MSP" CORE_PEER_LOCALMSPID="Org3MSP"
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG3_CA
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp
if [ $PEER -eq 0 ]; then if [ $PEER -eq 0 ]; then
CORE_PEER_ADDRESS=peer0.org3.example.com:7051 CORE_PEER_ADDRESS=peer0.org3.example.com:7051
@ -59,7 +63,9 @@ setGlobals () {
echo "================== ERROR !!! ORG Unknown ==================" echo "================== ERROR !!! ORG Unknown =================="
fi fi
env |grep CORE if [ "$VERBOSE" == "true" ]; then
env |grep CORE
fi
} }
@ -81,12 +87,12 @@ updateAnchorPeers() {
fi fi
cat log.txt cat log.txt
verifyResult $res "Anchor peer update failed" verifyResult $res "Anchor peer update failed"
echo "===================== Anchor peers for org \"$CORE_PEER_LOCALMSPID\" on \"$CHANNEL_NAME\" is updated successfully ===================== " echo "===================== Anchor peers updated for org '$CORE_PEER_LOCALMSPID' on channel '$CHANNEL_NAME' ===================== "
sleep $DELAY sleep $DELAY
echo echo
} }
## Sometimes Join takes time hence RETRY at least for 5 times ## Sometimes Join takes time hence RETRY at least 5 times
joinChannelWithRetry () { joinChannelWithRetry () {
PEER=$1 PEER=$1
ORG=$2 ORG=$2
@ -105,7 +111,7 @@ joinChannelWithRetry () {
else else
COUNTER=1 COUNTER=1
fi fi
verifyResult $res "After $MAX_RETRY attempts, peer${PEER}.org${ORG} has failed to Join the Channel" verifyResult $res "After $MAX_RETRY attempts, peer${PEER}.org${ORG} has failed to join channel '$CHANNEL_NAME' "
} }
installChaincode () { installChaincode () {
@ -118,7 +124,7 @@ installChaincode () {
res=$? res=$?
set +x set +x
cat log.txt cat log.txt
verifyResult $res "Chaincode installation on peer${PEER}.org${ORG} has Failed" verifyResult $res "Chaincode installation on peer${PEER}.org${ORG} has failed"
echo "===================== Chaincode is installed on peer${PEER}.org${ORG} ===================== " echo "===================== Chaincode is installed on peer${PEER}.org${ORG} ===================== "
echo echo
} }
@ -129,22 +135,23 @@ instantiateChaincode () {
setGlobals $PEER $ORG setGlobals $PEER $ORG
VERSION=${3:-1.0} VERSION=${3:-1.0}
# while 'peer chaincode' command can get the orderer endpoint from the peer (if join was successful), # while 'peer chaincode' command can get the orderer endpoint from the peer
# lets supply it directly as we know it using the "-o" option # (if join was successful), let's supply it directly as we know it using
# the "-o" option
if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
set -x set -x
peer chaincode instantiate -o orderer.example.com:7050 -C $CHANNEL_NAME -n mycc -l ${LANGUAGE} -v ${VERSION} -c '{"Args":["init","a","100","b","200"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer')" >&log.txt peer chaincode instantiate -o orderer.example.com:7050 -C $CHANNEL_NAME -n mycc -l ${LANGUAGE} -v ${VERSION} -c '{"Args":["init","a","100","b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')" >&log.txt
res=$? res=$?
set +x set +x
else else
set -x set -x
peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -l ${LANGUAGE} -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer')" >&log.txt peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -l ${LANGUAGE} -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')" >&log.txt
res=$? res=$?
set +x set +x
fi fi
cat log.txt cat log.txt
verifyResult $res "Chaincode instantiation on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' failed" verifyResult $res "Chaincode instantiation on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' failed"
echo "===================== Chaincode Instantiation on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' is successful ===================== " echo "===================== Chaincode is instantiated on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' ===================== "
echo echo
} }
@ -154,12 +161,12 @@ upgradeChaincode () {
setGlobals $PEER $ORG setGlobals $PEER $ORG
set -x set -x
peer chaincode upgrade -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 2.0 -c '{"Args":["init","a","90","b","210"]}' -P "OR ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')" peer chaincode upgrade -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 2.0 -c '{"Args":["init","a","90","b","210"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')"
res=$? res=$?
set +x set +x
cat log.txt cat log.txt
verifyResult $res "Chaincode upgrade on org${ORG} peer${PEER} has Failed" verifyResult $res "Chaincode upgrade on peer${PEER}.org${ORG} has failed"
echo "===================== Chaincode is upgraded on org${ORG} peer${PEER} ===================== " echo "===================== Chaincode is upgraded on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' ===================== "
echo echo
} }
@ -184,11 +191,16 @@ chaincodeQuery () {
set +x set +x
test $res -eq 0 && VALUE=$(cat log.txt | awk '/Query Result/ {print $NF}') test $res -eq 0 && VALUE=$(cat log.txt | awk '/Query Result/ {print $NF}')
test "$VALUE" = "$EXPECTED_RESULT" && let rc=0 test "$VALUE" = "$EXPECTED_RESULT" && let rc=0
# removed the string "Query Result" from peer chaincode query command
# result. as a result, have to support both options until the change
# is merged.
test $rc -ne 0 && VALUE=$(cat log.txt | egrep '^[0-9]+$')
test "$VALUE" = "$EXPECTED_RESULT" && let rc=0
done done
echo echo
cat log.txt cat log.txt
if test $rc -eq 0 ; then if test $rc -eq 0 ; then
echo "===================== Query on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' is successful ===================== " echo "===================== Query successful on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' ===================== "
else else
echo "!!!!!!!!!!!!!!! Query result on peer${PEER}.org${ORG} is INVALID !!!!!!!!!!!!!!!!" echo "!!!!!!!!!!!!!!! Query result on peer${PEER}.org${ORG} is INVALID !!!!!!!!!!!!!!!!"
echo "================== ERROR !!! FAILED to execute End-2-End Scenario ==================" echo "================== ERROR !!! FAILED to execute End-2-End Scenario =================="
@ -234,7 +246,8 @@ signConfigtxAsPeerOrg() {
} }
# createConfigUpdate <channel_id> <original_config.json> <modified_config.json> <output.pb> # createConfigUpdate <channel_id> <original_config.json> <modified_config.json> <output.pb>
# Takes an original and modified config, and produces the config update tx which transitions between the two # Takes an original and modified config, and produces the config update tx
# which transitions between the two
createConfigUpdate() { createConfigUpdate() {
CHANNEL=$1 CHANNEL=$1
ORIGINAL=$2 ORIGINAL=$2
@ -251,25 +264,56 @@ createConfigUpdate() {
set +x set +x
} }
# parsePeerConnectionParameters $@
# Helper function that takes the parameters from a chaincode operation
# (e.g. invoke, query, instantiate) and checks for an even number of
# peers and associated org, then sets $PEER_CONN_PARMS and $PEERS
parsePeerConnectionParameters() {
# check for uneven number of peer and org parameters
if [ $(( $# % 2 )) -ne 0 ]; then
exit 1
fi
PEER_CONN_PARMS=""
PEERS=""
while [ "$#" -gt 0 ]; do
PEER="peer$1.org$2"
PEERS="$PEERS $PEER"
PEER_CONN_PARMS="$PEER_CONN_PARMS --peerAddresses $PEER.example.com:7051"
if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "true" ]; then
TLSINFO=$(eval echo "--tlsRootCertFiles \$PEER$1_ORG$2_CA")
PEER_CONN_PARMS="$PEER_CONN_PARMS $TLSINFO"
fi
# shift by two to get the next pair of peer/org parameters
shift; shift
done
# remove leading space for output
PEERS="$(echo -e "$PEERS" | sed -e 's/^[[:space:]]*//')"
}
# chaincodeInvoke <peer> <org> ...
# Accepts as many peer/org pairs as desired and requests endorsement from each
chaincodeInvoke () { chaincodeInvoke () {
PEER=$1 parsePeerConnectionParameters $@
ORG=$2 res=$?
setGlobals $PEER $ORG verifyResult $res "Invoke transaction failed on channel '$CHANNEL_NAME' due to uneven number of peer and org parameters "
# 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 # while 'peer chaincode' command can get the orderer endpoint from the
# peer (if join was successful), let's supply it directly as we know
# it using the "-o" option
if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then
set -x set -x
peer chaincode invoke -o orderer.example.com:7050 -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}' >&log.txt peer chaincode invoke -o orderer.example.com:7050 -C $CHANNEL_NAME -n mycc $PEER_CONN_PARMS -c '{"Args":["invoke","a","b","10"]}' >&log.txt
res=$? res=$?
set +x set +x
else else
set -x set -x
peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}' >&log.txt peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc $PEER_CONN_PARMS -c '{"Args":["invoke","a","b","10"]}' >&log.txt
res=$? res=$?
set +x set +x
fi fi
cat log.txt cat log.txt
verifyResult $res "Invoke execution on peer${PEER}.org${ORG} failed " verifyResult $res "Invoke execution on $PEERS failed "
echo "===================== Invoke transaction on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' is successful ===================== " echo "===================== Invoke transaction successful on $PEERS on channel '$CHANNEL_NAME' ===================== "
echo echo
} }

View file

@ -1,3 +1,9 @@
<!--
Copyright IBM Corp All Rights Reserved
SPDX-License-Identifier: Apache-2.0
-->
# High-Throughput Network # High-Throughput Network
## Purpose ## Purpose
@ -106,9 +112,9 @@ and run some invocations are provided below.
`./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/` --> `./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/` -->
`./../high-throughput/scripts/:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/` `./../high-throughput/scripts/:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/`
* Finally, comment out the `command` section by placing a `#` before it, e.g. * Finally, comment out the `docker exec cli scripts/script.sh` command from the `byfn.sh` script by placing a `#` before it so that the standard BYFN end to end script doesn't run, e.g.
`#command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT'` `# docker exec cli scripts/script.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE`
3. We can now bring our network up by typing in `./byfn.sh -m up -c mychannel` 3. We can now bring our network up by typing in `./byfn.sh -m up -c mychannel`
4. Open a new terminal window and enter the CLI container using `docker exec -it cli bash`, all operations on the network will happen within 4. Open a new terminal window and enter the CLI container using `docker exec -it cli bash`, all operations on the network will happen within

View file

@ -1,4 +1,8 @@
/* /*
* Copyright IBM Corp All Rights Reserved
*
* SPDX-License-Identifier: Apache-2.0
*
* Demonstrates how to handle data in an application with a high transaction volume where the transactions * Demonstrates how to handle data in an application with a high transaction volume where the transactions
* all attempt to change the same key-value pair in the ledger. Such an application will have trouble * all attempt to change the same key-value pair in the ledger. Such an application will have trouble
* as multiple transactions may read a value at a certain version, which will then be invalid when the first * as multiple transactions may read a value at a certain version, which will then be invalid when the first

View file

@ -1,3 +1,9 @@
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
# Channel creation # Channel creation

View file

@ -1,2 +1,8 @@
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["delete","'$1'"]}' peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["delete","'$1'"]}'

View file

@ -1,2 +1,8 @@
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["get","'$1'"]}' peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["get","'$1'"]}'

View file

@ -1 +1,7 @@
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["getstandard","'$1'"]}' peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["getstandard","'$1'"]}'

View file

@ -1,3 +1,9 @@
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
echo "========== Installing chaincode on peer0.org1 ==========" echo "========== Installing chaincode on peer0.org1 =========="
export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp export CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_ADDRESS=peer0.org1.example.com:7051 export CORE_PEER_ADDRESS=peer0.org1.example.com:7051

View file

@ -1,3 +1,9 @@
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
echo "========== Instantiating chaincode v$1 ==========" echo "========== Instantiating chaincode v$1 =========="
peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args": []}' -v $1 -P "OR ('Org1MSP.member','Org2MSP.member')" peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args": []}' -v $1 -P "OR ('Org1MSP.member','Org2MSP.member')"

View file

@ -1,3 +1,9 @@
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
for (( i = 0; i < 1000; ++i )) for (( i = 0; i < 1000; ++i ))
do do
peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["putstandard","'$1'","'$i'"]}' peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["putstandard","'$1'","'$i'"]}'

View file

@ -1,3 +1,9 @@
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
for (( i = 0; i < 1000; ++i )) for (( i = 0; i < 1000; ++i ))
do do
peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["update","'$1'","'$2'","'$3'"]}' & peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["update","'$1'","'$2'","'$3'"]}' &

View file

@ -1,2 +1,8 @@
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["prunefast","'$1'"]}' peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["prunefast","'$1'"]}'

View file

@ -1,2 +1,8 @@
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["prunesafe","'$1'"]}' peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["prunesafe","'$1'"]}'

View file

@ -1,2 +1,8 @@
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
export CHANNEL_NAME=mychannel export CHANNEL_NAME=mychannel
export CC_NAME=bigdatacc export CC_NAME=bigdatacc

View file

@ -1,2 +1,8 @@
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["update","'$1'","'$2'","'$3'"]}' peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args":["update","'$1'","'$2'","'$3'"]}'

View file

@ -1,3 +1,9 @@
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
echo "========== Upgrade chaincode to version $1 ==========" echo "========== Upgrade chaincode to version $1 =========="
peer chaincode upgrade -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args": []}' -v $1 -P "OR ('Org1MSP.member','Org2MSP.member')" peer chaincode upgrade -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n $CC_NAME -c '{"Args": []}' -v $1 -P "OR ('Org1MSP.member','Org2MSP.member')"

220
scripts/bootstrap.sh Executable file
View file

@ -0,0 +1,220 @@
#!/bin/bash
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
# if version not passed in, default to latest released version
export VERSION=1.1.0
# if ca version not passed in, default to latest released version
export CA_VERSION=$VERSION
# current version of thirdparty images (couchdb, kafka and zookeeper) released
export THIRDPARTY_IMAGE_VERSION=0.4.7
export ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')")
export MARCH=$(uname -m)
# ensure we're in the fabric-samples directory
dir=`basename $PWD`
if [ "${dir}" == "scripts" ]; then
cd ..
fi
dir=`basename $PWD`
if [ "${dir}" != "fabric-samples" ]; then
echo "You should run this script from the fabric-samples root directory."
exit 1
fi
printHelp() {
echo "Usage: bootstrap.sh [<version>] [<ca_version>] [<thirdparty_version>][-d -b]"
echo
echo "-d - bypass docker image download"
echo "-b - bypass download of platform-specific binaries"
echo
echo "e.g. bootstrap.sh 1.1.1"
echo "would download docker images and binaries for version 1.1.1"
}
dockerFabricPull() {
local FABRIC_TAG=$1
for IMAGES in peer orderer ccenv tools; do
echo "==> FABRIC IMAGE: $IMAGES"
echo
docker pull hyperledger/fabric-$IMAGES:$FABRIC_TAG
docker tag hyperledger/fabric-$IMAGES:$FABRIC_TAG hyperledger/fabric-$IMAGES
done
}
dockerThirdPartyImagesPull() {
local THIRDPARTY_TAG=$1
for IMAGES in couchdb kafka zookeeper; do
echo "==> THIRDPARTY DOCKER IMAGE: $IMAGES"
echo
docker pull hyperledger/fabric-$IMAGES:$THIRDPARTY_TAG
docker tag hyperledger/fabric-$IMAGES:$THIRDPARTY_TAG hyperledger/fabric-$IMAGES
done
}
dockerCaPull() {
local CA_TAG=$1
echo "==> FABRIC CA IMAGE"
echo
docker pull hyperledger/fabric-ca:$CA_TAG
docker tag hyperledger/fabric-ca:$CA_TAG hyperledger/fabric-ca
}
# Incrementally downloads the .tar.gz file locally first, only decompressing it
# after the download is complete. This is slower than binaryDownload() but
# allows the download to be resumed.
binaryIncrementalDownload() {
local BINARY_FILE=$1
local URL=$2
curl -f -s -C - ${URL} -o ${BINARY_FILE} || rc=$?
# Due to limitations in the current Nexus repo:
# curl returns 33 when there's a resume attempt with no more bytes to download
# curl returns 2 after finishing a resumed download
# with -f curl returns 22 on a 404
if [ "$rc" = 22 ]; then
# looks like the requested file doesn't actually exist so stop here
return 22
fi
if [ -z "$rc" ] || [ $rc -eq 33 ] || [ $rc -eq 2 ]; then
# The checksum validates that RC 33 or 2 are not real failures
echo "==> File downloaded. Verifying the md5sum..."
localMd5sum=$(md5sum ${BINARY_FILE} | awk '{print $1}')
remoteMd5sum=$(curl -s ${URL}.md5)
if [ "$localMd5sum" == "$remoteMd5sum" ]; then
echo "==> Extracting ${BINARY_FILE}..."
tar xzf ./${BINARY_FILE} --overwrite
echo "==> Done."
rm -f ${BINARY_FILE} ${BINARY_FILE}.md5
else
echo "Download failed: the local md5sum is different from the remote md5sum. Please try again."
rm -f ${BINARY_FILE} ${BINARY_FILE}.md5
exit 1
fi
else
echo "Failure downloading binaries (curl RC=$rc). Please try again and the download will resume from where it stopped."
exit 1
fi
}
# This will attempt to download the .tar.gz all at once, but will trigger the
# binaryIncrementalDownload() function upon a failure, allowing for resume
# if there are network failures.
binaryDownload() {
local BINARY_FILE=$1
local URL=$2
echo "===> Downloading: " ${URL}
# Check if a previous failure occurred and the file was partially downloaded
if [ -e ${BINARY_FILE} ]; then
echo "==> Partial binary file found. Resuming download..."
binaryIncrementalDownload ${BINARY_FILE} ${URL}
else
curl ${URL} | tar xz || rc=$?
if [ ! -z "$rc" ]; then
echo "==> There was an error downloading the binary file. Switching to incremental download."
echo "==> Downloading file..."
binaryIncrementalDownload ${BINARY_FILE} ${URL}
else
echo "==> Done."
fi
fi
}
binariesInstall() {
echo "===> Downloading version ${FABRIC_TAG} platform specific fabric binaries"
binaryDownload ${BINARY_FILE} https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fabric/${ARCH}-${VERSION}/${BINARY_FILE}
if [ $? -eq 22 ]; then
echo
echo "------> ${FABRIC_TAG} platform specific fabric binary is not available to download <----"
echo
fi
echo "===> Downloading version ${CA_TAG} platform specific fabric-ca-client binary"
binaryDownload ${CA_BINARY_FILE} https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric-ca/hyperledger-fabric-ca/${ARCH}-${CA_VERSION}/${CA_BINARY_FILE}
if [ $? -eq 22 ]; then
echo
echo "------> ${CA_TAG} fabric-ca-client binary is not available to download (Available from 1.1.0-rc1) <----"
echo
fi
}
dockerInstall() {
which docker >& /dev/null
NODOCKER=$?
if [ "${NODOCKER}" == 0 ]; then
echo "===> Pulling fabric Images"
dockerFabricPull ${FABRIC_TAG}
echo "===> Pulling fabric ca Image"
dockerCaPull ${CA_TAG}
echo "===> Pulling thirdparty docker images"
dockerThirdPartyImagesPull ${THIRDPARTY_TAG}
echo
echo "===> List out hyperledger docker images"
docker images | grep hyperledger*
else
echo "========================================================="
echo "Docker not installed, bypassing download of Fabric images"
echo "========================================================="
fi
}
DOCKER=true
SAMPLES=true
BINARIES=true
# Parse commandline args pull out
# version and/or ca-version strings first
if echo $1 | grep -q '\d'; then
VERSION=$1;shift
if echo $1 | grep -q '\d'; then
CA_VERSION=$1;shift
if echo $1 | grep -q '\d'; then
THIRDPARTY_IMAGE_VERSION=$1;shift
fi
fi
fi
# prior to 1.1.0 architecture was determined by uname -m
if [[ $VERSION =~ ^1\.[0]\.* ]]; then
export FABRIC_TAG=${MARCH}-${VERSION}
export CA_TAG=${MARCH}-${CA_VERSION}
export THIRDPARTY_TAG=${MARCH}-${THIRDPARTY_IMAGE_VERSION}
else
# starting with 1.2.0, multi-arch images will be default
: ${CA_TAG:="$CA_VERSION"}
: ${FABRIC_TAG:="$VERSION"}
: ${THIRDPARTY_TAG:="$THIRDPARTY_IMAGE_VERSION"}
fi
BINARY_FILE=hyperledger-fabric-${ARCH}-${VERSION}.tar.gz
CA_BINARY_FILE=hyperledger-fabric-ca-${ARCH}-${CA_VERSION}.tar.gz
# then parse opts
while getopts "h?db" opt; do
case "$opt" in
h|\?)
printHelp
exit 0
;;
d) DOCKER=false
;;
b) BINARIES=false
;;
esac
done
if [ "$BINARIES" == "true" ]; then
echo
echo "Installing Hyperledger Fabric binaries"
echo
binariesInstall
fi
if [ "$DOCKER" == "true" ]; then
echo
echo "Installing Hyperledger Fabric docker images"
echo
dockerInstall
fi

View file

@ -1,42 +0,0 @@
#!/bin/bash
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
export VERSION=${1:-1.0.0}
export ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')" | awk '{print tolower($0)}')
#Set MARCH variable i.e ppc64le,s390x,x86_64,i386
MARCH=`uname -m`
dockerFabricPull() {
local FABRIC_TAG=$1
for IMAGES in peer orderer couchdb ccenv javaenv kafka zookeeper tools; do
echo "==> FABRIC IMAGE: $IMAGES"
echo
docker pull hyperledger/fabric-$IMAGES:$FABRIC_TAG
docker tag hyperledger/fabric-$IMAGES:$FABRIC_TAG hyperledger/fabric-$IMAGES
done
}
dockerCaPull() {
local CA_TAG=$1
echo "==> FABRIC CA IMAGE"
echo
docker pull hyperledger/fabric-ca:$CA_TAG
docker tag hyperledger/fabric-ca:$CA_TAG hyperledger/fabric-ca
}
: ${CA_TAG:="$MARCH-$VERSION"}
: ${FABRIC_TAG:="$MARCH-$VERSION"}
echo "===> Pulling fabric Images"
dockerFabricPull ${FABRIC_TAG}
echo "===> Pulling fabric ca Image"
dockerCaPull ${CA_TAG}
echo
echo "===> List out hyperledger docker images"
docker images | grep hyperledger*