├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── chaincode └── chaincode_example02 │ └── go │ └── chaincode_example02.go └── first-network ├── .env ├── .gitignore ├── README.md ├── base ├── docker-compose-base.yaml ├── kafka-base.yaml └── peer-base.yaml ├── byfn.sh ├── ccp-generate.sh ├── ccp-template.json ├── ccp-template.yaml ├── channel-artifacts └── .gitkeep ├── configtx.yaml ├── connection-org1.json ├── connection-org1.yaml ├── connection-org2.json ├── connection-org2.yaml ├── connection-org3.json ├── connection-org3.yaml ├── crypto-config.yaml ├── docker-compose-ca.yaml ├── docker-compose-cli.yaml ├── docker-compose-couch-org3.yaml ├── docker-compose-couch.yaml ├── docker-compose-e2e-template.yaml ├── docker-compose-etcdraft2.yaml ├── docker-compose-kafka.yaml ├── docker-compose-org3.yaml ├── eyfn.sh ├── org3-artifacts ├── configtx.yaml └── org3-crypto.yaml └── scripts ├── capabilities.json ├── script.sh ├── step1org3.sh ├── step2org3.sh ├── step3org3.sh ├── testorg3.sh ├── upgrade_to_v14.sh └── utils.sh /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | 3 | # Artifacts 4 | first-network/channel-artifacts/*.tx 5 | first-network/channel-artifacts/*.block 6 | 7 | crypto-config -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: requried 2 | 3 | services: 4 | - docker 5 | 6 | before_install: 7 | - docker -v 8 | - docker-compose -v 9 | 10 | install: 11 | - curl -sSL http://bit.ly/2ysbOFE | bash -s 12 | - docker images 13 | - ( cd bin && ./cryptogen version) 14 | 15 | script: 16 | - ls -l 17 | - cd first-network 18 | - ./byfn.sh up -o kafka 19 | 20 | after_script: 21 | - ./byfn.sh down -o kafka 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/keenkit/fabric-sample-with-kafka.svg?branch=master)](https://travis-ci.org/keenkit/fabric-sample-with-kafka) 2 | # fabric-sample-with-kafka 3 | 4 | ## Description 5 | The folder `first-nework` is copied from https://github.com/hyperledger/fabric-samples/tree/release-1.4 , different from verison 1.2 or before, the official `release-1.4` already contains `one zookeeper and one kafka` configuration inside. 6 | 7 | Thereby this repository does a little change to support `3 zookeepers and 4 kakfas`. 8 | 9 | Before drilling into this demo, please make sure you are very well understanding the offical Hyperledger Fabric 10 | ["Build Your First Network"](http://hyperledger-fabric.readthedocs.io/en/latest/build_network.html) tutorial. 11 | 12 | Basically, we will have 13 | >1 orderer, 4 peers, 1 CLI, 4 Kafkas, 3 Zookeepers in our fabric network. 14 | 15 | ## Fabric Version 16 | 1.4.4 17 | 18 | ## Bianary files version 19 | 1.4.4 20 | 21 | ## How to run it? 22 | 23 | #### 1. Get binaries & docker images 24 | Download the necessary binaries and docker images (You may skip it if you have done it before). 25 | 26 | Go to root folder, 27 | ```shell 28 | curl -sSL http://bit.ly/2ysbOFE | bash -s 29 | ``` 30 | After everything done you will have folder structure like: 31 | 32 | ``` 33 | fabric-sample-with-kafka$ tree 34 | . 35 | ├── bin 36 | │   ├── configtxgen 37 | │   ├── configtxlator 38 | │   ├── cryptogen 39 | │   ├── discover 40 | │   ├── fabric-ca-client 41 | │   ├── idemixgen 42 | │   ├── orderer 43 | │   └── peer 44 | ├── chaincode 45 | │   └── chaincode_example02 46 | ├── first-network 47 | │   ├── base 48 | ... 49 | ``` 50 | 51 | #### 3. Run E2E test. 52 | 53 | ```shell 54 | cd first-network 55 | 56 | # Start up network 57 | ./byfn.sh up -o kafka 58 | ``` 59 | 60 | You will see log like this if no exception: 61 | 62 | ```shell 63 | Starting for channel 'mychannel' with CLI timeout of '10' seconds and CLI delay of '3' seconds 64 | Continue? [Y/n] 65 | proceeding ... 66 | LOCAL_VERSION=1.4.4 67 | DOCKER_IMAGE_VERSION=1.4.4 68 | /home/will/Documents/blockchain/fabric-sample-with-kafka/first-network/../bin/cryptogen 69 | 70 | ########################################################## 71 | ##### Generate certificates using cryptogen tool ######### 72 | ########################################################## 73 | + cryptogen generate --config=./crypto-config.yaml 74 | org1.example.com 75 | org2.example.com 76 | + res=0 77 | + set +x 78 | ......... 79 | ......... 80 | 81 | 90 82 | ===================== Query successful on peer1.org2 on channel 'mychannel' ===================== 83 | 84 | ========= All GOOD, BYFN execution completed =========== 85 | 86 | 87 | _____ _ _ ____ 88 | | ____| | \ | | | _ \ 89 | | _| | \| | | | | | 90 | | |___ | |\ | | |_| | 91 | |_____| |_| \_| |____/ 92 | ``` 93 | 94 | #### 4. Bring down the network 95 | 96 | ```shell 97 | ./byfn.sh down -o kafka 98 | ``` 99 | ## What's behind the code change? 100 | 101 | #### 1. Change first-network/configtx.yaml 102 | 103 | Make sure change the SampleDevModeKafka content... 104 | 105 | ```yaml 106 | SampleDevModeKafka: 107 | <<: *ChannelDefaults 108 | Capabilities: 109 | <<: *ChannelCapabilities 110 | Orderer: 111 | <<: *OrdererDefaults 112 | OrdererType: kafka 113 | Kafka: 114 | Brokers: 115 | - kafka0.example.com:9092 116 | - kafka1.example.com:9092 117 | - kafka2.example.com:9092 118 | - kafka3.example.com:9092 119 | ``` 120 | 121 | #### 2. Add first-network/base/kafka-base.yaml 122 | 123 | It is just a kafka/zookeeper base yaml files to be referenced. 124 | 125 | #### 3. Change first-network/docker-compose-kafka.yaml 126 | 127 | Modify and add more zookeepers & kafka nodes 128 | 129 | ## Issues 130 | 1. Make sure you have the **RIGHT** version binaries as well as fabric image versions. 131 | In this case it is **1.4.4** 132 | 133 | 2. Make sure the **1.4.4** fabric images are marked as Latest. 134 | 135 | ``` 136 | hyperledger/fabric-ccenv 1.4.4 ca4780293e4c 8 weeks ago 1.37GB 137 | hyperledger/fabric-ccenv latest ca4780293e4c 8 weeks ago 1.37GB 138 | ``` 139 | 3. For previous version, please check 140 | 141 | - 1.2.0 https://github.com/keenkit/fabric-sample-with-kafka/tree/release-1.2.0 142 | - 1.0.6 https://github.com/keenkit/fabric-sample-with-kafka/tree/release-1.0.6 143 | -------------------------------------------------------------------------------- /chaincode/chaincode_example02/go/chaincode_example02.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright IBM Corp. 2016 All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | //WARNING - this chaincode's ID is hard-coded in chaincode_example04 to illustrate one way of 20 | //calling chaincode from a chaincode. If this example is modified, chaincode_example04.go has 21 | //to be modified as well with the new ID of chaincode_example02. 22 | //chaincode_example05 show's how chaincode ID can be passed in as a parameter instead of 23 | //hard-coding. 24 | 25 | import ( 26 | "fmt" 27 | "strconv" 28 | 29 | "github.com/hyperledger/fabric/core/chaincode/shim" 30 | pb "github.com/hyperledger/fabric/protos/peer" 31 | ) 32 | 33 | // SimpleChaincode example simple Chaincode implementation 34 | type SimpleChaincode struct { 35 | } 36 | 37 | func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { 38 | fmt.Println("ex02 Init") 39 | _, args := stub.GetFunctionAndParameters() 40 | var A, B string // Entities 41 | var Aval, Bval int // Asset holdings 42 | var err error 43 | 44 | if len(args) != 4 { 45 | return shim.Error("Incorrect number of arguments. Expecting 4") 46 | } 47 | 48 | // Initialize the chaincode 49 | A = args[0] 50 | Aval, err = strconv.Atoi(args[1]) 51 | if err != nil { 52 | return shim.Error("Expecting integer value for asset holding") 53 | } 54 | B = args[2] 55 | Bval, err = strconv.Atoi(args[3]) 56 | if err != nil { 57 | return shim.Error("Expecting integer value for asset holding") 58 | } 59 | fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) 60 | 61 | // Write the state to the ledger 62 | err = stub.PutState(A, []byte(strconv.Itoa(Aval))) 63 | if err != nil { 64 | return shim.Error(err.Error()) 65 | } 66 | 67 | err = stub.PutState(B, []byte(strconv.Itoa(Bval))) 68 | if err != nil { 69 | return shim.Error(err.Error()) 70 | } 71 | 72 | return shim.Success(nil) 73 | } 74 | 75 | func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { 76 | fmt.Println("ex02 Invoke") 77 | function, args := stub.GetFunctionAndParameters() 78 | if function == "invoke" { 79 | // Make payment of X units from A to B 80 | return t.invoke(stub, args) 81 | } else if function == "delete" { 82 | // Deletes an entity from its state 83 | return t.delete(stub, args) 84 | } else if function == "query" { 85 | // the old "Query" is now implemtned in invoke 86 | return t.query(stub, args) 87 | } 88 | 89 | return shim.Error("Invalid invoke function name. Expecting \"invoke\" \"delete\" \"query\"") 90 | } 91 | 92 | // Transaction makes payment of X units from A to B 93 | func (t *SimpleChaincode) invoke(stub shim.ChaincodeStubInterface, args []string) pb.Response { 94 | var A, B string // Entities 95 | var Aval, Bval int // Asset holdings 96 | var X int // Transaction value 97 | var err error 98 | 99 | if len(args) != 3 { 100 | return shim.Error("Incorrect number of arguments. Expecting 3") 101 | } 102 | 103 | A = args[0] 104 | B = args[1] 105 | 106 | // Get the state from the ledger 107 | // TODO: will be nice to have a GetAllState call to ledger 108 | Avalbytes, err := stub.GetState(A) 109 | if err != nil { 110 | return shim.Error("Failed to get state") 111 | } 112 | if Avalbytes == nil { 113 | return shim.Error("Entity not found") 114 | } 115 | Aval, _ = strconv.Atoi(string(Avalbytes)) 116 | 117 | Bvalbytes, err := stub.GetState(B) 118 | if err != nil { 119 | return shim.Error("Failed to get state") 120 | } 121 | if Bvalbytes == nil { 122 | return shim.Error("Entity not found") 123 | } 124 | Bval, _ = strconv.Atoi(string(Bvalbytes)) 125 | 126 | // Perform the execution 127 | X, err = strconv.Atoi(args[2]) 128 | if err != nil { 129 | return shim.Error("Invalid transaction amount, expecting a integer value") 130 | } 131 | Aval = Aval - X 132 | Bval = Bval + X 133 | fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) 134 | 135 | // Write the state back to the ledger 136 | err = stub.PutState(A, []byte(strconv.Itoa(Aval))) 137 | if err != nil { 138 | return shim.Error(err.Error()) 139 | } 140 | 141 | err = stub.PutState(B, []byte(strconv.Itoa(Bval))) 142 | if err != nil { 143 | return shim.Error(err.Error()) 144 | } 145 | 146 | return shim.Success(nil) 147 | } 148 | 149 | // Deletes an entity from state 150 | func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response { 151 | if len(args) != 1 { 152 | return shim.Error("Incorrect number of arguments. Expecting 1") 153 | } 154 | 155 | A := args[0] 156 | 157 | // Delete the key from the state in ledger 158 | err := stub.DelState(A) 159 | if err != nil { 160 | return shim.Error("Failed to delete state") 161 | } 162 | 163 | return shim.Success(nil) 164 | } 165 | 166 | // query callback representing the query of a chaincode 167 | func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response { 168 | var A string // Entities 169 | var err error 170 | 171 | if len(args) != 1 { 172 | return shim.Error("Incorrect number of arguments. Expecting name of the person to query") 173 | } 174 | 175 | A = args[0] 176 | 177 | // Get the state from the ledger 178 | Avalbytes, err := stub.GetState(A) 179 | if err != nil { 180 | jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}" 181 | return shim.Error(jsonResp) 182 | } 183 | 184 | if Avalbytes == nil { 185 | jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}" 186 | return shim.Error(jsonResp) 187 | } 188 | 189 | jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}" 190 | fmt.Printf("Query Response:%s\n", jsonResp) 191 | return shim.Success(Avalbytes) 192 | } 193 | 194 | func main() { 195 | err := shim.Start(new(SimpleChaincode)) 196 | if err != nil { 197 | fmt.Printf("Error starting Simple chaincode: %s", err) 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /first-network/.env: -------------------------------------------------------------------------------- 1 | COMPOSE_PROJECT_NAME=net 2 | IMAGE_TAG=latest 3 | SYS_CHANNEL=byfn-sys-channel 4 | -------------------------------------------------------------------------------- /first-network/.gitignore: -------------------------------------------------------------------------------- 1 | /channel-artifacts/*.tx 2 | /channel-artifacts/*.block 3 | /crypto-config/* 4 | /docker-compose-e2e.yaml 5 | /ledgers 6 | /ledgers-backup 7 | /channel-artifacts/*.json 8 | /org3-artifacts/crypto-config/* -------------------------------------------------------------------------------- /first-network/README.md: -------------------------------------------------------------------------------- 1 | ## Build Your First Network (BYFN) 2 | 3 | The directions for using this are documented in the Hyperledger Fabric 4 | ["Build Your First Network"](http://hyperledger-fabric.readthedocs.io/en/latest/build_network.html) tutorial. 5 | 6 | *NOTE:* After navigating to the documentation, choose the documentation version that matches your version of Fabric 7 | 8 | -------------------------------------------------------------------------------- /first-network/base/docker-compose-base.yaml: -------------------------------------------------------------------------------- 1 | # Copyright IBM Corp. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | 6 | version: '2' 7 | 8 | services: 9 | 10 | orderer.example.com: 11 | container_name: orderer.example.com 12 | extends: 13 | file: peer-base.yaml 14 | service: orderer-base 15 | volumes: 16 | - ../channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block 17 | - ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp 18 | - ../crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls 19 | - orderer.example.com:/var/hyperledger/production/orderer 20 | ports: 21 | - 7050:7050 22 | 23 | peer0.org1.example.com: 24 | container_name: peer0.org1.example.com 25 | extends: 26 | file: peer-base.yaml 27 | service: peer-base 28 | environment: 29 | - CORE_PEER_ID=peer0.org1.example.com 30 | - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 31 | - CORE_PEER_LISTENADDRESS=0.0.0.0:7051 32 | - CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052 33 | - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052 34 | - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:8051 35 | - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051 36 | - CORE_PEER_LOCALMSPID=Org1MSP 37 | volumes: 38 | - /var/run/:/host/var/run/ 39 | - ../crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp 40 | - ../crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls 41 | - peer0.org1.example.com:/var/hyperledger/production 42 | ports: 43 | - 7051:7051 44 | 45 | peer1.org1.example.com: 46 | container_name: peer1.org1.example.com 47 | extends: 48 | file: peer-base.yaml 49 | service: peer-base 50 | environment: 51 | - CORE_PEER_ID=peer1.org1.example.com 52 | - CORE_PEER_ADDRESS=peer1.org1.example.com:8051 53 | - CORE_PEER_LISTENADDRESS=0.0.0.0:8051 54 | - CORE_PEER_CHAINCODEADDRESS=peer1.org1.example.com:8052 55 | - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:8052 56 | - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.example.com:8051 57 | - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051 58 | - CORE_PEER_LOCALMSPID=Org1MSP 59 | volumes: 60 | - /var/run/:/host/var/run/ 61 | - ../crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp:/etc/hyperledger/fabric/msp 62 | - ../crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls:/etc/hyperledger/fabric/tls 63 | - peer1.org1.example.com:/var/hyperledger/production 64 | 65 | ports: 66 | - 8051:8051 67 | 68 | peer0.org2.example.com: 69 | container_name: peer0.org2.example.com 70 | extends: 71 | file: peer-base.yaml 72 | service: peer-base 73 | environment: 74 | - CORE_PEER_ID=peer0.org2.example.com 75 | - CORE_PEER_ADDRESS=peer0.org2.example.com:9051 76 | - CORE_PEER_LISTENADDRESS=0.0.0.0:9051 77 | - CORE_PEER_CHAINCODEADDRESS=peer0.org2.example.com:9052 78 | - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:9052 79 | - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org2.example.com:9051 80 | - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org2.example.com:10051 81 | - CORE_PEER_LOCALMSPID=Org2MSP 82 | volumes: 83 | - /var/run/:/host/var/run/ 84 | - ../crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/msp:/etc/hyperledger/fabric/msp 85 | - ../crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls:/etc/hyperledger/fabric/tls 86 | - peer0.org2.example.com:/var/hyperledger/production 87 | ports: 88 | - 9051:9051 89 | 90 | peer1.org2.example.com: 91 | container_name: peer1.org2.example.com 92 | extends: 93 | file: peer-base.yaml 94 | service: peer-base 95 | environment: 96 | - CORE_PEER_ID=peer1.org2.example.com 97 | - CORE_PEER_ADDRESS=peer1.org2.example.com:10051 98 | - CORE_PEER_LISTENADDRESS=0.0.0.0:10051 99 | - CORE_PEER_CHAINCODEADDRESS=peer1.org2.example.com:10052 100 | - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:10052 101 | - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org2.example.com:10051 102 | - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org2.example.com:9051 103 | - CORE_PEER_LOCALMSPID=Org2MSP 104 | volumes: 105 | - /var/run/:/host/var/run/ 106 | - ../crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/msp:/etc/hyperledger/fabric/msp 107 | - ../crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls:/etc/hyperledger/fabric/tls 108 | - peer1.org2.example.com:/var/hyperledger/production 109 | ports: 110 | - 10051:10051 111 | -------------------------------------------------------------------------------- /first-network/base/kafka-base.yaml: -------------------------------------------------------------------------------- 1 | # Copyright IBM Corp. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | 6 | version: '2' 7 | 8 | services: 9 | 10 | zookeeper: 11 | image: hyperledger/fabric-zookeeper 12 | environment: 13 | # 14 | # server.x=[hostname]:nnnnn[:nnnnn] 15 | # The list of servers that make up the ZK ensemble. The list that is used 16 | # by the clients must match the list of ZooKeeper servers that each ZK 17 | # server has. There are two port numbers `nnnnn`. The first is what 18 | # followers use to connect to the leader, while the second is for leader 19 | # election. 20 | - ZOO_SERVERS=server.1=zookeeper0.example.com:2888:3888 server.2=zookeeper1.example.com:2888:3888 server.3=zookeeper2.example.com:2888:3888 21 | restart: always 22 | 23 | kafka: 24 | image: hyperledger/fabric-kafka 25 | restart: always 26 | environment: 27 | # ======================================================================== 28 | # Reference: https://kafka.apache.org/documentation/#configuration 29 | # ======================================================================== 30 | # 31 | # socket.request.max.bytes 32 | # The maximum number of bytes in a socket request. ATTN: If you set this 33 | # env var, you should make sure that the value assigned to 34 | # `brokerConfig.Producer.MaxMessageBytes` in `newBrokerConfig()` in 35 | # `fabric/orderer/kafka/util.go` matches it. 36 | #- KAFKA_SOCKET_REQUEST_MAX_BYTES=104857600 # 100 * 1024 * 1024 B 37 | # 38 | # message.max.bytes 39 | # The maximum size of envelope that the broker can receive. 40 | - KAFKA_MESSAGE_MAX_BYTES=103809024 # 99 * 1024 * 1024 B 41 | # 42 | # replica.fetch.max.bytes 43 | # The number of bytes of messages to attempt to fetch for each channel. 44 | # This is not an absolute maximum, if the fetched envelope is larger than 45 | # this value, the envelope will still be returned to ensure that progress 46 | # can be made. The maximum message size accepted by the broker is defined 47 | # via message.max.bytes above. 48 | - KAFKA_REPLICA_FETCH_MAX_BYTES=103809024 # 99 * 1024 * 1024 B 49 | # 50 | # unclean.leader.election.enable 51 | # Data consistency is key in a blockchain environment. We cannot have a 52 | # leader chosen outside of the in-sync replica set, or we run the risk of 53 | # overwriting the offsets that the previous leader produced, and --as a 54 | # result-- rewriting the blockchain that the orderers produce. 55 | - KAFKA_UNCLEAN_LEADER_ELECTION_ENABLE=false 56 | 57 | # 58 | # min.insync.replicas 59 | # Let the value of this setting be M. Data is considered committed when 60 | # it is written to at least M replicas (which are then considered in-sync 61 | # and belong to the in-sync replica set, or ISR). In any other case, the 62 | # write operation returns an error. Then: 63 | # 1. if just one replica out of the N (see default.replication.factor 64 | # below) that the channel data is written to becomes unavailable, 65 | # operations proceed normally. 66 | # 2. If N - M + 1 (or more) replicas become unavailable, Kafka cannot 67 | # maintain an ISR set of M, so it stops accepting writes. Reads work 68 | # without issues. The cluster becomes writeable again when M replicas get 69 | # in-sync. 70 | - KAFKA_MIN_INSYNC_REPLICAS=2 71 | # 72 | # default.replication.factor 73 | # Let the value of this setting be M. This means that: 74 | # 1. Each channel will have its data replicated to N brokers. These are 75 | # the candidates for the ISR set for a channel. As we've noted in the 76 | # min.insync.replicas section above, not all of these brokers have to be 77 | # available all the time. We choose a default.replication.factor of N so 78 | # as to have the largest possible candidate set for a channel's ISR. 79 | # 2. Channel creations cannot go forward if less than N brokers are up. 80 | - KAFKA_DEFAULT_REPLICATION_FACTOR=3 81 | # 82 | # zookeper.connect 83 | # Point to the set of Zookeeper nodes comprising a ZK ensemble. 84 | - KAFKA_ZOOKEEPER_CONNECT=zookeeper0.example.com:2181,zookeeper1.example.com:2181,zookeeper2.example.com:2181 85 | # 86 | # zookeeper.connection.timeout.ms 87 | # The max time that the client waits to establish a connection to 88 | # Zookeeper. If not set, the value in zookeeper.session.timeout.ms (below) 89 | # is used. 90 | #- KAFKA_ZOOKEEPER_CONNECTION_TIMEOUT_MS = 6000 91 | # 92 | # zookeeper.session.timeout.ms 93 | #- KAFKA_ZOOKEEPER_SESSION_TIMEOUT_MS = 6000 94 | #ports: 95 | #- '9092' -------------------------------------------------------------------------------- /first-network/base/peer-base.yaml: -------------------------------------------------------------------------------- 1 | # Copyright IBM Corp. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | 6 | version: '2' 7 | 8 | services: 9 | peer-base: 10 | image: hyperledger/fabric-peer:$IMAGE_TAG 11 | environment: 12 | - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock 13 | # the following setting starts chaincode containers on the same 14 | # bridge network as the peers 15 | # https://docs.docker.com/compose/networking/ 16 | - CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=${COMPOSE_PROJECT_NAME}_byfn 17 | - FABRIC_LOGGING_SPEC=INFO 18 | #- FABRIC_LOGGING_SPEC=DEBUG 19 | - CORE_PEER_TLS_ENABLED=true 20 | - CORE_PEER_GOSSIP_USELEADERELECTION=true 21 | - CORE_PEER_GOSSIP_ORGLEADER=false 22 | - CORE_PEER_PROFILE_ENABLED=true 23 | - CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt 24 | - CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key 25 | - CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt 26 | working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer 27 | command: peer node start 28 | 29 | orderer-base: 30 | image: hyperledger/fabric-orderer:$IMAGE_TAG 31 | environment: 32 | - FABRIC_LOGGING_SPEC=INFO 33 | - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0 34 | - ORDERER_GENERAL_GENESISMETHOD=file 35 | - ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block 36 | - ORDERER_GENERAL_LOCALMSPID=OrdererMSP 37 | - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp 38 | # enabled TLS 39 | - ORDERER_GENERAL_TLS_ENABLED=true 40 | - ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key 41 | - ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt 42 | - ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] 43 | - ORDERER_KAFKA_TOPIC_REPLICATIONFACTOR=1 44 | - ORDERER_KAFKA_VERBOSE=true 45 | - ORDERER_GENERAL_CLUSTER_CLIENTCERTIFICATE=/var/hyperledger/orderer/tls/server.crt 46 | - ORDERER_GENERAL_CLUSTER_CLIENTPRIVATEKEY=/var/hyperledger/orderer/tls/server.key 47 | - ORDERER_GENERAL_CLUSTER_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt] 48 | working_dir: /opt/gopath/src/github.com/hyperledger/fabric 49 | command: orderer 50 | 51 | -------------------------------------------------------------------------------- /first-network/byfn.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright IBM Corp All Rights Reserved 4 | # 5 | # SPDX-License-Identifier: Apache-2.0 6 | # 7 | 8 | # This script will orchestrate a sample end-to-end execution of the Hyperledger 9 | # Fabric network. 10 | # 11 | # The end-to-end verification provisions a sample Fabric network consisting of 12 | # two organizations, each maintaining two peers, and a “solo” ordering service. 13 | # 14 | # This verification makes use of two fundamental tools, which are necessary to 15 | # create a functioning transactional network with digital signature validation 16 | # and access control: 17 | # 18 | # * cryptogen - generates the x509 certificates used to identify and 19 | # authenticate the various components in the network. 20 | # * configtxgen - generates the requisite configuration artifacts for orderer 21 | # bootstrap and channel creation. 22 | # 23 | # Each tool consumes a configuration yaml file, within which we specify the topology 24 | # of our network (cryptogen) and the location of our certificates for various 25 | # configuration operations (configtxgen). Once the tools have been successfully run, 26 | # we are able to launch our network. More detail on the tools and the structure of 27 | # the network will be provided later in this document. For now, let's get going... 28 | 29 | # prepending $PWD/../bin to PATH to ensure we are picking up the correct binaries 30 | # this may be commented out to resolve installed version of tools if desired 31 | export PATH=${PWD}/../bin:${PWD}:$PATH 32 | export FABRIC_CFG_PATH=${PWD} 33 | export VERBOSE=false 34 | 35 | # Print the usage message 36 | function printHelp() { 37 | echo "Usage: " 38 | echo " byfn.sh [-c ] [-t ] [-d ] [-f ] [-s ] [-l ] [-o ] [-i ] [-a] [-n] [-v]" 39 | echo " - one of 'up', 'down', 'restart', 'generate' or 'upgrade'" 40 | echo " - 'up' - bring up the network with docker-compose up" 41 | echo " - 'down' - clear the network with docker-compose down" 42 | echo " - 'restart' - restart the network" 43 | echo " - 'generate' - generate required certificates and genesis block" 44 | echo " - 'upgrade' - upgrade the network from version 1.3.x to 1.4.0" 45 | echo " -c - channel name to use (defaults to \"mychannel\")" 46 | echo " -t - CLI timeout duration in seconds (defaults to 10)" 47 | echo " -d - delay duration in seconds (defaults to 3)" 48 | echo " -f - specify which docker-compose file use (defaults to docker-compose-cli.yaml)" 49 | echo " -s - the database backend to use: goleveldb (default) or couchdb" 50 | echo " -l - the chaincode language: golang (default) or node" 51 | echo " -o - the consensus-type of the ordering service: solo (default), kafka, or etcdraft" 52 | echo " -i - the tag to be used to launch the network (defaults to \"latest\")" 53 | echo " -a - launch certificate authorities (no certificate authorities are launched by default)" 54 | echo " -n - do not deploy chaincode (abstore chaincode is deployed by default)" 55 | echo " -v - verbose mode" 56 | echo " byfn.sh -h (print this message)" 57 | echo 58 | echo "Typically, one would first generate the required certificates and " 59 | echo "genesis block, then bring up the network. e.g.:" 60 | echo 61 | echo " byfn.sh generate -c mychannel" 62 | echo " byfn.sh up -c mychannel -s couchdb" 63 | echo " byfn.sh up -c mychannel -s couchdb -i 1.4.0" 64 | echo " byfn.sh up -l node" 65 | echo " byfn.sh down -c mychannel" 66 | echo " byfn.sh upgrade -c mychannel" 67 | echo 68 | echo "Taking all defaults:" 69 | echo " byfn.sh generate" 70 | echo " byfn.sh up" 71 | echo " byfn.sh down" 72 | } 73 | 74 | # Ask user for confirmation to proceed 75 | function askProceed() { 76 | read -p "Continue? [Y/n] " ans 77 | case "$ans" in 78 | y | Y | "") 79 | echo "proceeding ..." 80 | ;; 81 | n | N) 82 | echo "exiting..." 83 | exit 1 84 | ;; 85 | *) 86 | echo "invalid response" 87 | askProceed 88 | ;; 89 | esac 90 | } 91 | 92 | # Obtain CONTAINER_IDS and remove them 93 | # TODO Might want to make this optional - could clear other containers 94 | function clearContainers() { 95 | CONTAINER_IDS=$(docker ps -a | awk '($2 ~ /dev-peer.*/) {print $1}') 96 | if [ -z "$CONTAINER_IDS" -o "$CONTAINER_IDS" == " " ]; then 97 | echo "---- No containers available for deletion ----" 98 | else 99 | docker rm -f $CONTAINER_IDS 100 | fi 101 | } 102 | 103 | # Delete any images that were generated as a part of this setup 104 | # specifically the following images are often left behind: 105 | # TODO list generated image naming patterns 106 | function removeUnwantedImages() { 107 | DOCKER_IMAGE_IDS=$(docker images | awk '($1 ~ /dev-peer.*/) {print $3}') 108 | if [ -z "$DOCKER_IMAGE_IDS" -o "$DOCKER_IMAGE_IDS" == " " ]; then 109 | echo "---- No images available for deletion ----" 110 | else 111 | docker rmi -f $DOCKER_IMAGE_IDS 112 | fi 113 | } 114 | 115 | # Versions of fabric known not to work with this release of first-network 116 | BLACKLISTED_VERSIONS="^1\.0\. ^1\.1\.0-preview ^1\.1\.0-alpha" 117 | 118 | # Do some basic sanity checking to make sure that the appropriate versions of fabric 119 | # binaries/images are available. In the future, additional checking for the presence 120 | # of go or other items could be added. 121 | function checkPrereqs() { 122 | # Note, we check configtxlator externally because it does not require a config file, and peer in the 123 | # docker image because of FAB-8551 that makes configtxlator return 'development version' in docker 124 | LOCAL_VERSION=$(configtxlator version | sed -ne 's/ Version: //p') 125 | DOCKER_IMAGE_VERSION=$(docker run --rm hyperledger/fabric-tools:$IMAGETAG peer version | sed -ne 's/ Version: //p' | head -1) 126 | 127 | echo "LOCAL_VERSION=$LOCAL_VERSION" 128 | echo "DOCKER_IMAGE_VERSION=$DOCKER_IMAGE_VERSION" 129 | 130 | if [ "$LOCAL_VERSION" != "$DOCKER_IMAGE_VERSION" ]; then 131 | echo "=================== WARNING ===================" 132 | echo " Local fabric binaries and docker images are " 133 | echo " out of sync. This may cause problems. " 134 | echo "===============================================" 135 | fi 136 | 137 | for UNSUPPORTED_VERSION in $BLACKLISTED_VERSIONS; do 138 | echo "$LOCAL_VERSION" | grep -q $UNSUPPORTED_VERSION 139 | if [ $? -eq 0 ]; then 140 | echo "ERROR! Local Fabric binary version of $LOCAL_VERSION does not match this newer version of BYFN and is unsupported. Either move to a later version of Fabric or checkout an earlier version of fabric-samples." 141 | exit 1 142 | fi 143 | 144 | echo "$DOCKER_IMAGE_VERSION" | grep -q $UNSUPPORTED_VERSION 145 | if [ $? -eq 0 ]; then 146 | echo "ERROR! Fabric Docker image version of $DOCKER_IMAGE_VERSION does not match this newer version of BYFN and is unsupported. Either move to a later version of Fabric or checkout an earlier version of fabric-samples." 147 | exit 1 148 | fi 149 | done 150 | } 151 | 152 | # Generate the needed certificates, the genesis block and start the network. 153 | function networkUp() { 154 | checkPrereqs 155 | # generate artifacts if they don't exist 156 | if [ ! -d "crypto-config" ]; then 157 | generateCerts 158 | replacePrivateKey 159 | generateChannelArtifacts 160 | fi 161 | COMPOSE_FILES="-f ${COMPOSE_FILE}" 162 | if [ "${CERTIFICATE_AUTHORITIES}" == "true" ]; then 163 | COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_CA}" 164 | export BYFN_CA1_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org1.example.com/ca && ls *_sk) 165 | export BYFN_CA2_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org2.example.com/ca && ls *_sk) 166 | fi 167 | if [ "${CONSENSUS_TYPE}" == "kafka" ]; then 168 | COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_KAFKA}" 169 | elif [ "${CONSENSUS_TYPE}" == "etcdraft" ]; then 170 | COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_RAFT2}" 171 | fi 172 | if [ "${IF_COUCHDB}" == "couchdb" ]; then 173 | COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_COUCH}" 174 | fi 175 | IMAGE_TAG=$IMAGETAG docker-compose ${COMPOSE_FILES} up -d 2>&1 176 | docker ps -a 177 | if [ $? -ne 0 ]; then 178 | echo "ERROR !!!! Unable to start network" 179 | exit 1 180 | fi 181 | 182 | if [ "$CONSENSUS_TYPE" == "kafka" ]; then 183 | sleep 1 184 | echo "Sleeping 10s 15 allow $CONSENSUS_TYPE cluster to complete booting" 185 | sleep 14 186 | fi 187 | 188 | if [ "$CONSENSUS_TYPE" == "etcdraft" ]; then 189 | sleep 1 190 | echo "Sleeping 15s to allow $CONSENSUS_TYPE cluster to complete booting" 191 | sleep 14 192 | fi 193 | 194 | # now run the end to end script 195 | docker exec cli scripts/script.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE $NO_CHAINCODE 196 | if [ $? -ne 0 ]; then 197 | echo "ERROR !!!! Test failed" 198 | exit 1 199 | fi 200 | } 201 | 202 | # Upgrade the network components which are at version 1.3.x to 1.4.x 203 | # Stop the orderer and peers, backup the ledger for orderer and peers, cleanup chaincode containers and images 204 | # and relaunch the orderer and peers with latest tag 205 | function upgradeNetwork() { 206 | if [[ "$IMAGETAG" == *"1.4"* ]] || [[ $IMAGETAG == "latest" ]]; then 207 | docker inspect -f '{{.Config.Volumes}}' orderer.example.com | grep -q '/var/hyperledger/production/orderer' 208 | if [ $? -ne 0 ]; then 209 | echo "ERROR !!!! This network does not appear to start with fabric-samples >= v1.3.x?" 210 | exit 1 211 | fi 212 | 213 | LEDGERS_BACKUP=./ledgers-backup 214 | 215 | # create ledger-backup directory 216 | mkdir -p $LEDGERS_BACKUP 217 | 218 | export IMAGE_TAG=$IMAGETAG 219 | COMPOSE_FILES="-f ${COMPOSE_FILE}" 220 | if [ "${CERTIFICATE_AUTHORITIES}" == "true" ]; then 221 | COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_CA}" 222 | export BYFN_CA1_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org1.example.com/ca && ls *_sk) 223 | export BYFN_CA2_PRIVATE_KEY=$(cd crypto-config/peerOrganizations/org2.example.com/ca && ls *_sk) 224 | fi 225 | if [ "${CONSENSUS_TYPE}" == "kafka" ]; then 226 | COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_KAFKA}" 227 | elif [ "${CONSENSUS_TYPE}" == "etcdraft" ]; then 228 | COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_RAFT2}" 229 | fi 230 | if [ "${IF_COUCHDB}" == "couchdb" ]; then 231 | COMPOSE_FILES="${COMPOSE_FILES} -f ${COMPOSE_FILE_COUCH}" 232 | fi 233 | 234 | # removing the cli container 235 | docker-compose $COMPOSE_FILES stop cli 236 | docker-compose $COMPOSE_FILES up -d --no-deps cli 237 | 238 | echo "Upgrading orderer" 239 | docker-compose $COMPOSE_FILES stop orderer.example.com 240 | docker cp -a orderer.example.com:/var/hyperledger/production/orderer $LEDGERS_BACKUP/orderer.example.com 241 | docker-compose $COMPOSE_FILES up -d --no-deps orderer.example.com 242 | 243 | for PEER in peer0.org1.example.com peer1.org1.example.com peer0.org2.example.com peer1.org2.example.com; do 244 | echo "Upgrading peer $PEER" 245 | 246 | # Stop the peer and backup its ledger 247 | docker-compose $COMPOSE_FILES stop $PEER 248 | docker cp -a $PEER:/var/hyperledger/production $LEDGERS_BACKUP/$PEER/ 249 | 250 | # Remove any old containers and images for this peer 251 | CC_CONTAINERS=$(docker ps | grep dev-$PEER | awk '{print $1}') 252 | if [ -n "$CC_CONTAINERS" ]; then 253 | docker rm -f $CC_CONTAINERS 254 | fi 255 | CC_IMAGES=$(docker images | grep dev-$PEER | awk '{print $1}') 256 | if [ -n "$CC_IMAGES" ]; then 257 | docker rmi -f $CC_IMAGES 258 | fi 259 | 260 | # Start the peer again 261 | docker-compose $COMPOSE_FILES up -d --no-deps $PEER 262 | done 263 | 264 | docker exec cli sh -c "SYS_CHANNEL=$CH_NAME && scripts/upgrade_to_v14.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE" 265 | if [ $? -ne 0 ]; then 266 | echo "ERROR !!!! Test failed" 267 | exit 1 268 | fi 269 | else 270 | echo "ERROR !!!! Pass the v1.4.x image tag" 271 | fi 272 | } 273 | 274 | # Tear down running network 275 | function networkDown() { 276 | # stop org3 containers also in addition to org1 and org2, in case we were running sample to add org3 277 | # stop kafka and zookeeper containers in case we're running with kafka consensus-type 278 | docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH -f $COMPOSE_FILE_KAFKA -f $COMPOSE_FILE_RAFT2 -f $COMPOSE_FILE_CA -f $COMPOSE_FILE_ORG3 down --volumes --remove-orphans 279 | 280 | # Don't remove the generated artifacts -- note, the ledgers are always removed 281 | if [ "$MODE" != "restart" ]; then 282 | # Bring down the network, deleting the volumes 283 | #Delete any ledger backups 284 | docker run -v $PWD:/tmp/first-network --rm hyperledger/fabric-tools:$IMAGETAG rm -Rf /tmp/first-network/ledgers-backup 285 | #Cleanup the chaincode containers 286 | clearContainers 287 | #Cleanup images 288 | removeUnwantedImages 289 | # remove orderer block and other channel configuration transactions and certs 290 | rm -rf channel-artifacts/*.block channel-artifacts/*.tx crypto-config ./org3-artifacts/crypto-config/ channel-artifacts/org3.json 291 | # remove the docker-compose yaml file that was customized to the example 292 | rm -f docker-compose-e2e.yaml 293 | fi 294 | } 295 | 296 | # Using docker-compose-e2e-template.yaml, replace constants with private key file names 297 | # generated by the cryptogen tool and output a docker-compose.yaml specific to this 298 | # configuration 299 | function replacePrivateKey() { 300 | # sed on MacOSX does not support -i flag with a null extension. We will use 301 | # 't' for our back-up's extension and delete it at the end of the function 302 | ARCH=$(uname -s | grep Darwin) 303 | if [ "$ARCH" == "Darwin" ]; then 304 | OPTS="-it" 305 | else 306 | OPTS="-i" 307 | fi 308 | 309 | # Copy the template to the file that will be modified to add the private key 310 | cp docker-compose-e2e-template.yaml docker-compose-e2e.yaml 311 | 312 | # The next steps will replace the template's contents with the 313 | # actual values of the private key file names for the two CAs. 314 | CURRENT_DIR=$PWD 315 | cd crypto-config/peerOrganizations/org1.example.com/ca/ 316 | PRIV_KEY=$(ls *_sk) 317 | cd "$CURRENT_DIR" 318 | sed $OPTS "s/CA1_PRIVATE_KEY/${PRIV_KEY}/g" docker-compose-e2e.yaml 319 | cd crypto-config/peerOrganizations/org2.example.com/ca/ 320 | PRIV_KEY=$(ls *_sk) 321 | cd "$CURRENT_DIR" 322 | sed $OPTS "s/CA2_PRIVATE_KEY/${PRIV_KEY}/g" docker-compose-e2e.yaml 323 | # If MacOSX, remove the temporary backup of the docker-compose file 324 | if [ "$ARCH" == "Darwin" ]; then 325 | rm docker-compose-e2e.yamlt 326 | fi 327 | } 328 | 329 | # We will use the cryptogen tool to generate the cryptographic material (x509 certs) 330 | # for our various network entities. The certificates are based on a standard PKI 331 | # implementation where validation is achieved by reaching a common trust anchor. 332 | # 333 | # Cryptogen consumes a file - ``crypto-config.yaml`` - that contains the network 334 | # topology and allows us to generate a library of certificates for both the 335 | # Organizations and the components that belong to those Organizations. Each 336 | # Organization is provisioned a unique root certificate (``ca-cert``), that binds 337 | # specific components (peers and orderers) to that Org. Transactions and communications 338 | # within Fabric are signed by an entity's private key (``keystore``), and then verified 339 | # by means of a public key (``signcerts``). You will notice a "count" variable within 340 | # this file. We use this to specify the number of peers per Organization; in our 341 | # case it's two peers per Org. The rest of this template is extremely 342 | # self-explanatory. 343 | # 344 | # After we run the tool, the certs will be parked in a folder titled ``crypto-config``. 345 | 346 | # Generates Org certs using cryptogen tool 347 | function generateCerts() { 348 | which cryptogen 349 | if [ "$?" -ne 0 ]; then 350 | echo "cryptogen tool not found. exiting" 351 | exit 1 352 | fi 353 | echo 354 | echo "##########################################################" 355 | echo "##### Generate certificates using cryptogen tool #########" 356 | echo "##########################################################" 357 | 358 | if [ -d "crypto-config" ]; then 359 | rm -Rf crypto-config 360 | fi 361 | set -x 362 | cryptogen generate --config=./crypto-config.yaml 363 | res=$? 364 | set +x 365 | if [ $res -ne 0 ]; then 366 | echo "Failed to generate certificates..." 367 | exit 1 368 | fi 369 | echo 370 | echo "Generate CCP files for Org1 and Org2" 371 | ./ccp-generate.sh 372 | } 373 | 374 | # The `configtxgen tool is used to create four artifacts: orderer **bootstrap 375 | # block**, fabric **channel configuration transaction**, and two **anchor 376 | # peer transactions** - one for each Peer Org. 377 | # 378 | # The orderer block is the genesis block for the ordering service, and the 379 | # channel transaction file is broadcast to the orderer at channel creation 380 | # time. The anchor peer transactions, as the name might suggest, specify each 381 | # Org's anchor peer on this channel. 382 | # 383 | # Configtxgen consumes a file - ``configtx.yaml`` - that contains the definitions 384 | # for the sample network. There are three members - one Orderer Org (``OrdererOrg``) 385 | # and two Peer Orgs (``Org1`` & ``Org2``) each managing and maintaining two peer nodes. 386 | # This file also specifies a consortium - ``SampleConsortium`` - consisting of our 387 | # two Peer Orgs. Pay specific attention to the "Profiles" section at the top of 388 | # this file. You will notice that we have two unique headers. One for the orderer genesis 389 | # block - ``TwoOrgsOrdererGenesis`` - and one for our channel - ``TwoOrgsChannel``. 390 | # These headers are important, as we will pass them in as arguments when we create 391 | # our artifacts. This file also contains two additional specifications that are worth 392 | # noting. Firstly, we specify the anchor peers for each Peer Org 393 | # (``peer0.org1.example.com`` & ``peer0.org2.example.com``). Secondly, we point to 394 | # the location of the MSP directory for each member, in turn allowing us to store the 395 | # root certificates for each Org in the orderer genesis block. This is a critical 396 | # concept. Now any network entity communicating with the ordering service can have 397 | # its digital signature verified. 398 | # 399 | # This function will generate the crypto material and our four configuration 400 | # artifacts, and subsequently output these files into the ``channel-artifacts`` 401 | # folder. 402 | # 403 | # If you receive the following warning, it can be safely ignored: 404 | # 405 | # [bccsp] GetDefault -> WARN 001 Before using BCCSP, please call InitFactories(). Falling back to bootBCCSP. 406 | # 407 | # You can ignore the logs regarding intermediate certs, we are not using them in 408 | # this crypto implementation. 409 | 410 | # Generate orderer genesis block, channel configuration transaction and 411 | # anchor peer update transactions 412 | function generateChannelArtifacts() { 413 | which configtxgen 414 | if [ "$?" -ne 0 ]; then 415 | echo "configtxgen tool not found. exiting" 416 | exit 1 417 | fi 418 | 419 | echo "##########################################################" 420 | echo "######### Generating Orderer Genesis block ##############" 421 | echo "##########################################################" 422 | # Note: For some unknown reason (at least for now) the block file can't be 423 | # named orderer.genesis.block or the orderer will fail to launch! 424 | echo "CONSENSUS_TYPE="$CONSENSUS_TYPE 425 | set -x 426 | if [ "$CONSENSUS_TYPE" == "solo" ]; then 427 | configtxgen -profile TwoOrgsOrdererGenesis -channelID $SYS_CHANNEL -outputBlock ./channel-artifacts/genesis.block 428 | elif [ "$CONSENSUS_TYPE" == "kafka" ]; then 429 | configtxgen -profile SampleDevModeKafka -channelID $SYS_CHANNEL -outputBlock ./channel-artifacts/genesis.block 430 | elif [ "$CONSENSUS_TYPE" == "etcdraft" ]; then 431 | configtxgen -profile SampleMultiNodeEtcdRaft -channelID $SYS_CHANNEL -outputBlock ./channel-artifacts/genesis.block 432 | else 433 | set +x 434 | echo "unrecognized CONSESUS_TYPE='$CONSENSUS_TYPE'. exiting" 435 | exit 1 436 | fi 437 | res=$? 438 | set +x 439 | if [ $res -ne 0 ]; then 440 | echo "Failed to generate orderer genesis block..." 441 | exit 1 442 | fi 443 | echo 444 | echo "#################################################################" 445 | echo "### Generating channel configuration transaction 'channel.tx' ###" 446 | echo "#################################################################" 447 | set -x 448 | configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME 449 | res=$? 450 | set +x 451 | if [ $res -ne 0 ]; then 452 | echo "Failed to generate channel configuration transaction..." 453 | exit 1 454 | fi 455 | 456 | echo 457 | echo "#################################################################" 458 | echo "####### Generating anchor peer update for Org1MSP ##########" 459 | echo "#################################################################" 460 | set -x 461 | configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP 462 | res=$? 463 | set +x 464 | if [ $res -ne 0 ]; then 465 | echo "Failed to generate anchor peer update for Org1MSP..." 466 | exit 1 467 | fi 468 | 469 | echo 470 | echo "#################################################################" 471 | echo "####### Generating anchor peer update for Org2MSP ##########" 472 | echo "#################################################################" 473 | set -x 474 | configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate \ 475 | ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP 476 | res=$? 477 | set +x 478 | if [ $res -ne 0 ]; then 479 | echo "Failed to generate anchor peer update for Org2MSP..." 480 | exit 1 481 | fi 482 | echo 483 | } 484 | 485 | # Obtain the OS and Architecture string that will be used to select the correct 486 | # native binaries for your platform, e.g., darwin-amd64 or linux-amd64 487 | OS_ARCH=$(echo "$(uname -s | tr '[:upper:]' '[:lower:]' | sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')" | awk '{print tolower($0)}') 488 | # timeout duration - the duration the CLI should wait for a response from 489 | # another container before giving up 490 | CLI_TIMEOUT=10 491 | # default for delay between commands 492 | CLI_DELAY=3 493 | # system channel name defaults to "byfn-sys-channel" 494 | SYS_CHANNEL="byfn-sys-channel" 495 | # channel name defaults to "mychannel" 496 | CHANNEL_NAME="mychannel" 497 | # use this as the default docker-compose yaml definition 498 | COMPOSE_FILE=docker-compose-cli.yaml 499 | # 500 | COMPOSE_FILE_COUCH=docker-compose-couch.yaml 501 | # org3 docker compose file 502 | COMPOSE_FILE_ORG3=docker-compose-org3.yaml 503 | # kafka and zookeeper compose file 504 | COMPOSE_FILE_KAFKA=docker-compose-kafka.yaml 505 | # two additional etcd/raft orderers 506 | COMPOSE_FILE_RAFT2=docker-compose-etcdraft2.yaml 507 | # certificate authorities compose file 508 | COMPOSE_FILE_CA=docker-compose-ca.yaml 509 | # 510 | # use golang as the default language for chaincode 511 | LANGUAGE=golang 512 | # default image tag 513 | IMAGETAG="latest" 514 | # default consensus type 515 | CONSENSUS_TYPE="solo" 516 | # Parse commandline args 517 | if [ "$1" = "-m" ]; then # supports old usage, muscle memory is powerful! 518 | shift 519 | fi 520 | MODE=$1 521 | shift 522 | # Determine whether starting, stopping, restarting, generating or upgrading 523 | if [ "$MODE" == "up" ]; then 524 | EXPMODE="Starting" 525 | elif [ "$MODE" == "down" ]; then 526 | EXPMODE="Stopping" 527 | elif [ "$MODE" == "restart" ]; then 528 | EXPMODE="Restarting" 529 | elif [ "$MODE" == "generate" ]; then 530 | EXPMODE="Generating certs and genesis block" 531 | elif [ "$MODE" == "upgrade" ]; then 532 | EXPMODE="Upgrading the network" 533 | else 534 | printHelp 535 | exit 1 536 | fi 537 | 538 | while getopts "h?c:t:d:f:s:l:i:o:anv" opt; do 539 | case "$opt" in 540 | h | \?) 541 | printHelp 542 | exit 0 543 | ;; 544 | c) 545 | CHANNEL_NAME=$OPTARG 546 | ;; 547 | t) 548 | CLI_TIMEOUT=$OPTARG 549 | ;; 550 | d) 551 | CLI_DELAY=$OPTARG 552 | ;; 553 | f) 554 | COMPOSE_FILE=$OPTARG 555 | ;; 556 | s) 557 | IF_COUCHDB=$OPTARG 558 | ;; 559 | l) 560 | LANGUAGE=$OPTARG 561 | ;; 562 | i) 563 | IMAGETAG=$(go env GOARCH)"-"$OPTARG 564 | ;; 565 | o) 566 | CONSENSUS_TYPE=$OPTARG 567 | ;; 568 | a) 569 | CERTIFICATE_AUTHORITIES=true 570 | ;; 571 | n) 572 | NO_CHAINCODE=true 573 | ;; 574 | v) 575 | VERBOSE=true 576 | ;; 577 | esac 578 | done 579 | 580 | 581 | # Announce what was requested 582 | 583 | if [ "${IF_COUCHDB}" == "couchdb" ]; then 584 | echo 585 | echo "${EXPMODE} for channel '${CHANNEL_NAME}' with CLI timeout of '${CLI_TIMEOUT}' seconds and CLI delay of '${CLI_DELAY}' seconds and using database '${IF_COUCHDB}'" 586 | else 587 | echo "${EXPMODE} for channel '${CHANNEL_NAME}' with CLI timeout of '${CLI_TIMEOUT}' seconds and CLI delay of '${CLI_DELAY}' seconds" 588 | fi 589 | # ask for confirmation to proceed 590 | # askProceed 591 | 592 | #Create the network using docker compose 593 | if [ "${MODE}" == "up" ]; then 594 | networkUp 595 | elif [ "${MODE}" == "down" ]; then ## Clear the network 596 | networkDown 597 | elif [ "${MODE}" == "generate" ]; then ## Generate Artifacts 598 | generateCerts 599 | replacePrivateKey 600 | generateChannelArtifacts 601 | elif [ "${MODE}" == "restart" ]; then ## Restart the network 602 | networkDown 603 | networkUp 604 | elif [ "${MODE}" == "upgrade" ]; then ## Upgrade the network from version 1.2.x to 1.3.x 605 | upgradeNetwork 606 | else 607 | printHelp 608 | exit 1 609 | fi 610 | -------------------------------------------------------------------------------- /first-network/ccp-generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function one_line_pem { 4 | echo "`awk 'NF {sub(/\\n/, ""); printf "%s\\\\\\\n",$0;}' $1`" 5 | } 6 | 7 | function json_ccp { 8 | local PP=$(one_line_pem $5) 9 | local CP=$(one_line_pem $6) 10 | sed -e "s/\${ORG}/$1/" \ 11 | -e "s/\${P0PORT}/$2/" \ 12 | -e "s/\${P1PORT}/$3/" \ 13 | -e "s/\${CAPORT}/$4/" \ 14 | -e "s#\${PEERPEM}#$PP#" \ 15 | -e "s#\${CAPEM}#$CP#" \ 16 | ccp-template.json 17 | } 18 | 19 | function yaml_ccp { 20 | local PP=$(one_line_pem $5) 21 | local CP=$(one_line_pem $6) 22 | sed -e "s/\${ORG}/$1/" \ 23 | -e "s/\${P0PORT}/$2/" \ 24 | -e "s/\${P1PORT}/$3/" \ 25 | -e "s/\${CAPORT}/$4/" \ 26 | -e "s#\${PEERPEM}#$PP#" \ 27 | -e "s#\${CAPEM}#$CP#" \ 28 | ccp-template.yaml | sed -e $'s/\\\\n/\\\n /g' 29 | } 30 | 31 | ORG=1 32 | P0PORT=7051 33 | P1PORT=8051 34 | CAPORT=7054 35 | PEERPEM=crypto-config/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem 36 | CAPEM=crypto-config/peerOrganizations/org1.example.com/ca/ca.org1.example.com-cert.pem 37 | 38 | echo "$(json_ccp $ORG $P0PORT $P1PORT $CAPORT $PEERPEM $CAPEM)" > connection-org1.json 39 | echo "$(yaml_ccp $ORG $P0PORT $P1PORT $CAPORT $PEERPEM $CAPEM)" > connection-org1.yaml 40 | 41 | ORG=2 42 | P0PORT=9051 43 | P1PORT=10051 44 | CAPORT=8054 45 | PEERPEM=crypto-config/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem 46 | CAPEM=crypto-config/peerOrganizations/org2.example.com/ca/ca.org2.example.com-cert.pem 47 | 48 | echo "$(json_ccp $ORG $P0PORT $P1PORT $CAPORT $PEERPEM $CAPEM)" > connection-org2.json 49 | echo "$(yaml_ccp $ORG $P0PORT $P1PORT $CAPORT $PEERPEM $CAPEM)" > connection-org2.yaml 50 | -------------------------------------------------------------------------------- /first-network/ccp-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "first-network-org${ORG}", 3 | "version": "1.0.0", 4 | "client": { 5 | "organization": "Org${ORG}", 6 | "connection": { 7 | "timeout": { 8 | "peer": { 9 | "endorser": "300" 10 | } 11 | } 12 | } 13 | }, 14 | "organizations": { 15 | "Org${ORG}": { 16 | "mspid": "Org${ORG}MSP", 17 | "peers": [ 18 | "peer0.org${ORG}.example.com", 19 | "peer1.org${ORG}.example.com" 20 | ], 21 | "certificateAuthorities": [ 22 | "ca.org${ORG}.example.com" 23 | ] 24 | } 25 | }, 26 | "peers": { 27 | "peer0.org${ORG}.example.com": { 28 | "url": "grpcs://localhost:${P0PORT}", 29 | "tlsCACerts": { 30 | "pem": "${PEERPEM}" 31 | }, 32 | "grpcOptions": { 33 | "ssl-target-name-override": "peer0.org${ORG}.example.com", 34 | "hostnameOverride": "peer0.org${ORG}.example.com" 35 | } 36 | }, 37 | "peer1.org${ORG}.example.com": { 38 | "url": "grpcs://localhost:${P1PORT}", 39 | "tlsCACerts": { 40 | "pem": "${PEERPEM}" 41 | }, 42 | "grpcOptions": { 43 | "ssl-target-name-override": "peer1.org${ORG}.example.com", 44 | "hostnameOverride": "peer1.org${ORG}.example.com" 45 | } 46 | } 47 | }, 48 | "certificateAuthorities": { 49 | "ca.org${ORG}.example.com": { 50 | "url": "https://localhost:${CAPORT}", 51 | "caName": "ca-org${ORG}", 52 | "tlsCACerts": { 53 | "pem": "${CAPEM}" 54 | }, 55 | "httpOptions": { 56 | "verify": false 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /first-network/ccp-template.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: first-network-org${ORG} 3 | version: 1.0.0 4 | client: 5 | organization: Org${ORG} 6 | connection: 7 | timeout: 8 | peer: 9 | endorser: '300' 10 | organizations: 11 | Org${ORG}: 12 | mspid: Org${ORG}MSP 13 | peers: 14 | - peer0.org${ORG}.example.com 15 | - peer1.org${ORG}.example.com 16 | certificateAuthorities: 17 | - ca.org${ORG}.example.com 18 | peers: 19 | peer0.org${ORG}.example.com: 20 | url: grpcs://localhost:${P0PORT} 21 | tlsCACerts: 22 | pem: | 23 | ${PEERPEM} 24 | grpcOptions: 25 | ssl-target-name-override: peer0.org${ORG}.example.com 26 | hostnameOverride: peer0.org${ORG}.example.com 27 | peer1.org${ORG}.example.com: 28 | url: grpcs://localhost:${P1PORT} 29 | tlsCACerts: 30 | pem: | 31 | ${PEERPEM} 32 | grpcOptions: 33 | ssl-target-name-override: peer1.org${ORG}.example.com 34 | hostnameOverride: peer1.org${ORG}.example.com 35 | certificateAuthorities: 36 | ca.org${ORG}.example.com: 37 | url: https://localhost:${CAPORT} 38 | caName: ca-org${ORG} 39 | tlsCACerts: 40 | pem: | 41 | ${CAPEM} 42 | httpOptions: 43 | verify: false 44 | -------------------------------------------------------------------------------- /first-network/channel-artifacts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/will-hu-0/fabric-sample-with-kafka/ab0ec26d3216ed43dd5d22eb29068a1749632057/first-network/channel-artifacts/.gitkeep -------------------------------------------------------------------------------- /first-network/configtx.yaml: -------------------------------------------------------------------------------- 1 | # Copyright IBM Corp. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | 6 | --- 7 | ################################################################################ 8 | # 9 | # Section: Organizations 10 | # 11 | # - This section defines the different organizational identities which will 12 | # be referenced later in the configuration. 13 | # 14 | ################################################################################ 15 | Organizations: 16 | 17 | # SampleOrg defines an MSP using the sampleconfig. It should never be used 18 | # in production but may be used as a template for other definitions 19 | - &OrdererOrg 20 | # DefaultOrg defines the organization which is used in the sampleconfig 21 | # of the fabric.git development environment 22 | Name: OrdererOrg 23 | 24 | # ID to load the MSP definition as 25 | ID: OrdererMSP 26 | 27 | # MSPDir is the filesystem path which contains the MSP configuration 28 | MSPDir: crypto-config/ordererOrganizations/example.com/msp 29 | 30 | # Policies defines the set of policies at this level of the config tree 31 | # For organization policies, their canonical path is usually 32 | # /Channel/// 33 | Policies: 34 | Readers: 35 | Type: Signature 36 | Rule: "OR('OrdererMSP.member')" 37 | Writers: 38 | Type: Signature 39 | Rule: "OR('OrdererMSP.member')" 40 | Admins: 41 | Type: Signature 42 | Rule: "OR('OrdererMSP.admin')" 43 | 44 | - &Org1 45 | # DefaultOrg defines the organization which is used in the sampleconfig 46 | # of the fabric.git development environment 47 | Name: Org1MSP 48 | 49 | # ID to load the MSP definition as 50 | ID: Org1MSP 51 | 52 | MSPDir: crypto-config/peerOrganizations/org1.example.com/msp 53 | 54 | # Policies defines the set of policies at this level of the config tree 55 | # For organization policies, their canonical path is usually 56 | # /Channel/// 57 | Policies: 58 | Readers: 59 | Type: Signature 60 | Rule: "OR('Org1MSP.admin', 'Org1MSP.peer', 'Org1MSP.client')" 61 | Writers: 62 | Type: Signature 63 | Rule: "OR('Org1MSP.admin', 'Org1MSP.client')" 64 | Admins: 65 | Type: Signature 66 | Rule: "OR('Org1MSP.admin')" 67 | 68 | # leave this flag set to true. 69 | AnchorPeers: 70 | # AnchorPeers defines the location of peers which can be used 71 | # for cross org gossip communication. Note, this value is only 72 | # encoded in the genesis block in the Application section context 73 | - Host: peer0.org1.example.com 74 | Port: 7051 75 | 76 | - &Org2 77 | # DefaultOrg defines the organization which is used in the sampleconfig 78 | # of the fabric.git development environment 79 | Name: Org2MSP 80 | 81 | # ID to load the MSP definition as 82 | ID: Org2MSP 83 | 84 | MSPDir: crypto-config/peerOrganizations/org2.example.com/msp 85 | 86 | # Policies defines the set of policies at this level of the config tree 87 | # For organization policies, their canonical path is usually 88 | # /Channel/// 89 | Policies: 90 | Readers: 91 | Type: Signature 92 | Rule: "OR('Org2MSP.admin', 'Org2MSP.peer', 'Org2MSP.client')" 93 | Writers: 94 | Type: Signature 95 | Rule: "OR('Org2MSP.admin', 'Org2MSP.client')" 96 | Admins: 97 | Type: Signature 98 | Rule: "OR('Org2MSP.admin')" 99 | 100 | AnchorPeers: 101 | # AnchorPeers defines the location of peers which can be used 102 | # for cross org gossip communication. Note, this value is only 103 | # encoded in the genesis block in the Application section context 104 | - Host: peer0.org2.example.com 105 | Port: 9051 106 | 107 | ################################################################################ 108 | # 109 | # SECTION: Capabilities 110 | # 111 | # - This section defines the capabilities of fabric network. This is a new 112 | # concept as of v1.1.0 and should not be utilized in mixed networks with 113 | # v1.0.x peers and orderers. Capabilities define features which must be 114 | # present in a fabric binary for that binary to safely participate in the 115 | # fabric network. For instance, if a new MSP type is added, newer binaries 116 | # might recognize and validate the signatures from this type, while older 117 | # binaries without this support would be unable to validate those 118 | # transactions. This could lead to different versions of the fabric binaries 119 | # having different world states. Instead, defining a capability for a channel 120 | # informs those binaries without this capability that they must cease 121 | # processing transactions until they have been upgraded. For v1.0.x if any 122 | # capabilities are defined (including a map with all capabilities turned off) 123 | # then the v1.0.x peer will deliberately crash. 124 | # 125 | ################################################################################ 126 | Capabilities: 127 | # Channel capabilities apply to both the orderers and the peers and must be 128 | # supported by both. 129 | # Set the value of the capability to true to require it. 130 | Channel: &ChannelCapabilities 131 | # V1.4.3 for Channel is a catchall flag for behavior which has been 132 | # determined to be desired for all orderers and peers running at the v1.4.3 133 | # level, but which would be incompatible with orderers and peers from 134 | # prior releases. 135 | # Prior to enabling V1.4.3 channel capabilities, ensure that all 136 | # orderers and peers on a channel are at v1.4.3 or later. 137 | V1_4_3: true 138 | # V1.3 for Channel enables the new non-backwards compatible 139 | # features and fixes of fabric v1.3 140 | V1_3: false 141 | # V1.1 for Channel enables the new non-backwards compatible 142 | # features and fixes of fabric v1.1 143 | V1_1: false 144 | 145 | # Orderer capabilities apply only to the orderers, and may be safely 146 | # used with prior release peers. 147 | # Set the value of the capability to true to require it. 148 | Orderer: &OrdererCapabilities 149 | # V1.4.2 for Orderer is a catchall flag for behavior which has been 150 | # determined to be desired for all orderers running at the v1.4.2 151 | # level, but which would be incompatible with orderers from prior releases. 152 | # Prior to enabling V1.4.2 orderer capabilities, ensure that all 153 | # orderers on a channel are at v1.4.2 or later. 154 | V1_4_2: true 155 | # V1.1 for Orderer enables the new non-backwards compatible 156 | # features and fixes of fabric v1.1 157 | V1_1: false 158 | 159 | # Application capabilities apply only to the peer network, and may be safely 160 | # used with prior release orderers. 161 | # Set the value of the capability to true to require it. 162 | Application: &ApplicationCapabilities 163 | # V1.4.2 for Application enables the new non-backwards compatible 164 | # features and fixes of fabric v1.4.2. 165 | V1_4_2: true 166 | # V1.3 for Application enables the new non-backwards compatible 167 | # features and fixes of fabric v1.3. 168 | V1_3: false 169 | # V1.2 for Application enables the new non-backwards compatible 170 | # features and fixes of fabric v1.2 (note, this need not be set if 171 | # later version capabilities are set) 172 | V1_2: false 173 | # V1.1 for Application enables the new non-backwards compatible 174 | # features and fixes of fabric v1.1 (note, this need not be set if 175 | # later version capabilities are set). 176 | V1_1: false 177 | 178 | ################################################################################ 179 | # 180 | # SECTION: Application 181 | # 182 | # - This section defines the values to encode into a config transaction or 183 | # genesis block for application related parameters 184 | # 185 | ################################################################################ 186 | Application: &ApplicationDefaults 187 | 188 | # Organizations is the list of orgs which are defined as participants on 189 | # the application side of the network 190 | Organizations: 191 | 192 | # Policies defines the set of policies at this level of the config tree 193 | # For Application policies, their canonical path is 194 | # /Channel/Application/ 195 | Policies: 196 | Readers: 197 | Type: ImplicitMeta 198 | Rule: "ANY Readers" 199 | Writers: 200 | Type: ImplicitMeta 201 | Rule: "ANY Writers" 202 | Admins: 203 | Type: ImplicitMeta 204 | Rule: "MAJORITY Admins" 205 | 206 | Capabilities: 207 | <<: *ApplicationCapabilities 208 | ################################################################################ 209 | # 210 | # SECTION: Orderer 211 | # 212 | # - This section defines the values to encode into a config transaction or 213 | # genesis block for orderer related parameters 214 | # 215 | ################################################################################ 216 | Orderer: &OrdererDefaults 217 | 218 | # Orderer Type: The orderer implementation to start 219 | # Available types are "solo","kafka" and "etcdraft" 220 | OrdererType: solo 221 | 222 | Addresses: 223 | - orderer.example.com:7050 224 | 225 | # Batch Timeout: The amount of time to wait before creating a batch 226 | BatchTimeout: 2s 227 | 228 | # Batch Size: Controls the number of messages batched into a block 229 | BatchSize: 230 | 231 | # Max Message Count: The maximum number of messages to permit in a batch 232 | MaxMessageCount: 10 233 | 234 | # Absolute Max Bytes: The absolute maximum number of bytes allowed for 235 | # the serialized messages in a batch. 236 | AbsoluteMaxBytes: 99 MB 237 | 238 | # Preferred Max Bytes: The preferred maximum number of bytes allowed for 239 | # the serialized messages in a batch. A message larger than the preferred 240 | # max bytes will result in a batch larger than preferred max bytes. 241 | PreferredMaxBytes: 512 KB 242 | 243 | Kafka: 244 | # Brokers: A list of Kafka brokers to which the orderer connects 245 | # NOTE: Use IP:port notation 246 | Brokers: 247 | - 172.0.0.1:9092 248 | 249 | # EtcdRaft defines configuration which must be set when the "etcdraft" 250 | # orderertype is chosen. 251 | EtcdRaft: 252 | # The set of Raft replicas for this network. For the etcd/raft-based 253 | # implementation, we expect every replica to also be an OSN. Therefore, 254 | # a subset of the host:port items enumerated in this list should be 255 | # replicated under the Orderer.Addresses key above. 256 | Consenters: 257 | - Host: orderer.example.com 258 | Port: 7050 259 | ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt 260 | ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt 261 | - Host: orderer2.example.com 262 | Port: 7050 263 | ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt 264 | ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt 265 | - Host: orderer3.example.com 266 | Port: 7050 267 | ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer3.example.com/tls/server.crt 268 | ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer3.example.com/tls/server.crt 269 | - Host: orderer4.example.com 270 | Port: 7050 271 | ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer4.example.com/tls/server.crt 272 | ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer4.example.com/tls/server.crt 273 | - Host: orderer5.example.com 274 | Port: 7050 275 | ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer5.example.com/tls/server.crt 276 | ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer5.example.com/tls/server.crt 277 | 278 | # Organizations is the list of orgs which are defined as participants on 279 | # the orderer side of the network 280 | Organizations: 281 | 282 | # Policies defines the set of policies at this level of the config tree 283 | # For Orderer policies, their canonical path is 284 | # /Channel/Orderer/ 285 | Policies: 286 | Readers: 287 | Type: ImplicitMeta 288 | Rule: "ANY Readers" 289 | Writers: 290 | Type: ImplicitMeta 291 | Rule: "ANY Writers" 292 | Admins: 293 | Type: ImplicitMeta 294 | Rule: "MAJORITY Admins" 295 | # BlockValidation specifies what signatures must be included in the block 296 | # from the orderer for the peer to validate it. 297 | BlockValidation: 298 | Type: ImplicitMeta 299 | Rule: "ANY Writers" 300 | 301 | ################################################################################ 302 | # 303 | # CHANNEL 304 | # 305 | # This section defines the values to encode into a config transaction or 306 | # genesis block for channel related parameters. 307 | # 308 | ################################################################################ 309 | Channel: &ChannelDefaults 310 | # Policies defines the set of policies at this level of the config tree 311 | # For Channel policies, their canonical path is 312 | # /Channel/ 313 | Policies: 314 | # Who may invoke the 'Deliver' API 315 | Readers: 316 | Type: ImplicitMeta 317 | Rule: "ANY Readers" 318 | # Who may invoke the 'Broadcast' API 319 | Writers: 320 | Type: ImplicitMeta 321 | Rule: "ANY Writers" 322 | # By default, who may modify elements at this config level 323 | Admins: 324 | Type: ImplicitMeta 325 | Rule: "MAJORITY Admins" 326 | 327 | # Capabilities describes the channel level capabilities, see the 328 | # dedicated Capabilities section elsewhere in this file for a full 329 | # description 330 | Capabilities: 331 | <<: *ChannelCapabilities 332 | 333 | ################################################################################ 334 | # 335 | # Profile 336 | # 337 | # - Different configuration profiles may be encoded here to be specified 338 | # as parameters to the configtxgen tool 339 | # 340 | ################################################################################ 341 | Profiles: 342 | 343 | TwoOrgsOrdererGenesis: 344 | <<: *ChannelDefaults 345 | Orderer: 346 | <<: *OrdererDefaults 347 | Organizations: 348 | - *OrdererOrg 349 | Capabilities: 350 | <<: *OrdererCapabilities 351 | Consortiums: 352 | SampleConsortium: 353 | Organizations: 354 | - *Org1 355 | - *Org2 356 | TwoOrgsChannel: 357 | Consortium: SampleConsortium 358 | <<: *ChannelDefaults 359 | Application: 360 | <<: *ApplicationDefaults 361 | Organizations: 362 | - *Org1 363 | - *Org2 364 | Capabilities: 365 | <<: *ApplicationCapabilities 366 | 367 | SampleDevModeKafka: 368 | <<: *ChannelDefaults 369 | Capabilities: 370 | <<: *ChannelCapabilities 371 | Orderer: 372 | <<: *OrdererDefaults 373 | OrdererType: kafka 374 | Kafka: 375 | Brokers: 376 | - kafka0.example.com:9092 377 | - kafka1.example.com:9092 378 | - kafka2.example.com:9092 379 | - kafka3.example.com:9092 380 | 381 | Organizations: 382 | - *OrdererOrg 383 | Capabilities: 384 | <<: *OrdererCapabilities 385 | Application: 386 | <<: *ApplicationDefaults 387 | Organizations: 388 | - <<: *OrdererOrg 389 | Consortiums: 390 | SampleConsortium: 391 | Organizations: 392 | - *Org1 393 | - *Org2 394 | 395 | SampleMultiNodeEtcdRaft: 396 | <<: *ChannelDefaults 397 | Capabilities: 398 | <<: *ChannelCapabilities 399 | Orderer: 400 | <<: *OrdererDefaults 401 | OrdererType: etcdraft 402 | EtcdRaft: 403 | Consenters: 404 | - Host: orderer.example.com 405 | Port: 7050 406 | ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt 407 | ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt 408 | - Host: orderer2.example.com 409 | Port: 7050 410 | ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt 411 | ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/server.crt 412 | - Host: orderer3.example.com 413 | Port: 7050 414 | ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer3.example.com/tls/server.crt 415 | ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer3.example.com/tls/server.crt 416 | - Host: orderer4.example.com 417 | Port: 7050 418 | ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer4.example.com/tls/server.crt 419 | ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer4.example.com/tls/server.crt 420 | - Host: orderer5.example.com 421 | Port: 7050 422 | ClientTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer5.example.com/tls/server.crt 423 | ServerTLSCert: crypto-config/ordererOrganizations/example.com/orderers/orderer5.example.com/tls/server.crt 424 | Addresses: 425 | - orderer.example.com:7050 426 | - orderer2.example.com:7050 427 | - orderer3.example.com:7050 428 | - orderer4.example.com:7050 429 | - orderer5.example.com:7050 430 | 431 | Organizations: 432 | - *OrdererOrg 433 | Capabilities: 434 | <<: *OrdererCapabilities 435 | Application: 436 | <<: *ApplicationDefaults 437 | Organizations: 438 | - <<: *OrdererOrg 439 | Consortiums: 440 | SampleConsortium: 441 | Organizations: 442 | - *Org1 443 | - *Org2 444 | -------------------------------------------------------------------------------- /first-network/connection-org1.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "first-network-org1", 3 | "version": "1.0.0", 4 | "client": { 5 | "organization": "Org1", 6 | "connection": { 7 | "timeout": { 8 | "peer": { 9 | "endorser": "300" 10 | } 11 | } 12 | } 13 | }, 14 | "organizations": { 15 | "Org1": { 16 | "mspid": "Org1MSP", 17 | "peers": [ 18 | "peer0.org1.example.com", 19 | "peer1.org1.example.com" 20 | ], 21 | "certificateAuthorities": [ 22 | "ca.org1.example.com" 23 | ] 24 | } 25 | }, 26 | "peers": { 27 | "peer0.org1.example.com": { 28 | "url": "grpcs://localhost:7051", 29 | "tlsCACerts": { 30 | "pem": "-----BEGIN CERTIFICATE-----\nMIICVzCCAf2gAwIBAgIQP40A0ki3A4Eg5isII8Md1jAKBggqhkjOPQQDAjB2MQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz\nY2Eub3JnMS5leGFtcGxlLmNvbTAeFw0yMDAxMTEwODM4MDBaFw0zMDAxMDgwODM4\nMDBaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH\nEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMR8wHQYD\nVQQDExZ0bHNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D\nAQcDQgAEYyDi10saag+/UMQg8il3Crn0rPHyH4GqqEdx4ZARPmsoTY2xvKxAwdzi\n3dOPirO7OvQ0zpZ+UvqhfTLgEAQi36NtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud\nJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud\nDgQiBCCaKCkD/DV0IWHgYkz7WhwmhxQJpc8nC3hNCfgqidYhRTAKBggqhkjOPQQD\nAgNIADBFAiEArIycl1ayNzSlncp138crg0Uwh7rIPq69BsTKu4vFpWgCIAMTXl2z\n7cHHTMy41lvc/89nfwLsBBnW1onRpmD2LBYj\n-----END CERTIFICATE-----\n" 31 | }, 32 | "grpcOptions": { 33 | "ssl-target-name-override": "peer0.org1.example.com", 34 | "hostnameOverride": "peer0.org1.example.com" 35 | } 36 | }, 37 | "peer1.org1.example.com": { 38 | "url": "grpcs://localhost:8051", 39 | "tlsCACerts": { 40 | "pem": "-----BEGIN CERTIFICATE-----\nMIICVzCCAf2gAwIBAgIQP40A0ki3A4Eg5isII8Md1jAKBggqhkjOPQQDAjB2MQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz\nY2Eub3JnMS5leGFtcGxlLmNvbTAeFw0yMDAxMTEwODM4MDBaFw0zMDAxMDgwODM4\nMDBaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH\nEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMR8wHQYD\nVQQDExZ0bHNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D\nAQcDQgAEYyDi10saag+/UMQg8il3Crn0rPHyH4GqqEdx4ZARPmsoTY2xvKxAwdzi\n3dOPirO7OvQ0zpZ+UvqhfTLgEAQi36NtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud\nJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud\nDgQiBCCaKCkD/DV0IWHgYkz7WhwmhxQJpc8nC3hNCfgqidYhRTAKBggqhkjOPQQD\nAgNIADBFAiEArIycl1ayNzSlncp138crg0Uwh7rIPq69BsTKu4vFpWgCIAMTXl2z\n7cHHTMy41lvc/89nfwLsBBnW1onRpmD2LBYj\n-----END CERTIFICATE-----\n" 41 | }, 42 | "grpcOptions": { 43 | "ssl-target-name-override": "peer1.org1.example.com", 44 | "hostnameOverride": "peer1.org1.example.com" 45 | } 46 | } 47 | }, 48 | "certificateAuthorities": { 49 | "ca.org1.example.com": { 50 | "url": "https://localhost:7054", 51 | "caName": "ca-org1", 52 | "tlsCACerts": { 53 | "pem": "-----BEGIN CERTIFICATE-----\nMIICUTCCAfegAwIBAgIQIbDAH/Y5RAxzqzDPhyHJiDAKBggqhkjOPQQDAjBzMQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMTY2Eu\nb3JnMS5leGFtcGxlLmNvbTAeFw0yMDAxMTEwODM4MDBaFw0zMDAxMDgwODM4MDBa\nMHMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T\nYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMRwwGgYDVQQD\nExNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\nkFsN9P/BfuOWHMgyfhmCnDQn8ab8ly21S+7KgR+HlSdpXWF0XsoupgjaEedX+iIn\ntewtnu3UVNiDAZUjk08Q/qNtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1UdJQQWMBQG\nCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBs\nLgsC097wSD10vHHN5Ad5PXp8XoZM6dhbvQdtilLh8zAKBggqhkjOPQQDAgNIADBF\nAiEA4pWHR6/t69yrvk8cacgIo5UV8zXfTBoyprR7xKJ3IOICIGUUdtS8oF8J3yBH\n+3WI1yvwS3qZxPq6nXokadFk81tX\n-----END CERTIFICATE-----\n" 54 | }, 55 | "httpOptions": { 56 | "verify": false 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /first-network/connection-org1.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: first-network-org1 3 | version: 1.0.0 4 | client: 5 | organization: Org1 6 | connection: 7 | timeout: 8 | peer: 9 | endorser: '300' 10 | organizations: 11 | Org1: 12 | mspid: Org1MSP 13 | peers: 14 | - peer0.org1.example.com 15 | - peer1.org1.example.com 16 | certificateAuthorities: 17 | - ca.org1.example.com 18 | peers: 19 | peer0.org1.example.com: 20 | url: grpcs://localhost:7051 21 | tlsCACerts: 22 | pem: | 23 | -----BEGIN CERTIFICATE----- 24 | MIICVzCCAf2gAwIBAgIQP40A0ki3A4Eg5isII8Md1jAKBggqhkjOPQQDAjB2MQsw 25 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 26 | YW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz 27 | Y2Eub3JnMS5leGFtcGxlLmNvbTAeFw0yMDAxMTEwODM4MDBaFw0zMDAxMDgwODM4 28 | MDBaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH 29 | Ew1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMR8wHQYD 30 | VQQDExZ0bHNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D 31 | AQcDQgAEYyDi10saag+/UMQg8il3Crn0rPHyH4GqqEdx4ZARPmsoTY2xvKxAwdzi 32 | 3dOPirO7OvQ0zpZ+UvqhfTLgEAQi36NtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud 33 | JQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud 34 | DgQiBCCaKCkD/DV0IWHgYkz7WhwmhxQJpc8nC3hNCfgqidYhRTAKBggqhkjOPQQD 35 | AgNIADBFAiEArIycl1ayNzSlncp138crg0Uwh7rIPq69BsTKu4vFpWgCIAMTXl2z 36 | 7cHHTMy41lvc/89nfwLsBBnW1onRpmD2LBYj 37 | -----END CERTIFICATE----- 38 | 39 | grpcOptions: 40 | ssl-target-name-override: peer0.org1.example.com 41 | hostnameOverride: peer0.org1.example.com 42 | peer1.org1.example.com: 43 | url: grpcs://localhost:8051 44 | tlsCACerts: 45 | pem: | 46 | -----BEGIN CERTIFICATE----- 47 | MIICVzCCAf2gAwIBAgIQP40A0ki3A4Eg5isII8Md1jAKBggqhkjOPQQDAjB2MQsw 48 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 49 | YW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz 50 | Y2Eub3JnMS5leGFtcGxlLmNvbTAeFw0yMDAxMTEwODM4MDBaFw0zMDAxMDgwODM4 51 | MDBaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH 52 | Ew1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMR8wHQYD 53 | VQQDExZ0bHNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D 54 | AQcDQgAEYyDi10saag+/UMQg8il3Crn0rPHyH4GqqEdx4ZARPmsoTY2xvKxAwdzi 55 | 3dOPirO7OvQ0zpZ+UvqhfTLgEAQi36NtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud 56 | JQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud 57 | DgQiBCCaKCkD/DV0IWHgYkz7WhwmhxQJpc8nC3hNCfgqidYhRTAKBggqhkjOPQQD 58 | AgNIADBFAiEArIycl1ayNzSlncp138crg0Uwh7rIPq69BsTKu4vFpWgCIAMTXl2z 59 | 7cHHTMy41lvc/89nfwLsBBnW1onRpmD2LBYj 60 | -----END CERTIFICATE----- 61 | 62 | grpcOptions: 63 | ssl-target-name-override: peer1.org1.example.com 64 | hostnameOverride: peer1.org1.example.com 65 | certificateAuthorities: 66 | ca.org1.example.com: 67 | url: https://localhost:7054 68 | caName: ca-org1 69 | tlsCACerts: 70 | pem: | 71 | -----BEGIN CERTIFICATE----- 72 | MIICUTCCAfegAwIBAgIQIbDAH/Y5RAxzqzDPhyHJiDAKBggqhkjOPQQDAjBzMQsw 73 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 74 | YW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMTY2Eu 75 | b3JnMS5leGFtcGxlLmNvbTAeFw0yMDAxMTEwODM4MDBaFw0zMDAxMDgwODM4MDBa 76 | MHMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T 77 | YW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMRwwGgYDVQQD 78 | ExNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE 79 | kFsN9P/BfuOWHMgyfhmCnDQn8ab8ly21S+7KgR+HlSdpXWF0XsoupgjaEedX+iIn 80 | tewtnu3UVNiDAZUjk08Q/qNtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1UdJQQWMBQG 81 | CCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCBs 82 | LgsC097wSD10vHHN5Ad5PXp8XoZM6dhbvQdtilLh8zAKBggqhkjOPQQDAgNIADBF 83 | AiEA4pWHR6/t69yrvk8cacgIo5UV8zXfTBoyprR7xKJ3IOICIGUUdtS8oF8J3yBH 84 | +3WI1yvwS3qZxPq6nXokadFk81tX 85 | -----END CERTIFICATE----- 86 | 87 | httpOptions: 88 | verify: false 89 | -------------------------------------------------------------------------------- /first-network/connection-org2.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "first-network-org2", 3 | "version": "1.0.0", 4 | "client": { 5 | "organization": "Org2", 6 | "connection": { 7 | "timeout": { 8 | "peer": { 9 | "endorser": "300" 10 | } 11 | } 12 | } 13 | }, 14 | "organizations": { 15 | "Org2": { 16 | "mspid": "Org2MSP", 17 | "peers": [ 18 | "peer0.org2.example.com", 19 | "peer1.org2.example.com" 20 | ], 21 | "certificateAuthorities": [ 22 | "ca.org2.example.com" 23 | ] 24 | } 25 | }, 26 | "peers": { 27 | "peer0.org2.example.com": { 28 | "url": "grpcs://localhost:9051", 29 | "tlsCACerts": { 30 | "pem": "-----BEGIN CERTIFICATE-----\nMIICVzCCAf2gAwIBAgIQAWgZ5+8EUfq39WLi9QnPvDAKBggqhkjOPQQDAjB2MQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz\nY2Eub3JnMi5leGFtcGxlLmNvbTAeFw0yMDAxMTEwODM4MDBaFw0zMDAxMDgwODM4\nMDBaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH\nEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcyLmV4YW1wbGUuY29tMR8wHQYD\nVQQDExZ0bHNjYS5vcmcyLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D\nAQcDQgAEOlrM9BCzt5rqAvhuDh/xLlTSPNmpbBajgJ4X0R+im/JigZdnuCyFbZs2\n2NWCJC26w5LgA3yjoG4FnDkCUV+GV6NtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud\nJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud\nDgQiBCDt22SZPLmeprhOFCOMx2ZEWYqryvq/6KXlMs8aSXe4RDAKBggqhkjOPQQD\nAgNIADBFAiEAzqDXY3n5EIC7vkunWrW0d8zKVNOUUP6MjAt7CxbO1BcCIEQsUVUA\nXPQn7GjPGMLtrBcZkMzMiRKIK+ryuwSLj/XR\n-----END CERTIFICATE-----\n" 31 | }, 32 | "grpcOptions": { 33 | "ssl-target-name-override": "peer0.org2.example.com", 34 | "hostnameOverride": "peer0.org2.example.com" 35 | } 36 | }, 37 | "peer1.org2.example.com": { 38 | "url": "grpcs://localhost:10051", 39 | "tlsCACerts": { 40 | "pem": "-----BEGIN CERTIFICATE-----\nMIICVzCCAf2gAwIBAgIQAWgZ5+8EUfq39WLi9QnPvDAKBggqhkjOPQQDAjB2MQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz\nY2Eub3JnMi5leGFtcGxlLmNvbTAeFw0yMDAxMTEwODM4MDBaFw0zMDAxMDgwODM4\nMDBaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH\nEw1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcyLmV4YW1wbGUuY29tMR8wHQYD\nVQQDExZ0bHNjYS5vcmcyLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D\nAQcDQgAEOlrM9BCzt5rqAvhuDh/xLlTSPNmpbBajgJ4X0R+im/JigZdnuCyFbZs2\n2NWCJC26w5LgA3yjoG4FnDkCUV+GV6NtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud\nJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud\nDgQiBCDt22SZPLmeprhOFCOMx2ZEWYqryvq/6KXlMs8aSXe4RDAKBggqhkjOPQQD\nAgNIADBFAiEAzqDXY3n5EIC7vkunWrW0d8zKVNOUUP6MjAt7CxbO1BcCIEQsUVUA\nXPQn7GjPGMLtrBcZkMzMiRKIK+ryuwSLj/XR\n-----END CERTIFICATE-----\n" 41 | }, 42 | "grpcOptions": { 43 | "ssl-target-name-override": "peer1.org2.example.com", 44 | "hostnameOverride": "peer1.org2.example.com" 45 | } 46 | } 47 | }, 48 | "certificateAuthorities": { 49 | "ca.org2.example.com": { 50 | "url": "https://localhost:8054", 51 | "caName": "ca-org2", 52 | "tlsCACerts": { 53 | "pem": "-----BEGIN CERTIFICATE-----\nMIICUDCCAfegAwIBAgIQe3p3sbQpWLAPCufGbwnxETAKBggqhkjOPQQDAjBzMQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEcMBoGA1UEAxMTY2Eu\nb3JnMi5leGFtcGxlLmNvbTAeFw0yMDAxMTEwODM4MDBaFw0zMDAxMDgwODM4MDBa\nMHMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T\nYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcyLmV4YW1wbGUuY29tMRwwGgYDVQQD\nExNjYS5vcmcyLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\n5jnzUph2E/lUDEw34tNR2Fn5k3gNlkvcGvcfOIFNReUCSZtR/Z6+aSOlmXvCno01\n9MBdP5cn1ljDvLSgkUPA96NtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1UdJQQWMBQG\nCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCA5\nmKjuOIKV0CzrZLFwhP8waASG0WdMf/H+ZogpFChOTDAKBggqhkjOPQQDAgNHADBE\nAiBpWaa0jnC9F1oHNaajfHArbWiZc1MI9UsEsUACKEzRxQIgVZ3v4QBl3e4gGyUq\n+5/jxI2Mw18/l2fit/gP0+U/wac=\n-----END CERTIFICATE-----\n" 54 | }, 55 | "httpOptions": { 56 | "verify": false 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /first-network/connection-org2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: first-network-org2 3 | version: 1.0.0 4 | client: 5 | organization: Org2 6 | connection: 7 | timeout: 8 | peer: 9 | endorser: '300' 10 | organizations: 11 | Org2: 12 | mspid: Org2MSP 13 | peers: 14 | - peer0.org2.example.com 15 | - peer1.org2.example.com 16 | certificateAuthorities: 17 | - ca.org2.example.com 18 | peers: 19 | peer0.org2.example.com: 20 | url: grpcs://localhost:9051 21 | tlsCACerts: 22 | pem: | 23 | -----BEGIN CERTIFICATE----- 24 | MIICVzCCAf2gAwIBAgIQAWgZ5+8EUfq39WLi9QnPvDAKBggqhkjOPQQDAjB2MQsw 25 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 26 | YW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz 27 | Y2Eub3JnMi5leGFtcGxlLmNvbTAeFw0yMDAxMTEwODM4MDBaFw0zMDAxMDgwODM4 28 | MDBaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH 29 | Ew1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcyLmV4YW1wbGUuY29tMR8wHQYD 30 | VQQDExZ0bHNjYS5vcmcyLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D 31 | AQcDQgAEOlrM9BCzt5rqAvhuDh/xLlTSPNmpbBajgJ4X0R+im/JigZdnuCyFbZs2 32 | 2NWCJC26w5LgA3yjoG4FnDkCUV+GV6NtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud 33 | JQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud 34 | DgQiBCDt22SZPLmeprhOFCOMx2ZEWYqryvq/6KXlMs8aSXe4RDAKBggqhkjOPQQD 35 | AgNIADBFAiEAzqDXY3n5EIC7vkunWrW0d8zKVNOUUP6MjAt7CxbO1BcCIEQsUVUA 36 | XPQn7GjPGMLtrBcZkMzMiRKIK+ryuwSLj/XR 37 | -----END CERTIFICATE----- 38 | 39 | grpcOptions: 40 | ssl-target-name-override: peer0.org2.example.com 41 | hostnameOverride: peer0.org2.example.com 42 | peer1.org2.example.com: 43 | url: grpcs://localhost:10051 44 | tlsCACerts: 45 | pem: | 46 | -----BEGIN CERTIFICATE----- 47 | MIICVzCCAf2gAwIBAgIQAWgZ5+8EUfq39WLi9QnPvDAKBggqhkjOPQQDAjB2MQsw 48 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 49 | YW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz 50 | Y2Eub3JnMi5leGFtcGxlLmNvbTAeFw0yMDAxMTEwODM4MDBaFw0zMDAxMDgwODM4 51 | MDBaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH 52 | Ew1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcyLmV4YW1wbGUuY29tMR8wHQYD 53 | VQQDExZ0bHNjYS5vcmcyLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D 54 | AQcDQgAEOlrM9BCzt5rqAvhuDh/xLlTSPNmpbBajgJ4X0R+im/JigZdnuCyFbZs2 55 | 2NWCJC26w5LgA3yjoG4FnDkCUV+GV6NtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1Ud 56 | JQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1Ud 57 | DgQiBCDt22SZPLmeprhOFCOMx2ZEWYqryvq/6KXlMs8aSXe4RDAKBggqhkjOPQQD 58 | AgNIADBFAiEAzqDXY3n5EIC7vkunWrW0d8zKVNOUUP6MjAt7CxbO1BcCIEQsUVUA 59 | XPQn7GjPGMLtrBcZkMzMiRKIK+ryuwSLj/XR 60 | -----END CERTIFICATE----- 61 | 62 | grpcOptions: 63 | ssl-target-name-override: peer1.org2.example.com 64 | hostnameOverride: peer1.org2.example.com 65 | certificateAuthorities: 66 | ca.org2.example.com: 67 | url: https://localhost:8054 68 | caName: ca-org2 69 | tlsCACerts: 70 | pem: | 71 | -----BEGIN CERTIFICATE----- 72 | MIICUDCCAfegAwIBAgIQe3p3sbQpWLAPCufGbwnxETAKBggqhkjOPQQDAjBzMQsw 73 | CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy 74 | YW5jaXNjbzEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEcMBoGA1UEAxMTY2Eu 75 | b3JnMi5leGFtcGxlLmNvbTAeFw0yMDAxMTEwODM4MDBaFw0zMDAxMDgwODM4MDBa 76 | MHMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T 77 | YW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcyLmV4YW1wbGUuY29tMRwwGgYDVQQD 78 | ExNjYS5vcmcyLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE 79 | 5jnzUph2E/lUDEw34tNR2Fn5k3gNlkvcGvcfOIFNReUCSZtR/Z6+aSOlmXvCno01 80 | 9MBdP5cn1ljDvLSgkUPA96NtMGswDgYDVR0PAQH/BAQDAgGmMB0GA1UdJQQWMBQG 81 | CCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdDgQiBCA5 82 | mKjuOIKV0CzrZLFwhP8waASG0WdMf/H+ZogpFChOTDAKBggqhkjOPQQDAgNHADBE 83 | AiBpWaa0jnC9F1oHNaajfHArbWiZc1MI9UsEsUACKEzRxQIgVZ3v4QBl3e4gGyUq 84 | +5/jxI2Mw18/l2fit/gP0+U/wac= 85 | -----END CERTIFICATE----- 86 | 87 | httpOptions: 88 | verify: false 89 | -------------------------------------------------------------------------------- /first-network/connection-org3.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "first-network-org3", 3 | "version": "1.0.0", 4 | "client": { 5 | "organization": "Org3", 6 | "connection": { 7 | "timeout": { 8 | "peer": { 9 | "endorser": "300" 10 | } 11 | } 12 | } 13 | }, 14 | "organizations": { 15 | "Org3": { 16 | "mspid": "Org3MSP", 17 | "peers": [ 18 | "peer0.org3.example.com", 19 | "peer1.org3.example.com" 20 | ] 21 | } 22 | }, 23 | "peers": { 24 | "peer0.org3.example.com": { 25 | "url": "grpcs://localhost:11051", 26 | "tlsCACerts": { 27 | "path": "org3-artifacts/crypto-config/peerOrganizations/org3.example.com/tlsca/tlsca.org3.example.com-cert.pem" 28 | }, 29 | "grpcOptions": { 30 | "ssl-target-name-override": "peer0.org3.example.com" 31 | } 32 | }, 33 | "peer1.org3.example.com": { 34 | "url": "grpcs://localhost:12051", 35 | "tlsCACerts": { 36 | "path": "org3-artifacts/crypto-config/peerOrganizations/org3.example.com/tlsca/tlsca.org3.example.com-cert.pem" 37 | }, 38 | "grpcOptions": { 39 | "ssl-target-name-override": "peer1.org3.example.com" 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /first-network/connection-org3.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: first-network-org3 3 | version: 1.0.0 4 | client: 5 | organization: Org3 6 | connection: 7 | timeout: 8 | peer: 9 | endorser: '300' 10 | organizations: 11 | Org3: 12 | mspid: Org3MSP 13 | peers: 14 | - peer0.org3.example.com 15 | - peer1.org3.example.com 16 | peers: 17 | peer0.org3.example.com: 18 | url: grpcs://localhost:11051 19 | tlsCACerts: 20 | path: org3-artifacts/crypto-config/peerOrganizations/org3.example.com/tlsca/tlsca.org3.example.com-cert.pem 21 | grpcOptions: 22 | ssl-target-name-override: peer0.org3.example.com 23 | peer1.org3.example.com: 24 | url: grpcs://localhost:12051 25 | tlsCACerts: 26 | path: org3-artifacts/crypto-config/peerOrganizations/org3.example.com/tlsca/tlsca.org3.example.com-cert.pem 27 | grpcOptions: 28 | ssl-target-name-override: peer1.org3.example.com 29 | -------------------------------------------------------------------------------- /first-network/crypto-config.yaml: -------------------------------------------------------------------------------- 1 | # Copyright IBM Corp. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | 6 | # --------------------------------------------------------------------------- 7 | # "OrdererOrgs" - Definition of organizations managing orderer nodes 8 | # --------------------------------------------------------------------------- 9 | OrdererOrgs: 10 | # --------------------------------------------------------------------------- 11 | # Orderer 12 | # --------------------------------------------------------------------------- 13 | - Name: Orderer 14 | Domain: example.com 15 | EnableNodeOUs: true 16 | # --------------------------------------------------------------------------- 17 | # "Specs" - See PeerOrgs below for complete description 18 | # --------------------------------------------------------------------------- 19 | Specs: 20 | - Hostname: orderer 21 | - Hostname: orderer2 22 | - Hostname: orderer3 23 | - Hostname: orderer4 24 | - Hostname: orderer5 25 | 26 | # --------------------------------------------------------------------------- 27 | # "PeerOrgs" - Definition of organizations managing peer nodes 28 | # --------------------------------------------------------------------------- 29 | PeerOrgs: 30 | # --------------------------------------------------------------------------- 31 | # Org1 32 | # --------------------------------------------------------------------------- 33 | - Name: Org1 34 | Domain: org1.example.com 35 | EnableNodeOUs: true 36 | # --------------------------------------------------------------------------- 37 | # "Specs" 38 | # --------------------------------------------------------------------------- 39 | # Uncomment this section to enable the explicit definition of hosts in your 40 | # configuration. Most users will want to use Template, below 41 | # 42 | # Specs is an array of Spec entries. Each Spec entry consists of two fields: 43 | # - Hostname: (Required) The desired hostname, sans the domain. 44 | # - CommonName: (Optional) Specifies the template or explicit override for 45 | # the CN. By default, this is the template: 46 | # 47 | # "{{.Hostname}}.{{.Domain}}" 48 | # 49 | # which obtains its values from the Spec.Hostname and 50 | # Org.Domain, respectively. 51 | # --------------------------------------------------------------------------- 52 | # Specs: 53 | # - Hostname: foo # implicitly "foo.org1.example.com" 54 | # CommonName: foo27.org5.example.com # overrides Hostname-based FQDN set above 55 | # - Hostname: bar 56 | # - Hostname: baz 57 | # --------------------------------------------------------------------------- 58 | # "Template" 59 | # --------------------------------------------------------------------------- 60 | # Allows for the definition of 1 or more hosts that are created sequentially 61 | # from a template. By default, this looks like "peer%d" from 0 to Count-1. 62 | # You may override the number of nodes (Count), the starting index (Start) 63 | # or the template used to construct the name (Hostname). 64 | # 65 | # Note: Template and Specs are not mutually exclusive. You may define both 66 | # sections and the aggregate nodes will be created for you. Take care with 67 | # name collisions 68 | # --------------------------------------------------------------------------- 69 | Template: 70 | Count: 2 71 | # Start: 5 72 | # Hostname: {{.Prefix}}{{.Index}} # default 73 | # --------------------------------------------------------------------------- 74 | # "Users" 75 | # --------------------------------------------------------------------------- 76 | # Count: The number of user accounts _in addition_ to Admin 77 | # --------------------------------------------------------------------------- 78 | Users: 79 | Count: 1 80 | # --------------------------------------------------------------------------- 81 | # Org2: See "Org1" for full specification 82 | # --------------------------------------------------------------------------- 83 | - Name: Org2 84 | Domain: org2.example.com 85 | EnableNodeOUs: true 86 | Template: 87 | Count: 2 88 | Users: 89 | Count: 1 90 | -------------------------------------------------------------------------------- /first-network/docker-compose-ca.yaml: -------------------------------------------------------------------------------- 1 | # Copyright IBM Corp. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | 6 | version: '2' 7 | 8 | networks: 9 | byfn: 10 | 11 | services: 12 | ca0: 13 | image: hyperledger/fabric-ca:$IMAGE_TAG 14 | environment: 15 | - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server 16 | - FABRIC_CA_SERVER_CA_NAME=ca-org1 17 | - FABRIC_CA_SERVER_TLS_ENABLED=true 18 | - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem 19 | - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/${BYFN_CA1_PRIVATE_KEY} 20 | - FABRIC_CA_SERVER_PORT=7054 21 | ports: 22 | - "7054:7054" 23 | command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/${BYFN_CA1_PRIVATE_KEY} -b admin:adminpw -d' 24 | volumes: 25 | - ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config 26 | container_name: ca_peerOrg1 27 | networks: 28 | - byfn 29 | 30 | ca1: 31 | image: hyperledger/fabric-ca:$IMAGE_TAG 32 | environment: 33 | - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server 34 | - FABRIC_CA_SERVER_CA_NAME=ca-org2 35 | - FABRIC_CA_SERVER_TLS_ENABLED=true 36 | - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org2.example.com-cert.pem 37 | - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/${BYFN_CA2_PRIVATE_KEY} 38 | - FABRIC_CA_SERVER_PORT=8054 39 | ports: 40 | - "8054:8054" 41 | command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org2.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/${BYFN_CA2_PRIVATE_KEY} -b admin:adminpw -d' 42 | volumes: 43 | - ./crypto-config/peerOrganizations/org2.example.com/ca/:/etc/hyperledger/fabric-ca-server-config 44 | container_name: ca_peerOrg2 45 | networks: 46 | - byfn -------------------------------------------------------------------------------- /first-network/docker-compose-cli.yaml: -------------------------------------------------------------------------------- 1 | # Copyright IBM Corp. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | 6 | version: '2' 7 | 8 | volumes: 9 | orderer.example.com: 10 | peer0.org1.example.com: 11 | peer1.org1.example.com: 12 | peer0.org2.example.com: 13 | peer1.org2.example.com: 14 | 15 | networks: 16 | byfn: 17 | 18 | services: 19 | 20 | orderer.example.com: 21 | extends: 22 | file: base/docker-compose-base.yaml 23 | service: orderer.example.com 24 | container_name: orderer.example.com 25 | networks: 26 | - byfn 27 | 28 | peer0.org1.example.com: 29 | container_name: peer0.org1.example.com 30 | extends: 31 | file: base/docker-compose-base.yaml 32 | service: peer0.org1.example.com 33 | networks: 34 | - byfn 35 | 36 | peer1.org1.example.com: 37 | container_name: peer1.org1.example.com 38 | extends: 39 | file: base/docker-compose-base.yaml 40 | service: peer1.org1.example.com 41 | networks: 42 | - byfn 43 | 44 | peer0.org2.example.com: 45 | container_name: peer0.org2.example.com 46 | extends: 47 | file: base/docker-compose-base.yaml 48 | service: peer0.org2.example.com 49 | networks: 50 | - byfn 51 | 52 | peer1.org2.example.com: 53 | container_name: peer1.org2.example.com 54 | extends: 55 | file: base/docker-compose-base.yaml 56 | service: peer1.org2.example.com 57 | networks: 58 | - byfn 59 | 60 | cli: 61 | container_name: cli 62 | image: hyperledger/fabric-tools:$IMAGE_TAG 63 | tty: true 64 | stdin_open: true 65 | environment: 66 | - SYS_CHANNEL=$SYS_CHANNEL 67 | - GOPATH=/opt/gopath 68 | - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock 69 | #- FABRIC_LOGGING_SPEC=DEBUG 70 | - FABRIC_LOGGING_SPEC=INFO 71 | - CORE_PEER_ID=cli 72 | - CORE_PEER_ADDRESS=peer0.org1.example.com:7051 73 | - CORE_PEER_LOCALMSPID=Org1MSP 74 | - CORE_PEER_TLS_ENABLED=true 75 | - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.crt 76 | - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/server.key 77 | - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt 78 | - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp 79 | working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer 80 | command: /bin/bash 81 | volumes: 82 | - /var/run/:/host/var/run/ 83 | - ./../chaincode/:/opt/gopath/src/github.com/chaincode 84 | - ./crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ 85 | - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/ 86 | - ./channel-artifacts:/opt/gopath/src/github.com/hyperledger/fabric/peer/channel-artifacts 87 | depends_on: 88 | - orderer.example.com 89 | - peer0.org1.example.com 90 | - peer1.org1.example.com 91 | - peer0.org2.example.com 92 | - peer1.org2.example.com 93 | networks: 94 | - byfn 95 | -------------------------------------------------------------------------------- /first-network/docker-compose-couch-org3.yaml: -------------------------------------------------------------------------------- 1 | # Copyright IBM Corp. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | 6 | version: '2' 7 | 8 | networks: 9 | byfn: 10 | 11 | services: 12 | couchdb4: 13 | container_name: couchdb4 14 | image: hyperledger/fabric-couchdb 15 | # Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password 16 | # for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode. 17 | environment: 18 | - COUCHDB_USER= 19 | - COUCHDB_PASSWORD= 20 | # Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service, 21 | # for example map it to utilize Fauxton User Interface in dev environments. 22 | ports: 23 | - "9984:5984" 24 | networks: 25 | - byfn 26 | 27 | peer0.org3.example.com: 28 | environment: 29 | - CORE_LEDGER_STATE_STATEDATABASE=CouchDB 30 | - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb4:5984 31 | # The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD 32 | # provide the credentials for ledger to connect to CouchDB. The username and password must 33 | # match the username and password set for the associated CouchDB. 34 | - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME= 35 | - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD= 36 | depends_on: 37 | - couchdb4 38 | 39 | couchdb5: 40 | container_name: couchdb5 41 | image: hyperledger/fabric-couchdb 42 | # Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password 43 | # for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode. 44 | environment: 45 | - COUCHDB_USER= 46 | - COUCHDB_PASSWORD= 47 | # Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service, 48 | # for example map it to utilize Fauxton User Interface in dev environments. 49 | ports: 50 | - "10984:5984" 51 | networks: 52 | - byfn 53 | 54 | peer1.org3.example.com: 55 | environment: 56 | - CORE_LEDGER_STATE_STATEDATABASE=CouchDB 57 | - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb5:5984 58 | # The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD 59 | # provide the credentials for ledger to connect to CouchDB. The username and password must 60 | # match the username and password set for the associated CouchDB. 61 | - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME= 62 | - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD= 63 | depends_on: 64 | - couchdb5 65 | -------------------------------------------------------------------------------- /first-network/docker-compose-couch.yaml: -------------------------------------------------------------------------------- 1 | # Copyright IBM Corp. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | 6 | version: '2' 7 | 8 | networks: 9 | byfn: 10 | 11 | services: 12 | couchdb0: 13 | container_name: couchdb0 14 | image: hyperledger/fabric-couchdb 15 | # Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password 16 | # for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode. 17 | environment: 18 | - COUCHDB_USER= 19 | - COUCHDB_PASSWORD= 20 | # Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service, 21 | # for example map it to utilize Fauxton User Interface in dev environments. 22 | ports: 23 | - "5984:5984" 24 | networks: 25 | - byfn 26 | 27 | peer0.org1.example.com: 28 | environment: 29 | - CORE_LEDGER_STATE_STATEDATABASE=CouchDB 30 | - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0:5984 31 | # The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD 32 | # provide the credentials for ledger to connect to CouchDB. The username and password must 33 | # match the username and password set for the associated CouchDB. 34 | - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME= 35 | - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD= 36 | depends_on: 37 | - couchdb0 38 | 39 | couchdb1: 40 | container_name: couchdb1 41 | image: hyperledger/fabric-couchdb 42 | # Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password 43 | # for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode. 44 | environment: 45 | - COUCHDB_USER= 46 | - COUCHDB_PASSWORD= 47 | # Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service, 48 | # for example map it to utilize Fauxton User Interface in dev environments. 49 | ports: 50 | - "6984:5984" 51 | networks: 52 | - byfn 53 | 54 | peer1.org1.example.com: 55 | environment: 56 | - CORE_LEDGER_STATE_STATEDATABASE=CouchDB 57 | - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb1:5984 58 | # The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD 59 | # provide the credentials for ledger to connect to CouchDB. The username and password must 60 | # match the username and password set for the associated CouchDB. 61 | - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME= 62 | - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD= 63 | depends_on: 64 | - couchdb1 65 | 66 | couchdb2: 67 | container_name: couchdb2 68 | image: hyperledger/fabric-couchdb 69 | # Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password 70 | # for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode. 71 | environment: 72 | - COUCHDB_USER= 73 | - COUCHDB_PASSWORD= 74 | # Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service, 75 | # for example map it to utilize Fauxton User Interface in dev environments. 76 | ports: 77 | - "7984:5984" 78 | networks: 79 | - byfn 80 | 81 | peer0.org2.example.com: 82 | environment: 83 | - CORE_LEDGER_STATE_STATEDATABASE=CouchDB 84 | - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb2:5984 85 | # The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD 86 | # provide the credentials for ledger to connect to CouchDB. The username and password must 87 | # match the username and password set for the associated CouchDB. 88 | - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME= 89 | - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD= 90 | depends_on: 91 | - couchdb2 92 | 93 | couchdb3: 94 | container_name: couchdb3 95 | image: hyperledger/fabric-couchdb 96 | # Populate the COUCHDB_USER and COUCHDB_PASSWORD to set an admin user and password 97 | # for CouchDB. This will prevent CouchDB from operating in an "Admin Party" mode. 98 | environment: 99 | - COUCHDB_USER= 100 | - COUCHDB_PASSWORD= 101 | # Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service, 102 | # for example map it to utilize Fauxton User Interface in dev environments. 103 | ports: 104 | - "8984:5984" 105 | networks: 106 | - byfn 107 | 108 | peer1.org2.example.com: 109 | environment: 110 | - CORE_LEDGER_STATE_STATEDATABASE=CouchDB 111 | - CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb3:5984 112 | # The CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME and CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD 113 | # provide the credentials for ledger to connect to CouchDB. The username and password must 114 | # match the username and password set for the associated CouchDB. 115 | - CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME= 116 | - CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD= 117 | depends_on: 118 | - couchdb3 119 | -------------------------------------------------------------------------------- /first-network/docker-compose-e2e-template.yaml: -------------------------------------------------------------------------------- 1 | # Copyright IBM Corp. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | 6 | version: '2' 7 | 8 | volumes: 9 | orderer.example.com: 10 | peer0.org1.example.com: 11 | peer1.org1.example.com: 12 | peer0.org2.example.com: 13 | peer1.org2.example.com: 14 | 15 | networks: 16 | byfn: 17 | services: 18 | ca0: 19 | image: hyperledger/fabric-ca:$IMAGE_TAG 20 | environment: 21 | - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server 22 | - FABRIC_CA_SERVER_CA_NAME=ca-org1 23 | - FABRIC_CA_SERVER_TLS_ENABLED=true 24 | - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem 25 | - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/CA1_PRIVATE_KEY 26 | ports: 27 | - "7054:7054" 28 | command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/CA1_PRIVATE_KEY -b admin:adminpw -d' 29 | volumes: 30 | - ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config 31 | container_name: ca_peerOrg1 32 | networks: 33 | - byfn 34 | 35 | ca1: 36 | image: hyperledger/fabric-ca:$IMAGE_TAG 37 | environment: 38 | - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server 39 | - FABRIC_CA_SERVER_CA_NAME=ca-org2 40 | - FABRIC_CA_SERVER_TLS_ENABLED=true 41 | - FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org2.example.com-cert.pem 42 | - FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/CA2_PRIVATE_KEY 43 | ports: 44 | - "8054:7054" 45 | command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/ca.org2.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/CA2_PRIVATE_KEY -b admin:adminpw -d' 46 | volumes: 47 | - ./crypto-config/peerOrganizations/org2.example.com/ca/:/etc/hyperledger/fabric-ca-server-config 48 | container_name: ca_peerOrg2 49 | networks: 50 | - byfn 51 | 52 | orderer.example.com: 53 | extends: 54 | file: base/docker-compose-base.yaml 55 | service: orderer.example.com 56 | container_name: orderer.example.com 57 | networks: 58 | - byfn 59 | 60 | peer0.org1.example.com: 61 | container_name: peer0.org1.example.com 62 | extends: 63 | file: base/docker-compose-base.yaml 64 | service: peer0.org1.example.com 65 | networks: 66 | - byfn 67 | 68 | peer1.org1.example.com: 69 | container_name: peer1.org1.example.com 70 | extends: 71 | file: base/docker-compose-base.yaml 72 | service: peer1.org1.example.com 73 | networks: 74 | - byfn 75 | 76 | peer0.org2.example.com: 77 | container_name: peer0.org2.example.com 78 | extends: 79 | file: base/docker-compose-base.yaml 80 | service: peer0.org2.example.com 81 | networks: 82 | - byfn 83 | 84 | peer1.org2.example.com: 85 | container_name: peer1.org2.example.com 86 | extends: 87 | file: base/docker-compose-base.yaml 88 | service: peer1.org2.example.com 89 | networks: 90 | - byfn 91 | -------------------------------------------------------------------------------- /first-network/docker-compose-etcdraft2.yaml: -------------------------------------------------------------------------------- 1 | # Copyright IBM Corp. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | 6 | version: '2' 7 | 8 | volumes: 9 | orderer2.example.com: 10 | orderer3.example.com: 11 | orderer4.example.com: 12 | orderer5.example.com: 13 | 14 | networks: 15 | byfn: 16 | 17 | services: 18 | 19 | orderer2.example.com: 20 | extends: 21 | file: base/peer-base.yaml 22 | service: orderer-base 23 | container_name: orderer2.example.com 24 | networks: 25 | - byfn 26 | volumes: 27 | - ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block 28 | - ./crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/msp:/var/hyperledger/orderer/msp 29 | - ./crypto-config/ordererOrganizations/example.com/orderers/orderer2.example.com/tls/:/var/hyperledger/orderer/tls 30 | - orderer2.example.com:/var/hyperledger/production/orderer 31 | ports: 32 | - 8050:7050 33 | 34 | orderer3.example.com: 35 | extends: 36 | file: base/peer-base.yaml 37 | service: orderer-base 38 | container_name: orderer3.example.com 39 | networks: 40 | - byfn 41 | volumes: 42 | - ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block 43 | - ./crypto-config/ordererOrganizations/example.com/orderers/orderer3.example.com/msp:/var/hyperledger/orderer/msp 44 | - ./crypto-config/ordererOrganizations/example.com/orderers/orderer3.example.com/tls/:/var/hyperledger/orderer/tls 45 | - orderer3.example.com:/var/hyperledger/production/orderer 46 | ports: 47 | - 9050:7050 48 | 49 | orderer4.example.com: 50 | extends: 51 | file: base/peer-base.yaml 52 | service: orderer-base 53 | container_name: orderer4.example.com 54 | networks: 55 | - byfn 56 | volumes: 57 | - ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block 58 | - ./crypto-config/ordererOrganizations/example.com/orderers/orderer4.example.com/msp:/var/hyperledger/orderer/msp 59 | - ./crypto-config/ordererOrganizations/example.com/orderers/orderer4.example.com/tls/:/var/hyperledger/orderer/tls 60 | - orderer4.example.com:/var/hyperledger/production/orderer 61 | ports: 62 | - 10050:7050 63 | 64 | orderer5.example.com: 65 | extends: 66 | file: base/peer-base.yaml 67 | service: orderer-base 68 | container_name: orderer5.example.com 69 | networks: 70 | - byfn 71 | volumes: 72 | - ./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block 73 | - ./crypto-config/ordererOrganizations/example.com/orderers/orderer5.example.com/msp:/var/hyperledger/orderer/msp 74 | - ./crypto-config/ordererOrganizations/example.com/orderers/orderer5.example.com/tls/:/var/hyperledger/orderer/tls 75 | - orderer5.example.com:/var/hyperledger/production/orderer 76 | ports: 77 | - 11050:7050 78 | -------------------------------------------------------------------------------- /first-network/docker-compose-kafka.yaml: -------------------------------------------------------------------------------- 1 | # Copyright IBM Corp. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | 6 | 7 | # NOTE: This is not the way a Kafka cluster would normally be deployed in production, as it is not secure 8 | # and is not fault tolerant. This example is a toy deployment that is only meant to exercise the Kafka code path 9 | # of the ordering service. 10 | 11 | version: '2' 12 | 13 | networks: 14 | byfn: 15 | 16 | services: 17 | zookeeper0.example.com: 18 | container_name: zookeeper0.example.com 19 | extends: 20 | file: base/kafka-base.yaml 21 | service: zookeeper 22 | environment: 23 | - ZOO_MY_ID=1 24 | ports: 25 | - 2181:2181 26 | - 2888:2888 27 | - 3888:3888 28 | networks: 29 | - byfn 30 | 31 | zookeeper1.example.com: 32 | container_name: zookeeper1.example.com 33 | extends: 34 | file: base/kafka-base.yaml 35 | service: zookeeper 36 | environment: 37 | - ZOO_MY_ID=2 38 | ports: 39 | - 12181:2181 40 | - 12888:2888 41 | - 13888:3888 42 | networks: 43 | - byfn 44 | 45 | zookeeper2.example.com: 46 | container_name: zookeeper2.example.com 47 | extends: 48 | file: base/kafka-base.yaml 49 | service: zookeeper 50 | environment: 51 | - ZOO_MY_ID=3 52 | ports: 53 | - 22181:2181 54 | - 22888:2888 55 | - 23888:3888 56 | networks: 57 | - byfn 58 | 59 | kafka0.example.com: 60 | container_name: kafka0.example.com 61 | extends: 62 | file: base/kafka-base.yaml 63 | service: kafka 64 | environment: 65 | - KAFKA_BROKER_ID=0 66 | ports: 67 | - 9092:9092 68 | - 9093:9093 69 | networks: 70 | - byfn 71 | depends_on: 72 | - zookeeper0.example.com 73 | - zookeeper1.example.com 74 | - zookeeper2.example.com 75 | 76 | kafka3.example.com: 77 | container_name: kafka3.example.com 78 | extends: 79 | file: base/kafka-base.yaml 80 | service: kafka 81 | environment: 82 | - KAFKA_BROKER_ID=1 83 | ports: 84 | - 10092:9092 85 | - 10093:9093 86 | networks: 87 | - byfn 88 | depends_on: 89 | - zookeeper0.example.com 90 | - zookeeper1.example.com 91 | - zookeeper2.example.com 92 | 93 | kafka2.example.com: 94 | container_name: kafka2.example.com 95 | extends: 96 | file: base/kafka-base.yaml 97 | service: kafka 98 | environment: 99 | - KAFKA_BROKER_ID=2 100 | ports: 101 | - 11092:9092 102 | - 11093:9093 103 | networks: 104 | - byfn 105 | depends_on: 106 | - zookeeper0.example.com 107 | - zookeeper1.example.com 108 | - zookeeper2.example.com 109 | 110 | kafka3.example.com: 111 | container_name: kafka3.example.com 112 | extends: 113 | file: base/kafka-base.yaml 114 | service: kafka 115 | environment: 116 | - KAFKA_BROKER_ID=3 117 | ports: 118 | - 12092:9092 119 | - 12093:9093 120 | networks: 121 | - byfn 122 | depends_on: 123 | - zookeeper0.example.com 124 | - zookeeper1.example.com 125 | - zookeeper2.example.com -------------------------------------------------------------------------------- /first-network/docker-compose-org3.yaml: -------------------------------------------------------------------------------- 1 | # Copyright IBM Corp. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | 6 | version: '2' 7 | 8 | volumes: 9 | peer0.org3.example.com: 10 | peer1.org3.example.com: 11 | 12 | networks: 13 | byfn: 14 | 15 | services: 16 | 17 | peer0.org3.example.com: 18 | container_name: peer0.org3.example.com 19 | extends: 20 | file: base/peer-base.yaml 21 | service: peer-base 22 | environment: 23 | - CORE_PEER_ID=peer0.org3.example.com 24 | - CORE_PEER_ADDRESS=peer0.org3.example.com:11051 25 | - CORE_PEER_LISTENADDRESS=0.0.0.0:11051 26 | - CORE_PEER_CHAINCODEADDRESS=peer0.org3.example.com:11052 27 | - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:11052 28 | - CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org3.example.com:12051 29 | - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org3.example.com:11051 30 | - CORE_PEER_LOCALMSPID=Org3MSP 31 | volumes: 32 | - /var/run/:/host/var/run/ 33 | - ./org3-artifacts/crypto-config/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/msp:/etc/hyperledger/fabric/msp 34 | - ./org3-artifacts/crypto-config/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls:/etc/hyperledger/fabric/tls 35 | - peer0.org3.example.com:/var/hyperledger/production 36 | ports: 37 | - 11051:11051 38 | networks: 39 | - byfn 40 | 41 | peer1.org3.example.com: 42 | container_name: peer1.org3.example.com 43 | extends: 44 | file: base/peer-base.yaml 45 | service: peer-base 46 | environment: 47 | - CORE_PEER_ID=peer1.org3.example.com 48 | - CORE_PEER_ADDRESS=peer1.org3.example.com:12051 49 | - CORE_PEER_LISTENADDRESS=0.0.0.0:12051 50 | - CORE_PEER_CHAINCODEADDRESS=peer1.org3.example.com:12052 51 | - CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:12052 52 | - CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org3.example.com:11051 53 | - CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org3.example.com:12051 54 | - CORE_PEER_LOCALMSPID=Org3MSP 55 | volumes: 56 | - /var/run/:/host/var/run/ 57 | - ./org3-artifacts/crypto-config/peerOrganizations/org3.example.com/peers/peer1.org3.example.com/msp:/etc/hyperledger/fabric/msp 58 | - ./org3-artifacts/crypto-config/peerOrganizations/org3.example.com/peers/peer1.org3.example.com/tls:/etc/hyperledger/fabric/tls 59 | - peer1.org3.example.com:/var/hyperledger/production 60 | ports: 61 | - 12051:12051 62 | networks: 63 | - byfn 64 | 65 | 66 | Org3cli: 67 | container_name: Org3cli 68 | image: hyperledger/fabric-tools:$IMAGE_TAG 69 | tty: true 70 | stdin_open: true 71 | environment: 72 | - GOPATH=/opt/gopath 73 | - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock 74 | - FABRIC_LOGGING_SPEC=INFO 75 | #- FABRIC_LOGGING_SPEC=DEBUG 76 | - CORE_PEER_ID=Org3cli 77 | - CORE_PEER_ADDRESS=peer0.org3.example.com:11051 78 | - CORE_PEER_LOCALMSPID=Org3MSP 79 | - CORE_PEER_TLS_ENABLED=true 80 | - CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/server.crt 81 | - CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/server.key 82 | - CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt 83 | - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp 84 | working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer 85 | command: /bin/bash 86 | volumes: 87 | - /var/run/:/host/var/run/ 88 | - ./../chaincode/:/opt/gopath/src/github.com/chaincode 89 | - ./org3-artifacts/crypto-config:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ 90 | - ./crypto-config/peerOrganizations/org1.example.com:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com 91 | - ./crypto-config/peerOrganizations/org2.example.com:/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com 92 | - ./scripts:/opt/gopath/src/github.com/hyperledger/fabric/peer/scripts/ 93 | depends_on: 94 | - peer0.org3.example.com 95 | - peer1.org3.example.com 96 | networks: 97 | - byfn 98 | -------------------------------------------------------------------------------- /first-network/eyfn.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright IBM Corp All Rights Reserved 4 | # 5 | # SPDX-License-Identifier: Apache-2.0 6 | # 7 | 8 | # This script extends the Hyperledger Fabric By Your First Network by 9 | # adding a third organization to the network previously setup in the 10 | # BYFN tutorial. 11 | # 12 | 13 | # prepending $PWD/../bin to PATH to ensure we are picking up the correct binaries 14 | # this may be commented out to resolve installed version of tools if desired 15 | export PATH=${PWD}/../bin:${PWD}:$PATH 16 | export FABRIC_CFG_PATH=${PWD} 17 | export VERBOSE=false 18 | 19 | # Print the usage message 20 | function printHelp () { 21 | echo "Usage: " 22 | echo " eyfn.sh up|down|restart|generate [-c ] [-t ] [-d ] [-f ] [-s ]" 23 | echo " eyfn.sh -h|--help (print this message)" 24 | echo " - one of 'up', 'down', 'restart' or 'generate'" 25 | echo " - 'up' - bring up the network with docker-compose up" 26 | echo " - 'down' - clear the network with docker-compose down" 27 | echo " - 'restart' - restart the network" 28 | echo " - 'generate' - generate required certificates and genesis block" 29 | echo " -c - channel name to use (defaults to \"mychannel\")" 30 | echo " -t - CLI timeout duration in seconds (defaults to 10)" 31 | echo " -d - delay duration in seconds (defaults to 3)" 32 | echo " -f - specify which docker-compose file use (defaults to docker-compose-cli.yaml)" 33 | echo " -s - the database backend to use: goleveldb (default) or couchdb" 34 | echo " -l - the chaincode language: golang (default) or node" 35 | echo " -i - the tag to be used to launch the network (defaults to \"latest\")" 36 | echo " -v - verbose mode" 37 | echo 38 | echo "Typically, one would first generate the required certificates and " 39 | echo "genesis block, then bring up the network. e.g.:" 40 | echo 41 | echo " eyfn.sh generate -c mychannel" 42 | echo " eyfn.sh up -c mychannel -s couchdb" 43 | echo " eyfn.sh up -l node" 44 | echo " eyfn.sh down -c mychannel" 45 | echo 46 | echo "Taking all defaults:" 47 | echo " eyfn.sh generate" 48 | echo " eyfn.sh up" 49 | echo " eyfn.sh down" 50 | } 51 | 52 | # Ask user for confirmation to proceed 53 | function askProceed () { 54 | read -p "Continue? [Y/n] " ans 55 | case "$ans" in 56 | y|Y|"" ) 57 | echo "proceeding ..." 58 | ;; 59 | n|N ) 60 | echo "exiting..." 61 | exit 1 62 | ;; 63 | * ) 64 | echo "invalid response" 65 | askProceed 66 | ;; 67 | esac 68 | } 69 | 70 | # Obtain CONTAINER_IDS and remove them 71 | # TODO Might want to make this optional - could clear other containers 72 | function clearContainers () { 73 | CONTAINER_IDS=$(docker ps -aq) 74 | if [ -z "$CONTAINER_IDS" -o "$CONTAINER_IDS" == " " ]; then 75 | echo "---- No containers available for deletion ----" 76 | else 77 | docker rm -f $CONTAINER_IDS 78 | fi 79 | } 80 | 81 | # Delete any images that were generated as a part of this setup 82 | # specifically the following images are often left behind: 83 | # TODO list generated image naming patterns 84 | function removeUnwantedImages() { 85 | DOCKER_IMAGE_IDS=$(docker images|awk '($1 ~ /dev-peer.*.mycc.*/) {print $3}') 86 | if [ -z "$DOCKER_IMAGE_IDS" -o "$DOCKER_IMAGE_IDS" == " " ]; then 87 | echo "---- No images available for deletion ----" 88 | else 89 | docker rmi -f $DOCKER_IMAGE_IDS 90 | fi 91 | } 92 | 93 | # Generate the needed certificates, the genesis block and start the network. 94 | function networkUp () { 95 | # generate artifacts if they don't exist 96 | if [ ! -d "org3-artifacts/crypto-config" ]; then 97 | generateCerts 98 | generateChannelArtifacts 99 | createConfigTx 100 | fi 101 | # start org3 peers 102 | if [ "${IF_COUCHDB}" == "couchdb" ]; then 103 | IMAGE_TAG=${IMAGETAG} docker-compose -f $COMPOSE_FILE_ORG3 -f $COMPOSE_FILE_COUCH_ORG3 up -d 2>&1 104 | else 105 | IMAGE_TAG=$IMAGETAG docker-compose -f $COMPOSE_FILE_ORG3 up -d 2>&1 106 | fi 107 | if [ $? -ne 0 ]; then 108 | echo "ERROR !!!! Unable to start Org3 network" 109 | exit 1 110 | fi 111 | echo 112 | echo "###############################################################" 113 | echo "############### Have Org3 peers join network ##################" 114 | echo "###############################################################" 115 | docker exec Org3cli ./scripts/step2org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE 116 | if [ $? -ne 0 ]; then 117 | echo "ERROR !!!! Unable to have Org3 peers join network" 118 | exit 1 119 | fi 120 | echo 121 | echo "###############################################################" 122 | echo "##### Upgrade chaincode to have Org3 peers on the network #####" 123 | echo "###############################################################" 124 | docker exec cli ./scripts/step3org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE 125 | if [ $? -ne 0 ]; then 126 | echo "ERROR !!!! Unable to add Org3 peers on network" 127 | exit 1 128 | fi 129 | # finish by running the test 130 | docker exec Org3cli ./scripts/testorg3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE 131 | if [ $? -ne 0 ]; then 132 | echo "ERROR !!!! Unable to run test" 133 | exit 1 134 | fi 135 | } 136 | 137 | # Tear down running network 138 | function networkDown () { 139 | docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_KAFKA -f $COMPOSE_FILE_RAFT2 -f $COMPOSE_FILE_ORG3 -f $COMPOSE_FILE_COUCH down --volumes --remove-orphans 140 | # Don't remove containers, images, etc if restarting 141 | if [ "$MODE" != "restart" ]; then 142 | #Cleanup the chaincode containers 143 | clearContainers 144 | #Cleanup images 145 | removeUnwantedImages 146 | # remove orderer block and other channel configuration transactions and certs 147 | rm -rf channel-artifacts/*.block channel-artifacts/*.tx crypto-config ./org3-artifacts/crypto-config/ channel-artifacts/org3.json 148 | # remove the docker-compose yaml file that was customized to the example 149 | rm -f docker-compose-e2e.yaml 150 | fi 151 | } 152 | 153 | # Use the CLI container to create the configuration transaction needed to add 154 | # Org3 to the network 155 | function createConfigTx () { 156 | echo 157 | echo "###############################################################" 158 | echo "####### Generate and submit config tx to add Org3 #############" 159 | echo "###############################################################" 160 | docker exec cli scripts/step1org3.sh $CHANNEL_NAME $CLI_DELAY $LANGUAGE $CLI_TIMEOUT $VERBOSE 161 | if [ $? -ne 0 ]; then 162 | echo "ERROR !!!! Unable to create config tx" 163 | exit 1 164 | fi 165 | } 166 | 167 | # We use the cryptogen tool to generate the cryptographic material 168 | # (x509 certs) for the new org. After we run the tool, the certs will 169 | # be parked in the BYFN folder titled ``crypto-config``. 170 | 171 | # Generates Org3 certs using cryptogen tool 172 | function generateCerts (){ 173 | which cryptogen 174 | if [ "$?" -ne 0 ]; then 175 | echo "cryptogen tool not found. exiting" 176 | exit 1 177 | fi 178 | echo 179 | echo "###############################################################" 180 | echo "##### Generate Org3 certificates using cryptogen tool #########" 181 | echo "###############################################################" 182 | 183 | (cd org3-artifacts 184 | set -x 185 | cryptogen generate --config=./org3-crypto.yaml 186 | res=$? 187 | set +x 188 | if [ $res -ne 0 ]; then 189 | echo "Failed to generate certificates..." 190 | exit 1 191 | fi 192 | ) 193 | echo 194 | } 195 | 196 | # Generate channel configuration transaction 197 | function generateChannelArtifacts() { 198 | which configtxgen 199 | if [ "$?" -ne 0 ]; then 200 | echo "configtxgen tool not found. exiting" 201 | exit 1 202 | fi 203 | echo "##########################################################" 204 | echo "######### Generating Org3 config material ###############" 205 | echo "##########################################################" 206 | (cd org3-artifacts 207 | export FABRIC_CFG_PATH=$PWD 208 | set -x 209 | configtxgen -printOrg Org3MSP > ../channel-artifacts/org3.json 210 | res=$? 211 | set +x 212 | if [ $res -ne 0 ]; then 213 | echo "Failed to generate Org3 config material..." 214 | exit 1 215 | fi 216 | ) 217 | cp -r crypto-config/ordererOrganizations org3-artifacts/crypto-config/ 218 | echo 219 | } 220 | 221 | 222 | # If BYFN wasn't run abort 223 | if [ ! -d crypto-config ]; then 224 | echo 225 | echo "ERROR: Please, run byfn.sh first." 226 | echo 227 | exit 1 228 | fi 229 | 230 | # Obtain the OS and Architecture string that will be used to select the correct 231 | # native binaries for your platform 232 | OS_ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')" | awk '{print tolower($0)}') 233 | # timeout duration - the duration the CLI should wait for a response from 234 | # another container before giving up 235 | CLI_TIMEOUT=10 236 | #default for delay 237 | CLI_DELAY=3 238 | # channel name defaults to "mychannel" 239 | CHANNEL_NAME="mychannel" 240 | # use this as the default docker-compose yaml definition 241 | COMPOSE_FILE=docker-compose-cli.yaml 242 | # 243 | COMPOSE_FILE_COUCH=docker-compose-couch.yaml 244 | # use this as the default docker-compose yaml definition 245 | COMPOSE_FILE_ORG3=docker-compose-org3.yaml 246 | # 247 | COMPOSE_FILE_COUCH_ORG3=docker-compose-couch-org3.yaml 248 | # kafka and zookeeper compose file 249 | COMPOSE_FILE_KAFKA=docker-compose-kafka.yaml 250 | # two additional etcd/raft orderers 251 | COMPOSE_FILE_RAFT2=docker-compose-etcdraft2.yaml 252 | # use golang as the default language for chaincode 253 | LANGUAGE=golang 254 | # default image tag 255 | IMAGETAG="latest" 256 | 257 | # Parse commandline args 258 | if [ "$1" = "-m" ];then # supports old usage, muscle memory is powerful! 259 | shift 260 | fi 261 | MODE=$1;shift 262 | # Determine whether starting, stopping, restarting or generating for announce 263 | if [ "$MODE" == "up" ]; then 264 | EXPMODE="Starting" 265 | elif [ "$MODE" == "down" ]; then 266 | EXPMODE="Stopping" 267 | elif [ "$MODE" == "restart" ]; then 268 | EXPMODE="Restarting" 269 | elif [ "$MODE" == "generate" ]; then 270 | EXPMODE="Generating certs and genesis block for" 271 | else 272 | printHelp 273 | exit 1 274 | fi 275 | while getopts "h?c:t:d:f:s:l:i:v" opt; do 276 | case "$opt" in 277 | h|\?) 278 | printHelp 279 | exit 0 280 | ;; 281 | c) CHANNEL_NAME=$OPTARG 282 | ;; 283 | t) CLI_TIMEOUT=$OPTARG 284 | ;; 285 | d) CLI_DELAY=$OPTARG 286 | ;; 287 | f) COMPOSE_FILE=$OPTARG 288 | ;; 289 | s) IF_COUCHDB=$OPTARG 290 | ;; 291 | l) LANGUAGE=$OPTARG 292 | ;; 293 | i) IMAGETAG=$OPTARG 294 | ;; 295 | v) VERBOSE=true 296 | ;; 297 | esac 298 | done 299 | 300 | # Announce what was requested 301 | 302 | if [ "${IF_COUCHDB}" == "couchdb" ]; then 303 | echo 304 | echo "${EXPMODE} with channel '${CHANNEL_NAME}' and CLI timeout of '${CLI_TIMEOUT}' seconds and CLI delay of '${CLI_DELAY}' seconds and using database '${IF_COUCHDB}'" 305 | else 306 | echo "${EXPMODE} with channel '${CHANNEL_NAME}' and CLI timeout of '${CLI_TIMEOUT}' seconds and CLI delay of '${CLI_DELAY}' seconds" 307 | fi 308 | # ask for confirmation to proceed 309 | askProceed 310 | 311 | #Create the network using docker compose 312 | if [ "${MODE}" == "up" ]; then 313 | networkUp 314 | elif [ "${MODE}" == "down" ]; then ## Clear the network 315 | networkDown 316 | elif [ "${MODE}" == "generate" ]; then ## Generate Artifacts 317 | generateCerts 318 | generateChannelArtifacts 319 | createConfigTx 320 | elif [ "${MODE}" == "restart" ]; then ## Restart the network 321 | networkDown 322 | networkUp 323 | else 324 | printHelp 325 | exit 1 326 | fi 327 | -------------------------------------------------------------------------------- /first-network/org3-artifacts/configtx.yaml: -------------------------------------------------------------------------------- 1 | # Copyright IBM Corp. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | 6 | --- 7 | ################################################################################ 8 | # 9 | # Section: Organizations 10 | # 11 | # - This section defines the different organizational identities which will 12 | # be referenced later in the configuration. 13 | # 14 | ################################################################################ 15 | Organizations: 16 | - &Org3 17 | # DefaultOrg defines the organization which is used in the sampleconfig 18 | # of the fabric.git development environment 19 | Name: Org3MSP 20 | 21 | # ID to load the MSP definition as 22 | ID: Org3MSP 23 | 24 | MSPDir: crypto-config/peerOrganizations/org3.example.com/msp 25 | 26 | # Policies defines the set of policies at this level of the config tree 27 | # For organization policies, their canonical path is usually 28 | # /Channel/// 29 | Policies: 30 | Readers: 31 | Type: Signature 32 | Rule: "OR('Org3MSP.admin', 'Org3MSP.peer', 'Org3MSP.client')" 33 | Writers: 34 | Type: Signature 35 | Rule: "OR('Org3MSP.admin', 'Org3MSP.client')" 36 | Admins: 37 | Type: Signature 38 | Rule: "OR('Org3MSP.admin')" 39 | 40 | AnchorPeers: 41 | # AnchorPeers defines the location of peers which can be used 42 | # for cross org gossip communication. Note, this value is only 43 | # encoded in the genesis block in the Application section context 44 | - Host: peer0.org3.example.com 45 | Port: 11051 46 | -------------------------------------------------------------------------------- /first-network/org3-artifacts/org3-crypto.yaml: -------------------------------------------------------------------------------- 1 | # Copyright IBM Corp. All Rights Reserved. 2 | # 3 | # SPDX-License-Identifier: Apache-2.0 4 | # 5 | 6 | # --------------------------------------------------------------------------- 7 | # "PeerOrgs" - Definition of organizations managing peer nodes 8 | # --------------------------------------------------------------------------- 9 | PeerOrgs: 10 | # --------------------------------------------------------------------------- 11 | # Org3 12 | # --------------------------------------------------------------------------- 13 | - Name: Org3 14 | Domain: org3.example.com 15 | EnableNodeOUs: true 16 | Template: 17 | Count: 2 18 | Users: 19 | Count: 1 20 | -------------------------------------------------------------------------------- /first-network/scripts/capabilities.json: -------------------------------------------------------------------------------- 1 | { 2 | "channel": { 3 | "mod_policy": "Admins", 4 | "value": { 5 | "capabilities": { 6 | "V1_4_3": {} 7 | } 8 | }, 9 | "version": "0" 10 | }, 11 | "orderer": { 12 | "mod_policy": "Admins", 13 | "value": { 14 | "capabilities": { 15 | "V1_4_2": {} 16 | } 17 | }, 18 | "version": "0" 19 | }, 20 | "application": { 21 | "mod_policy": "Admins", 22 | "value": { 23 | "capabilities": { 24 | "V1_4_2": {} 25 | } 26 | }, 27 | "version": "0" 28 | } 29 | } -------------------------------------------------------------------------------- /first-network/scripts/script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo 4 | echo " ____ _____ _ ____ _____ " 5 | echo "/ ___| |_ _| / \ | _ \ |_ _|" 6 | echo "\___ \ | | / _ \ | |_) | | | " 7 | echo " ___) | | | / ___ \ | _ < | | " 8 | echo "|____/ |_| /_/ \_\ |_| \_\ |_| " 9 | echo 10 | echo "Build your first network (BYFN) end-to-end test" 11 | echo 12 | CHANNEL_NAME="$1" 13 | DELAY="$2" 14 | LANGUAGE="$3" 15 | TIMEOUT="$4" 16 | VERBOSE="$5" 17 | NO_CHAINCODE="$6" 18 | : ${CHANNEL_NAME:="mychannel"} 19 | : ${DELAY:="3"} 20 | : ${LANGUAGE:="golang"} 21 | : ${TIMEOUT:="10"} 22 | : ${VERBOSE:="false"} 23 | : ${NO_CHAINCODE:="false"} 24 | LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` 25 | COUNTER=1 26 | MAX_RETRY=10 27 | 28 | CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" 29 | if [ "$LANGUAGE" = "node" ]; then 30 | CC_SRC_PATH="/opt/gopath/src/github.com/chaincode/chaincode_example02/node/" 31 | fi 32 | 33 | if [ "$LANGUAGE" = "java" ]; then 34 | CC_SRC_PATH="/opt/gopath/src/github.com/chaincode/chaincode_example02/java/" 35 | fi 36 | 37 | echo "Channel name : "$CHANNEL_NAME 38 | 39 | # import utils 40 | . scripts/utils.sh 41 | 42 | createChannel() { 43 | setGlobals 0 1 44 | 45 | if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then 46 | set -x 47 | peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx >&log.txt 48 | res=$? 49 | set +x 50 | else 51 | set -x 52 | peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA >&log.txt 53 | res=$? 54 | set +x 55 | fi 56 | cat log.txt 57 | verifyResult $res "Channel creation failed" 58 | echo "===================== Channel '$CHANNEL_NAME' created ===================== " 59 | echo 60 | } 61 | 62 | joinChannel () { 63 | for org in 1 2; do 64 | for peer in 0 1; do 65 | joinChannelWithRetry $peer $org 66 | echo "===================== peer${peer}.org${org} joined channel '$CHANNEL_NAME' ===================== " 67 | sleep $DELAY 68 | echo 69 | done 70 | done 71 | } 72 | 73 | ## Create channel 74 | echo "Creating channel..." 75 | createChannel 76 | 77 | ## Join all the peers to the channel 78 | echo "Having all peers join the channel..." 79 | joinChannel 80 | 81 | ## Set the anchor peers for each org in the channel 82 | echo "Updating anchor peers for org1..." 83 | updateAnchorPeers 0 1 84 | echo "Updating anchor peers for org2..." 85 | updateAnchorPeers 0 2 86 | 87 | if [ "${NO_CHAINCODE}" != "true" ]; then 88 | 89 | ## Install chaincode on peer0.org1 and peer0.org2 90 | echo "Installing chaincode on peer0.org1..." 91 | installChaincode 0 1 92 | echo "Install chaincode on peer0.org2..." 93 | installChaincode 0 2 94 | 95 | # Instantiate chaincode on peer0.org2 96 | echo "Instantiating chaincode on peer0.org2..." 97 | instantiateChaincode 0 2 98 | 99 | # Query chaincode on peer0.org1 100 | echo "Querying chaincode on peer0.org1..." 101 | chaincodeQuery 0 1 100 102 | 103 | # Invoke chaincode on peer0.org1 and peer0.org2 104 | echo "Sending invoke transaction on peer0.org1 peer0.org2..." 105 | chaincodeInvoke 0 1 0 2 106 | 107 | ## Install chaincode on peer1.org2 108 | echo "Installing chaincode on peer1.org2..." 109 | installChaincode 1 2 110 | 111 | # Query on chaincode on peer1.org2, check if the result is 90 112 | echo "Querying chaincode on peer1.org2..." 113 | chaincodeQuery 1 2 90 114 | 115 | fi 116 | 117 | echo 118 | echo "========= All GOOD, BYFN execution completed =========== " 119 | echo 120 | 121 | echo 122 | echo " _____ _ _ ____ " 123 | echo "| ____| | \ | | | _ \ " 124 | echo "| _| | \| | | | | | " 125 | echo "| |___ | |\ | | |_| | " 126 | echo "|_____| |_| \_| |____/ " 127 | echo 128 | 129 | exit 0 130 | -------------------------------------------------------------------------------- /first-network/scripts/step1org3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright IBM Corp. All Rights Reserved. 4 | # 5 | # SPDX-License-Identifier: Apache-2.0 6 | # 7 | 8 | # This script is designed to be run in the org3cli container as the 9 | # first step of the EYFN tutorial. It creates and submits a 10 | # configuration transaction to add org3 to the network previously 11 | # setup in the BYFN tutorial. 12 | # 13 | 14 | CHANNEL_NAME="$1" 15 | DELAY="$2" 16 | LANGUAGE="$3" 17 | TIMEOUT="$4" 18 | VERBOSE="$5" 19 | : ${CHANNEL_NAME:="mychannel"} 20 | : ${DELAY:="3"} 21 | : ${LANGUAGE:="golang"} 22 | : ${TIMEOUT:="10"} 23 | : ${VERBOSE:="false"} 24 | LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` 25 | COUNTER=1 26 | MAX_RETRY=5 27 | 28 | CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" 29 | if [ "$LANGUAGE" = "node" ]; then 30 | CC_SRC_PATH="/opt/gopath/src/github.com/chaincode/chaincode_example02/node/" 31 | fi 32 | 33 | # import utils 34 | . scripts/utils.sh 35 | 36 | echo 37 | echo "========= Creating config transaction to add org3 to network =========== " 38 | echo 39 | 40 | echo "Installing jq" 41 | apt-get -y update && apt-get -y install jq 42 | 43 | # Fetch the config for the channel, writing it to config.json 44 | fetchChannelConfig ${CHANNEL_NAME} config.json 45 | 46 | # Modify the configuration to append the new org 47 | set -x 48 | jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' config.json ./channel-artifacts/org3.json > modified_config.json 49 | set +x 50 | 51 | # Compute a config update, based on the differences between config.json and modified_config.json, write it as a transaction to org3_update_in_envelope.pb 52 | createConfigUpdate ${CHANNEL_NAME} config.json modified_config.json org3_update_in_envelope.pb 53 | 54 | echo 55 | echo "========= Config transaction to add org3 to network created ===== " 56 | echo 57 | 58 | echo "Signing config transaction" 59 | echo 60 | signConfigtxAsPeerOrg 1 org3_update_in_envelope.pb 61 | 62 | echo 63 | echo "========= Submitting transaction from a different peer (peer0.org2) which also signs it ========= " 64 | echo 65 | setGlobals 0 2 66 | set -x 67 | peer channel update -f org3_update_in_envelope.pb -c ${CHANNEL_NAME} -o orderer.example.com:7050 --tls --cafile ${ORDERER_CA} 68 | set +x 69 | 70 | echo 71 | echo "========= Config transaction to add org3 to network submitted! =========== " 72 | echo 73 | 74 | exit 0 75 | -------------------------------------------------------------------------------- /first-network/scripts/step2org3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright IBM Corp. All Rights Reserved. 4 | # 5 | # SPDX-License-Identifier: Apache-2.0 6 | # 7 | 8 | # This script is designed to be run in the org3cli container as the 9 | # second step of the EYFN tutorial. It joins the org3 peers to the 10 | # channel previously setup in the BYFN tutorial and install the 11 | # chaincode as version 2.0 on peer0.org3. 12 | # 13 | 14 | echo 15 | echo "========= Getting Org3 on to your first network ========= " 16 | echo 17 | CHANNEL_NAME="$1" 18 | DELAY="$2" 19 | LANGUAGE="$3" 20 | TIMEOUT="$4" 21 | VERBOSE="$5" 22 | : ${CHANNEL_NAME:="mychannel"} 23 | : ${DELAY:="3"} 24 | : ${LANGUAGE:="golang"} 25 | : ${TIMEOUT:="10"} 26 | : ${VERBOSE:="false"} 27 | LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` 28 | COUNTER=1 29 | MAX_RETRY=5 30 | 31 | CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" 32 | if [ "$LANGUAGE" = "node" ]; then 33 | CC_SRC_PATH="/opt/gopath/src/github.com/chaincode/chaincode_example02/node/" 34 | fi 35 | 36 | # import utils 37 | . scripts/utils.sh 38 | 39 | echo "Fetching channel config block from orderer..." 40 | set -x 41 | peer channel fetch 0 $CHANNEL_NAME.block -o orderer.example.com:7050 -c $CHANNEL_NAME --tls --cafile $ORDERER_CA >&log.txt 42 | res=$? 43 | set +x 44 | cat log.txt 45 | verifyResult $res "Fetching config block from orderer has Failed" 46 | 47 | joinChannelWithRetry 0 3 48 | echo "===================== peer0.org3 joined channel '$CHANNEL_NAME' ===================== " 49 | joinChannelWithRetry 1 3 50 | echo "===================== peer1.org3 joined channel '$CHANNEL_NAME' ===================== " 51 | echo "Installing chaincode 2.0 on peer0.org3..." 52 | installChaincode 0 3 2.0 53 | 54 | echo 55 | echo "========= Org3 is now halfway onto your first network ========= " 56 | echo 57 | 58 | exit 0 59 | -------------------------------------------------------------------------------- /first-network/scripts/step3org3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright IBM Corp. All Rights Reserved. 4 | # 5 | # SPDX-License-Identifier: Apache-2.0 6 | # 7 | 8 | # This script is designed to be run in the cli container as the third 9 | # step of the EYFN tutorial. It installs the chaincode as version 2.0 10 | # on peer0.org1 and peer0.org2, and uprage the chaincode on the 11 | # channel to version 2.0, thus completing the addition of org3 to the 12 | # network previously setup in the BYFN tutorial. 13 | # 14 | 15 | echo 16 | echo "========= Finish adding Org3 to your first network ========= " 17 | echo 18 | CHANNEL_NAME="$1" 19 | DELAY="$2" 20 | LANGUAGE="$3" 21 | TIMEOUT="$4" 22 | VERBOSE="$5" 23 | : ${CHANNEL_NAME:="mychannel"} 24 | : ${DELAY:="3"} 25 | : ${LANGUAGE:="golang"} 26 | : ${TIMEOUT:="10"} 27 | : ${VERBOSE:="false"} 28 | LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` 29 | COUNTER=1 30 | MAX_RETRY=5 31 | 32 | CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" 33 | if [ "$LANGUAGE" = "node" ]; then 34 | CC_SRC_PATH="/opt/gopath/src/github.com/chaincode/chaincode_example02/node/" 35 | fi 36 | 37 | # import utils 38 | . scripts/utils.sh 39 | 40 | echo "===================== Installing chaincode 2.0 on peer0.org1 ===================== " 41 | installChaincode 0 1 2.0 42 | echo "===================== Installing chaincode 2.0 on peer0.org2 ===================== " 43 | installChaincode 0 2 2.0 44 | 45 | echo "===================== Upgrading chaincode on peer0.org1 ===================== " 46 | upgradeChaincode 0 1 47 | 48 | echo 49 | echo "========= Finished adding Org3 to your first network! ========= " 50 | echo 51 | 52 | exit 0 53 | -------------------------------------------------------------------------------- /first-network/scripts/testorg3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright IBM Corp. All Rights Reserved. 4 | # 5 | # SPDX-License-Identifier: Apache-2.0 6 | # 7 | 8 | # This script is designed to be run in the org3cli container as the 9 | # final step of the EYFN tutorial. It simply issues a couple of 10 | # chaincode requests through the org3 peers to check that org3 was 11 | # properly added to the network previously setup in the BYFN tutorial. 12 | # 13 | 14 | echo 15 | echo " ____ _____ _ ____ _____ " 16 | echo "/ ___| |_ _| / \ | _ \ |_ _|" 17 | echo "\___ \ | | / _ \ | |_) | | | " 18 | echo " ___) | | | / ___ \ | _ < | | " 19 | echo "|____/ |_| /_/ \_\ |_| \_\ |_| " 20 | echo 21 | echo "Extend your first network (EYFN) test" 22 | echo 23 | CHANNEL_NAME="$1" 24 | DELAY="$2" 25 | LANGUAGE="$3" 26 | TIMEOUT="$4" 27 | VERBOSE="$5" 28 | : ${CHANNEL_NAME:="mychannel"} 29 | : ${TIMEOUT:="10"} 30 | : ${LANGUAGE:="golang"} 31 | : ${VERBOSE:="false"} 32 | LANGUAGE=`echo "$LANGUAGE" | tr [:upper:] [:lower:]` 33 | COUNTER=1 34 | MAX_RETRY=5 35 | 36 | CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" 37 | if [ "$LANGUAGE" = "node" ]; then 38 | CC_SRC_PATH="/opt/gopath/src/github.com/chaincode/chaincode_example02/node/" 39 | fi 40 | 41 | echo "Channel name : "$CHANNEL_NAME 42 | 43 | # import functions 44 | . scripts/utils.sh 45 | 46 | # Query chaincode on peer0.org3, check if the result is 90 47 | echo "Querying chaincode on peer0.org3..." 48 | chaincodeQuery 0 3 90 49 | 50 | # Invoke chaincode on peer0.org1, peer0.org2, and peer0.org3 51 | echo "Sending invoke transaction on peer0.org1 peer0.org2 peer0.org3..." 52 | chaincodeInvoke 0 1 0 2 0 3 53 | 54 | # Query on chaincode on peer0.org3, peer0.org2, peer0.org1 check if the result is 80 55 | # We query a peer in each organization, to ensure peers from all organizations are in sync 56 | # and there is no state fork between organizations. 57 | echo "Querying chaincode on peer0.org3..." 58 | chaincodeQuery 0 3 80 59 | 60 | echo "Querying chaincode on peer0.org2..." 61 | chaincodeQuery 0 2 80 62 | 63 | echo "Querying chaincode on peer0.org1..." 64 | chaincodeQuery 0 1 80 65 | 66 | 67 | echo 68 | echo "========= All GOOD, EYFN test execution completed =========== " 69 | echo 70 | 71 | echo 72 | echo " _____ _ _ ____ " 73 | echo "| ____| | \ | | | _ \ " 74 | echo "| _| | \| | | | | | " 75 | echo "| |___ | |\ | | |_| | " 76 | echo "|_____| |_| \_| |____/ " 77 | echo 78 | 79 | exit 0 80 | -------------------------------------------------------------------------------- /first-network/scripts/upgrade_to_v14.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo 4 | echo " ____ _____ _ ____ _____ " 5 | echo "/ ___| |_ _| / \ | _ \ |_ _|" 6 | echo "\___ \ | | / _ \ | |_) | | | " 7 | echo " ___) | | | / ___ \ | _ < | | " 8 | echo "|____/ |_| /_/ \_\ |_| \_\ |_| " 9 | echo 10 | echo "Upgrade your first network (BYFN) from v1.3.x to v1.4.x end-to-end test" 11 | echo 12 | CHANNEL_NAME="$1" 13 | DELAY="$2" 14 | LANGUAGE="$3" 15 | TIMEOUT="$4" 16 | VERBOSE="$5" 17 | : ${CHANNEL_NAME:="mychannel"} 18 | : ${DELAY:="5"} 19 | : ${LANGUAGE:="golang"} 20 | : ${TIMEOUT:="10"} 21 | : ${VERBOSE:="false"} 22 | LANGUAGE=$(echo "$LANGUAGE" | tr [:upper:] [:lower:]) 23 | COUNTER=1 24 | MAX_RETRY=5 25 | SYS_CHANNEL=$SYS_CHANNEL 26 | 27 | CC_SRC_PATH="github.com/chaincode/chaincode_example02/go/" 28 | if [ "$LANGUAGE" = "node" ]; then 29 | CC_SRC_PATH="/opt/gopath/src/github.com/chaincode/chaincode_example02/node/" 30 | fi 31 | 32 | echo "System channel name : "$SYS_CHANNEL 33 | echo "Channel name : "$CHANNEL_NAME 34 | 35 | # import utils 36 | . scripts/utils.sh 37 | 38 | # addCapabilityToChannel 39 | # This function pulls the current channel config, modifies it with capabilities 40 | # for the specified group, computes the config update, signs, and submits it. 41 | addCapabilityToChannel() { 42 | CH_NAME=$1 43 | GROUP=$2 44 | 45 | setOrdererGlobals 46 | 47 | # Get the current channel config, decode and write it to config.json 48 | fetchChannelConfig $CH_NAME config.json 49 | 50 | # Modify the correct section of the config based on capabilities group 51 | if [ $GROUP == "orderer" ]; then 52 | jq -s '.[0] * {"channel_group":{"groups":{"Orderer": {"values": {"Capabilities": .[1].orderer}}}}}' config.json ./scripts/capabilities.json > modified_config.json 53 | elif [ $GROUP == "channel" ]; then 54 | jq -s '.[0] * {"channel_group":{"values": {"Capabilities": .[1].channel}}}' config.json ./scripts/capabilities.json > modified_config.json 55 | elif [ $GROUP == "application" ]; then 56 | jq -s '.[0] * {"channel_group":{"groups":{"Application": {"values": {"Capabilities": .[1].application}}}}}' config.json ./scripts/capabilities.json > modified_config.json 57 | fi 58 | 59 | # Create a config updated for this channel based on the differences between config.json and modified_config.json 60 | # write the output to config_update_in_envelope.pb 61 | createConfigUpdate "$CH_NAME" config.json modified_config.json config_update_in_envelope.pb 62 | 63 | # Sign, and set the correct identity for submission. 64 | if [ $CH_NAME != $SYS_CHANNEL ] ; then 65 | if [ $GROUP == "orderer" ]; then 66 | # Modifying the orderer group requires only the Orderer admin to sign. 67 | # Prepare to sign the update as the OrdererOrg.Admin 68 | setOrdererGlobals 69 | elif [ $GROUP == "channel" ]; then 70 | # Modifying the channel group requires a majority of application admins and the orderer admin to sign. 71 | # Sign with PeerOrg1.Admin 72 | signConfigtxAsPeerOrg 1 config_update_in_envelope.pb 73 | # Sign with PeerOrg2.Admin 74 | signConfigtxAsPeerOrg 2 config_update_in_envelope.pb 75 | # Prepare to sign the update as the OrdererOrg.Admin 76 | setOrdererGlobals 77 | elif [ $GROUP == "application" ]; then 78 | # Modifying the application group requires a majority of application admins to sign. 79 | # Sign with PeerOrg1.Admin 80 | signConfigtxAsPeerOrg 1 config_update_in_envelope.pb 81 | # Prepare to sign the update as the PeerOrg2.Admin 82 | setGlobals 0 2 83 | fi 84 | else 85 | # For the orderer system channel, only the orderer admin needs sign 86 | # which will be attached during the update 87 | setOrdererGlobals 88 | fi 89 | 90 | if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then 91 | set -x 92 | peer channel update -f config_update_in_envelope.pb -c $CH_NAME -o orderer.example.com:7050 --cafile $ORDERER_CA 93 | res=$? 94 | set +x 95 | else 96 | set -x 97 | peer channel update -f config_update_in_envelope.pb -c $CH_NAME -o orderer.example.com:7050 --tls true --cafile $ORDERER_CA 98 | res=$? 99 | set +x 100 | fi 101 | verifyResult $res "Config update for \"$GROUP\" on \"$CH_NAME\" failed" 102 | echo "===================== Config update for \"$GROUP\" on \"$CH_NAME\" is completed ===================== " 103 | 104 | } 105 | 106 | sleep $DELAY 107 | 108 | #Config update for /Channel on $SYS_CHANNEL 109 | echo "Config update for /Channel on \"$SYS_CHANNEL\"" 110 | addCapabilityToChannel $SYS_CHANNEL channel 111 | 112 | sleep $DELAY 113 | 114 | #Config update for /Channel/Orderer on $SYS_CHANNEL 115 | echo "Config update for /Channel/Orderer on \"$SYS_CHANNEL\"" 116 | addCapabilityToChannel $SYS_CHANNEL orderer 117 | 118 | sleep $DELAY 119 | 120 | #Config update for /Channel on $CHANNEL_NAME 121 | echo "Config update for /Channel on \"$CHANNEL_NAME\"" 122 | addCapabilityToChannel $CHANNEL_NAME channel 123 | 124 | sleep $DELAY 125 | 126 | #Config update for /Channel/Orderer 127 | echo "Config update for /Channel/Orderer on \"$CHANNEL_NAME\"" 128 | addCapabilityToChannel $CHANNEL_NAME orderer 129 | 130 | sleep $DELAY 131 | 132 | #Config update for /Channel/Application 133 | echo "Config update for /Channel/Application on \"$CHANNEL_NAME\"" 134 | addCapabilityToChannel $CHANNEL_NAME application 135 | 136 | sleep $DELAY 137 | 138 | #Query on chaincode on Peer0/Org1 139 | echo "Querying chaincode on org1/peer0..." 140 | chaincodeQuery 0 1 90 141 | 142 | sleep $DELAY 143 | 144 | #Invoke on chaincode on Peer0/Org1 145 | echo "Sending invoke transaction on org1/peer0..." 146 | chaincodeInvoke 0 1 0 2 147 | 148 | sleep $DELAY 149 | 150 | #Query on chaincode on Peer0/Org1 151 | echo "Querying chaincode on org1/peer0..." 152 | chaincodeQuery 0 1 80 153 | 154 | echo 155 | echo "===================== All GOOD, End-2-End UPGRADE Scenario execution completed ===================== " 156 | echo 157 | 158 | echo 159 | echo " _____ _ _ ____ _____ ____ _____ " 160 | echo "| ____| | \ | | | _ \ | ____| |___ \ | ____|" 161 | echo "| _| | \| | | | | | _____ | _| __) | | _| " 162 | echo "| |___ | |\ | | |_| | |_____| | |___ / __/ | |___ " 163 | echo "|_____| |_| \_| |____/ |_____| |_____| |_____|" 164 | echo 165 | 166 | exit 0 167 | -------------------------------------------------------------------------------- /first-network/scripts/utils.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright IBM Corp All Rights Reserved 3 | # 4 | # SPDX-License-Identifier: Apache-2.0 5 | # 6 | 7 | # This is a collection of bash functions used by different scripts 8 | 9 | ORDERER_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 10 | PEER0_ORG1_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt 11 | PEER0_ORG2_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt 12 | PEER0_ORG3_CA=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt 13 | 14 | # verify the result of the end-to-end test 15 | verifyResult() { 16 | if [ $1 -ne 0 ]; then 17 | echo "!!!!!!!!!!!!!!! "$2" !!!!!!!!!!!!!!!!" 18 | echo "========= ERROR !!! FAILED to execute End-2-End Scenario ===========" 19 | echo 20 | exit 1 21 | fi 22 | } 23 | 24 | # Set OrdererOrg.Admin globals 25 | setOrdererGlobals() { 26 | CORE_PEER_LOCALMSPID="OrdererMSP" 27 | CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 28 | CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/users/Admin@example.com/msp 29 | } 30 | 31 | setGlobals() { 32 | PEER=$1 33 | ORG=$2 34 | if [ $ORG -eq 1 ]; then 35 | CORE_PEER_LOCALMSPID="Org1MSP" 36 | CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG1_CA 37 | CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp 38 | if [ $PEER -eq 0 ]; then 39 | CORE_PEER_ADDRESS=peer0.org1.example.com:7051 40 | else 41 | CORE_PEER_ADDRESS=peer1.org1.example.com:8051 42 | fi 43 | elif [ $ORG -eq 2 ]; then 44 | CORE_PEER_LOCALMSPID="Org2MSP" 45 | CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG2_CA 46 | CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp 47 | if [ $PEER -eq 0 ]; then 48 | CORE_PEER_ADDRESS=peer0.org2.example.com:9051 49 | else 50 | CORE_PEER_ADDRESS=peer1.org2.example.com:10051 51 | fi 52 | 53 | elif [ $ORG -eq 3 ]; then 54 | CORE_PEER_LOCALMSPID="Org3MSP" 55 | CORE_PEER_TLS_ROOTCERT_FILE=$PEER0_ORG3_CA 56 | CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp 57 | if [ $PEER -eq 0 ]; then 58 | CORE_PEER_ADDRESS=peer0.org3.example.com:11051 59 | else 60 | CORE_PEER_ADDRESS=peer1.org3.example.com:12051 61 | fi 62 | else 63 | echo "================== ERROR !!! ORG Unknown ==================" 64 | fi 65 | 66 | if [ "$VERBOSE" == "true" ]; then 67 | env | grep CORE 68 | fi 69 | } 70 | 71 | updateAnchorPeers() { 72 | PEER=$1 73 | ORG=$2 74 | setGlobals $PEER $ORG 75 | 76 | if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then 77 | set -x 78 | peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx >&log.txt 79 | res=$? 80 | set +x 81 | else 82 | set -x 83 | peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/${CORE_PEER_LOCALMSPID}anchors.tx --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA >&log.txt 84 | res=$? 85 | set +x 86 | fi 87 | cat log.txt 88 | verifyResult $res "Anchor peer update failed" 89 | echo "===================== Anchor peers updated for org '$CORE_PEER_LOCALMSPID' on channel '$CHANNEL_NAME' ===================== " 90 | sleep $DELAY 91 | echo 92 | } 93 | 94 | ## Sometimes Join takes time hence RETRY at least 5 times 95 | joinChannelWithRetry() { 96 | PEER=$1 97 | ORG=$2 98 | setGlobals $PEER $ORG 99 | 100 | set -x 101 | peer channel join -b $CHANNEL_NAME.block >&log.txt 102 | res=$? 103 | set +x 104 | cat log.txt 105 | if [ $res -ne 0 -a $COUNTER -lt $MAX_RETRY ]; then 106 | COUNTER=$(expr $COUNTER + 1) 107 | echo "peer${PEER}.org${ORG} failed to join the channel, Retry after $DELAY seconds" 108 | sleep $DELAY 109 | joinChannelWithRetry $PEER $ORG 110 | else 111 | COUNTER=1 112 | fi 113 | verifyResult $res "After $MAX_RETRY attempts, peer${PEER}.org${ORG} has failed to join channel '$CHANNEL_NAME' " 114 | } 115 | 116 | installChaincode() { 117 | PEER=$1 118 | ORG=$2 119 | setGlobals $PEER $ORG 120 | VERSION=${3:-1.0} 121 | set -x 122 | peer chaincode install -n mycc -v ${VERSION} -l ${LANGUAGE} -p ${CC_SRC_PATH} >&log.txt 123 | res=$? 124 | set +x 125 | cat log.txt 126 | verifyResult $res "Chaincode installation on peer${PEER}.org${ORG} has failed" 127 | echo "===================== Chaincode is installed on peer${PEER}.org${ORG} ===================== " 128 | echo 129 | } 130 | 131 | instantiateChaincode() { 132 | PEER=$1 133 | ORG=$2 134 | setGlobals $PEER $ORG 135 | VERSION=${3:-1.0} 136 | 137 | # while 'peer chaincode' command can get the orderer endpoint from the peer 138 | # (if join was successful), let's supply it directly as we know it using 139 | # the "-o" option 140 | if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then 141 | set -x 142 | peer chaincode instantiate -o orderer.example.com:7050 -C $CHANNEL_NAME -n mycc -l ${LANGUAGE} -v ${VERSION} -c '{"Args":["init","a","100","b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')" >&log.txt 143 | res=$? 144 | set +x 145 | else 146 | set -x 147 | peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -l ${LANGUAGE} -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer')" >&log.txt 148 | res=$? 149 | set +x 150 | fi 151 | cat log.txt 152 | verifyResult $res "Chaincode instantiation on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' failed" 153 | echo "===================== Chaincode is instantiated on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' ===================== " 154 | echo 155 | } 156 | 157 | upgradeChaincode() { 158 | PEER=$1 159 | ORG=$2 160 | setGlobals $PEER $ORG 161 | 162 | set -x 163 | peer chaincode upgrade -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc -v 2.0 -c '{"Args":["init","a","90","b","210"]}' -P "AND ('Org1MSP.peer','Org2MSP.peer','Org3MSP.peer')" 164 | res=$? 165 | set +x 166 | cat log.txt 167 | verifyResult $res "Chaincode upgrade on peer${PEER}.org${ORG} has failed" 168 | echo "===================== Chaincode is upgraded on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' ===================== " 169 | echo 170 | } 171 | 172 | chaincodeQuery() { 173 | PEER=$1 174 | ORG=$2 175 | setGlobals $PEER $ORG 176 | EXPECTED_RESULT=$3 177 | echo "===================== Querying on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME'... ===================== " 178 | local rc=1 179 | local starttime=$(date +%s) 180 | 181 | # continue to poll 182 | # we either get a successful response, or reach TIMEOUT 183 | while 184 | test "$(($(date +%s) - starttime))" -lt "$TIMEOUT" -a $rc -ne 0 185 | do 186 | sleep $DELAY 187 | echo "Attempting to Query peer${PEER}.org${ORG} ...$(($(date +%s) - starttime)) secs" 188 | set -x 189 | peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' >&log.txt 190 | res=$? 191 | set +x 192 | test $res -eq 0 && VALUE=$(cat log.txt | awk '/Query Result/ {print $NF}') 193 | test "$VALUE" = "$EXPECTED_RESULT" && let rc=0 194 | # removed the string "Query Result" from peer chaincode query command 195 | # result. as a result, have to support both options until the change 196 | # is merged. 197 | test $rc -ne 0 && VALUE=$(cat log.txt | egrep '^[0-9]+$') 198 | test "$VALUE" = "$EXPECTED_RESULT" && let rc=0 199 | done 200 | echo 201 | cat log.txt 202 | if test $rc -eq 0; then 203 | echo "===================== Query successful on peer${PEER}.org${ORG} on channel '$CHANNEL_NAME' ===================== " 204 | else 205 | echo "!!!!!!!!!!!!!!! Query result on peer${PEER}.org${ORG} is INVALID !!!!!!!!!!!!!!!!" 206 | echo "================== ERROR !!! FAILED to execute End-2-End Scenario ==================" 207 | echo 208 | exit 1 209 | fi 210 | } 211 | 212 | # fetchChannelConfig 213 | # Writes the current channel config for a given channel to a JSON file 214 | fetchChannelConfig() { 215 | CHANNEL=$1 216 | OUTPUT=$2 217 | 218 | setOrdererGlobals 219 | 220 | echo "Fetching the most recent configuration block for the channel" 221 | if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then 222 | set -x 223 | peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL --cafile $ORDERER_CA 224 | set +x 225 | else 226 | set -x 227 | peer channel fetch config config_block.pb -o orderer.example.com:7050 -c $CHANNEL --tls --cafile $ORDERER_CA 228 | set +x 229 | fi 230 | 231 | echo "Decoding config block to JSON and isolating config to ${OUTPUT}" 232 | set -x 233 | configtxlator proto_decode --input config_block.pb --type common.Block | jq .data.data[0].payload.data.config >"${OUTPUT}" 234 | set +x 235 | } 236 | 237 | # signConfigtxAsPeerOrg 238 | # Set the peerOrg admin of an org and signing the config update 239 | signConfigtxAsPeerOrg() { 240 | PEERORG=$1 241 | TX=$2 242 | setGlobals 0 $PEERORG 243 | set -x 244 | peer channel signconfigtx -f "${TX}" 245 | set +x 246 | } 247 | 248 | # createConfigUpdate 249 | # Takes an original and modified config, and produces the config update tx 250 | # which transitions between the two 251 | createConfigUpdate() { 252 | CHANNEL=$1 253 | ORIGINAL=$2 254 | MODIFIED=$3 255 | OUTPUT=$4 256 | 257 | set -x 258 | configtxlator proto_encode --input "${ORIGINAL}" --type common.Config >original_config.pb 259 | configtxlator proto_encode --input "${MODIFIED}" --type common.Config >modified_config.pb 260 | configtxlator compute_update --channel_id "${CHANNEL}" --original original_config.pb --updated modified_config.pb >config_update.pb 261 | configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate >config_update.json 262 | echo '{"payload":{"header":{"channel_header":{"channel_id":"'$CHANNEL'", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . >config_update_in_envelope.json 263 | configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope >"${OUTPUT}" 264 | set +x 265 | } 266 | 267 | # parsePeerConnectionParameters $@ 268 | # Helper function that takes the parameters from a chaincode operation 269 | # (e.g. invoke, query, instantiate) and checks for an even number of 270 | # peers and associated org, then sets $PEER_CONN_PARMS and $PEERS 271 | parsePeerConnectionParameters() { 272 | # check for uneven number of peer and org parameters 273 | if [ $(($# % 2)) -ne 0 ]; then 274 | exit 1 275 | fi 276 | 277 | PEER_CONN_PARMS="" 278 | PEERS="" 279 | while [ "$#" -gt 0 ]; do 280 | setGlobals $1 $2 281 | PEER="peer$1.org$2" 282 | PEERS="$PEERS $PEER" 283 | PEER_CONN_PARMS="$PEER_CONN_PARMS --peerAddresses $CORE_PEER_ADDRESS" 284 | if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "true" ]; then 285 | TLSINFO=$(eval echo "--tlsRootCertFiles \$PEER$1_ORG$2_CA") 286 | PEER_CONN_PARMS="$PEER_CONN_PARMS $TLSINFO" 287 | fi 288 | # shift by two to get the next pair of peer/org parameters 289 | shift 290 | shift 291 | done 292 | # remove leading space for output 293 | PEERS="$(echo -e "$PEERS" | sed -e 's/^[[:space:]]*//')" 294 | } 295 | 296 | # chaincodeInvoke ... 297 | # Accepts as many peer/org pairs as desired and requests endorsement from each 298 | chaincodeInvoke() { 299 | parsePeerConnectionParameters $@ 300 | res=$? 301 | verifyResult $res "Invoke transaction failed on channel '$CHANNEL_NAME' due to uneven number of peer and org parameters " 302 | 303 | # while 'peer chaincode' command can get the orderer endpoint from the 304 | # peer (if join was successful), let's supply it directly as we know 305 | # it using the "-o" option 306 | if [ -z "$CORE_PEER_TLS_ENABLED" -o "$CORE_PEER_TLS_ENABLED" = "false" ]; then 307 | set -x 308 | peer chaincode invoke -o orderer.example.com:7050 -C $CHANNEL_NAME -n mycc $PEER_CONN_PARMS -c '{"Args":["invoke","a","b","10"]}' >&log.txt 309 | res=$? 310 | set +x 311 | else 312 | set -x 313 | peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C $CHANNEL_NAME -n mycc $PEER_CONN_PARMS -c '{"Args":["invoke","a","b","10"]}' >&log.txt 314 | res=$? 315 | set +x 316 | fi 317 | cat log.txt 318 | verifyResult $res "Invoke execution on $PEERS failed " 319 | echo "===================== Invoke transaction successful on $PEERS on channel '$CHANNEL_NAME' ===================== " 320 | echo 321 | } 322 | --------------------------------------------------------------------------------