[
  {
    "path": ".gitignore",
    "content": "#\n# Copyright SecureKey Technologies Inc. All Rights Reserved.\n#\n# SPDX-License-Identifier: Apache-2.0\n#\n*.db\n*report.xml\n.DS_Store\n.vscode\ndebug.test\nvendor/\n.idea/\n/fabric-cli/cmd/fabric-cli/fabric-cli\n"
  },
  {
    "path": ".gitreview",
    "content": "[gerrit]\nhost=gerrit.securekey.com\nport=29418\nproject=fabric-examples\n"
  },
  {
    "path": "README.md",
    "content": "fabric-examples\n"
  },
  {
    "path": "fabric-cli/.gitignore",
    "content": "#\n# Copyright SecureKey Technologies Inc. All Rights Reserved.\n#\n# SPDX-License-Identifier: Apache-2.0\n#\nvendor/\nfabric-sdk-go/\n"
  },
  {
    "path": "fabric-cli/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "fabric-cli/Makefile",
    "content": "#\n# Copyright SecureKey Technologies Inc. All Rights Reserved.\n#\n# SPDX-License-Identifier: Apache-2.0\n#\n\n# Supported Targets:\n#\n# populate-sdk: retrieves all fabric-sdk-files required for tests\n# fabric-sdk-go-pin: populates only upstream files (not included in git)\n# example-network: start the example fabric network\n# example-network-clean: stops any running network and cleans up the artifacts\n# clean: removes all generated artifacts\n#\n\n# Tool commands (overridable)\nGO_CMD             ?= go\nGO_DEP_CMD         ?= dep\nDOCKER_CMD         ?= docker\nDOCKER_COMPOSE_CMD ?= docker-compose\n\n# fabric-sdk-go version (overridable)\nFABRIC_SDK_GO_BRANCH    ?= master\nFABRIC_SDK_GO_COMMIT    ?= 8f3d32c9d1a66f88d405c9f5335870c5277f773a\n\n# Test fixture paths\nFIXTURE_DOCKERENV_PATH := fabric-sdk-go/test/fixtures/dockerenv\n\n.PHONY: polulate-sdk\npopulate-sdk: fabric-sdk-go-pin fabric-sdk-go-populate\n\n.PHONY: fabric-sdk-go-pin\nfabric-sdk-go-pin:\n\t@echo \"Pinning fabric-sdk-go ...\"\n\t@UPSTREAM_COMMIT=$(FABRIC_SDK_GO_COMMIT) UPSTREAM_BRANCH=$(FABRIC_SDK_GO_BRANCH) scripts/fabric-sdk-go/apply_upstream.sh\n\n.PHONY: fabric-sdk-go-populate\nfabric-sdk-go-populate:\n\t@scripts/fabric-sdk-go/populate.sh\n\n.PHONY: clean\nclean: example-network-clean\n\trm -Rf vendor\n\trm -Rf fabric-sdk-go\n\n.PHONY: example-network\nexample-network:\n\t@cd ./fabric-sdk-go && \\\n\t\tmake dockerenv-stable-up\n\n.PHONY: example-network-clean\nexample-network-clean:\n\t@DOCKER_CMD=$(DOCKER_CMD) scripts/fabric-sdk-go/example-network-clean.sh\n"
  },
  {
    "path": "fabric-cli/README.md",
    "content": "# Fabric CLI Sample Application\n\nFabric CLI is a sample command-line interface built using Fabric SDK GO. It provides the following functionality:\n\nChannel:\n\n- Create - Create a channel\n- Join - Join a peer to a channel\n\nQuery:\n\n- Info - Displays information about the block, including the block height\n- Block - Displays the contents of a given block\n- Tx - Displays the contents of a transaction within a block\n- Channels - Displays all channels for a peer\n- Installed - Displays the chaincodes installed on a peer\n- Peers - Displays the discovered peers on a channel\n- Local Peers - Displays the discovered local peers in an org\n\nChaincode:\n\n- Install - Installs chaincode\n- Instantiate - Instantiates chaincode\n- Upgrade - Upgrades chaincode\n- Invoke - Invokes chaincode with a transaction proposal and a commit\n- Query - Invokes chaincode without a commit\n- Info - Retrieves details about the chaincode\n\nEvents:\n\n- Listen Block - Listens for block events and displays the block when a new block is created\n- Listen Filtered Block - Listens for filtered block events and displays the filtered block when a new block is created\n- Listen TX - Listens for transaction events\n- Listen CC - Listens for chaincode events for a specified chaincode\n\n## Running\n\nNOTE: If using Go 1.11 or 1.12, you'll need to set the following environment variable:\n\n```bash\nexport GO111MODULE=on\n```\n\nRun the client:\n\n```bash\ngo run fabric-cli.go <command> <sub-command> [options]\n```\n\nTo display the available commands/options:\n\n```bash\ngo run fabric-cli.go\n```\n\n## Compatability\n\nThis example is compatible with the following Hyperledger Fabric/SDK commit levels:\n\n- fabric: v1.3.0, v1.4, v2.0\n- fabric-sdk-go: master:33f4504ff8f169ebddd822443eadbe1bf4b96887\n\n### Quick Tour\n\nStart the example HLF network locally\n\n```bash\nmake populate-sdk\nmake example-network\n```\n\nOpen another shell and go to the CLI directory\n\n```bash\ncd $GOPATH/src/github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli\n```\n\nCreate channel 'orgchannel' and add anchor peers\n\n```bash\ngo run fabric-cli.go channel create --cid orgchannel --txfile ../../fabric-sdk-go/test/fixtures/fabric/v1.4/channel/orgchannel.tx --config ../../test/fixtures/config/config_test_local.yaml\ngo run fabric-cli.go channel create --cid orgchannel --txfile ../../fabric-sdk-go/test/fixtures/fabric/v1.4/channel/orgchannelOrg1MSPanchors.tx --config ../../test/fixtures/config/config_test_local.yaml --orgid org1\ngo run fabric-cli.go channel create --cid orgchannel --txfile ../../fabric-sdk-go/test/fixtures/fabric/v1.4/channel/orgchannelOrg2MSPanchors.tx --config ../../test/fixtures/config/config_test_local.yaml --orgid org2\n```\n\nJoin all peers to channel 'orgchannel'\n\n```bash\ngo run fabric-cli.go channel join --cid orgchannel --config ../../test/fixtures/config/config_test_local.yaml\n```\n\nInstall ExampleCC chaincode on all peers\n\n```bash\ngo run fabric-cli.go chaincode install --ccp=github.com/securekey/example_cc --ccid=ExampleCC --v v0 --gopath ../../test/fixtures/testdata --config ../../test/fixtures/config/config_test_local.yaml\n```\n\nInstantiate ExampleCC chaincode with endorsement policy AND('Org1MSP.member','Org2MSP.member')\n\n```bash\ngo run fabric-cli.go chaincode instantiate --cid orgchannel --ccp=github.com/securekey/example_cc --ccid ExampleCC --v v0 --args '{\"Args\":[\"A\",\"1\",\"B\",\"2\"]}' --policy \"AND('Org1MSP.member','Org2MSP.member')\" --config ../../test/fixtures/config/config_test_local.yaml\n```\n\nQuery ExampleCC chaincode on a set of peers\n\n```bash\ngo run fabric-cli.go chaincode query --cid orgchannel --ccid ExampleCC --args '{\"Func\":\"query\",\"Args\":[\"A\"]}' --peer localhost:7051,localhost:8051 --payload --config ../../test/fixtures/config/config_test_local.yaml\n```\n\nListen for block events:\n\n```bash\ngo run fabric-cli.go event listenblock --cid orgchannel --base64 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\nThen invoke ExampleCC chaincode in another shell and observe block events in the first shell.\n\n```bash\ngo run fabric-cli.go chaincode invoke --cid orgchannel --ccid=ExampleCC --args '{\"Func\":\"move\",\"Args\":[\"A\",\"B\",\"1\"]}' --peer localhost:7051,localhost:8051 --base64 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\nTo clean up example network artifacts run\n\n```bash\nmake example-network-clean\n```\n\nTo clean up all generated artifacts run\n\n```bash\nmake clean\n```\n\n## CLI examples\n\n### Channel\n\n#### Create a channel\n\n```bash\ngo run fabric-cli.go channel create --cid orgchannel --txfile ../../fabric-sdk-go/test/fixtures/fabric/v1.4/channel/orgchannel.tx --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Update anchor peers\n\n```bash\ngo run fabric-cli.go channel create --cid orgchannel --txfile ../../fabric-sdk-go/test/fixtures/fabric/v1.4/channel/orgchannelOrg1MSPanchors.tx --orgid=org1 --config ../../test/fixtures/config/config_test_local.yaml\ngo run fabric-cli.go channel create --cid orgchannel --txfile ../../fabric-sdk-go/test/fixtures/fabric/v1.4/channel/orgchannelOrg2MSPanchors.tx --orgid=org2 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Join a peer to a channel\n\n```bash\ngo run fabric-cli.go channel join --cid orgchannel --peer localhost:7051 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Join all peers in org1 to a channel\n\n```bash\ngo run fabric-cli.go channel join --cid orgchannel --orgid org1 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Join all peers to a channel\n\n```bash\ngo run fabric-cli.go channel join --cid orgchannel --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n### Query\n\n#### Query info\n\n```bash\ngo run fabric-cli.go query info --cid orgchannel --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Query block by block number\n\n```bash\ngo run fabric-cli.go query block --cid orgchannel --num 0 --base64 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Query block by hash (replace the example hash with a valid hash, e.g. using the output from query info)\n\n```bash\ngo run fabric-cli.go query block --cid orgchannel --hash BNNsxK_Xyz2d3Yj2g6M2t3aOYkHCxvoPeIGmTWdOJ9w --base64 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Query block output in JSON format\n\n```bash\ngo run fabric-cli.go query block --cid orgchannel --num 0 --format json --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Query transaction (replace txid with a valid transaction, e.g. using the output from query block)\n\n```bash\ngo run fabric-cli.go query tx --cid orgchannel --txid 0ed409872e0e6a6aa745df10d5e71e33d7e160b84519c2ad89281e65b6561364 --base64 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Query channels joined by a peer\n\n```bash\ngo run fabric-cli.go query channels --peer localhost:7051 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Query installed chaincodes on a peer\n\n```bash\ngo run fabric-cli.go query installed --peer localhost:7051 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Query discovered peers on a channel\n\n```bash\ngo run fabric-cli.go query peers --cid orgchannel --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Query discovered peers in an org\n\n```bash\ngo run fabric-cli.go query localpeers --orgid org1 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n## Chaincode\n\n### Install Chaincode\n\n#### Install chaincode on a peer\n\n```bash\ngo run fabric-cli.go chaincode install --peer localhost:7051 --ccp=github.com/securekey/example_cc --gopath ../../test/fixtures/testdata --ccid=examplecc --v v0 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Install chaincode on all peers of org1\n\n```bash\ngo run fabric-cli.go chaincode install --orgid org1 --ccp=github.com/securekey/example_cc --gopath ../../test/fixtures/testdata --ccid=examplecc --v v0 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Install chaincode on all peers\n\n```bash\ngo run fabric-cli.go chaincode install --ccp=github.com/securekey/example_cc --gopath ../../test/fixtures/testdata --ccid=examplecc --v v0 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n### Instantiate and Upgrade Chaincode\n\n#### Instantiate chaincode with default endorsement policy (any one)\n\n```bash\ngo run fabric-cli.go chaincode instantiate --cid orgchannel --ccp github.com/securekey/example_cc --ccid examplecc --v v0 --args='{\"Args\":[\"A\",\"1\",\"B\",\"2\"]}' --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Instantiate chaincode with specified endorsement policy\n\n```bash\ngo run fabric-cli.go chaincode instantiate --cid orgchannel --ccp github.com/securekey/example_cc --ccid examplecc --v v0 --args='{\"Args\":[\"A\",\"1\",\"B\",\"2\"]}' --policy \"AND('Org1MSP.member','Org2MSP.member')\" --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Instantiate chaincode with specified private data collection configuration (Fabric 1.2 and greater)\n\n```bash\ngo run fabric-cli.go chaincode install --ccp=github.com/securekey/example2_cc --gopath ../../test/fixtures/testdata --ccid=example2cc --v v0 --config ../../test/fixtures/config/config_test_local.yaml\ngo run fabric-cli.go chaincode instantiate --cid orgchannel --ccp github.com/securekey/example2_cc --ccid example2cc --v v0 --policy \"AND('Org1MSP.member','Org2MSP.member')\" --collconfig ../../test/fixtures/config/pvtdatacollection.json --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Upgrade chaincode\n\n```bash\ngo run fabric-cli.go chaincode install --cid=orgchannel --ccp=github.com/securekey/example_cc --gopath ../../test/fixtures/testdata --ccid=examplecc --v v1 --config ../../test/fixtures/config/config_test_local.yaml\ngo run fabric-cli.go chaincode upgrade --cid orgchannel --ccp github.com/securekey/example_cc --ccid examplecc --v v1 --args='{\"Args\":[\"A\",\"1\",\"B\",\"2\"]}' --policy \"OutOf(2,'Org1MSP.member','Org2MSP.member')\" --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n### Chaincode Info\n\n#### Retrieve chaincode deployment info\n\n```bash\ngo run fabric-cli.go chaincode info --cid orgchannel --ccid examplecc --base64 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n### Query Chaincode\n\n#### Query chaincode on a set of peers\n\n```bash\ngo run fabric-cli.go chaincode query --cid orgchannel --ccid=examplecc --args='{\"Func\":\"query\",\"Args\":[\"A\"]}' --peer localhost:7051,localhost:8051 --base64 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Query chaincode and view payloads only\n\n```bash\ngo run fabric-cli.go chaincode query --cid orgchannel --ccid=examplecc --args='{\"Func\":\"query\",\"Args\":[\"A\"]}' --peer localhost:7051,localhost:8051 --payload --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n### Invoke Chaincode\n\n#### Invoke chaincode on all peers in org1\n\n```bash\ngo run fabric-cli.go chaincode invoke --cid orgchannel --ccid=examplecc --args='{\"Func\":\"move\",\"Args\":[\"A\",\"B\",\"1\"]}' --orgid org1 --base64 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Invoke chaincode using a 'dynamic' selection provider that chooses a minimal set of peers required to satisfy the endorsement policy of the chaincode\n\n```bash\ngo run fabric-cli.go chaincode invoke --cid orgchannel --ccid=examplecc --args='{\"Func\":\"move\",\"Args\":[\"A\",\"B\",\"1\"]}' --selectprovider=dynamic --base64 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Invoke chaincode using Fabric's discovery service to choose a minimal set of peers required to satisfy the endorsement policy of the chaincode (Requires Fabric >=1.2)\n\n```bash\ngo run fabric-cli.go chaincode invoke --cid orgchannel --ccid=examplecc --args='{\"Func\":\"move\",\"Args\":[\"A\",\"B\",\"1\"]}' --selectprovider=fabric --base64 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Invoke chaincode using a selection provider automatically determined from channel capabilities ('dynamic' for v1.1; 'fabric' for >=v1.2)\n\n```bash\ngo run fabric-cli.go chaincode invoke --cid orgchannel --ccid=examplecc --args='{\"Func\":\"move\",\"Args\":[\"A\",\"B\",\"1\"]}' --base64 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Invoke chaincode 5 times\n\n```bash\ngo run fabric-cli.go chaincode invoke --cid orgchannel --ccid=examplecc --args='{\"Func\":\"move\",\"Args\":[\"A\",\"B\",\"1\"]}' --iterations 5 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Invoke chaincode 100 times in 8 Go routines with a maximum of 5 attempts for each invocation (in case the invocation fails)\n\n```bash\ngo run fabric-cli.go chaincode invoke --cid orgchannel --ccid=examplecc --args='{\"Func\":\"move\",\"Args\":[\"A\",\"B\",\"1\"]}' --iterations 100 --concurrency 8 --attempts 5 --backoff 1000 --backofffactor 1.5 --maxbackoff 5000 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Invoke chaincode with two sets of args, 100 times each in 8 Go routines with 3 attempts for each invocation (in case the invocation fails)\n\n```bash\ngo run fabric-cli.go chaincode invoke --cid orgchannel --ccid=examplecc --args='[{\"Func\":\"move\",\"Args\":[\"A\",\"B\",\"1\"]},{\"Func\":\"move\",\"Args\":[\"B\",\"A\",\"1\"]}]' --iterations 100 --concurrency 8 --attempts=3 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Invoke chaincode 100 times in 8 Go routines using randomly generated keys, values, and variables\n\n```bash\ngo run fabric-cli.go chaincode invoke --cid orgchannel --ccid=example2cc --args='[{\"Func\":\"putprivate\",\"Args\":[\"$set(coll,coll1)\",\"$set(key,Key_$rand(500))\",\"Val_$rand(1000)\"]},{\"Func\":\"getprivate\",\"Args\":[\"${coll}\",\"${key}\"]}]' --iterations 100 --concurrency 8 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Invoke chaincode 100 times in 8 Go routines using sequentially generated keys and large values\n\n```bash\ngo run fabric-cli.go chaincode invoke --cid orgchannel --ccid=example2cc --args='{\"Func\":\"putprivate\",\"Args\":[\"coll1\",\"Key_$seq()\",\"Val_$pad(500,X)\"]}' --iterations 100 --concurrency 8 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Invoke chaincode 100 times in 8 Go routines using randomly generated keys and random size values\n\n```bash\ngo run fabric-cli.go chaincode invoke --cid orgchannel --ccid=example2cc --args='{\"Func\":\"putprivate\",\"Args\":[\"coll1\",\"Key_$rand(500)\",\"Val_$pad($rand(500),X)\"]}' --iterations 100 --concurrency 8 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n#### Invoke a chaincode using the contents of a file as a value\n\n```bash\ngo run fabric-cli.go chaincode invoke --cid orgchannel --ccid=example2cc --args='{\"Func\":\"put\",\"Args\":[\"coll1\",\"Key_1\",\"$file(./chaincode/utils/test.json)\"]}' --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n## Event\n\n### Block Events\n\n### Listen for block events on a specific peer (output in JSON)\n\n```bash\ngo run fabric-cli.go event listenblock --cid orgchannel --peer localhost:7051 --format json --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n### Listen for block events starting from block number 20\n\n```bash\ngo run fabric-cli.go event listenblock --cid orgchannel --peer localhost:7051 --seek from --num 20 --base64 --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n### Listen for filtered block events (output in JSON)\n\n```bash\ngo run fabric-cli.go event listenfilteredblock --cid orgchannel --format json --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n### Listen for chaincode events\n\n```bash\ngo run fabric-cli.go event listencc --cid orgchannel --ccid=examplecc --event=.* --config ../../test/fixtures/config/config_test_local.yaml\n```\n\n### Listen for tx event\n\n```bash\ngo run fabric-cli.go event listentx --cid orgchannel --txid <txid> --config ../../test/fixtures/config/config_test_local.yaml\n```\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/action/action.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage action\n\nimport (\n\t\"encoding/json\"\n\t\"math/rand\"\n\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/factory/defcore\"\n\n\t\"github.com/pkg/errors\"\n\n\t\"strings\"\n\n\t\"io\"\n\n\t\"fmt\"\n\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/channel\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/event\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/ledger\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/msp\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/logging\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab\"\n\tmspapi \"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp\"\n\tcontextImpl \"github.com/hyperledger/fabric-sdk-go/pkg/context\"\n\tcryptosuiteimpl \"github.com/hyperledger/fabric-sdk-go/pkg/core/cryptosuite/bccsp/multisuite\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/fab/orderer\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/printer\"\n\t\"github.com/spf13/pflag\"\n)\n\nconst (\n\tdefaultUser = \"User1\" // pre-enrolled user\n\tadminUser   = \"Admin\"\n)\n\n// ArgStruct is used for marshalling arguments to chaincode invocations\ntype ArgStruct struct {\n\tFunc string   `json:\"Func\"`\n\tArgs []string `json:\"Args\"`\n}\n\n// Action is the base implementation of the Action interface.\ntype Action struct {\n\tflags          *pflag.FlagSet\n\tsdk            *fabsdk.FabricSDK\n\tendpointConfig fab.EndpointConfig\n\tpeersByOrg     map[string][]fab.Peer\n\tpeers          []fab.Peer\n\torgIDByPeer    map[string]string\n\tprinter        printer.Printer\n\tinitError      error\n\tWriter         io.Writer\n\tsessions       map[string]context.ClientProvider\n}\n\n// Initialize initializes the action using the given flags\nfunc (action *Action) Initialize(flags *pflag.FlagSet) error {\n\n\taction.sessions = make(map[string]context.ClientProvider)\n\taction.flags = flags\n\n\tif err := cliconfig.InitConfig(flags); err != nil {\n\t\treturn err\n\t}\n\n\tvar opts []fabsdk.Option\n\tif cliconfig.Config().SelectionProvider() != cliconfig.AutoDetectSelectionProvider {\n\t\tsvcPackage, err := newServiceProviderFactory()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\topts = append(opts, fabsdk.WithServicePkg(svcPackage))\n\t}\n\topts = append(opts, fabsdk.WithCorePkg(&cryptoSuiteProviderFactory{}))\n\n\tsdk, err := fabsdk.New(cliconfig.Provider(), opts...)\n\tif err != nil {\n\t\treturn errors.Errorf(\"Error initializing SDK: %s\", err)\n\t}\n\taction.sdk = sdk\n\n\tctx, err := sdk.Context()()\n\tif err != nil {\n\t\treturn errors.WithMessage(err, \"Error creating anonymous provider\")\n\t}\n\n\taction.endpointConfig = ctx.EndpointConfig()\n\n\tnetworkConfig := action.endpointConfig.NetworkConfig()\n\n\tlevel := levelFromName(cliconfig.Config().LoggingLevel())\n\n\tlogging.SetLevel(\"\", level)\n\n\taction.orgIDByPeer = make(map[string]string)\n\n\tvar allPeers []fab.Peer\n\tallPeersByOrg := make(map[string][]fab.Peer)\n\tfor orgID := range networkConfig.Organizations {\n\t\tpeersConfig, ok := action.endpointConfig.PeersConfig(orgID)\n\t\tif !ok {\n\t\t\treturn errors.Errorf(\"failed to get peer configs for org [%s]\", orgID)\n\t\t}\n\n\t\tcliconfig.Config().Logger().Debugf(\"Peers for org [%s]: %v\\n\", orgID, peersConfig)\n\n\t\tvar peers []fab.Peer\n\t\tfor _, p := range peersConfig {\n\t\t\tendorser, err := ctx.InfraProvider().CreatePeerFromConfig(&fab.NetworkPeer{PeerConfig: p})\n\t\t\tif err != nil {\n\t\t\t\treturn errors.Wrapf(err, \"failed to create peer from config\")\n\t\t\t}\n\t\t\tpeers = append(peers, endorser)\n\t\t\taction.orgIDByPeer[endorser.URL()] = orgID\n\t\t}\n\t\tallPeersByOrg[orgID] = peers\n\t\tallPeers = append(allPeers, peers...)\n\t}\n\n\tif cliconfig.Config().IsLoggingEnabledFor(logging.DEBUG) {\n\t\tcliconfig.Config().Logger().Debug(\"All Peers:\")\n\t\tfor orgID, peers := range allPeersByOrg {\n\t\t\tcliconfig.Config().Logger().Debugf(\"Org: %s\\n\", orgID)\n\t\t\tfor i, peer := range peers {\n\t\t\t\tcliconfig.Config().Logger().Debugf(\"-- Peer[%d]: MSPID: %s, URL: %s\\n\", i, peer.MSPID(), peer.URL())\n\t\t\t}\n\t\t}\n\t}\n\n\t// Filter peers by specified peers/orgs\n\tpeers, err := action.getPeers(allPeers, cliconfig.Config().PeerURLs(), cliconfig.Config().OrgIDs())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Organize peers by orgs\n\tpeersByOrg := make(map[string][]fab.Peer)\n\tcliconfig.Config().Logger().Debugf(\"Selected Peers:\\n\")\n\tfor _, peer := range peers {\n\t\tcliconfig.Config().Logger().Debugf(\"- URL: %s\\n\", peer.URL())\n\t\torgID := action.orgIDByPeer[peer.URL()]\n\t\tif orgID == \"\" {\n\t\t\treturn errors.Errorf(\"unable to find org for peer: %s\", peer.URL())\n\t\t}\n\t\tpeersByOrg[orgID] = append(peersByOrg[orgID], peer)\n\t}\n\n\taction.peers = peers\n\taction.peersByOrg = peersByOrg\n\n\taction.printer = printer.NewBlockPrinterWithOpts(\n\t\tprinter.AsOutputFormat(cliconfig.Config().PrintFormat()),\n\t\tprinter.AsWriterType(cliconfig.Config().Writer()),\n\t\t&printer.FormatterOpts{Base64Encode: cliconfig.Config().Base64()})\n\n\treturn nil\n}\n\n// Terminate closes any open connections. This function should be called at the end of every command invocation.\nfunc (action *Action) Terminate() {\n\tif action.sdk != nil {\n\t\tcliconfig.Config().Logger().Info(\"Closing SDK\")\n\t\taction.sdk.Close()\n\t}\n}\n\n// Flags returns the flag-set\nfunc (action *Action) Flags() *pflag.FlagSet {\n\treturn action.flags\n}\n\n// EndpointConfig returns the endpoint configuration\nfunc (action *Action) EndpointConfig() fab.EndpointConfig {\n\treturn action.endpointConfig\n}\n\n// ChannelClient creates a new channel client\nfunc (action *Action) ChannelClient(...channel.ClientOption) (*channel.Client, error) {\n\tuser, err := action.User()\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error getting user: %s\", err)\n\t}\n\tsession, err := action.context(user)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error getting session for user [%s,%s]: %v\", user.Identifier().MSPID, user.Identifier().ID, err)\n\t}\n\tchannelProvider := func() (context.Channel, error) {\n\t\treturn contextImpl.NewChannel(session, cliconfig.Config().ChannelID())\n\t}\n\treturn channel.New(channelProvider)\n}\n\n// OrgAdminChannelClient creates a new channel client for the given org in order to perform administrative functions\nfunc (action *Action) OrgAdminChannelClient(orgID string) (*channel.Client, error) {\n\tchannelID := cliconfig.Config().ChannelID()\n\tcliconfig.Config().Logger().Debugf(\"Creating new channel client for channel [%s] and org [%s] ...\", channelID, orgID)\n\n\tuser, err := action.OrgAdminUser(orgID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tchannelClient, err := action.ClientForUser(channelID, user)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error creating fabric client: %s\", err)\n\t}\n\n\treturn channelClient, nil\n}\n\n// AdminChannelClient creates a new channel client for performing administrative functions\nfunc (action *Action) AdminChannelClient() (*channel.Client, error) {\n\treturn action.OrgAdminChannelClient(action.OrgID())\n}\n\n// Printer returns the Printer\nfunc (action *Action) Printer() printer.Printer {\n\treturn action.printer\n}\n\n// LocalContext creates a new local context\nfunc (action *Action) LocalContext() (context.Local, error) {\n\tuser, err := action.User()\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error getting user: %s\", err)\n\t}\n\tcontextProvider, err := action.context(user)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error getting context for user [%s,%s]: %v\", user.Identifier().MSPID, user.Identifier().ID, err)\n\t}\n\treturn contextImpl.NewLocal(contextProvider)\n}\n\n// ChannelProvider returns the ChannelProvider\nfunc (action *Action) ChannelProvider() (context.ChannelProvider, error) {\n\tchannelID := cliconfig.Config().ChannelID()\n\tuser, err := action.User()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcliconfig.Config().Logger().Debugf(\"creating channel provider for user [%s] in org [%s]...\", user.Identifier().ID, user.Identifier().MSPID)\n\tclientContext, err := action.context(user)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error getting client context for user [%s,%s]: %v\", user.Identifier().MSPID, user.Identifier().ID, err)\n\t}\n\tchannelProvider := func() (context.Channel, error) {\n\t\treturn contextImpl.NewChannel(clientContext, channelID)\n\t}\n\treturn channelProvider, nil\n}\n\n// EventClient returns the event hub.\nfunc (action *Action) EventClient(opts ...event.ClientOption) (*event.Client, error) {\n\tchannelProvider, err := action.ChannelProvider()\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error creating channel provider: %v\", err)\n\t}\n\tc, err := event.New(channelProvider, opts...)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error creating new event client: %v\", err)\n\t}\n\treturn c, nil\n}\n\n// LedgerClient returns the Fabric client for the current user\nfunc (action *Action) LedgerClient() (*ledger.Client, error) {\n\tchannelProvider, err := action.ChannelProvider()\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error creating channel provider: %v\", err)\n\t}\n\tc, err := ledger.New(channelProvider)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error creating new ledger client: %v\", err)\n\t}\n\treturn c, nil\n}\n\n// Peer returns the first peer in the list of selected peers\nfunc (action *Action) Peer() fab.Peer {\n\tif len(action.peers) == 0 {\n\t\treturn nil\n\t}\n\treturn action.peers[0]\n}\n\n// Peers returns the peers\nfunc (action *Action) Peers() []fab.Peer {\n\treturn action.peers\n}\n\n// PeersByOrg returns the peers mapped by organization\nfunc (action *Action) PeersByOrg() map[string][]fab.Peer {\n\treturn action.peersByOrg\n}\n\n// OrgOfPeer returns the organization ID of the given peer\nfunc (action *Action) OrgOfPeer(peerURL string) (string, error) {\n\torgID, ok := action.orgIDByPeer[peerURL]\n\tif !ok {\n\t\treturn \"\", errors.Errorf(\"org not found for peer %s\", peerURL)\n\t}\n\treturn orgID, nil\n}\n\n// Client returns the Fabric client for the current user\nfunc (action *Action) Client(channelID string) (*channel.Client, error) {\n\tuser, err := action.User()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn action.ClientForUser(channelID, user)\n}\n\n// ResourceMgmtClient returns a resource management client for the current user\nfunc (action *Action) ResourceMgmtClient() (*resmgmt.Client, error) {\n\treturn action.ResourceMgmtClientForOrg(action.OrgID())\n}\n\n// ResourceMgmtClientForOrg returns a resource management client for the given org\nfunc (action *Action) ResourceMgmtClientForOrg(orgID string) (*resmgmt.Client, error) {\n\tuser, err := action.OrgAdminUser(orgID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn action.ResourceMgmtClientForUser(user)\n}\n\n// ClientForUser returns the Channel client for the given user\nfunc (action *Action) ClientForUser(channelID string, user mspapi.SigningIdentity) (*channel.Client, error) {\n\tcliconfig.Config().Logger().Debugf(\"create resmgmt client for user [%s] in org [%s]...\", user.Identifier().ID, user.Identifier().MSPID)\n\tsession, err := action.context(user)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error getting session for user [%s,%s]: %v\", user.Identifier().MSPID, user.Identifier().ID, err)\n\t}\n\tchannelProvider := func() (context.Channel, error) {\n\t\treturn contextImpl.NewChannel(session, channelID)\n\t}\n\tc, err := channel.New(channelProvider)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error creating new resmgmt client for user [%s,%s]: %v\", user.Identifier().MSPID, user.Identifier().ID, err)\n\t}\n\treturn c, nil\n}\n\n// ResourceMgmtClientForUser returns the Fabric client for the given user\nfunc (action *Action) ResourceMgmtClientForUser(user mspapi.SigningIdentity) (*resmgmt.Client, error) {\n\tcliconfig.Config().Logger().Debugf(\"create resmgmt client for user [%s] in org [%s]...\", user.Identifier().ID, user.Identifier().MSPID)\n\tsession, err := action.context(user)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error getting session for user [%s,%s]: %v\", user.Identifier().MSPID, user.Identifier().ID, err)\n\t}\n\tc, err := resmgmt.New(session)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error creating new resmgmt client for user [%s,%s]: %v\", user.Identifier().MSPID, user.Identifier().ID, err)\n\t}\n\treturn c, nil\n}\n\n// ChannelMgmtClientForUser returns the Fabric client for the given user\nfunc (action *Action) ChannelMgmtClientForUser(channelID string, user mspapi.SigningIdentity) (*channel.Client, error) {\n\tcliconfig.Config().Logger().Debugf(\"create channel client for user [%s] in org [%s]...\", user.Identifier().ID, user.Identifier().MSPID)\n\tsession, err := action.context(user)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error getting session for user [%s,%s]: %v\", user.Identifier().MSPID, user.Identifier().ID, err)\n\t}\n\tchannelProvider := func() (context.Channel, error) {\n\t\treturn contextImpl.NewChannel(session, channelID)\n\t}\n\tc, err := channel.New(channelProvider)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error creating new channel client for user [%s,%s]: %v\", user.Identifier().MSPID, user.Identifier().ID, err)\n\t}\n\treturn c, nil\n}\n\nfunc (action *Action) context(user mspapi.SigningIdentity) (context.ClientProvider, error) {\n\tkey := user.Identifier().MSPID + \"_\" + user.Identifier().ID\n\tsession := action.sessions[key]\n\tif session == nil {\n\t\tsession = action.sdk.Context(fabsdk.WithIdentity(user))\n\t\tcliconfig.Config().Logger().Debugf(\"Created session for user [%s] in org [%s]\", user.Identifier().ID, user.Identifier().MSPID)\n\t\taction.sessions[key] = session\n\t}\n\treturn session, nil\n}\n\n// OrgID returns the organization ID of the first peer in the list of peers\nfunc (action *Action) OrgID() string {\n\tif len(action.Peers()) == 0 {\n\t\t// This shouldn't happen since we should already have passed validation\n\t\tpanic(\"no peers to choose from!\")\n\t}\n\n\tpeer := action.Peers()[0]\n\torgID, err := action.OrgOfPeer(peer.URL())\n\tif err != nil {\n\t\t// This shouldn't happen since we should already have passed validation\n\t\tpanic(err)\n\t}\n\treturn orgID\n}\n\n// GetOrgID returns the organization ID for the given MSP ID\nfunc (action *Action) GetOrgID(mspID string) (string, error) {\n\tnetworkConfig := action.endpointConfig.NetworkConfig()\n\n\tfor orgID, orgConfig := range networkConfig.Organizations {\n\t\tif mspID == orgConfig.MSPID {\n\t\t\treturn orgID, nil\n\t\t}\n\t}\n\treturn \"\", errors.Errorf(\"unable to find org ID for MSP [%s]\", mspID)\n}\n\n// User returns the enrolled user. If the user doesn't exist then a new user is enrolled.\nfunc (action *Action) User() (mspapi.SigningIdentity, error) {\n\tuserName := cliconfig.Config().UserName()\n\tif userName == \"\" {\n\t\tuserName = defaultUser\n\t}\n\treturn action.OrgUser(action.OrgID(), userName)\n}\n\nfunc (action *Action) newUser(orgID, username, pwd string) (mspapi.SigningIdentity, error) {\n\n\tcliconfig.Config().Logger().Infof(\"Enrolling user %s...\\n\", username)\n\n\tmspClient, err := msp.New(action.sdk.Context(), msp.WithOrg(orgID))\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error creating MSP client: %s\", err)\n\t}\n\n\tcliconfig.Config().Logger().Infof(\"Creating new user %s...\\n\", username)\n\terr = mspClient.Enroll(username, msp.WithSecret(pwd))\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"Enroll returned error: %v\", err)\n\t}\n\n\tuser, err := mspClient.GetSigningIdentity(username)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"GetSigningIdentity returned error: %v\", err)\n\t}\n\n\tcliconfig.Config().Logger().Infof(\"Returning user [%s], MSPID [%s]\\n\", user.Identifier().ID, user.Identifier().MSPID)\n\n\treturn user, nil\n}\n\n// OrgUser returns an already enrolled user for the given organization\nfunc (action *Action) OrgUser(orgID, username string) (mspapi.SigningIdentity, error) {\n\tif username == \"\" {\n\t\treturn nil, errors.Errorf(\"no username specified\")\n\t}\n\tmspClient, err := msp.New(action.sdk.Context(), msp.WithOrg(orgID))\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error creating MSP client: %s\", err)\n\t}\n\n\tuser, err := mspClient.GetSigningIdentity(username)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"GetSigningIdentity returned error: %v\", err)\n\t}\n\n\tcliconfig.Config().Logger().Infof(\"Returning user [%s], MSPID [%s]\\n\", user.Identifier().ID, user.Identifier().MSPID)\n\n\treturn user, nil\n}\n\n// OrgAdminUser returns the pre-enrolled administrative user for the given organization\nfunc (action *Action) OrgAdminUser(orgID string) (mspapi.SigningIdentity, error) {\n\tuserName := cliconfig.Config().UserName()\n\tif userName == \"\" {\n\t\tuserName = adminUser\n\t}\n\treturn action.OrgUser(orgID, userName)\n}\n\n// PeerFromURL returns the peer for the given URL\nfunc (action *Action) PeerFromURL(url string) (fab.Peer, bool) {\n\tfor _, peer := range action.peers {\n\t\tif url == peer.URL() {\n\t\t\treturn peer, true\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// Orderers returns all Orderers from the set of configured Orderers\nfunc (action *Action) Orderers() ([]fab.Orderer, error) {\n\tordererConfigs := action.endpointConfig.OrderersConfig()\n\tordererURL := cliconfig.Config().OrdererURL()\n\n\tvar orderers []fab.Orderer\n\tfor _, ordererConfig := range ordererConfigs {\n\t\tif ordererURL == \"\" || ordererConfig.URL == ordererURL {\n\t\t\tnewOrderer, err := orderer.New(action.endpointConfig, orderer.FromOrdererConfig(&ordererConfig))\n\t\t\tif err != nil {\n\t\t\t\treturn nil, errors.WithMessage(err, \"creating orderer failed\")\n\t\t\t}\n\t\t\torderers = append(orderers, newOrderer)\n\t\t}\n\t}\n\n\treturn orderers, nil\n}\n\n// RandomOrderer chooses a random Orderer from the set of configured Orderers\nfunc (action *Action) RandomOrderer() (fab.Orderer, error) {\n\torderers, err := action.Orderers()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(orderers) == 0 {\n\t\treturn nil, errors.New(\"No orders found\")\n\t}\n\treturn orderers[rand.Intn(len(orderers))], nil\n}\n\n// ArgsArray returns an array of args used in chaincode invocations\nfunc ArgsArray() ([]ArgStruct, error) {\n\tvar argsArray []ArgStruct\n\targBytes := []byte(cliconfig.Config().Args())\n\tif strings.HasPrefix(cliconfig.Config().Args(), \"[\") {\n\t\tif err := json.Unmarshal(argBytes, &argsArray); err != nil {\n\t\t\treturn nil, errors.Errorf(\"Error unmarshaling JSON arg string: %v\", err)\n\t\t}\n\t} else {\n\t\targs := ArgStruct{}\n\t\tif err := json.Unmarshal(argBytes, &args); err != nil {\n\t\t\treturn nil, errors.Errorf(\"Error unmarshaling JSON arg string: %v\", err)\n\t\t}\n\t\targsArray = append(argsArray, args)\n\t}\n\treturn argsArray, nil\n}\n\nfunc levelFromName(levelName string) logging.Level {\n\tswitch levelName {\n\tcase \"CRITICAL\":\n\t\treturn logging.CRITICAL\n\tcase \"ERROR\":\n\t\treturn logging.ERROR\n\tcase \"WARNING\":\n\t\treturn logging.WARNING\n\tcase \"INFO\":\n\t\treturn logging.INFO\n\tcase \"DEBUG\":\n\t\treturn logging.DEBUG\n\tdefault:\n\t\treturn logging.ERROR\n\t}\n}\n\nfunc (action *Action) getPeers(allPeers []fab.Peer, peerURLs []string, orgIDs []string) ([]fab.Peer, error) {\n\tselectAll := false\n\tif len(peerURLs) == 0 && len(orgIDs) == 0 {\n\t\tselectAll = true\n\t}\n\tvar selectedPeers []fab.Peer\n\tvar allPeerURLs []string\n\tfor _, peer := range allPeers {\n\t\tallPeerURLs = append(allPeerURLs, peer.URL())\n\t\torgID := action.orgIDByPeer[peer.URL()]\n\t\tif selectAll || containsString(peerURLs, peer.URL()) || len(peerURLs) == 0 && containsString(orgIDs, orgID) {\n\t\t\tselectedPeers = append(selectedPeers, peer)\n\t\t}\n\t}\n\tfor _, url := range peerURLs {\n\t\tif !containsString(allPeerURLs, url) {\n\t\t\treturn nil, fmt.Errorf(\"invalid peer URL: %s\", url)\n\t\t}\n\t}\n\treturn selectedPeers, nil\n}\n\n// PeerConfig returns the PeerConfig for the first peer in the current org\nfunc (action *Action) PeerConfig() (*fab.PeerConfig, error) {\n\tpeersConfig, ok := action.endpointConfig.PeersConfig(action.OrgID())\n\tif !ok {\n\t\treturn nil, errors.Errorf(\"Error reading peers config for %s: %v\", action.OrgID())\n\t}\n\n\tpeer := action.Peer()\n\n\tfor _, p := range peersConfig {\n\t\tif peer.URL() == \"\" || p.URL == peer.URL() {\n\t\t\treturn &p, nil\n\t\t}\n\t}\n\n\treturn nil, errors.Errorf(\"No configuration found for peer %s\", peer.URL())\n}\n\n// CreateDiscoveryService returns a new DiscoveryService for the given channel.\n// This is an implementation of the DiscoveryProvider interface\nfunc (action *Action) CreateDiscoveryService(channelID string) (fab.DiscoveryService, error) {\n\treturn action, nil\n}\n\n// GetPeers returns the peers in context.\n// This is an implementation of the DiscoveryService interface\nfunc (action *Action) GetPeers() ([]fab.Peer, error) {\n\treturn action.Peers(), nil\n}\n\nfunc containsString(sarr []string, s string) bool {\n\tfor _, str := range sarr {\n\t\tif s == str {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// cryptoSuiteProviderFactory will provide custom cryptosuite (bccsp.BCCSP)\ntype cryptoSuiteProviderFactory struct {\n\tdefcore.ProviderFactory\n}\n\n// CreateCryptoSuiteProvider returns a new default implementation of BCCSP\nfunc (f *cryptoSuiteProviderFactory) CreateCryptoSuiteProvider(config core.CryptoSuiteConfig) (core.CryptoSuite, error) {\n\treturn cryptosuiteimpl.GetSuiteByConfig(config)\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/action/svcproviderfactory.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage action\n\nimport (\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/common/selection/dynamicselection\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/common/selection/fabricselection\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/common/selection/staticselection\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/options\"\n\tcontextApi \"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/factory/defsvc\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/provider/chpvdr\"\n\t\"github.com/pkg/errors\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n)\n\n// serviceProviderFactory is configured with either static or dynamic selection provider\ntype serviceProviderFactory struct {\n\tdefsvc.ProviderFactory\n}\n\nfunc newServiceProviderFactory() (*serviceProviderFactory, error) {\n\treturn &serviceProviderFactory{}, nil\n}\n\ntype fabricSelectionChannelProvider struct {\n\tfab.ChannelProvider\n\tservice   fab.ChannelService\n\tselection fab.SelectionService\n}\n\ntype fabricSelectionChannelService struct {\n\tfab.ChannelService\n\tselection fab.SelectionService\n}\n\n// CreateChannelProvider returns a new default implementation of channel provider\nfunc (f *serviceProviderFactory) CreateChannelProvider(config fab.EndpointConfig, opts ...options.Opt) (fab.ChannelProvider, error) {\n\tchProvider, err := chpvdr.New(config, opts...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &fabricSelectionChannelProvider{\n\t\tChannelProvider: chProvider,\n\t}, nil\n}\n\ntype closable interface {\n\tClose()\n}\n\n// Close frees resources and caches.\nfunc (cp *fabricSelectionChannelProvider) Close() {\n\tif c, ok := cp.ChannelProvider.(closable); ok {\n\t\tc.Close()\n\t}\n\tif cp.selection != nil {\n\t\tif c, ok := cp.selection.(closable); ok {\n\t\t\tc.Close()\n\t\t}\n\t}\n}\n\ntype providerInit interface {\n\tInitialize(providers contextApi.Providers) error\n}\n\nfunc (cp *fabricSelectionChannelProvider) Initialize(providers contextApi.Providers) error {\n\tif init, ok := cp.ChannelProvider.(providerInit); ok {\n\t\treturn init.Initialize(providers)\n\t}\n\treturn nil\n}\n\n// ChannelService creates a ChannelService for an identity\nfunc (cp *fabricSelectionChannelProvider) ChannelService(ctx fab.ClientContext, channelID string) (fab.ChannelService, error) {\n\tchService, err := cp.ChannelProvider.ChannelService(ctx, channelID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tdiscovery, err := chService.Discovery()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif cp.selection == nil {\n\t\tswitch cliconfig.Config().SelectionProvider() {\n\t\tcase cliconfig.StaticSelectionProvider:\n\t\t\tcliconfig.Config().Logger().Debugf(\"Using static selection provider.\")\n\t\t\tcp.selection, err = staticselection.NewService(discovery)\n\t\tcase cliconfig.DynamicSelectionProvider:\n\t\t\tcliconfig.Config().Logger().Debugf(\"Using dynamic selection provider.\")\n\t\t\tcp.selection, err = dynamicselection.NewService(ctx, channelID, discovery)\n\t\tcase cliconfig.FabricSelectionProvider:\n\t\t\tcliconfig.Config().Logger().Debugf(\"Using Fabric selection provider.\")\n\t\t\tcp.selection, err = fabricselection.New(ctx, channelID, discovery)\n\t\tdefault:\n\t\t\treturn nil, errors.Errorf(\"invalid selection provider: %s\", cliconfig.Config().SelectionProvider())\n\t\t}\n\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\treturn &fabricSelectionChannelService{\n\t\tChannelService: chService,\n\t\tselection:      cp.selection,\n\t}, nil\n}\n\nfunc (cs *fabricSelectionChannelService) Selection() (fab.SelectionService, error) {\n\treturn cs.selection, nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/chaincode/chaincodecmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage chaincode\n\nimport (\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar chaincodeCmd = &cobra.Command{\n\tUse:   \"chaincode\",\n\tShort: \"Chaincode commands\",\n\tLong:  \"Chaincode commands\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tcmd.HelpFunc()(cmd, args)\n\t},\n}\n\n// Cmd returns the chaincode command\nfunc Cmd() *cobra.Command {\n\tcliconfig.InitChannelID(chaincodeCmd.Flags())\n\n\tchaincodeCmd.AddCommand(getInstallCmd())\n\tchaincodeCmd.AddCommand(getInstantiateCmd())\n\tchaincodeCmd.AddCommand(getInvokeCmd())\n\tchaincodeCmd.AddCommand(getQueryCmd())\n\tchaincodeCmd.AddCommand(getGetInfoCmd())\n\tchaincodeCmd.AddCommand(getUpgradeCmd())\n\n\treturn chaincodeCmd\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/chaincode/getinfocmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage chaincode\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/golang/protobuf/proto\"\n\tpb \"github.com/hyperledger/fabric-protos-go/peer\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/channel\"\n\t\"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/core/common/ccprovider\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nconst (\n\tlifecycleSCC = \"lscc\"\n\n\tgetCCDataFunc     = \"getccdata\"\n\tgetCollConfigFunc = \"getcollectionsconfig\"\n)\n\nvar getInfoCmd = &cobra.Command{\n\tUse:   \"info\",\n\tShort: \"Get chaincode info\",\n\tLong:  \"Retrieves details about the chaincode\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tif cliconfig.Config().ChaincodeID() == \"\" {\n\t\t\tfmt.Printf(\"\\nMust specify the chaincode ID\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\t\taction, err := newGetInfoAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing getAction: %v\", err)\n\t\t\treturn\n\t\t}\n\n\t\tdefer action.Terminate()\n\n\t\terr = action.invoke()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running getAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getGetInfoCmd() *cobra.Command {\n\tflags := getInfoCmd.Flags()\n\tcliconfig.InitPeerURL(flags)\n\tcliconfig.InitChannelID(flags)\n\tcliconfig.InitChaincodeID(flags)\n\treturn getInfoCmd\n}\n\ntype getInfoAction struct {\n\taction.Action\n}\n\nfunc newGetInfoAction(flags *pflag.FlagSet) (*getInfoAction, error) {\n\taction := &getInfoAction{}\n\terr := action.Initialize(flags)\n\tif len(action.Peers()) == 0 {\n\t\treturn nil, errors.New(\"a peer must be specified\")\n\t}\n\treturn action, err\n}\n\nfunc (action *getInfoAction) invoke() error {\n\tchannelClient, err := action.ChannelClient()\n\tif err != nil {\n\t\treturn errors.Errorf(\"error retrieving channel client: %v\", err)\n\t}\n\n\tccData, err := action.getCCData(channelClient)\n\tif err != nil {\n\t\treturn errors.WithMessagef(err, \"error querying for chaincode data\")\n\t}\n\n\tcollConfig, err := action.getCollConfig(channelClient)\n\tif err != nil {\n\t\tif !strings.Contains(errors.Cause(err).Error(), \"collections config not defined for chaincode\") {\n\t\t\treturn errors.WithMessagef(err, \"error querying for collection config\")\n\t\t}\n\t}\n\n\taction.Printer().PrintChaincodeData(ccData, collConfig)\n\n\treturn nil\n}\n\nfunc (action *getInfoAction) getCCData(channelClient *channel.Client) (*ccprovider.ChaincodeData, error) {\n\tvar args [][]byte\n\targs = append(args, []byte(cliconfig.Config().ChannelID()))\n\targs = append(args, []byte(cliconfig.Config().ChaincodeID()))\n\n\tpeer := action.Peer()\n\tfmt.Printf(\"querying chaincode info for %s on peer: %s...\\n\", cliconfig.Config().ChaincodeID(), peer.URL())\n\n\tresponse, err := channelClient.Query(\n\t\tchannel.Request{ChaincodeID: lifecycleSCC, Fcn: getCCDataFunc, Args: args},\n\t\tchannel.WithTargetEndpoints(peer.URL()))\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error querying for chaincode info: %v\", err)\n\t}\n\n\tccData := &ccprovider.ChaincodeData{}\n\terr = proto.Unmarshal(response.Payload, ccData)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error unmarshalling chaincode data: %v\", err)\n\t}\n\treturn ccData, nil\n}\n\nfunc (action *getInfoAction) getCollConfig(channelClient *channel.Client) (*pb.CollectionConfigPackage, error) {\n\tvar args [][]byte\n\targs = append(args, []byte(cliconfig.Config().ChaincodeID()))\n\n\tpeer := action.Peer()\n\tfmt.Printf(\"querying collections config for %s on peer: %s...\\n\", cliconfig.Config().ChaincodeID(), peer.URL())\n\n\tresponse, err := channelClient.Query(\n\t\tchannel.Request{ChaincodeID: lifecycleSCC, Fcn: getCollConfigFunc, Args: args},\n\t\tchannel.WithTargetEndpoints(peer.URL()))\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error querying for collections config: %v\", err)\n\t}\n\n\tcollConfig := &pb.CollectionConfigPackage{}\n\terr = proto.Unmarshal(response.Payload, collConfig)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"error unmarshalling collections config: %v\", err)\n\t}\n\treturn collConfig, nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/chaincode/installcmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage chaincode\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/gopackager\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar installCmd = &cobra.Command{\n\tUse:   \"install\",\n\tShort: \"Install chaincode.\",\n\tLong:  \"Install chaincode\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tif cliconfig.Config().ChaincodeID() == \"\" {\n\t\t\tfmt.Printf(\"\\nMust specify the chaincode ID\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\t\tif cliconfig.Config().ChaincodePath() == \"\" {\n\t\t\tfmt.Printf(\"\\nMust specify the path of the chaincode\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\t\taction, err := newInstallAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing installAction: %v\", err)\n\t\t\treturn\n\t\t}\n\n\t\tdefer action.Terminate()\n\n\t\terr = action.invoke()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running installAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getInstallCmd() *cobra.Command {\n\tflags := installCmd.Flags()\n\tcliconfig.InitPeerURL(flags, \"\", \"The URL of the peer on which to install the chaincode, e.g. localhost:7051\")\n\tcliconfig.InitChannelID(flags)\n\tcliconfig.InitChaincodeID(flags)\n\tcliconfig.InitChaincodePath(flags)\n\tcliconfig.InitChaincodeVersion(flags)\n\tcliconfig.InitGoPath(flags)\n\treturn installCmd\n}\n\ntype installAction struct {\n\taction.Action\n}\n\nfunc newInstallAction(flags *pflag.FlagSet) (*installAction, error) {\n\taction := &installAction{}\n\terr := action.Initialize(flags)\n\treturn action, err\n}\n\nfunc (action *installAction) invoke() error {\n\tvar lastErr error\n\tfor orgID, peers := range action.PeersByOrg() {\n\t\tfmt.Printf(\"Installing chaincode %s on org[%s] peers:\\n\", cliconfig.Config().ChaincodeID(), orgID)\n\t\tfor _, peer := range peers {\n\t\t\tfmt.Printf(\"-- %s\\n\", peer.URL())\n\t\t}\n\t\terr := action.installChaincode(orgID, peers)\n\t\tif err != nil {\n\t\t\tlastErr = err\n\t\t}\n\t}\n\n\treturn lastErr\n}\n\nfunc (action *installAction) installChaincode(orgID string, targets []fab.Peer) error {\n\n\tresMgmtClient, err := action.ResourceMgmtClientForOrg(orgID)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tccPkg, err := gopackager.NewCCPackage(cliconfig.Config().ChaincodePath(), cliconfig.Config().GoPath())\n\tif err != nil {\n\t\treturn err\n\t}\n\treq := resmgmt.InstallCCRequest{\n\t\tName:    cliconfig.Config().ChaincodeID(),\n\t\tPath:    cliconfig.Config().ChaincodePath(),\n\t\tVersion: cliconfig.Config().ChaincodeVersion(),\n\t\tPackage: ccPkg,\n\t}\n\tresponses, err := resMgmtClient.InstallCC(req, resmgmt.WithTargets(targets...))\n\tif err != nil {\n\t\treturn errors.Errorf(\"InstallChaincode returned error: %v\", err)\n\t}\n\n\tccIDVersion := cliconfig.Config().ChaincodeID() + \".\" + cliconfig.Config().ChaincodeVersion()\n\n\tvar errs []error\n\tfor _, resp := range responses {\n\t\tif resp.Info == \"already installed\" {\n\t\t\tfmt.Printf(\"Chaincode %s already installed on peer: %s.\\n\", ccIDVersion, resp.Target)\n\t\t} else if resp.Status != http.StatusOK {\n\t\t\terrs = append(errs, errors.Errorf(\"installCC returned error from peer %s: %s\", resp.Target, resp.Info))\n\t\t} else {\n\t\t\tfmt.Printf(\"...successfuly installed chaincode %s on peer %s.\\n\", ccIDVersion, resp.Target)\n\t\t}\n\t}\n\n\tif len(errs) > 0 {\n\t\tcliconfig.Config().Logger().Warnf(\"Errors returned from InstallCC: %v\\n\", errs)\n\t\treturn errs[0]\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/chaincode/instantiatecmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage chaincode\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"strings\"\n\n\t\"github.com/hyperledger/fabric-protos-go/common\"\n\tpb \"github.com/hyperledger/fabric-protos-go/peer\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt\"\n\t\"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/cauthdsl\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/utils\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar instantiateCmd = &cobra.Command{\n\tUse:   \"instantiate\",\n\tShort: \"Instantiate chaincode.\",\n\tLong:  \"Instantiates the chaincode\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tif cliconfig.Config().ChaincodeID() == \"\" {\n\t\t\tfmt.Printf(\"\\nMust specify the chaincode ID\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\t\tif cliconfig.Config().ChaincodePath() == \"\" {\n\t\t\tfmt.Printf(\"\\nMust specify the path of the chaincode\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\t\taction, err := newInstantiateAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing instantiateAction: %v\", err)\n\t\t\treturn\n\t\t}\n\n\t\tdefer action.Terminate()\n\n\t\terr = action.invoke()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running instantiateAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getInstantiateCmd() *cobra.Command {\n\tflags := instantiateCmd.Flags()\n\tcliconfig.InitPeerURL(flags)\n\tcliconfig.InitChannelID(flags)\n\tcliconfig.InitChaincodeID(flags)\n\tcliconfig.InitChaincodePath(flags)\n\tcliconfig.InitChaincodeVersion(flags)\n\tcliconfig.InitArgs(flags)\n\tcliconfig.InitChaincodePolicy(flags)\n\tcliconfig.InitCollectionConfigFile(flags)\n\tcliconfig.InitTimeout(flags)\n\treturn instantiateCmd\n}\n\ntype instantiateAction struct {\n\taction.Action\n}\n\nfunc newInstantiateAction(flags *pflag.FlagSet) (*instantiateAction, error) {\n\taction := &instantiateAction{}\n\terr := action.Initialize(flags)\n\tif len(action.Peers()) == 0 {\n\t\treturn nil, errors.Errorf(\"a peer must be specified\")\n\t}\n\treturn action, err\n}\n\nfunc (a *instantiateAction) invoke() error {\n\ts := cliconfig.Config().Args()\n\targBytes := []byte(s)\n\targs := &action.ArgStruct{}\n\n\tif err := json.Unmarshal(argBytes, args); err != nil {\n\t\treturn errors.Errorf(\"Error unmarshalling JSON arg string: %v\", err)\n\t}\n\n\tresMgmtClient, err := a.ResourceMgmtClient()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcliconfig.Config().Logger().Infof(\"Sending instantiate %s ...\\n\", cliconfig.Config().ChaincodeID())\n\n\tchaincodePolicy, err := a.newChaincodePolicy()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Private Data Collection Configuration\n\t// - see fixtures/config/pvtdatacollection.json for sample config file\n\tvar collConfig []*pb.CollectionConfig\n\tcollConfigFile := cliconfig.Config().CollectionConfigFile()\n\tif collConfigFile != \"\" {\n\t\tcollConfig, err = getCollectionConfigFromFile(cliconfig.Config().CollectionConfigFile())\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"error getting private data collection configuration from file [%s]\", cliconfig.Config().CollectionConfigFile())\n\t\t}\n\t}\n\n\treq := resmgmt.InstantiateCCRequest{\n\t\tName:       cliconfig.Config().ChaincodeID(),\n\t\tPath:       cliconfig.Config().ChaincodePath(),\n\t\tVersion:    cliconfig.Config().ChaincodeVersion(),\n\t\tArgs:       utils.AsBytes(utils.NewContext(), args.Args),\n\t\tPolicy:     chaincodePolicy,\n\t\tCollConfig: collConfig,\n\t}\n\n\t_, err = resMgmtClient.InstantiateCC(cliconfig.Config().ChannelID(), req, resmgmt.WithTargets(a.Peer()))\n\tif err != nil {\n\t\tif strings.Contains(err.Error(), \"chaincode exists \"+cliconfig.Config().ChaincodeID()) {\n\t\t\t// Ignore\n\t\t\tcliconfig.Config().Logger().Infof(\"Chaincode %s already instantiated.\", cliconfig.Config().ChaincodeID())\n\t\t\tfmt.Printf(\"...chaincode %s already instantiated.\\n\", cliconfig.Config().ChaincodeID())\n\t\t\treturn nil\n\t\t}\n\t\treturn errors.Errorf(\"error instantiating chaincode: %v\", err)\n\t}\n\n\tfmt.Printf(\"...successfuly instantiated chaincode %s on channel %s.\\n\", cliconfig.Config().ChaincodeID(), cliconfig.Config().ChannelID())\n\n\treturn nil\n}\n\nfunc (a *instantiateAction) newChaincodePolicy() (*common.SignaturePolicyEnvelope, error) {\n\tif cliconfig.Config().ChaincodePolicy() != \"\" {\n\t\t// Create a signature policy from the policy expression passed in\n\t\treturn newChaincodePolicy(cliconfig.Config().ChaincodePolicy())\n\t}\n\n\t// Default policy is 'signed by any member' for all known orgs\n\treturn cauthdsl.AcceptAllPolicy, nil\n}\n\nfunc newChaincodePolicy(policyString string) (*common.SignaturePolicyEnvelope, error) {\n\tccPolicy, err := cauthdsl.FromString(policyString)\n\tif err != nil {\n\t\treturn nil, errors.Errorf(\"invalid chaincode policy [%s]: %s\", policyString, err)\n\t}\n\treturn ccPolicy, nil\n}\n\ntype collectionConfigJSON struct {\n\tName              string `json:\"name\"`\n\tPolicy            string `json:\"policy\"`\n\tRequiredPeerCount int32  `json:\"requiredPeerCount\"`\n\tMaxPeerCount      int32  `json:\"maxPeerCount\"`\n}\n\nfunc getCollectionConfigFromFile(ccFile string) ([]*pb.CollectionConfig, error) {\n\tfileBytes, err := ioutil.ReadFile(ccFile)\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"could not read file [%s]\", ccFile)\n\t}\n\tcconf := &[]collectionConfigJSON{}\n\tif err = json.Unmarshal(fileBytes, cconf); err != nil {\n\t\treturn nil, errors.Wrapf(err, \"error parsing collection configuration in file [%s]\", ccFile)\n\t}\n\treturn getCollectionConfig(*cconf)\n}\n\nfunc getCollectionConfig(cconf []collectionConfigJSON) ([]*pb.CollectionConfig, error) {\n\tccarray := make([]*pb.CollectionConfig, 0, len(cconf))\n\tfor _, cconfitem := range cconf {\n\t\tp, err := cauthdsl.FromString(cconfitem.Policy)\n\t\tif err != nil {\n\t\t\treturn nil, errors.WithMessage(err, fmt.Sprintf(\"invalid policy %s\", cconfitem.Policy))\n\t\t}\n\t\tcpc := &pb.CollectionPolicyConfig{\n\t\t\tPayload: &pb.CollectionPolicyConfig_SignaturePolicy{\n\t\t\t\tSignaturePolicy: p,\n\t\t\t},\n\t\t}\n\t\tcc := &pb.CollectionConfig{\n\t\t\tPayload: &pb.CollectionConfig_StaticCollectionConfig{\n\t\t\t\tStaticCollectionConfig: &pb.StaticCollectionConfig{\n\t\t\t\t\tName:              cconfitem.Name,\n\t\t\t\t\tMemberOrgsPolicy:  cpc,\n\t\t\t\t\tRequiredPeerCount: cconfitem.RequiredPeerCount,\n\t\t\t\t\tMaximumPeerCount:  cconfitem.MaxPeerCount,\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tccarray = append(ccarray, cc)\n\t}\n\treturn ccarray, nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/chaincode/invokecmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage chaincode\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/invoketask\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/multitask\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/task\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/utils\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/executor\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar invokeCmd = &cobra.Command{\n\tUse:   \"invoke\",\n\tShort: \"invoke chaincode.\",\n\tLong:  \"invoke chaincode\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tif cliconfig.Config().ChaincodeID() == \"\" {\n\t\t\tfmt.Printf(\"\\nMust specify the chaincode ID\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\t\taction, err := newInvokeAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing invokeAction: %v\", err)\n\t\t\treturn\n\t\t}\n\n\t\tdefer action.Terminate()\n\n\t\terr = action.invoke()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running invokeAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getInvokeCmd() *cobra.Command {\n\tflags := invokeCmd.Flags()\n\tcliconfig.InitPeerURL(flags)\n\tcliconfig.InitChannelID(flags)\n\tcliconfig.InitChaincodeID(flags)\n\tcliconfig.InitArgs(flags)\n\tcliconfig.InitIterations(flags)\n\tcliconfig.InitSleepTime(flags)\n\tcliconfig.InitTimeout(flags)\n\tcliconfig.InitPrintPayloadOnly(flags)\n\tcliconfig.InitConcurrency(flags)\n\tcliconfig.InitMaxAttempts(flags)\n\tcliconfig.InitInitialBackoff(flags)\n\tcliconfig.InitMaxBackoff(flags)\n\tcliconfig.InitBackoffFactor(flags)\n\tcliconfig.InitVerbosity(flags)\n\tcliconfig.InitSelectionProvider(flags)\n\treturn invokeCmd\n}\n\ntype invokeAction struct {\n\taction.Action\n\tnumInvoked uint32\n\tdone       chan bool\n}\n\nfunc newInvokeAction(flags *pflag.FlagSet) (*invokeAction, error) {\n\taction := &invokeAction{done: make(chan bool)}\n\terr := action.Initialize(flags)\n\treturn action, err\n}\n\nfunc (a *invokeAction) invoke() error {\n\tchannelClient, err := a.ChannelClient()\n\tif err != nil {\n\t\treturn errors.Errorf(\"Error getting channel client: %v\", err)\n\t}\n\n\targsArray, err := action.ArgsArray()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\texecutor := executor.NewConcurrent(\"Invoke Chaincode\", cliconfig.Config().Concurrency())\n\texecutor.Start()\n\tdefer executor.Stop(true)\n\n\tsuccess := 0\n\tvar errs []error\n\tvar successDurations []time.Duration\n\tvar failDurations []time.Duration\n\n\tvar targets []fab.Peer\n\tif len(cliconfig.Config().PeerURL()) > 0 || len(cliconfig.Config().OrgIDs()) > 0 {\n\t\ttargets = a.Peers()\n\t}\n\n\tvar wg sync.WaitGroup\n\tvar mutex sync.RWMutex\n\tvar tasks []task.Task\n\tvar taskID int\n\tfor i := 0; i < cliconfig.Config().Iterations(); i++ {\n\t\tctxt := utils.NewContext()\n\t\tmultiTask := multitask.New(wg.Done)\n\t\tfor _, args := range argsArray {\n\t\t\ttaskID++\n\t\t\tvar startTime time.Time\n\t\t\tcargs := args\n\t\t\ttask := invoketask.New(\n\t\t\t\tctxt,\n\t\t\t\tstrconv.Itoa(taskID), channelClient, targets,\n\t\t\t\tcliconfig.Config().ChaincodeID(),\n\t\t\t\t&cargs, executor,\n\t\t\t\tretry.Opts{\n\t\t\t\t\tAttempts:       cliconfig.Config().MaxAttempts(),\n\t\t\t\t\tInitialBackoff: cliconfig.Config().InitialBackoff(),\n\t\t\t\t\tMaxBackoff:     cliconfig.Config().MaxBackoff(),\n\t\t\t\t\tBackoffFactor:  cliconfig.Config().BackoffFactor(),\n\t\t\t\t\tRetryableCodes: retry.ChannelClientRetryableCodes,\n\t\t\t\t},\n\t\t\t\tcliconfig.Config().Verbose() || cliconfig.Config().Iterations() == 1,\n\t\t\t\tcliconfig.Config().PrintPayloadOnly(), a.Printer(),\n\n\t\t\t\tfunc() {\n\t\t\t\t\tstartTime = time.Now()\n\t\t\t\t},\n\t\t\t\tfunc(err error) {\n\t\t\t\t\tduration := time.Since(startTime)\n\t\t\t\t\tmutex.Lock()\n\t\t\t\t\tdefer mutex.Unlock()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrs = append(errs, err)\n\t\t\t\t\t\tfailDurations = append(failDurations, duration)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsuccess++\n\t\t\t\t\t\tsuccessDurations = append(successDurations, duration)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\tmultiTask.Add(task)\n\t\t}\n\t\ttasks = append(tasks, multiTask)\n\t}\n\n\twg.Add(len(tasks))\n\n\tnumInvocations := len(tasks) * len(argsArray)\n\n\tdone := make(chan bool)\n\tgo func() {\n\t\tticker := time.NewTicker(10 * time.Second)\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-ticker.C:\n\t\t\t\tmutex.RLock()\n\t\t\t\tif len(errs) > 0 {\n\t\t\t\t\tfmt.Printf(\"*** %d failed invocation(s) out of %d\\n\", len(errs), numInvocations)\n\t\t\t\t}\n\t\t\t\tfmt.Printf(\"*** %d successfull invocation(s) out of %d\\n\", success, numInvocations)\n\t\t\t\tmutex.RUnlock()\n\t\t\tcase <-done:\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\tstartTime := time.Now()\n\tsleepTime := time.Duration(cliconfig.Config().SleepTime()) * time.Millisecond\n\n\tfor _, task := range tasks {\n\t\tif err := executor.Submit(task); err != nil {\n\t\t\treturn errors.Errorf(\"error submitting task: %s\", err)\n\t\t}\n\t\tif sleepTime > 0 {\n\t\t\ttime.Sleep(sleepTime)\n\t\t}\n\t}\n\n\t// Wait for all tasks to complete\n\twg.Wait()\n\tdone <- true\n\n\tduration := time.Now().Sub(startTime)\n\n\tvar allErrs []error\n\tvar attempts int\n\tfor _, task := range tasks {\n\t\tattempts = attempts + task.Attempts()\n\t\tif task.LastError() != nil {\n\t\t\tallErrs = append(allErrs, task.LastError())\n\t\t}\n\t}\n\n\tif len(errs) > 0 {\n\t\tfmt.Printf(\"\\n*** %d errors invoking chaincode:\\n\", len(errs))\n\t\tfor _, err := range errs {\n\t\t\tfmt.Printf(\"%s\\n\", err)\n\t\t}\n\t} else if len(allErrs) > 0 {\n\t\tfmt.Printf(\"\\n*** %d transient errors invoking chaincode:\\n\", len(allErrs))\n\t\tfor _, err := range allErrs {\n\t\t\tfmt.Printf(\"%s\\n\", err)\n\t\t}\n\t}\n\n\tif numInvocations/len(argsArray) > 1 {\n\t\tfmt.Printf(\"\\n\")\n\t\tfmt.Printf(\"*** ---------- Summary: ----------\\n\")\n\t\tfmt.Printf(\"***   - Invocations:     %d\\n\", numInvocations)\n\t\tfmt.Printf(\"***   - Concurrency:     %d\\n\", cliconfig.Config().Concurrency())\n\t\tfmt.Printf(\"***   - Successfull:     %d\\n\", success)\n\t\tfmt.Printf(\"***   - Total attempts:  %d\\n\", attempts)\n\t\tfmt.Printf(\"***   - Duration:        %2.2fs\\n\", duration.Seconds())\n\t\tfmt.Printf(\"***   - Rate:            %2.2f/s\\n\", float64(numInvocations)/duration.Seconds())\n\t\tfmt.Printf(\"***   - Average:         %2.2fs\\n\", average(append(successDurations, failDurations...)))\n\t\tfmt.Printf(\"***   - Average Success: %2.2fs\\n\", average(successDurations))\n\t\tfmt.Printf(\"***   - Average Fail:    %2.2fs\\n\", average(failDurations))\n\t\tfmt.Printf(\"***   - Min Success:     %2.2fs\\n\", min(successDurations))\n\t\tfmt.Printf(\"***   - Max Success:     %2.2fs\\n\", max(successDurations))\n\t\tfmt.Printf(\"*** ------------------------------\\n\")\n\t}\n\n\treturn nil\n}\n\nfunc average(durations []time.Duration) float64 {\n\tif len(durations) == 0 {\n\t\treturn 0\n\t}\n\n\tvar total float64\n\tfor _, duration := range durations {\n\t\ttotal += duration.Seconds()\n\t}\n\treturn total / float64(len(durations))\n}\n\nfunc min(durations []time.Duration) float64 {\n\tmin, _ := minMax(durations)\n\treturn min\n}\n\nfunc max(durations []time.Duration) float64 {\n\t_, max := minMax(durations)\n\treturn max\n}\n\nfunc minMax(durations []time.Duration) (min float64, max float64) {\n\tfor _, duration := range durations {\n\t\tif min == 0 || min > duration.Seconds() {\n\t\t\tmin = duration.Seconds()\n\t\t}\n\t\tif max == 0 || max < duration.Seconds() {\n\t\t\tmax = duration.Seconds()\n\t\t}\n\t}\n\treturn\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/chaincode/invokeerror/invokeerror.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage invokeerror\n\nimport \"github.com/pkg/errors\"\n\ntype ErrorCode int\n\nconst (\n\t// PersistentError indicates that an unknown error occurred\n\t// and a retry of the request would NOT be successful\n\tPersistentError ErrorCode = iota\n\n\t// TransientError indicates that a transient error occurred\n\t// and a retry of the request could be successful\n\tTransientError\n\n\t// TimeoutOnCommit indicates that a timeout occurred while waiting\n\t// for a TxStatus event\n\tTimeoutOnCommit\n)\n\n// Error extends error with\n// additional context\ntype Error interface {\n\terror\n\n\t// Status returns the error code\n\tErrorCode() ErrorCode\n}\n\ntype invokeError struct {\n\terror\n\tcode ErrorCode\n}\n\n// New returns a new Error\nfunc New(code ErrorCode, msg string) Error {\n\treturn &invokeError{\n\t\terror: errors.New(msg),\n\t\tcode:  code,\n\t}\n}\n\n// Wrap returns a new Error\nfunc Wrap(code ErrorCode, cause error, msg string) Error {\n\treturn &invokeError{\n\t\terror: errors.Wrap(cause, msg),\n\t\tcode:  code,\n\t}\n}\n\n// Wrapf returns a new Error\nfunc Wrapf(code ErrorCode, cause error, fmt string, args ...interface{}) Error {\n\treturn &invokeError{\n\t\terror: errors.Wrapf(cause, fmt, args...),\n\t\tcode:  code,\n\t}\n}\n\n// Errorf returns a new Error\nfunc Errorf(code ErrorCode, fmt string, args ...interface{}) Error {\n\treturn &invokeError{\n\t\terror: errors.Errorf(fmt, args...),\n\t\tcode:  code,\n\t}\n}\n\n// ErrorCode returns the error code\nfunc (e *invokeError) ErrorCode() ErrorCode {\n\treturn e.code\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/chaincode/invoketask/invoketask.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage invoketask\n\nimport (\n\tpb \"github.com/hyperledger/fabric-protos-go/peer\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/channel\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/invokeerror\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/utils\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/executor\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/printer\"\n)\n\n// Task is a Task that invokes a chaincode\ntype Task struct {\n\tctxt          utils.Context\n\texecutor      *executor.Executor\n\tchannelClient *channel.Client\n\ttargets       []fab.Peer\n\tid            string\n\tccID          string\n\targs          *action.ArgStruct\n\tretryOpts     retry.Opts\n\tattempt       int\n\tlastErr       error\n\tstartedCB     func()\n\tcompletedCB   func(err error)\n\tverbose       bool\n\tprinter       printer.Printer\n\ttxID          string\n\tpayloadOnly   bool\n}\n\n// New returns a new Task\nfunc New(ctxt utils.Context, id string, channelClient *channel.Client, targets []fab.Peer, ccID string, args *action.ArgStruct,\n\texecutor *executor.Executor, retryOpts retry.Opts, verbose bool,\n\tpayloadOnly bool, p printer.Printer, startedCB func(), completedCB func(err error)) *Task {\n\treturn &Task{\n\t\tctxt:          ctxt,\n\t\tid:            id,\n\t\tchannelClient: channelClient,\n\t\ttargets:       targets,\n\t\tprinter:       p,\n\t\tccID:          ccID,\n\t\targs:          args,\n\t\texecutor:      executor,\n\t\tretryOpts:     retryOpts,\n\t\tstartedCB:     startedCB,\n\t\tcompletedCB:   completedCB,\n\t\tattempt:       1,\n\t\tverbose:       verbose,\n\t\tpayloadOnly:   payloadOnly,\n\t}\n}\n\n// Attempts returns the number of invocation attempts that were made\n// in order to achieve a successful response\nfunc (t *Task) Attempts() int {\n\treturn t.attempt\n}\n\n// LastError returns the last error that was recorder\nfunc (t *Task) LastError() error {\n\treturn t.lastErr\n}\n\n// Invoke invokes the task\nfunc (t *Task) Invoke() {\n\tt.startedCB()\n\tif err := t.doInvoke(); err != nil {\n\t\tt.lastErr = err\n\t\tt.completedCB(err)\n\t} else {\n\t\tcliconfig.Config().Logger().Debugf(\"(%s) - Successfully invoked chaincode\\n\", t.id)\n\t\tt.completedCB(nil)\n\t}\n}\n\nfunc (t *Task) doInvoke() error {\n\tcliconfig.Config().Logger().Debugf(\"(%s) - Invoking chaincode: %s, function: %s, args: %+v. Attempt #%d...\\n\",\n\t\tt.id, t.ccID, t.args.Func, t.args.Args, t.attempt)\n\n\tvar opts []channel.RequestOption\n\topts = append(opts, channel.WithRetry(t.retryOpts))\n\topts = append(opts, channel.WithBeforeRetry(func(err error) {\n\t\tt.attempt++\n\t}))\n\tif len(t.targets) > 0 {\n\t\topts = append(opts, channel.WithTargets(t.targets...))\n\t}\n\n\tresponse, err := t.channelClient.Execute(\n\t\tchannel.Request{\n\t\t\tChaincodeID: t.ccID,\n\t\t\tFcn:         t.args.Func,\n\t\t\tArgs:        utils.AsBytes(t.ctxt, t.args.Args),\n\t\t},\n\t\topts...,\n\t)\n\tif err != nil {\n\t\treturn invokeerror.Errorf(invokeerror.TransientError, \"SendTransactionProposal return error: %v\", err)\n\t}\n\n\tif t.verbose {\n\t\tt.printer.PrintTxProposalResponses(response.Responses, t.payloadOnly)\n\t}\n\n\tt.txID = string(response.TransactionID)\n\n\tswitch pb.TxValidationCode(response.TxValidationCode) {\n\tcase pb.TxValidationCode_VALID:\n\t\tcliconfig.Config().Logger().Debugf(\"(%s) - Successfully committed transaction [%s] ...\\n\", t.id, response.TransactionID)\n\t\treturn nil\n\tcase pb.TxValidationCode_DUPLICATE_TXID, pb.TxValidationCode_MVCC_READ_CONFLICT, pb.TxValidationCode_PHANTOM_READ_CONFLICT:\n\t\tcliconfig.Config().Logger().Debugf(\"(%s) - Transaction commit failed for [%s] with code [%s]. This is most likely a transient error.\\n\", t.id, response.TransactionID, response.TxValidationCode)\n\t\treturn invokeerror.Wrapf(invokeerror.TransientError, errors.New(\"Duplicate TxID\"), \"invoke Error received from eventhub for TxID [%s]. Code: %s\", response.TransactionID, response.TxValidationCode)\n\tdefault:\n\t\tcliconfig.Config().Logger().Debugf(\"(%s) - Transaction commit failed for [%s] with code [%s].\\n\", t.id, response.TransactionID, response.TxValidationCode)\n\t\treturn invokeerror.Wrapf(invokeerror.PersistentError, errors.New(\"error\"), \"invoke Error received from eventhub for TxID [%s]. Code: %s\", response.TransactionID, response.TxValidationCode)\n\t}\n\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/chaincode/multitask/multitask.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage multitask\n\nimport \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/task\"\n\n// MultiTask contains a set of Tasks to be invoked synchronously\ntype MultiTask struct {\n\ttasks       []task.Task\n\tcompletedCB func()\n}\n\n// New creates a new multi task\nfunc New(completedCB func()) *MultiTask {\n\treturn &MultiTask{\n\t\tcompletedCB: completedCB,\n\t}\n}\n\n// Add adds a task\nfunc (m *MultiTask) Add(task task.Task) {\n\tm.tasks = append(m.tasks, task)\n}\n\n// Invoke invokes the task\nfunc (m *MultiTask) Invoke() {\n\tdefer m.completedCB()\n\n\tfor _, task := range m.tasks {\n\t\ttask.Invoke()\n\t}\n}\n\n// Attempts returns the number of invocation attempts that were made\n// in order to achieve a successful response\nfunc (m *MultiTask) Attempts() int {\n\tvar attempts int\n\tfor _, t := range m.tasks {\n\t\tattempts += t.Attempts()\n\t}\n\treturn attempts\n}\n\n// LastError returns the last error that was recorder\nfunc (m *MultiTask) LastError() error {\n\tfor _, t := range m.tasks {\n\t\tif t.LastError() != nil {\n\t\t\treturn t.LastError()\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/chaincode/querycmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage chaincode\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/multitask\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/querytask\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/task\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/utils\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/executor\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar queryCmd = &cobra.Command{\n\tUse:   \"query\",\n\tShort: \"Query chaincode.\",\n\tLong:  \"Query chaincode\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tif cliconfig.Config().ChaincodeID() == \"\" {\n\t\t\tfmt.Printf(\"\\nMust specify the chaincode ID\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\t\taction, err := newQueryAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing queryAction: %v\", err)\n\t\t\treturn\n\t\t}\n\n\t\tdefer action.Terminate()\n\n\t\terr = action.query()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running queryAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getQueryCmd() *cobra.Command {\n\tflags := queryCmd.Flags()\n\tcliconfig.InitPeerURL(flags)\n\tcliconfig.InitChannelID(flags)\n\tcliconfig.InitChaincodeID(flags)\n\tcliconfig.InitArgs(flags)\n\tcliconfig.InitIterations(flags)\n\tcliconfig.InitSleepTime(flags)\n\tcliconfig.InitTimeout(flags)\n\tcliconfig.InitPrintPayloadOnly(flags)\n\tcliconfig.InitConcurrency(flags)\n\tcliconfig.InitVerbosity(flags)\n\tcliconfig.InitSelectionProvider(flags)\n\tcliconfig.InitValidate(flags)\n\treturn queryCmd\n}\n\ntype queryAction struct {\n\taction.Action\n\tnumInvoked uint32\n\tdone       chan bool\n}\n\nfunc newQueryAction(flags *pflag.FlagSet) (*queryAction, error) {\n\taction := &queryAction{done: make(chan bool)}\n\terr := action.Initialize(flags)\n\treturn action, err\n}\n\nfunc (a *queryAction) query() error {\n\tchannelClient, err := a.ChannelClient()\n\tif err != nil {\n\t\treturn errors.Errorf(\"Error getting channel client: %v\", err)\n\t}\n\n\targsArray, err := action.ArgsArray()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar targets []fab.Peer\n\tif len(cliconfig.Config().PeerURL()) > 0 || len(cliconfig.Config().OrgIDs()) > 0 {\n\t\ttargets = a.Peers()\n\t}\n\n\texecutor := executor.NewConcurrent(\"Query Chaincode\", cliconfig.Config().Concurrency())\n\texecutor.Start()\n\tdefer executor.Stop(true)\n\n\tverbose := cliconfig.Config().Verbose() || cliconfig.Config().Iterations() == 1\n\n\tvar mutex sync.RWMutex\n\tvar tasks []task.Task\n\tvar errs []error\n\tvar wg sync.WaitGroup\n\tvar taskID int\n\tvar success int\n\tvar successDurations []time.Duration\n\tvar failDurations []time.Duration\n\n\tfor i := 0; i < cliconfig.Config().Iterations(); i++ {\n\t\tctxt := utils.NewContext()\n\t\tmultiTask := multitask.New(wg.Done)\n\t\tfor _, args := range argsArray {\n\t\t\ttaskID++\n\t\t\tvar startTime time.Time\n\t\t\tcargs := args\n\t\t\ttask := querytask.New(\n\t\t\t\tctxt,\n\t\t\t\tstrconv.Itoa(taskID), channelClient, targets, &cargs, a.Printer(),\n\t\t\t\tretry.Opts{\n\t\t\t\t\tAttempts:       cliconfig.Config().MaxAttempts(),\n\t\t\t\t\tInitialBackoff: cliconfig.Config().InitialBackoff(),\n\t\t\t\t\tMaxBackoff:     cliconfig.Config().MaxBackoff(),\n\t\t\t\t\tBackoffFactor:  cliconfig.Config().BackoffFactor(),\n\t\t\t\t\tRetryableCodes: retry.ChannelClientRetryableCodes,\n\t\t\t\t},\n\t\t\t\tverbose,\n\t\t\t\tcliconfig.Config().PrintPayloadOnly(),\n\t\t\t\tcliconfig.Config().Validate(),\n\t\t\t\tfunc() {\n\t\t\t\t\tstartTime = time.Now()\n\t\t\t\t},\n\t\t\t\tfunc(err error) {\n\t\t\t\t\tduration := time.Since(startTime)\n\t\t\t\t\tmutex.Lock()\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\terrs = append(errs, err)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsuccess++\n\t\t\t\t\t\tsuccessDurations = append(successDurations, duration)\n\t\t\t\t\t}\n\t\t\t\t\tmutex.Unlock()\n\t\t\t\t})\n\t\t\tmultiTask.Add(task)\n\t\t}\n\t\ttasks = append(tasks, multiTask)\n\t}\n\n\twg.Add(len(tasks))\n\n\tnumInvocations := len(tasks) * len(argsArray)\n\n\tdone := make(chan bool)\n\tgo func() {\n\t\tticker := time.NewTicker(3 * time.Second)\n\t\tfor {\n\t\t\tselect {\n\t\t\tcase <-ticker.C:\n\t\t\t\tmutex.RLock()\n\t\t\t\tif len(errs) > 0 {\n\t\t\t\t\tfmt.Printf(\"*** %d failed query(s) out of %d\\n\", len(errs), numInvocations)\n\t\t\t\t}\n\t\t\t\tfmt.Printf(\"*** %d successfull query(s) out of %d\\n\", success, numInvocations)\n\t\t\t\tmutex.RUnlock()\n\t\t\tcase <-done:\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\n\tstartTime := time.Now()\n\tsleepTime := time.Duration(cliconfig.Config().SleepTime()) * time.Millisecond\n\n\tfor _, task := range tasks {\n\t\tif err := executor.Submit(task); err != nil {\n\t\t\treturn errors.Errorf(\"error submitting task: %s\", err)\n\t\t}\n\t\tif sleepTime > 0 {\n\t\t\ttime.Sleep(sleepTime)\n\t\t}\n\t}\n\n\t// Wait for all tasks to complete\n\twg.Wait()\n\tdone <- true\n\n\tduration := time.Now().Sub(startTime)\n\n\tvar allErrs []error\n\tvar attempts int\n\tfor _, task := range tasks {\n\t\tattempts = attempts + task.Attempts()\n\t\tif task.LastError() != nil {\n\t\t\tallErrs = append(allErrs, task.LastError())\n\t\t}\n\t}\n\n\tif len(errs) > 0 {\n\t\tfmt.Printf(\"\\n*** %d errors querying chaincode:\\n\", len(errs))\n\t\tfor _, err := range errs {\n\t\t\tfmt.Printf(\"%s\\n\", err)\n\t\t}\n\t} else if len(allErrs) > 0 {\n\t\tfmt.Printf(\"\\n*** %d transient errors querying chaincode:\\n\", len(allErrs))\n\t\tfor _, err := range allErrs {\n\t\t\tfmt.Printf(\"%s\\n\", err)\n\t\t}\n\t}\n\n\tif numInvocations/len(argsArray) > 1 {\n\t\tfmt.Printf(\"\\n\")\n\t\tfmt.Printf(\"*** ---------- Summary: ----------\\n\")\n\t\tfmt.Printf(\"***   - Queries:         %d\\n\", numInvocations)\n\t\tfmt.Printf(\"***   - Concurrency:     %d\\n\", cliconfig.Config().Concurrency())\n\t\tfmt.Printf(\"***   - Successfull:     %d\\n\", success)\n\t\tfmt.Printf(\"***   - Total attempts:  %d\\n\", attempts)\n\t\tfmt.Printf(\"***   - Duration:        %2.2fs\\n\", duration.Seconds())\n\t\tfmt.Printf(\"***   - Rate:            %2.2f/s\\n\", float64(numInvocations)/duration.Seconds())\n\t\tfmt.Printf(\"***   - Average:         %2.2fs\\n\", average(append(successDurations, failDurations...)))\n\t\tfmt.Printf(\"***   - Average Success: %2.2fs\\n\", average(successDurations))\n\t\tfmt.Printf(\"***   - Average Fail:    %2.2fs\\n\", average(failDurations))\n\t\tfmt.Printf(\"***   - Min Success:     %2.2fs\\n\", min(successDurations))\n\t\tfmt.Printf(\"***   - Max Success:     %2.2fs\\n\", max(successDurations))\n\t\tfmt.Printf(\"*** ------------------------------\\n\")\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/chaincode/querytask/querytask.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage querytask\n\nimport (\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/channel\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/channel/invoke\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/utils\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/printer\"\n)\n\n// Task is the query task\ntype Task struct {\n\tctxt          utils.Context\n\tchannelClient *channel.Client\n\ttargets       []fab.Peer\n\tretryOpts     retry.Opts\n\tid            string\n\targs          *action.ArgStruct\n\tstartedCB     func()\n\tcompletedCB   func(err error)\n\tprinter       printer.Printer\n\tverbose       bool\n\tpayloadOnly   bool\n\tvalidate      bool\n\tattempt       int\n\tlastErr       error\n}\n\n// New creates a new query Task\nfunc New(ctxt utils.Context, id string, channelClient *channel.Client, targets []fab.Peer, args *action.ArgStruct, printer printer.Printer,\n\tretryOpts retry.Opts, verbose bool, payloadOnly bool, validate bool, startedCB func(), completedCB func(err error)) *Task {\n\treturn &Task{\n\t\tctxt:          ctxt,\n\t\tid:            id,\n\t\tchannelClient: channelClient,\n\t\ttargets:       targets,\n\t\tretryOpts:     retryOpts,\n\t\targs:          args,\n\t\tstartedCB:     startedCB,\n\t\tcompletedCB:   completedCB,\n\t\tattempt:       1,\n\t\tprinter:       printer,\n\t\tverbose:       verbose,\n\t\tpayloadOnly:   payloadOnly,\n\t\tvalidate:      validate,\n\t}\n}\n\n// Invoke invokes the query task\nfunc (t *Task) Invoke() {\n\tt.startedCB()\n\n\tvar opts []channel.RequestOption\n\topts = append(opts, channel.WithRetry(t.retryOpts))\n\topts = append(opts, channel.WithBeforeRetry(func(err error) {\n\t\tt.attempt++\n\t}))\n\tif len(t.targets) > 0 {\n\t\topts = append(opts, channel.WithTargets(t.targets...))\n\t}\n\n\trequest := channel.Request{\n\t\tChaincodeID: cliconfig.Config().ChaincodeID(),\n\t\tFcn:         t.args.Func,\n\t\tArgs:        utils.AsBytes(t.ctxt, t.args.Args),\n\t}\n\n\tvar additionalHandlers []invoke.Handler\n\tif t.validate {\n\t\t// Add the validation handlers\n\t\tadditionalHandlers = append(additionalHandlers,\n\t\t\tinvoke.NewEndorsementValidationHandler(\n\t\t\t\tinvoke.NewSignatureValidationHandler(),\n\t\t\t),\n\t\t)\n\t}\n\n\tresponse, err := t.channelClient.InvokeHandler(\n\t\tinvoke.NewProposalProcessorHandler(\n\t\t\tinvoke.NewEndorsementHandler(additionalHandlers...),\n\t\t),\n\t\trequest, opts...)\n\tif err != nil {\n\t\tcliconfig.Config().Logger().Debugf(\"(%s) - Error querying chaincode: %s\\n\", t.id, err)\n\t\tt.lastErr = err\n\t\tt.completedCB(err)\n\t} else {\n\t\tcliconfig.Config().Logger().Debugf(\"(%s) - Chaincode query was successful\\n\", t.id)\n\n\t\tif t.verbose {\n\t\t\tt.printer.PrintTxProposalResponses(response.Responses, t.payloadOnly)\n\t\t}\n\n\t\tt.completedCB(nil)\n\t}\n}\n\n// Attempts returns the number of invocation attempts that were made\n// in order to achieve a successful response\nfunc (t *Task) Attempts() int {\n\treturn t.attempt\n}\n\n// LastError returns the last error that was recorder\nfunc (t *Task) LastError() error {\n\treturn t.lastErr\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/chaincode/task/task.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage task\n\n// Task is an invocable unit of work\ntype Task interface {\n\t// Invoke invokes the task\n\tInvoke()\n\n\t// Attempts returns the number of invocation attempts that were made\n\t// in order to achieve a successful response\n\tAttempts() int\n\n\t// LastError returns the last error that occurred\n\tLastError() error\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/chaincode/upgradecmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage chaincode\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\n\tfabricCommon \"github.com/hyperledger/fabric-protos-go/common\"\n\tpb \"github.com/hyperledger/fabric-protos-go/peer\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt\"\n\t\"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/cauthdsl\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/utils\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar upgradeCmd = &cobra.Command{\n\tUse:   \"upgrade\",\n\tShort: \"Upgrade chaincode.\",\n\tLong:  \"Upgrades the chaincode\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tif cliconfig.Config().ChaincodeID() == \"\" {\n\t\t\tfmt.Printf(\"\\nMust specify the chaincode ID\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\t\tif cliconfig.Config().ChaincodePath() == \"\" {\n\t\t\tfmt.Printf(\"\\nMust specify the path of the chaincode\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\t\taction, err := newUpgradeAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing upgradeAction: %v\", err)\n\t\t\treturn\n\t\t}\n\n\t\tdefer action.Terminate()\n\n\t\terr = action.invoke()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running upgradeAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getUpgradeCmd() *cobra.Command {\n\tflags := upgradeCmd.Flags()\n\tcliconfig.InitPeerURL(flags)\n\tcliconfig.InitChannelID(flags)\n\tcliconfig.InitChaincodeID(flags)\n\tcliconfig.InitChaincodePath(flags)\n\tcliconfig.InitChaincodeVersion(flags)\n\tcliconfig.InitArgs(flags)\n\tcliconfig.InitChaincodePolicy(flags)\n\tcliconfig.InitCollectionConfigFile(flags)\n\tcliconfig.InitTimeout(flags)\n\treturn upgradeCmd\n}\n\ntype upgradeAction struct {\n\taction.Action\n}\n\nfunc newUpgradeAction(flags *pflag.FlagSet) (*upgradeAction, error) {\n\taction := &upgradeAction{}\n\terr := action.Initialize(flags)\n\tif len(action.Peers()) == 0 {\n\t\treturn nil, errors.Errorf(\"a peer must be specified\")\n\t}\n\treturn action, err\n}\n\nfunc (a *upgradeAction) invoke() error {\n\targBytes := []byte(cliconfig.Config().Args())\n\targs := &action.ArgStruct{}\n\n\tif err := json.Unmarshal(argBytes, args); err != nil {\n\t\treturn errors.Errorf(\"Error unmarshalling JSON arg string: %v\", err)\n\t}\n\n\tresMgmtClient, err := a.ResourceMgmtClient()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tcliconfig.Config().Logger().Infof(\"Sending upgrade %s ...\\n\", cliconfig.Config().ChaincodeID())\n\n\tchaincodePolicy, err := a.newChaincodePolicy()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// Private Data Collection Configuration\n\t// - see fixtures/config/pvtdatacollection.json for sample config file\n\tvar collConfig []*pb.CollectionConfig\n\tcollConfigFile := cliconfig.Config().CollectionConfigFile()\n\tif collConfigFile != \"\" {\n\t\tcollConfig, err = getCollectionConfigFromFile(cliconfig.Config().CollectionConfigFile())\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"error getting private data collection configuration from file [%s]\", cliconfig.Config().CollectionConfigFile())\n\t\t}\n\t}\n\n\treq := resmgmt.UpgradeCCRequest{\n\t\tName:       cliconfig.Config().ChaincodeID(),\n\t\tPath:       cliconfig.Config().ChaincodePath(),\n\t\tVersion:    cliconfig.Config().ChaincodeVersion(),\n\t\tArgs:       utils.AsBytes(utils.NewContext(), args.Args),\n\t\tPolicy:     chaincodePolicy,\n\t\tCollConfig: collConfig,\n\t}\n\n\t_, err = resMgmtClient.UpgradeCC(cliconfig.Config().ChannelID(), req, resmgmt.WithTargets(a.Peers()...))\n\tif err != nil {\n\t\tif strings.Contains(err.Error(), \"chaincode exists \"+cliconfig.Config().ChaincodeID()) {\n\t\t\t// Ignore\n\t\t\tcliconfig.Config().Logger().Infof(\"Chaincode %s already instantiated.\", cliconfig.Config().ChaincodeID())\n\t\t\tfmt.Printf(\"...chaincode %s already instantiated.\\n\", cliconfig.Config().ChaincodeID())\n\t\t\treturn nil\n\t\t}\n\t\treturn errors.Errorf(\"error instantiating chaincode: %v\", err)\n\t}\n\n\tfmt.Printf(\"...successfuly upgraded chaincode %s on channel %s.\\n\", cliconfig.Config().ChaincodeID(), cliconfig.Config().ChannelID())\n\n\treturn nil\n}\n\nfunc (a *upgradeAction) newChaincodePolicy() (*fabricCommon.SignaturePolicyEnvelope, error) {\n\tif cliconfig.Config().ChaincodePolicy() != \"\" {\n\t\t// Create a signature policy from the policy expression passed in\n\t\treturn newChaincodePolicy(cliconfig.Config().ChaincodePolicy())\n\t}\n\n\t// Default policy is 'signed my any member' for all known orgs\n\tvar mspIDs []string\n\tfor _, orgID := range cliconfig.Config().OrgIDs() {\n\t\torgConfig, ok := a.EndpointConfig().NetworkConfig().Organizations[orgID]\n\t\tif !ok {\n\t\t\treturn nil, errors.Errorf(\"Unable to get the MSP ID from org ID %s\", orgID)\n\t\t}\n\t\tmspIDs = append(mspIDs, orgConfig.MSPID)\n\t}\n\treturn cauthdsl.SignedByAnyMember(mspIDs), nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/chaincode/utils/test.json",
    "content": "{\"Field1\": \"Value1\"}"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/chaincode/utils/util.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage utils\n\nimport (\n\t\"fmt\"\n\t\"github.com/pkg/errors\"\n\t\"io/ioutil\"\n\t\"math/rand\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync/atomic\"\n\t\"time\"\n\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n)\n\nconst (\n\trandFunc = \"$rand(\"\n\tpadFunc  = \"$pad(\"\n\tseqFunc  = \"$seq(\"\n\tsetFunc  = \"$set(\"\n\tfileFunc = \"$file(\"\n\tvarExp   = \"${\"\n)\n\nvar (\n\tsequence uint64\n)\n\ntype Context interface {\n\tSetVar(name, value string)\n\tGetVar(name string) (string, bool)\n}\n\n// AsBytes converts the string array to an array of byte arrays.\n// The args may contain functions $rand(n) or $pad(n,chars).\n// The functions are evaluated before returning.\n//\n// Examples:\n// - \"key$rand(3)\" -> \"key0\" or \"key1\" or \"key2\"\n// - \"val$pad(3,XYZ) -> \"valXYZXYZXYZ\"\n// - \"val$pad($rand(3),XYZ) -> \"val\" or \"valXYZ\" or \"valXYZXYZ\"\n// - \"key$seq()\" -> \"key1\", \"key2\", \"key2\", ...\n// - \"val$pad($seq(),X)\" -> \"valX\", \"valXX\", \"valXX\", \"valXXX\", ...\n// - \"Key_$set(x,$seq())=Val_${x}\" -> Key_1=Val_1, Key_2=Val_2, ...\nfunc AsBytes(ctxt Context, args []string) [][]byte {\n\trand := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))\n\tbytes := make([][]byte, len(args))\n\n\tif cliconfig.Config().Verbose() {\n\t\tfmt.Printf(\"Args:\\n\")\n\t}\n\tfor i, a := range args {\n\t\targ := getArg(ctxt, rand, a)\n\t\tif cliconfig.Config().Verbose() {\n\t\t\tfmt.Printf(\"- [%d]=%s\\n\", i, arg)\n\t\t}\n\t\tbytes[i] = []byte(arg)\n\t}\n\treturn bytes\n}\n\nfunc getArg(ctxt Context, r *rand.Rand, arg string) string {\n\targ = evaluateSeqExpression(arg)\n\targ = evaluateRandExpression(r, arg)\n\targ = evaluatePadExpression(arg)\n\targ = evaluateFileExpression(arg)\n\targ = evaluateSetExpression(ctxt, arg)\n\targ = evaluateVarExpression(ctxt, arg)\n\treturn arg\n}\n\n// evaluateSeqExpression replaces occurrences of $seq() with a sequential\n// number starting at 1 and incrementing for each task\nfunc evaluateSeqExpression(arg string) string {\n\treturn evaluateExpression(arg, seqFunc, \")\",\n\t\tfunc(expression string) (string, error) {\n\t\t\treturn strconv.FormatUint(atomic.AddUint64(&sequence, 1), 10), nil\n\t\t})\n}\n\n// evaluateRandExpression replaces occurrences of $rand(n) with a random\n// number between 0 and n (exclusive)\nfunc evaluateRandExpression(r *rand.Rand, arg string) string {\n\treturn evaluateExpression(arg, randFunc, \")\",\n\t\tfunc(expression string) (string, error) {\n\t\t\tn, err := strconv.ParseInt(expression, 10, 64)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", errors.Errorf(\"invalid number %s in $rand expression\\n\", expression)\n\t\t\t}\n\t\t\treturn strconv.FormatInt(r.Int63n(n), 10), nil\n\t\t})\n}\n\n// evaluatePadExpression replaces occurrences of $pad(n,chars) with n of the given pad characters\nfunc evaluatePadExpression(arg string) string {\n\treturn evaluateExpression(arg, padFunc, \")\",\n\t\tfunc(expression string) (string, error) {\n\t\t\ts := strings.Split(expression, \",\")\n\t\t\tif len(s) != 2 {\n\t\t\t\treturn \"\", errors.Errorf(\"invalid $pad expression: '%s'. Expecting $pad(n,chars)\", expression)\n\t\t\t}\n\n\t\t\tn, err := strconv.Atoi(s[0])\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", errors.Errorf(\"invalid number %s in $pad expression\\n\", s[0])\n\t\t\t}\n\n\t\t\tresult := \"\"\n\t\t\tfor i := 0; i < n; i++ {\n\t\t\t\tresult += s[1]\n\t\t\t}\n\n\t\t\treturn result, nil\n\t\t})\n}\n\n// evaluateFileExpression replaces occurrences of $file(path) with the contents of the file\nfunc evaluateFileExpression(arg string) string {\n\treturn evaluateExpression(arg, fileFunc, \")\",\n\t\tfunc(expression string) (string, error) {\n\t\t\treturn readFile(expression)\n\t\t})\n}\n\n// evaluateSetExpression sets a variable to the given value using the syntax $set(var,expression).\n// The variable may be used in a subsequent expression, ${var}.\n// Example: $set(v,$rand(10)) sets variable \"v\" to a random value that may be accessed as ${v}\nfunc evaluateSetExpression(ctxt Context, arg string) string {\n\treturn evaluateExpression(arg, setFunc, \")\",\n\t\tfunc(expression string) (string, error) {\n\t\t\ts := strings.Split(expression, \",\")\n\t\t\tif len(s) != 2 {\n\t\t\t\treturn \"\", errors.Errorf(\"invalid $set expression: '%s'. Expecting $set(var,value)\", expression)\n\t\t\t}\n\n\t\t\tvariable := s[0]\n\t\t\tvalue := s[1]\n\n\t\t\tctxt.SetVar(variable, value)\n\t\t\treturn value, nil\n\t\t})\n}\n\n// evaluateVarExpression references a variable previously set with the $set(var,expression) expression.\n// Example: ${someVar}\nfunc evaluateVarExpression(ctxt Context, arg string) string {\n\treturn evaluateExpression(arg, varExp, \"}\",\n\t\tfunc(varName string) (string, error) {\n\t\t\tvalue, ok := ctxt.GetVar(varName)\n\t\t\tif !ok {\n\t\t\t\treturn \"\", errors.Errorf(\"variable [%s] not set\", varName)\n\t\t\t}\n\t\t\treturn value, nil\n\t\t})\n}\n\nfunc evaluateExpression(expression, funcType, endDelim string, evaluate func(string) (string, error)) string {\n\tresult := \"\"\n\tfor {\n\t\ti := strings.Index(expression, funcType)\n\t\tif i == -1 {\n\t\t\tresult += expression\n\t\t\tbreak\n\t\t}\n\n\t\tj := strings.Index(expression[i:], endDelim)\n\t\tif j == -1 {\n\t\t\tfmt.Printf(\"expecting '%s' in expression '%s'\", endDelim, expression)\n\t\t\tresult = expression\n\t\t\tbreak\n\t\t}\n\n\t\tj = i + j\n\n\t\treplacement, err := evaluate(expression[i+len(funcType) : j])\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"%s\\n\", err)\n\t\t\tresult += expression[0 : j+1]\n\t\t} else {\n\t\t\tresult += expression[0:i] + replacement\n\t\t}\n\n\t\texpression = expression[j+1:]\n\t}\n\n\treturn result\n}\n\nfunc NewContext() Context {\n\treturn &defaultContext{\n\t\tvars: make(map[string]string),\n\t}\n}\n\ntype defaultContext struct {\n\tvars map[string]string\n}\n\nfunc (c *defaultContext) SetVar(k, v string) {\n\tc.vars[k] = v\n}\n\nfunc (c *defaultContext) GetVar(k string) (string, bool) {\n\tvalue, ok := c.vars[k]\n\treturn value, ok\n}\n\nfunc readFile(filePath string) (string, error) {\n\tfmt.Printf(\"Reading file: [%s]\", filePath)\n\tfile, err := os.Open(filepath.Clean(filePath))\n\tif err != nil {\n\t\treturn \"\", errors.Wrapf(err, \"error opening file [%s]\", filePath)\n\t}\n\tdefer func() {\n\t\tfileErr := file.Close()\n\t\tif fileErr != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Failed to close file : %s\", fileErr)\n\t\t}\n\t}()\n\n\tconfigBytes, err := ioutil.ReadAll(file)\n\tif err != nil {\n\t\treturn \"\", errors.Wrapf(err, \"error reading config file [%s]\", filePath)\n\t}\n\treturn string(configBytes), nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/chaincode/utils/util_test.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage utils\n\nimport (\n\t\"fmt\"\n\t\"github.com/stretchr/testify/assert\"\n\t\"math/rand\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestEvaluatePadExpression(t *testing.T) {\n\tresult := evaluatePadExpression(\"Value_$pad(3,XYZ)!\")\n\tassert.Equal(t, \"Value_XYZXYZXYZ!\", result)\n\n\tresult = evaluatePadExpression(\"Value_$pad(3,XYZ)_$pad(2,123)!\")\n\tassert.Equal(t, \"Value_XYZXYZXYZ_123123!\", result)\n}\n\nfunc TestFailEvaluatePadExpression(t *testing.T) {\n\tresult := evaluatePadExpression(\"Value_$pad(3,XYZ!\")\n\tassert.Equal(t, \"Value_$pad(3,XYZ!\", result)\n\n\tresult = evaluatePadExpression(\"Value_$pad3,XYZ)!\")\n\tassert.Equal(t, \"Value_$pad3,XYZ)!\", result)\n\n\tresult = evaluatePadExpression(\"Value_$pad(3)!\")\n\tassert.Equal(t, \"Value_$pad(3)!\", result)\n\n\tresult = evaluatePadExpression(\"Value_$pad(3)_$pad(3,X)!\")\n\tassert.Equal(t, \"Value_$pad(3)_XXX!\", result)\n}\n\nfunc TestEvaluateRandExpression(t *testing.T) {\n\trand := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))\n\tfor i := 0; i < 5; i++ {\n\t\tresult := evaluateRandExpression(rand, \"Value_$rand(2)!\")\n\t\tassert.True(t, result == \"Value_0!\" || result == \"Value_1!\")\n\n\t\tresult = evaluateRandExpression(rand, \"Value_$rand(2)_$rand(1)!\")\n\t\tassert.True(t, result == \"Value_0_0!\" || result == \"Value_1_0!\")\n\t}\n}\n\nfunc TestFailEvaluateRandExpression(t *testing.T) {\n\trand := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))\n\tresult := evaluateRandExpression(rand, \"Value_$rand(3,!\")\n\tassert.Equal(t, \"Value_$rand(3,!\", result)\n\n\tresult = evaluateRandExpression(rand, \"Value_$rand3)!\")\n\tassert.Equal(t, \"Value_$rand3)!\", result)\n\n\tresult = evaluateRandExpression(rand, \"Value_$rand(X)!\")\n\tassert.Equal(t, \"Value_$rand(X)!\", result)\n\n\tresult = evaluateRandExpression(rand, \"Value_$rand(X)_$rand(1)!\")\n\tassert.Equal(t, \"Value_$rand(X)_0!\", result)\n}\n\nfunc TestEvaluateSeqExpression(t *testing.T) {\n\tassert.Equal(t, \"Value_1!\", evaluateSeqExpression(\"Value_$seq()!\"))\n\tassert.Equal(t, \"Value_2!\", evaluateSeqExpression(\"Value_$seq()!\"))\n\tassert.Equal(t, \"Value_3!\", evaluateSeqExpression(\"Value_$seq()!\"))\n}\n\nfunc TestFailEvaluateSeqExpression(t *testing.T) {\n\tassert.Equal(t, \"Value_$seq(!\", evaluateSeqExpression(\"Value_$seq(!\"))\n}\n\nfunc TestEvaluateFileExpression(t *testing.T) {\n\tassert.Equal(t, `{\"Field1\": \"Value1\"}`, evaluateFileExpression(\"$file(./test.json)\"))\n}\n\nfunc TestFailEvaluateFileExpression(t *testing.T) {\n\tassert.Equal(t, \"$file(./invalid.json)\", evaluateSeqExpression(\"$file(./invalid.json)\"))\n}\n\nfunc TestEvaluateSetExpression(t *testing.T) {\n\tctxt := NewContext()\n\tassert.Equal(t, \"Value_1000!\", evaluateSetExpression(ctxt, \"Value_$set(x,1000)!\"))\n\tassert.Equal(t, \"Value_1000!\", evaluateVarExpression(ctxt, \"Value_${x}!\"))\n}\n\nfunc TestFailEvaluateSetExpression(t *testing.T) {\n\tctxt := NewContext()\n\tassert.Equal(t, \"Value_$set(x,1000\", evaluateSetExpression(ctxt, \"Value_$set(x,1000\"))\n\tassert.Equal(t, \"Value_${x\", evaluateVarExpression(ctxt, \"Value_${x\"))\n\n\t// Var not set\n\tassert.Equal(t, \"Value_${x}\", evaluateVarExpression(NewContext(), \"Value_${x}\"))\n}\n\nfunc TestGetArg(t *testing.T) {\n\trand := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))\n\tresult := getArg(NewContext(), rand, \"Value_$pad(3,X)!\")\n\tassert.Equal(t, \"Value_XXX!\", result)\n\n\tfor i := 0; i < 5; i++ {\n\t\tresult := getArg(NewContext(), rand, \"Value_$rand(2)!\")\n\t\tassert.True(t, result == \"Value_0!\" || result == \"Value_1!\")\n\t}\n\n\tfor i := 0; i < 5; i++ {\n\t\tresult := getArg(NewContext(), rand, \"Value_$pad(3,X)_$rand(2)!\")\n\t\tassert.True(t, result == \"Value_XXX_0!\" || result == \"Value_XXX_1!\")\n\t}\n\n\tfor i := 0; i < 5; i++ {\n\t\tresult := getArg(NewContext(), rand, \"Value_$pad($rand(3),X)!\")\n\t\tassert.True(t, result == \"Value_!\" || result == \"Value_X!\" || result == \"Value_XX!\")\n\t}\n\n\tn := sequence + 1\n\tfor i := n; i <= n+5; i++ {\n\t\tresult := getArg(NewContext(), rand, \"Value_$seq()!\")\n\t\tassert.True(t, result == fmt.Sprintf(\"Value_%d!\", i))\n\t}\n\n\tn = sequence + 1\n\tfor i := n; i <= n+5; i++ {\n\t\tctxt := NewContext()\n\t\tassert.Equal(t, fmt.Sprintf(\"Key_%d=Val_%d\", i, i), getArg(ctxt, rand, \"Key_$set(x,$seq())=Val_${x}\"))\n\t\tassert.Equal(t, fmt.Sprintf(\"Value_%d!\", i), getArg(ctxt, rand, \"Value_${x}!\"))\n\t}\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/channel/channelcmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage channel\n\nimport (\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar channelCmd = &cobra.Command{\n\tUse:   \"channel\",\n\tShort: \"Channel commands\",\n\tLong:  \"Channel commands\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tcmd.HelpFunc()(cmd, args)\n\t},\n}\n\n// Cmd returns the channel command\nfunc Cmd() *cobra.Command {\n\tcliconfig.InitChannelID(channelCmd.Flags())\n\n\tchannelCmd.AddCommand(getChannelCreateCmd())\n\tchannelCmd.AddCommand(getChannelJoinCmd())\n\n\treturn channelCmd\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/channel/channelcreatecmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage channel\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar channelCreateCmd = &cobra.Command{\n\tUse:   \"create\",\n\tShort: \"Create Channel\",\n\tLong:  \"Create a new channel\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\taction, err := newChannelCreateAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing channelCreateAction: %v\", err)\n\t\t\treturn\n\t\t}\n\n\t\tdefer action.Terminate()\n\n\t\terr = action.invoke()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running channelCreateAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getChannelCreateCmd() *cobra.Command {\n\tflags := channelCreateCmd.Flags()\n\tcliconfig.InitChannelID(flags)\n\tcliconfig.InitOrdererURL(flags)\n\tcliconfig.InitTxFile(flags)\n\treturn channelCreateCmd\n}\n\ntype channelCreateAction struct {\n\taction.Action\n}\n\nfunc newChannelCreateAction(flags *pflag.FlagSet) (*channelCreateAction, error) {\n\ta := &channelCreateAction{}\n\terr := a.Initialize(flags)\n\treturn a, err\n}\n\nfunc (a *channelCreateAction) invoke() error {\n\tuser, err := a.OrgAdminUser(a.OrgID())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tchMgmtClient, err := a.ResourceMgmtClient()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Printf(\"Attempting to create/update channel: %s\\n\", cliconfig.Config().ChannelID())\n\n\treq := resmgmt.SaveChannelRequest{\n\t\tChannelID:         cliconfig.Config().ChannelID(),\n\t\tChannelConfigPath: cliconfig.Config().TxFile(),\n\t\tSigningIdentities: []msp.SigningIdentity{user},\n\t}\n\n\torderer, err := a.RandomOrderer()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t_, err = chMgmtClient.SaveChannel(req, resmgmt.WithOrderer(orderer))\n\tif err != nil {\n\t\treturn errors.Errorf(\"Error from save channel: %s\", err.Error())\n\t}\n\n\tfmt.Printf(\"Channel created/updated: %s\\n\", cliconfig.Config().ChannelID())\n\n\treturn nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/channel/channeljoincmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage channel\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar chainJoinCmd = &cobra.Command{\n\tUse:   \"join\",\n\tShort: \"Join Channel\",\n\tLong:  \"Join a channel\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\taction, err := newChannelJoinAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing channelJoinAction: %v\", err)\n\t\t\treturn\n\t\t}\n\n\t\tdefer action.Terminate()\n\n\t\terr = action.invoke()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running channelJoinAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getChannelJoinCmd() *cobra.Command {\n\tflags := chainJoinCmd.Flags()\n\tcliconfig.InitChannelID(flags)\n\tcliconfig.InitOrdererURL(flags)\n\tcliconfig.InitPeerURL(flags)\n\treturn chainJoinCmd\n}\n\ntype channelJoinAction struct {\n\taction.Action\n}\n\nfunc newChannelJoinAction(flags *pflag.FlagSet) (*channelJoinAction, error) {\n\taction := &channelJoinAction{}\n\terr := action.Initialize(flags)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif len(action.Peers()) == 0 {\n\t\treturn nil, errors.Errorf(\"at least one peer is required for join\")\n\t}\n\treturn action, nil\n}\n\nfunc (a *channelJoinAction) invoke() error {\n\tfmt.Printf(\"Attempting to join channel: %s\\n\", cliconfig.Config().ChannelID())\n\n\tvar lastErr error\n\tfor orgID, peers := range a.PeersByOrg() {\n\t\tfmt.Printf(\"Joining channel %s on org[%s] peers:\\n\", cliconfig.Config().ChannelID(), orgID)\n\t\tfor _, peer := range peers {\n\t\t\tfmt.Printf(\"-- %s\\n\", peer.URL())\n\t\t}\n\t\terr := a.joinChannel(orgID, peers)\n\t\tif err != nil {\n\t\t\tlastErr = err\n\t\t}\n\t}\n\treturn lastErr\n}\n\nfunc (a *channelJoinAction) joinChannel(orgID string, peers []fab.Peer) error {\n\tcliconfig.Config().Logger().Debugf(\"Joining channel [%s]...\\n\", cliconfig.Config().ChannelID())\n\n\tfmt.Printf(\"==========> JOIN ORG: %s\\n\", orgID)\n\n\tresMgmtClient, err := a.ResourceMgmtClientForOrg(orgID)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\torderer, err := a.RandomOrderer()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\terr = resMgmtClient.JoinChannel(cliconfig.Config().ChannelID(), resmgmt.WithTargets(peers...), resmgmt.WithOrderer(orderer))\n\tif err != nil {\n\t\treturn errors.WithMessage(err, \"Could not join channel: %v\")\n\t}\n\n\tfmt.Printf(\"Channel %s joined!\\n\", cliconfig.Config().ChannelID())\n\n\treturn nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/cmd/fabric-cli.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage cmd\n\nimport (\n\t\"os\"\n\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/channel\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/event\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/query\"\n\t\"github.com/spf13/cobra\"\n)\n\nfunc newFabricCLICmd() *cobra.Command {\n\n\tmainCmd := &cobra.Command{\n\t\tUse: \"fabric-cli\",\n\t\tPersistentPreRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\treturn nil\n\t\t},\n\t\tRun: func(cmd *cobra.Command, args []string) {\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t},\n\t}\n\n\tflags := mainCmd.PersistentFlags()\n\tcliconfig.InitConfigFile(flags)\n\tcliconfig.InitLoggingLevel(flags)\n\tcliconfig.InitUserName(flags)\n\tcliconfig.InitUserPassword(flags)\n\tcliconfig.InitOrdererTLSCertificate(flags)\n\tcliconfig.InitPrintFormat(flags)\n\tcliconfig.InitWriter(flags)\n\tcliconfig.InitBase64(flags)\n\tcliconfig.InitOrgIDs(flags)\n\n\tmainCmd.AddCommand(chaincode.Cmd())\n\tmainCmd.AddCommand(query.Cmd())\n\tmainCmd.AddCommand(channel.Cmd())\n\tmainCmd.AddCommand(event.Cmd())\n\n\treturn mainCmd\n}\n\nfunc Execute() {\n\tif newFabricCLICmd().Execute() != nil {\n\t\tos.Exit(1)\n\t}\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/config/config.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage config\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\t\"time\"\n\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/fab/events/deliverclient/seek\"\n\n\t\"strings\"\n\n\t\"github.com/spf13/pflag\"\n\n\t\"os\"\n\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/logging\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/core/config\"\n)\n\nconst (\n\tloggerName    = \"fabriccli\"\n\tuserStatePath = \"/tmp/enroll_user\"\n\n\t// AutoDetectSelectionProvider indicates that a selection provider is to be automatically determined using channel capabilities\n\tAutoDetectSelectionProvider = \"auto\"\n\n\t// StaticSelectionProvider indicates that a static selection provider is to be used for selecting peers for invoke/query commands\n\tStaticSelectionProvider = \"static\"\n\n\t// DynamicSelectionProvider indicates that a dynamic selection provider is to be used for selecting peers for invoke/query commands\n\tDynamicSelectionProvider = \"dynamic\"\n\n\t// FabricSelectionProvider indicates that the Fabric selection provider is to be used for selecting peers for invoke/query commands\n\tFabricSelectionProvider = \"fabric\"\n)\n\n// Flags\nconst (\n\tUserFlag        = \"user\"\n\tuserDescription = \"The user\"\n\tdefaultUser     = \"\"\n\n\tPasswordFlag        = \"pw\"\n\tpasswordDescription = \"The password of the user\"\n\tdefaultPassword     = \"\"\n\n\tChaincodeVersionFlag        = \"v\"\n\tchaincodeVersionDescription = \"The chaincode version\"\n\tdefaultChaincodeVersion     = \"v0\"\n\n\tLoggingLevelFlag        = \"logging-level\"\n\tloggingLevelDescription = \"Logging level - ERROR, WARN, INFO, DEBUG\"\n\tdefaultLoggingLevel     = \"ERROR\"\n\n\tOrgIDsFlag        = \"orgid\"\n\torgIDsDescription = \"A comma-separated list of organization IDs\"\n\tdefaultOrgIDs     = \"\"\n\n\tChannelIDFlag        = \"cid\"\n\tchannelIDDescription = \"The channel ID\"\n\tdefaultChannelID     = \"\"\n\n\tChaincodeIDFlag        = \"ccid\"\n\tchaincodeIDDescription = \"The Chaincode ID\"\n\tdefaultChaincodeID     = \"\"\n\n\tChaincodePathFlag        = \"ccp\"\n\tchaincodePathDescription = \"The chaincode path\"\n\tdefaultChaincodePath     = \"\"\n\n\tConfigFileFlag        = \"config\"\n\tconfigFileDescription = \"The path of the config.yaml file\"\n\tdefaultConfigFile     = \"\"\n\n\tPeerURLFlag        = \"peer\"\n\tpeerURLDescription = \"A comma-separated list of peer targets, e.g. 'grpcs://localhost:7051,grpcs://localhost:8051'\"\n\tdefaultPeerURL     = \"\"\n\n\tOrdererFlag           = \"orderer\"\n\tordererURLDescription = \"The URL of the orderer, e.g. grpcs://localhost:7050\"\n\tdefaultOrdererURL     = \"\"\n\n\tPrintFormatFlag        = \"format\"\n\tprintFormatDescription = \"The output format - display, json, raw\"\n\n\tWriterFlag        = \"writer\"\n\twriterDescription = \"The writer - stdout, stderr, log\"\n\n\tBase64Flag        = \"base64\"\n\tbase64Description = \"If true then binary values are encoded in base64 (only applies to 'display' format)\"\n\n\tCertificateFileFlag    = \"cacert\"\n\tcertificateDescription = \"The path of the ca-cert.pem file\"\n\tdefaultCertificate     = \"\"\n\n\tArgsFlag        = \"args\"\n\targsDescription = `The args in JSON format. Example: {\"Func\":\"function\",\"Args\":[\"arg1\",\"arg2\"]}. Note that $rand(N) may be used anywhere within the value of the arg in order to generate a random value between 0 and N. For example {\"Func\":\"function\",\"Args\":[\"arg_$rand(100)\",\"$rand(10)\"]}.`\n\n\tIterationsFlag        = \"iterations\"\n\titerationsDescription = \"The number of times to invoke the chaincode\"\n\tdefaultIterations     = \"1\"\n\n\tSleepFlag            = \"sleep\"\n\tsleepTimeDescription = \"The number of milliseconds to sleep between invocations of the chaincode.\"\n\tdefaultSleepTime     = \"0\"\n\n\tTxFileFlag        = \"txfile\"\n\ttxFileDescription = \"The path of the channel.tx file\"\n\tdefaultTxFile     = \"\"\n\n\tChaincodeEventFlag        = \"event\"\n\tchaincodeEventDescription = \"The name of the chaincode event to listen for\"\n\tdefaultChaincodeEvent     = \"\"\n\n\tSeekTypeFlag        = \"seek\"\n\tseekTypeDescription = \"The seek type. Possible values: oldest - delivers all blocks from the oldest block; newest - delivers the newest block; from - delivers from the block number as specified by the '--num' flag\"\n\tdefaultSeekType     = string(seek.Newest)\n\n\tTxIDFlag        = \"txid\"\n\ttxIDDescription = \"The transaction ID\"\n\tdefaultTxID     = \"\"\n\n\tBlockNumFlag        = \"num\"\n\tblockNumDescription = \"The block number\"\n\tdefaultBlockNum     = \"0\"\n\n\tBlockHashFlag        = \"hash\"\n\tblockHashDescription = \"The block hash\"\n\tdefaultBlockHash     = \"\"\n\n\tTraverseFlag        = \"traverse\"\n\ttraverseDescription = \"Blocks will be traversed starting with the given block in reverse order up to the given number of blocks\"\n\tdefaultTraverse     = \"0\"\n\n\tChaincodePolicyFlag        = \"policy\"\n\tchaincodePolicyDescription = \"The chaincode policy, e.g. OutOf(1,'Org1MSP.admin','Org2MSP.admin',AND('Org3MSP.member','Org4MSP.member'))\"\n\tdefaultChaincodePolicy     = \"\"\n\n\tCollectionConfigFileFlag        = \"collconfig\"\n\tcollectionConfigFileDescription = \"The path of the JSON file that contains the private data collection configuration for the chaincode\"\n\tdefaultCollectionConfigFile     = \"\"\n\n\tTimeoutFlag        = \"timeout\"\n\ttimeoutDescription = \"The timeout (in milliseconds) for the operation\"\n\tdefaultTimeout     = \"5000\"\n\n\tPrintPayloadOnlyFlag        = \"payload\"\n\tprintPayloadOnlyDescription = \"If specified then only the payload from the transaction proposal response(s) will be output\"\n\tdefaultPrintPayloadOnly     = \"false\"\n\n\tValidateFlag        = \"validate\"\n\tvalidateDescription = \"If specified then endorsement responses from queries will be validated\"\n\tdefaultValidate     = \"false\"\n\n\tConcurrencyFlag        = \"concurrency\"\n\tconcurrencyDescription = \"Specifies the number of concurrent requests sent on an invoke or a query chaincode request\"\n\tdefaultConcurrency     = \"1\"\n\n\tMaxAttemptsFlag        = \"attempts\"\n\tmaxAttemptsDescription = \"Specifies the maximum number of attempts to be made for a single chaincode invocation request. If >1 then retries will be attempted should transient errors occur.\"\n\tdefaultMaxAttempts     = \"3\"\n\n\tInitialBackoffFlag        = \"backoff\"\n\tinitialBackoffDescription = \"The initial backoff is the time (in milliseconds) to wait before resubmitting an invocation after a transient error\"\n\tdefaultInitialBackoff     = \"1000\"\n\n\tMaxBackoffFlag        = \"maxbackoff\"\n\tmaxBackoffDescription = \"The maximum backoff time (in milliseconds)\"\n\tdefaultMaxBackoff     = \"5000\"\n\n\tBackoffFactorFlag        = \"backofffactor\"\n\tbackoffFactorDescription = \"The factor by which the backoff time is multiplied each time a retry fails. For example, if the initial backoff is 1s and factor is 2 then the next retry will have a backoff of 2s and a subsequent backoff will be 4s up to the maximum backoff\"\n\tdefaultBackoffFactor     = \"2\"\n\n\tVerboseFlag        = \"verbose\"\n\tverboseDescription = \"If specified then the transaction proposal responses will be output when iterations > 1, otherwise transaction proposal responses are only output when iterations = 1\"\n\tdefaultVerbosity   = \"false\"\n\n\tSelectionProviderFlag        = \"selectprovider\"\n\tselectionProviderDescription = \"The peer selection provider for invoke/query commands. The possible values are: (1) static - Selects all peers; (2) dynamic - Uses the built-in selection service from the SDK to select a minimal set of peers according to the endorsement policy of the chaincode; (3) fabric - Uses Fabric's Discovery Service to select a minimal set of peers according to the endorsement/collection policy of the chaincode; (4) auto (default) - Automatically determines which selection service to use based on channel capabilities.\"\n\tdefaultSelectionProvider     = AutoDetectSelectionProvider\n\n\tGoPathFlag        = \"gopath\"\n\tgoPathDescription = \"GOPATH for chaincode install command. If not set, GOPATH is taken from the environment\"\n\tdefaultGoPath     = \"\"\n)\n\nvar opts *options\nvar instance *CLIConfig\n\ntype options struct {\n\tcertificate          string\n\tuser                 string\n\tpassword             string\n\tloggingLevel         string\n\torgIDsStr            string\n\tchannelID            string\n\tchaincodeID          string\n\tchaincodePath        string\n\tchaincodeVersion     string\n\tpeerURL              string\n\tordererURL           string\n\titerations           int\n\tsleepTime            int64\n\tconfigFile           string\n\ttxFile               string\n\ttxID                 string\n\tprintFormat          string\n\twriter               string\n\tbase64               bool\n\targs                 string\n\tchaincodeEvent       string\n\tseekType             string\n\tblockHash            string\n\tblockNum             uint64\n\ttraverse             int\n\tchaincodePolicy      string\n\tcollectionConfigFile string\n\ttimeout              int64\n\tprintPayloadOnly     bool\n\tvalidate             bool\n\tconcurrency          int\n\tmaxAttempts          int\n\tinitialBackoff       int64\n\tmaxBackoff           int64\n\tbackoffFactor        float64\n\tverbose              bool\n\tselectionProvider    string\n\tgoPath               string\n}\n\nfunc init() {\n\topts = &options{\n\t\tuser:             defaultUser,\n\t\tpassword:         defaultPassword,\n\t\tloggingLevel:     defaultLoggingLevel,\n\t\tchannelID:        defaultChannelID,\n\t\torgIDsStr:        defaultOrgIDs,\n\t\tchaincodeVersion: defaultChaincodeVersion,\n\t\titerations:       1,\n\t\tconcurrency:      1,\n\t\targs:             getEmptyArgs(),\n\t}\n}\n\n// CLIConfig overrides certain configuration values with those supplied on the command-line\ntype CLIConfig struct {\n\tcore.ConfigProvider\n\tlogger   *logging.Logger\n\tsetFlags map[string]string\n}\n\n// InitConfig initializes the configuration\nfunc InitConfig(flags *pflag.FlagSet) error {\n\n\tinstance = &CLIConfig{\n\t\tlogger:   logging.NewLogger(loggerName),\n\t\tsetFlags: make(map[string]string),\n\t}\n\tflags.Visit(func(flag *pflag.Flag) {\n\t\tinstance.setFlags[flag.Name] = flag.Value.String()\n\t})\n\n\tcnfg := config.FromFile(opts.configFile)\n\n\tinstance.ConfigProvider = cnfg\n\n\treturn nil\n}\n\n// IsFlagSet indicates whether or not the given flag is set\nfunc IsFlagSet(name string) bool {\n\t_, ok := instance.setFlags[name]\n\treturn ok\n}\n\n// Provider returns the config provider\nfunc Provider() core.ConfigProvider {\n\treturn instance.ConfigProvider\n}\n\n// Config returns the CLI configuration\nfunc Config() *CLIConfig {\n\treturn instance\n}\n\n// Logger returns the Logger for the CLI tool\nfunc (c *CLIConfig) Logger() *logging.Logger {\n\treturn c.logger\n}\n\n// LoggingLevel specifies the logging level (DEBUG, INFO, WARNING, ERROR, or CRITICAL)\nfunc (c *CLIConfig) LoggingLevel() string {\n\treturn opts.loggingLevel\n}\n\n// InitLoggingLevel initializes the logging level from the provided arguments\nfunc InitLoggingLevel(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultLoggingLevel, loggingLevelDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.loggingLevel, LoggingLevelFlag, defaultValue, description)\n}\n\n// InitConfigFile initializes the config file path from the provided arguments\nfunc InitConfigFile(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultConfigFile, configFileDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.configFile, ConfigFileFlag, defaultValue, description)\n}\n\n// OrgID specifies the ID of the current organization. If multiple org IDs are specified then the first one is returned.\nfunc (c *CLIConfig) OrgID() string {\n\tif len(c.OrgIDs()) == 0 {\n\t\treturn \"\"\n\t}\n\treturn c.OrgIDs()[0]\n}\n\n// OrgIDs returns a comma-separated list of organization IDs\nfunc (c *CLIConfig) OrgIDs() []string {\n\tvar orgIDs []string\n\tif len(strings.TrimSpace(opts.orgIDsStr)) > 0 {\n\t\ts := strings.Split(opts.orgIDsStr, \",\")\n\t\tfor _, orgID := range s {\n\t\t\torgIDs = append(orgIDs, orgID)\n\t\t}\n\t}\n\treturn orgIDs\n}\n\n// InitOrgIDs initializes the org IDs from the provided arguments\nfunc InitOrgIDs(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultOrgIDs, orgIDsDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.orgIDsStr, OrgIDsFlag, defaultValue, description)\n}\n\n// ChannelID returns the channel ID\nfunc (c *CLIConfig) ChannelID() string {\n\treturn opts.channelID\n}\n\n// InitChannelID initializes the channel ID from the provided arguments\nfunc InitChannelID(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultChannelID, channelIDDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.channelID, ChannelIDFlag, defaultValue, description)\n}\n\n// UserName returns the name of the enrolled user\nfunc (c *CLIConfig) UserName() string {\n\treturn opts.user\n}\n\n// InitUserName initializes the user name from the provided arguments\nfunc InitUserName(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultUser, userDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.user, UserFlag, defaultValue, description)\n}\n\n// UserPassword is the password to use when enrolling a user\nfunc (c *CLIConfig) UserPassword() string {\n\treturn opts.password\n}\n\n// InitUserPassword initializes the user password from the provided arguments\nfunc InitUserPassword(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultPassword, passwordDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.password, PasswordFlag, defaultValue, description)\n}\n\n// ChaincodeID returns the chaicode ID\nfunc (c *CLIConfig) ChaincodeID() string {\n\treturn opts.chaincodeID\n}\n\n// InitChaincodeID initializes the chaincode ID from the provided arguments\nfunc InitChaincodeID(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultChaincodeID, chaincodeIDDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.chaincodeID, ChaincodeIDFlag, defaultValue, description)\n}\n\n// ChaincodeEvent the name of the chaincode event to listen for\nfunc (c *CLIConfig) ChaincodeEvent() string {\n\treturn opts.chaincodeEvent\n}\n\n// InitChaincodeEvent initializes the chaincode event name from the provided arguments\nfunc InitChaincodeEvent(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultChaincodeEvent, chaincodeEventDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.chaincodeEvent, ChaincodeEventFlag, defaultValue, description)\n}\n\n// SeekType the seek type for Deliver Events. Possible values:\n// - Oldest - will deliver all blocks from the oldest block and will continue listening for new blocks\n// - Newest - will deliver the newest block and will continue listening for new blocks\n// - FromBlock - Delivers from the specific block, as specified by the \"--num\" flag\nfunc (c *CLIConfig) SeekType() seek.Type {\n\treturn seek.Type(opts.seekType)\n}\n\n// InitSeekType initializes the seek type from the provided arguments\nfunc InitSeekType(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultSeekType, seekTypeDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.seekType, SeekTypeFlag, defaultValue, description)\n}\n\n// ChaincodePath returns the source path of the chaincode to install/instantiate\nfunc (c *CLIConfig) ChaincodePath() string {\n\treturn opts.chaincodePath\n}\n\n// InitChaincodePath initializes the chaincode install source path from the provided arguments\nfunc InitChaincodePath(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultChaincodePath, chaincodePathDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.chaincodePath, ChaincodePathFlag, defaultValue, description)\n}\n\n// ChaincodeVersion returns the version of the chaincode\nfunc (c *CLIConfig) ChaincodeVersion() string {\n\treturn opts.chaincodeVersion\n}\n\n// InitChaincodeVersion initializes the chaincode version from the provided arguments\nfunc InitChaincodeVersion(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultChaincodeVersion, chaincodeVersionDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.chaincodeVersion, ChaincodeVersionFlag, defaultValue, description)\n}\n\n// PeerURL returns a comma-separated list of peers in the format host1:port1,host2:port2,...\nfunc (c *CLIConfig) PeerURL() string {\n\treturn opts.peerURL\n}\n\n// PeerURLs returns a list of peer URLs\nfunc (c *CLIConfig) PeerURLs() []string {\n\tvar urls []string\n\tif len(strings.TrimSpace(opts.peerURL)) > 0 {\n\t\ts := strings.Split(opts.peerURL, \",\")\n\t\tfor _, orgID := range s {\n\t\t\turls = append(urls, orgID)\n\t\t}\n\t}\n\treturn urls\n}\n\n// InitPeerURL initializes the peer URL from the provided arguments\nfunc InitPeerURL(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultPeerURL, peerURLDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.peerURL, PeerURLFlag, defaultValue, description)\n}\n\n// OrdererURL returns the URL of the orderer\nfunc (c *CLIConfig) OrdererURL() string {\n\treturn opts.ordererURL\n}\n\n// InitOrdererURL initializes the orderer URL from the provided arguments\nfunc InitOrdererURL(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultOrdererURL, ordererURLDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.ordererURL, OrdererFlag, defaultValue, description)\n}\n\n// Iterations returns the number of times that a chaincode should be invoked\nfunc (c *CLIConfig) Iterations() int {\n\treturn opts.iterations\n}\n\n// InitIterations initializes the number of query/invoke iterations from the provided arguments\nfunc InitIterations(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultIterations, iterationsDescription, defaultValueAndDescription...)\n\ti, err := strconv.Atoi(defaultValue)\n\tif err != nil {\n\t\tfmt.Printf(\"Invalid number for %s: %s\\n\", IterationsFlag, defaultValue)\n\t\tos.Exit(-1)\n\t}\n\tflags.IntVar(&opts.iterations, IterationsFlag, i, description)\n}\n\n// SleepTime returns the number of milliseconds to sleep between invocations of a chaincode\nfunc (c *CLIConfig) SleepTime() int64 {\n\treturn opts.sleepTime\n}\n\n// InitSleepTime initializes the sleep time from the provided arguments\nfunc InitSleepTime(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultSleepTime, sleepTimeDescription, defaultValueAndDescription...)\n\ti, err := strconv.Atoi(defaultValue)\n\tif err != nil {\n\t\tfmt.Printf(\"Invalid number for %s: %s\\n\", SleepFlag, defaultValue)\n\t\tos.Exit(-1)\n\t}\n\tflags.Int64Var(&opts.sleepTime, SleepFlag, int64(i), description)\n}\n\n// BlockNum returns the block number (where 0 is the first block)\nfunc (c *CLIConfig) BlockNum() uint64 {\n\treturn opts.blockNum\n}\n\n// InitBlockNum initializes the bluck number from the provided arguments\nfunc InitBlockNum(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultBlockNum, blockNumDescription, defaultValueAndDescription...)\n\ti, err := strconv.ParseUint(defaultValue, 10, 64)\n\tif err != nil {\n\t\tfmt.Printf(\"Invalid number for %s: %s\\n\", BlockNumFlag, defaultValue)\n\t\tos.Exit(-1)\n\t}\n\tflags.Uint64Var(&opts.blockNum, BlockNumFlag, i, description)\n}\n\n// BlockHash specifies the hash of the block\nfunc (c *CLIConfig) BlockHash() string {\n\treturn opts.blockHash\n}\n\n// InitBlockHash initializes the block hash from the provided arguments\nfunc InitBlockHash(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultBlockHash, blockHashDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.blockHash, BlockHashFlag, defaultValue, description)\n}\n\n// Traverse returns the number of blocks to traverse backwards in the query block command\nfunc (c *CLIConfig) Traverse() int {\n\treturn opts.traverse\n}\n\n// InitTraverse initializes the 'traverse' flag from the provided arguments\nfunc InitTraverse(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultTraverse, traverseDescription, defaultValueAndDescription...)\n\ti, err := strconv.Atoi(defaultValue)\n\tif err != nil {\n\t\tfmt.Printf(\"Invalid number for %s: %s\\n\", TimeoutFlag, defaultValue)\n\t\ti = 1\n\t}\n\tflags.IntVar(&opts.traverse, TraverseFlag, i, description)\n}\n\n// PrintFormat returns the print (output) format for a block\nfunc (c *CLIConfig) PrintFormat() string {\n\treturn opts.printFormat\n}\n\n// InitPrintFormat initializes the print format from the provided arguments\nfunc InitPrintFormat(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(\"display\", printFormatDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.printFormat, PrintFormatFlag, defaultValue, description)\n}\n\n// Writer returns the writer for output\nfunc (c *CLIConfig) Writer() string {\n\treturn opts.writer\n}\n\n// InitWriter initializes the print writer from the provided arguments\nfunc InitWriter(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(\"stdout\", writerDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.writer, WriterFlag, defaultValue, description)\n}\n\n// Base64 indicates whether binary values are to be encoded in base64. (Only applies to 'display' format.)\nfunc (c *CLIConfig) Base64() bool {\n\treturn opts.base64\n}\n\n// InitBase64 initializes the base64 flag from the provided arguments\nfunc InitBase64(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(\"false\", writerDescription, defaultValueAndDescription...)\n\tflags.BoolVar(&opts.base64, Base64Flag, defaultValue == \"true\", description)\n}\n\n// OrdererTLSCertificate is the path of the orderer TLS certificate\nfunc (c *CLIConfig) OrdererTLSCertificate() string {\n\treturn opts.certificate\n}\n\n// InitOrdererTLSCertificate initializes the orderer TLS certificate from the provided arguments\nfunc InitOrdererTLSCertificate(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultCertificate, certificateDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.certificate, CertificateFileFlag, defaultValue, description)\n}\n\n// Args returns the chaincode invocation arguments as a JSON string in the format, {\"Func\":\"function\",\"Args\":[\"arg1\",\"arg2\",...]}\nfunc (c *CLIConfig) Args() string {\n\treturn opts.args\n}\n\n// InitArgs initializes the invoke/query args from the provided arguments\nfunc InitArgs(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(getEmptyArgs(), argsDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.args, ArgsFlag, defaultValue, description)\n}\n\n// TxFile is the path of the .tx file used to create a channel\nfunc (c *CLIConfig) TxFile() string {\n\treturn opts.txFile\n}\n\n// InitTxFile initializes the path of the .tx file used to create/update a channel from the provided arguments\nfunc InitTxFile(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultTxFile, txFileDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.txFile, TxFileFlag, defaultValue, description)\n}\n\n// TxID returns the transaction ID\nfunc (c *CLIConfig) TxID() string {\n\treturn opts.txID\n}\n\n// InitTxID initializes the transaction D from the provided arguments\nfunc InitTxID(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultTxID, txIDDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.txID, TxIDFlag, defaultValue, description)\n}\n\n// ChaincodePolicy returns the chaincode policy string, e.g Nof(1,(SignedBy(Org1Msp),SignedBy(Org2MSP)))\nfunc (c *CLIConfig) ChaincodePolicy() string {\n\treturn opts.chaincodePolicy\n}\n\n// InitChaincodePolicy initializes the chaincode policy from the provided arguments\nfunc InitChaincodePolicy(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultChaincodePolicy, chaincodePolicyDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.chaincodePolicy, ChaincodePolicyFlag, defaultValue, description)\n}\n\n// CollectionConfigFile returns the path of the JSON file that contains the private data collection configuration for the chaincode to be instantiated/upgraded\nfunc (c *CLIConfig) CollectionConfigFile() string {\n\treturn opts.collectionConfigFile\n}\n\n// InitCollectionConfigFile initializes the collection config file from the provided arguments\nfunc InitCollectionConfigFile(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultCollectionConfigFile, collectionConfigFileDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.collectionConfigFile, CollectionConfigFileFlag, defaultValue, description)\n}\n\n// Timeout returns the timeout (in milliseconds) for various operations\nfunc (c *CLIConfig) Timeout(timeoutType fab.TimeoutType) time.Duration {\n\t// TODO use provided timoutType\n\treturn time.Duration(opts.timeout) * time.Millisecond\n}\n\n// InitTimeout initializes the timeout from the provided arguments\nfunc InitTimeout(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultTimeout, timeoutDescription, defaultValueAndDescription...)\n\ti, err := strconv.Atoi(defaultValue)\n\tif err != nil {\n\t\tfmt.Printf(\"Invalid number for %s: %s\\n\", TimeoutFlag, defaultValue)\n\t\ti = 1000\n\t}\n\tflags.Int64Var(&opts.timeout, TimeoutFlag, int64(i), description)\n}\n\n// PrintPayloadOnly indicates whether only the payload or the entire\n// transaction proposal response should be printed\nfunc (c *CLIConfig) PrintPayloadOnly() bool {\n\treturn opts.printPayloadOnly\n}\n\n// InitPrintPayloadOnly initializes the PrintPayloadOnly flag from the provided arguments\nfunc InitPrintPayloadOnly(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultPrintPayloadOnly, printPayloadOnlyDescription, defaultValueAndDescription...)\n\tflags.BoolVar(&opts.printPayloadOnly, PrintPayloadOnlyFlag, defaultValue == \"true\", description)\n}\n\n// Validate indicates whether the endorsement responses from a query should be validated\nfunc (c *CLIConfig) Validate() bool {\n\treturn opts.validate\n}\n\n// InitValidate initializes the Validate flag from the provided arguments\nfunc InitValidate(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultValidate, validateDescription, defaultValueAndDescription...)\n\tflags.BoolVar(&opts.validate, ValidateFlag, defaultValue == \"true\", description)\n}\n\n// Concurrency returns the number of concurrent invocations/queries\nfunc (c *CLIConfig) Concurrency() uint16 {\n\treturn uint16(opts.concurrency)\n}\n\n// InitConcurrency initializes the 'concurrency' flag from the provided arguments\nfunc InitConcurrency(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultConcurrency, concurrencyDescription, defaultValueAndDescription...)\n\ti, err := strconv.Atoi(defaultValue)\n\tif err != nil {\n\t\tfmt.Printf(\"Invalid number for %s: %s\\n\", TimeoutFlag, defaultValue)\n\t\ti = 1\n\t}\n\tflags.IntVar(&opts.concurrency, ConcurrencyFlag, i, description)\n}\n\n// MaxAttempts returns the maximum number of invocations attempts to be made\n// for a single chaincode invocation request. If >1 then a retry will be attempted\n// if a transient failure occurs.\nfunc (c *CLIConfig) MaxAttempts() int {\n\treturn opts.maxAttempts\n}\n\n// InitMaxAttempts initializes the 'maxAttempts' flag from the provided arguments\nfunc InitMaxAttempts(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultMaxAttempts, maxAttemptsDescription, defaultValueAndDescription...)\n\ti, err := strconv.Atoi(defaultValue)\n\tif err != nil {\n\t\tfmt.Printf(\"Invalid number for %s: %s\\n\", TimeoutFlag, defaultValue)\n\t\ti = 1\n\t}\n\tflags.IntVar(&opts.maxAttempts, MaxAttemptsFlag, i, description)\n}\n\n// InitialBackoff returns the time (in milliseconds) to wait\n// before resubmitting an invocation after a transient error\nfunc (c *CLIConfig) InitialBackoff() time.Duration {\n\treturn time.Duration(opts.initialBackoff) * time.Millisecond\n}\n\n// InitInitialBackoff initializes the initial backoff from the provided arguments\nfunc InitInitialBackoff(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultInitialBackoff, initialBackoffDescription, defaultValueAndDescription...)\n\ti, err := strconv.Atoi(defaultValue)\n\tif err != nil {\n\t\tfmt.Printf(\"Invalid number for %s: %s\\n\", TimeoutFlag, defaultValue)\n\t\ti = 1000\n\t}\n\tflags.Int64Var(&opts.initialBackoff, InitialBackoffFlag, int64(i), description)\n}\n\n// MaxBackoff returns the number\nfunc (c *CLIConfig) MaxBackoff() time.Duration {\n\treturn time.Duration(opts.maxBackoff) * time.Millisecond\n}\n\n// InitMaxBackoff initializes the maximum backoff from the provided arguments\nfunc InitMaxBackoff(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultMaxBackoff, maxBackoffDescription, defaultValueAndDescription...)\n\ti, err := strconv.Atoi(defaultValue)\n\tif err != nil {\n\t\tfmt.Printf(\"Invalid number for %s: %s\\n\", TimeoutFlag, defaultValue)\n\t\ti = 1000\n\t}\n\tflags.Int64Var(&opts.maxBackoff, MaxBackoffFlag, int64(i), description)\n}\n\n// BackoffFactor returns the factor by which the backoff time is multiplied each time a retry fails. For example, if the initial\n// backoff is 1s and factor is 2 then the next retry will have a backoff of 2s and a subsequent backoff will be 4s up to the maximum backoff\nfunc (c *CLIConfig) BackoffFactor() float64 {\n\treturn opts.backoffFactor\n}\n\n// InitBackoffFactor initializes the backoff factor from the provided arguments\nfunc InitBackoffFactor(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultBackoffFactor, backoffFactorDescription, defaultValueAndDescription...)\n\ti, err := strconv.Atoi(defaultValue)\n\tif err != nil {\n\t\tfmt.Printf(\"Invalid number for %s: %s\\n\", TimeoutFlag, defaultValue)\n\t\ti = 1000\n\t}\n\tflags.Float64Var(&opts.backoffFactor, BackoffFactorFlag, float64(i), description)\n}\n\n// Verbose indicates whether or not to print the transaction proposal responses\n// when Iterations > 1\nfunc (c *CLIConfig) Verbose() bool {\n\treturn opts.verbose\n}\n\n// InitVerbosity initializes the Verbose flag from the provided arguments\nfunc InitVerbosity(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultVerbosity, verboseDescription, defaultValueAndDescription...)\n\tflags.BoolVar(&opts.verbose, VerboseFlag, defaultValue == \"true\", description)\n}\n\n// SelectionProvider returns the peer selection provider - either static or dynamic\nfunc (c *CLIConfig) SelectionProvider() string {\n\treturn opts.selectionProvider\n}\n\n// InitSelectionProvider initializes the peer selection provider from the provided arguments\nfunc InitSelectionProvider(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultSelectionProvider, selectionProviderDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.selectionProvider, SelectionProviderFlag, defaultValue, description)\n}\n\n// InitGoPath initializes the gopath from the provided arguments\nfunc InitGoPath(flags *pflag.FlagSet, defaultValueAndDescription ...string) {\n\tdefaultValue, description := getDefaultValueAndDescription(defaultGoPath, goPathDescription, defaultValueAndDescription...)\n\tflags.StringVar(&opts.goPath, GoPathFlag, defaultValue, description)\n}\n\n// GoPath returns the gopath\nfunc (c *CLIConfig) GoPath() string {\n\tgopath := opts.goPath\n\tif !IsFlagSet(GoPathFlag) {\n\t\tgopath = os.Getenv(\"GOPATH\")\n\t}\n\treturn gopath\n}\n\n// IsLoggingEnabledFor indicates whether the logger is enabled for the given logging level\nfunc (c *CLIConfig) IsLoggingEnabledFor(level logging.Level) bool {\n\treturn logging.IsEnabledFor(loggerName, level)\n}\n\n// Utility functions...\n\nfunc getEmptyArgs() string {\n\treturn \"{}\"\n}\n\nfunc getDefaultValueAndDescription(defaultValue string, defaultDescription string, overrides ...string) (value, description string) {\n\tif len(overrides) > 0 {\n\t\tvalue = overrides[0]\n\t} else {\n\t\tvalue = defaultValue\n\t}\n\tif len(overrides) > 1 {\n\t\tdescription = overrides[1]\n\t} else {\n\t\tdescription = defaultDescription\n\t}\n\treturn value, description\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/event/eventcmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage event\n\nimport (\n\t\"github.com/spf13/cobra\"\n)\n\nvar eventCmd = &cobra.Command{\n\tUse:   \"event\",\n\tShort: \"Event commands\",\n\tLong:  \"Event commands\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tcmd.HelpFunc()(cmd, args)\n\t},\n}\n\n// Cmd returns the events command\nfunc Cmd() *cobra.Command {\n\teventCmd.AddCommand(getListenCCCmd())\n\teventCmd.AddCommand(getListenTXCmd())\n\teventCmd.AddCommand(getListenBlockCmd())\n\teventCmd.AddCommand(getListenFilteredBlockCmd())\n\n\treturn eventCmd\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/event/inputevent.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage event\n\nimport (\n\t\"bufio\"\n\t\"os\"\n)\n\ntype inputEvent struct {\n\tdone chan bool\n}\n\n// WaitForEnter waits until the user presses Enter\nfunc (c *inputEvent) WaitForEnter() chan bool {\n\tgo c.readFromCLI()\n\treturn c.done\n}\n\nfunc (c *inputEvent) readFromCLI() {\n\treader := bufio.NewReader(os.Stdin)\n\treader.ReadString('\\n')\n\tc.done <- true\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/event/listenblockcmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage event\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/event\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar listenBlockCmd = &cobra.Command{\n\tUse:   \"listenblock\",\n\tShort: \"Listen to block events.\",\n\tLong:  \"Listen to block events\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\taction, err := newlistenBlockAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing listenBlockAction: %v\", err)\n\t\t\treturn\n\t\t}\n\n\t\tdefer action.Terminate()\n\n\t\terr = action.invoke()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running listenBlockAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getListenBlockCmd() *cobra.Command {\n\tflags := listenBlockCmd.Flags()\n\tcliconfig.InitChannelID(flags)\n\tcliconfig.InitPeerURL(flags, \"\", \"The URL of the peer on which to listen for events, e.g. localhost:7051\")\n\tcliconfig.InitSeekType(flags)\n\tcliconfig.InitBlockNum(flags)\n\treturn listenBlockCmd\n}\n\ntype listenBlockAction struct {\n\taction.Action\n\tinputEvent\n}\n\nfunc newlistenBlockAction(flags *pflag.FlagSet) (*listenBlockAction, error) {\n\taction := &listenBlockAction{inputEvent: inputEvent{done: make(chan bool)}}\n\terr := action.Initialize(flags)\n\treturn action, err\n}\n\nfunc (a *listenBlockAction) invoke() error {\n\teventClient, err := a.EventClient(event.WithBlockEvents(), event.WithSeekType(cliconfig.Config().SeekType()), event.WithBlockNum(cliconfig.Config().BlockNum()))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Printf(\"Registering block event\\n\")\n\n\tbreg, beventch, err := eventClient.RegisterBlockEvent()\n\tif err != nil {\n\t\treturn errors.WithMessage(err, \"Error registering for block events\")\n\t}\n\tdefer eventClient.Unregister(breg)\n\n\tenterch := a.WaitForEnter()\n\tfor {\n\t\tselect {\n\t\tcase _, _ = <-enterch:\n\t\t\treturn nil\n\t\tcase event, ok := <-beventch:\n\t\t\tif !ok {\n\t\t\t\treturn errors.WithMessage(err, \"unexpected closed channel while waiting for block event\")\n\t\t\t}\n\t\t\ta.Printer().PrintBlock(event.Block)\n\t\t\tfmt.Println(\"Press <enter> to terminate\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/event/listencccmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage event\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar listenccCmd = &cobra.Command{\n\tUse:   \"listencc\",\n\tShort: \"Listen to chaincode events.\",\n\tLong:  \"Listen to chaincode events\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tif cliconfig.Config().ChaincodeID() == \"\" {\n\t\t\tfmt.Printf(\"\\nMust specify the chaincode ID\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\t\tif cliconfig.Config().ChaincodeEvent() == \"\" {\n\t\t\tfmt.Printf(\"\\nMust specify the event name\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\n\t\taction, err := newListenCCAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"\\nError while initializing listenCCAction: %v\\n\", err)\n\t\t\treturn\n\t\t}\n\n\t\tdefer action.Terminate()\n\n\t\terr = action.invoke()\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"\\nError while running listenCCAction: %v\\n\", err)\n\t\t}\n\t},\n}\n\nfunc getListenCCCmd() *cobra.Command {\n\tflags := listenccCmd.Flags()\n\tcliconfig.InitChannelID(flags)\n\tcliconfig.InitPeerURL(flags, \"\", \"The URL of the peer on which to listen for events, e.g. grpcs://localhost:7051\")\n\tcliconfig.InitChaincodeID(flags)\n\tcliconfig.InitChaincodeEvent(flags)\n\treturn listenccCmd\n}\n\ntype listenccAction struct {\n\taction.Action\n\tinputEvent\n}\n\nfunc newListenCCAction(flags *pflag.FlagSet) (*listenccAction, error) {\n\taction := &listenccAction{inputEvent: inputEvent{done: make(chan bool)}}\n\terr := action.Initialize(flags)\n\treturn action, err\n}\n\nfunc (a *listenccAction) invoke() error {\n\n\tfmt.Printf(\"Registering CC event on chaincode [%s] and event [%s]\\n\", cliconfig.Config().ChaincodeID(), cliconfig.Config().ChaincodeEvent())\n\n\teventHub, err := a.EventClient()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbreg, beventch, err := eventHub.RegisterChaincodeEvent(cliconfig.Config().ChaincodeID(), cliconfig.Config().ChaincodeEvent())\n\tif err != nil {\n\t\treturn errors.WithMessage(err, \"Error registering for block events\")\n\t}\n\tdefer eventHub.Unregister(breg)\n\n\tenterch := a.WaitForEnter()\n\tfor {\n\t\tselect {\n\t\tcase _, _ = <-enterch:\n\t\t\treturn nil\n\t\tcase event, ok := <-beventch:\n\t\t\tif !ok {\n\t\t\t\treturn errors.WithMessage(err, \"unexpected closed channel while waiting for block event\")\n\t\t\t}\n\t\t\ta.Printer().PrintChaincodeEvent(event)\n\t\t\tfmt.Println(\"Press <enter> to terminate\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/event/listenfilteredblockcmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage event\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/event\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar listenFilteredBlockCmd = &cobra.Command{\n\tUse:   \"listenfilteredblock\",\n\tShort: \"Listen to filtered block events.\",\n\tLong:  \"Listen to filtered block events\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\taction, err := newlistenFilteredBlockAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing listenFilteredBlockAction: %v\", err)\n\t\t\treturn\n\t\t}\n\n\t\tdefer action.Terminate()\n\n\t\terr = action.invoke()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running listenFilteredBlockAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getListenFilteredBlockCmd() *cobra.Command {\n\tflags := listenFilteredBlockCmd.Flags()\n\tcliconfig.InitChannelID(flags)\n\tcliconfig.InitPeerURL(flags, \"\", \"The URL of the peer on which to listen for events, e.g. localhost:7051\")\n\tcliconfig.InitSeekType(flags)\n\tcliconfig.InitBlockNum(flags)\n\treturn listenFilteredBlockCmd\n}\n\ntype listenFilteredBlockAction struct {\n\taction.Action\n\tinputEvent\n}\n\nfunc newlistenFilteredBlockAction(flags *pflag.FlagSet) (*listenFilteredBlockAction, error) {\n\taction := &listenFilteredBlockAction{inputEvent: inputEvent{done: make(chan bool)}}\n\terr := action.Initialize(flags)\n\treturn action, err\n}\n\nfunc (a *listenFilteredBlockAction) invoke() error {\n\teventClient, err := a.EventClient(event.WithSeekType(cliconfig.Config().SeekType()), event.WithBlockNum(cliconfig.Config().BlockNum()))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Printf(\"Registering filtered block event\\n\")\n\n\tbreg, beventch, err := eventClient.RegisterFilteredBlockEvent()\n\tif err != nil {\n\t\treturn errors.WithMessage(err, \"Error registering for filtered block events\")\n\t}\n\tdefer eventClient.Unregister(breg)\n\n\tenterch := a.WaitForEnter()\n\tfor {\n\t\tselect {\n\t\tcase _, _ = <-enterch:\n\t\t\treturn nil\n\t\tcase event, ok := <-beventch:\n\t\t\tif !ok {\n\t\t\t\treturn errors.WithMessage(err, \"unexpected closed channel while waiting for filtered block event\")\n\t\t\t}\n\t\t\ta.Printer().PrintFilteredBlock(event.FilteredBlock)\n\t\t\tfmt.Println(\"Press <enter> to terminate\")\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/event/listentxcmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage event\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar listenTxCmd = &cobra.Command{\n\tUse:   \"listentx\",\n\tShort: \"Listen to transaction events.\",\n\tLong:  \"Listen to transaction events\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tif cliconfig.Config().TxID() == \"\" {\n\t\t\tfmt.Printf(\"\\nMust specify the transaction ID\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\t\taction, err := newListenTXAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing listenTxAction: %v\", err)\n\t\t\treturn\n\t\t}\n\n\t\tdefer action.Terminate()\n\n\t\terr = action.invoke()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running listenTxAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getListenTXCmd() *cobra.Command {\n\tflags := listenTxCmd.Flags()\n\tcliconfig.InitChannelID(flags)\n\tcliconfig.InitTxID(flags)\n\tcliconfig.InitPeerURL(flags, \"\", \"The URL of the peer on which to listen for events, e.g. grpcs://localhost:7051\")\n\treturn listenTxCmd\n}\n\ntype listentxAction struct {\n\taction.Action\n\tinputEvent\n}\n\nfunc newListenTXAction(flags *pflag.FlagSet) (*listentxAction, error) {\n\taction := &listentxAction{inputEvent: inputEvent{done: make(chan bool)}}\n\terr := action.Initialize(flags)\n\treturn action, err\n}\n\nfunc (a *listentxAction) invoke() error {\n\n\teventHub, err := a.EventClient()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Printf(\"Registering TX event for TxID [%s]\\n\", cliconfig.Config().TxID())\n\n\treg, eventch, err := eventHub.RegisterTxStatusEvent(cliconfig.Config().TxID())\n\tif err != nil {\n\t\treturn errors.WithMessage(err, \"Error registering for block events\")\n\t}\n\tdefer eventHub.Unregister(reg)\n\n\tenterch := a.WaitForEnter()\n\tfmt.Println(\"Press <enter> to terminate\")\n\n\tselect {\n\tcase _, _ = <-enterch:\n\t\treturn nil\n\tcase event, ok := <-eventch:\n\t\tif !ok {\n\t\t\treturn errors.WithMessage(err, \"unexpected closed channel while waiting for tx status event\")\n\t\t}\n\t\tfmt.Printf(\"Received TX event. TxID: %s, Code: %s, Error: %s\\n\", event.TxID, event.TxValidationCode, err)\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/executor/executor.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage executor\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"sync\"\n\t\"time\"\n\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/executor/worker\"\n)\n\n// State is the state of the executor\ntype State uint8\n\nconst (\n\t// NEW indicates that the executor is new and has not been started yet\n\tNEW State = iota\n\n\t// STARTED indicates that the executor is up and running\n\tSTARTED\n\n\t// TERMINATED indicates that the executor has been shut down\n\tTERMINATED\n)\n\n// Executor maintains a pool of workers that execute Tasks in separate Go routines. The caller submits\n// a Task to the Executor, which is submitted to an available worker. If a worker is not available then\n// the task is queue until one becomes available. The Executor is useful for throttling requests in order\n// not to overload the application.\ntype Executor struct {\n\tname        string\n\tstate       State\n\ttasks       chan worker.Task\n\tterminating chan bool\n\tpool        *worker.Pool\n\twg          sync.WaitGroup\n}\n\n// NewConcurrent creates a new, concurrent executor with the given concurrency.\n// As tasks are submitted they are queued while waiting for a worker for execution.\n//\n// - name: The name of the executor (useful for debugging)\n// - concurrency: The concurrency, i.e. the number of workers executing concurrently\nfunc NewConcurrent(name string, concurrency uint16) *Executor {\n\treturn New(name, math.MaxInt16, worker.NewPool(name, concurrency))\n}\n\n// NewBoundedConcurrent creates a new, concurrent executor with the given concurrency\n// and queue length. As tasks are submitted they are queued while waiting for a worker for execution. Once the\n// number of queued tasks reaches the given queue length, the Submit operation will block until a worker becomes\n// available.\n//\n// - name: The name of the executor (useful for debugging)\n// - concurrency: The concurrency, i.e. the number of workers executing concurrently\n// - queueLength: The maximum number of tasks allowed to be queued while waiting for a worker\nfunc NewBoundedConcurrent(name string, concurrency uint16, queueLength uint16) *Executor {\n\treturn New(name, queueLength, worker.NewPool(name, concurrency))\n}\n\n// New creates a new, multi-threaded executor with the given options:\n// - name: The name of the executor (useful for debugging)\n// - queueLength: The maximum number of tasks allowed to be queued while waiting for a worker\n// \t\tIf queueSize == concurrency then the Submit() function will block until a worker becomes free,\n//\t\totherwise the task will be added to the queue and Submit() will not block.\n// pool - The worker pool\nfunc New(name string, queueLength uint16, pool *worker.Pool) *Executor {\n\treturn &Executor{\n\t\tname:        name,\n\t\tstate:       NEW,\n\t\tterminating: make(chan bool),\n\t\ttasks:       make(chan worker.Task, queueLength),\n\t\tpool:        pool,\n\t}\n}\n\n// Start starts the Executor\nfunc (e *Executor) Start() bool {\n\tif e.state != NEW {\n\t\treturn false\n\t}\n\n\t// Start the worker pool\n\te.pool.Start()\n\n\t// Start the task dispatcher\n\tgo e.dispatch()\n\n\te.state = STARTED\n\n\treturn true\n}\n\n// Submit submits a new task\nfunc (e *Executor) Submit(task worker.Task) error {\n\tif e.state != STARTED {\n\t\treturn fmt.Errorf(\"executor [%s] is not started\", e.name)\n\t}\n\n\t// Submit the task to the dispatcher\n\tcliconfig.Config().Logger().Debugf(\"Submit[%s] - submitting task...\\n\", e.name)\n\te.wg.Add(1)\n\te.tasks <- task\n\tcliconfig.Config().Logger().Debugf(\"...Submit[%s] - submitted task\\n\", e.name)\n\n\treturn nil\n}\n\n// SubmitDelayed submits a new task in the future\nfunc (e *Executor) SubmitDelayed(task worker.Task, delay time.Duration) error {\n\tif e.state != STARTED {\n\t\treturn fmt.Errorf(\"executor [%s] is not started\", e.name)\n\t}\n\n\tcliconfig.Config().Logger().Debugf(\"Submit[%s] - submitting task to execute in %s ...\\n\", e.name, delay)\n\n\te.wg.Add(1)\n\n\tgo func() {\n\t\t<-time.After(delay)\n\t\te.Submit(task)\n\t\te.wg.Done()\n\t}()\n\n\treturn nil\n}\n\n// Wait waits for all outstanding tasks to complete\nfunc (e *Executor) Wait() {\n\te.wg.Wait()\n}\n\n// Stop stops the executor.\n// - wait: If true then the call will block until all outstanding\n//   tasks have completed; otherwise the executor will shut down immediately\nfunc (e *Executor) Stop(wait bool) bool {\n\tif e.state != STARTED {\n\t\treturn false\n\t}\n\n\te.state = TERMINATED\n\n\tcliconfig.Config().Logger().Debugf(\"[%s] Stopping executor ...\\n\", e.name)\n\n\t// Wait for the dispatcher to purge its queue\n\te.wg.Wait()\n\n\tcliconfig.Config().Logger().Debugf(\"[%s] Stopping the dispatcher ...\\n\", e.name)\n\n\t// Stop the dispatcher\n\te.terminating <- true\n\n\tcliconfig.Config().Logger().Debugf(\"[%s] Stopping the worker pool ...\\n\", e.name)\n\n\t// Stop the worker pool\n\te.pool.Stop(wait)\n\n\tcliconfig.Config().Logger().Debugf(\"[%s] ... executor stopped.\\n\", e.name)\n\n\treturn true\n}\n\nfunc (e *Executor) dispatch() {\n\tfor {\n\t\tselect {\n\t\t// Wait for a task\n\t\tcase task := <-e.tasks:\n\t\t\te.pool.Submit(task)\n\t\t\te.wg.Done()\n\n\t\tcase <-e.terminating:\n\t\t\tcliconfig.Config().Logger().Debugf(\"[%s] ... executor dispatcher ended\\n\", e.name)\n\t\t\treturn\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/executor/worker/worker.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage worker\n\nimport (\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n)\n\n// State is the state of a Worker\ntype State uint8\n\nconst (\n\t// READY indicates that a worker is ready to accept a new task\n\tREADY State = iota\n\n\t// STOPPED indicates that the worker has terminated\n\tSTOPPED\n)\n\n// Task is the task that the Worker invokes\ntype Task interface {\n\tInvoke()\n}\n\n// Events receives event notifications from the worker\ntype Events interface {\n\t// StateChange indicates the new state of the worker\n\tStateChange(w *Worker, state State)\n\n\t// TaskStarted indicates that the given worker has started executing the given task\n\tTaskStarted(w *Worker, task Task)\n\n\t// TaskCompleted indicates that the given worker has completed the given task\n\tTaskCompleted(w *Worker, task Task)\n}\n\n// Worker invokes a Task\ntype Worker struct {\n\tname   string\n\tevents Events\n\ttask   chan Task\n\tdone   chan bool\n}\n\nfunc newWorker(name string, events Events) *Worker {\n\treturn &Worker{\n\t\tname:   name,\n\t\tevents: events,\n\t\ttask:   make(chan Task),\n\t\tdone:   make(chan bool),\n\t}\n}\n\n// Name returns the name of the worker (useful for debugging)\nfunc (w *Worker) Name() string {\n\treturn w.name\n}\n\n// Submit submits a task\nfunc (w *Worker) Submit(task Task) {\n\tw.task <- task\n}\n\nfunc (w *Worker) invoke(task Task) {\n\tcliconfig.Config().Logger().Debugf(\"Worker[%s].invoke ...\\n\", w.name)\n\tdefer w.events.TaskCompleted(w, task)\n\n\tw.events.TaskStarted(w, task)\n\ttask.Invoke()\n\tcliconfig.Config().Logger().Debugf(\"Worker[%s].invoke done.\\n\", w.name)\n}\n\n// Start starts the worker\nfunc (w *Worker) Start() {\n\tcliconfig.Config().Logger().Debugf(\"Worker[%s] starting...\\n\", w.name)\n\tgo func() {\n\t\tfor {\n\t\t\tcliconfig.Config().Logger().Debugf(\"Worker[%s] waiting for task...\\n\", w.name)\n\n\t\t\t// Inform the events that I'm available\n\t\t\tw.events.StateChange(w, READY)\n\n\t\t\tselect {\n\t\t\tcase task := <-w.task:\n\t\t\t\tw.invoke(task)\n\n\t\t\tcase <-w.done:\n\t\t\t\tw.events.StateChange(w, STOPPED)\n\t\t\t\tcliconfig.Config().Logger().Debugf(\"Worker[%s] stopped\\n\", w.name)\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n}\n\n// Stop stops the worker\nfunc (w *Worker) Stop() {\n\tcliconfig.Config().Logger().Debugf(\"Worker[%s] stopping...\\n\", w.name)\n\tw.done <- true\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/executor/worker/workerpool.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage worker\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n)\n\n// Pool contains a pool of workers that can each execute a Task\ntype Pool struct {\n\tname            string\n\tworkers         []*Worker\n\tavailableWorker chan *Worker\n\ttaskWg          sync.WaitGroup\n\twg              sync.WaitGroup\n}\n\n// NewPool creates a worker Pool with the given Factory\nfunc NewPool(name string, concurrency uint16) *Pool {\n\tpool := &Pool{\n\t\tname:            name,\n\t\tavailableWorker: make(chan *Worker, concurrency),\n\t\tworkers:         make([]*Worker, concurrency),\n\t}\n\n\t// Create the workers\n\tfor i := 0; i < int(concurrency); i++ {\n\t\tpool.workers[i] = newWorker(fmt.Sprintf(\"%s-%d\", name, i), pool)\n\t}\n\n\treturn pool\n}\n\n// Name returns the name of the pool\nfunc (p *Pool) Name() string {\n\treturn p.name\n}\n\n// Start starts the pool\nfunc (p *Pool) Start() {\n\tp.wg.Add(len(p.workers))\n\n\t// Start the workers\n\tfor _, w := range p.workers {\n\t\tw.Start()\n\t}\n}\n\n// Stop stops the pool and optionally waits until all tasks have completed\nfunc (p *Pool) Stop(wait bool) {\n\tcliconfig.Config().Logger().Debugf(\"[%s] Stopping worker pool ...\\n\", p.name)\n\n\tif wait {\n\t\t// Wait for all the tasks to complete\n\t\tcliconfig.Config().Logger().Debugf(\"[%s] ... waiting for tasks to complete ...\\n\", p.name)\n\t\tp.taskWg.Wait()\n\t} else {\n\t\tcliconfig.Config().Logger().Debugf(\"[%s] ... forcing all tasks to stop ...\\n\", p.name)\n\t}\n\n\t// Shut down the workers\n\tcliconfig.Config().Logger().Debugf(\"[%s] ... stopping workers ...\\n\", p.name)\n\tfor i := 0; i < len(p.workers); i++ {\n\t\tw := <-p.availableWorker\n\t\tw.Stop()\n\t}\n\n\t// Wait for all of the workers to stop\n\tp.wg.Wait()\n}\n\n// Submit submits a Task for execution\nfunc (p *Pool) Submit(task Task) {\n\tcliconfig.Config().Logger().Debugf(\"worker pool.Submit[%s] - waiting for available worker\\n\", p.name)\n\n\tp.taskWg.Add(1)\n\n\t// Wait for an available worker\n\tw := <-p.availableWorker\n\n\tcliconfig.Config().Logger().Debugf(\"worker pool.Submit[%s] - got worker [%s]. Submitting task...\\n\", p.name, w.Name())\n\n\t// Submit the task to the worker\n\tw.Submit(task)\n\n\tcliconfig.Config().Logger().Debugf(\"worker pool.Submit[%s] - submitted task to worker[%s]\\n\", p.name, w.Name())\n}\n\n// StateChange is invoked when the state of the Worker changes\nfunc (p *Pool) StateChange(w *Worker, state State) {\n\tswitch state {\n\tcase READY:\n\t\tp.availableWorker <- w\n\t\tbreak\n\n\tcase STOPPED:\n\t\tcliconfig.Config().Logger().Debugf(\"...Worker[%s] stopped\\n\", w.Name())\n\t\tp.wg.Done()\n\t\tbreak\n\n\tdefault:\n\t\tcliconfig.Config().Logger().Warnf(\"Unsupported worker state: %d\\n\", state)\n\t\tbreak\n\t}\n}\n\n// TaskStarted is invoked when the given Worker begins executing the given Task\nfunc (p *Pool) TaskStarted(w *Worker, task Task) {\n\t// Nothing to do\n}\n\n// TaskCompleted is invoked when the given Worker completed executing the given Task\nfunc (p *Pool) TaskCompleted(w *Worker, task Task) {\n\tp.taskWg.Done()\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/fabric-cli.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage main\n\nimport (\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/cmd\"\n)\n\nfunc main() {\n\tcmd.Execute()\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/go.mod",
    "content": "// Copyright SecureKey Technologies Inc. All Rights Reserved.\n//\n// SPDX-License-Identifier: Apache-2.0\n\nmodule github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli\n\nrequire (\n\tgithub.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5 // indirect\n\tgithub.com/golang/protobuf v1.3.2\n\tgithub.com/hyperledger/fabric-protos-go v0.0.0-20191121202242-f5500d5e3e85\n\tgithub.com/hyperledger/fabric-sdk-go v1.0.0-beta1.0.20200106161850-8f3d32c9d1a6\n\tgithub.com/inconshreveable/mousetrap v1.0.0 // indirect\n\tgithub.com/magiconair/properties v1.8.0 // indirect\n\tgithub.com/mitchellh/mapstructure v0.0.0-20180511142126-bb74f1db0675 // indirect\n\tgithub.com/pelletier/go-toml v1.2.0 // indirect\n\tgithub.com/pkg/errors v0.8.1\n\tgithub.com/prometheus/common v0.0.0-20180801064454-c7de2306084e // indirect\n\tgithub.com/prometheus/procfs v0.0.0-20180920065004-418d78d0b9a7 // indirect\n\tgithub.com/spf13/afero v1.1.1 // indirect\n\tgithub.com/spf13/cobra v0.0.3\n\tgithub.com/spf13/pflag v1.0.1\n\tgithub.com/stretchr/testify v1.3.0\n)\n\ngo 1.13\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/go.sum",
    "content": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ngithub.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg=\ngithub.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=\ngithub.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=\ngithub.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=\ngithub.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5 h1:PqZ3bA4yzwywivzk7PBQWngJp2/PAS0bWRZerKteicY=\ngithub.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=\ngithub.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=\ngithub.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=\ngithub.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=\ngithub.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=\ngithub.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/google/certificate-transparency-go v0.0.0-20180222191210-5ab67e519c93 h1:qdfmdGwtm13OVx+AxguOWUTbgmXGn2TbdUHipo3chMg=\ngithub.com/google/certificate-transparency-go v0.0.0-20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce h1:xdsDDbiBDQTKASoGEZ+pEmF1OnWuu8AQ9I8iNbHNeno=\ngithub.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=\ngithub.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=\ngithub.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=\ngithub.com/hyperledger/fabric-lib-go v1.0.0 h1:UL1w7c9LvHZUSkIvHTDGklxFv2kTeva1QI2emOVc324=\ngithub.com/hyperledger/fabric-lib-go v1.0.0/go.mod h1:H362nMlunurmHwkYqR5uHL2UDWbQdbfz74n8kbCFsqc=\ngithub.com/hyperledger/fabric-protos-go v0.0.0-20191121202242-f5500d5e3e85 h1:bNgEcCg5NVRWs/T+VUEfhgh5Olx/N4VB+0+ybW+oSuA=\ngithub.com/hyperledger/fabric-protos-go v0.0.0-20191121202242-f5500d5e3e85/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0=\ngithub.com/hyperledger/fabric-sdk-go v1.0.0-beta1.0.20200106161850-8f3d32c9d1a6 h1:oEdHFGkrXcfoJdXmxem5fCyXS23SdfHc2UPt5g8o6HM=\ngithub.com/hyperledger/fabric-sdk-go v1.0.0-beta1.0.20200106161850-8f3d32c9d1a6/go.mod h1:/s224b8NLvOJOCIqBvWd9O6u7GE33iuIOT6OfcTE1OE=\ngithub.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=\ngithub.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=\ngithub.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=\ngithub.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/miekg/pkcs11 v0.0.0-20190329070431-55f3fac3af27 h1:XA/VH+SzpYyukhgh7v2mTp8rZoKKITXR/x3FIizVEXs=\ngithub.com/miekg/pkcs11 v0.0.0-20190329070431-55f3fac3af27/go.mod h1:WCBAbTOdfhHhz7YXujeZMF7owC4tPb1naKFsgfUISjo=\ngithub.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v0.0.0-20180511142126-bb74f1db0675 h1:/rdJjIiKG5rRdwG5yxHmSE/7ZREjpyC0kL7GxGT/qJw=\ngithub.com/mitchellh/mapstructure v0.0.0-20180511142126-bb74f1db0675/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=\ngithub.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=\ngithub.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=\ngithub.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=\ngithub.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=\ngithub.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=\ngithub.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_golang v0.8.0 h1:1921Yw9Gc3iSc4VQh3PIoOqgPCZS7G/4xQNVUp8Mda8=\ngithub.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/common v0.0.0-20180518154759-7600349dcfe1/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=\ngithub.com/prometheus/common v0.0.0-20180801064454-c7de2306084e h1:n/3MEhJQjQxrOUCzh1Y3Re6aJUUWRp2M9+Oc3eVn/54=\ngithub.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=\ngithub.com/prometheus/procfs v0.0.0-20180705121852-ae68e2d4c00f/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.0-20180920065004-418d78d0b9a7 h1:NgR6WN8nQ4SmFC1sSUHY8SriLuWCZ6cCIQtH4vDZN3c=\ngithub.com/prometheus/procfs v0.0.0-20180920065004-418d78d0b9a7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/spf13/afero v1.1.0/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=\ngithub.com/spf13/afero v1.1.1 h1:Lt3ihYMlE+lreX1GS4Qw4ZsNpYQLxIXKBTEOXm3nt6I=\ngithub.com/spf13/afero v1.1.1/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=\ngithub.com/spf13/cast v1.2.0 h1:HHl1DSRbEQN2i8tJmtS6ViPyHx35+p51amrdsiTCrkg=\ngithub.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=\ngithub.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=\ngithub.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=\ngithub.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec h1:2ZXvIUGghLpdTVHR1UfvfrzoVlZaE/yOWC5LueIHZig=\ngithub.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=\ngithub.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4=\ngithub.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/spf13/viper v1.0.2 h1:Ncr3ZIuJn322w2k1qmzXDnkLAdQMlJqBa9kfAH+irso=\ngithub.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd h1:HuTn7WObtcDo9uEEU7rEqL0jYthdXAmZ6PP+meazmaU=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=\ngolang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190327125643-d831d65fe17d h1:XB2jc5XQ9uhizGTS2vWcN01bc4dI6z3C4KY5MQm8SS8=\ngoogle.golang.org/genproto v0.0.0-20190327125643-d831d65fe17d/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=\ngopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=\ngopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/printer/blockprinter.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage printer\n\nimport (\n\t\"encoding/base64\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"reflect\"\n\t\"strings\"\n\n\t\"github.com/golang/protobuf/proto\"\n\tfabriccmn \"github.com/hyperledger/fabric-protos-go/common\"\n\t\"github.com/hyperledger/fabric-protos-go/ledger/rwset/kvrwset\"\n\t\"github.com/hyperledger/fabric-protos-go/msp\"\n\tab \"github.com/hyperledger/fabric-protos-go/orderer\"\n\tpb \"github.com/hyperledger/fabric-protos-go/peer\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab\"\n\t\"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/core/common/ccprovider\"\n\t\"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/rwsetutil\"\n\tledgerUtil \"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/core/ledger/util\"\n\t\"github.com/pkg/errors\"\n)\n\nconst (\n\t// AnchorPeersKey is the key name for the AnchorPeers ConfigValue\n\tAnchorPeersKey = \"AnchorPeers\"\n\n\t// ReadersPolicyKey is the key used for the read policy\n\tReadersPolicyKey = \"Readers\"\n\n\t// WritersPolicyKey is the key used for the read policy\n\tWritersPolicyKey = \"Writers\"\n\n\t// AdminsPolicyKey is the key used for the read policy\n\tAdminsPolicyKey = \"Admins\"\n\n\t// MSPKey is the org key used for MSP configuration\n\tMSPKey = \"MSP\"\n\n\t// ConsensusTypeKey is the cb.ConfigItem type key name for the ConsensusType message\n\tConsensusTypeKey = \"ConsensusType\"\n\n\t// BatchSizeKey is the cb.ConfigItem type key name for the BatchSize message\n\tBatchSizeKey = \"BatchSize\"\n\n\t// BatchTimeoutKey is the cb.ConfigItem type key name for the BatchTimeout message\n\tBatchTimeoutKey = \"BatchTimeout\"\n\n\t// ChannelRestrictionsKey is the key name for the ChannelRestrictions message\n\tChannelRestrictionsKey = \"ChannelRestrictions\"\n\n\t// KafkaBrokersKey is the cb.ConfigItem type key name for the KafkaBrokers message\n\tKafkaBrokersKey = \"KafkaBrokers\"\n\n\t// ChannelCreationPolicyKey is the key for the ChannelCreationPolicy value\n\tChannelCreationPolicyKey = \"ChannelCreationPolicy\"\n\n\t// ConsortiumKey is the key for the cb.ConfigValue for the Consortium message\n\tConsortiumKey = \"Consortium\"\n\n\t// HashingAlgorithmKey is the cb.ConfigItem type key name for the HashingAlgorithm message\n\tHashingAlgorithmKey = \"HashingAlgorithm\"\n\n\t// BlockDataHashingStructureKey is the cb.ConfigItem type key name for the BlockDataHashingStructure message\n\tBlockDataHashingStructureKey = \"BlockDataHashingStructure\"\n\n\t// OrdererAddressesKey is the cb.ConfigItem type key name for the OrdererAddresses message\n\tOrdererAddressesKey = \"OrdererAddresses\"\n\n\t// ChannelGroupKey is the name of the channel group\n\tChannelGroupKey = \"Channel\"\n\n\t// CapabilitiesKey is the key for capabilities\n\tCapabilitiesKey = \"Capabilities\"\n\n\tcollectionSeparator = \"~\"\n)\n\n// Printer is used for printing various data structures\ntype Printer interface {\n\t// PrintBlockchainInfo outputs BlockchainInfo\n\tPrintBlockchainInfo(info *fabriccmn.BlockchainInfo)\n\n\t// PrintBlock outputs a Block\n\tPrintBlock(block *fabriccmn.Block)\n\n\t// PrintFilteredBlock outputs a Block\n\tPrintFilteredBlock(block *pb.FilteredBlock)\n\n\t// PrintChannels outputs the array of ChannelInfo\n\tPrintChannels(channels []*pb.ChannelInfo)\n\n\t// PrintChaincodes outputs the given array of ChaincodeInfo\n\tPrintChaincodes(chaincodes []*pb.ChaincodeInfo)\n\n\t// PrintProcessedTransaction outputs a ProcessedTransaction\n\tPrintProcessedTransaction(tx *pb.ProcessedTransaction)\n\n\t// PrintChaincodeData outputs ChaincodeData\n\tPrintChaincodeData(ccdata *ccprovider.ChaincodeData, collConfig *pb.CollectionConfigPackage)\n\n\t// PrintTxProposalResponses outputs the proposal responses\n\tPrintTxProposalResponses(responses []*fab.TransactionProposalResponse, payloadOnly bool)\n\n\t// PrintResponses outputs responses\n\tPrintResponses(response []*pb.Response)\n\n\t// PrintChaincodeEvent outputs a chaincode event\n\tPrintChaincodeEvent(event *fab.CCEvent)\n\n\t// PrintPeers outputs the array of Peers\n\tPrintPeers(peers []fab.Peer)\n\n\t// Print outputs a formatted string\n\tPrint(frmt string, vars ...interface{})\n}\n\n// BlockPrinter is an implementation of BlockPrinter\ntype BlockPrinter struct {\n\tprinter\n}\n\n// NewBlockPrinter returns a new Printer of the given OutputFormat and WriterType\nfunc NewBlockPrinter(format OutputFormat, writerType WriterType) *BlockPrinter {\n\treturn &BlockPrinter{\n\t\tprinter: *newPrinter(format, writerType),\n\t}\n}\n\n// NewBlockPrinterWithOpts returns a new Printer of the given OutputFormat and WriterType\nfunc NewBlockPrinterWithOpts(format OutputFormat, writerType WriterType, opts *FormatterOpts) *BlockPrinter {\n\treturn &BlockPrinter{\n\t\tprinter: *newPrinterWithOpts(format, writerType, opts),\n\t}\n}\n\n// PrintBlockchainInfo prints BlockchainInfo\nfunc (p *BlockPrinter) PrintBlockchainInfo(info *fabriccmn.BlockchainInfo) {\n\tif p.Formatter == nil {\n\t\tfmt.Printf(\"%s\\n\", info)\n\t\treturn\n\t}\n\n\tp.PrintHeader()\n\tp.Field(\"Height\", info.Height)\n\tp.Field(\"CurrentBlockHash\", Base64URLEncode(info.CurrentBlockHash))\n\tp.Field(\"PreviousBlockHash\", Base64URLEncode(info.PreviousBlockHash))\n\tp.PrintFooter()\n}\n\n// PrintBlock prints a Block\nfunc (p *BlockPrinter) PrintBlock(block *fabriccmn.Block) {\n\tif p.Formatter == nil {\n\t\tfmt.Printf(\"%s\\n\", block)\n\t\treturn\n\t}\n\n\tp.PrintHeader()\n\tp.Element(\"Header\")\n\tp.Field(\"Number\", block.Header.Number)\n\tp.Field(\"PreviousHash\", Base64URLEncode(block.Header.PreviousHash))\n\tp.Field(\"DataHash\", Base64URLEncode(block.Header.DataHash))\n\tp.ElementEnd()\n\n\tp.Element(\"Metadata\")\n\tp.PrintBlockMetadata(block.Metadata)\n\tp.ElementEnd()\n\n\tp.Element(\"Data\")\n\tp.Array(\"Data\")\n\tfor i := range block.Data.Data {\n\t\tp.Item(\"Envelope\", i)\n\t\tp.PrintEnvelope(ExtractEnvelopeOrPanic(block, i))\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n\tp.ElementEnd()\n\tp.PrintFooter()\n}\n\n// PrintFilteredBlock prints a FilteredBlock\nfunc (p *BlockPrinter) PrintFilteredBlock(block *pb.FilteredBlock) {\n\tif p.Formatter == nil {\n\t\tfmt.Printf(\"%s\\n\", block)\n\t\treturn\n\t}\n\n\tp.PrintHeader()\n\tp.Field(\"ChannelID\", block.ChannelId)\n\tp.Field(\"Number\", block.Number)\n\n\tp.Element(\"FilteredTransactions\")\n\tp.Array(\"FilteredTransactions\")\n\tfor _, tx := range block.FilteredTransactions {\n\t\tp.PrintFilteredTransaction(tx)\n\t}\n\tp.ArrayEnd()\n\tp.ElementEnd()\n\tp.PrintFooter()\n}\n\n// PrintChannels prints the array of ChannelInfo\nfunc (p *BlockPrinter) PrintChannels(channels []*pb.ChannelInfo) {\n\tif p.Formatter == nil {\n\t\tfmt.Printf(\"%s\\n\", channels)\n\t\treturn\n\t}\n\n\tp.PrintHeader()\n\tp.Array(\"Channels\")\n\tfor _, channel := range channels {\n\t\tp.Field(\"ChannelId\", channel.ChannelId)\n\t}\n\tp.ArrayEnd()\n\tp.PrintFooter()\n}\n\nfunc (p *BlockPrinter) PrintPeers(peers []fab.Peer) {\n\tif p.Formatter == nil {\n\t\tfmt.Printf(\"%s\\n\", peers)\n\t\treturn\n\t}\n\n\tp.PrintHeader()\n\tp.Array(\"Peers\")\n\tfor _, peer := range peers {\n\t\tp.Item(\"Peer\", peer.URL())\n\t\tp.PrintPeer(peer)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n\tp.PrintFooter()\n}\n\n// PrintChaincodes prints the array of ChaincodeInfo\nfunc (p *BlockPrinter) PrintChaincodes(chaincodes []*pb.ChaincodeInfo) {\n\tif p.Formatter == nil {\n\t\tfmt.Printf(\"%s\\n\", chaincodes)\n\t\treturn\n\t}\n\n\tp.PrintHeader()\n\tp.Array(\"\")\n\tfor _, ccInfo := range chaincodes {\n\t\tp.Item(\"ChaincodeInfo\", ccInfo.Name)\n\t\tp.PrintChaincodeInfo(ccInfo)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n\tp.PrintFooter()\n}\n\n// PrintProcessedTransaction prints a ProcessedTransaction\nfunc (p *BlockPrinter) PrintProcessedTransaction(tx *pb.ProcessedTransaction) {\n\tif p.Formatter == nil {\n\t\tfmt.Printf(\"%s\\n\", tx)\n\t\treturn\n\t}\n\n\tp.PrintHeader()\n\tp.Print(\"ValidationCode: %s\", pb.TxValidationCode(tx.ValidationCode))\n\tp.PrintEnvelope(tx.TransactionEnvelope)\n\tp.PrintFooter()\n}\n\n// PrintChaincodeData prints the given ChaincodeData\nfunc (p *BlockPrinter) PrintChaincodeData(ccData *ccprovider.ChaincodeData, collConfig *pb.CollectionConfigPackage) {\n\tif p.Formatter == nil {\n\t\tfmt.Printf(\"%s\\n\", ccData)\n\t\treturn\n\t}\n\n\tp.PrintHeader()\n\tp.doPrintChaincodeData(ccData)\n\tif collConfig != nil {\n\t\tp.doPrintCollConfig(collConfig)\n\t}\n\tp.PrintFooter()\n}\n\nfunc (p *BlockPrinter) doPrintChaincodeData(ccData *ccprovider.ChaincodeData) {\n\tp.Field(\"Id\", ccData.Id)\n\tp.Field(\"Name\", ccData.Name)\n\tp.Field(\"Version\", ccData.Version)\n\tp.Field(\"Escc\", ccData.Escc)\n\tp.Field(\"Vscc\", ccData.Vscc)\n\n\tcdsData := &ccprovider.CDSData{}\n\tunmarshalOrPanic(ccData.Data, cdsData)\n\tp.Element(\"Data\")\n\tp.PrintCDSData(cdsData)\n\tp.ElementEnd()\n\n\tpolicy := &fabriccmn.SignaturePolicyEnvelope{}\n\tunmarshalOrPanic(ccData.Policy, policy)\n\tp.Element(\"Policy\")\n\tp.PrintSignaturePolicyEnvelope(policy)\n\tp.ElementEnd()\n\n\tinstPolicy := &fabriccmn.SignaturePolicyEnvelope{}\n\tunmarshalOrPanic(ccData.InstantiationPolicy, instPolicy)\n\tp.Element(\"InstantiationPolicy\")\n\tp.PrintSignaturePolicyEnvelope(instPolicy)\n\tp.ElementEnd()\n}\n\nfunc (p *BlockPrinter) doPrintCollConfig(collConfig *pb.CollectionConfigPackage) {\n\tp.Array(\"CollectionConfig\")\n\tfor i, c := range collConfig.Config {\n\t\tp.Item(\"Config\", i)\n\t\tsc := c.GetStaticCollectionConfig()\n\t\tif sc == nil {\n\t\t\tp.Value(\"unknown config type\")\n\t\t\tcontinue\n\t\t}\n\t\tp.printStaticCollectionConfig(sc)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n}\n\nfunc (p *BlockPrinter) printStaticCollectionConfig(config *pb.StaticCollectionConfig) {\n\tp.Field(\"Name\", config.Name)\n\tp.Field(\"BlockToLive\", config.BlockToLive)\n\tp.Field(\"MaximumPeerCount\", config.MaximumPeerCount)\n\tp.Field(\"RequiredPeerCount\", config.RequiredPeerCount)\n\tp.Field(\"MemberOnlyRead\", config.MemberOnlyRead)\n\tp.Field(\"MemberOnlyWrite\", config.MemberOnlyWrite)\n\n\tp.Element(\"MemberOrgsPolicy\")\n\tp.PrintSignaturePolicyEnvelope(config.MemberOrgsPolicy.GetSignaturePolicy())\n\tp.ElementEnd()\n}\n\n// PrintTxProposalResponses prints the given transaction proposal responses\nfunc (p *BlockPrinter) PrintTxProposalResponses(responses []*fab.TransactionProposalResponse, payloadOnly bool) {\n\tif p.Formatter == nil {\n\t\tfor i, response := range responses {\n\t\t\tfmt.Printf(\"Response[%d]: %v\\n\", i, response)\n\t\t}\n\t\treturn\n\t}\n\n\tp.PrintHeader()\n\tp.Array(\"\")\n\tfor i, response := range responses {\n\t\tp.Item(\"Response\", i)\n\t\tp.PrintTxProposalResponse(response, payloadOnly)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n\tp.PrintFooter()\n}\n\n// PrintChaincodeEvent prints the given ChaincodeEvent\nfunc (p *BlockPrinter) PrintChaincodeEvent(event *fab.CCEvent) {\n\tif p.Formatter == nil {\n\t\tfmt.Printf(\"%v\\n\", event)\n\t\treturn\n\t}\n\n\tp.PrintHeader()\n\tp.Field(\"ChaincodeID\", event.ChaincodeID)\n\tp.Field(\"EventName\", event.EventName)\n\t//p.Field(\"ChannelID\", event.ChannelID)\n\tp.Field(\"TxID\", event.TxID)\n\tp.Field(\"Payload\", event.Payload)\n\tp.PrintFooter()\n}\n\n// PrintTxProposalResponse prints the TransactionProposalResponse\nfunc (p *BlockPrinter) PrintTxProposalResponse(response *fab.TransactionProposalResponse, payloadOnly bool) {\n\tif payloadOnly {\n\t\tif response.Status != http.StatusOK {\n\t\t\tp.Field(\"Err\", response.Status)\n\t\t} else if response.ProposalResponse == nil || response.ProposalResponse.Response == nil {\n\t\t\tp.Field(\"Response\", nil)\n\t\t} else {\n\t\t\tp.Field(\"Payload\", response.ProposalResponse.Response.Payload)\n\t\t}\n\t} else {\n\t\tp.Field(\"Endorser\", response.Endorser)\n\t\tp.Field(\"Status\", response.Status)\n\t\tp.Element(\"ProposalResponse\")\n\t\tp.PrintProposalResponse(response.ProposalResponse)\n\t\tp.ElementEnd()\n\t}\n}\n\n// PrintProposalResponse prints a ProposalResponse\nfunc (p *BlockPrinter) PrintProposalResponse(response *pb.ProposalResponse) {\n\tif response == nil {\n\t\treturn\n\t}\n\tp.Element(\"Response\")\n\tp.PrintResponse(response.Response)\n\tp.ElementEnd()\n\n\tprp := &pb.ProposalResponsePayload{}\n\tunmarshalOrPanic(response.Payload, prp)\n\n\tp.Element(\"ProposalResponsePayload\")\n\tp.PrintProposalResponsePayload(prp)\n\tp.ElementEnd()\n\n\tp.Element(\"Endorsement\")\n\tp.PrintEndorsement(response.Endorsement)\n\tp.ElementEnd()\n}\n\n// PrintResponses prints an array of Response\nfunc (p *BlockPrinter) PrintResponses(responses []*pb.Response) {\n\tif p.Formatter == nil {\n\t\tfor i, response := range responses {\n\t\t\tfmt.Printf(\"Response[%d]: %v\\n\", i, response)\n\t\t}\n\t\treturn\n\t}\n\n\tp.PrintHeader()\n\tp.Array(\"\")\n\tfor i, response := range responses {\n\t\tp.Item(\"Response\", i)\n\t\tp.PrintResponse(response)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n\tp.PrintFooter()\n}\n\n// PrintResponse prints the Response\nfunc (p *BlockPrinter) PrintResponse(response *pb.Response) {\n\tp.Field(\"Message\", response.Message)\n\tp.Field(\"Status\", response.Status)\n\tp.Field(\"Payload\", response.Payload)\n}\n\n// PrintCDSData prints the chaincode deployment spec data (CDSData)\nfunc (p *BlockPrinter) PrintCDSData(cdsData *ccprovider.CDSData) {\n\tp.Field(\"CodeHash\", Base64URLEncode(cdsData.CodeHash))\n\tp.Field(\"MetaDataHash\", Base64URLEncode(cdsData.MetaDataHash))\n}\n\n// PrintEnvelope prints the given Envelope\nfunc (p *BlockPrinter) PrintEnvelope(envelope *fabriccmn.Envelope) {\n\tp.Field(\"Signature\", envelope.Signature)\n\n\tpayload := ExtractPayloadOrPanic(envelope)\n\tp.Element(\"Payload\")\n\tp.PrintPayload(payload)\n\tp.ElementEnd()\n}\n\n// PrintPayload prints a Payload\nfunc (p *BlockPrinter) PrintPayload(payload *fabriccmn.Payload) {\n\tp.Element(\"Header\")\n\n\tchdr, err := UnmarshalChannelHeader(payload.Header.ChannelHeader)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tp.Element(\"ChannelHeader\")\n\tp.PrintChannelHeader(chdr)\n\tp.ElementEnd()\n\n\tsigHeader, err := GetSignatureHeader(payload.Header.SignatureHeader)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tp.Element(\"SignatureHeader\")\n\tp.PrintSignatureHeader(sigHeader)\n\tp.ElementEnd()\n\n\tp.ElementEnd() // Header\n\n\tp.Element(\"Data\")\n\tp.Field(\"Type\", fabriccmn.HeaderType(chdr.Type))\n\tp.PrintData(fabriccmn.HeaderType(chdr.Type), payload.Data)\n\tp.ElementEnd()\n}\n\n// PrintChannelHeader prints the ChannelHeader\nfunc (p *BlockPrinter) PrintChannelHeader(chdr *fabriccmn.ChannelHeader) {\n\tp.Field(\"Type\", fabriccmn.HeaderType(chdr.Type))\n\tp.Field(\"ChannelId\", chdr.ChannelId)\n\tp.Field(\"Epoch\", chdr.Epoch)\n\n\tccHdrExt := &pb.ChaincodeHeaderExtension{}\n\tunmarshalOrPanic(chdr.Extension, ccHdrExt)\n\tp.Element(\"Extension\")\n\tp.PrintChaincodeHeaderExtension(ccHdrExt)\n\tp.ElementEnd()\n\n\tp.Field(\"Timestamp\", chdr.Timestamp)\n\tp.Field(\"TxId\", chdr.TxId)\n\tp.Field(\"Version\", chdr.Version)\n}\n\n// PrintChaincodeHeaderExtension prints the ChaincodeHeaderExtension\nfunc (p *BlockPrinter) PrintChaincodeHeaderExtension(ccHdrExt *pb.ChaincodeHeaderExtension) {\n\tp.Element(\"ChaincodeId\")\n\tp.PrintChaincodeID(ccHdrExt.ChaincodeId)\n\tp.ElementEnd()\n}\n\n// PrintChaincodeID prints the ChaincodeID\nfunc (p *BlockPrinter) PrintChaincodeID(ccID *pb.ChaincodeID) {\n\tif ccID == nil {\n\t\treturn\n\t}\n\tp.Field(\"Name\", ccID.Name)\n\tp.Field(\"Version\", ccID.Version)\n\tp.Field(\"Path\", ccID.Path)\n}\n\n// PrintChaincodeInfo prints ChaincodeInfo\nfunc (p *BlockPrinter) PrintChaincodeInfo(ccInfo *pb.ChaincodeInfo) {\n\tp.Field(\"Name\", ccInfo.Name)\n\tp.Field(\"Path\", ccInfo.Path)\n\tp.Field(\"Version\", ccInfo.Version)\n\tp.Field(\"Escc\", ccInfo.Escc)\n\tp.Field(\"Vscc\", ccInfo.Vscc)\n\tp.Field(\"Input\", ccInfo.Input)\n}\n\n// PrintSignatureHeader prints a SignatureHeader\nfunc (p *BlockPrinter) PrintSignatureHeader(sigHdr *fabriccmn.SignatureHeader) {\n\tp.Field(\"Nonce\", sigHdr.Nonce)\n\tp.Field(\"Creator\", sigHdr.Creator)\n}\n\n// PrintData prints the block of data formatted according to the given HeaderType\nfunc (p *BlockPrinter) PrintData(headerType fabriccmn.HeaderType, data []byte) {\n\tif headerType == fabriccmn.HeaderType_CONFIG {\n\t\tenvelope := &fabriccmn.ConfigEnvelope{}\n\t\tif err := proto.Unmarshal(data, envelope); err != nil {\n\t\t\tpanic(errors.Errorf(\"Bad envelope: %v\", err))\n\t\t}\n\t\tp.Print(\"Config Envelope:\")\n\t\tp.PrintConfigEnvelope(envelope)\n\t} else if headerType == fabriccmn.HeaderType_CONFIG_UPDATE {\n\t\tenvelope := &fabriccmn.ConfigUpdateEnvelope{}\n\t\tif err := proto.Unmarshal(data, envelope); err != nil {\n\t\t\tpanic(errors.Errorf(\"Bad envelope: %v\", err))\n\t\t}\n\t\tp.Print(\"Config Update Envelope:\")\n\t\tp.PrintConfigUpdateEnvelope(envelope)\n\t} else if headerType == fabriccmn.HeaderType_ENDORSER_TRANSACTION {\n\t\ttx, err := GetTransaction(data)\n\t\tif err != nil {\n\t\t\tpanic(errors.Errorf(\"Bad envelope: %v\", err))\n\t\t}\n\t\tp.Print(\"Transaction:\")\n\t\tp.PrintTransaction(tx)\n\t} else {\n\t\tp.Field(\"Unsupported Envelope\", Base64URLEncode(data))\n\t}\n}\n\n// PrintConfigEnvelope prints the ConfigEnvelope\nfunc (p *BlockPrinter) PrintConfigEnvelope(envelope *fabriccmn.ConfigEnvelope) {\n\tp.Element(\"Config\")\n\tp.PrintConfig(envelope.Config)\n\tp.ElementEnd()\n\tp.Element(\"LastUpdate\")\n\tp.PrintEnvelope(envelope.LastUpdate)\n\tp.ElementEnd()\n}\n\n// PrintConfigUpdateEnvelope prints a ConfigUpdateEnvelope\nfunc (p *BlockPrinter) PrintConfigUpdateEnvelope(envelope *fabriccmn.ConfigUpdateEnvelope) {\n\tp.Array(\"Signatures\")\n\tfor i, sig := range envelope.Signatures {\n\t\tp.Item(\"Config Signature\", i)\n\t\tp.PrintConfigSignature(sig)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n\n\tconfigUpdate := &fabriccmn.ConfigUpdate{}\n\tif err := proto.Unmarshal(envelope.ConfigUpdate, configUpdate); err != nil {\n\t\tpanic(err)\n\t}\n\n\tp.Element(\"ConfigUpdate\")\n\tp.PrintConfigUpdate(configUpdate)\n\tp.ElementEnd()\n}\n\n// PrintTransaction prints a Transaction\nfunc (p *BlockPrinter) PrintTransaction(tx *pb.Transaction) {\n\tp.Array(\"Actions\")\n\tfor i, action := range tx.Actions {\n\t\tp.Item(\"Action\", i)\n\t\tp.PrintTXAction(action)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintFilteredTransaction prints a FilteredTransaction\nfunc (p *BlockPrinter) PrintFilteredTransaction(tx *pb.FilteredTransaction) {\n\tp.Field(\"Txid\", tx.GetTxid())\n\tp.Field(\"Type\", tx.GetType())\n\tp.Field(\"TxValidationCode\", tx.GetTxValidationCode())\n\tp.Element(\"ChaincodeEvents\")\n\tp.Array(\"ChaincodeEvents\")\n\ttxActions := tx.GetTransactionActions()\n\tif txActions != nil {\n\t\tfor _, ccAction := range txActions.ChaincodeActions {\n\t\t\tp.PrintFilteredCCAction(ccAction)\n\t\t}\n\t}\n\tp.ArrayEnd()\n\tp.ElementEnd()\n}\n\n// PrintTXAction prinbts a transaction action\nfunc (p *BlockPrinter) PrintTXAction(action *pb.TransactionAction) {\n\tp.Element(\"Header\")\n\n\tsigHeader, err := GetSignatureHeader(action.Header)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tp.PrintSignatureHeader(sigHeader)\n\tp.ElementEnd()\n\n\tp.Element(\"Payload\")\n\n\tchaPayload, err := GetChaincodeActionPayload(action.Payload)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tp.PrintChaincodeActionPayload(chaPayload)\n\tp.ElementEnd()\n}\n\n// PrintFilteredCCAction prinbts a chaincode action\nfunc (p *BlockPrinter) PrintFilteredCCAction(action *pb.FilteredChaincodeAction) {\n\tccEvent := action.GetChaincodeEvent()\n\tp.Field(\"Txid\", ccEvent.GetTxId())\n\tp.Field(\"ChaincodeId\", ccEvent.GetChaincodeId())\n\tp.Field(\"EventName\", ccEvent.GetEventName())\n\tp.Field(\"Payload\", ccEvent.GetPayload())\n}\n\n// PrintChaincodeActionPayload prints a ChaincodeActionPayload\nfunc (p *BlockPrinter) PrintChaincodeActionPayload(chaPayload *pb.ChaincodeActionPayload) {\n\n\tcpp := &pb.ChaincodeProposalPayload{}\n\terr := proto.Unmarshal(chaPayload.ChaincodeProposalPayload, cpp)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tp.Element(\"ChaincodeProposalPayload\")\n\tp.PrintChaincodeProposalPayload(cpp)\n\tp.ElementEnd()\n\n\tp.Element(\"Action\")\n\tp.PrintAction(chaPayload.Action)\n\tp.ElementEnd()\n}\n\n// PrintChaincodeProposalPayload prints a ChaincodeProposalPayload\nfunc (p *BlockPrinter) PrintChaincodeProposalPayload(cpp *pb.ChaincodeProposalPayload) {\n\tcis := &pb.ChaincodeInvocationSpec{}\n\terr := proto.Unmarshal(cpp.Input, cis)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tp.Element(\"Input\")\n\tp.PrintChaincodeInvocationSpec(cis)\n\tp.ElementEnd()\n\n\tp.Array(\"TransientMap\")\n\tfor key, value := range cpp.TransientMap {\n\t\tp.Item(\"Key\", key)\n\t\tp.Field(\"Value\", value)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintChaincodeInvocationSpec prints a ChaincodeProposalPayload\nfunc (p *BlockPrinter) PrintChaincodeInvocationSpec(cis *pb.ChaincodeInvocationSpec) {\n\tp.Element(\"ChaincodeSpec\")\n\tp.PrintChaincodeSpec(cis.ChaincodeSpec)\n\tp.ElementEnd()\n}\n\n// PrintAction prints a ChaincodeEndorsedAction\nfunc (p *BlockPrinter) PrintAction(action *pb.ChaincodeEndorsedAction) {\n\tp.Array(\"Endorsements\")\n\tfor i, endorsement := range action.Endorsements {\n\t\tp.Item(\"Endorsement\", i)\n\t\tp.PrintEndorsement(endorsement)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n\n\tprp := &pb.ProposalResponsePayload{}\n\tunmarshalOrPanic(action.ProposalResponsePayload, prp)\n\n\tp.Element(\"ProposalResponsePayload\")\n\tp.PrintProposalResponsePayload(prp)\n\tp.ElementEnd()\n}\n\n// PrintProposalResponsePayload prints a ProposalResponsePayload\nfunc (p *BlockPrinter) PrintProposalResponsePayload(prp *pb.ProposalResponsePayload) {\n\tp.Field(\"ProposalHash\", Base64URLEncode(prp.ProposalHash))\n\n\tchaincodeAction := &pb.ChaincodeAction{}\n\tunmarshalOrPanic(prp.Extension, chaincodeAction)\n\tp.Element(\"Extension\")\n\tp.PrintChaincodeAction(chaincodeAction)\n\tp.ElementEnd()\n}\n\n// PrintChaincodeAction prints a ChaincodeAction\nfunc (p *BlockPrinter) PrintChaincodeAction(chaincodeAction *pb.ChaincodeAction) {\n\tp.Element(\"Response\")\n\tp.PrintChaincodeResponse(chaincodeAction.Response)\n\tp.ElementEnd()\n\n\tp.Element(\"Results\")\n\tif len(chaincodeAction.Results) > 0 {\n\t\ttxRWSet := &rwsetutil.TxRwSet{}\n\t\tif err := txRWSet.FromProtoBytes(chaincodeAction.Results); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\n\t\tp.PrintTxReadWriteSet(txRWSet)\n\t}\n\tp.ElementEnd()\n\n\tp.Element(\"Events\")\n\tif len(chaincodeAction.Events) > 0 {\n\t\tchaincodeEvent := &pb.ChaincodeEvent{}\n\t\tunmarshalOrPanic(chaincodeAction.Events, chaincodeEvent)\n\t\tp.PrintChaincodeEventFromBlock(chaincodeEvent)\n\t}\n\tp.ElementEnd()\n}\n\n// PrintTxReadWriteSet prints a transaction read-write set (TxRwSet)\nfunc (p *BlockPrinter) PrintTxReadWriteSet(txRWSet *rwsetutil.TxRwSet) {\n\tp.Array(\"NsRWs\")\n\tfor i, nsRWSet := range txRWSet.NsRwSets {\n\t\tp.Item(\"TxRwSet\", i)\n\t\tp.PrintNsReadWriteSet(nsRWSet)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintNsReadWriteSet prints a namespaced read-write set (NsRwSet)\nfunc (p *BlockPrinter) PrintNsReadWriteSet(nsRWSet *rwsetutil.NsRwSet) {\n\tp.Field(\"NameSpace\", nsRWSet.NameSpace)\n\n\tp.Element(\"KvRwSet\")\n\tp.PrintKvRwSet(nsRWSet.KvRwSet, nsRWSet.NameSpace)\n\tp.ElementEnd()\n\n\tp.Element(\"CollHashedRwSets\")\n\tp.PrintCollHashedRwSets(nsRWSet.CollHashedRwSets)\n\tp.ElementEnd()\n}\n\n// PrintKvRwSet prints a key-value read-write set\nfunc (p *BlockPrinter) PrintKvRwSet(kvRWSet *kvrwset.KVRWSet, namespace string) {\n\tp.Array(\"Reads\")\n\tfor i, r := range kvRWSet.Reads {\n\t\tp.Item(\"Read\", i)\n\t\tp.PrintRead(r)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n\n\tp.Array(\"Writes\")\n\tfor i, w := range kvRWSet.Writes {\n\t\tp.Item(\"Write\", i)\n\t\tif namespace == \"lscc\" {\n\t\t\tp.PrintLSCCWrite(w)\n\t\t} else {\n\t\t\tp.PrintWrite(w)\n\t\t}\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n\n\tp.Array(\"RangeQueriesInfo\")\n\tfor i, rqi := range kvRWSet.RangeQueriesInfo {\n\t\tp.Item(\"RangeQueryInfo\", i)\n\t\tp.PrintRangeQueryInfo(rqi)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintCollHashedRwSets prints an array of collection hashed read-write set\nfunc (p *BlockPrinter) PrintCollHashedRwSets(collHashedRwSets []*rwsetutil.CollHashedRwSet) {\n\tp.Array(\"CollHashedRwSets\")\n\tfor i, w := range collHashedRwSets {\n\t\tp.Item(\"CollHashedRwSet\", i)\n\t\tp.PrintCollHashedRwSet(w)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintCollHashedRwSet prints a collection hashed read-write set\nfunc (p *BlockPrinter) PrintCollHashedRwSet(collHashedRwSet *rwsetutil.CollHashedRwSet) {\n\tp.Field(\"CollectionName\", collHashedRwSet.CollectionName)\n\tp.Field(\"PvtRwSetHash\", Base64URLEncode(collHashedRwSet.PvtRwSetHash))\n\n\tp.Element(\"HashedRwSet\")\n\tp.PrintHashedRwSet(collHashedRwSet.HashedRwSet)\n\tp.ElementEnd()\n}\n\n// PrintHashedRwSet prints a HashedRWSet\nfunc (p *BlockPrinter) PrintHashedRwSet(hashedRwSet *kvrwset.HashedRWSet) {\n\tp.PrintHashedReads(hashedRwSet.HashedReads)\n\tp.PrintHashedWrites(hashedRwSet.HashedWrites)\n}\n\n// PrintHashedReads prints an array of key-value read hashes (KVReadHash)\nfunc (p *BlockPrinter) PrintHashedReads(hashedReads []*kvrwset.KVReadHash) {\n\tp.Array(\"HashedReads\")\n\tfor i, r := range hashedReads {\n\t\tp.Item(\"HashedRead\", i)\n\t\tp.PrintHashedRead(r)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintHashedWrites prints an array of key-value write hashes (KVWriteHash)\nfunc (p *BlockPrinter) PrintHashedWrites(hashedWrites []*kvrwset.KVWriteHash) {\n\tp.Array(\"HashedWrites\")\n\tfor i, r := range hashedWrites {\n\t\tp.Item(\"HashedWrite\", i)\n\t\tp.PrintHashedWrite(r)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintHashedRead prints a key-value read hash (KVReadHash)\nfunc (p *BlockPrinter) PrintHashedRead(hashedRead *kvrwset.KVReadHash) {\n\tp.Field(\"KeyHash\", Base64URLEncode(hashedRead.KeyHash))\n\tp.PrintVersion(hashedRead.Version)\n}\n\n// PrintHashedWrite prints a key-value write hash (KVWriteHash)\nfunc (p *BlockPrinter) PrintHashedWrite(hashedWrite *kvrwset.KVWriteHash) {\n\tp.Field(\"KeyHash\", Base64URLEncode(hashedWrite.KeyHash))\n\tp.Field(\"ValueHash\", Base64URLEncode(hashedWrite.ValueHash))\n\tp.Field(\"IsDelete\", hashedWrite.IsDelete)\n}\n\n// PrintRangeQueryInfo prints a RangeQueryInfo\nfunc (p *BlockPrinter) PrintRangeQueryInfo(rqi *kvrwset.RangeQueryInfo) {\n\tp.Field(\"StartKey\", rqi.StartKey)\n\tp.Field(\"EndKey\", rqi.EndKey)\n\tp.Field(\"ItrExhausted\", rqi.ItrExhausted)\n\tp.Element(\"ReadsInfo\")\n\tp.PrintReadsInfo(rqi.ReadsInfo)\n\tp.ElementEnd()\n}\n\n// PrintReadsInfo prints a RangeQuery reads info\nfunc (p *BlockPrinter) PrintReadsInfo(ri interface{}) {\n\tswitch x := ri.(type) {\n\tcase *kvrwset.RangeQueryInfo_RawReads:\n\t\tp.PrintRawReads(x.RawReads)\n\tcase *kvrwset.RangeQueryInfo_ReadsMerkleHashes:\n\t\tp.PrintReadsMerkleHashes(x.ReadsMerkleHashes)\n\tcase nil:\n\tdefault:\n\t\tp.Print(\"unknown type: %v\", reflect.TypeOf(ri))\n\t}\n}\n\n// PrintRawReads prints QueryReads\nfunc (p *BlockPrinter) PrintRawReads(qr *kvrwset.QueryReads) {\n\tp.Array(\"QueryReads\")\n\tfor i, r := range qr.KvReads {\n\t\tp.Item(\"Read\", i)\n\t\tp.PrintRead(r)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintReadsMerkleHashes prints QueryReadsMerkleSummary\nfunc (p *BlockPrinter) PrintReadsMerkleHashes(qr *kvrwset.QueryReadsMerkleSummary) {\n\tp.Field(\"MaxDegree\", qr.MaxDegree)\n\tp.Field(\"MaxLevel\", qr.MaxLevel)\n\n\tp.Array(\"MaxLevelHashes\")\n\tfor i, r := range qr.MaxLevelHashes {\n\t\tp.ItemValue(\"Hash\", i, Base64URLEncode(r))\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintRead prints a\nfunc (p *BlockPrinter) PrintRead(r *kvrwset.KVRead) {\n\tp.Field(\"Key\", r.Key)\n\tp.Element(\"Version\")\n\tp.PrintVersion(r.Version)\n\tp.ElementEnd()\n}\n\n// PrintVersion print a Version\nfunc (p *BlockPrinter) PrintVersion(version *kvrwset.Version) {\n\tif version == nil {\n\t\treturn\n\t}\n\n\tp.Field(\"BlockNum\", version.BlockNum)\n\tp.Field(\"TxNum\", version.TxNum)\n}\n\n// PrintWrite prints a key-value write (KVWrite)\nfunc (p *BlockPrinter) PrintWrite(w *kvrwset.KVWrite) {\n\tp.Field(\"Key\", w.Key)\n\tp.Field(\"IsDelete\", w.IsDelete)\n\tp.Field(\"Value\", w.Value)\n}\n\n// PrintLSCCWrite prints a key-value write (KVWrite)\nfunc (p *BlockPrinter) PrintLSCCWrite(w *kvrwset.KVWrite) {\n\tp.Field(\"Key\", w.Key)\n\tp.Field(\"IsDelete\", w.IsDelete)\n\tif w.IsDelete {\n\t\treturn\n\t}\n\tif isCollectionConfigKey(w.Key) {\n\t\tp.printCollectionConfig(w.Value)\n\t} else {\n\t\tp.printChaincodeData(w.Value)\n\t}\n}\n\nfunc (p *BlockPrinter) printChaincodeData(value []byte) {\n\tchaincodeData := &ccprovider.ChaincodeData{}\n\tif err := proto.Unmarshal(value, chaincodeData); err != nil {\n\t\tfmt.Printf(\"Error unmarshalling chaincode data from lscc KV WriteSet: %s\", err)\n\t} else {\n\t\tp.Element(\"Value_ChaincodeData\")\n\t\tp.doPrintChaincodeData(chaincodeData)\n\t\tp.ElementEnd()\n\t}\n}\n\nfunc (p *BlockPrinter) printCollectionConfig(value []byte) {\n\tcp := &pb.CollectionConfigPackage{}\n\terr := proto.Unmarshal(value, cp)\n\tif err != nil {\n\t\tfmt.Printf(\"Error unmarshalling collection config from lscc KV WriteSet: %s\", err)\n\t\treturn\n\t}\n\tp.doPrintCollConfig(cp)\n}\n\n// PrintChaincodeResponse prints a response\nfunc (p *BlockPrinter) PrintChaincodeResponse(response *pb.Response) {\n\tp.Field(\"Message\", response.Message)\n\tp.Field(\"Status\", response.Status)\n\tp.Field(\"Payload\", response.Payload)\n}\n\n// PrintChaincodeEventFromBlock prints a ChaincodeEvent\nfunc (p *BlockPrinter) PrintChaincodeEventFromBlock(chaincodeEvent *pb.ChaincodeEvent) {\n\tp.Field(\"ChaincodeId\", chaincodeEvent.ChaincodeId)\n\tp.Field(\"EventName\", chaincodeEvent.EventName)\n\tp.Field(\"TxID\", chaincodeEvent.TxId)\n\tp.Field(\"Payload\", chaincodeEvent.Payload)\n}\n\n// PrintEndorsement prints an Endorsement\nfunc (p *BlockPrinter) PrintEndorsement(endorsement *pb.Endorsement) {\n\tp.Field(\"Endorser\", endorsement.Endorser)\n\tp.Field(\"Signature\", endorsement.Signature)\n}\n\n// PrintConfig prints a Config\nfunc (p *BlockPrinter) PrintConfig(config *fabriccmn.Config) {\n\tp.Field(\"Sequence\", config.Sequence)\n\tp.Element(\"ChannelGroup\")\n\tp.PrintConfigGroup(config.ChannelGroup)\n\tp.ElementEnd()\n}\n\n// PrintConfigGroup prints a ConfigGroup\nfunc (p *BlockPrinter) PrintConfigGroup(configGroup *fabriccmn.ConfigGroup) {\n\tif configGroup == nil {\n\t\treturn\n\t}\n\n\tp.Field(\"Version\", configGroup.Version)\n\tp.Field(\"ModPolicy\", configGroup.ModPolicy)\n\tp.Array(\"Groups\")\n\tfor key, grp := range configGroup.Groups {\n\t\tp.Item(\"Group\", key)\n\t\tp.PrintConfigGroup(grp)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n\n\tp.Array(\"Values\")\n\tfor key, val := range configGroup.Values {\n\t\tp.Item(\"Value\", key)\n\t\tp.PrintConfigValue(key, val)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n\n\tp.Array(\"Policies\")\n\tfor key, policy := range configGroup.Policies {\n\t\tp.Item(\"Policy\", key)\n\t\tp.PrintConfigPolicy(policy)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintConfigPolicy prints a ConfigPolicy\nfunc (p *BlockPrinter) PrintConfigPolicy(policy *fabriccmn.ConfigPolicy) {\n\tp.Field(\"ModPolicy\", policy.ModPolicy)\n\tp.Field(\"Version\", policy.Version)\n\n\tif policy.Policy == nil {\n\t\treturn\n\t}\n\n\tpolicyType := fabriccmn.Policy_PolicyType(policy.Policy.Type)\n\tswitch policyType {\n\tcase fabriccmn.Policy_SIGNATURE:\n\t\tsigPolicyEnv := &fabriccmn.SignaturePolicyEnvelope{}\n\t\tunmarshalOrPanic(policy.Policy.Value, sigPolicyEnv)\n\t\tp.Field(\"Type\", \"SIGNATURE\")\n\t\tp.PrintSignaturePolicyEnvelope(sigPolicyEnv)\n\t\tbreak\n\n\tcase fabriccmn.Policy_MSP:\n\t\tp.Field(\"Type\", \"MSP\")\n\t\tp.Print(\"!!!!!!! Don't know how to Print MSP policy\")\n\t\tbreak\n\n\tcase fabriccmn.Policy_IMPLICIT_META:\n\t\timpMetaPolicy := &fabriccmn.ImplicitMetaPolicy{}\n\t\tunmarshalOrPanic(policy.Policy.Value, impMetaPolicy)\n\t\tp.Field(\"Type\", \"IMPLICIT_META\")\n\t\tp.PrintImplicitMetaPolicy(impMetaPolicy)\n\t\tbreak\n\n\tdefault:\n\t\tbreak\n\t}\n}\n\n// PrintCapabilities prints capabilities\nfunc (p *BlockPrinter) PrintCapabilities(capabilities *fabriccmn.Capabilities) {\n\tfor capability := range capabilities.Capabilities {\n\t\tp.Field(\"Capability\", capability)\n\t}\n}\n\n// PrintImplicitMetaPolicy prints an ImplicitMetaPolicy\nfunc (p *BlockPrinter) PrintImplicitMetaPolicy(impMetaPolicy *fabriccmn.ImplicitMetaPolicy) {\n\tp.Field(\"Rule\", impMetaPolicy.Rule)\n\tp.Field(\"Sub-policy\", impMetaPolicy.SubPolicy)\n}\n\n// PrintSignaturePolicyEnvelope prints a SignaturePolicyEnvelope\nfunc (p *BlockPrinter) PrintSignaturePolicyEnvelope(sigPolicyEnv *fabriccmn.SignaturePolicyEnvelope) {\n\tp.Element(\"Rule\")\n\tp.PrintSignaturePolicy(sigPolicyEnv.Rule)\n\tp.ElementEnd()\n\n\tp.Array(\"Identities\")\n\tfor i, identity := range sigPolicyEnv.Identities {\n\t\tp.Item(\"Identity\", i)\n\t\tp.PrintMSPPrincipal(identity)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintMSPPrincipal prints a MSPPrincipal\nfunc (p *BlockPrinter) PrintMSPPrincipal(principal *msp.MSPPrincipal) {\n\tp.Field(\"PrincipalClassification\", principal.PrincipalClassification)\n\tp.Element(\"Principal\")\n\tswitch principal.PrincipalClassification {\n\tcase msp.MSPPrincipal_ROLE:\n\t\t// Principal contains the msp role\n\t\tmspRole := &msp.MSPRole{}\n\t\tunmarshalOrPanic(principal.Principal, mspRole)\n\t\tp.Field(\"Role\", mspRole.Role)\n\t\tp.Field(\"MspIdentifier\", mspRole.MspIdentifier)\n\tcase msp.MSPPrincipal_IDENTITY:\n\t\tp.Value(principal.Principal)\n\tcase msp.MSPPrincipal_ORGANIZATION_UNIT:\n\t\t// Principal contains the OrganizationUnit\n\t\tunit := &msp.OrganizationUnit{}\n\t\tunmarshalOrPanic(principal.Principal, unit)\n\n\t\tp.Field(\"MspIdentifier\", unit.MspIdentifier)\n\t\tp.Field(\"OrganizationalUnitIdentifier\", unit.OrganizationalUnitIdentifier)\n\t\tp.Field(\"CertifiersIdentifier\", unit.CertifiersIdentifier)\n\tdefault:\n\t\tp.Value(\"unknown PrincipalClassification\")\n\t}\n\tp.ElementEnd()\n}\n\n// PrintSignaturePolicy prints a SignaturePolicy\nfunc (p *BlockPrinter) PrintSignaturePolicy(sigPolicy *fabriccmn.SignaturePolicy) {\n\tswitch t := sigPolicy.Type.(type) {\n\tcase *fabriccmn.SignaturePolicy_SignedBy:\n\t\tp.Field(\"Type\", \"SignedBy\")\n\t\tp.PrintSignaturePolicySignedBy(t)\n\tcase *fabriccmn.SignaturePolicy_NOutOf_:\n\t\tp.Field(\"Type\", \"NOutOf\")\n\t\tp.PrintSignaturePolicyNOutOf(t.NOutOf)\n\tdefault:\n\t\tp.Print(\"!!!!!!! Don't know how to print signature policy: %s\", t)\n\t}\n}\n\n// PrintSignaturePolicySignedBy prints a SignaturePolicy_SignedBy policy\nfunc (p *BlockPrinter) PrintSignaturePolicySignedBy(sigPolicy *fabriccmn.SignaturePolicy_SignedBy) {\n\tp.Field(\"SignedBy\", sigPolicy.SignedBy)\n}\n\n// PrintSignaturePolicyNOutOf prints a SignaturePolicy_NOutOf policy\nfunc (p *BlockPrinter) PrintSignaturePolicyNOutOf(sigPolicy *fabriccmn.SignaturePolicy_NOutOf) {\n\tp.Field(\"N\", sigPolicy.N)\n\tp.Array(\"Rules\")\n\tfor i, policy := range sigPolicy.Rules {\n\t\tp.Item(\"Rule\", i)\n\t\tp.PrintSignaturePolicy(policy)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintConfigValue prints a ConfigValue\nfunc (p *BlockPrinter) PrintConfigValue(name string, value *fabriccmn.ConfigValue) {\n\tp.Field(\"Version\", value.Version)\n\tp.Field(\"ModPolicy\", value.ModPolicy)\n\n\tswitch name {\n\tcase AnchorPeersKey:\n\t\tanchorPeers := &pb.AnchorPeers{}\n\t\tunmarshalOrPanic(value.Value, anchorPeers)\n\t\tp.Element(\"AnchorPeers\")\n\t\tp.PrintAnchorPeers(anchorPeers)\n\t\tp.ElementEnd()\n\t\tbreak\n\n\tcase MSPKey:\n\t\tmspConfig := &msp.MSPConfig{}\n\t\tunmarshalOrPanic(value.Value, mspConfig)\n\t\tp.Element(\"MSPConfig\")\n\t\tp.PrintMSPConfig(mspConfig)\n\t\tp.ElementEnd()\n\t\tbreak\n\n\tcase ConsensusTypeKey:\n\t\tconsensusType := &ab.ConsensusType{}\n\t\tunmarshalOrPanic(value.Value, consensusType)\n\t\tp.Field(\"ConsensusType\", consensusType.Type)\n\t\tbreak\n\n\tcase BatchSizeKey:\n\t\tbatchSize := &ab.BatchSize{}\n\t\tunmarshalOrPanic(value.Value, batchSize)\n\t\tp.Element(\"BatchSize\")\n\t\tp.PrintBatchSize(batchSize)\n\t\tp.ElementEnd()\n\t\tbreak\n\n\tcase BatchTimeoutKey:\n\t\tbatchTimeout := &ab.BatchTimeout{}\n\t\tunmarshalOrPanic(value.Value, batchTimeout)\n\t\tp.Field(\"Timeout\", batchTimeout.Timeout)\n\t\tbreak\n\n\tcase ChannelRestrictionsKey:\n\t\tchRestrictions := &ab.ChannelRestrictions{}\n\t\tunmarshalOrPanic(value.Value, chRestrictions)\n\t\tp.Element(\"ChannelRestrictions\")\n\t\tp.Field(\"MaxCount\", chRestrictions.MaxCount)\n\t\tp.ElementEnd()\n\t\tbreak\n\n\tcase ChannelCreationPolicyKey:\n\t\tcreationPolicy := &fabriccmn.ConfigPolicy{}\n\t\tunmarshalOrPanic(value.Value, creationPolicy)\n\t\tp.Element(\"ChannelCreationPolicy\")\n\t\tp.PrintConfigPolicy(creationPolicy)\n\t\tp.ElementEnd()\n\t\tbreak\n\n\t// case ChainCreationPolicyNamesKey:\n\t// \tchainCreationPolicyNames := &ab.ChainCreationPolicyNames{}\n\t// \tunmarshalOrPanic(value.Value, chainCreationPolicyNames)\n\t// \tp.Print(\"ChainCreationPolicyNames\")\n\t// \tp.Field(\"Names\", chainCreationPolicyNames.Names)\n\t// \tbreak\n\n\tcase HashingAlgorithmKey:\n\t\thashingAlgorithm := &fabriccmn.HashingAlgorithm{}\n\t\tunmarshalOrPanic(value.Value, hashingAlgorithm)\n\t\tp.Element(\"HashingAlgorithm\")\n\t\tp.Field(\"Name\", hashingAlgorithm.Name)\n\t\tp.ElementEnd()\n\t\tbreak\n\n\tcase BlockDataHashingStructureKey:\n\t\thashingStructure := &fabriccmn.BlockDataHashingStructure{}\n\t\tunmarshalOrPanic(value.Value, hashingStructure)\n\t\tp.Element(\"BlockDataHashingStructure\")\n\t\tp.Field(\"Width\", hashingStructure.Width)\n\t\tp.ElementEnd()\n\t\tbreak\n\n\tcase OrdererAddressesKey:\n\t\taddresses := &fabriccmn.OrdererAddresses{}\n\t\tunmarshalOrPanic(value.Value, addresses)\n\t\tp.Element(\"OrdererAddresses\")\n\t\tp.Field(\"Addresses\", addresses.Addresses)\n\t\tp.ElementEnd()\n\t\tbreak\n\n\tcase ConsortiumKey:\n\t\tconsortium := &fabriccmn.Consortium{}\n\t\tunmarshalOrPanic(value.Value, consortium)\n\t\tp.Element(\"Consortium\")\n\t\tp.Field(\"Name\", consortium.Name)\n\t\tp.ElementEnd()\n\t\tbreak\n\n\tcase CapabilitiesKey:\n\t\tcapabilities := &fabriccmn.Capabilities{}\n\t\tunmarshalOrPanic(value.Value, capabilities)\n\t\tp.Element(\"Capabilities\")\n\t\tp.PrintCapabilities(capabilities)\n\t\tp.ElementEnd()\n\t\tbreak\n\n\tdefault:\n\t\tp.Print(\"!!!!!!! Don't know how to Print config value: %s\", name)\n\t\tbreak\n\t}\n}\n\n// PrintBatchSize prints a BatchSize\nfunc (p *BlockPrinter) PrintBatchSize(batchSize *ab.BatchSize) {\n\tp.Field(\"MaxMessageCount\", batchSize.MaxMessageCount)\n\tp.Field(\"AbsoluteMaxBytes\", batchSize.AbsoluteMaxBytes)\n\tp.Field(\"PreferredMaxBytes\", batchSize.PreferredMaxBytes)\n}\n\n// ProviderType indicates the type of an identity provider\ntype ProviderType int\n\n// The ProviderType of a member relative to the member API\nconst (\n\tFABRIC ProviderType = iota // MSP is of FABRIC type\n\tIDEMIX                     // MSP is of IDEMIX type\n\tOTHER                      // MSP is of OTHER TYPE\n)\n\n// PrintMSPConfig prints a MSPConfig\nfunc (p *BlockPrinter) PrintMSPConfig(mspConfig *msp.MSPConfig) {\n\tswitch ProviderType(mspConfig.Type) {\n\tcase FABRIC:\n\t\tp.Print(\"Type: FABRIC\")\n\n\t\tconfig := &msp.FabricMSPConfig{}\n\t\tunmarshalOrPanic(mspConfig.Config, config)\n\n\t\tp.Print(\"Config:\")\n\t\tp.PrintFabricMSPConfig(config)\n\t\tbreak\n\n\tdefault:\n\t\tp.Print(\"Type: OTHER\")\n\t\tbreak\n\t}\n}\n\n// PrintFabricMSPConfig prints a FabricMSPConfig\nfunc (p *BlockPrinter) PrintFabricMSPConfig(mspConfig *msp.FabricMSPConfig) {\n\tp.Field(\"Name\", mspConfig.Name)\n\tp.Array(\"Admins\")\n\tfor i, admCert := range mspConfig.Admins {\n\t\tp.ItemValue(\"Admin Cert\", i, admCert)\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintAnchorPeers prints AnchorPeers\nfunc (p *BlockPrinter) PrintAnchorPeers(anchorPeers *pb.AnchorPeers) {\n\tp.Array(\"AnchorPeers\")\n\tfor i, anchorPeer := range anchorPeers.AnchorPeers {\n\t\tp.Item(\"Anchor Peer\", i)\n\t\tp.PrintAnchorPeer(anchorPeer)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintAnchorPeer prints an AnchorPeer\nfunc (p *BlockPrinter) PrintAnchorPeer(anchorPeer *pb.AnchorPeer) {\n\tp.Field(\"Host\", anchorPeer.Host)\n\tp.Field(\"Port\", anchorPeer.Port)\n}\n\n// PrintConfigSignature prints ConfigSignature\nfunc (p *BlockPrinter) PrintConfigSignature(sig *fabriccmn.ConfigSignature) {\n\tp.Field(\"Signature\", sig.Signature)\n\n\tsigHeader, err := GetSignatureHeader(sig.SignatureHeader)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tp.Element(\"SignatureHeader\")\n\tp.PrintSignatureHeader(sigHeader)\n\tp.ElementEnd()\n}\n\n// PrintConfigUpdate prints ConfigUpdate\nfunc (p *BlockPrinter) PrintConfigUpdate(configUpdate *fabriccmn.ConfigUpdate) {\n\tp.Field(\"ChannelId\", configUpdate.ChannelId)\n\tp.Element(\"ReadSet\")\n\tp.PrintConfigGroup(configUpdate.ReadSet)\n\tp.ElementEnd()\n\tp.Element(\"WriteSet\")\n\tp.PrintConfigGroup(configUpdate.WriteSet)\n\tp.ElementEnd()\n}\n\n// PrintBlockMetadata prints BlockMetadata\nfunc (p *BlockPrinter) PrintBlockMetadata(blockMetaData *fabriccmn.BlockMetadata) {\n\tp.PrintSignaturesMetadata(getMetadataOrPanic(blockMetaData, fabriccmn.BlockMetadataIndex_SIGNATURES))\n\tp.PrintLastConfigMetadata(getMetadataOrPanic(blockMetaData, fabriccmn.BlockMetadataIndex_LAST_CONFIG))\n\tp.PrintTransactionsFilterMetadata(ledgerUtil.TxValidationFlags(blockMetaData.Metadata[fabriccmn.BlockMetadataIndex_TRANSACTIONS_FILTER]))\n\tp.PrintOrdererMetadata(getMetadataOrPanic(blockMetaData, fabriccmn.BlockMetadataIndex_ORDERER))\n}\n\n// PrintSignaturesMetadata prints signature Metadata\nfunc (p *BlockPrinter) PrintSignaturesMetadata(metadata *fabriccmn.Metadata) {\n\tp.Array(\"Signatures\")\n\tfor i, metadataSignature := range metadata.Signatures {\n\t\tshdr, err := GetSignatureHeader(metadataSignature.SignatureHeader)\n\t\tif err != nil {\n\t\t\tpanic(errors.Errorf(\"Failed unmarshalling meta data signature header. Error: %v\", err))\n\t\t}\n\t\tp.Item(\"Metadata Signature\", i)\n\t\tp.PrintSignatureHeader(shdr)\n\t\tp.ItemEnd()\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintLastConfigMetadata prints last-config MetaData\nfunc (p *BlockPrinter) PrintLastConfigMetadata(metadata *fabriccmn.Metadata) {\n\tlastConfig := &fabriccmn.LastConfig{}\n\terr := proto.Unmarshal(metadata.Value, lastConfig)\n\tif err != nil {\n\t\tpanic(errors.Errorf(\"Failed unmarshalling meta data last config. Error: %v\", err))\n\t}\n\n\tp.Field(\"Last Config Index\", lastConfig.Index)\n}\n\n// PrintTransactionsFilterMetadata prints TxValidationFlags\nfunc (p *BlockPrinter) PrintTransactionsFilterMetadata(txFilter ledgerUtil.TxValidationFlags) {\n\tp.Array(\"TransactionFilters\")\n\tfor i := 0; i < len(txFilter); i++ {\n\t\tp.ItemValue(\"TxValidationFlag\", i, txFilter.Flag(i))\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintOrdererMetadata prints orderer Metadata\nfunc (p *BlockPrinter) PrintOrdererMetadata(metadata *fabriccmn.Metadata) {\n\tp.Field(\"Orderer Metadata\", metadata.Value)\n}\n\n// PrintChaincodeDeploymentSpec prints ChaincodeDeploymentSpec\nfunc (p *BlockPrinter) PrintChaincodeDeploymentSpec(depSpec *pb.ChaincodeDeploymentSpec) {\n\tp.Element(\"ChaincodeSpec\")\n\tp.PrintChaincodeSpec(depSpec.ChaincodeSpec)\n\tp.ElementEnd()\n}\n\n// PrintChaincodeSpec prints ChaincodeSpec\nfunc (p *BlockPrinter) PrintChaincodeSpec(ccSpec *pb.ChaincodeSpec) {\n\tp.Element(\"ChaincodeId\")\n\tp.PrintChaincodeID(ccSpec.ChaincodeId)\n\tp.ElementEnd()\n\n\tp.Field(\"Timeout\", ccSpec.Timeout)\n\tp.Field(\"Type\", ccSpec.Type)\n\n\tp.Element(\"Input\")\n\tp.PrintChaincodeInput(ccSpec.Input)\n\tp.ElementEnd()\n}\n\n// PrintChaincodeInput prints ChaincodeInput\nfunc (p *BlockPrinter) PrintChaincodeInput(ccInput *pb.ChaincodeInput) {\n\tp.Array(\"Args\")\n\tfor i, value := range ccInput.Args {\n\t\tp.ItemValue(\"Arg\", i, value)\n\t}\n\tp.ArrayEnd()\n\tp.Array(\"Decorations\")\n\tfor key, value := range ccInput.Decorations {\n\t\tp.ItemValue(\"Decoration\", key, value)\n\t}\n\tp.ArrayEnd()\n}\n\n// PrintPeer prints the peer\nfunc (p *BlockPrinter) PrintPeer(peer fab.Peer) {\n\tp.Field(\"URL\", peer.URL())\n\tp.Field(\"MSP\", peer.MSPID())\n\n\tpeerState, ok := peer.(fab.PeerState)\n\tif ok {\n\t\tp.Field(\"BlockHeight\", peerState.BlockHeight())\n\t}\n}\n\nfunc getMetadataOrPanic(blockMetaData *fabriccmn.BlockMetadata, index fabriccmn.BlockMetadataIndex) *fabriccmn.Metadata {\n\tmetaData := &fabriccmn.Metadata{}\n\terr := proto.Unmarshal(blockMetaData.Metadata[index], metaData)\n\tif err != nil {\n\t\tpanic(errors.Errorf(\"Unable to unmarshal meta data at index %d\", index))\n\t}\n\treturn metaData\n}\n\nfunc unmarshalOrPanic(buf []byte, pb proto.Message) {\n\terr := proto.Unmarshal(buf, pb)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n}\n\n// Base64URLEncode encodes the byte array into a base64 string\nfunc Base64URLEncode(data []byte) string {\n\treturn base64.RawURLEncoding.EncodeToString(data)\n}\n\n// Base64URLDecode decodes the base64 string into a byte array\nfunc Base64URLDecode(data string) ([]byte, error) {\n\t//check if it has padding or not\n\tif strings.HasSuffix(data, \"=\") {\n\t\treturn base64.URLEncoding.DecodeString(data)\n\t}\n\treturn base64.RawURLEncoding.DecodeString(data)\n}\n\n// isCollectionConfigKey detects if a key is a collection key\nfunc isCollectionConfigKey(key string) bool {\n\treturn strings.Contains(key, collectionSeparator)\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/printer/formatter.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage printer\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\n// OutputFormat specifies the format for printing data\ntype OutputFormat uint8\n\nconst (\n\t// RAW displays the raw data\n\tRAW OutputFormat = iota\n\n\t// JSON formats the data into Java Script Object Notation format\n\tJSON\n\n\t// DISPLAY formats the data into a human readable format\n\tDISPLAY\n)\n\nfunc (f OutputFormat) String() string {\n\tswitch f {\n\tcase DISPLAY:\n\t\treturn \"display\"\n\tcase JSON:\n\t\treturn \"json\"\n\tcase RAW:\n\t\treturn \"raw\"\n\tdefault:\n\t\treturn \"unknown\"\n\t}\n}\n\n// AsOutputFormat returns the OutputFormat given an Output Format string\nfunc AsOutputFormat(f string) OutputFormat {\n\tswitch strings.ToLower(f) {\n\tcase \"json\":\n\t\treturn JSON\n\tcase \"raw\":\n\t\treturn RAW\n\tdefault:\n\t\treturn DISPLAY\n\t}\n}\n\n// Formatter outputs the data in a specific format\ntype Formatter interface {\n\t// PrintHeader outputs a header\n\tPrintHeader()\n\n\t// PrintFooter outputs a footer\n\tPrintFooter()\n\n\t// Element starts an element\n\tElement(element string)\n\n\t// ElementEnd ends an element\n\tElementEnd()\n\n\t// Field outputs the value of a field\n\tField(field string, value interface{})\n\n\t// Array starts an array\n\tArray(element string)\n\n\t// ArrayEnd ends the array\n\tArrayEnd()\n\n\t// Item starts a complex array item\n\tItem(element string, index interface{})\n\n\t// ItemEnd ends an array item\n\tItemEnd()\n\n\t// ItemValue outputs a single array item\n\tItemValue(element string, index interface{}, value interface{})\n\n\t// Value outputs a value\n\tValue(value interface{})\n\n\t// Print outputs additional info\n\tPrint(frmt string, vars ...interface{})\n}\n\n// FormatterOpts contains options for the formatter\ntype FormatterOpts struct {\n\t// Base64Encode indicates whether binary values are to be encoded in base 64\n\tBase64Encode bool\n}\n\n// NewFormatter returns a new Formatter given the format and writer type. nil is returned\n// if no formatter exists for the given type\nfunc NewFormatter(format OutputFormat, writerType WriterType) Formatter {\n\treturn NewFormatterWithOpts(format, writerType, &FormatterOpts{})\n}\n\n// NewFormatterWithOpts returns a new Formatter given the format and writer type. nil is returned\n// if no formatter exists for the given type\nfunc NewFormatterWithOpts(format OutputFormat, writerType WriterType, opts *FormatterOpts) Formatter {\n\tswitch format {\n\tcase JSON:\n\t\treturn &jsonFormatter{formatter: formatter{writer: NewWriter(writerType)}}\n\tcase DISPLAY:\n\t\treturn &displayFormatter{formatter: formatter{writer: NewWriter(writerType)}, base64Encode: opts.Base64Encode}\n\tdefault:\n\t\treturn nil\n\t}\n}\n\ntype formatter struct {\n\twriter Writer\n}\n\nfunc (f *formatter) write(format string, a ...interface{}) error {\n\treturn f.writer.Write(format, a...)\n}\n\ntype displayFormatter struct {\n\tformatter\n\tindent       int\n\tbase64Encode bool\n}\n\nfunc (p *displayFormatter) Print(frmt string, vars ...interface{}) {\n\tformat := fmt.Sprintf(\"%s%s\\n\", p.prefix(), frmt)\n\tp.write(format, vars...)\n}\n\nfunc (p *displayFormatter) Field(field string, value interface{}) {\n\tif value != nil {\n\t\tp.write(\"%s%s: %v\\n\", p.prefix(), field, p.encodeValue(value))\n\t} else {\n\t\tp.write(\"%s%s:\\n\", p.prefix(), field)\n\t}\n}\n\nfunc (p *displayFormatter) Element(element string) {\n\tif element != \"\" {\n\t\tp.write(\"%s%s:\\n\", p.prefix(), element)\n\t}\n\tp.indent++\n}\n\nfunc (p *displayFormatter) ElementEnd() {\n\tp.indent--\n}\n\nfunc (p *displayFormatter) Array(element string) {\n\tif element != \"\" {\n\t\tp.write(\"%s%s:\\n\", p.prefix(), element)\n\t}\n\tp.indent++\n}\n\nfunc (p *displayFormatter) ArrayEnd() {\n\tp.indent--\n\n}\n\nfunc (p *displayFormatter) Item(element string, index interface{}) {\n\tif element != \"\" {\n\t\tp.write(\"%s%s[%v]:\\n\", p.prefix(), element, index)\n\t}\n\tp.indent++\n}\n\nfunc (p *displayFormatter) ItemEnd() {\n\tp.ElementEnd()\n}\n\nfunc (p *displayFormatter) ItemValue(element string, index interface{}, value interface{}) {\n\tif element != \"\" {\n\t\tp.write(\"%s%s[%v]: %v\\n\", p.prefix(), element, index, p.encodeValue(value))\n\t}\n}\n\nfunc (p *displayFormatter) Value(value interface{}) {\n\tp.write(\"%s%v\", p.prefix(), p.encodeValue(value))\n}\n\nfunc (p *displayFormatter) PrintHeader() {\n\tp.write(\"%s\\n\", strings.Repeat(\"*\", 100))\n}\n\nfunc (p *displayFormatter) PrintFooter() {\n\tp.write(\"%s\\n\", strings.Repeat(\"*\", 100))\n}\n\nfunc (p *displayFormatter) prefix() string {\n\ts := \"***** \"\n\tfor i := 0; i < p.indent; i++ {\n\t\ts = s + fmt.Sprintf(\"|%s\", strings.Repeat(\" \", indentSize-1))\n\t}\n\treturn s\n}\n\nfunc (p *displayFormatter) encodeValue(value interface{}) interface{} {\n\tswitch value.(type) {\n\tcase []byte:\n\t\tif p.base64Encode {\n\t\t\treturn Base64URLEncode(value.([]byte))\n\t\t}\n\t\treturn string(value.([]byte))\n\tdefault:\n\t\treturn value\n\t}\n}\n\ntype jsonFormatter struct {\n\tformatter\n\tcommaRequired bool\n}\n\nfunc (p *jsonFormatter) Print(frmt string, vars ...interface{}) {\n\t// Ignore additional output in JSON format\n}\n\nfunc (p *jsonFormatter) Field(field string, value interface{}) {\n\tif p.commaRequired {\n\t\tp.write(\",\")\n\t}\n\n\tif value != nil {\n\t\tp.write(\"\\\"%s\\\":\\\"%v\\\"\", field, p.encodeValue(value))\n\t} else {\n\t\tp.write(\"\\\"%s\\\":\\\"null\\\"\", field)\n\t}\n\n\tp.commaRequired = true\n}\n\nfunc (p *jsonFormatter) Element(element string) {\n\tif p.commaRequired {\n\t\tp.write(\",\")\n\t\tp.commaRequired = false\n\t}\n\tif element != \"\" {\n\t\tp.write(\"\\\"%s\\\":{\", element)\n\t} else {\n\t\tp.write(\"{\")\n\t}\n}\n\nfunc (p *jsonFormatter) ElementEnd() {\n\tp.write(\"}\")\n\tp.commaRequired = true\n}\n\nfunc (p *jsonFormatter) Array(element string) {\n\tif p.commaRequired {\n\t\tp.write(\",\")\n\t\tp.commaRequired = false\n\t}\n\tif element != \"\" {\n\t\tp.write(\"\\\"%s\\\":[\", element)\n\t} else {\n\t\tp.write(\"[\")\n\t}\n}\n\nfunc (p *jsonFormatter) ArrayEnd() {\n\tp.write(\"]\")\n\tp.commaRequired = true\n}\n\nfunc (p *jsonFormatter) Item(element string, index interface{}) {\n\tif p.commaRequired {\n\t\tp.write(\",\")\n\t\tp.commaRequired = false\n\t}\n\tp.write(\"{\")\n}\n\nfunc (p *jsonFormatter) ItemEnd() {\n\tp.ElementEnd()\n}\n\nfunc (p *jsonFormatter) ItemValue(element string, index interface{}, value interface{}) {\n\tif i, ok := index.(int); ok && i > 0 {\n\t\tp.commaRequired = true\n\t\tp.write(\",\")\n\t}\n\tp.write(\"\\\"%v\\\"\", p.encodeValue(value))\n}\n\nfunc (p *jsonFormatter) Value(value interface{}) {\n\tif p.commaRequired {\n\t\tp.write(\",\")\n\t}\n\tp.write(\"\\\"%v\\\"\", p.encodeValue(value))\n}\n\nfunc (p *jsonFormatter) PrintHeader() {\n\tp.Element(\"\")\n\tp.commaRequired = false\n}\n\nfunc (p *jsonFormatter) PrintFooter() {\n\tp.ElementEnd()\n\tp.write(\"\\n\")\n\tp.commaRequired = false\n}\n\nfunc (p *jsonFormatter) encodeValue(value interface{}) interface{} {\n\tswitch value.(type) {\n\tcase []byte:\n\t\treturn Base64URLEncode(value.([]byte))\n\tdefault:\n\t\treturn value\n\t}\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/printer/printer.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage printer\n\nimport \"fmt\"\n\nconst (\n\tindentSize = 3\n)\n\ntype printer struct {\n\tFormatter Formatter\n}\n\n// newPrinter returns a new Printer of the given OutputFormat and WriterType\nfunc newPrinter(format OutputFormat, writerType WriterType) *printer {\n\treturn &printer{Formatter: NewFormatter(format, writerType)}\n}\n\n// newPrinterWithOpts returns a new Printer of the given OutputFormat and WriterType\nfunc newPrinterWithOpts(format OutputFormat, writerType WriterType, opts *FormatterOpts) *printer {\n\treturn &printer{Formatter: NewFormatterWithOpts(format, writerType, opts)}\n}\n\n// Print prints a formatted string\nfunc (p *printer) Print(frmt string, vars ...interface{}) {\n\tif p.Formatter == nil {\n\t\tfmt.Printf(frmt, vars)\n\t\treturn\n\t}\n\tp.Formatter.Print(frmt, vars...)\n}\n\n// Field prints a field/value\nfunc (p *printer) Field(Field string, value interface{}) {\n\tp.Formatter.Field(Field, value)\n}\n\n// Element starts a new named element. (Should be followed by ElementEnd.)\nfunc (p *printer) Element(element string) {\n\tp.Formatter.Element(element)\n}\n\n// ElementEnd ends an element that was started with ElementStart.\nfunc (p *printer) ElementEnd() {\n\tp.Formatter.ElementEnd()\n}\n\n// Array starts an array. (Should be followed by ArrayEnd.)\nfunc (p *printer) Array(element string) {\n\tp.Formatter.Array(element)\n}\n\n// ArrayEnd ends an array that was started with Array.\nfunc (p *printer) ArrayEnd() {\n\tp.Formatter.ArrayEnd()\n}\n\n// Item starts an array item at the given index. (A previous call to Array must have been made.)\nfunc (p *printer) Item(element string, index interface{}) {\n\tp.Formatter.Item(element, index)\n}\n\n// ItemEnd ends an array item that was started with Item.\nfunc (p *printer) ItemEnd() {\n\tp.Formatter.ItemEnd()\n}\n\n// ItemValue prints an array value at the given index. (A previous call to Array must have been made.)\nfunc (p *printer) ItemValue(element string, index interface{}, value interface{}) {\n\tp.Formatter.ItemValue(element, index, value)\n}\n\n// Value prints a value.\nfunc (p *printer) Value(value interface{}) {\n\tp.Formatter.Value(value)\n}\n\n// PrintHeader prints a header.\nfunc (p *printer) PrintHeader() {\n\tp.Formatter.PrintHeader()\n}\n\n// PrintFooter prints a footer.\nfunc (p *printer) PrintFooter() {\n\tp.Formatter.PrintFooter()\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/printer/protoutils.go",
    "content": "/*\nCopyright IBM Corp. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage printer\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/golang/protobuf/proto\"\n\tcb \"github.com/hyperledger/fabric-protos-go/common\"\n\t\"github.com/hyperledger/fabric-protos-go/peer\"\n\t\"github.com/pkg/errors\"\n)\n\n// ExtractEnvelopeOrPanic retrieves the requested envelope from a given block\n// and unmarshals it -- it panics if either of these operations fail\nfunc ExtractEnvelopeOrPanic(block *cb.Block, index int) *cb.Envelope {\n\tenvelope, err := ExtractEnvelope(block, index)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn envelope\n}\n\n// ExtractEnvelope retrieves the requested envelope from a given block and\n// unmarshals it\nfunc ExtractEnvelope(block *cb.Block, index int) (*cb.Envelope, error) {\n\tif block.Data == nil {\n\t\treturn nil, errors.New(\"block data is nil\")\n\t}\n\n\tenvelopeCount := len(block.Data.Data)\n\tif index < 0 || index >= envelopeCount {\n\t\treturn nil, errors.New(\"envelope index out of bounds\")\n\t}\n\tmarshaledEnvelope := block.Data.Data[index]\n\tenvelope, err := GetEnvelopeFromBlock(marshaledEnvelope)\n\terr = errors.WithMessage(err, fmt.Sprintf(\"block data does not carry an envelope at index %d\", index))\n\treturn envelope, err\n}\n\n// GetEnvelopeFromBlock gets an envelope from a block's Data field.\nfunc GetEnvelopeFromBlock(data []byte) (*cb.Envelope, error) {\n\t// Block always begins with an envelope\n\tvar err error\n\tenv := &cb.Envelope{}\n\tif err = proto.Unmarshal(data, env); err != nil {\n\t\treturn nil, errors.Wrap(err, \"error unmarshaling Envelope\")\n\t}\n\n\treturn env, nil\n}\n\n// ExtractPayloadOrPanic retrieves the payload of a given envelope and\n// unmarshals it -- it panics if either of these operations fail\nfunc ExtractPayloadOrPanic(envelope *cb.Envelope) *cb.Payload {\n\tpayload, err := ExtractPayload(envelope)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn payload\n}\n\n// ExtractPayload retrieves the payload of a given envelope and unmarshals it.\nfunc ExtractPayload(envelope *cb.Envelope) (*cb.Payload, error) {\n\tpayload := &cb.Payload{}\n\terr := proto.Unmarshal(envelope.Payload, payload)\n\terr = errors.Wrap(err, \"no payload in envelope\")\n\treturn payload, err\n}\n\n// UnmarshalChannelHeader returns a ChannelHeader from bytes\nfunc UnmarshalChannelHeader(bytes []byte) (*cb.ChannelHeader, error) {\n\tchdr := &cb.ChannelHeader{}\n\terr := proto.Unmarshal(bytes, chdr)\n\treturn chdr, errors.Wrap(err, \"error unmarshaling ChannelHeader\")\n}\n\n// GetSignatureHeader Get SignatureHeader from bytes\nfunc GetSignatureHeader(bytes []byte) (*cb.SignatureHeader, error) {\n\tsh := &cb.SignatureHeader{}\n\terr := proto.Unmarshal(bytes, sh)\n\treturn sh, errors.Wrap(err, \"error unmarshaling SignatureHeader\")\n}\n\n// GetTransaction Get Transaction from bytes\nfunc GetTransaction(txBytes []byte) (*peer.Transaction, error) {\n\ttx := &peer.Transaction{}\n\terr := proto.Unmarshal(txBytes, tx)\n\treturn tx, errors.Wrap(err, \"error unmarshaling Transaction\")\n\n}\n\n// GetChaincodeActionPayload Get ChaincodeActionPayload from bytes\nfunc GetChaincodeActionPayload(capBytes []byte) (*peer.ChaincodeActionPayload, error) {\n\tcap := &peer.ChaincodeActionPayload{}\n\terr := proto.Unmarshal(capBytes, cap)\n\treturn cap, errors.Wrap(err, \"error unmarshaling ChaincodeActionPayload\")\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/printer/writer.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage printer\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\tconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n)\n\n// WriterType specifies the format for printing data\ntype WriterType uint8\n\nconst (\n\t// STDOUT writes to standard out\n\tSTDOUT WriterType = iota\n\n\t// STDERR writes to standard error\n\tSTDERR\n\n\t// LOG writes to the logger\n\tLOG\n)\n\nconst (\n\tstdout = \"stdout\"\n\tstderr = \"stderr\"\n\tlog    = \"log\"\n)\n\nfunc (f WriterType) String() string {\n\tswitch f {\n\tcase STDOUT:\n\t\treturn stdout\n\tcase STDERR:\n\t\treturn stderr\n\tcase LOG:\n\t\treturn log\n\tdefault:\n\t\treturn \"unknown\"\n\t}\n}\n\n// AsWriterType returns the WriterType given a Writer Type string\nfunc AsWriterType(t string) WriterType {\n\tswitch strings.ToLower(t) {\n\tcase log:\n\t\treturn LOG\n\tcase stderr:\n\t\treturn STDERR\n\tdefault:\n\t\treturn STDOUT\n\t}\n}\n\n// Writer writes the output\ntype Writer interface {\n\tWrite(format string, a ...interface{}) error\n}\n\n// NewWriter returns a new writer given the writer type\nfunc NewWriter(writerType WriterType) Writer {\n\tswitch writerType {\n\tcase STDERR:\n\t\treturn &stdErrWriter{}\n\tcase LOG:\n\t\treturn &logWriter{}\n\tdefault:\n\t\treturn &stdOutWriter{}\n\t}\n}\n\ntype stdOutWriter struct {\n}\n\nfunc (w *stdOutWriter) Write(format string, a ...interface{}) error {\n\t_, err := fmt.Fprintf(os.Stdout, format, a...)\n\treturn err\n}\n\ntype stdErrWriter struct {\n}\n\nfunc (w *stdErrWriter) Write(format string, a ...interface{}) error {\n\t_, err := fmt.Fprintf(os.Stderr, format, a...)\n\treturn err\n}\n\ntype logWriter struct {\n}\n\nfunc (w *logWriter) Write(format string, a ...interface{}) error {\n\tconfig.Config().Logger().Infof(format, a...)\n\treturn nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/query/queryblockcmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage query\n\nimport (\n\t\"encoding/base64\"\n\t\"strings\"\n\n\tfabricCommon \"github.com/hyperledger/fabric-protos-go/common\"\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/ledger\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar queryBlockCmd = &cobra.Command{\n\tUse:   \"block\",\n\tShort: \"Query block\",\n\tLong:  \"Queries a block\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\taction, err := newQueryBlockAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing queryBlockAction: %v\", err)\n\t\t\treturn\n\t\t}\n\n\t\tdefer action.Terminate()\n\n\t\terr = action.invoke()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running queryBlockAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getQueryBlockCmd() *cobra.Command {\n\tflags := queryBlockCmd.Flags()\n\tcliconfig.InitChannelID(flags)\n\tcliconfig.InitBlockNum(flags)\n\tcliconfig.InitBlockHash(flags)\n\tcliconfig.InitTraverse(flags)\n\tcliconfig.InitPeerURL(flags, \"\", \"The URL of the peer on which to install the chaincode, e.g. grpcs://localhost:7051\")\n\treturn queryBlockCmd\n}\n\ntype queryBlockAction struct {\n\taction.Action\n}\n\nfunc newQueryBlockAction(flags *pflag.FlagSet) (*queryBlockAction, error) {\n\taction := &queryBlockAction{}\n\terr := action.Initialize(flags)\n\treturn action, err\n}\n\nfunc (a *queryBlockAction) invoke() error {\n\tledgerClient, err := a.LedgerClient()\n\tif err != nil {\n\t\treturn errors.Errorf(\"Error getting admin channel client: %v\", err)\n\t}\n\n\tvar block *fabricCommon.Block\n\tif cliconfig.IsFlagSet(cliconfig.BlockNumFlag) {\n\t\tvar err error\n\t\tblock, err = ledgerClient.QueryBlock(cliconfig.Config().BlockNum())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if cliconfig.IsFlagSet(cliconfig.BlockHashFlag) {\n\t\tvar err error\n\n\t\thashBytes, err := Base64URLDecode(cliconfig.Config().BlockHash())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tblock, err = ledgerClient.QueryBlockByHash(hashBytes)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\treturn errors.Errorf(\"must specify either a block number of a block hash\")\n\t}\n\n\ta.Printer().PrintBlock(block)\n\n\ta.traverse(ledgerClient, block, cliconfig.Config().Traverse()-1)\n\n\treturn nil\n}\n\nfunc (a *queryBlockAction) traverse(ledgerClient *ledger.Client, currentBlock *fabricCommon.Block, num int) error {\n\tif num <= 0 {\n\t\treturn nil\n\t}\n\n\tblock, err := ledgerClient.QueryBlockByHash(currentBlock.Header.PreviousHash)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ta.Printer().PrintBlock(block)\n\n\tif block.Header.PreviousHash != nil {\n\t\treturn a.traverse(ledgerClient, block, num-1)\n\t}\n\treturn nil\n}\n\n// Base64URLDecode decodes the base64 string into a byte array\nfunc Base64URLDecode(data string) ([]byte, error) {\n\t//check if it has padding or not\n\tif strings.HasSuffix(data, \"=\") {\n\t\treturn base64.URLEncoding.DecodeString(data)\n\t}\n\treturn base64.RawURLEncoding.DecodeString(data)\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/query/querychannelscmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage query\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar queryChannelsCmd = &cobra.Command{\n\tUse:   \"channels\",\n\tShort: \"Query channels\",\n\tLong:  \"Queries the channels of the specified peer\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\taction, err := newQueryChannelsAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing queryChannelsAction: %v\", err)\n\t\t\treturn\n\t\t}\n\t\tdefer action.Terminate()\n\n\t\tif len(cliconfig.Config().PeerURLs()) != 1 {\n\t\t\tfmt.Printf(\"\\nMust specify exactly one peer URL\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\n\t\terr = action.run()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running queryChannelsAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getQueryChannelsCmd() *cobra.Command {\n\tcliconfig.InitPeerURL(queryChannelsCmd.Flags())\n\treturn queryChannelsCmd\n}\n\ntype queryChannelsAction struct {\n\taction.Action\n}\n\nfunc newQueryChannelsAction(flags *pflag.FlagSet) (*queryChannelsAction, error) {\n\taction := &queryChannelsAction{}\n\terr := action.Initialize(flags)\n\treturn action, err\n}\n\nfunc (a *queryChannelsAction) run() error {\n\n\turl := cliconfig.Config().PeerURLs()\n\tif len(url) != 1 {\n\t\treturn errors.New(\"must specify exactly one peer URL\")\n\t}\n\tpeer, ok := a.PeerFromURL(url[0])\n\tif !ok {\n\t\treturn fmt.Errorf(\"invalid peer URL: %s\", url)\n\t}\n\n\tuser, err := a.OrgAdminUser(a.OrgID())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tclient, err := a.ResourceMgmtClientForUser(user)\n\tif err != nil {\n\t\treturn errors.WithMessage(err, \"error getting fabric client\")\n\t}\n\n\tresponse, err := client.QueryChannels(resmgmt.WithTargets(peer))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Printf(\"Channels for peer [%s]\\n\", a.Peer().URL())\n\n\ta.Printer().PrintChannels(response.Channels)\n\n\treturn nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/query/querycmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage query\n\nimport (\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n)\n\nvar queryCmd = &cobra.Command{\n\tUse:   \"query\",\n\tShort: \"Query commands\",\n\tLong:  \"Query commands\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tcmd.HelpFunc()(cmd, args)\n\t},\n}\n\n// Cmd returns the query command\nfunc Cmd() *cobra.Command {\n\tcliconfig.InitChannelID(queryCmd.Flags())\n\n\tqueryCmd.AddCommand(getQueryBlockCmd())\n\tqueryCmd.AddCommand(getQueryInfoCmd())\n\tqueryCmd.AddCommand(getQueryTXCmd())\n\tqueryCmd.AddCommand(getQueryChannelsCmd())\n\tqueryCmd.AddCommand(getQueryInstalledCmd())\n\tqueryCmd.AddCommand(getQueryPeersCmd())\n\tqueryCmd.AddCommand(getQueryLocalPeersCmd())\n\n\treturn queryCmd\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/query/queryinfocmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage query\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar queryInfoCmd = &cobra.Command{\n\tUse:   \"info\",\n\tShort: \"Query info\",\n\tLong:  \"Queries general info\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\taction, err := newQueryInfoAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing queryInfoAction: %v\", err)\n\t\t\treturn\n\t\t}\n\t\tdefer action.Terminate()\n\n\t\tif cliconfig.Config().ChannelID() == \"\" {\n\t\t\tfmt.Printf(\"\\nMust specify channel ID\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\n\t\terr = action.run()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running queryInfoAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getQueryInfoCmd() *cobra.Command {\n\tflags := queryInfoCmd.Flags()\n\tcliconfig.InitTxID(flags)\n\tcliconfig.InitChannelID(flags)\n\tcliconfig.InitPeerURL(flags)\n\treturn queryInfoCmd\n}\n\ntype queryInfoAction struct {\n\taction.Action\n}\n\nfunc newQueryInfoAction(flags *pflag.FlagSet) (*queryInfoAction, error) {\n\taction := &queryInfoAction{}\n\terr := action.Initialize(flags)\n\treturn action, err\n}\n\nfunc (a *queryInfoAction) run() error {\n\tchannelClient, err := a.LedgerClient()\n\tif err != nil {\n\t\treturn errors.Errorf(\"Error getting admin ledger client: %v\", err)\n\t}\n\n\tinfo, err := channelClient.QueryInfo()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ta.Printer().PrintBlockchainInfo(info.BCI)\n\n\treturn nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/query/queryinstalledcmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage query\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar queryInstalledCmd = &cobra.Command{\n\tUse:   \"installed\",\n\tShort: \"Query installed chaincodes\",\n\tLong:  \"Queries the chaincodes installed to the specified peer\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\taction, err := newqueryInstalledAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing queryInstalledAction: %v\", err)\n\t\t\treturn\n\t\t}\n\n\t\tif len(cliconfig.Config().PeerURLs()) != 1 {\n\t\t\tfmt.Printf(\"\\nMust specify exactly one peer URL\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\n\t\tdefer action.Terminate()\n\n\t\terr = action.run()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running queryInstalledAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getQueryInstalledCmd() *cobra.Command {\n\tcliconfig.InitPeerURL(queryInstalledCmd.Flags())\n\treturn queryInstalledCmd\n}\n\ntype queryInstalledAction struct {\n\taction.Action\n}\n\nfunc newqueryInstalledAction(flags *pflag.FlagSet) (*queryInstalledAction, error) {\n\taction := &queryInstalledAction{}\n\terr := action.Initialize(flags)\n\treturn action, err\n}\n\nfunc (a *queryInstalledAction) run() error {\n\n\turl := cliconfig.Config().PeerURLs()\n\tif len(url) != 1 {\n\t\treturn errors.New(\"must specify exactly one peer URL\")\n\t}\n\tpeer, ok := a.PeerFromURL(url[0])\n\tif !ok {\n\t\treturn fmt.Errorf(\"invalid peer URL: %s\", url)\n\t}\n\n\tuser, err := a.OrgAdminUser(a.OrgID())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tclient, err := a.ResourceMgmtClientForUser(user)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tresponse, err := client.QueryInstalledChaincodes(resmgmt.WithTargets(peer))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Printf(\"Chaincodes for peer [%s]\\n\", a.Peer().URL())\n\ta.Printer().PrintChaincodes(response.Chaincodes)\n\treturn nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/query/querylocalpeerscmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage query\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar queryLocalPeersCmd = &cobra.Command{\n\tUse:   \"localpeers\",\n\tShort: \"Query local peers\",\n\tLong:  \"Queries the peers for the specified org\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\taction, err := newQueryLocalPeersAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing queryLocalPeersAction: %v\", err)\n\t\t\treturn\n\t\t}\n\t\tdefer action.Terminate()\n\n\t\tif cliconfig.Config().OrgID() == \"\" {\n\t\t\tfmt.Printf(\"\\nMust specify org ID\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\n\t\terr = action.run()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running queryLocalPeersAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getQueryLocalPeersCmd() *cobra.Command {\n\tflags := queryLocalPeersCmd.Flags()\n\tcliconfig.InitOrgIDs(flags)\n\tcliconfig.InitPeerURL(flags)\n\treturn queryLocalPeersCmd\n}\n\ntype queryLocalPeersAction struct {\n\taction.Action\n}\n\nfunc newQueryLocalPeersAction(flags *pflag.FlagSet) (*queryLocalPeersAction, error) {\n\taction := &queryLocalPeersAction{}\n\terr := action.Initialize(flags)\n\treturn action, err\n}\n\nfunc (a *queryLocalPeersAction) run() error {\n\tlocalContext, err := a.LocalContext()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tpeers, err := localContext.LocalDiscoveryService().GetPeers()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ta.Printer().PrintPeers(peers)\n\n\treturn nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/query/querypeerscmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage query\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar queryPeersCmd = &cobra.Command{\n\tUse:   \"peers\",\n\tShort: \"Query peers\",\n\tLong:  \"Queries the peers for the specified channel\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\taction, err := newQueryPeersAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing queryPeersAction: %v\", err)\n\t\t\treturn\n\t\t}\n\t\tdefer action.Terminate()\n\n\t\tif cliconfig.Config().ChannelID() == \"\" {\n\t\t\tfmt.Printf(\"\\nMust specify channel ID\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\n\t\terr = action.run()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running queryPeersAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getQueryPeersCmd() *cobra.Command {\n\tflags := queryPeersCmd.Flags()\n\tcliconfig.InitChannelID(flags)\n\tcliconfig.InitPeerURL(flags)\n\treturn queryPeersCmd\n}\n\ntype queryPeersAction struct {\n\taction.Action\n}\n\nfunc newQueryPeersAction(flags *pflag.FlagSet) (*queryPeersAction, error) {\n\taction := &queryPeersAction{}\n\terr := action.Initialize(flags)\n\treturn action, err\n}\n\nfunc (a *queryPeersAction) run() error {\n\tchProvider, err := a.ChannelProvider()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tchContext, err := chProvider()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tdiscovery, err := chContext.ChannelService().Discovery()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tpeers, err := discovery.GetPeers()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\ta.Printer().PrintPeers(peers)\n\n\treturn nil\n}\n"
  },
  {
    "path": "fabric-cli/cmd/fabric-cli/query/querytxcmd.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage query\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab\"\n\t\"github.com/pkg/errors\"\n\t\"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action\"\n\tcliconfig \"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config\"\n\t\"github.com/spf13/cobra\"\n\t\"github.com/spf13/pflag\"\n)\n\nvar queryTXCmd = &cobra.Command{\n\tUse:   \"tx\",\n\tShort: \"Query transaction\",\n\tLong:  \"Queries a transaction\",\n\tRun: func(cmd *cobra.Command, args []string) {\n\t\tif cliconfig.Config().TxID() == \"\" {\n\t\t\tfmt.Printf(\"\\nMust specify the transaction ID\\n\\n\")\n\t\t\tcmd.HelpFunc()(cmd, args)\n\t\t\treturn\n\t\t}\n\t\taction, err := newQueryTXAction(cmd.Flags())\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while initializing queryTXAction: %v\", err)\n\t\t\treturn\n\t\t}\n\n\t\tdefer action.Terminate()\n\n\t\terr = action.run()\n\t\tif err != nil {\n\t\t\tcliconfig.Config().Logger().Errorf(\"Error while running queryTXAction: %v\", err)\n\t\t}\n\t},\n}\n\nfunc getQueryTXCmd() *cobra.Command {\n\tflags := queryTXCmd.Flags()\n\tcliconfig.InitChannelID(flags)\n\tcliconfig.InitTxID(flags)\n\tcliconfig.InitPeerURL(flags)\n\treturn queryTXCmd\n}\n\ntype queryTXAction struct {\n\taction.Action\n}\n\nfunc newQueryTXAction(flags *pflag.FlagSet) (*queryTXAction, error) {\n\taction := &queryTXAction{}\n\terr := action.Initialize(flags)\n\n\treturn action, err\n}\n\nfunc (a *queryTXAction) run() error {\n\tledgerClient, err := a.LedgerClient()\n\tif err != nil {\n\t\treturn errors.Errorf(\"Error getting ledger client: %v\", err)\n\t}\n\n\ttx, err := ledgerClient.QueryTransaction(fab.TransactionID(cliconfig.Config().TxID()))\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfmt.Printf(\"Transaction %s in channel %s\\n\", cliconfig.Config().TxID(), cliconfig.Config().ChannelID())\n\ta.Printer().PrintProcessedTransaction(tx)\n\n\treturn nil\n}\n"
  },
  {
    "path": "fabric-cli/test/fixtures/config/config_test_local.yaml",
    "content": "#\n# Copyright SecureKey Technologies Inc. All Rights Reserved.\n#\n# SPDX-License-Identifier: Apache-2.0\n#\n#\n# The network connection profile provides client applications the information about the target\n# blockchain network that are necessary for the applications to interact with it. These are all\n# knowledge that must be acquired from out-of-band sources. This file provides such a source.\n#\n\n\n#\n# Schema version of the content. Used by the SDK to apply the corresponding parsing rules.\n#\nversion: 1.0.0\n\n#\n# The client section used by GO SDK.\n#\nclient:\n\n  # Which organization does this application instance belong to? The value must be the name of an org\n  # defined under \"organizations\"\n  organization: org1\n\n  logging:\n    level: info\n\n\n  # Root of the MSP directories with keys and certs.\n  cryptoconfig:\n    path: ${GOPATH}/src/github.com/securekey/fabric-examples/fabric-cli/fabric-sdk-go/${CRYPTOCONFIG_FIXTURES_PATH}\n\n  # Some SDKs support pluggable KV stores, the properties under \"credentialStore\"\n  # are implementation specific\n  credentialStore:\n    # [Optional]. Used by user store. Not needed if all credentials are embedded in configuration\n    # and enrollments are performed elswhere.\n    path: \"/tmp/state-store\"\n\n    # [Optional]. Specific to the CryptoSuite implementation used by GO SDK. Software-based implementations\n    # requiring a key store. PKCS#11 based implementations does not.\n    cryptoStore:\n      # Specific to the underlying KeyValueStore that backs the crypto key store.\n      path: /tmp/msp\n\n   # BCCSP config for the client. Used by GO SDK.\n  BCCSP:\n    security:\n     enabled: true\n     default:\n      provider: \"SW\"\n     hashAlgorithm: \"SHA2\"\n     softVerify: true\n     ephemeral: false\n     level: 256\n\n  tlsCerts:\n    # [Optional]. Use system certificate pool when connecting to peers, orderers (for negotiating TLS) Default: false\n    systemCertPool: false\n\n    # [Optional]. Client key and cert for TLS handshake with peers and orderers\n    client:\n      key:\n        path: ${GOPATH}/src/github.com/securekey/fabric-examples/fabric-cli/fabric-sdk-go/${CRYPTOCONFIG_FIXTURES_PATH}/peerOrganizations/tls.example.com/users/User1@tls.example.com/tls/client.key\n      cert:\n        path: ${GOPATH}/src/github.com/securekey/fabric-examples/fabric-cli/fabric-sdk-go/${CRYPTOCONFIG_FIXTURES_PATH}/peerOrganizations/tls.example.com/users/User1@tls.example.com/tls/client.crt\n\n#\n# [Optional]. But most apps would have this section so that channel objects can be constructed\n# based on the content below. If an app is creating channels, then it likely will not need this\n# section.\n#\nchannels:\n  # name of the channel\n  mychannel:\n    # Required. list of peers from participating orgs\n    peers:\n      local.peer0.org1.example.com:\n        # [Optional]. will this peer be sent transaction proposals for endorsement? The peer must\n        # have the chaincode installed. The app can also use this property to decide which peers\n        # to send the chaincode install request. Default: true\n        endorsingPeer: true\n\n        # [Optional]. will this peer be sent query proposals? The peer must have the chaincode\n        # installed. The app can also use this property to decide which peers to send the\n        # chaincode install request. Default: true\n        chaincodeQuery: true\n\n        # [Optional]. will this peer be sent query proposals that do not require chaincodes, like\n        # queryBlock(), queryTransaction(), etc. Default: true\n        ledgerQuery: true\n\n        # [Optional]. will this peer be the target of the SDK's listener registration? All peers can\n        # produce events but the app typically only needs to connect to one to listen to events.\n        # Default: true\n        eventSource: true\n\n      local.peer0.org2.example.com:\n        endorsingPeer: true\n        chaincodeQuery: true\n        ledgerQuery: true\n        eventSource: true\n\n    # [Optional]. The application can use these options to perform channel operations like retrieving channel\n    # config etc.\n    policies:\n      #[Optional] options for retrieving channel configuration blocks\n      queryChannelConfig:\n        #[Optional] min number of success responses (from targets/peers)\n        minResponses: 1\n        #[Optional] channel config will be retrieved for these number of random targets\n        maxTargets: 1\n        #[Optional] retry options for query config block\n        retryOpts:\n          #[Optional] number of retry attempts\n          attempts: 5\n          #[Optional] the back off interval for the first retry attempt\n          initialBackoff: 500ms\n          #[Optional] the maximum back off interval for any retry attempt\n          maxBackoff: 5s\n          #[Optional] he factor by which the initial back off period is exponentially incremented\n          backoffFactor: 2.0\n\n  # multi-org test channel\n  orgchannel:\n    peers:\n      local.peer0.org1.example.com:\n        endorsingPeer: true\n        chaincodeQuery: true\n        ledgerQuery: true\n        eventSource: true\n\n      local.peer0.org2.example.com:\n        endorsingPeer: true\n        chaincodeQuery: true\n        ledgerQuery: true\n        eventSource: true\n\n    # [Optional]. The application can use these options to perform channel operations like retrieving channel\n    # config etc.\n    policies:\n      #[Optional] options for retrieving channel configuration blocks\n      queryChannelConfig:\n        #[Optional] min number of success responses (from targets/peers)\n        minResponses: 1\n        #[Optional] channel config will be retrieved for these number of random targets\n        maxTargets: 1\n        #[Optional] retry options for query config block\n        retryOpts:\n          #[Optional] number of retry attempts\n          attempts: 5\n          #[Optional] the back off interval for the first retry attempt\n          initialBackoff: 500ms\n          #[Optional] the maximum back off interval for any retry attempt\n          maxBackoff: 5s\n          #[Optional] he factor by which the initial back off period is exponentially incremented\n          backoffFactor: 2.0\n\n#\n# list of participating organizations in this network\n#\norganizations:\n  org1:\n    mspid: Org1MSP\n\n    # This org's MSP store (absolute path or relative to client.cryptoconfig)\n    cryptoPath:  peerOrganizations/org1.example.com/users/{username}@org1.example.com/msp\n\n    peers:\n      - local.peer0.org1.example.com\n      - local.peer1.org1.example.com\n\n    # [Optional]. Certificate Authorities issue certificates for identification purposes in a Fabric based\n    # network. Typically certificates provisioning is done in a separate process outside of the\n    # runtime network. Fabric-CA is a special certificate authority that provides a REST APIs for\n    # dynamic certificate management (enroll, revoke, re-enroll). The following section is only for\n    # Fabric-CA servers.\n#    certificateAuthorities:\n#      - local.ca.org1.example.com\n\n  # the profile will contain public information about organizations other than the one it belongs to.\n  # These are necessary information to make transaction lifecycles work, including MSP IDs and\n  # peers with a public URL to send transaction proposals. The file will not contain private\n  # information reserved for members of the organization, such as admin key and certificate,\n  # fabric-ca registrar enroll ID and secret, etc.\n  org2:\n    mspid: Org2MSP\n\n    # This org's MSP store (absolute path or relative to client.cryptoconfig)\n    cryptoPath:  peerOrganizations/org2.example.com/users/{username}@org2.example.com/msp\n\n    peers:\n      - local.peer0.org2.example.com\n      - local.peer1.org2.example.com\n\n#    certificateAuthorities:\n#      - local.ca.org2.example.com\n\n  # Orderer Org name\n  ordererorg:\n      # Membership Service Provider ID for this organization\n      mspID: \"OrdererOrg\"\n\n      # Needed to load users crypto keys and certs for this org (absolute path or relative to global crypto path, DEV mode)\n      cryptoPath: ordererOrganizations/example.com/users/{username}@example.com/msp\n\n#\n# List of orderers to send transaction and channel create/update requests to. For the time\n# being only one orderer is needed. If more than one is defined, which one get used by the\n# SDK is implementation specific. Consult each SDK's documentation for its handling of orderers.\n#\norderers:\n  local.orderer.example.com:\n    url: localhost:7050\n\n    # these are standard properties defined by the gRPC library\n    # they will be passed in as-is to gRPC client constructor\n    grpcOptions:\n      ssl-target-name-override: orderer.example.com\n      # These parameters should be set in coordination with the keepalive policy on the server,\n      # as incompatible settings can result in closing of connection.\n      # When duration of the 'keep-alive-time' is set to 0 or less the keep alive client parameters are disabled\n      keep-alive-time: 0s\n      keep-alive-timeout: 20s\n      keep-alive-permit: false\n      fail-fast: false\n      # allow-insecure will be taken into consideration if address has no protocol defined, if true then grpc or else grpcs\n      allow-insecure: false\n\n    tlsCACerts:\n      # Certificate location absolute path\n      path: ${GOPATH}/src/github.com/securekey/fabric-examples/fabric-cli/fabric-sdk-go/${CRYPTOCONFIG_FIXTURES_PATH}/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem\n\n#\n# List of peers to send various requests to, including endorsement, query\n# and event listener registration.\n#\npeers:\n  local.peer0.org1.example.com:\n    # this URL is used to send endorsement and query requests\n    url: localhost:7051\n    # eventUrl is only needed when using eventhub (default is delivery service)\n    eventUrl: localhost:7053\n\n    grpcOptions:\n      ssl-target-name-override: peer0.org1.example.com\n      # These parameters should be set in coordination with the keepalive policy on the server,\n      # as incompatible settings can result in closing of connection.\n      # When duration of the 'keep-alive-time' is set to 0 or less the keep alive client parameters are disabled\n      keep-alive-time: 0s\n      keep-alive-timeout: 20s\n      keep-alive-permit: false\n      fail-fast: false\n      # allow-insecure will be taken into consideration if address has no protocol defined, if true then grpc or else grpcs\n      allow-insecure: false\n\n    tlsCACerts:\n      # Certificate location absolute path\n      path: ${GOPATH}/src/github.com/securekey/fabric-examples/fabric-cli/fabric-sdk-go/${CRYPTOCONFIG_FIXTURES_PATH}/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem\n\n  local.peer1.org1.example.com:\n    # this URL is used to send endorsement and query requests\n    url: localhost:7151\n    # eventUrl is only needed when using eventhub (default is delivery service)\n    eventUrl: localhost:7153\n\n    grpcOptions:\n      ssl-target-name-override: peer1.org1.example.com\n      # These parameters should be set in coordination with the keepalive policy on the server,\n      # as incompatible settings can result in closing of connection.\n      # When duration of the 'keep-alive-time' is set to 0 or less the keep alive client parameters are disabled\n      keep-alive-time: 0s\n      keep-alive-timeout: 20s\n      keep-alive-permit: false\n      fail-fast: false\n      # allow-insecure will be taken into consideration if address has no protocol defined, if true then grpc or else grpcs\n      allow-insecure: false\n\n    tlsCACerts:\n      # Certificate location absolute path\n      path: ${GOPATH}/src/github.com/securekey/fabric-examples/fabric-cli/fabric-sdk-go/${CRYPTOCONFIG_FIXTURES_PATH}/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem\n\n  local.peer0.org2.example.com:\n    url: localhost:8051\n    # eventUrl is only needed when using eventhub (default is delivery service)\n    eventUrl: localhost:8053\n    grpcOptions:\n      ssl-target-name-override: peer0.org2.example.com\n      # These parameters should be set in coordination with the keepalive policy on the server,\n      # as incompatible settings can result in closing of connection.\n      # When duration of the 'keep-alive-time' is set to 0 or less the keep alive client parameters are disabled\n      keep-alive-time: 0s\n      keep-alive-timeout: 20s\n      keep-alive-permit: false\n      fail-fast: false\n      # allow-insecure will be taken into consideration if address has no protocol defined, if true then grpc or else grpcs\n      allow-insecure: false\n\n    tlsCACerts:\n      path: ${GOPATH}/src/github.com/securekey/fabric-examples/fabric-cli/fabric-sdk-go/${CRYPTOCONFIG_FIXTURES_PATH}/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem\n\n  local.peer1.org2.example.com:\n    url: localhost:9051\n    # eventUrl is only needed when using eventhub (default is delivery service)\n    eventUrl: localhost:9053\n    grpcOptions:\n      ssl-target-name-override: peer1.org2.example.com\n      # These parameters should be set in coordination with the keepalive policy on the server,\n      # as incompatible settings can result in closing of connection.\n      # When duration of the 'keep-alive-time' is set to 0 or less the keep alive client parameters are disabled\n      keep-alive-time: 0s\n      keep-alive-timeout: 20s\n      keep-alive-permit: false\n      fail-fast: false\n      # allow-insecure will be taken into consideration if address has no protocol defined, if true then grpc or else grpcs\n      allow-insecure: false\n\n    tlsCACerts:\n      path: ${GOPATH}/src/github.com/securekey/fabric-examples/fabric-cli/fabric-sdk-go/${CRYPTOCONFIG_FIXTURES_PATH}/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem\n\n#\n# Fabric-CA is a special kind of Certificate Authority provided by Hyperledger Fabric which allows\n# certificate management to be done via REST APIs. Application may choose to use a standard\n# Certificate Authority instead of Fabric-CA, in which case this section would not be specified.\n#\ncertificateAuthorities:\n  ca.org1.example.com:\n    url: https://ca.org1.example.com:7054\n    tlsCACerts:\n      # Comma-Separated list of paths\n      path: ${GOPATH}/src/github.com/securekey/fabric-examples/fabric-cli/fabric-sdk-go/${CRYPTOCONFIG_FIXTURES_PATH}/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem\n      # Client key and cert for SSL handshake with Fabric CA\n      client:\n        key:\n          path: ${GOPATH}/src/github.com/securekey/fabric-examples/fabric-cli/fabric-sdk-go/${CRYPTOCONFIG_FIXTURES_PATH}/peerOrganizations/tls.example.com/users/User1@tls.example.com/tls/client.key\n        cert:\n          path: ${GOPATH}/src/github.com/securekey/fabric-examples/fabric-cli/fabric-sdk-go/${CRYPTOCONFIG_FIXTURES_PATH}/peerOrganizations/tls.example.com/users/User1@tls.example.com/tls/client.crt\n\n    # Fabric-CA supports dynamic user enrollment via REST APIs. A \"root\" user, a.k.a registrar, is\n    # needed to enroll and invoke new users.\n    registrar:\n      enrollId: admin\n      enrollSecret: adminpw\n    # [Optional] The optional name of the CA.\n    caName: ca.org1.example.com\n  ca.org2.example.com:\n    url: https://ca.org2.example.com:8054\n    tlsCACerts:\n      # Comma-Separated list of paths\n      path: ${GOPATH}/src/github.com/securekey/fabric-examples/fabric-cli/fabric-sdk-go/${CRYPTOCONFIG_FIXTURES_PATH}/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem\n      # Client key and cert for SSL handshake with Fabric CA\n      client:\n        key:\n          path: ${GOPATH}/src/github.com/securekey/fabric-examples/fabric-cli/fabric-sdk-go/${CRYPTOCONFIG_FIXTURES_PATH}/peerOrganizations/tls.example.com/users/User1@tls.example.com/tls/client.key\n        cert:\n          path: ${GOPATH}/src/github.com/securekey/fabric-examples/fabric-cli/fabric-sdk-go/${CRYPTOCONFIG_FIXTURES_PATH}/peerOrganizations/tls.example.com/users/User1@tls.example.com/tls/client.crt\n\n     # Fabric-CA supports dynamic user enrollment via REST APIs. A \"root\" user, a.k.a registrar, is\n     # needed to enroll and invoke new users.\n    registrar:\n      enrollId: admin\n      enrollSecret: adminpw\n    # [Optional] The optional name of the CA.\n    caName: ca.org2.example.com\n\nentityMatchers:\n  peer:\n    - pattern: peer0.org1.example.com:7051\n      urlSubstitutionExp: localhost:7051\n      eventUrlSubstitutionExp: localhost:7053\n      sslTargetOverrideUrlSubstitutionExp: peer0.org1.example.com\n      mappedHost: local.peer0.org1.example.com\n    - pattern: peer1.org1.example.com:7151\n      urlSubstitutionExp: localhost:7151\n      eventUrlSubstitutionExp: localhost:7153\n      sslTargetOverrideUrlSubstitutionExp: peer1.org1.example.com\n      mappedHost: local.peer1.org1.example.com\n    - pattern: peer0.org2.example.com:8051\n      urlSubstitutionExp: localhost:8051\n      eventUrlSubstitutionExp: localhost:8053\n      sslTargetOverrideUrlSubstitutionExp: peer0.org2.example.com\n      mappedHost: local.peer0.org2.example.com\n    - pattern: peer1.org2.example.com:9051\n      urlSubstitutionExp: localhost:9051\n      eventUrlSubstitutionExp: localhost:9053\n      sslTargetOverrideUrlSubstitutionExp: peer1.org2.example.com\n      mappedHost: local.peer1.org2.example.com\n\n  orderer:\n    - pattern: orderer.example.com\n      urlSubstitutionExp: localhost:7050\n      sslTargetOverrideUrlSubstitutionExp: orderer.example.com\n      mappedHost: local.orderer.example.com\n\n#  certificateAuthority:\n#    - pattern: (\\w+).org1.example.(\\w+)\n#      urlSubstitutionExp: https://localhost:7054\n#      mappedHost: local.ca.org1.example.com\n#\n#    - pattern: (\\w+).org2.example.(\\w+)\n#      urlSubstitutionExp: https://localhost:8054\n#      mappedHost: local.ca.org2.example.com"
  },
  {
    "path": "fabric-cli/test/fixtures/config/pvtdatacollection.json",
    "content": "[\n    {\n        \"name\": \"coll1\",\n        \"policy\": \"OR('Org1MSP.member', 'Org2MSP.member')\",\n        \"requiredPeerCount\": 1,\n        \"maxPeerCount\": 2\n    },\n    {\n        \"name\": \"coll2\",\n        \"policy\": \"OR('Org2MSP.member')\",\n        \"requiredPeerCount\": 0,\n        \"maxPeerCount\": 2\n    }\n]\n"
  },
  {
    "path": "fabric-cli/test/fixtures/testdata/src/github.com/securekey/example2_cc/example2_cc.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/hyperledger/fabric/core/chaincode/shim\"\n\tpb \"github.com/hyperledger/fabric/protos/peer\"\n)\n\ntype invokeFunc func(stub shim.ChaincodeStubInterface, args []string) pb.Response\ntype funcMap map[string]invokeFunc\n\nconst (\n\tgetFunc           = \"get\"\n\tputFunc           = \"put\"\n\tdelFunc           = \"del\"\n\tputPrivateFunc    = \"putprivate\"\n\tgetPrivateFunc    = \"getprivate\"\n\tdelPrivateFunc    = \"delprivate\"\n\tputBothFunc       = \"putboth\"\n\tgetAndPutBothFunc = \"getandputboth\"\n\tinvokeCCFunc      = \"invokecc\"\n)\n\n// ExampleCC example simple Chaincode implementation\ntype ExampleCC struct {\n\tfuncRegistry funcMap\n}\n\n// Init ...\nfunc (cc *ExampleCC) Init(stub shim.ChaincodeStubInterface) pb.Response {\n\treturn shim.Success(nil)\n}\n\n// Invoke invoke the chaincode with a given function\nfunc (cc *ExampleCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response {\n\tfmt.Println(\"########### example2_cc Invoke ###########\")\n\tfunction, args := stub.GetFunctionAndParameters()\n\tif function == \"\" {\n\t\treturn shim.Error(\"Expecting function\")\n\t}\n\n\tf, ok := cc.funcRegistry[function]\n\tif !ok {\n\t\treturn shim.Error(fmt.Sprintf(\"Unknown function [%s]. Expecting one of: %v\", function, cc.functions()))\n\t}\n\n\treturn f(stub, args)\n}\n\nfunc (cc *ExampleCC) put(stub shim.ChaincodeStubInterface, args []string) pb.Response {\n\tif len(args) != 2 {\n\t\treturn shim.Error(\"Invalid args. Expecting key and value\")\n\t}\n\n\tkey := args[0]\n\tvalue := args[1]\n\n\texistingValue, err := stub.GetState(key)\n\tif err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Error getting data for key [%s]: %s\", key, err))\n\t}\n\tif existingValue != nil {\n\t\tvalue = string(existingValue) + \"-\" + value\n\t}\n\n\tif err := stub.PutState(key, []byte(value)); err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Error putting data for key [%s]: %s\", key, err))\n\t}\n\n\treturn shim.Success([]byte(value))\n}\n\nfunc (cc *ExampleCC) get(stub shim.ChaincodeStubInterface, args []string) pb.Response {\n\tif len(args) != 1 {\n\t\treturn shim.Error(\"Invalid args. Expecting key\")\n\t}\n\n\tkey := args[0]\n\n\tvalue, err := stub.GetState(key)\n\tif err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Error getting data for key [%s]: %s\", key, err))\n\t}\n\n\treturn shim.Success([]byte(value))\n}\n\nfunc (cc *ExampleCC) del(stub shim.ChaincodeStubInterface, args []string) pb.Response {\n\tif len(args) != 1 {\n\t\treturn shim.Error(\"Invalid args. Expecting key\")\n\t}\n\n\tkey := args[1]\n\n\terr := stub.DelState(key)\n\tif err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Failed to delete state for [%s]: %s\", key, err))\n\t}\n\n\treturn shim.Success(nil)\n}\n\nfunc (cc *ExampleCC) putPrivate(stub shim.ChaincodeStubInterface, args []string) pb.Response {\n\tif len(args) != 3 {\n\t\treturn shim.Error(\"Invalid args. Expecting collection, key and value\")\n\t}\n\n\tcoll := args[0]\n\tkey := args[1]\n\tvalue := args[2]\n\n\tif err := stub.PutPrivateData(coll, key, []byte(value)); err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Error putting private data for collection [%s] and key [%s]: %s\", coll, key, err))\n\t}\n\n\treturn shim.Success(nil)\n}\n\nfunc (cc *ExampleCC) getPrivate(stub shim.ChaincodeStubInterface, args []string) pb.Response {\n\tif len(args) != 2 {\n\t\treturn shim.Error(\"Invalid args. Expecting collection and key\")\n\t}\n\n\tcoll := args[0]\n\tkey := args[1]\n\n\tvalue, err := stub.GetPrivateData(coll, key)\n\tif err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Error getting private data for collection [%s] and key [%s]: %s\", coll, key, err))\n\t}\n\n\treturn shim.Success([]byte(value))\n}\n\nfunc (cc *ExampleCC) delPrivate(stub shim.ChaincodeStubInterface, args []string) pb.Response {\n\tif len(args) != 2 {\n\t\treturn shim.Error(\"Invalid args. Expecting collection and key\")\n\t}\n\n\tcoll := args[0]\n\tkey := args[1]\n\n\terr := stub.DelPrivateData(coll, key)\n\tif err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Error getting private data for collection [%s] and key [%s]: %s\", coll, key, err))\n\t}\n\n\treturn shim.Success(nil)\n}\n\nfunc (cc *ExampleCC) putBoth(stub shim.ChaincodeStubInterface, args []string) pb.Response {\n\tif len(args) != 5 {\n\t\treturn shim.Error(\"Invalid args. Expecting key, value, collection, privkey and privvalue\")\n\t}\n\n\tkey := args[0]\n\tvalue := args[1]\n\tcoll := args[2]\n\tprivKey := args[3]\n\tprivValue := args[4]\n\n\tif err := stub.PutState(key, []byte(value)); err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Error putting state for key [%s]: %s\", key, err))\n\t}\n\tif err := stub.PutPrivateData(coll, privKey, []byte(privValue)); err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Error putting private data for collection [%s] and key [%s]: %s\", coll, key, err))\n\t}\n\n\treturn shim.Success(nil)\n}\n\nfunc (cc *ExampleCC) getAndPutBoth(stub shim.ChaincodeStubInterface, args []string) pb.Response {\n\tif len(args) != 5 {\n\t\treturn shim.Error(\"Invalid args. Expecting key, value, collection, privkey and privvalue\")\n\t}\n\n\tkey := args[0]\n\tvalue := args[1]\n\tcoll := args[2]\n\tprivKey := args[3]\n\tprivValue := args[4]\n\n\toldValue, err := stub.GetState(key)\n\tif err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Error getting state for key [%s]: %s\", key, err))\n\t}\n\tif oldValue != nil {\n\t\tvalue = value + \"_\" + string(oldValue)\n\t}\n\toldPrivValue, err := stub.GetPrivateData(coll, privKey)\n\tif err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Error getting private data for collection [%s] and key [%s]: %s\", coll, privKey, err))\n\t}\n\tif oldPrivValue != nil {\n\t\tprivValue = privValue + \"_\" + string(oldPrivValue)\n\t}\n\n\tif err := stub.PutState(key, []byte(value)); err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Error putting state for key [%s]: %s\", key, err))\n\t}\n\tif err := stub.PutPrivateData(coll, privKey, []byte(privValue)); err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Error putting private data for collection [%s] and key [%s]: %s\", coll, key, err))\n\t}\n\n\treturn shim.Success(nil)\n}\n\ntype argStruct struct {\n\tArgs []string `json:\"Args\"`\n}\n\nfunc asBytes(args []string) [][]byte {\n\tbytes := make([][]byte, len(args))\n\tfor i, arg := range args {\n\t\tbytes[i] = []byte(arg)\n\t}\n\treturn bytes\n}\n\nfunc (cc *ExampleCC) invokeCC(stub shim.ChaincodeStubInterface, args []string) pb.Response {\n\tif len(args) < 2 {\n\t\treturn shim.Error(`Invalid args. Expecting name of chaincode to invoke and chaincode args in the format {\"Args\":[\"arg1\",\"arg2\",...]}`)\n\t}\n\n\tccName := args[0]\n\tinvokeArgsJSON := strings.Replace(args[1], \"`\", `\"`, -1)\n\n\targStruct := argStruct{}\n\tif err := json.Unmarshal([]byte(invokeArgsJSON), &argStruct); err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Invalid invoke args: %s\", err))\n\t}\n\n\tif err := stub.PutState(stub.GetTxID()+\"_invokedcc\", []byte(ccName)); err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Error putting state: %s\", err))\n\t}\n\n\treturn stub.InvokeChaincode(ccName, asBytes(argStruct.Args), \"\")\n}\n\nfunc (cc *ExampleCC) initRegistry() {\n\tcc.funcRegistry = make(map[string]invokeFunc)\n\tcc.funcRegistry[getFunc] = cc.get\n\tcc.funcRegistry[putFunc] = cc.put\n\tcc.funcRegistry[delFunc] = cc.del\n\tcc.funcRegistry[getPrivateFunc] = cc.getPrivate\n\tcc.funcRegistry[putPrivateFunc] = cc.putPrivate\n\tcc.funcRegistry[delPrivateFunc] = cc.delPrivate\n\tcc.funcRegistry[putBothFunc] = cc.putBoth\n\tcc.funcRegistry[getAndPutBothFunc] = cc.getAndPutBoth\n\tcc.funcRegistry[invokeCCFunc] = cc.invokeCC\n}\n\nfunc (cc *ExampleCC) functions() []string {\n\tvar funcs []string\n\tfor key := range cc.funcRegistry {\n\t\tfuncs = append(funcs, key)\n\t}\n\treturn funcs\n}\n\nfunc main() {\n\tcc := new(ExampleCC)\n\tcc.initRegistry()\n\terr := shim.Start(cc)\n\tif err != nil {\n\t\tfmt.Printf(\"Error starting example chaincode: %s\", err)\n\t}\n}\n"
  },
  {
    "path": "fabric-cli/test/fixtures/testdata/src/github.com/securekey/example_cc/example_cc.go",
    "content": "/*\nCopyright IBM Corp. 2016 All Rights Reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n\t\t http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"strconv\"\n\n\t\"github.com/hyperledger/fabric/core/chaincode/shim\"\n\tpb \"github.com/hyperledger/fabric/protos/peer\"\n)\n\n// SimpleChaincode example simple Chaincode implementation\ntype SimpleChaincode struct {\n}\n\n// Init ...\nfunc (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {\n\tfmt.Println(\"########### example_cc Init ###########\")\n\targs := stub.GetStringArgs()\n\tvar A, B string    // Entities\n\tvar Aval, Bval int // Asset holdings\n\tvar err error\n\n\tif len(args) != 4 {\n\t\treturn shim.Error(fmt.Sprintf(\"Incorrect number of arguments. Expecting 4, got %d\", len(args)))\n\t}\n\n\t// Initialize the chaincode\n\tA = args[0]\n\tAval, err = strconv.Atoi(args[1])\n\tif err != nil {\n\t\treturn shim.Error(\"Expecting integer value for asset holding\")\n\t}\n\tB = args[2]\n\tBval, err = strconv.Atoi(args[3])\n\tif err != nil {\n\t\treturn shim.Error(\"Expecting integer value for asset holding\")\n\t}\n\tfmt.Printf(\"Aval = %d, Bval = %d\\n\", Aval, Bval)\n\n\t// Write the state to the ledger\n\terr = stub.PutState(A, []byte(strconv.Itoa(Aval)))\n\tif err != nil {\n\t\treturn shim.Error(err.Error())\n\t}\n\n\terr = stub.PutState(B, []byte(strconv.Itoa(Bval)))\n\tif err != nil {\n\t\treturn shim.Error(err.Error())\n\t}\n\n\tif transientMap, err := stub.GetTransient(); err == nil {\n\t\tif transientData, ok := transientMap[\"result\"]; ok {\n\t\t\tfmt.Printf(\"Transient data in 'init' : %s\\n\", transientData)\n\t\t\treturn shim.Success(transientData)\n\t\t}\n\t}\n\treturn shim.Success(nil)\n\n}\n\n// Query ...\nfunc (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface) pb.Response {\n\treturn shim.Error(\"Unknown supported call\")\n}\n\n// Invoke ...\n// Transaction makes payment of X units from A to B\nfunc (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {\n\tfmt.Println(\"########### example_cc Invoke ###########\")\n\targs := stub.GetStringArgs()\n\tif len(args) == 0 {\n\t\treturn shim.Error(\"Function not provided\")\n\t}\n\n\tfunction := args[0]\n\n\tif len(args) < 2 {\n\t\treturn shim.Error(\"Incorrect number of arguments. Expecting at least 2\")\n\t}\n\n\tif function == \"delete\" {\n\t\t// Deletes an entity from its state\n\t\treturn t.delete(stub, args)\n\t}\n\n\tif function == \"query\" {\n\t\t// queries an entity state\n\t\treturn t.query(stub, args)\n\t}\n\n\tif function == \"move\" {\n\t\teventID := \"testEvent\"\n\t\tif len(args) >= 5 {\n\t\t\teventID = args[4]\n\t\t}\n\t\tif err := stub.SetEvent(eventID, []byte(\"Test Payload\")); err != nil {\n\t\t\treturn shim.Error(\"Unable to set CC event: testEvent. Aborting transaction ...\")\n\t\t}\n\t\treturn t.move(stub, args)\n\t}\n\n\tif function == \"put\" {\n\t\treturn t.put(stub, args[1:])\n\t}\n\n\tif function == \"get\" {\n\t\treturn t.get(stub, args[1:])\n\t}\n\n\treturn shim.Error(fmt.Sprintf(\"Unknown function call: %s\", function))\n}\n\nfunc (t *SimpleChaincode) move(stub shim.ChaincodeStubInterface, args []string) pb.Response {\n\t// must be an invoke\n\tvar A, B string    // Entities\n\tvar Aval, Bval int // Asset holdings\n\tvar X int          // Transaction value\n\tvar err error\n\tif len(args) < 4 {\n\t\treturn shim.Error(\"Incorrect number of arguments. Expecting 4, function followed by 2 names and 1 value\")\n\t}\n\n\tA = args[1]\n\tB = args[2]\n\n\t// Get the state from the ledger\n\t// TODO: will be nice to have a GetAllState call to ledger\n\tAvalbytes, err := stub.GetState(A)\n\tif err != nil {\n\t\treturn shim.Error(\"Failed to get state\")\n\t}\n\tif Avalbytes == nil {\n\t\treturn shim.Error(\"Entity not found\")\n\t}\n\tAval, _ = strconv.Atoi(string(Avalbytes))\n\n\tBvalbytes, err := stub.GetState(B)\n\tif err != nil {\n\t\treturn shim.Error(\"Failed to get state\")\n\t}\n\tif Bvalbytes == nil {\n\t\treturn shim.Error(\"Entity not found\")\n\t}\n\tBval, _ = strconv.Atoi(string(Bvalbytes))\n\n\t// Perform the execution\n\tX, err = strconv.Atoi(args[3])\n\tif err != nil {\n\t\treturn shim.Error(\"Invalid transaction amount, expecting a integer value\")\n\t}\n\tAval = Aval - X\n\tBval = Bval + X\n\tfmt.Printf(\"Aval = %d, Bval = %d\\n\", Aval, Bval)\n\n\t// Write the state back to the ledger\n\terr = stub.PutState(A, []byte(strconv.Itoa(Aval)))\n\tif err != nil {\n\t\treturn shim.Error(err.Error())\n\t}\n\n\terr = stub.PutState(B, []byte(strconv.Itoa(Bval)))\n\tif err != nil {\n\t\treturn shim.Error(err.Error())\n\t}\n\n\tif transientMap, err := stub.GetTransient(); err == nil {\n\t\tif transientData, ok := transientMap[\"result\"]; ok {\n\t\t\tfmt.Printf(\"Transient data in 'move' : %s\\n\", transientData)\n\t\t\treturn shim.Success(transientData)\n\t\t}\n\t}\n\treturn shim.Success(nil)\n}\n\n// Deletes an entity from state\nfunc (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, args []string) pb.Response {\n\tif len(args) != 1 {\n\t\treturn shim.Error(\"Incorrect number of arguments. Expecting 1\")\n\t}\n\n\tA := args[1]\n\n\t// Delete the key from the state in ledger\n\terr := stub.DelState(A)\n\tif err != nil {\n\t\treturn shim.Error(\"Failed to delete state\")\n\t}\n\n\treturn shim.Success(nil)\n}\n\n// Query callback representing the query of a chaincode\nfunc (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args []string) pb.Response {\n\tvar A string // Entities\n\tvar err error\n\n\tif len(args) != 2 {\n\t\treturn shim.Error(fmt.Sprintf(\"Incorrect number of arguments: %v\", args))\n\t}\n\n\tA = args[1]\n\n\t// Get the state from the ledger\n\tAvalbytes, err := stub.GetState(A)\n\tif err != nil {\n\t\tjsonResp := \"{\\\"Error\\\":\\\"Failed to get state for \" + A + \"\\\"}\"\n\t\treturn shim.Error(jsonResp)\n\t}\n\n\tif Avalbytes == nil {\n\t\tjsonResp := \"{\\\"Error\\\":\\\"Nil amount for \" + A + \"\\\"}\"\n\t\treturn shim.Error(jsonResp)\n\t}\n\n\tjsonResp := \"{\\\"Name\\\":\\\"\" + A + \"\\\",\\\"Amount\\\":\\\"\" + string(Avalbytes) + \"\\\"}\"\n\tfmt.Printf(\"Query Response:%s\\n\", jsonResp)\n\treturn shim.Success(Avalbytes)\n}\n\nfunc (t *SimpleChaincode) put(stub shim.ChaincodeStubInterface, args []string) pb.Response {\n\tif len(args) != 2 {\n\t\treturn shim.Error(\"Invalid args. Expecting key and value\")\n\t}\n\n\tkey := args[0]\n\tvalue := args[1]\n\n\texistingValue, err := stub.GetState(key)\n\tif err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Error getting data for key [%s]: %s\", key, err))\n\t}\n\tif existingValue != nil {\n\t\tvalue = string(existingValue) + \"-\" + value\n\t}\n\n\tif err := stub.PutState(key, []byte(value)); err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Error putting data for key [%s]: %s\", key, err))\n\t}\n\n\treturn shim.Success([]byte(value))\n}\n\nfunc (t *SimpleChaincode) get(stub shim.ChaincodeStubInterface, args []string) pb.Response {\n\tif len(args) != 1 {\n\t\treturn shim.Error(\"Invalid args. Expecting key\")\n\t}\n\n\tkey := args[0]\n\n\tvalue, err := stub.GetState(key)\n\tif err != nil {\n\t\treturn shim.Error(fmt.Sprintf(\"Error getting data for key [%s]: %s\", key, err))\n\t}\n\n\treturn shim.Success([]byte(value))\n}\n\nfunc main() {\n\terr := shim.Start(new(SimpleChaincode))\n\tif err != nil {\n\t\tfmt.Printf(\"Error starting Simple chaincode: %s\", err)\n\t}\n}\n"
  },
  {
    "path": "fabric-cli/test/fixtures/testdata/src/go.mod",
    "content": "// Copyright SecureKey Technologies Inc. All Rights Reserved.\n//\n// SPDX-License-Identifier: Apache-2.0\n\nmodule github.com/securekey/fabric-examples/test/cc\n\nrequire github.com/hyperledger/fabric v1.4.0\n\ngo 1.13\n"
  },
  {
    "path": "fabric-cli/test/fixtures/testdata/src/go.sum",
    "content": "github.com/hyperledger/fabric v1.4.0/go.mod h1:tGFAOCT696D3rG0Vofd2dyWYLySHlh0aQjf7Q1HAju0=\n"
  },
  {
    "path": "fabric-cli/test/integration/fabric-cli_test.go",
    "content": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage integration\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n\n\tclicmd \"github.com/securekey/fabric-examples/fabric-cli/cmd\"\n)\n\n//\n// Test cases that can run (and debugged) from an IDE\n//\n\nfunc run(cmd string) {\n\tos.Args = strings.Split(cmd, \" \")\n\tos.Setenv(\"GRPC_TRACE\", \"all\")\n\tos.Setenv(\"GRPC_VERBOSITY\", \"DEBUG\")\n\tos.Setenv(\"GRPC_GO_LOG_SEVERITY_LEVEL\", \"INFO\")\n\tclicmd.Execute()\n}\n\nfunc header(h string) {\n\tfmt.Println(\"****************************************\")\n\tfmt.Println(\"*\")\n\tfmt.Printf(\"*     %s\\n\", h)\n\tfmt.Println(\"*\")\n\tfmt.Println(\"****************************************\")\n}\n\n//// ********** Create a channel ************ ////\n\nfunc TestCreate_a_channel(t *testing.T) {\n\theader(\"Create a channel\")\n\trun(\"fabric-cli channel create --cid mychannel --txfile ../fixtures/fabric/v1.1/channel/mychannel.tx --config ../fixtures/config/config_test_local.yaml\")\n}\n\n//// ********** Join a channel ************ ////\n\nfunc TestJoin_org1_peer_to_a_channel(t *testing.T) {\n\theader(\"Join a peer to a channel\")\n\trun(\"fabric-cli.go channel join --cid mychannel --peer localhost:7051 --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestJoin_org2_peer_to_a_channel(t *testing.T) {\n\theader(\"Join a peer to a channel\")\n\trun(\"fabric-cli.go channel join --cid mychannel --peer localhost:8051 --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestJoin_all_peers_in_org1_to_a_channel(t *testing.T) {\n\theader(\"Join all peers in org1 to a channel\")\n\trun(\"fabric-cli.go channel join --cid mychannel --orgid org1 --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestJoin_all_peers_in_org2_to_a_channel(t *testing.T) {\n\theader(\"Join all peers in org1 to a channel\")\n\trun(\"fabric-cli.go channel join --cid mychannel --orgid org2 --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestJoin_all_peers_to_a_channel(t *testing.T) {\n\theader(\"Join all peers to a channel\")\n\trun(\"fabric-cli.go channel join --cid mychannel --config ../fixtures/config/config_test_local.yaml\")\n}\n\n//// ********** Install chaincode ************ ////\n\nfunc TestInstall_chaincode_on_all_peers_of_org1(t *testing.T) {\n\theader(\"Install chaincode on all peers of org1\")\n\trun(\"fabric-cli.go chaincode install --cid mychannel --orgid org1 --ccp github.com/example_cc --ccid ExampleCC --v v0 --gopath ../fixtures/testdata --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestInstall_chaincode_on_all_peers_of_org2(t *testing.T) {\n\theader(\"Install chaincode on all peers of org2\")\n\trun(\"fabric-cli.go chaincode install --cid=mychannel --orgid org2 --ccp=github.com/example_cc --ccid=ExampleCC --v v0 --gopath ../fixtures/testdata --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestInstall_chaincode_on_all_peers(t *testing.T) {\n\theader(\"Install chaincode on all peers\")\n\trun(\"fabric-cli.go chaincode install --cid=mychannel --ccp=github.com/example_cc --ccid=ExampleCC --v v0 --gopath ../fixtures/testdata --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestInstall_chaincode_on_all_peers_v1(t *testing.T) {\n\theader(\"Install chaincode on all peers\")\n\trun(\"fabric-cli.go chaincode install --cid=mychannel --ccp=github.com/example_cc --ccid=ExampleCC --v v1 --gopath ../fixtures/testdata --config ../fixtures/config/config_test_local.yaml\")\n}\n\n//// ********** Instantiate ************ ////\n\nfunc TestInstantiate_chaincode_with_default_endorsement_policy(t *testing.T) {\n\theader(\"Instantiate chaincode with default endorsement policy\")\n\trun(\"fabric-cli.go chaincode instantiate --cid mychannel --ccp=github.com/example_cc --ccid ExampleCC --v v0 --args {\\\"Args\\\":[\\\"A\\\",\\\"1\\\",\\\"B\\\",\\\"2\\\"]} --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestInstantiate_chaincode_with_specified_endorsement_policy(t *testing.T) {\n\theader(\"Instantiate chaincode with specified endorsement policy\")\n\trun(\"fabric-cli.go chaincode instantiate --cid mychannel --ccp=github.com/example_cc --ccid ExampleCC --v v0 --args {\\\"Args\\\":[\\\"A\\\",\\\"1\\\",\\\"B\\\",\\\"2\\\"]} --policy AND('Org1MSP.member','Org2MSP.member') --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestInstantiate_chaincode_with_specified_private_data_collection_configuration(t *testing.T) {\n\theader(\"Instantiate chaincode with specified private data collection configuration\")\n\trun(\"fabric-cli.go chaincode instantiate --cid mychannel --ccp=github.com/example_cc --ccid ExampleCC --v v0 --args {\\\"Args\\\":[\\\"A\\\",\\\"1\\\",\\\"B\\\",\\\"2\\\"]} --policy AND('Org1MSP.member','Org2MSP.member') --collconfig ../fixtures/config/pvtdatacollection.json --config ../fixtures/config/config_test_local.yaml\")\n}\n\n//// ********** Upgrade chaincode to v1 ************ ////\n\nfunc TestUpgrade_chaincode_to_v1(t *testing.T) {\n\theader(\"Upgrade chaincode\")\n\t//run(\"fabric-cli.go chaincode upgrade --cid mychannel --ccp=github.com/example_cc --ccid ExampleCC --v v1 --args {\\\"Args\\\":[\\\"A\\\",\\\"1\\\",\\\"B\\\",\\\"2\\\"]} --policy AND('Org1MSP.member','Org2MSP.member') --config ../fixtures/config/config_test_local.yaml\")\n\trun(\"fabric-cli.go chaincode upgrade --cid mychannel --ccp=github.com/example_cc --ccid ExampleCC --v v1 --args {\\\"Args\\\":[\\\"A\\\",\\\"1\\\",\\\"B\\\",\\\"2\\\"]} --config ../fixtures/config/config_test_local.yaml\")\n}\n\n//// ********** Query channel ************ ////\n\nfunc TestQuery_info(t *testing.T) {\n\theader(\"Query info\")\n\trun(\"fabric-cli.go query info --cid mychannel --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestQuery_block_by_block_number(t *testing.T) {\n\theader(\"Query block by block number\")\n\trun(\"fabric-cli.go query block --cid mychannel --num 0 --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestQuery_block_by_hash(t *testing.T) {\n\theader(\"Query block by hash\")\n\t// hash is the output of \"query info\"\n\trun(\"fabric-cli.go query block --cid mychannel --hash HnjHWaHuTr813ettkpL7LXRx20QxY3X9MVbJesGqs6o --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestQuery_block_output_in_JSON_format(t *testing.T) {\n\theader(\"Query block output in JSON format\")\n\trun(\"fabric-cli.go query block --cid mychannel --num 0 --format json --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestQuery_transaction(t *testing.T) {\n\theader(\"Query transaction\")\n\trun(\"fabric-cli.go query tx --cid mychannel --txid 711451464d26a5564fa7066f0d2acb513b79800d4e4b11e144492bb620155210 --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestQuery_channels_joined_by_a_peer(t *testing.T) {\n\theader(\"Query channels joined by a peer\")\n\trun(\"fabric-cli.go query channels --peer localhost:7051 --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestQuery_installed_chaincodes_on_a_peer(t *testing.T) {\n\theader(\"Query installed chaincodes on a peer\")\n\trun(\"fabric-cli.go query installed --peer localhost:7051 --config ../fixtures/config/config_test_local.yaml\")\n}\n\n//// ********** Retrieve chaincode deployment info ************ ////\n\nfunc TestRetrieve_chaincode_deployment_info(t *testing.T) {\n\theader(\"Retrieve chaincode deployment info\")\n\trun(\"fabric-cli.go chaincode info --cid mychannel --ccid ExampleCC --config ../fixtures/config/config_test_local.yaml\")\n}\n\n//// ********** Query Chaincode ************ ////\n\nfunc TestQuery_chaincode_on_a_set_of_peers(t *testing.T) {\n\theader(\"Query chaincode on a set of peers\")\n\trun(\"fabric-cli.go chaincode query --ccid ExampleCC --args {\\\"Func\\\":\\\"query\\\",\\\"Args\\\":[\\\"A\\\"]} --peer localhost:7051,localhost:8051 --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestQuery_chaincode_and_view_payloads_only(t *testing.T) {\n\theader(\"Query chaincode and view payloads only\")\n\trun(\"fabric-cli.go chaincode query --ccid=ExampleCC --args {\\\"Func\\\":\\\"query\\\",\\\"Args\\\":[\\\"A\\\"]} --peer localhost:7051,localhost:8051 --payload --config ../fixtures/config/config_test_local.yaml\")\n}\n\n//// ********** Invoke Chaincode ************ ////\n\nfunc TestInvoke_chaincode(t *testing.T) {\n\theader(\"Invoke chaincode\")\n\trun(\"fabric-cli.go chaincode invoke --ccid=ExampleCC --args {\\\"Func\\\":\\\"move\\\",\\\"Args\\\":[\\\"A\\\",\\\"B\\\",\\\"1\\\"]} --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestInvoke_chaincode_5_times(t *testing.T) {\n\theader(\"Invoke chaincode 5 times\")\n\trun(\"fabric-cli.go chaincode invoke --ccid=ExampleCC --args {\\\"Func\\\":\\\"move\\\",\\\"Args\\\":[\\\"A\\\",\\\"B\\\",\\\"1\\\"]} --iterations 5 --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestInvoke_chaincode_100_times_in_8_Go_routines(t *testing.T) {\n\theader(\"Invoke chaincode 100 times in 8 Go routines with 3 attempts for each invocation (in case the invocation fails)\")\n\trun(\"fabric-cli.go chaincode invoke --ccid=ExampleCC --args {\\\"Func\\\":\\\"move\\\",\\\"Args\\\":[\\\"A\\\",\\\"B\\\",\\\"1\\\"]} --iterations 100 --concurrency 8 --attempts 3 --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestInvoke_chaincode_with_two_sets_of_args(t *testing.T) {\n\theader(\"Invoke chaincode with two sets of args, 100 times each in 8 Go routines with 3 attempts for each invocation (in case the invocation fails)\")\n\trun(\"fabric-cli.go chaincode invoke --ccid=ExampleCC --args [{\\\"Func\\\":\\\"move\\\",\\\"Args\\\":[\\\"A\\\",\\\"B\\\",\\\"1\\\"]},{\\\"Func\\\":\\\"move\\\",\\\"Args\\\":[\\\"B\\\",\\\"A\\\",\\\"2\\\"]}] --iterations 100 --concurrency 8 --attempts 3 --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestInvoke_chaincode_using_dynamic_selection_provider(t *testing.T) {\n\theader(\"Invoke chaincode using a 'dynamic' selection provider that chooses a minimal set of peers required to satisfy the endorsement policy of the chaincode:\")\n\trun(\"fabric-cli.go chaincode invoke --ccid=ExampleCC --args {\\\"Func\\\":\\\"move\\\",\\\"Args\\\":[\\\"A\\\",\\\"B\\\",\\\"1\\\"]} --orgid org1,org2 --selectprovider=dynamic --config ../fixtures/config/config_test_local.yaml\")\n}\n\n//// ********** Events ************ ////\n\nfunc TestListen_for_block_events(t *testing.T) {\n\theader(\"Listen for block events (output in JSON)\")\n\trun(\"fabric-cli.go event listenblock --format json --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestListen_for_filtered_block_events(t *testing.T) {\n\theader(\"Listen for filtered block events (output in JSON)\")\n\trun(\"fabric-cli.go event listenfilteredblock --format json --config ../fixtures/config/config_test_local.yaml\")\n}\n\nfunc TestListen_for_chaincode_events(t *testing.T) {\n\theader(\"Listen for chaincode events\")\n\trun(\"fabric-cli.go event listencc --ccid=ExampleCC --event=testEvent --config ../fixtures/config/config_test_local.yaml\")\n}\n"
  },
  {
    "path": "fabric-cli/test/integration/go.mod",
    "content": "// Copyright SecureKey Technologies Inc. All Rights Reserved.\n//\n// SPDX-License-Identifier: Apache-2.0\n\nmodule github.com/securekey/fabric-examples/integration\n\nrequire github.com/securekey/fabric-examples/fabric-cli v0.0.0\n\nreplace github.com/securekey/fabric-examples/fabric-cli v0.0.0 => ../../../fabric-cli/cmd/fabric-cli\n\ngo 1.13\n"
  },
  {
    "path": "fabric-cli/test/integration/go.sum",
    "content": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ngithub.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg=\ngithub.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=\ngithub.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=\ngithub.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=\ngithub.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5 h1:PqZ3bA4yzwywivzk7PBQWngJp2/PAS0bWRZerKteicY=\ngithub.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=\ngithub.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=\ngithub.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=\ngithub.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=\ngithub.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=\ngithub.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/google/certificate-transparency-go v0.0.0-20180222191210-5ab67e519c93 h1:qdfmdGwtm13OVx+AxguOWUTbgmXGn2TbdUHipo3chMg=\ngithub.com/google/certificate-transparency-go v0.0.0-20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce h1:xdsDDbiBDQTKASoGEZ+pEmF1OnWuu8AQ9I8iNbHNeno=\ngithub.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=\ngithub.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=\ngithub.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=\ngithub.com/hyperledger/fabric-lib-go v1.0.0 h1:UL1w7c9LvHZUSkIvHTDGklxFv2kTeva1QI2emOVc324=\ngithub.com/hyperledger/fabric-lib-go v1.0.0/go.mod h1:H362nMlunurmHwkYqR5uHL2UDWbQdbfz74n8kbCFsqc=\ngithub.com/hyperledger/fabric-protos-go v0.0.0-20190821180310-6b6ac9042dfd h1:z0IbaMd4Ry2Cmmxujzy4UDgCUsT/0dOqqoGtOcvDw9Q=\ngithub.com/hyperledger/fabric-protos-go v0.0.0-20190821180310-6b6ac9042dfd/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0=\ngithub.com/hyperledger/fabric-protos-go v0.0.0-20191121202242-f5500d5e3e85/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0=\ngithub.com/hyperledger/fabric-protos-go v0.0.0-20191204195335-3ddf3f16d6cf/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0=\ngithub.com/hyperledger/fabric-sdk-go v1.0.0-alpha5.0.20190827185549-6c3f788a32f8 h1:VUal7sIRsOAO8KBIcStUTEmda41y5eTbZhQfHRDq4Uk=\ngithub.com/hyperledger/fabric-sdk-go v1.0.0-alpha5.0.20190827185549-6c3f788a32f8/go.mod h1:H5Atl/PpXhEKYYShSLFElohDoB11o4/R0OwBxOs7hcM=\ngithub.com/hyperledger/fabric-sdk-go v1.0.0-beta1.0.20190930220855-cea2ffaf627c/go.mod h1:i8yJ9t8i1fGe7opUcq6uESxhruMJNXlc+Rx9ooBZsYg=\ngithub.com/hyperledger/fabric-sdk-go v1.0.0-beta1.0.20191219180315-e1055f391525/go.mod h1:/s224b8NLvOJOCIqBvWd9O6u7GE33iuIOT6OfcTE1OE=\ngithub.com/hyperledger/fabric-sdk-go v1.0.0-beta1.0.20200106161850-8f3d32c9d1a6/go.mod h1:/s224b8NLvOJOCIqBvWd9O6u7GE33iuIOT6OfcTE1OE=\ngithub.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=\ngithub.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=\ngithub.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=\ngithub.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/miekg/pkcs11 v0.0.0-20190329070431-55f3fac3af27 h1:XA/VH+SzpYyukhgh7v2mTp8rZoKKITXR/x3FIizVEXs=\ngithub.com/miekg/pkcs11 v0.0.0-20190329070431-55f3fac3af27/go.mod h1:WCBAbTOdfhHhz7YXujeZMF7owC4tPb1naKFsgfUISjo=\ngithub.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/mitchellh/mapstructure v0.0.0-20180511142126-bb74f1db0675 h1:/rdJjIiKG5rRdwG5yxHmSE/7ZREjpyC0kL7GxGT/qJw=\ngithub.com/mitchellh/mapstructure v0.0.0-20180511142126-bb74f1db0675/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=\ngithub.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=\ngithub.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=\ngithub.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=\ngithub.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=\ngithub.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=\ngithub.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=\ngithub.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=\ngithub.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prometheus/client_golang v0.8.0 h1:1921Yw9Gc3iSc4VQh3PIoOqgPCZS7G/4xQNVUp8Mda8=\ngithub.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/common v0.0.0-20180518154759-7600349dcfe1/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=\ngithub.com/prometheus/common v0.0.0-20180801064454-c7de2306084e h1:n/3MEhJQjQxrOUCzh1Y3Re6aJUUWRp2M9+Oc3eVn/54=\ngithub.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=\ngithub.com/prometheus/procfs v0.0.0-20180705121852-ae68e2d4c00f/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.0-20180920065004-418d78d0b9a7 h1:NgR6WN8nQ4SmFC1sSUHY8SriLuWCZ6cCIQtH4vDZN3c=\ngithub.com/prometheus/procfs v0.0.0-20180920065004-418d78d0b9a7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/securekey/fabric-examples v0.0.0-20190226225026-644fda76ee3b h1:hUFS/EkSw2bclWJ5nNpYYijbQhZIOxqGb74AR3RkfF4=\ngithub.com/securekey/fabric-examples v0.0.0-20190226225026-644fda76ee3b/go.mod h1:TFB0Em4NQmx/PNpsdoJxqRwdS9j70aGbdTL/pqgc8DE=\ngithub.com/spf13/afero v1.1.0/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=\ngithub.com/spf13/afero v1.1.1 h1:Lt3ihYMlE+lreX1GS4Qw4ZsNpYQLxIXKBTEOXm3nt6I=\ngithub.com/spf13/afero v1.1.1/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=\ngithub.com/spf13/cast v1.2.0 h1:HHl1DSRbEQN2i8tJmtS6ViPyHx35+p51amrdsiTCrkg=\ngithub.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=\ngithub.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=\ngithub.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=\ngithub.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec h1:2ZXvIUGghLpdTVHR1UfvfrzoVlZaE/yOWC5LueIHZig=\ngithub.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=\ngithub.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4=\ngithub.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=\ngithub.com/spf13/viper v1.0.2 h1:Ncr3ZIuJn322w2k1qmzXDnkLAdQMlJqBa9kfAH+irso=\ngithub.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd h1:HuTn7WObtcDo9uEEU7rEqL0jYthdXAmZ6PP+meazmaU=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=\ngolang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190327125643-d831d65fe17d h1:XB2jc5XQ9uhizGTS2vWcN01bc4dI6z3C4KY5MQm8SS8=\ngoogle.golang.org/genproto v0.0.0-20190327125643-d831d65fe17d/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=\ngopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=\ngopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=\ngopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\n"
  }
]