mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-17 07:25:10 +00:00
[FAB-6050] Adding fabric-ca sample
This sample uses fabric-ca to run an end-to-end test similar to the BYFN sample. However, instead of using cryptogen, it uses fabric-ca. All private keys are generated dynamically in the container in which they are used. This sample also demonstrates how to use abac (Attribute-Based Access Control) to make access decisions. See chaincode/abac/abac.go. Change-Id: I5eddc9e35908e409ac07266c3183ce89a5a6cd82 Signed-off-by: Keith Smith <bksmith@us.ibm.com>
This commit is contained in:
parent
7cca09f047
commit
caf5c33db2
15 changed files with 1604 additions and 0 deletions
206
chaincode/abac/abac.go
Normal file
206
chaincode/abac/abac.go
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
Copyright IBM Corp. 2016 All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/hyperledger/fabric/core/chaincode/shim"
|
||||
"github.com/hyperledger/fabric/core/chaincode/lib/cid"
|
||||
pb "github.com/hyperledger/fabric/protos/peer"
|
||||
)
|
||||
|
||||
// SimpleChaincode example simple Chaincode implementation
|
||||
type SimpleChaincode struct {
|
||||
}
|
||||
|
||||
// Init initializes the chaincode
|
||||
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
|
||||
|
||||
fmt.Println("abac Init")
|
||||
|
||||
//
|
||||
// Demonstrate the use of Attribute-Based Access Control (ABAC) by checking
|
||||
// to see if the caller has the "abac.init" attribute with a value of true;
|
||||
// if not, return an error.
|
||||
//
|
||||
err := cid.AssertAttributeValue(stub, "abac.init", "true")
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
_, args := stub.GetFunctionAndParameters()
|
||||
var A, B string // Entities
|
||||
var Aval, Bval int // Asset holdings
|
||||
|
||||
if len(args) != 4 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting 4")
|
||||
}
|
||||
|
||||
// Initialize the chaincode
|
||||
A = args[0]
|
||||
Aval, err = strconv.Atoi(args[1])
|
||||
if err != nil {
|
||||
return shim.Error("Expecting integer value for asset holding")
|
||||
}
|
||||
B = args[2]
|
||||
Bval, err = strconv.Atoi(args[3])
|
||||
if err != nil {
|
||||
return shim.Error("Expecting integer value for asset holding")
|
||||
}
|
||||
fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
|
||||
|
||||
// Write the state to the ledger
|
||||
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
return shim.Success(nil)
|
||||
}
|
||||
|
||||
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
|
||||
fmt.Println("abac Invoke")
|
||||
function, args := stub.GetFunctionAndParameters()
|
||||
if function == "invoke" {
|
||||
// Make payment of X units from A to B
|
||||
return t.invoke(stub, args)
|
||||
} else if function == "delete" {
|
||||
// Deletes an entity from its state
|
||||
return t.delete(stub, args)
|
||||
} else if function == "query" {
|
||||
// the old "Query" is now implemtned in invoke
|
||||
return t.query(stub, args)
|
||||
}
|
||||
|
||||
return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"")
|
||||
}
|
||||
|
||||
// Transaction makes payment of X units from A to B
|
||||
func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
var A, B string // Entities
|
||||
var Aval, Bval int // Asset holdings
|
||||
var X int // Transaction value
|
||||
var err error
|
||||
|
||||
if len(args) != 3 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting 3")
|
||||
}
|
||||
|
||||
A = args[0]
|
||||
B = args[1]
|
||||
|
||||
// Get the state from the ledger
|
||||
// TODO: will be nice to have a GetAllState call to ledger
|
||||
Avalbytes, err := stub.GetState(A)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to get state")
|
||||
}
|
||||
if Avalbytes == nil {
|
||||
return shim.Error("Entity not found")
|
||||
}
|
||||
Aval, _ = strconv.Atoi(string(Avalbytes))
|
||||
|
||||
Bvalbytes, err := stub.GetState(B)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to get state")
|
||||
}
|
||||
if Bvalbytes == nil {
|
||||
return shim.Error("Entity not found")
|
||||
}
|
||||
Bval, _ = strconv.Atoi(string(Bvalbytes))
|
||||
|
||||
// Perform the execution
|
||||
X, err = strconv.Atoi(args[2])
|
||||
if err != nil {
|
||||
return shim.Error("Invalid transaction amount, expecting a integer value")
|
||||
}
|
||||
Aval = Aval - X
|
||||
Bval = Bval + X
|
||||
fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)
|
||||
|
||||
// Write the state back to the ledger
|
||||
err = stub.PutState(A, []byte(strconv.Itoa(Aval)))
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
err = stub.PutState(B, []byte(strconv.Itoa(Bval)))
|
||||
if err != nil {
|
||||
return shim.Error(err.Error())
|
||||
}
|
||||
|
||||
return shim.Success(nil)
|
||||
}
|
||||
|
||||
// Deletes an entity from state
|
||||
func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
if len(args) != 1 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting 1")
|
||||
}
|
||||
|
||||
A := args[0]
|
||||
|
||||
// Delete the key from the state in ledger
|
||||
err := stub.DelState(A)
|
||||
if err != nil {
|
||||
return shim.Error("Failed to delete state")
|
||||
}
|
||||
|
||||
return shim.Success(nil)
|
||||
}
|
||||
|
||||
// query callback representing the query of a chaincode
|
||||
func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response {
|
||||
var A string // Entities
|
||||
var err error
|
||||
|
||||
if len(args) != 1 {
|
||||
return shim.Error("Incorrect number of arguments. Expecting name of the person to query")
|
||||
}
|
||||
|
||||
A = args[0]
|
||||
|
||||
// Get the state from the ledger
|
||||
Avalbytes, err := stub.GetState(A)
|
||||
if err != nil {
|
||||
jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
}
|
||||
|
||||
if Avalbytes == nil {
|
||||
jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"
|
||||
return shim.Error(jsonResp)
|
||||
}
|
||||
|
||||
jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"
|
||||
fmt.Printf("Query Response:%s\n", jsonResp)
|
||||
return shim.Success(Avalbytes)
|
||||
}
|
||||
|
||||
func main() {
|
||||
err := shim.Start(new(SimpleChaincode))
|
||||
if err != nil {
|
||||
fmt.Printf("Error starting Simple chaincode: %s", err)
|
||||
}
|
||||
}
|
||||
1
fabric-ca/.env
Normal file
1
fabric-ca/.env
Normal file
|
|
@ -0,0 +1 @@
|
|||
COMPOSE_PROJECT_NAME=net
|
||||
2
fabric-ca/.gitignore
vendored
Normal file
2
fabric-ca/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
docker-compose.yml
|
||||
data
|
||||
88
fabric-ca/README.md
Executable file
88
fabric-ca/README.md
Executable file
|
|
@ -0,0 +1,88 @@
|
|||
# Hyperledger Fabric CA sample
|
||||
|
||||
The Hyperledger Fabric CA sample demonstrates the following:
|
||||
|
||||
* How to use the Hyperledger Fabric CA client and server to generate all crypto
|
||||
material rather than using cryptogen. The cryptogen tool is not intended for
|
||||
a production environment because it generates all private keys in one location
|
||||
which must then be copied to the appropriate host or container. This sample demonstrates
|
||||
how to generate crypto material for orderers, peers, administrators, and end
|
||||
users so that private keys never leave the host or container in which they are generated.
|
||||
|
||||
* How to use Attribute-Based Access Control (ABAC). See fabric-samples/chaincode/abac/abac.go and
|
||||
note the use of the *github.com/hyperledger/fabric/core/chaincode/lib/cid* package to extract
|
||||
attributes from the invoker's identity. Only identities with the *abac.init* attribute value of
|
||||
*true* can successfully call the *Init* function to instantiate the chaincode.
|
||||
|
||||
## Running this sample
|
||||
|
||||
1. The following images are required to run this sample:
|
||||
*hyperledger/fabric-ca-orderer*, *hyperledger/fabric-ca-peer*, and *hyperledger/fabric-ca-tools*.
|
||||
These images are new in the v1.1.0 release of the *github.com/hyperledger/fabric-ca*.
|
||||
In order to run this sample prior to the v1.1.0 release, you must build these
|
||||
images manually as follows:
|
||||
a) pull the master branch of the *github.com/hyperledger/fabric* and
|
||||
*github.com/hyperledger/fabric-ca* repositories;
|
||||
b) make sure these repositories are on your GOPATH;
|
||||
c) run the *build-images.sh* script provided with this sample.
|
||||
|
||||
2. To run this sample, simply run the *start.sh* script. You may do this multiple times in a row as needed
|
||||
since the *start.sh* script cleans up before starting each time.
|
||||
|
||||
3. To stop the containers which are started by the *start.sh* script, you may run the *stop.sh* script.
|
||||
|
||||
## Understanding this sample
|
||||
|
||||
There are some variables at the top of *fabric-samples/fabric-ca/scripts/env.sh* script which
|
||||
define the names and topology of this sample. You may modify these as described in the comments
|
||||
of the script in order to customize this sample. By default, there are three organizations.
|
||||
The orderer organization is *org0*, and two peer organizations are *org1* and *org2*.
|
||||
|
||||
The *start.sh* script first builds the *docker-compose.yml* file (by invoking the
|
||||
*makeDocker.sh* script) and then starts the docker containers.
|
||||
The *data* directory is a volume mount for all containers.
|
||||
This volume mount is not be needed in a real scenario, but it is used by this sample
|
||||
for the following reasons:
|
||||
a) so that all containers can write their logs to a common directory
|
||||
(i.e. *the *data/logs* directory) to make debugging easier;
|
||||
b) to synchronize the sequence in which containers start as described below
|
||||
(for example, an intermediate CA in an *ica* container must wait for the
|
||||
corresponding root CA in a *rca* container to write its certificate to
|
||||
the *data* directory);
|
||||
c) to access bootstrap certificates required by clients to connect over TLS.
|
||||
|
||||
The containers defined in the *docker-compose.yml* file are started in the
|
||||
following sequence.
|
||||
|
||||
1. The *rca* (root CA) containers start first, one for each organization.
|
||||
An *rca* container runs the fabric-ca-server for the root CA of an
|
||||
organization. The root CA certificate is written to the *data* directory
|
||||
and is used when an intermediate CA must connect to it over TLS.
|
||||
|
||||
2. The *ica* (Intermediate CA) containers start next. An *ica* container
|
||||
runs the fabric-ca-server for the intermediate CA of an organization.
|
||||
Each of these containers enrolls with a corresponding root CA.
|
||||
The intermediate CA certificate is also written to the *data* directory.
|
||||
|
||||
3. The *setup* container registers identities with the intermediate CAs,
|
||||
generates the genesis block, and other artifacts needed to setup the
|
||||
blockchain network. This is performed by the
|
||||
*fabric-samples/fabric-ca/scripts/run-fabric.sh* script. Note that the
|
||||
admin identity is registered with **abac.init=true:ecert**
|
||||
(see the *registerPeerIdentities* function of this script). This causes
|
||||
the admin's enrollment certificate (ECert) to have an attribute named "abac.init"
|
||||
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
|
||||
invokes its Init function. See the chaincode at *fabric-samples/chaincode/abac/abac.go*).
|
||||
For more information on Attribute-Based Access Control (ABAC), see
|
||||
https://github.com/hyperledger/fabric/tree/release/core/chaincode/lib/cid/README.md.
|
||||
|
||||
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.
|
||||
|
||||
5. The *run* container is started which runs the actual test case. It creates
|
||||
a channel, peers join the channel, chaincode is installed and instantiated,
|
||||
and the chaincode is queried and invoked. See the *main* function of the
|
||||
*fabric-samples/fabric-ca/scripts/run-fabric.sh* script for more details.
|
||||
|
||||
<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>
|
||||
54
fabric-ca/build-images.sh
Executable file
54
fabric-ca/build-images.sh
Executable file
|
|
@ -0,0 +1,54 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright IBM Corp. All Rights Reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
#
|
||||
# This script builds the images required to run this sample.
|
||||
#
|
||||
|
||||
function assertOnMasterBranch {
|
||||
if [ "`git rev-parse --abbrev-ref HEAD`" != "master" ]; then
|
||||
fatal "You must switch to the master branch in `pwd`"
|
||||
fi
|
||||
}
|
||||
|
||||
set -e
|
||||
|
||||
SDIR=$(dirname "$0")
|
||||
source $SDIR/scripts/env.sh
|
||||
|
||||
# Delete docker containers
|
||||
dockerContainers=$(docker ps -a | awk '$2~/hyperledger/ {print $1}')
|
||||
if [ "$dockerContainers" != "" ]; then
|
||||
log "Deleting existing docker containers ..."
|
||||
docker rm -f $dockerContainers > /dev/null
|
||||
fi
|
||||
|
||||
# Remove chaincode docker images
|
||||
chaincodeImages=`docker images | grep "^dev-peer" | awk '{print $3}'`
|
||||
if [ "$chaincodeImages" != "" ]; then
|
||||
log "Removing chaincode docker images ..."
|
||||
docker rmi $chaincodeImages > /dev/null
|
||||
fi
|
||||
|
||||
# Perform docker clean for fabric-ca
|
||||
log "Cleaning fabric-ca docker images ..."
|
||||
cd $GOPATH/src/github.com/hyperledger/fabric-ca
|
||||
assertOnMasterBranch
|
||||
make docker-clean
|
||||
|
||||
# Perform docker clean for fabric and rebuild
|
||||
log "Cleaning and rebuilding fabric docker images ..."
|
||||
cd $GOPATH/src/github.com/hyperledger/fabric
|
||||
assertOnMasterBranch
|
||||
make docker-clean docker
|
||||
|
||||
# Perform docker clean for fabric and rebuild against latest fabric images just built
|
||||
log "Rebuilding fabric-ca docker images ..."
|
||||
cd $GOPATH/src/github.com/hyperledger/fabric-ca
|
||||
FABRIC_TAG=latest make docker
|
||||
|
||||
log "Setup completed successfully. You may run the tests multiple times by running start.sh."
|
||||
261
fabric-ca/makeDocker.sh
Executable file
261
fabric-ca/makeDocker.sh
Executable file
|
|
@ -0,0 +1,261 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright IBM Corp. All Rights Reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
#
|
||||
# This script builds the docker compose file needed to run this sample.
|
||||
#
|
||||
|
||||
SDIR=$(dirname "$0")
|
||||
source $SDIR/scripts/env.sh
|
||||
|
||||
function main {
|
||||
{
|
||||
writeHeader
|
||||
writeRootFabricCA
|
||||
if $USE_INTERMEDIATE_CA; then
|
||||
writeIntermediateFabricCA
|
||||
fi
|
||||
writeSetupFabric
|
||||
writeStartFabric
|
||||
writeRunFabric
|
||||
} > $SDIR/docker-compose.yml
|
||||
log "Created docker-compose.yml"
|
||||
}
|
||||
|
||||
# Write services for the root fabric CA servers
|
||||
function writeRootFabricCA {
|
||||
for ORG in $ORGS; do
|
||||
initOrgVars $ORG
|
||||
writeRootCA
|
||||
done
|
||||
}
|
||||
|
||||
# Write services for the intermediate fabric CA servers
|
||||
function writeIntermediateFabricCA {
|
||||
for ORG in $ORGS; do
|
||||
initOrgVars $ORG
|
||||
writeIntermediateCA
|
||||
done
|
||||
}
|
||||
|
||||
# Write a service to setup the fabric artifacts (e.g. genesis block, etc)
|
||||
function writeSetupFabric {
|
||||
echo " setup:
|
||||
container_name: setup
|
||||
image: hyperledger/fabric-ca-tools
|
||||
command: /bin/bash -c '/scripts/setup-fabric.sh 2>&1 | tee /$SETUP_LOGFILE; sleep 99999'
|
||||
volumes:
|
||||
- ./scripts:/scripts
|
||||
- ./$DATA:/$DATA
|
||||
networks:
|
||||
- $NETWORK
|
||||
depends_on:"
|
||||
for ORG in $ORGS; do
|
||||
initOrgVars $ORG
|
||||
echo " - $CA_NAME"
|
||||
done
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Write services for fabric orderer and peer containers
|
||||
function writeStartFabric {
|
||||
for ORG in $ORDERER_ORGS; do
|
||||
COUNT=1
|
||||
while [[ "$COUNT" -le $NUM_ORDERERS ]]; do
|
||||
initOrdererVars $ORG $COUNT
|
||||
writeOrderer
|
||||
COUNT=$((COUNT+1))
|
||||
done
|
||||
done
|
||||
for ORG in $PEER_ORGS; do
|
||||
COUNT=1
|
||||
while [[ "$COUNT" -le $NUM_PEERS ]]; do
|
||||
initPeerVars $ORG $COUNT
|
||||
writePeer
|
||||
COUNT=$((COUNT+1))
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
# Write a service to run a fabric test including creating a channel,
|
||||
# installing chaincode, invoking and querying
|
||||
function writeRunFabric {
|
||||
# Set samples directory relative to this script
|
||||
SAMPLES_DIR=$(dirname $(cd ${SDIR} && pwd))
|
||||
# Set fabric directory relative to GOPATH
|
||||
FABRIC_DIR=${GOPATH}/src/github.com/hyperledger/fabric
|
||||
echo " run:
|
||||
container_name: run
|
||||
image: hyperledger/fabric-ca-tools
|
||||
environment:
|
||||
- GOPATH=/opt/gopath
|
||||
command: /bin/bash -c 'sleep 3;/scripts/run-fabric.sh 2>&1 | tee /$RUN_LOGFILE; sleep 99999'
|
||||
volumes:
|
||||
- ./scripts:/scripts
|
||||
- ./$DATA:/$DATA
|
||||
- ${SAMPLES_DIR}:/opt/gopath/src/github.com/hyperledger/fabric-samples
|
||||
- ${FABRIC_DIR}:/opt/gopath/src/github.com/hyperledger/fabric
|
||||
networks:
|
||||
- $NETWORK
|
||||
depends_on:"
|
||||
for ORG in $ORDERER_ORGS; do
|
||||
COUNT=1
|
||||
while [[ "$COUNT" -le $NUM_ORDERERS ]]; do
|
||||
initOrdererVars $ORG $COUNT
|
||||
echo " - $ORDERER_NAME"
|
||||
COUNT=$((COUNT+1))
|
||||
done
|
||||
done
|
||||
for ORG in $PEER_ORGS; do
|
||||
COUNT=1
|
||||
while [[ "$COUNT" -le $NUM_PEERS ]]; do
|
||||
initPeerVars $ORG $COUNT
|
||||
echo " - $PEER_NAME"
|
||||
COUNT=$((COUNT+1))
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
function writeRootCA {
|
||||
echo " $ROOT_CA_NAME:
|
||||
container_name: $ROOT_CA_NAME
|
||||
image: hyperledger/fabric-ca
|
||||
command: /bin/bash -c '/scripts/start-root-ca.sh 2>&1 | tee /$ROOT_CA_LOGFILE'
|
||||
environment:
|
||||
- FABRIC_CA_SERVER_HOME=/etc/hyperledger/fabric-ca
|
||||
- FABRIC_CA_SERVER_TLS_ENABLED=true
|
||||
- FABRIC_CA_SERVER_CSR_CN=$ROOT_CA_NAME
|
||||
- FABRIC_CA_SERVER_CSR_HOSTS=$ROOT_CA_HOST
|
||||
- FABRIC_CA_SERVER_DEBUG=true
|
||||
- BOOTSTRAP_USER_PASS=$ROOT_CA_ADMIN_USER_PASS
|
||||
- TARGET_CERTFILE=$ROOT_CA_CERTFILE
|
||||
volumes:
|
||||
- ./scripts:/scripts
|
||||
- ./$DATA:/$DATA
|
||||
networks:
|
||||
- $NETWORK
|
||||
"
|
||||
}
|
||||
|
||||
function writeIntermediateCA {
|
||||
echo " $INT_CA_NAME:
|
||||
container_name: $INT_CA_NAME
|
||||
image: hyperledger/fabric-ca
|
||||
command: /bin/bash -c '/scripts/start-intermediate-ca.sh $ORG 2>&1 | tee /$INT_CA_LOGFILE'
|
||||
environment:
|
||||
- FABRIC_CA_SERVER_HOME=/etc/hyperledger/fabric-ca
|
||||
- FABRIC_CA_SERVER_CA_NAME=$INT_CA_NAME
|
||||
- FABRIC_CA_SERVER_INTERMEDIATE_TLS_CERTFILES=$ROOT_CA_CERTFILE
|
||||
- FABRIC_CA_SERVER_CSR_HOSTS=$INT_CA_HOST
|
||||
- FABRIC_CA_SERVER_TLS_ENABLED=true
|
||||
- FABRIC_CA_SERVER_DEBUG=true
|
||||
- BOOTSTRAP_USER_PASS=$INT_CA_ADMIN_USER_PASS
|
||||
- PARENT_URL=https://$ROOT_CA_ADMIN_USER_PASS@$ROOT_CA_HOST:7054
|
||||
- TARGET_CHAINFILE=$INT_CA_CHAINFILE
|
||||
- ORG=$ORG
|
||||
volumes:
|
||||
- ./scripts:/scripts
|
||||
- ./$DATA:/$DATA
|
||||
networks:
|
||||
- $NETWORK
|
||||
depends_on:
|
||||
- $ROOT_CA_NAME
|
||||
"
|
||||
}
|
||||
|
||||
function writeOrderer {
|
||||
MYHOME=/etc/hyperledger/orderer
|
||||
echo " $ORDERER_NAME:
|
||||
container_name: $ORDERER_NAME
|
||||
image: hyperledger/fabric-ca-orderer
|
||||
environment:
|
||||
- FABRIC_CA_CLIENT_HOME=$MYHOME
|
||||
- FABRIC_CA_CLIENT_TLS_CERTFILES=$CA_CHAINFILE
|
||||
- ENROLLMENT_URL=https://$ORDERER_NAME_PASS@$CA_HOST:7054
|
||||
- ORDERER_HOME=$MYHOME
|
||||
- ORDERER_HOST=$ORDERER_HOST
|
||||
- ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
|
||||
- ORDERER_GENERAL_GENESISMETHOD=file
|
||||
- ORDERER_GENERAL_GENESISFILE=$GENESIS_BLOCK_FILE
|
||||
- ORDERER_GENERAL_LOCALMSPID=$ORG_MSP_ID
|
||||
- ORDERER_GENERAL_LOCALMSPDIR=$MYHOME/msp
|
||||
- ORDERER_GENERAL_TLS_ENABLED=true
|
||||
- ORDERER_GENERAL_TLS_PRIVATEKEY=$MYHOME/tls/server.key
|
||||
- ORDERER_GENERAL_TLS_CERTIFICATE=$MYHOME/tls/server.crt
|
||||
- ORDERER_GENERAL_TLS_ROOTCAS=[$CA_CHAINFILE]
|
||||
- ORDERER_GENERAL_LOGLEVEL=debug
|
||||
- ORDERER_DEBUG_BROADCASTTRACEDIR=$LOGDIR
|
||||
- ORG=$ORG
|
||||
- ORG_ADMIN_CERT=$ORG_ADMIN_CERT
|
||||
command: /bin/bash -c '/scripts/start-orderer.sh 2>&1 | tee /$ORDERER_LOGFILE'
|
||||
volumes:
|
||||
- ./scripts:/scripts
|
||||
- ./$DATA:/$DATA
|
||||
networks:
|
||||
- $NETWORK
|
||||
depends_on:
|
||||
- setup
|
||||
"
|
||||
}
|
||||
|
||||
function writePeer {
|
||||
MYHOME=/opt/gopath/src/github.com/hyperledger/fabric/peer
|
||||
echo " $PEER_NAME:
|
||||
container_name: $PEER_NAME
|
||||
image: hyperledger/fabric-ca-peer
|
||||
environment:
|
||||
- FABRIC_CA_CLIENT_HOME=$MYHOME
|
||||
- FABRIC_CA_CLIENT_TLS_CERTFILES=$CA_CHAINFILE
|
||||
- ENROLLMENT_URL=https://$PEER_NAME_PASS@$CA_HOST:7054
|
||||
- PEER_HOME=$MYHOME
|
||||
- PEER_HOST=$PEER_HOST
|
||||
- PEER_NAME_PASS=$PEER_NAME_PASS
|
||||
- CORE_PEER_ID=$PEER_HOST
|
||||
- CORE_PEER_ADDRESS=$PEER_HOST:7051
|
||||
- CORE_PEER_LOCALMSPID=$ORG_MSP_ID
|
||||
- CORE_PEER_MSPCONFIGPATH=$MYHOME/msp
|
||||
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
|
||||
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=net_${NETWORK}
|
||||
- CORE_LOGGING_LEVEL=DEBUG
|
||||
- CORE_PEER_TLS_ENABLED=true
|
||||
- CORE_PEER_PROFILE_ENABLED=true
|
||||
- CORE_PEER_TLS_CERT_FILE=$MYHOME/tls/server.crt
|
||||
- CORE_PEER_TLS_KEY_FILE=$MYHOME/tls/server.key
|
||||
- CORE_PEER_TLS_ROOTCERT_FILE=$CA_CHAINFILE
|
||||
- CORE_PEER_GOSSIP_USELEADERELECTION=true
|
||||
- CORE_PEER_GOSSIP_ORGLEADER=false
|
||||
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=$PEER_HOST:7051
|
||||
- CORE_PEER_GOSSIP_SKIPHANDSHAKE=true
|
||||
- ORG=$ORG
|
||||
- ORG_ADMIN_CERT=$ORG_ADMIN_CERT"
|
||||
if [ $NUM -gt 1 ]; then
|
||||
echo " - CORE_PEER_GOSSIP_BOOTSTRAP=peer1-${ORG}:7051"
|
||||
fi
|
||||
echo " working_dir: $MYHOME
|
||||
command: /bin/bash -c '/scripts/start-peer.sh 2>&1 | tee /$PEER_LOGFILE'
|
||||
volumes:
|
||||
- ./scripts:/scripts
|
||||
- ./$DATA:/$DATA
|
||||
- /var/run:/host/var/run
|
||||
networks:
|
||||
- $NETWORK
|
||||
depends_on:
|
||||
- setup
|
||||
"
|
||||
}
|
||||
|
||||
function writeHeader {
|
||||
echo "version: '2'
|
||||
|
||||
networks:
|
||||
$NETWORK:
|
||||
|
||||
services:
|
||||
"
|
||||
}
|
||||
|
||||
main
|
||||
322
fabric-ca/scripts/env.sh
Executable file
322
fabric-ca/scripts/env.sh
Executable file
|
|
@ -0,0 +1,322 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright IBM Corp. All Rights Reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
#
|
||||
# The following variables describe the topology and may be modified to provide
|
||||
# different organization names or the number of peers in each peer organization.
|
||||
#
|
||||
|
||||
# Name of the docker-compose network
|
||||
NETWORK=fabric-ca
|
||||
|
||||
# Names of the orderer organizations
|
||||
ORDERER_ORGS="org0"
|
||||
|
||||
# Names of the peer organizations
|
||||
PEER_ORGS="org1 org2"
|
||||
|
||||
# Number of peers in each peer organization
|
||||
NUM_PEERS=2
|
||||
|
||||
#
|
||||
# The remainder of this file contains variables which typically would not be changed.
|
||||
#
|
||||
|
||||
# All org names
|
||||
ORGS="$ORDERER_ORGS $PEER_ORGS"
|
||||
|
||||
# Set to true to populate the "admincerts" folder of MSPs
|
||||
ADMINCERTS=true
|
||||
|
||||
# Number of orderer nodes
|
||||
NUM_ORDERERS=1
|
||||
|
||||
# The volume mount to share data between containers
|
||||
DATA=data
|
||||
|
||||
# The path to the genesis block
|
||||
GENESIS_BLOCK_FILE=/$DATA/genesis.block
|
||||
|
||||
# The path to a channel transaction
|
||||
CHANNEL_TX_FILE=/$DATA/channel.tx
|
||||
|
||||
# Name of test channel
|
||||
CHANNEL_NAME=mychannel
|
||||
|
||||
# Query timeout in seconds
|
||||
QUERY_TIMEOUT=15
|
||||
|
||||
# Log directory
|
||||
LOGDIR=$DATA/logs
|
||||
LOGPATH=/$LOGDIR
|
||||
|
||||
# Name of a the file to create when setup is successful
|
||||
SETUP_SUCCESS_FILE=${LOGDIR}/setup.successful
|
||||
# The setup container's log file
|
||||
SETUP_LOGFILE=${LOGDIR}/setup.log
|
||||
|
||||
# The run container's log file
|
||||
RUN_LOGFILE=${LOGDIR}/run.log
|
||||
# The run container's summary log file
|
||||
RUN_SUMFILE=${LOGDIR}/run.sum
|
||||
RUN_SUMPATH=/${RUN_SUMFILE}
|
||||
# Run success and failure files
|
||||
RUN_SUCCESS_FILE=${LOGDIR}/run.success
|
||||
RUN_FAIL_FILE=${LOGDIR}/run.fail
|
||||
|
||||
# Affiliation is not used to limit users in this sample, so just put
|
||||
# all identities in the same affiliation.
|
||||
export FABRIC_CA_CLIENT_ID_AFFILIATION=org1
|
||||
|
||||
# Set to true to enable use of intermediate CAs
|
||||
USE_INTERMEDIATE_CA=true
|
||||
|
||||
# initOrgVars <ORG>
|
||||
function initOrgVars {
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "Usage: initOrgVars <ORG>"
|
||||
exit 1
|
||||
fi
|
||||
ORG=$1
|
||||
ORG_CONTAINER_NAME=${ORG//./-}
|
||||
ROOT_CA_HOST=rca-${ORG}
|
||||
ROOT_CA_NAME=rca-${ORG}
|
||||
ROOT_CA_LOGFILE=$LOGDIR/${ROOT_CA_NAME}.log
|
||||
INT_CA_HOST=ica-${ORG}
|
||||
INT_CA_NAME=ica-${ORG}
|
||||
INT_CA_LOGFILE=$LOGDIR/${INT_CA_NAME}.log
|
||||
|
||||
# Root CA admin identity
|
||||
ROOT_CA_ADMIN_USER=rca-${ORG}-admin
|
||||
ROOT_CA_ADMIN_PASS=${ROOT_CA_ADMIN_USER}pw
|
||||
ROOT_CA_ADMIN_USER_PASS=${ROOT_CA_ADMIN_USER}:${ROOT_CA_ADMIN_PASS}
|
||||
# Root CA intermediate identity to bootstrap the intermediate CA
|
||||
ROOT_CA_INT_USER=ica-${ORG}
|
||||
ROOT_CA_INT_PASS=${ROOT_CA_INT_USER}pw
|
||||
ROOT_CA_INT_USER_PASS=${ROOT_CA_INT_USER}:${ROOT_CA_INT_PASS}
|
||||
# Intermediate CA admin identity
|
||||
INT_CA_ADMIN_USER=ica-${ORG}-admin
|
||||
INT_CA_ADMIN_PASS=${INT_CA_ADMIN_USER}pw
|
||||
INT_CA_ADMIN_USER_PASS=${INT_CA_ADMIN_USER}:${INT_CA_ADMIN_PASS}
|
||||
# Admin identity for the org
|
||||
ADMIN_NAME=admin-${ORG}
|
||||
ADMIN_PASS=${ADMIN_NAME}pw
|
||||
# Typical user identity for the org
|
||||
USER_NAME=user-${ORG}
|
||||
USER_PASS=${USER_NAME}pw
|
||||
|
||||
ROOT_CA_CERTFILE=/${DATA}/${ORG}-ca-cert.pem
|
||||
INT_CA_CHAINFILE=/${DATA}/${ORG}-ca-chain.pem
|
||||
ANCHOR_TX_FILE=/${DATA}/orgs/${ORG}/anchors.tx
|
||||
ORG_MSP_ID=${ORG}MSP
|
||||
ORG_MSP_DIR=/${DATA}/orgs/${ORG}/msp
|
||||
ORG_ADMIN_CERT=${ORG_MSP_DIR}/admincerts/cert.pem
|
||||
ORG_ADMIN_HOME=/${DATA}/orgs/$ORG/admin
|
||||
|
||||
if $USE_INTERMEDIATE_CA; then
|
||||
CA_NAME=$INT_CA_NAME
|
||||
CA_HOST=$INT_CA_HOST
|
||||
CA_CHAINFILE=$INT_CA_CHAINFILE
|
||||
CA_ADMIN_USER_PASS=$INT_CA_ADMIN_USER_PASS
|
||||
CA_LOGFILE=$INT_CA_LOGFILE
|
||||
else
|
||||
CA_NAME=$ROOT_CA_NAME
|
||||
CA_HOST=$ROOT_CA_HOST
|
||||
CA_CHAINFILE=$ROOT_CA_CERTFILE
|
||||
CA_ADMIN_USER_PASS=$ROOT_CA_ADMIN_USER_PASS
|
||||
CA_LOGFILE=$ROOT_CA_LOGFILE
|
||||
fi
|
||||
}
|
||||
|
||||
# initOrdererVars <NUM>
|
||||
function initOrdererVars {
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "Usage: initOrdererVars <ORG> <NUM>"
|
||||
exit 1
|
||||
fi
|
||||
initOrgVars $1
|
||||
NUM=$2
|
||||
ORDERER_HOST=orderer${NUM}-${ORG}
|
||||
ORDERER_NAME=orderer${NUM}-${ORG}
|
||||
ORDERER_PASS=${ORDERER_NAME}pw
|
||||
ORDERER_NAME_PASS=${ORDERER_NAME}:${ORDERER_PASS}
|
||||
ORDERER_LOGFILE=$LOGDIR/${ORDERER_NAME}.log
|
||||
MYHOME=/etc/hyperledger/orderer
|
||||
|
||||
export FABRIC_CA_CLIENT=$MYHOME
|
||||
export ORDERER_GENERAL_LOGLEVEL=debug
|
||||
export ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
|
||||
export ORDERER_GENERAL_GENESISMETHOD=file
|
||||
export ORDERER_GENERAL_GENESISFILE=$GENESIS_BLOCK_FILE
|
||||
export ORDERER_GENERAL_LOCALMSPID=$ORG_MSP_ID
|
||||
export ORDERER_GENERAL_LOCALMSPDIR=$MYHOME/msp
|
||||
# enabled TLS
|
||||
export ORDERER_GENERAL_TLS_ENABLED=true
|
||||
TLSDIR=$MYHOME/tls
|
||||
export ORDERER_GENERAL_TLS_PRIVATEKEY=$TLSDIR/server.key
|
||||
export ORDERER_GENERAL_TLS_CERTIFICATE=$TLSDIR/server.crt
|
||||
export ORDERER_GENERAL_TLS_ROOTCAS=[$INT_CA_CHAINFILE]
|
||||
}
|
||||
|
||||
# initPeerVars <ORG> <NUM>
|
||||
function initPeerVars {
|
||||
if [ $# -ne 2 ]; then
|
||||
echo "Usage: initPeerVars <ORG> <NUM>: $*"
|
||||
exit 1
|
||||
fi
|
||||
initOrgVars $1
|
||||
NUM=$2
|
||||
PEER_HOST=peer${NUM}-${ORG}
|
||||
PEER_NAME=peer${NUM}-${ORG}
|
||||
PEER_PASS=${PEER_NAME}pw
|
||||
PEER_NAME_PASS=${PEER_NAME}:${PEER_PASS}
|
||||
PEER_LOGFILE=$LOGDIR/${PEER_NAME}.log
|
||||
MYHOME=/opt/gopath/src/github.com/hyperledger/fabric/peer
|
||||
TLSDIR=$MYHOME/tls
|
||||
|
||||
export FABRIC_CA_CLIENT=$MYHOME
|
||||
export CORE_PEER_ID=$PEER_HOST
|
||||
export CORE_PEER_ADDRESS=$PEER_HOST:7051
|
||||
export CORE_PEER_LOCALMSPID=$ORG_MSP_ID
|
||||
export CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
|
||||
# the following setting starts chaincode containers on the same
|
||||
# bridge network as the peers
|
||||
# https://docs.docker.com/compose/networking/
|
||||
#export CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_${NETWORK}
|
||||
export CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=net_${NETWORK}
|
||||
# export CORE_LOGGING_LEVEL=ERROR
|
||||
export CORE_LOGGING_LEVEL=DEBUG
|
||||
export CORE_PEER_TLS_ENABLED=true
|
||||
export CORE_PEER_PROFILE_ENABLED=true
|
||||
export CORE_PEER_TLS_CERT_FILE=$TLSDIR/server.crt
|
||||
export CORE_PEER_TLS_KEY_FILE=$TLSDIR/server.key
|
||||
export CORE_PEER_TLS_ROOTCERT_FILE=$INT_CA_CHAINFILE
|
||||
# gossip variables
|
||||
export CORE_PEER_GOSSIP_USELEADERELECTION=true
|
||||
export CORE_PEER_GOSSIP_ORGLEADER=false
|
||||
export CORE_PEER_GOSSIP_EXTERNALENDPOINT=$PEER_HOST:7051
|
||||
if [ $NUM -gt 1 ]; then
|
||||
# Point the non-anchor peers to the anchor peer, which is always the 1st peer
|
||||
export CORE_PEER_GOSSIP_BOOTSTRAP=peer1-${ORG}:7051
|
||||
fi
|
||||
}
|
||||
|
||||
# Switch to the current org's admin identity. Enroll if not previously enrolled.
|
||||
function switchToAdminIdentity {
|
||||
if [ ! -d $ORG_ADMIN_HOME ]; then
|
||||
dowait "$CA_NAME to start" 10 $CA_LOGFILE $CA_CHAINFILE
|
||||
log "Enrolling admin '$ADMIN_NAME' with $CA_HOST ..."
|
||||
export FABRIC_CA_CLIENT_HOME=$ORG_ADMIN_HOME
|
||||
export FABRIC_CA_CLIENT_TLS_CERTFILES=$CA_CHAINFILE
|
||||
fabric-ca-client enroll -d -u https://$ADMIN_NAME:$ADMIN_PASS@$CA_HOST:7054
|
||||
# If admincerts are required in the MSP, copy the cert there now and to my local MSP also
|
||||
if [ $ADMINCERTS ]; then
|
||||
mkdir -p $(dirname "${ORG_ADMIN_CERT}")
|
||||
cp $ORG_ADMIN_HOME/msp/signcerts/* $ORG_ADMIN_CERT
|
||||
mkdir $ORG_ADMIN_HOME/msp/admincerts
|
||||
cp $ORG_ADMIN_HOME/msp/signcerts/* $ORG_ADMIN_HOME/msp/admincerts
|
||||
fi
|
||||
fi
|
||||
export CORE_PEER_MSPCONFIGPATH=$ORG_ADMIN_HOME/msp
|
||||
}
|
||||
|
||||
# Switch to the current org's user identity. Enroll if not previously enrolled.
|
||||
function switchToUserIdentity {
|
||||
export FABRIC_CA_CLIENT_HOME=/etc/hyperledger/fabric/orgs/$ORG/user
|
||||
export CORE_PEER_MSPCONFIGPATH=$FABRIC_CA_CLIENT_HOME/msp
|
||||
if [ ! -d $FABRIC_CA_CLIENT_HOME ]; then
|
||||
dowait "$CA_NAME to start" 10 $CA_LOGFILE $CA_CHAINFILE
|
||||
log "Enrolling user for organization $ORG with home directory $FABRIC_CA_CLIENT_HOME ..."
|
||||
export FABRIC_CA_CLIENT_TLS_CERTFILES=$CA_CHAINFILE
|
||||
fabric-ca-client enroll -d -u https://$USER_NAME:$USER_PASS@$CA_HOST:7054
|
||||
# Set up admincerts directory if required
|
||||
if [ $ADMINCERTS ]; then
|
||||
ACDIR=$CORE_PEER_MSPCONFIGPATH/admincerts
|
||||
mkdir -p $ACDIR
|
||||
cp $ORG_ADMIN_HOME/msp/signcerts/* $ACDIR
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Copy the org's admin cert into some target MSP directory
|
||||
# This is only required if ADMINCERTS is enabled.
|
||||
function copyAdminCert {
|
||||
if [ $# -ne 1 ]; then
|
||||
fatal "Usage: copyAdminCert <targetMSPDIR>"
|
||||
fi
|
||||
if $ADMINCERTS; then
|
||||
dstDir=$1/admincerts
|
||||
mkdir -p $dstDir
|
||||
dowait "$ORG administator to enroll" 10 $SETUP_LOGFILE $ORG_ADMIN_CERT
|
||||
cp $ORG_ADMIN_CERT $dstDir
|
||||
fi
|
||||
}
|
||||
|
||||
# Create the TLS directories of the MSP folder if they don't exist.
|
||||
# The fabric-ca-client should do this.
|
||||
function finishMSPSetup {
|
||||
if [ $# -ne 1 ]; then
|
||||
fatal "Usage: finishMSPSetup <targetMSPDIR>"
|
||||
fi
|
||||
if [ ! -d $1/tlscacerts ]; then
|
||||
mkdir $1/tlscacerts
|
||||
cp $1/cacerts/* $1/tlscacerts
|
||||
if [ -d $1/intermediatecerts ]; then
|
||||
mkdir $1/tlsintermediatecerts
|
||||
cp $1/intermediatecerts/* $1/tlsintermediatecerts
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
function awaitSetup {
|
||||
dowait "the 'setup' container to finish registering identities, creating the genesis block and other artifacts" $1 $SETUP_LOGFILE /$SETUP_SUCCESS_FILE
|
||||
}
|
||||
|
||||
# Wait for one or more files to exist
|
||||
# Usage: dowait <what> <timeoutInSecs> <errorLogFile> <file> [<file> ...]
|
||||
function dowait {
|
||||
if [ $# -lt 4 ]; then
|
||||
fatal "Usage: dowait: $*"
|
||||
fi
|
||||
local what=$1
|
||||
local secs=$2
|
||||
local logFile=$3
|
||||
shift 3
|
||||
local logit=true
|
||||
local starttime=$(date +%s)
|
||||
for file in $*; do
|
||||
until [ -f $file ]; do
|
||||
if [ "$logit" = true ]; then
|
||||
log -n "Waiting for $what ..."
|
||||
logit=false
|
||||
fi
|
||||
sleep 1
|
||||
if [ "$(($(date +%s)-starttime))" -gt "$secs" ]; then
|
||||
echo ""
|
||||
fatal "Failed waiting for $what ($file not found); see $logFile"
|
||||
fi
|
||||
echo -n "."
|
||||
done
|
||||
done
|
||||
echo ""
|
||||
}
|
||||
|
||||
# log a message
|
||||
function log {
|
||||
if [ "$1" = "-n" ]; then
|
||||
shift
|
||||
echo -n "##### `date '+%Y-%m-%d %H:%M:%S'` $*"
|
||||
else
|
||||
echo "##### `date '+%Y-%m-%d %H:%M:%S'` $*"
|
||||
fi
|
||||
}
|
||||
|
||||
# fatal a message
|
||||
function fatal {
|
||||
log "FATAL: $*"
|
||||
exit 1
|
||||
}
|
||||
191
fabric-ca/scripts/run-fabric.sh
Executable file
191
fabric-ca/scripts/run-fabric.sh
Executable file
|
|
@ -0,0 +1,191 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright IBM Corp. All Rights Reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
source $(dirname "$0")/env.sh
|
||||
|
||||
function main {
|
||||
|
||||
done=false
|
||||
|
||||
# Wait for setup to complete and then wait another 5 seconds for the orderer and peers to start
|
||||
awaitSetup 10
|
||||
sleep 5
|
||||
|
||||
trap finish EXIT
|
||||
|
||||
mkdir -p $LOGPATH
|
||||
logr "The docker 'run' container has started"
|
||||
|
||||
# Set ORDERER_PORT_ARGS to the args needed to communicate with the 1st orderer
|
||||
IFS=', ' read -r -a OORGS <<< "$ORDERER_ORGS"
|
||||
initOrdererVars ${OORGS[0]} 1
|
||||
ORDERER_PORT_ARGS="-o $ORDERER_HOST:7050 --tls true --cafile $CA_CHAINFILE"
|
||||
|
||||
# Convert PEER_ORGS to an array named PORGS
|
||||
IFS=', ' read -r -a PORGS <<< "$PEER_ORGS"
|
||||
|
||||
# Create the channel
|
||||
createChannel
|
||||
|
||||
# All peers join the channel
|
||||
for ORG in $PEER_ORGS; do
|
||||
local COUNT=1
|
||||
while [[ "$COUNT" -le $NUM_PEERS ]]; do
|
||||
initPeerVars $ORG $COUNT
|
||||
joinChannel
|
||||
COUNT=$((COUNT+1))
|
||||
done
|
||||
done
|
||||
|
||||
# Update the anchor peers
|
||||
for ORG in $PEER_ORGS; do
|
||||
initPeerVars $ORG 1
|
||||
switchToAdminIdentity
|
||||
logr "Updating anchor peers for $PEER_HOST ..."
|
||||
peer channel update -c $CHANNEL_NAME -f $ANCHOR_TX_FILE $ORDERER_PORT_ARGS
|
||||
done
|
||||
|
||||
# Install chaincode on the 1st peer in each org
|
||||
for ORG in $PEER_ORGS; do
|
||||
initPeerVars $ORG 1
|
||||
installChaincode
|
||||
done
|
||||
|
||||
# Instantiate chaincode on the 1st peer of the 2nd org
|
||||
makePolicy
|
||||
initPeerVars ${PORGS[1]} 1
|
||||
switchToAdminIdentity
|
||||
logr "Instantiating chaincode on $PEER_HOST ..."
|
||||
peer chaincode instantiate -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "$POLICY" $ORDERER_PORT_ARGS
|
||||
|
||||
# Query chaincode from the 1st peer of the 1st org
|
||||
initPeerVars ${PORGS[0]} 1
|
||||
switchToUserIdentity
|
||||
chaincodeQuery 100
|
||||
|
||||
# Invoke chaincode on the 1st peer of the 1st org
|
||||
initPeerVars ${PORGS[0]} 1
|
||||
switchToUserIdentity
|
||||
logr "Sending invoke transaction to $PEER_HOST ..."
|
||||
peer chaincode invoke -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}' $ORDERER_PORT_ARGS
|
||||
|
||||
## Install chaincode on 2nd peer of 2nd org
|
||||
initPeerVars ${PORGS[1]} 2
|
||||
installChaincode
|
||||
|
||||
# Query chaincode on 2nd peer of 2nd org
|
||||
sleep 10
|
||||
initPeerVars ${PORGS[1]} 2
|
||||
switchToUserIdentity
|
||||
chaincodeQuery 90
|
||||
|
||||
logr "Congratulations! The tests ran successfully."
|
||||
|
||||
done=true
|
||||
|
||||
}
|
||||
|
||||
# Enroll as a peer admin and create the channel
|
||||
function createChannel {
|
||||
initPeerVars ${PORGS[0]} 1
|
||||
switchToAdminIdentity
|
||||
logr "Creating channel '$CHANNEL_NAME' on $ORDERER_HOST ..."
|
||||
peer channel create --logging-level=DEBUG -c $CHANNEL_NAME -f $CHANNEL_TX_FILE $ORDERER_PORT_ARGS
|
||||
}
|
||||
|
||||
# Enroll as a fabric admin and join the channel
|
||||
function joinChannel {
|
||||
switchToAdminIdentity
|
||||
set +e
|
||||
local COUNT=1
|
||||
MAX_RETRY=10
|
||||
while true; do
|
||||
logr "Peer $PEER_HOST is attempting to join channel '$CHANNEL_NAME' (attempt #${COUNT}) ..."
|
||||
peer channel join -b $CHANNEL_NAME.block
|
||||
if [ $? -eq 0 ]; then
|
||||
set -e
|
||||
logr "Peer $PEER_HOST successfully joined channel '$CHANNEL_NAME'"
|
||||
return
|
||||
fi
|
||||
if [ $COUNT -gt $MAX_RETRY ]; then
|
||||
fatalr "Peer $PEER_HOST failed to join channel '$CHANNEL_NAME' in $MAX_RETRY retries"
|
||||
fi
|
||||
COUNT=$((COUNT+1))
|
||||
sleep 1
|
||||
done
|
||||
}
|
||||
|
||||
chaincodeQuery () {
|
||||
if [ $# -ne 1 ]; then
|
||||
fatalr "Usage: chaincodeQuery <expected-value>"
|
||||
fi
|
||||
set +e
|
||||
logr "Querying chaincode in channel '$CHANNEL_NAME' on peer '$PEER_HOST' ..."
|
||||
local rc=1
|
||||
local starttime=$(date +%s)
|
||||
# Continue to poll until we get a successful response or reach QUERY_TIMEOUT
|
||||
while test "$(($(date +%s)-starttime))" -lt "$QUERY_TIMEOUT"; do
|
||||
sleep 1
|
||||
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' >& log.txt
|
||||
VALUE=$(cat log.txt | awk '/Query Result/ {print $NF}')
|
||||
if [ $? -eq 0 -a "$VALUE" = "$1" ]; then
|
||||
logr "Query of channel '$CHANNEL_NAME' on peer '$PEER_HOST' was successful"
|
||||
set -e
|
||||
return 0
|
||||
fi
|
||||
echo -n "."
|
||||
done
|
||||
cat log.txt
|
||||
cat log.txt >> $RUN_SUMFILE
|
||||
fatalr "Failed to query channel '$CHANNEL_NAME' on peer '$PEER_HOST'; expected value was $1 and found $VALUE"
|
||||
}
|
||||
|
||||
|
||||
function makePolicy {
|
||||
POLICY="OR("
|
||||
local COUNT=0
|
||||
for ORG in $PEER_ORGS; do
|
||||
if [ $COUNT -ne 0 ]; then
|
||||
POLICY="${POLICY},"
|
||||
fi
|
||||
initOrgVars $ORG
|
||||
POLICY="${POLICY}'${ORG_MSP_ID}.member'"
|
||||
COUNT=$((COUNT+1))
|
||||
done
|
||||
POLICY="${POLICY})"
|
||||
log "policy: $POLICY"
|
||||
}
|
||||
|
||||
function installChaincode {
|
||||
switchToAdminIdentity
|
||||
logr "Installing chaincode on $PEER_HOST ..."
|
||||
peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric-samples/chaincode/abac
|
||||
}
|
||||
|
||||
function finish {
|
||||
if [ "$done" = true ]; then
|
||||
logr "See $RUN_LOGFILE for more details"
|
||||
touch /$RUN_SUCCESS_FILE
|
||||
else
|
||||
logr "Tests did not complete successfully; see $RUN_LOGFILE for more details"
|
||||
touch /$RUN_FAIL_FILE
|
||||
fi
|
||||
}
|
||||
|
||||
function logr {
|
||||
log $*
|
||||
log $* >> $RUN_SUMPATH
|
||||
}
|
||||
|
||||
function fatalr {
|
||||
logr "FATAL: $*"
|
||||
exit 1
|
||||
}
|
||||
|
||||
main
|
||||
288
fabric-ca/scripts/setup-fabric.sh
Executable file
288
fabric-ca/scripts/setup-fabric.sh
Executable file
|
|
@ -0,0 +1,288 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright IBM Corp. All Rights Reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
#
|
||||
# This script does the following:
|
||||
# 1) registers orderer and peer identities with intermediate fabric-ca-servers
|
||||
# 2) Builds the channel artifacts (e.g. genesis block, etc)
|
||||
#
|
||||
|
||||
function main {
|
||||
sleep 1
|
||||
log "Beginning building channel artifacts ..."
|
||||
registerIdentities
|
||||
getCACerts
|
||||
makeConfigTxYaml
|
||||
generateChannelArtifacts
|
||||
log "Finished building channel artifacts"
|
||||
touch /$SETUP_SUCCESS_FILE
|
||||
}
|
||||
|
||||
# Enroll as the CA admin
|
||||
function enrollCAAdmin {
|
||||
dowait "$CA_NAME to start" 10 $CA_LOGFILE $CA_CHAINFILE
|
||||
log "Enrolling with $CA_NAME as bootstrap identity ..."
|
||||
export FABRIC_CA_CLIENT_HOME=$HOME/cas/$CA_NAME
|
||||
export FABRIC_CA_CLIENT_TLS_CERTFILES=$CA_CHAINFILE
|
||||
fabric-ca-client enroll -d -u https://$CA_ADMIN_USER_PASS@$CA_HOST:7054
|
||||
}
|
||||
|
||||
function registerIdentities {
|
||||
log "Registering identities ..."
|
||||
registerOrdererIdentities
|
||||
registerPeerIdentities
|
||||
}
|
||||
|
||||
# Register any identities associated with the orderer
|
||||
function registerOrdererIdentities {
|
||||
for ORG in $ORDERER_ORGS; do
|
||||
initOrgVars $ORG
|
||||
enrollCAAdmin
|
||||
local COUNT=1
|
||||
while [[ "$COUNT" -le $NUM_ORDERERS ]]; do
|
||||
initOrdererVars $ORG $COUNT
|
||||
log "Registering $ORDERER_NAME with $CA_NAME"
|
||||
fabric-ca-client register -d --id.name $ORDERER_NAME --id.secret $ORDERER_PASS
|
||||
COUNT=$((COUNT+1))
|
||||
done
|
||||
log "Registering admin identity with $CA_NAME"
|
||||
# The admin identity has the "hf.admin" attribute which is added to ECert by default
|
||||
fabric-ca-client register -d --id.name $ADMIN_NAME --id.secret $ADMIN_PASS --id.attrs "hf.admin=true:ecert"
|
||||
done
|
||||
}
|
||||
|
||||
# Register any identities associated with a peer
|
||||
function registerPeerIdentities {
|
||||
for ORG in $PEER_ORGS; do
|
||||
initOrgVars $ORG
|
||||
enrollCAAdmin
|
||||
local COUNT=1
|
||||
while [[ "$COUNT" -le $NUM_PEERS ]]; do
|
||||
initPeerVars $ORG $COUNT
|
||||
log "Registering $PEER_NAME with $CA_NAME"
|
||||
fabric-ca-client register -d --id.name $PEER_NAME --id.secret $PEER_PASS
|
||||
COUNT=$((COUNT+1))
|
||||
done
|
||||
log "Registering admin identity with $CA_NAME"
|
||||
# The admin identity has the "hf.admin" attribute which is added to ECert by default
|
||||
fabric-ca-client register -d --id.name $ADMIN_NAME --id.secret $ADMIN_PASS --id.attrs "hf.admin=true:ecert,abac.init=true:ecert"
|
||||
log "Registering user identity with $CA_NAME"
|
||||
fabric-ca-client register -d --id.name $USER_NAME --id.secret $USER_PASS
|
||||
done
|
||||
}
|
||||
|
||||
function getCACerts {
|
||||
log "Getting CA certificates ..."
|
||||
for ORG in $ORGS; do
|
||||
initOrgVars $ORG
|
||||
log "Getting CA certs for organization $ORG and storing in $ORG_MSP_DIR"
|
||||
export FABRIC_CA_CLIENT_TLS_CERTFILES=$CA_CHAINFILE
|
||||
fabric-ca-client getcacert -d -u https://$CA_HOST:7054 -M $ORG_MSP_DIR
|
||||
finishMSPSetup $ORG_MSP_DIR
|
||||
# If ADMINCERTS is true, we need to enroll the admin now to populate the admincerts directory
|
||||
if [ $ADMINCERTS ]; then
|
||||
switchToAdminIdentity
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# printOrg
|
||||
function printOrg {
|
||||
echo "
|
||||
- &$ORG_CONTAINER_NAME
|
||||
|
||||
Name: $ORG
|
||||
|
||||
# ID to load the MSP definition as
|
||||
ID: $ORG_MSP_ID
|
||||
|
||||
# MSPDir is the filesystem path which contains the MSP configuration
|
||||
MSPDir: $ORG_MSP_DIR"
|
||||
}
|
||||
|
||||
# printOrdererOrg <ORG>
|
||||
function printOrdererOrg {
|
||||
initOrgVars $1
|
||||
printOrg
|
||||
}
|
||||
|
||||
# printPeerOrg <ORG> <COUNT>
|
||||
function printPeerOrg {
|
||||
initPeerVars $1 $2
|
||||
printOrg
|
||||
echo "
|
||||
AnchorPeers:
|
||||
# AnchorPeers defines the location of peers which can be used
|
||||
# for cross org gossip communication. Note, this value is only
|
||||
# encoded in the genesis block in the Application section context
|
||||
- Host: $PEER_HOST
|
||||
Port: 7051"
|
||||
}
|
||||
|
||||
function makeConfigTxYaml {
|
||||
{
|
||||
echo "################################################################################
|
||||
#
|
||||
# Profile
|
||||
#
|
||||
# - Different configuration profiles may be encoded here to be specified
|
||||
# as parameters to the configtxgen tool
|
||||
#
|
||||
################################################################################
|
||||
Profiles:
|
||||
|
||||
OrgsOrdererGenesis:
|
||||
Orderer:
|
||||
# Orderer Type: The orderer implementation to start
|
||||
# Available types are \"solo\" and \"kafka\"
|
||||
OrdererType: solo
|
||||
Addresses:"
|
||||
|
||||
for ORG in $ORDERER_ORGS; do
|
||||
local COUNT=1
|
||||
while [[ "$COUNT" -le $NUM_ORDERERS ]]; do
|
||||
initOrdererVars $ORG $COUNT
|
||||
echo " - $ORDERER_HOST:7050"
|
||||
COUNT=$((COUNT+1))
|
||||
done
|
||||
done
|
||||
|
||||
echo "
|
||||
# Batch Timeout: The amount of time to wait before creating a batch
|
||||
BatchTimeout: 2s
|
||||
|
||||
# Batch Size: Controls the number of messages batched into a block
|
||||
BatchSize:
|
||||
|
||||
# Max Message Count: The maximum number of messages to permit in a batch
|
||||
MaxMessageCount: 10
|
||||
|
||||
# Absolute Max Bytes: The absolute maximum number of bytes allowed for
|
||||
# the serialized messages in a batch.
|
||||
AbsoluteMaxBytes: 99 MB
|
||||
|
||||
# Preferred Max Bytes: The preferred maximum number of bytes allowed for
|
||||
# the serialized messages in a batch. A message larger than the preferred
|
||||
# max bytes will result in a batch larger than preferred max bytes.
|
||||
PreferredMaxBytes: 512 KB
|
||||
|
||||
Kafka:
|
||||
# Brokers: A list of Kafka brokers to which the orderer connects
|
||||
# NOTE: Use IP:port notation
|
||||
Brokers:
|
||||
- 127.0.0.1:9092
|
||||
|
||||
# Organizations is the list of orgs which are defined as participants on
|
||||
# the orderer side of the network
|
||||
Organizations:"
|
||||
|
||||
for ORG in $ORDERER_ORGS; do
|
||||
initOrgVars $ORG
|
||||
echo " - *${ORG_CONTAINER_NAME}"
|
||||
done
|
||||
|
||||
echo "
|
||||
Consortiums:
|
||||
|
||||
SampleConsortium:
|
||||
|
||||
Organizations:"
|
||||
|
||||
for ORG in $PEER_ORGS; do
|
||||
initOrgVars $ORG
|
||||
echo " - *${ORG_CONTAINER_NAME}"
|
||||
done
|
||||
|
||||
echo "
|
||||
OrgsChannel:
|
||||
Consortium: SampleConsortium
|
||||
Application:
|
||||
<<: *ApplicationDefaults
|
||||
Organizations:"
|
||||
|
||||
for ORG in $PEER_ORGS; do
|
||||
initOrgVars $ORG
|
||||
echo " - *${ORG_CONTAINER_NAME}"
|
||||
done
|
||||
|
||||
echo "
|
||||
################################################################################
|
||||
#
|
||||
# Section: Organizations
|
||||
#
|
||||
# - This section defines the different organizational identities which will
|
||||
# be referenced later in the configuration.
|
||||
#
|
||||
################################################################################
|
||||
Organizations:"
|
||||
|
||||
for ORG in $ORDERER_ORGS; do
|
||||
printOrdererOrg $ORG
|
||||
done
|
||||
|
||||
for ORG in $PEER_ORGS; do
|
||||
printPeerOrg $ORG 1
|
||||
done
|
||||
|
||||
echo "
|
||||
################################################################################
|
||||
#
|
||||
# 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:
|
||||
"
|
||||
|
||||
} > /etc/hyperledger/fabric/configtx.yaml
|
||||
# Copy it to the data directory to make debugging easier
|
||||
cp /etc/hyperledger/fabric/configtx.yaml /$DATA
|
||||
}
|
||||
|
||||
function generateChannelArtifacts() {
|
||||
which configtxgen
|
||||
if [ "$?" -ne 0 ]; then
|
||||
fatal "configtxgen tool not found. exiting"
|
||||
fi
|
||||
|
||||
log "Generating orderer genesis block at $GENESIS_BLOCK_FILE"
|
||||
# Note: For some unknown reason (at least for now) the block file can't be
|
||||
# named orderer.genesis.block or the orderer will fail to launch!
|
||||
configtxgen -profile OrgsOrdererGenesis -outputBlock $GENESIS_BLOCK_FILE
|
||||
if [ "$?" -ne 0 ]; then
|
||||
fatal "Failed to generate orderer genesis block"
|
||||
fi
|
||||
|
||||
log "Generating channel configuration transaction at $CHANNEL_TX_FILE"
|
||||
configtxgen -profile OrgsChannel -outputCreateChannelTx $CHANNEL_TX_FILE -channelID $CHANNEL_NAME
|
||||
if [ "$?" -ne 0 ]; then
|
||||
fatal "Failed to generate channel configuration transaction"
|
||||
fi
|
||||
|
||||
for ORG in $PEER_ORGS; do
|
||||
initOrgVars $ORG
|
||||
log "Generating anchor peer update transaction for $ORG at $ANCHOR_TX_FILE"
|
||||
configtxgen -profile OrgsChannel -outputAnchorPeersUpdate $ANCHOR_TX_FILE \
|
||||
-channelID $CHANNEL_NAME -asOrg $ORG
|
||||
if [ "$?" -ne 0 ]; then
|
||||
fatal "Failed to generate anchor peer update for $ORG"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
set -e
|
||||
|
||||
SDIR=$(dirname "$0")
|
||||
source $SDIR/env.sh
|
||||
|
||||
main
|
||||
24
fabric-ca/scripts/start-intermediate-ca.sh
Executable file
24
fabric-ca/scripts/start-intermediate-ca.sh
Executable file
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright IBM Corp. All Rights Reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
source $(dirname "$0")/env.sh
|
||||
initOrgVars $ORG
|
||||
|
||||
set -e
|
||||
|
||||
dowait "Root CA certificate file to be created" 10 $ROOT_CA_CERTFILE $ROOT_CA_LOGFILE
|
||||
|
||||
sleep 2
|
||||
|
||||
# Initialize the intermediate CA
|
||||
fabric-ca-server init -b $BOOTSTRAP_USER_PASS -u $PARENT_URL
|
||||
|
||||
# Copy the intermediate CA's certificate chain to the data directory to be used by others
|
||||
cp $FABRIC_CA_SERVER_HOME/ca-chain.pem $TARGET_CHAINFILE
|
||||
|
||||
# Start the intermediate CA
|
||||
fabric-ca-server start
|
||||
37
fabric-ca/scripts/start-orderer.sh
Executable file
37
fabric-ca/scripts/start-orderer.sh
Executable file
|
|
@ -0,0 +1,37 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright IBM Corp. All Rights Reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
source $(dirname "$0")/env.sh
|
||||
|
||||
# Wait for setup to complete sucessfully
|
||||
awaitSetup 10
|
||||
|
||||
# Enroll to get orderer's TLS cert (using the "tls" profile)
|
||||
fabric-ca-client enroll -d --enrollment.profile tls -u $ENROLLMENT_URL -M /tmp/tls --csr.hosts $ORDERER_HOST
|
||||
|
||||
# Copy the TLS key and cert to the appropriate place
|
||||
TLSDIR=$ORDERER_HOME/tls
|
||||
mkdir -p $TLSDIR
|
||||
cp /tmp/tls/keystore/* $ORDERER_GENERAL_TLS_PRIVATEKEY
|
||||
cp /tmp/tls/signcerts/* $ORDERER_GENERAL_TLS_CERTIFICATE
|
||||
rm -rf /tmp/tls
|
||||
|
||||
# Enroll again to get the orderer's enrollment certificate (default profile)
|
||||
fabric-ca-client enroll -d -u $ENROLLMENT_URL -M $ORDERER_GENERAL_LOCALMSPDIR
|
||||
|
||||
# Finish setting up the local MSP for the orderer
|
||||
finishMSPSetup $ORDERER_GENERAL_LOCALMSPDIR
|
||||
copyAdminCert $ORDERER_GENERAL_LOCALMSPDIR
|
||||
|
||||
# Wait for the genesis block to be created
|
||||
dowait "genesis block to be created" 10 $SETUP_LOGFILE $ORDERER_GENERAL_GENESISFILE
|
||||
|
||||
# Start the orderer
|
||||
env | grep ORDERER
|
||||
orderer
|
||||
32
fabric-ca/scripts/start-peer.sh
Executable file
32
fabric-ca/scripts/start-peer.sh
Executable file
|
|
@ -0,0 +1,32 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright IBM Corp. All Rights Reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
source $(dirname "$0")/env.sh
|
||||
|
||||
awaitSetup 10
|
||||
|
||||
# Enroll the peer to get a TLS cert
|
||||
fabric-ca-client enroll -d --enrollment.profile tls -u $ENROLLMENT_URL -M /tmp/tls --csr.hosts $PEER_HOST
|
||||
|
||||
# Copy the TLS key and cert to the appropriate place
|
||||
TLSDIR=$PEER_HOME/tls
|
||||
mkdir -p $TLSDIR
|
||||
cp /tmp/tls/signcerts/* $CORE_PEER_TLS_CERT_FILE
|
||||
cp /tmp/tls/keystore/* $CORE_PEER_TLS_KEY_FILE
|
||||
rm -rf /tmp/tls
|
||||
|
||||
# Enroll the peer to get an enrollment certificate and set up the core's local MSP directory
|
||||
fabric-ca-client enroll -d -u $ENROLLMENT_URL -M $CORE_PEER_MSPCONFIGPATH
|
||||
finishMSPSetup $CORE_PEER_MSPCONFIGPATH
|
||||
copyAdminCert $CORE_PEER_MSPCONFIGPATH
|
||||
|
||||
# Start the peer
|
||||
log "Starting peer '$CORE_PEER_ID' with MSP at '$CORE_PEER_MSPCONFIGPATH'"
|
||||
env | grep CORE
|
||||
peer node start
|
||||
17
fabric-ca/scripts/start-root-ca.sh
Executable file
17
fabric-ca/scripts/start-root-ca.sh
Executable file
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright IBM Corp. All Rights Reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Initialize the root CA
|
||||
fabric-ca-server init -b $BOOTSTRAP_USER_PASS
|
||||
|
||||
# Copy the root CA's signing certificate to the data directory to be used by others
|
||||
cp $FABRIC_CA_SERVER_HOME/ca-cert.pem $TARGET_CERTFILE
|
||||
|
||||
# Start the root CA
|
||||
fabric-ca-server start
|
||||
67
fabric-ca/start.sh
Executable file
67
fabric-ca/start.sh
Executable file
|
|
@ -0,0 +1,67 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright IBM Corp. All Rights Reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
#
|
||||
# This script does everything required to run the fabric CA sample.
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
SDIR=$(dirname "$0")
|
||||
source ${SDIR}/scripts/env.sh
|
||||
|
||||
cd ${SDIR}
|
||||
|
||||
# Delete docker containers
|
||||
dockerContainers=$(docker ps -a | awk '$2~/hyperledger/ {print $1}')
|
||||
if [ "$dockerContainers" != "" ]; then
|
||||
log "Deleting existing docker containers ..."
|
||||
docker rm -f $dockerContainers > /dev/null
|
||||
fi
|
||||
|
||||
# Remove chaincode docker images
|
||||
chaincodeImages=`docker images | grep "^dev-peer" | awk '{print $3}'`
|
||||
if [ "$chaincodeImages" != "" ]; then
|
||||
log "Removing chaincode docker images ..."
|
||||
docker rmi -f $chaincodeImages > /dev/null
|
||||
fi
|
||||
|
||||
# Start with a clean data directory
|
||||
DDIR=${SDIR}/${DATA}
|
||||
if [ -d ${DDIR} ]; then
|
||||
log "Cleaning up the data directory from previous run at $DDIR"
|
||||
rm -rf ${SDIR}/data
|
||||
fi
|
||||
mkdir -p ${DDIR}/logs
|
||||
|
||||
# Create the docker-compose file
|
||||
${SDIR}/makeDocker.sh
|
||||
|
||||
# Create the docker containers
|
||||
log "Creating docker containers ..."
|
||||
docker-compose up -d
|
||||
|
||||
# Wait for the setup container to complete
|
||||
dowait "the 'setup' container to finish registering identities, creating the genesis block and other artifacts" 10 $SDIR/$SETUP_LOGFILE $SDIR/$SETUP_SUCCESS_FILE
|
||||
|
||||
# Wait for the run container to start and then tails it's summary log
|
||||
dowait "the docker 'run' container to start" 15 ${SDIR}/${SETUP_LOGFILE} ${SDIR}/${RUN_SUMFILE}
|
||||
tail -f ${SDIR}/${RUN_SUMFILE}&
|
||||
TAIL_PID=$!
|
||||
|
||||
# Wait for the run container to complete
|
||||
while true; do
|
||||
if [ -f ${SDIR}/${RUN_SUCCESS_FILE} ]; then
|
||||
kill -9 $TAIL_PID
|
||||
exit 0
|
||||
elif [ -f ${SDIR}/${RUN_FAIL_FILE} ]; then
|
||||
kill -9 $TAIL_PID
|
||||
exit 1
|
||||
else
|
||||
sleep 1
|
||||
fi
|
||||
done
|
||||
14
fabric-ca/stop.sh
Executable file
14
fabric-ca/stop.sh
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Copyright IBM Corp. All Rights Reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
set -e
|
||||
SDIR=$(dirname "$0")
|
||||
source $SDIR/scripts/env.sh
|
||||
|
||||
log "Stopping docker containers ..."
|
||||
docker-compose down
|
||||
log "Docker containers have been stopped"
|
||||
Loading…
Reference in a new issue