From 5bc50a8feccbdb7475c651282a3ae35735548aad Mon Sep 17 00:00:00 2001 From: Samuel Venzi Date: Wed, 10 Jul 2024 15:03:04 -0300 Subject: [PATCH 1/9] Add ccaas start up on chaincode Signed-off-by: Samuel Venzi --- chaincode/main.go | 71 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/chaincode/main.go b/chaincode/main.go index 3310f85..c7f9cb5 100644 --- a/chaincode/main.go +++ b/chaincode/main.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "log" + "os" "time" "github.com/hyperledger-labs/cc-tools-demo/chaincode/assettypes" @@ -62,11 +63,79 @@ func main() { if err != nil { return } - if err = shim.Start(new(CCDemo)); err != nil { + + if os.Getenv("RUN_CCAAS") == "true" { + err = runCCaaS() + } else { + err = shim.Start(new(CCDemo)) + } + + if err != nil { fmt.Printf("Error starting chaincode: %s", err) } } +func runCCaaS() error { + address := os.Getenv("CHAINCODE_SERVER_ADDRESS") + ccid := os.Getenv("CHAINCODE_ID") + + tlsProps, err := getTLSProperties() + if err != nil { + return err + } + + server := &shim.ChaincodeServer{ + CCID: ccid, + Address: address, + CC: new(CCDemo), + TLSProps: *tlsProps, + } + + return server.Start() +} + +func getTLSProperties() (*shim.TLSProperties, error) { + if enableTLS := os.Getenv("TLS_ENABLED"); enableTLS != "true" { + return &shim.TLSProperties{ + Disabled: true, + }, nil + } + + log.Printf("TLS enabled") + + // Get key + keyPath := os.Getenv("KEY_PATH") + key, err := os.ReadFile(keyPath) + + if err != nil { + fmt.Println("Failed to read key file") + return nil, err + } + + // Get cert + certPath := os.Getenv("CERT_PATH") + cert, err := os.ReadFile(certPath) + if err != nil { + fmt.Println("Failed to read cert file") + return nil, err + } + + // Get CA cert + clientCertPath := os.Getenv("CA_CERT_PATH") + caCert, err := os.ReadFile(clientCertPath) + if err != nil { + fmt.Println("Failed to read CA cert file") + return nil, err + } + + return &shim.TLSProperties{ + Disabled: false, + Key: key, + Cert: cert, + ClientCACerts: caCert, + }, nil +} + // CCDemo implements the shim.Chaincode interface type CCDemo struct{} From 9d110b6f9f2bf9aa862afbf075940d9e4e61c82f Mon Sep 17 00:00:00 2001 From: Samuel Venzi Date: Wed, 10 Jul 2024 15:26:24 -0300 Subject: [PATCH 2/9] Add chaincode Dockerfile Signed-off-by: Samuel Venzi --- chaincode/Dockerfile | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 chaincode/Dockerfile diff --git a/chaincode/Dockerfile b/chaincode/Dockerfile new file mode 100644 index 0000000..8f6d635 --- /dev/null +++ b/chaincode/Dockerfile @@ -0,0 +1,18 @@ +# Copyright IBM Corp. All Rights Reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +ARG GO_VER=1.21 +ARG ALPINE_VER=3.20 +ARG CC_SERVER_PORT=9999 + +FROM golang:${GO_VER}-alpine${ALPINE_VER} + +WORKDIR /go/src/github.com/hyperledger-labs/cc-tools-demo +COPY . . + +RUN go get -d -v . +RUN go build -o cc-tools-demo -v . + +EXPOSE ${CC_SERVER_PORT} +CMD ["./cc-tools-demo"] From 2ca068601e34405a58ed4e03733a542975e82623 Mon Sep 17 00:00:00 2001 From: Samuel Venzi Date: Wed, 10 Jul 2024 15:26:44 -0300 Subject: [PATCH 3/9] Add external builder files Signed-off-by: Samuel Venzi --- fabric/externalBuilder/bin/build | 21 +++++++++++++++++ fabric/externalBuilder/bin/detect | 14 +++++++++++ fabric/externalBuilder/bin/release | 38 ++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 fabric/externalBuilder/bin/build create mode 100644 fabric/externalBuilder/bin/detect create mode 100644 fabric/externalBuilder/bin/release diff --git a/fabric/externalBuilder/bin/build b/fabric/externalBuilder/bin/build new file mode 100644 index 0000000..3632ad4 --- /dev/null +++ b/fabric/externalBuilder/bin/build @@ -0,0 +1,21 @@ +#!/bin/sh + +# set -euo pipefail + +SOURCE=$1 +OUTPUT=$3 + +#external chaincodes expect connection.json file in the chaincode package +if [ ! -f "$SOURCE/connection.json" ]; then + >&2 echo "$SOURCE/connection.json not found" + exit 1 +fi + +#simply copy the endpoint information to specified output location +cp $SOURCE/connection.json $OUTPUT/connection.json + +if [ -d "$SOURCE/metadata" ]; then + cp -a $SOURCE/metadata $OUTPUT/metadata +fi + +exit 0 \ No newline at end of file diff --git a/fabric/externalBuilder/bin/detect b/fabric/externalBuilder/bin/detect new file mode 100644 index 0000000..514d5f7 --- /dev/null +++ b/fabric/externalBuilder/bin/detect @@ -0,0 +1,14 @@ +#!/bin/sh + +set -euo pipefail + +METADIR=$2 +# check if the "type" field is set to "external" +# crude way without jq which is not in the default fabric peer image +TYPE=$(tr -d '\n' < "$METADIR/metadata.json" | awk -F':' '{ for (i = 1; i < NF; i++){ if ($i~/type/) { print $(i+1); break }}}'| cut -d\" -f2) + +if [ "$TYPE" = "external" ]; then + exit 0 +fi + +exit 1 \ No newline at end of file diff --git a/fabric/externalBuilder/bin/release b/fabric/externalBuilder/bin/release new file mode 100644 index 0000000..eed8c6c --- /dev/null +++ b/fabric/externalBuilder/bin/release @@ -0,0 +1,38 @@ +#!/bin/sh + +set -euo pipefail + +BLD="$1" +RELEASE="$2" + +if [ -d "$BLD/metadata" ]; then + cp -a "$BLD/metadata/"* "$RELEASE/" +fi + +#external chaincodes expect artifacts to be placed under "$RELEASE"/chaincode/server +if [ -f $BLD/connection.json ]; then + mkdir -p "$RELEASE"/chaincode/server + + sed -i "s/{{.org}}/$CCAAS_ORG/" $BLD/connection.json + sed -i "s/{{.port}}/$CCAAS_PORT/" $BLD/connection.json + + # Check if tls is enabled + if [ "$(jq -r .tls_required $BLD/connection.json)" = "true" ]; then + client_cert=$(awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' "$CCAAS_CLIENT_CERT_FILE") + client_key=$(awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' "$CCAAS_CLIENT_KEY_FILE") + root_cert=$(awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' "$CCAAS_ROOT_CERT_FILE") + + # Add certs files to connection.json + echo $(jq ".client_cert=\"$client_cert\"" $BLD/connection.json) > $BLD/connection.json + echo $(jq ".client_key=\"$client_key\"" $BLD/connection.json) > $BLD/connection.json + echo $(jq ".root_cert=\"$root_cert\"" $BLD/connection.json) > $BLD/connection.json + fi + + cp $BLD/connection.json "$RELEASE"/chaincode/server + + exit 0 +fi + +exit 1 + + \ No newline at end of file From d38eface5d802de0c0972af1a9b41cfd06076294 Mon Sep 17 00:00:00 2001 From: Samuel Venzi Date: Wed, 10 Jul 2024 15:26:57 -0300 Subject: [PATCH 4/9] Map external builder to containers Signed-off-by: Samuel Venzi --- fabric/docker/docker-compose-test-net-org.yaml | 2 ++ fabric/docker/docker-compose-test-net.yaml | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/fabric/docker/docker-compose-test-net-org.yaml b/fabric/docker/docker-compose-test-net-org.yaml index 61200d2..0659b62 100644 --- a/fabric/docker/docker-compose-test-net-org.yaml +++ b/fabric/docker/docker-compose-test-net-org.yaml @@ -83,11 +83,13 @@ services: - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org.example.com:7051 - CORE_PEER_LOCALMSPID=orgMSP - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp + - CORE_CHAINCODE_EXTERNALBUILDERS=[{"name":"basic-builder","path":"/etc/hyperledger/external-builder","propagateEnvironment":["CCAAS_CLIENT_CERT_FILE","CCAAS_CLIENT_KEY_FILE","CCAAS_ROOT_CERT_FILE","CCAAS_ORG","CCAAS_PORT"]}] volumes: - /var/run/docker.sock:/host/var/run/docker.sock - ../organizations/peerOrganizations/org.example.com/peers/peer0.org.example.com/msp:/etc/hyperledger/fabric/msp - ../organizations/peerOrganizations/org.example.com/peers/peer0.org.example.com/tls:/etc/hyperledger/fabric/tls - peer0.org.example.com:/var/hyperledger/production + - ../externalBuilder:/etc/hyperledger/external-builder working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer command: peer node start ports: diff --git a/fabric/docker/docker-compose-test-net.yaml b/fabric/docker/docker-compose-test-net.yaml index 93ebcea..f5c2426 100644 --- a/fabric/docker/docker-compose-test-net.yaml +++ b/fabric/docker/docker-compose-test-net.yaml @@ -85,11 +85,13 @@ services: - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051 - CORE_PEER_LOCALMSPID=org1MSP - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp + - CORE_CHAINCODE_EXTERNALBUILDERS=[{"name":"basic-builder","path":"/etc/hyperledger/external-builder","propagateEnvironment":["CCAAS_CLIENT_CERT_FILE","CCAAS_CLIENT_KEY_FILE","CCAAS_ROOT_CERT_FILE","CCAAS_ORG","CCAAS_PORT"]}] volumes: - /var/run/docker.sock:/host/var/run/docker.sock - ../organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp - ../organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls - peer0.org1.example.com:/var/hyperledger/production + - ../externalBuilder:/etc/hyperledger/external-builder working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer command: peer node start ports: @@ -125,11 +127,13 @@ services: - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:7051 - CORE_PEER_LOCALMSPID=org2MSP - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp + - CORE_CHAINCODE_EXTERNALBUILDERS=[{"name":"basic-builder","path":"/etc/hyperledger/external-builder","propagateEnvironment":["CCAAS_CLIENT_CERT_FILE","CCAAS_CLIENT_KEY_FILE","CCAAS_ROOT_CERT_FILE","CCAAS_ORG","CCAAS_PORT"]}] volumes: - /var/run/docker.sock:/host/var/run/docker.sock - ../organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp:/etc/hyperledger/fabric/msp - ../organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls:/etc/hyperledger/fabric/tls - peer0.org2.example.com:/var/hyperledger/production + - ../externalBuilder:/etc/hyperledger/external-builder working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer command: peer node start ports: @@ -165,11 +169,13 @@ services: - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org3.example.com:7051 - CORE_PEER_LOCALMSPID=org3MSP - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp + - CORE_CHAINCODE_EXTERNALBUILDERS=[{"name":"basic-builder","path":"/etc/hyperledger/external-builder","propagateEnvironment":["CCAAS_CLIENT_CERT_FILE","CCAAS_CLIENT_KEY_FILE","CCAAS_ROOT_CERT_FILE","CCAAS_ORG","CCAAS_PORT"]}] volumes: - /var/run/docker.sock:/host/var/run/docker.sock - ../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/msp:/etc/hyperledger/fabric/msp - ../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls:/etc/hyperledger/fabric/tls - peer0.org3.example.com:/var/hyperledger/production + - ../externalBuilder:/etc/hyperledger/external-builder working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer command: peer node start ports: From a7ac192bcd40ec49eb15424645076cfeff7389f6 Mon Sep 17 00:00:00 2001 From: Samuel Venzi Date: Wed, 10 Jul 2024 15:27:39 -0300 Subject: [PATCH 5/9] Add external builder to core.yaml Signed-off-by: Samuel Venzi --- fabric/config/core.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fabric/config/core.yaml b/fabric/config/core.yaml index 7809b00..2443203 100644 --- a/fabric/config/core.yaml +++ b/fabric/config/core.yaml @@ -599,11 +599,11 @@ chaincode: # If you don't need to fallback to the default Docker builder, also unconfigure vm.endpoint above. # To override this property via env variable use CORE_CHAINCODE_EXTERNALBUILDERS: [{name: x, path: dir1}, {name: y, path: dir2}] # The path must be an absolute path. - externalBuilders: - - name: ccaas_builder - path: /opt/hyperledger/ccaas_builder - propagateEnvironment: - - CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG + externalBuilders: [] + # - name: ccaas_builder + # path: /opt/hyperledger/ccaas_builder + # propagateEnvironment: + # - CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG # The maximum duration to wait for the chaincode build and install process From 3e2d76eefd2d7a5c0afdbdf811de46d8d71e82db Mon Sep 17 00:00:00 2001 From: Samuel Venzi Date: Wed, 10 Jul 2024 16:28:12 -0300 Subject: [PATCH 6/9] Add scripts to deploy ccaas Signed-off-by: Samuel Venzi --- fabric/config/core.yaml | 10 +- .../docker/docker-compose-test-net-org.yaml | 11 +- fabric/docker/docker-compose-test-net.yaml | 29 +- fabric/externalBuilder/bin/build | 2 +- fabric/externalBuilder/bin/detect | 2 +- fabric/externalBuilder/bin/release | 2 +- fabric/network.sh | 78 ++++- fabric/scripts/ccutils.sh | 288 ++++++++++++++++++ fabric/scripts/deployCCAAS.sh | 205 +++++++++++++ fabric/scripts/envVar.sh | 10 +- fabric/scripts/utils.sh | 6 + fabric/startDev.sh | 32 +- startDev.sh | 27 +- 13 files changed, 669 insertions(+), 33 deletions(-) mode change 100644 => 100755 fabric/externalBuilder/bin/build mode change 100644 => 100755 fabric/externalBuilder/bin/detect mode change 100644 => 100755 fabric/externalBuilder/bin/release create mode 100644 fabric/scripts/ccutils.sh create mode 100755 fabric/scripts/deployCCAAS.sh diff --git a/fabric/config/core.yaml b/fabric/config/core.yaml index 2443203..bc97646 100644 --- a/fabric/config/core.yaml +++ b/fabric/config/core.yaml @@ -599,11 +599,11 @@ chaincode: # If you don't need to fallback to the default Docker builder, also unconfigure vm.endpoint above. # To override this property via env variable use CORE_CHAINCODE_EXTERNALBUILDERS: [{name: x, path: dir1}, {name: y, path: dir2}] # The path must be an absolute path. - externalBuilders: [] - # - name: ccaas_builder - # path: /opt/hyperledger/ccaas_builder - # propagateEnvironment: - # - CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG + externalBuilders: + - name: ccaas_builder + path: /opt/hyperledger/external-builder + propagateEnvironment: + - CHAINCODE_AS_A_SERVICE_BUILDER_CONFIG # The maximum duration to wait for the chaincode build and install process diff --git a/fabric/docker/docker-compose-test-net-org.yaml b/fabric/docker/docker-compose-test-net-org.yaml index 0659b62..aa4328d 100644 --- a/fabric/docker/docker-compose-test-net-org.yaml +++ b/fabric/docker/docker-compose-test-net-org.yaml @@ -22,6 +22,8 @@ services: - FABRIC_LOGGING_SPEC=INFO - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 - ORDERER_GENERAL_LISTENPORT=7050 + - ORDERER_GENERAL_GENESISMETHOD=file + - ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block - ORDERER_GENERAL_LOCALMSPID=OrdererMSP - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp - ORDERER_CHANNELPARTICIPATION_ENABLED=true @@ -82,14 +84,21 @@ services: - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org.example.com:7051 - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org.example.com:7051 - CORE_PEER_LOCALMSPID=orgMSP - - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp - CORE_CHAINCODE_EXTERNALBUILDERS=[{"name":"basic-builder","path":"/etc/hyperledger/external-builder","propagateEnvironment":["CCAAS_CLIENT_CERT_FILE","CCAAS_CLIENT_KEY_FILE","CCAAS_ROOT_CERT_FILE","CCAAS_ORG","CCAAS_PORT"]}] + - CCAAS_CLIENT_CERT_FILE=/etc/hyperledger/fabric/ccaas/tls/client/cert.pem + - CCAAS_CLIENT_KEY_FILE=/etc/hyperledger/fabric/ccaas/tls/client/key.pem + - CCAAS_ROOT_CERT_FILE=/etc/hyperledger/fabric/ccaas/tls/ca/cert.pem + - CCAAS_ORG=org + - CCAAS_PORT=9999 + - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp volumes: - /var/run/docker.sock:/host/var/run/docker.sock - ../organizations/peerOrganizations/org.example.com/peers/peer0.org.example.com/msp:/etc/hyperledger/fabric/msp - ../organizations/peerOrganizations/org.example.com/peers/peer0.org.example.com/tls:/etc/hyperledger/fabric/tls + - ../organizations/ccaas/org.example.com:/etc/hyperledger/fabric/ccaas/tls - peer0.org.example.com:/var/hyperledger/production - ../externalBuilder:/etc/hyperledger/external-builder + - ../bin/jq:/usr/local/bin/jq working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer command: peer node start ports: diff --git a/fabric/docker/docker-compose-test-net.yaml b/fabric/docker/docker-compose-test-net.yaml index f5c2426..181a165 100644 --- a/fabric/docker/docker-compose-test-net.yaml +++ b/fabric/docker/docker-compose-test-net.yaml @@ -24,6 +24,8 @@ services: - FABRIC_LOGGING_SPEC=INFO - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 - ORDERER_GENERAL_LISTENPORT=7050 + - ORDERER_GENERAL_GENESISMETHOD=file + - ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block - ORDERER_GENERAL_LOCALMSPID=OrdererMSP - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp - ORDERER_CHANNELPARTICIPATION_ENABLED=true @@ -84,14 +86,21 @@ services: - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051 - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051 - CORE_PEER_LOCALMSPID=org1MSP - - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp - CORE_CHAINCODE_EXTERNALBUILDERS=[{"name":"basic-builder","path":"/etc/hyperledger/external-builder","propagateEnvironment":["CCAAS_CLIENT_CERT_FILE","CCAAS_CLIENT_KEY_FILE","CCAAS_ROOT_CERT_FILE","CCAAS_ORG","CCAAS_PORT"]}] + - CCAAS_CLIENT_CERT_FILE=/etc/hyperledger/fabric/ccaas/tls/client/cert.pem + - CCAAS_CLIENT_KEY_FILE=/etc/hyperledger/fabric/ccaas/tls/client/key.pem + - CCAAS_ROOT_CERT_FILE=/etc/hyperledger/fabric/ccaas/tls/ca/cert.pem + - CCAAS_ORG=org1 + - CCAAS_PORT=9999 + - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp volumes: - /var/run/docker.sock:/host/var/run/docker.sock - ../organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp - ../organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls + - ../organizations/ccaas/org1.example.com:/etc/hyperledger/fabric/ccaas/tls - peer0.org1.example.com:/var/hyperledger/production - ../externalBuilder:/etc/hyperledger/external-builder + - ../bin/jq:/usr/local/bin/jq working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer command: peer node start ports: @@ -126,14 +135,21 @@ services: - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:7051 - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:7051 - CORE_PEER_LOCALMSPID=org2MSP - - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp - CORE_CHAINCODE_EXTERNALBUILDERS=[{"name":"basic-builder","path":"/etc/hyperledger/external-builder","propagateEnvironment":["CCAAS_CLIENT_CERT_FILE","CCAAS_CLIENT_KEY_FILE","CCAAS_ROOT_CERT_FILE","CCAAS_ORG","CCAAS_PORT"]}] + - CCAAS_CLIENT_CERT_FILE=/etc/hyperledger/fabric/ccaas/tls/client/cert.pem + - CCAAS_CLIENT_KEY_FILE=/etc/hyperledger/fabric/ccaas/tls/client/key.pem + - CCAAS_ROOT_CERT_FILE=/etc/hyperledger/fabric/ccaas/tls/ca/cert.pem + - CCAAS_ORG=org2 + - CCAAS_PORT=9998 + - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp volumes: - /var/run/docker.sock:/host/var/run/docker.sock - ../organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp:/etc/hyperledger/fabric/msp - ../organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls:/etc/hyperledger/fabric/tls + - ../organizations/ccaas/org2.example.com:/etc/hyperledger/fabric/ccaas/tls - peer0.org2.example.com:/var/hyperledger/production - ../externalBuilder:/etc/hyperledger/external-builder + - ../bin/jq:/usr/local/bin/jq working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer command: peer node start ports: @@ -168,14 +184,21 @@ services: - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org3.example.com:7051 - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org3.example.com:7051 - CORE_PEER_LOCALMSPID=org3MSP - - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp - CORE_CHAINCODE_EXTERNALBUILDERS=[{"name":"basic-builder","path":"/etc/hyperledger/external-builder","propagateEnvironment":["CCAAS_CLIENT_CERT_FILE","CCAAS_CLIENT_KEY_FILE","CCAAS_ROOT_CERT_FILE","CCAAS_ORG","CCAAS_PORT"]}] + - CCAAS_CLIENT_CERT_FILE=/etc/hyperledger/fabric/ccaas/tls/client/cert.pem + - CCAAS_CLIENT_KEY_FILE=/etc/hyperledger/fabric/ccaas/tls/client/key.pem + - CCAAS_ROOT_CERT_FILE=/etc/hyperledger/fabric/ccaas/tls/ca/cert.pem + - CCAAS_ORG=org3 + - CCAAS_PORT=9997 + - CORE_PEER_MSPCONFIGPATH=/etc/hyperledger/fabric/msp volumes: - /var/run/docker.sock:/host/var/run/docker.sock - ../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/msp:/etc/hyperledger/fabric/msp - ../organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls:/etc/hyperledger/fabric/tls + - ../organizations/ccaas/org3.example.com:/etc/hyperledger/fabric/ccaas/tls - peer0.org3.example.com:/var/hyperledger/production - ../externalBuilder:/etc/hyperledger/external-builder + - ../bin/jq:/usr/local/bin/jq working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer command: peer node start ports: diff --git a/fabric/externalBuilder/bin/build b/fabric/externalBuilder/bin/build old mode 100644 new mode 100755 index 3632ad4..87a6bca --- a/fabric/externalBuilder/bin/build +++ b/fabric/externalBuilder/bin/build @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # set -euo pipefail diff --git a/fabric/externalBuilder/bin/detect b/fabric/externalBuilder/bin/detect old mode 100644 new mode 100755 index 514d5f7..6a0f53a --- a/fabric/externalBuilder/bin/detect +++ b/fabric/externalBuilder/bin/detect @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash set -euo pipefail diff --git a/fabric/externalBuilder/bin/release b/fabric/externalBuilder/bin/release old mode 100644 new mode 100755 index eed8c6c..4936715 --- a/fabric/externalBuilder/bin/release +++ b/fabric/externalBuilder/bin/release @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash set -euo pipefail diff --git a/fabric/network.sh b/fabric/network.sh index c6cfe91..4a292d3 100755 --- a/fabric/network.sh +++ b/fabric/network.sh @@ -191,6 +191,17 @@ function createOrgs() { copyRestCerts org1.example.com copyRestCerts org2.example.com copyRestCerts org3.example.com + + if [ "$CCAAS_TLS_ENABLED" = "true" ]; then + infoln "Creating Chaincode As a Service certs for Org1" + generateCCAASCerts "org1" + + infoln "Creating Chaincode As a Service certs for Org2" + generateCCAASCerts "org2" + + infoln "Creating Chaincode As a Service certs for Org3" + generateCCAASCerts "org3" + fi else infoln "Creating Org Identities" @@ -211,8 +222,13 @@ function createOrgs() { if [ $res -ne 0 ]; then fatalln "Failed to generate certificates..." fi - + copyRestCerts org.example.com + + if [ "$CCAAS_TLS_ENABLED" = "true" ]; then + infoln "Creating Chaincode As a Service keys for Org" + generateCCAASCerts "org" + fi fi fi @@ -301,6 +317,39 @@ function copyRestCerts() { cp $TLSCERT_PATH $REST_CERTS_FOLDER/${ORGNAME}/orderertls.crt } +function generateCCAASCerts() { + org="$1" + cc_certs_base_path=./organizations/ccaas/${org}.example.com + + # CC CA certs + infoln "Creating CC CA certs" + mkdir -p $cc_certs_base_path/ca + openssl genrsa 2048 > $cc_certs_base_path/ca/key.pem + openssl req -new -x509 -nodes -key $cc_certs_base_path/ca/key.pem -out $cc_certs_base_path/ca/cert.pem -subj "/C=US/ST=California/L=San Francisco/O=${org}.example.com Inc/OU=Developer/CN=cc-tools-demo.${org}.example.com" + + echo subjectAltName=DNS:cc-tools-demo.${org}.example.com > $cc_certs_base_path/subj.cnf + + # CC Server certs + infoln "Creating CC Server certs" + mkdir -p $cc_certs_base_path/server + openssl req -newkey rsa:2048 -nodes -keyout $cc_certs_base_path/server/key.pem -out $cc_certs_base_path/server/req.pem -subj "/C=US/ST=California/L=San Francisco/O=${org}.example.com Inc/OU=Developer/CN=cc-tools-demo.${org}.example.com" + + openssl x509 -req -set_serial 01 -in $cc_certs_base_path/server/req.pem -extfile $cc_certs_base_path/subj.cnf -out $cc_certs_base_path/server/cert.pem \ + -CA $cc_certs_base_path/ca/cert.pem -CAkey $cc_certs_base_path/ca/key.pem + + rm $cc_certs_base_path/server/req.pem + + # CC Client certs + infoln "Creating CC Clients certs" + mkdir -p $cc_certs_base_path/client + openssl req -newkey rsa:2048 -nodes -keyout $cc_certs_base_path/client/key.pem -out $cc_certs_base_path/client/req.pem -subj "/C=US/ST=California/L=San Francisco/O=${org}.example.com Inc/OU=Developer/CN=${org}.example.com" + + openssl x509 -req -set_serial 01 -in $cc_certs_base_path/client/req.pem -extfile $cc_certs_base_path/subj.cnf -out $cc_certs_base_path/client/cert.pem \ + -CA $cc_certs_base_path/ca/cert.pem -CAkey $cc_certs_base_path/ca/key.pem + + rm $cc_certs_base_path/client/req.pem +} + # Once you create the organization crypto material, you need to create the # genesis block of the orderer system channel. This block is required to bring # up any orderer nodes and create any application channels. @@ -413,6 +462,14 @@ function deployCC() { fi } +## Call the script to deploy a chaincode to the channel +function deployCCAAS() { + scripts/deployCCAAS.sh $CHANNEL_NAME $CC_NAME $CC_SRC_PATH $CCAAS_DOCKER_RUN $CC_VERSION $CC_SEQUENCE $CC_INIT_FCN $CC_END_POLICY $CC_COLL_CONFIG $CLI_DELAY $MAX_RETRY $VERBOSE $ORG_QNTY $CCAAS_TLS_ENABLED + + if [ $? -ne 0 ]; then + fatalln "Deploying chaincode-as-a-service failed" + fi +} # Tear down running network function networkDown() { @@ -420,6 +477,7 @@ function networkDown() { docker-compose -f $COMPOSE_FILE_BASE_ORG -f $COMPOSE_FILE_COUCH_ORG down --volumes --remove-orphans docker-compose -f $COMPOSE_FILE_BASE -f $COMPOSE_FILE_COUCH -f $COMPOSE_FILE_CA down --volumes --remove-orphans docker-compose -f $COMPOSE_FILE_COUCH_ORG3 -f $COMPOSE_FILE_ORG3 down --volumes --remove-orphans + # Don't remove the generated artifacts -- note, the ledgers are always removed if [ "$MODE" != "restart" ]; then # Bring down the network, deleting the volumes @@ -480,6 +538,10 @@ COMPOSE_FILE_ORG3=addOrg3/docker/docker-compose-org3.yaml # # chaincode language defaults to "NA" CC_SRC_LANGUAGE="NA" +# default to running the docker commands for the CCAAS +CCAAS_DOCKER_RUN=true +# enable tls for chaincode as a service +CCAAS_TLS_ENABLED=false # Chaincode version CC_VERSION="0.1" # Chaincode definition sequence @@ -490,7 +552,7 @@ IMAGETAG="2.5.3" CA_IMAGETAG="latest" # default database DATABASE="couchdb" -# default number of organizartions +# default number of organizations ORG_QNTY=3 # Clear containers (down mode) -- default = true CLR_CONTAINERS=true @@ -595,6 +657,14 @@ while [[ $# -ge 1 ]] ; do CLR_CONTAINERS=false shift ;; + -ccaasdocker ) + CCAAS_DOCKER_RUN="$2" + shift + ;; + -ccaastls ) + CCAAS_TLS_ENABLED=true + shift + ;; * ) errorln "Unknown flag: $key" printHelp @@ -623,6 +693,8 @@ elif [ "$MODE" == "restart" ]; then infoln "Restarting network" elif [ "$MODE" == "deployCC" ]; then infoln "deploying chaincode on channel '${CHANNEL_NAME}'" +elif [ "$MODE" == "deployCCAAS" ]; then + infoln "deploying chaincode-as-a-service on channel '${CHANNEL_NAME}'" else printHelp exit 1 @@ -641,6 +713,8 @@ elif [ "${MODE}" == "createChannel" ]; then createChannel elif [ "${MODE}" == "deployCC" ]; then deployCC +elif [ "$MODE" == "deployCCAAS" ]; then + deployCCAAS elif [ "${MODE}" == "down" ]; then networkDown else diff --git a/fabric/scripts/ccutils.sh b/fabric/scripts/ccutils.sh new file mode 100644 index 0000000..7e4d39f --- /dev/null +++ b/fabric/scripts/ccutils.sh @@ -0,0 +1,288 @@ +#!/bin/bash + +# installChaincode PEER ORG +installChaincode() { + ORG=$1 + setGlobals $ORG + set -x + peer lifecycle chaincode install ${CC_NAME}.tar.gz >&log.txt + res=$? + { set +x; } 2>/dev/null + cat log.txt + verifyResult $res "Chaincode installation on peer0.org${ORG} has failed" + successln "Chaincode is installed on peer0.org${ORG}" +} + +# queryInstalled PEER ORG +queryInstalled() { + ORG=$1 + setGlobals $ORG + set -x + peer lifecycle chaincode queryinstalled >&log.txt + res=$? + { set +x; } 2>/dev/null + cat log.txt + PACKAGE_ID=$(sed -n "/${CC_NAME}_${CC_VERSION}/{s/^Package ID: //; s/, Label:.*$//; p;}" log.txt) + verifyResult $res "Query installed on peer0.org${ORG} has failed" + successln "Query installed successful on peer0.org${ORG} on channel" +} + +# approveForMyOrg VERSION PEER ORG +approveForMyOrg() { + ORG=$1 + setGlobals $ORG + set -x + peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile $ORDERER_CA --channelID $CHANNEL_NAME --name ${CC_NAME} --version ${CC_VERSION} --package-id ${PACKAGE_ID} --sequence ${CC_SEQUENCE} ${INIT_REQUIRED} ${CC_END_POLICY} ${CC_COLL_CONFIG} >&log.txt + res=$? + { set +x; } 2>/dev/null + cat log.txt + verifyResult $res "Chaincode definition approved on peer0.org${ORG} on channel '$CHANNEL_NAME' failed" + successln "Chaincode definition approved on peer0.org${ORG} on channel '$CHANNEL_NAME'" +} + +# checkCommitReadiness VERSION PEER ORG +checkCommitReadiness() { + ORG=$1 + shift 1 + setGlobals $ORG + infoln "Checking the commit readiness of the chaincode definition on peer0.org${ORG} on channel '$CHANNEL_NAME'..." + local rc=1 + local COUNTER=1 + # continue to poll + # we either get a successful response, or reach MAX RETRY + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ]; do + sleep $DELAY + infoln "Attempting to check the commit readiness of the chaincode definition on peer0.org${ORG}, Retry after $DELAY seconds." + set -x + peer lifecycle chaincode checkcommitreadiness --channelID $CHANNEL_NAME --name ${CC_NAME} --version ${CC_VERSION} --sequence ${CC_SEQUENCE} ${INIT_REQUIRED} ${CC_END_POLICY} ${CC_COLL_CONFIG} --output json >&log.txt + res=$? + { set +x; } 2>/dev/null + let rc=0 + for var in "$@"; do + grep "$var" log.txt &>/dev/null || let rc=1 + done + COUNTER=$(expr $COUNTER + 1) + done + cat log.txt + if test $rc -eq 0; then + infoln "Checking the commit readiness of the chaincode definition successful on peer0.org${ORG} on channel '$CHANNEL_NAME'" + else + fatalln "After $MAX_RETRY attempts, Check commit readiness result on peer0.org${ORG} is INVALID!" + fi +} + +# commitChaincodeDefinition VERSION PEER ORG (PEER ORG)... +commitChaincodeDefinition() { + parsePeerConnectionParameters $@ + res=$? + 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), let's supply it directly as we know + # it using the "-o" option + set -x + peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile $ORDERER_CA --channelID $CHANNEL_NAME --name ${CC_NAME} $PEER_CONN_PARMS --version ${CC_VERSION} --sequence ${CC_SEQUENCE} ${INIT_REQUIRED} ${CC_END_POLICY} ${CC_COLL_CONFIG} >&log.txt + res=$? + { set +x; } 2>/dev/null + cat log.txt + verifyResult $res "Chaincode definition commit failed on peer0.org${ORG} on channel '$CHANNEL_NAME' failed" + successln "Chaincode definition committed on channel '$CHANNEL_NAME'" +} + +# queryCommitted ORG +queryCommitted() { + ORG=$1 + setGlobals $ORG + EXPECTED_RESULT="Version: ${CC_VERSION}, Sequence: ${CC_SEQUENCE}, Endorsement Plugin: escc, Validation Plugin: vscc" + infoln "Querying chaincode definition on peer0.org${ORG} on channel '$CHANNEL_NAME'..." + local rc=1 + local COUNTER=1 + # continue to poll + # we either get a successful response, or reach MAX RETRY + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ]; do + sleep $DELAY + infoln "Attempting to Query committed status on peer0.org${ORG}, Retry after $DELAY seconds." + set -x + peer lifecycle chaincode querycommitted --channelID $CHANNEL_NAME --name ${CC_NAME} >&log.txt + res=$? + { set +x; } 2>/dev/null + test $res -eq 0 && VALUE=$(cat log.txt | grep -o '^Version: '$CC_VERSION', Sequence: [0-9]*, Endorsement Plugin: escc, Validation Plugin: vscc') + test "$VALUE" = "$EXPECTED_RESULT" && let rc=0 + COUNTER=$(expr $COUNTER + 1) + done + cat log.txt + if test $rc -eq 0; then + successln "Query chaincode definition successful on peer0.org${ORG} on channel '$CHANNEL_NAME'" + else + fatalln "After $MAX_RETRY attempts, Query chaincode definition result on peer0.org${ORG} is INVALID!" + fi +} + +chaincodeInvokeInit() { + parsePeerConnectionParameters $@ + res=$? + 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), let's supply it directly as we know + # it using the "-o" option + set -x + fcn_call='{"function":"'${CC_INIT_FCN}'","Args":[]}' + infoln "invoke fcn call:${fcn_call}" + peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile $ORDERER_CA -C $CHANNEL_NAME -n ${CC_NAME} $PEER_CONN_PARMS --isInit -c ${fcn_call} >&log.txt + res=$? + { set +x; } 2>/dev/null + cat log.txt + verifyResult $res "Invoke execution on $PEERS failed " + successln "Invoke transaction successful on $PEERS on channel '$CHANNEL_NAME'" +} + +chaincodeQuery() { + ORG=$1 + setGlobals $ORG + infoln "Querying on peer0.org${ORG} on channel '$CHANNEL_NAME'..." + local rc=1 + local COUNTER=1 + # continue to poll + # we either get a successful response, or reach MAX RETRY + while [ $rc -ne 0 -a $COUNTER -lt $MAX_RETRY ]; do + sleep $DELAY + infoln "Attempting to Query peer0.org${ORG}, Retry after $DELAY seconds." + set -x + peer chaincode query -C $CHANNEL_NAME -n ${CC_NAME} -c '{"Args":["queryAllCars"]}' >&log.txt + res=$? + { set +x; } 2>/dev/null + let rc=$res + COUNTER=$(expr $COUNTER + 1) + done + cat log.txt + if test $rc -eq 0; then + successln "Query successful on peer0.org${ORG} on channel '$CHANNEL_NAME'" + else + fatalln "After $MAX_RETRY attempts, Query result on peer0.org${ORG} is INVALID!" + fi +} + +buildDockerImages() { + # if set don't build - useful when you want to debug yourself + if [ "$CCAAS_DOCKER_RUN" = "true" ]; then + # build the docker container + infoln "Building Chaincode-as-a-Service docker image '${CC_NAME}' '${CC_SRC_PATH}'" + infoln "This may take several minutes..." + set -x + ${CONTAINER_CLI} build -f $CC_SRC_PATH/Dockerfile -t ${CC_NAME}_ccaas_image:latest --build-arg CC_SERVER_PORT=${CCAAS_SERVER_PORT} $CC_SRC_PATH >&log.txt + res=$? + { set +x; } 2>/dev/null + cat log.txt + verifyResult $res "Docker build of chaincode-as-a-service container failed" + successln "Docker image '${CC_NAME}_ccaas_image:latest' built succesfully" + else + infoln "Not building docker image; this the command we would have run" + infoln " ${CONTAINER_CLI} build -f $CC_SRC_PATH/Dockerfile -t ${CC_NAME}_ccaas_image:latest --build-arg CC_SERVER_PORT=${CCAAS_SERVER_PORT} $CC_SRC_PATH" + fi +} + +startDockerContainer() { + # start the docker container + if [ "$CCAAS_DOCKER_RUN" = "true" ]; then + WORKDIR_CC=/go/src/github.com/goledgerdev/cc-tools-demo + infoln "Starting the Chaincode-as-a-Service docker container..." + + if [ $ORG_QNTY -gt 1 ] ; then + setGlobals 1 + set -x + ${CONTAINER_CLI} rm -f ${CC_NAME}.org1.example.com + ${CONTAINER_CLI} run -d --name ${CC_NAME}.org1.example.com \ + --network cc-tools-demo-net \ + -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:9999 \ + -e CHAINCODE_ID=$PACKAGE_ID -e CORE_CHAINCODE_ID_NAME=$PACKAGE_ID \ + -e RUN_CCAAS=true -e TLS_ENABLED=$CCAAS_TLS_ENABLED \ + -e KEY_PATH=certs/server/key.pem -e CERT_PATH=certs/server/cert.pem \ + -e CA_CERT_PATH=certs/ca/cert.pem \ + -v ${CCAAS_CERTS_PATH}:$WORKDIR_CC/certs \ + ${CC_NAME}_ccaas_image:latest + res=$? + { set +x; } 2>/dev/null + + setGlobals 2 + set -x + ${CONTAINER_CLI} rm -f ${CC_NAME}.org2.example.com + ${CONTAINER_CLI} run -d --name ${CC_NAME}.org2.example.com \ + --network cc-tools-demo-net \ + -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:9998 \ + -e CHAINCODE_ID=$PACKAGE_ID -e CORE_CHAINCODE_ID_NAME=$PACKAGE_ID \ + -e RUN_CCAAS=true -e TLS_ENABLED=$CCAAS_TLS_ENABLED \ + -e KEY_PATH=certs/server/key.pem -e CERT_PATH=certs/server/cert.pem \ + -e CA_CERT_PATH=certs/ca/cert.pem \ + -v ${CCAAS_CERTS_PATH}:$WORKDIR_CC/certs \ + ${CC_NAME}_ccaas_image:latest + res=$? + { set +x; } 2>/dev/null + + setGlobals 3 + set -x + ${CONTAINER_CLI} rm -f ${CC_NAME}.org3.example.com + ${CONTAINER_CLI} run -d --name ${CC_NAME}.org3.example.com \ + --network cc-tools-demo-net \ + -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:9997 \ + -e CHAINCODE_ID=$PACKAGE_ID -e CORE_CHAINCODE_ID_NAME=$PACKAGE_ID \ + -e RUN_CCAAS=true -e TLS_ENABLED=$CCAAS_TLS_ENABLED \ + -e KEY_PATH=certs/server/key.pem -e CERT_PATH=certs/server/cert.pem \ + -e CA_CERT_PATH=certs/ca/cert.pem \ + -v ${CCAAS_CERTS_PATH}:$WORKDIR_CC/certs \ + ${CC_NAME}_ccaas_image:latest + + res=$? + { set +x; } 2>/dev/null + else + setGlobals 0 + set -x + ${CONTAINER_CLI} rm -f ${CC_NAME}.org.example.com + ${CONTAINER_CLI} run -d --name ${CC_NAME}.org.example.com \ + --network cc-tools-demo-net \ + -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:${CCAAS_SERVER_PORT} \ + -e CHAINCODE_ID=$PACKAGE_ID -e CORE_CHAINCODE_ID_NAME=$PACKAGE_ID \ + -e RUN_CCAAS=true -e TLS_ENABLED=$CCAAS_TLS_ENABLED \ + -e KEY_PATH=certs/server/key.pem -e CERT_PATH=certs/server/cert.pem \ + -e CA_CERT_PATH=certs/ca/cert.pem \ + -v ${CCAAS_CERTS_PATH}:$WORKDIR_CC/certs \ + ${CC_NAME}_ccaas_image:latest + res=$? + { set +x; } 2>/dev/null + fi + + cat log.txt + verifyResult $res "Failed to start the container container '${CC_NAME}_ccaas_image:latest' " + successln "Docker container started succesfully '${CC_NAME}_ccaas_image:latest'" + else + infoln "Not starting docker containers; these are the commands we would have run" + if [ $ORG_QNTY -gt 1 ] ; then + infoln " ${CONTAINER_CLI} run --rm -d --name peer0.org1_${CC_NAME}_ccaas \ + --network cc-tools-demo-net \ + -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:${CCAAS_SERVER_PORT} \ + -e CHAINCODE_ID=$PACKAGE_ID -e CORE_CHAINCODE_ID_NAME=$PACKAGE_ID \ + -e RUN_CCAAS=true \ + ${CC_NAME}_ccaas_image:latest" + infoln " ${CONTAINER_CLI} run --rm -d --name peer0.org2_${CC_NAME}_ccaas \ + --network cc-tools-demo-net \ + -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:${CCAAS_SERVER_PORT} \ + -e CHAINCODE_ID=$PACKAGE_ID -e CORE_CHAINCODE_ID_NAME=$PACKAGE_ID \ + -e RUN_CCAAS=true \ + ${CC_NAME}_ccaas_image:latest" + + infoln " ${CONTAINER_CLI} run --rm -d --name peer0.org3_${CC_NAME}_ccaas \ + --network cc-tools-demo-net \ + -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:${CCAAS_SERVER_PORT} \ + -e CHAINCODE_ID=$PACKAGE_ID -e CORE_CHAINCODE_ID_NAME=$PACKAGE_ID \ + -e RUN_CCAAS=true \ + ${CC_NAME}_ccaas_image:latest" + else + infoln " ${CONTAINER_CLI} run --rm -d --name peer0.org_${CC_NAME}_ccaas \ + --network cc-tools-demo-net \ + -e CHAINCODE_SERVER_ADDRESS=0.0.0.0:${CCAAS_SERVER_PORT} \ + -e CHAINCODE_ID=$PACKAGE_ID -e CORE_CHAINCODE_ID_NAME=$PACKAGE_ID \ + -e RUN_CCAAS=true \ + ${CC_NAME}_ccaas_image:latest" + fi + fi +} \ No newline at end of file diff --git a/fabric/scripts/deployCCAAS.sh b/fabric/scripts/deployCCAAS.sh new file mode 100755 index 0000000..017ce39 --- /dev/null +++ b/fabric/scripts/deployCCAAS.sh @@ -0,0 +1,205 @@ +#!/bin/bash + +source scripts/utils.sh + +CHANNEL_NAME=${1:-"mychannel"} +CC_NAME=${2} +CC_SRC_PATH=${3} +CCAAS_DOCKER_RUN=${4:-"true"} +CC_VERSION=${5:-"1.0"} +CC_SEQUENCE=${6:-"1"} +CC_INIT_FCN=${7:-"NA"} +CC_END_POLICY=${8:-"NA"} +CC_COLL_CONFIG=${9:-"NA"} +DELAY=${10:-"3"} +MAX_RETRY=${11:-"5"} +VERBOSE=${12:-"false"} +ORG_QNTY=${13:-3} +CCAAS_TLS_ENABLED=${14:-"false"} + +CCAAS_SERVER_PORT=9999 + +: ${CONTAINER_CLI:="docker"} +: ${CONTAINER_CLI_COMPOSE:="${CONTAINER_CLI}-compose"} +infoln "Using ${CONTAINER_CLI} and ${CONTAINER_CLI_COMPOSE}" + +println "executing with the following" +println "- CHANNEL_NAME: ${C_GREEN}${CHANNEL_NAME}${C_RESET}" +println "- CC_NAME: ${C_GREEN}${CC_NAME}${C_RESET}" +println "- CC_SRC_PATH: ${C_GREEN}${CC_SRC_PATH}${C_RESET}" +println "- CC_VERSION: ${C_GREEN}${CC_VERSION}${C_RESET}" +println "- CC_SEQUENCE: ${C_GREEN}${CC_SEQUENCE}${C_RESET}" +println "- CC_END_POLICY: ${C_GREEN}${CC_END_POLICY}${C_RESET}" +println "- CC_COLL_CONFIG: ${C_GREEN}${CC_COLL_CONFIG}${C_RESET}" +println "- CC_INIT_FCN: ${C_GREEN}${CC_INIT_FCN}${C_RESET}" +println "- CCAAS_DOCKER_RUN: ${C_GREEN}${CCAAS_DOCKER_RUN}${C_RESET}" +println "- DELAY: ${C_GREEN}${DELAY}${C_RESET}" +println "- MAX_RETRY: ${C_GREEN}${MAX_RETRY}${C_RESET}" +println "- VERBOSE: ${C_GREEN}${VERBOSE}${C_RESET}" +println "- ORG_QUANTITY: ${C_GREEN}${ORG_QNTY}${C_RESET}" +println "- CCAAS_TLS_ENABLED: ${C_GREEN}${CCAAS_TLS_ENABLED}${C_RESET}" + +FABRIC_CFG_PATH=$PWD/./config/ + +#User has not provided a name +if [ -z "$CC_NAME" ] || [ "$CC_NAME" = "NA" ]; then + fatalln "No chaincode name was provided. Valid call example: ./network.sh deployCCAS -ccn basic -ccp ../asset-transfer-basic/chaincode-go " + +# User has not provided a path +elif [ -z "$CC_SRC_PATH" ] || [ "$CC_SRC_PATH" = "NA" ]; then + fatalln "No chaincode path was provided. Valid call example: ./network.sh deployCCAS -ccn basic -ccp ../asset-transfer-basic/chaincode-go " + +## Make sure that the path to the chaincode exists +elif [ ! -d "$CC_SRC_PATH" ]; then + fatalln "Path to chaincode does not exist. Please provide different path." +fi + +if [ "$CC_END_POLICY" = "NA" ]; then + CC_END_POLICY="" +else + CC_END_POLICY="--signature-policy $CC_END_POLICY" +fi + +if [ "$CC_COLL_CONFIG" = "NA" ]; then + CC_COLL_CONFIG="" +else + CC_COLL_CONFIG="--collections-config $CC_COLL_CONFIG" +fi + +# import utils +. scripts/envVar.sh +. scripts/ccutils.sh + +packageChaincode() { + address="${CC_NAME}.{{.org}}.example.com:{{.port}}" + prefix=$(basename "$0") + tempdir=$(mktemp -d -t "$prefix.XXXXXXXX") || error_exit "Error creating temporary directory" + label=${CC_NAME}_${CC_VERSION} + mkdir -p "$tempdir/src" + +cat > "$tempdir/src/connection.json" < "$tempdir/pkg/metadata.json" +{ + "type": "external", + "label": "$label" +} +METADATA-EOF + + tar -C "$tempdir/src" -czf "$tempdir/pkg/code.tar.gz" . + tar -C "$tempdir/pkg" -czf "${CC_NAME}.tar.gz" metadata.json code.tar.gz + rm -Rf "$tempdir" + + export PACKAGE_ID=$(peer lifecycle chaincode calculatepackageid ${CC_NAME}.tar.gz) + + successln "Chaincode is packaged ${address}, id ${PACKAGE_ID}" +} + +# Build the docker image +buildDockerImages + +# Package chaincode +packageChaincode + +# start the container +startDockerContainer + +if [ $ORG_QNTY -gt 1 ] ; then + ## Install chaincode on peer0.org1 and peer0.org2 + infoln "Installing chaincode on peer0.org1..." + installChaincode 1 + + infoln "Install chaincode on peer0.org2..." + installChaincode 2 + + infoln "Install chaincode on peer0.org3..." + installChaincode 3 + + ## query whether the chaincode is installed + queryInstalled 1 + queryInstalled 2 + queryInstalled 3 + + ## approve the definition for org1 + approveForMyOrg 1 + + ## check whether the chaincode definition is ready to be committed + ## expect org1 to have approved and org2 not to + checkCommitReadiness 1 "\"org1MSP\": true" "\"org2MSP\": false" "\"org3MSP\": false" + checkCommitReadiness 2 "\"org1MSP\": true" "\"org2MSP\": false" "\"org3MSP\": false" + checkCommitReadiness 3 "\"org1MSP\": true" "\"org2MSP\": false" "\"org3MSP\": false" + + ## now approve also for org2 + approveForMyOrg 2 + + ## check whether the chaincode definition is ready to be committed + ## expect them both to have approved + checkCommitReadiness 1 "\"org1MSP\": true" "\"org2MSP\": true" "\"org3MSP\": false" + checkCommitReadiness 2 "\"org1MSP\": true" "\"org2MSP\": true" "\"org3MSP\": false" + checkCommitReadiness 3 "\"org1MSP\": true" "\"org2MSP\": true" "\"org3MSP\": false" + + ## now approve also for org3 + approveForMyOrg 3 + + ## check whether the chaincode definition is ready to be committed + ## expect them both to have approved + checkCommitReadiness 1 "\"org1MSP\": true" "\"org2MSP\": true" "\"org3MSP\": true" + checkCommitReadiness 2 "\"org1MSP\": true" "\"org2MSP\": true" "\"org3MSP\": true" + checkCommitReadiness 3 "\"org1MSP\": true" "\"org2MSP\": true" "\"org3MSP\": true" + + ## now that we know for sure both orgs have approved, commit the definition + commitChaincodeDefinition 1 2 3 + + ## query on both orgs to see that the definition committed successfully + queryCommitted 1 + queryCommitted 2 + queryCommitted 3 + + ## Invoke the chaincode - this does require that the chaincode have the 'initLedger' + ## method defined + if [ "$CC_INIT_FCN" = "NA" ]; then + infoln "Chaincode initialization is not required" + else + chaincodeInvokeInit 1 2 3 + fi +else + ## Install chaincode on peer0.org + infoln "Installing chaincode on peer0.org..." + installChaincode 0 + + ## query whether the chaincode is installed + queryInstalled 0 + + ## approve the definition for org + approveForMyOrg 0 + + ## check whether the chaincode definition is ready to be committed + checkCommitReadiness 0 "\"orgMSP\": true" + + ## now that we know for sure org have approved, commit the definition + commitChaincodeDefinition 0 + + ## query on both orgs to see that the definition committed successfully + queryCommitted 0 + + ## Invoke the chaincode - this does require that the chaincode have the 'initLedger' + ## method defined + if [ "$CC_INIT_FCN" = "NA" ]; then + infoln "Chaincode initialization is not required" + else + chaincodeInvokeInit 0 + fi +fi + +exit 0 diff --git a/fabric/scripts/envVar.sh b/fabric/scripts/envVar.sh index bab2fab..45384d4 100755 --- a/fabric/scripts/envVar.sh +++ b/fabric/scripts/envVar.sh @@ -33,21 +33,25 @@ setGlobals() { export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp export CORE_PEER_ADDRESS=localhost:7051 + export CCAAS_CERTS_PATH=${PWD}/organizations/ccaas/org1.example.com elif [ $USING_ORG -eq 2 ]; then export CORE_PEER_LOCALMSPID="org2MSP" export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp export CORE_PEER_ADDRESS=localhost:8051 + export CCAAS_CERTS_PATH=${PWD}/organizations/ccaas/org2.example.com elif [ $USING_ORG -eq 3 ]; then export CORE_PEER_LOCALMSPID="org3MSP" export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG3_CA export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp export CORE_PEER_ADDRESS=localhost:9051 + export CCAAS_CERTS_PATH=${PWD}/organizations/ccaas/org3.example.com elif [ $USING_ORG -eq 0 ]; then export CORE_PEER_LOCALMSPID="orgMSP" export CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG_CA export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org.example.com/users/Admin@org.example.com/msp export CORE_PEER_ADDRESS=localhost:7051 + export CCAAS_CERTS_PATH=${PWD}/organizations/ccaas/org.example.com else errorln "ORG Unknown" fi @@ -113,9 +117,3 @@ parsePeerConnectionParameters() { # remove leading space for output PEERS="$(echo -e "$PEERS" | sed -e 's/^[[:space:]]*//')" } - -verifyResult() { - if [ $1 -ne 0 ]; then - fatalln "$2" - fi -} diff --git a/fabric/scripts/utils.sh b/fabric/scripts/utils.sh index 66edf4c..f9040e1 100755 --- a/fabric/scripts/utils.sh +++ b/fabric/scripts/utils.sh @@ -169,6 +169,12 @@ function fatalln() { exit 1 } +verifyResult() { + if [ $1 -ne 0 ]; then + fatalln "$2" + fi +} + export -f errorln export -f successln export -f infoln diff --git a/fabric/startDev.sh b/fabric/startDev.sh index 0cd02a4..869a4af 100755 --- a/fabric/startDev.sh +++ b/fabric/startDev.sh @@ -1,12 +1,26 @@ #!/usr/bin/env bash ORG_QNTY=3 +DEPLOY_CCAAS=false +CCAAS_TLS_ENABLED="" -while getopts n: opt; do - case $opt in - n) ORG_QNTY=${OPTARG} +while [[ $# -ge 1 ]] ; do + key="$1" + case $key in + -n ) + ORG_QNTY=$2 + shift ;; - esac + -ccaas ) + DEPLOY_CCAAS=$2 + shift + ;; + -ccaastls ) + CCAAS_TLS_ENABLED="-ccaastls" + shift + ;; + esac + shift done if [ $ORG_QNTY != 3 -a $ORG_QNTY != 1 ] @@ -23,7 +37,6 @@ rm -rf organizations/peerOrganizations rm -rf organizations/ordererOrganizations rm -rf organizations/rest-certs - download_binaries(){ echo "Preparing to download fabric binaries..." curl -sSLO https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh && chmod +x install-fabric.sh @@ -75,5 +88,10 @@ else fi docker network create cc-tools-demo-net -./network.sh up createChannel -n $ORG_QNTY -./network.sh deployCC -ccn cc-tools-demo -ccp ../chaincode -ccl go -n $ORG_QNTY -cccg $CCCG_PATH \ No newline at end of file +./network.sh up createChannel -n $ORG_QNTY $CCAAS_TLS_ENABLED + +if [ "$DEPLOY_CCAAS" = "false" ]; then + ./network.sh deployCC -ccn cc-tools-demo -ccp ../chaincode -ccl go -n $ORG_QNTY -cccg $CCCG_PATH +else + ./network.sh deployCCAAS -ccn cc-tools-demo -ccp ../chaincode -n $ORG_QNTY -cccg $CCCG_PATH $CCAAS_TLS_ENABLED +fi diff --git a/startDev.sh b/startDev.sh index b079eba..bda050a 100755 --- a/startDev.sh +++ b/startDev.sh @@ -1,15 +1,30 @@ #!/usr/bin/env bash ORG_QNTY=3 +DEPLOY_CCAAS=false +CCAAS_TLS_ENABLEd="" SKIP_COLL_GEN=false -while getopts n:c opt; do - case $opt in - n) ORG_QNTY=${OPTARG} +while [[ $# -ge 1 ]] ; do + key="$1" + case $key in + -n ) + ORG_QNTY=$2 + shift ;; - c) SKIP_COLL_GEN=true + -ccaas ) + DEPLOY_CCAAS=$2 + shift ;; - esac + -ccaastls ) + CCAAS_TLS_ENABLED="-ccaastls" + shift + ;; + -c ) + SKIP_COLL_GEN=true + ;; + esac + shift done if [ $ORG_QNTY != 3 -a $ORG_QNTY != 1 ] @@ -38,7 +53,7 @@ if [ ! -d "chaincode/vendor" ]; then cd ./chaincode; GOWORK=off go mod vendor; cd .. fi cd ./chaincode; go fmt ./...; cd .. -cd ./fabric; ./startDev.sh -n $ORG_QNTY; cd .. +cd ./fabric; ./startDev.sh -n $ORG_QNTY -ccaas $DEPLOY_CCAAS $CCAAS_TLS_ENABLED; cd .. ## This brings up API in Go if [ $ORG_QNTY == 1 ] From e43c5b9514d00d961c872a5b9d5f86c09e44b679 Mon Sep 17 00:00:00 2001 From: Samuel Venzi Date: Wed, 10 Jul 2024 16:29:51 -0300 Subject: [PATCH 7/9] Add ccaas to upgradeCC Signed-off-by: Samuel Venzi --- upgradeCC.sh | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/upgradeCC.sh b/upgradeCC.sh index 37716e5..d6b82e6 100755 --- a/upgradeCC.sh +++ b/upgradeCC.sh @@ -1,21 +1,34 @@ #!/usr/bin/env bash -if [[ $# -lt 2 || $# -gt 4 ]]; then - printf 'Usage: ./upgradeCC.sh [-n ]\n' +if [[ $# -lt 2 || $# -gt 6 ]]; then + printf 'Usage: ./upgradeCC.sh [-n ] [-ccaas ]\n' exit 1 fi ORG_QNTY=3 +DEPLOY_CCAAS=false SKIP_COLL_GEN=false +version=$1 +sequence=$2 + OPTIND=3 -while getopts n:c opt; do - case $opt in - n) ORG_QNTY=${OPTARG} +while [[ $# -ge 1 ]] ; do + key="$1" + case $key in + -n ) + ORG_QNTY=$2 + shift + ;; + -ccaas ) + DEPLOY_CCAAS=$2 + shift ;; - c) SKIP_COLL_GEN=true + -c ) + SKIP_COLL_GEN=true ;; - esac + esac + shift done if [ $ORG_QNTY != 3 -a $ORG_QNTY != 1 ] @@ -39,9 +52,10 @@ CCCG_PATH="../chaincode/collections.json" cd ./chaincode; go fmt ./...; cd .. -version=$1 -sequence=$2 - cd fabric -./network.sh deployCC -ccn cc-tools-demo -ccp ../chaincode -ccl go -ccv $version -ccs $sequence -n $ORG_QNTY -cccg $CCCG_PATH -cci init +if [ "$DEPLOY_CCAAS" = "false" ]; then + ./network.sh deployCC -ccn cc-tools-demo -ccp ../chaincode -ccl go -ccv $version -ccs $sequence -n $ORG_QNTY -cccg $CCCG_PATH -cci init +else + ./network.sh deployCCAAS -ccn cc-tools-demo -ccp ../chaincode -ccv $version -ccs $sequence -n $ORG_QNTY -cccg $CCCG_PATH +fi cd .. From d5ddd7c2452ef1dd1b500fe149db4fe8d54fa074 Mon Sep 17 00:00:00 2001 From: Samuel Venzi Date: Wed, 10 Jul 2024 16:31:07 -0300 Subject: [PATCH 8/9] Update README with ccaas Signed-off-by: Samuel Venzi --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index a7865db..6a3b0ce 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,17 @@ To apply chaincode changes, run `$ ./upgradeCC.sh ` with a v To apply CC API changes, run `$ ./reloadCCAPI.sh`. +## Deploying Chaincode as a service + +After installing, use the script `./startDev.sh -ccaas` in the root folder to start the development environment. It will +start all components of the project with 3 organizations. + +If you want to deploy with 1 organization, run the command `./startDev.sh -ccaas -n 1`. + +To apply chaincode changes, run `$ ./upgradeCC.sh -ccaas ` with a version higher than the current one (starts with 0.1). Append `-n 1` to the command if running with 1 organization. + +To apply CC API changes, run `$ ./reloadCCAPI.sh`. + ## Automated tryout and test To test transactions after starting all components, run `$ ./tryout.sh`. From a737d024ca61739c828f7005a487290ae2a4addc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Macedo?= Date: Wed, 10 Jul 2024 16:41:46 -0300 Subject: [PATCH 9/9] Remove unecessary optind on script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: André Macedo --- upgradeCC.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/upgradeCC.sh b/upgradeCC.sh index d6b82e6..ffebed5 100755 --- a/upgradeCC.sh +++ b/upgradeCC.sh @@ -12,7 +12,6 @@ SKIP_COLL_GEN=false version=$1 sequence=$2 -OPTIND=3 while [[ $# -ge 1 ]] ; do key="$1" case $key in