From d15b94b0a3dd68f37f636aff1303e89339a66db3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Macedo?= Date: Wed, 20 Sep 2023 15:07:29 -0300 Subject: [PATCH] Automatic collection generation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: André Macedo --- .gitignore | 1 + README.md | 17 ++++++- chaincode/collections.json | 35 -------------- chaincode/collections2-org.json | 10 ---- chaincode/collections2.json | 10 ---- chaincode/generateCollections.go | 82 ++++++++++++++++++++++++++++++++ chaincode/main.go | 11 +++++ fabric/network.sh | 2 +- fabric/startDev.sh | 7 +-- generateCollection.sh | 25 ++++++++++ generateTar.sh | 31 +++++++++++- startDev.sh | 15 +++++- upgradeCC.sh | 27 +++++++---- 13 files changed, 199 insertions(+), 74 deletions(-) delete mode 100644 chaincode/collections.json delete mode 100644 chaincode/collections2-org.json delete mode 100644 chaincode/collections2.json create mode 100644 chaincode/generateCollections.go create mode 100755 generateCollection.sh diff --git a/.gitignore b/.gitignore index c7dc4f3..6317597 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ fabric/crypto-config fabric/channel-artifacts fabric/ca chaincode/vendor/* +chaincode/collections.json ccapi/vendor/* cc-tools-demo.tar.gz package-lock.json diff --git a/README.md b/README.md index f60f02c..e138e81 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ start all components of the project with 3 organizations. If you want to deploy with 1 organization, run the command `./startDev.sh -n 1`. -To apply chaincode changes, run `$ ./upgradeCC2.sh ` 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 chaincode changes, run `$ ./upgradeCC.sh ` 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`. @@ -44,10 +44,23 @@ To test transactions after starting all components, run `$ ./tryout.sh`. To test transactions using the godog tool, run `$ ./godog.sh`. + +## Generate TAR archive for the chaincode + +The `generateTar.sh` script is available to generate a `tar.gz` archive of the chaincode. + +By running `$ ./generateTar.sh` without any option, the script generates a `collections.json` file for the private data on the chaincode with all the organizations defined on the readers section of private asset types, and then archives the code without the CCAPI. + +By using the `--org/-o` option along the script, it's possible to specify the organizations to be considered when generating the `collections.json` file. This option may be used multiple times to add all the organizations, ex: `$ ./generateTar.sh -o org1MSP -o org2MSP`. + +To also archive the the CCAPI alongside the chaincode, the `--ccapi/-c` flag may be used. Example: `$ ./generateTar.sh -c`. + +By standard the archive is created using the project name with *1.0* label, to change it the `--name/-n` and `--label/-l` flags may be used. Example: `$ ./generateTar.sh -n my-project -l 2.0` + ## More You can reach GoLedger developers and `cc-tools` maintainers at our Discord - [Join us!](https://discord.gg/GndkYHxNyQ) More documentation and details on `cc-tools` can be found at [https://goledger-cc-tools.readthedocs.io/en/latest/](https://goledger-cc-tools.readthedocs.io/en/latest/) -For production deployment please consider using GoFabric - [https://gofabric.io](https://gofabric.io) +For production deployment please consider using GoFabric - [https://gofabric.io](https://gofabric.io) \ No newline at end of file diff --git a/chaincode/collections.json b/chaincode/collections.json deleted file mode 100644 index 2c10e34..0000000 --- a/chaincode/collections.json +++ /dev/null @@ -1,35 +0,0 @@ -[ - { - "name": "secret", - "requiredPeerCount": 0, - "maxPeerCount": 3, - "blockToLive": 1000000, - "memberOnlyRead": true, - "policy": { - "identities": [ - { - "role": { - "name": "member", - "mspId": "org2MSP" - } - }, - { - "role": { - "name": "member", - "mspId": "org3MSP" - } - } - ], - "policy": { - "1-of": [ - { - "signed-by": 0 - }, - { - "signed-by": 1 - } - ] - } - } - } -] \ No newline at end of file diff --git a/chaincode/collections2-org.json b/chaincode/collections2-org.json deleted file mode 100644 index 690ffba..0000000 --- a/chaincode/collections2-org.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "name": "secret", - "requiredPeerCount": 0, - "maxPeerCount": 3, - "blockToLive": 1000000, - "memberOnlyRead": true, - "policy": "OR('orgMSP.member')" - } -] \ No newline at end of file diff --git a/chaincode/collections2.json b/chaincode/collections2.json deleted file mode 100644 index 49cc2a0..0000000 --- a/chaincode/collections2.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "name": "secret", - "requiredPeerCount": 0, - "maxPeerCount": 3, - "blockToLive": 1000000, - "memberOnlyRead": true, - "policy": "OR('org2MSP.member', 'org3MSP.member')" - } -] \ No newline at end of file diff --git a/chaincode/generateCollections.go b/chaincode/generateCollections.go new file mode 100644 index 0000000..81e1d85 --- /dev/null +++ b/chaincode/generateCollections.go @@ -0,0 +1,82 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" +) + +type ArrayFlags []string + +func (i *ArrayFlags) String() string { + return "my string representation" +} + +func (i *ArrayFlags) Set(value string) error { + *i = append(*i, value) + return nil +} + +type CollectionElem struct { + Name string `json:"name"` + RequiredPeerCount int `json:"requiredPeerCount"` + MaxPeerCount int `json:"maxPeerCount"` + BlockToLive int `json:"blockToLive"` + MemberOnlyRead bool `json:"memberOnlyRead"` + Policy string `json:"policy"` +} + +func generateCollection(orgs ArrayFlags) { + collection := []CollectionElem{} + + for _, a := range assetTypeList { + if len(a.Readers) > 0 { + elem := CollectionElem{ + Name: a.Tag, + RequiredPeerCount: 0, + MaxPeerCount: 3, + BlockToLive: 1000000, + MemberOnlyRead: true, + Policy: generatePolicy(a.Readers, orgs), + } + collection = append(collection, elem) + } + } + + b, err := json.MarshalIndent(collection, "", " ") + if err != nil { + fmt.Println(err) + return + } + err = ioutil.WriteFile("collections.json", b, 0644) + if err != nil { + fmt.Println(err) + return + } +} + +func generatePolicy(readers []string, orgs ArrayFlags) string { + firstElem := true + policy := "OR(" + for _, r := range readers { + if len(orgs) > 0 { + found := false + for _, o := range orgs { + if r == o { + found = true + break + } + } + if !found { + continue + } + } + if !firstElem { + policy += ", " + } + policy += fmt.Sprintf("'%s.member'", r) + firstElem = false + } + policy += ")" + return policy +} diff --git a/chaincode/main.go b/chaincode/main.go index b4a6eb5..a904da9 100644 --- a/chaincode/main.go +++ b/chaincode/main.go @@ -1,6 +1,7 @@ package main import ( + "flag" "fmt" "log" "time" @@ -45,6 +46,16 @@ func SetupCC() error { // main function starts up the chaincode in the container during instantiate func main() { + // Generate collection json + genFlag := flag.Bool("g", false, "Enable collection generation") + flag.Bool("orgs", false, "List of orgs to generate collection for") + flag.Parse() + if *genFlag { + listOrgs := flag.Args() + generateCollection(listOrgs) + return + } + log.Printf("Starting chaincode %s version %s\n", header.Name, header.Version) err := SetupCC() diff --git a/fabric/network.sh b/fabric/network.sh index a7d28cd..c6cfe91 100755 --- a/fabric/network.sh +++ b/fabric/network.sh @@ -460,7 +460,7 @@ CC_SRC_PATH="NA" # endorsement policy defaults to "NA". This would allow chaincodes to use the majority default policy. CC_END_POLICY="NA" # collection configuration defaults to "NA" -CC_COLL_CONFIG="../chaincode/collections2.json" +CC_COLL_CONFIG="../chaincode/collections.json" # chaincode init function defaults to "NA" CC_INIT_FCN="NA" # use this as the default docker-compose yaml definition diff --git a/fabric/startDev.sh b/fabric/startDev.sh index 8bc3773..3014a4e 100755 --- a/fabric/startDev.sh +++ b/fabric/startDev.sh @@ -16,12 +16,7 @@ then ORG_QNTY=3 fi -if [ $ORG_QNTY == 1 ] -then - CCCG_PATH="../chaincode/collections2-org.json" -else - CCCG_PATH="../chaincode/collections2.json" -fi +CCCG_PATH="../chaincode/collections.json" ./network.sh down -n $ORG_QNTY rm -rf organizations/peerOrganizations diff --git a/generateCollection.sh b/generateCollection.sh new file mode 100755 index 0000000..79109fe --- /dev/null +++ b/generateCollection.sh @@ -0,0 +1,25 @@ +#!/usr/bin/bash + +while getopts "o:h" opt; do + case $opt in + o) orgs+=("$OPTARG");; + #... + h) + echo "Usage: ./generateCollection.sh [-o ]" + echo " -o: Include an organization in the collection configuration file" + echo " This option can be used multiple times to include multiple organizations" + echo " If no organizations are specified, the default is to include any organization found in the readers" + echo "" + echo "Example: ./generateCollection.sh -o org1MSP -o org2MSP -o org3MSP" + exit 0 + ;; + esac +done +shift $((OPTIND -1)) + +if [ ${#orgs[@]} -gt 0 ] +then + cd ./chaincode; go run . -g --orgs ${orgs[@]}; cd .. +else + cd ./chaincode; go run . -g; cd .. +fi \ No newline at end of file diff --git a/generateTar.sh b/generateTar.sh index cc95e60..c62899d 100755 --- a/generateTar.sh +++ b/generateTar.sh @@ -3,6 +3,7 @@ # Default values for the flags FLAG_CCAPI="none" FLAG_LABEL="1.0" +SKIP_COLL_GEN=false # You can change this if you want to avoid using the --name flag FLAG_NAME="cc-tools-demo" @@ -32,12 +33,29 @@ while [[ $# -gt 0 ]]; do exit 1 fi ;; + --org | -o) + if [[ $# -gt 1 ]]; then + orgs+=("$2") + shift 2 + else + echo "Error: --org flag requires a value." + exit 1 + fi + ;; + --skip | -s) + SKIP_COLL_GEN=true + shift 1 + ;; --help | -h) echo "Usage: ./generateTar.sh [--ccapi] [--label