Showing preview only (331K chars total). Download the full file or copy to clipboard to get everything.
Repository: securekey/fabric-examples
Branch: master
Commit: 600b6db41b10
Files: 63
Total size: 310.4 KB
Directory structure:
gitextract_8xm2cptt/
├── .gitignore
├── .gitreview
├── README.md
└── fabric-cli/
├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── cmd/
│ └── fabric-cli/
│ ├── action/
│ │ ├── action.go
│ │ └── svcproviderfactory.go
│ ├── chaincode/
│ │ ├── chaincodecmd.go
│ │ ├── getinfocmd.go
│ │ ├── installcmd.go
│ │ ├── instantiatecmd.go
│ │ ├── invokecmd.go
│ │ ├── invokeerror/
│ │ │ └── invokeerror.go
│ │ ├── invoketask/
│ │ │ └── invoketask.go
│ │ ├── multitask/
│ │ │ └── multitask.go
│ │ ├── querycmd.go
│ │ ├── querytask/
│ │ │ └── querytask.go
│ │ ├── task/
│ │ │ └── task.go
│ │ ├── upgradecmd.go
│ │ └── utils/
│ │ ├── test.json
│ │ ├── util.go
│ │ └── util_test.go
│ ├── channel/
│ │ ├── channelcmd.go
│ │ ├── channelcreatecmd.go
│ │ └── channeljoincmd.go
│ ├── cmd/
│ │ └── fabric-cli.go
│ ├── config/
│ │ └── config.go
│ ├── event/
│ │ ├── eventcmd.go
│ │ ├── inputevent.go
│ │ ├── listenblockcmd.go
│ │ ├── listencccmd.go
│ │ ├── listenfilteredblockcmd.go
│ │ └── listentxcmd.go
│ ├── executor/
│ │ ├── executor.go
│ │ └── worker/
│ │ ├── worker.go
│ │ └── workerpool.go
│ ├── fabric-cli.go
│ ├── go.mod
│ ├── go.sum
│ ├── printer/
│ │ ├── blockprinter.go
│ │ ├── formatter.go
│ │ ├── printer.go
│ │ ├── protoutils.go
│ │ └── writer.go
│ └── query/
│ ├── queryblockcmd.go
│ ├── querychannelscmd.go
│ ├── querycmd.go
│ ├── queryinfocmd.go
│ ├── queryinstalledcmd.go
│ ├── querylocalpeerscmd.go
│ ├── querypeerscmd.go
│ └── querytxcmd.go
└── test/
├── fixtures/
│ ├── config/
│ │ ├── config_test_local.yaml
│ │ └── pvtdatacollection.json
│ └── testdata/
│ └── src/
│ ├── github.com/
│ │ └── securekey/
│ │ ├── example2_cc/
│ │ │ └── example2_cc.go
│ │ └── example_cc/
│ │ └── example_cc.go
│ ├── go.mod
│ └── go.sum
└── integration/
├── fabric-cli_test.go
├── go.mod
└── go.sum
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
#
# Copyright SecureKey Technologies Inc. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
*.db
*report.xml
.DS_Store
.vscode
debug.test
vendor/
.idea/
/fabric-cli/cmd/fabric-cli/fabric-cli
================================================
FILE: .gitreview
================================================
[gerrit]
host=gerrit.securekey.com
port=29418
project=fabric-examples
================================================
FILE: README.md
================================================
fabric-examples
================================================
FILE: fabric-cli/.gitignore
================================================
#
# Copyright SecureKey Technologies Inc. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
vendor/
fabric-sdk-go/
================================================
FILE: fabric-cli/LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: fabric-cli/Makefile
================================================
#
# Copyright SecureKey Technologies Inc. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
# Supported Targets:
#
# populate-sdk: retrieves all fabric-sdk-files required for tests
# fabric-sdk-go-pin: populates only upstream files (not included in git)
# example-network: start the example fabric network
# example-network-clean: stops any running network and cleans up the artifacts
# clean: removes all generated artifacts
#
# Tool commands (overridable)
GO_CMD ?= go
GO_DEP_CMD ?= dep
DOCKER_CMD ?= docker
DOCKER_COMPOSE_CMD ?= docker-compose
# fabric-sdk-go version (overridable)
FABRIC_SDK_GO_BRANCH ?= master
FABRIC_SDK_GO_COMMIT ?= 8f3d32c9d1a66f88d405c9f5335870c5277f773a
# Test fixture paths
FIXTURE_DOCKERENV_PATH := fabric-sdk-go/test/fixtures/dockerenv
.PHONY: polulate-sdk
populate-sdk: fabric-sdk-go-pin fabric-sdk-go-populate
.PHONY: fabric-sdk-go-pin
fabric-sdk-go-pin:
@echo "Pinning fabric-sdk-go ..."
@UPSTREAM_COMMIT=$(FABRIC_SDK_GO_COMMIT) UPSTREAM_BRANCH=$(FABRIC_SDK_GO_BRANCH) scripts/fabric-sdk-go/apply_upstream.sh
.PHONY: fabric-sdk-go-populate
fabric-sdk-go-populate:
@scripts/fabric-sdk-go/populate.sh
.PHONY: clean
clean: example-network-clean
rm -Rf vendor
rm -Rf fabric-sdk-go
.PHONY: example-network
example-network:
@cd ./fabric-sdk-go && \
make dockerenv-stable-up
.PHONY: example-network-clean
example-network-clean:
@DOCKER_CMD=$(DOCKER_CMD) scripts/fabric-sdk-go/example-network-clean.sh
================================================
FILE: fabric-cli/README.md
================================================
# Fabric CLI Sample Application
Fabric CLI is a sample command-line interface built using Fabric SDK GO. It provides the following functionality:
Channel:
- Create - Create a channel
- Join - Join a peer to a channel
Query:
- Info - Displays information about the block, including the block height
- Block - Displays the contents of a given block
- Tx - Displays the contents of a transaction within a block
- Channels - Displays all channels for a peer
- Installed - Displays the chaincodes installed on a peer
- Peers - Displays the discovered peers on a channel
- Local Peers - Displays the discovered local peers in an org
Chaincode:
- Install - Installs chaincode
- Instantiate - Instantiates chaincode
- Upgrade - Upgrades chaincode
- Invoke - Invokes chaincode with a transaction proposal and a commit
- Query - Invokes chaincode without a commit
- Info - Retrieves details about the chaincode
Events:
- Listen Block - Listens for block events and displays the block when a new block is created
- Listen Filtered Block - Listens for filtered block events and displays the filtered block when a new block is created
- Listen TX - Listens for transaction events
- Listen CC - Listens for chaincode events for a specified chaincode
## Running
NOTE: If using Go 1.11 or 1.12, you'll need to set the following environment variable:
```bash
export GO111MODULE=on
```
Run the client:
```bash
go run fabric-cli.go <command> <sub-command> [options]
```
To display the available commands/options:
```bash
go run fabric-cli.go
```
## Compatability
This example is compatible with the following Hyperledger Fabric/SDK commit levels:
- fabric: v1.3.0, v1.4, v2.0
- fabric-sdk-go: master:33f4504ff8f169ebddd822443eadbe1bf4b96887
### Quick Tour
Start the example HLF network locally
```bash
make populate-sdk
make example-network
```
Open another shell and go to the CLI directory
```bash
cd $GOPATH/src/github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli
```
Create channel 'orgchannel' and add anchor peers
```bash
go 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
go 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
go 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
```
Join all peers to channel 'orgchannel'
```bash
go run fabric-cli.go channel join --cid orgchannel --config ../../test/fixtures/config/config_test_local.yaml
```
Install ExampleCC chaincode on all peers
```bash
go 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
```
Instantiate ExampleCC chaincode with endorsement policy AND('Org1MSP.member','Org2MSP.member')
```bash
go 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
```
Query ExampleCC chaincode on a set of peers
```bash
go 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
```
Listen for block events:
```bash
go run fabric-cli.go event listenblock --cid orgchannel --base64 --config ../../test/fixtures/config/config_test_local.yaml
```
Then invoke ExampleCC chaincode in another shell and observe block events in the first shell.
```bash
go 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
```
To clean up example network artifacts run
```bash
make example-network-clean
```
To clean up all generated artifacts run
```bash
make clean
```
## CLI examples
### Channel
#### Create a channel
```bash
go 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
```
#### Update anchor peers
```bash
go 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
go 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
```
#### Join a peer to a channel
```bash
go run fabric-cli.go channel join --cid orgchannel --peer localhost:7051 --config ../../test/fixtures/config/config_test_local.yaml
```
#### Join all peers in org1 to a channel
```bash
go run fabric-cli.go channel join --cid orgchannel --orgid org1 --config ../../test/fixtures/config/config_test_local.yaml
```
#### Join all peers to a channel
```bash
go run fabric-cli.go channel join --cid orgchannel --config ../../test/fixtures/config/config_test_local.yaml
```
### Query
#### Query info
```bash
go run fabric-cli.go query info --cid orgchannel --config ../../test/fixtures/config/config_test_local.yaml
```
#### Query block by block number
```bash
go run fabric-cli.go query block --cid orgchannel --num 0 --base64 --config ../../test/fixtures/config/config_test_local.yaml
```
#### Query block by hash (replace the example hash with a valid hash, e.g. using the output from query info)
```bash
go run fabric-cli.go query block --cid orgchannel --hash BNNsxK_Xyz2d3Yj2g6M2t3aOYkHCxvoPeIGmTWdOJ9w --base64 --config ../../test/fixtures/config/config_test_local.yaml
```
#### Query block output in JSON format
```bash
go run fabric-cli.go query block --cid orgchannel --num 0 --format json --config ../../test/fixtures/config/config_test_local.yaml
```
#### Query transaction (replace txid with a valid transaction, e.g. using the output from query block)
```bash
go run fabric-cli.go query tx --cid orgchannel --txid 0ed409872e0e6a6aa745df10d5e71e33d7e160b84519c2ad89281e65b6561364 --base64 --config ../../test/fixtures/config/config_test_local.yaml
```
#### Query channels joined by a peer
```bash
go run fabric-cli.go query channels --peer localhost:7051 --config ../../test/fixtures/config/config_test_local.yaml
```
#### Query installed chaincodes on a peer
```bash
go run fabric-cli.go query installed --peer localhost:7051 --config ../../test/fixtures/config/config_test_local.yaml
```
#### Query discovered peers on a channel
```bash
go run fabric-cli.go query peers --cid orgchannel --config ../../test/fixtures/config/config_test_local.yaml
```
#### Query discovered peers in an org
```bash
go run fabric-cli.go query localpeers --orgid org1 --config ../../test/fixtures/config/config_test_local.yaml
```
## Chaincode
### Install Chaincode
#### Install chaincode on a peer
```bash
go 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
```
#### Install chaincode on all peers of org1
```bash
go 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
```
#### Install chaincode on all peers
```bash
go 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
```
### Instantiate and Upgrade Chaincode
#### Instantiate chaincode with default endorsement policy (any one)
```bash
go 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
```
#### Instantiate chaincode with specified endorsement policy
```bash
go 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
```
#### Instantiate chaincode with specified private data collection configuration (Fabric 1.2 and greater)
```bash
go 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
go 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
```
#### Upgrade chaincode
```bash
go 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
go 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
```
### Chaincode Info
#### Retrieve chaincode deployment info
```bash
go run fabric-cli.go chaincode info --cid orgchannel --ccid examplecc --base64 --config ../../test/fixtures/config/config_test_local.yaml
```
### Query Chaincode
#### Query chaincode on a set of peers
```bash
go 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
```
#### Query chaincode and view payloads only
```bash
go 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
```
### Invoke Chaincode
#### Invoke chaincode on all peers in org1
```bash
go 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
```
#### Invoke chaincode using a 'dynamic' selection provider that chooses a minimal set of peers required to satisfy the endorsement policy of the chaincode
```bash
go 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
```
#### 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)
```bash
go 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
```
#### Invoke chaincode using a selection provider automatically determined from channel capabilities ('dynamic' for v1.1; 'fabric' for >=v1.2)
```bash
go 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
```
#### Invoke chaincode 5 times
```bash
go 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
```
#### Invoke chaincode 100 times in 8 Go routines with a maximum of 5 attempts for each invocation (in case the invocation fails)
```bash
go 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
```
#### 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)
```bash
go 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
```
#### Invoke chaincode 100 times in 8 Go routines using randomly generated keys, values, and variables
```bash
go 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
```
#### Invoke chaincode 100 times in 8 Go routines using sequentially generated keys and large values
```bash
go 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
```
#### Invoke chaincode 100 times in 8 Go routines using randomly generated keys and random size values
```bash
go 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
```
#### Invoke a chaincode using the contents of a file as a value
```bash
go 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
```
## Event
### Block Events
### Listen for block events on a specific peer (output in JSON)
```bash
go run fabric-cli.go event listenblock --cid orgchannel --peer localhost:7051 --format json --config ../../test/fixtures/config/config_test_local.yaml
```
### Listen for block events starting from block number 20
```bash
go run fabric-cli.go event listenblock --cid orgchannel --peer localhost:7051 --seek from --num 20 --base64 --config ../../test/fixtures/config/config_test_local.yaml
```
### Listen for filtered block events (output in JSON)
```bash
go run fabric-cli.go event listenfilteredblock --cid orgchannel --format json --config ../../test/fixtures/config/config_test_local.yaml
```
### Listen for chaincode events
```bash
go run fabric-cli.go event listencc --cid orgchannel --ccid=examplecc --event=.* --config ../../test/fixtures/config/config_test_local.yaml
```
### Listen for tx event
```bash
go run fabric-cli.go event listentx --cid orgchannel --txid <txid> --config ../../test/fixtures/config/config_test_local.yaml
```
================================================
FILE: fabric-cli/cmd/fabric-cli/action/action.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package action
import (
"encoding/json"
"math/rand"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core"
"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/factory/defcore"
"github.com/pkg/errors"
"strings"
"io"
"fmt"
"github.com/hyperledger/fabric-sdk-go/pkg/client/channel"
"github.com/hyperledger/fabric-sdk-go/pkg/client/event"
"github.com/hyperledger/fabric-sdk-go/pkg/client/ledger"
"github.com/hyperledger/fabric-sdk-go/pkg/client/msp"
"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt"
"github.com/hyperledger/fabric-sdk-go/pkg/common/logging"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
mspapi "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp"
contextImpl "github.com/hyperledger/fabric-sdk-go/pkg/context"
cryptosuiteimpl "github.com/hyperledger/fabric-sdk-go/pkg/core/cryptosuite/bccsp/multisuite"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/orderer"
"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/printer"
"github.com/spf13/pflag"
)
const (
defaultUser = "User1" // pre-enrolled user
adminUser = "Admin"
)
// ArgStruct is used for marshalling arguments to chaincode invocations
type ArgStruct struct {
Func string `json:"Func"`
Args []string `json:"Args"`
}
// Action is the base implementation of the Action interface.
type Action struct {
flags *pflag.FlagSet
sdk *fabsdk.FabricSDK
endpointConfig fab.EndpointConfig
peersByOrg map[string][]fab.Peer
peers []fab.Peer
orgIDByPeer map[string]string
printer printer.Printer
initError error
Writer io.Writer
sessions map[string]context.ClientProvider
}
// Initialize initializes the action using the given flags
func (action *Action) Initialize(flags *pflag.FlagSet) error {
action.sessions = make(map[string]context.ClientProvider)
action.flags = flags
if err := cliconfig.InitConfig(flags); err != nil {
return err
}
var opts []fabsdk.Option
if cliconfig.Config().SelectionProvider() != cliconfig.AutoDetectSelectionProvider {
svcPackage, err := newServiceProviderFactory()
if err != nil {
return err
}
opts = append(opts, fabsdk.WithServicePkg(svcPackage))
}
opts = append(opts, fabsdk.WithCorePkg(&cryptoSuiteProviderFactory{}))
sdk, err := fabsdk.New(cliconfig.Provider(), opts...)
if err != nil {
return errors.Errorf("Error initializing SDK: %s", err)
}
action.sdk = sdk
ctx, err := sdk.Context()()
if err != nil {
return errors.WithMessage(err, "Error creating anonymous provider")
}
action.endpointConfig = ctx.EndpointConfig()
networkConfig := action.endpointConfig.NetworkConfig()
level := levelFromName(cliconfig.Config().LoggingLevel())
logging.SetLevel("", level)
action.orgIDByPeer = make(map[string]string)
var allPeers []fab.Peer
allPeersByOrg := make(map[string][]fab.Peer)
for orgID := range networkConfig.Organizations {
peersConfig, ok := action.endpointConfig.PeersConfig(orgID)
if !ok {
return errors.Errorf("failed to get peer configs for org [%s]", orgID)
}
cliconfig.Config().Logger().Debugf("Peers for org [%s]: %v\n", orgID, peersConfig)
var peers []fab.Peer
for _, p := range peersConfig {
endorser, err := ctx.InfraProvider().CreatePeerFromConfig(&fab.NetworkPeer{PeerConfig: p})
if err != nil {
return errors.Wrapf(err, "failed to create peer from config")
}
peers = append(peers, endorser)
action.orgIDByPeer[endorser.URL()] = orgID
}
allPeersByOrg[orgID] = peers
allPeers = append(allPeers, peers...)
}
if cliconfig.Config().IsLoggingEnabledFor(logging.DEBUG) {
cliconfig.Config().Logger().Debug("All Peers:")
for orgID, peers := range allPeersByOrg {
cliconfig.Config().Logger().Debugf("Org: %s\n", orgID)
for i, peer := range peers {
cliconfig.Config().Logger().Debugf("-- Peer[%d]: MSPID: %s, URL: %s\n", i, peer.MSPID(), peer.URL())
}
}
}
// Filter peers by specified peers/orgs
peers, err := action.getPeers(allPeers, cliconfig.Config().PeerURLs(), cliconfig.Config().OrgIDs())
if err != nil {
return err
}
// Organize peers by orgs
peersByOrg := make(map[string][]fab.Peer)
cliconfig.Config().Logger().Debugf("Selected Peers:\n")
for _, peer := range peers {
cliconfig.Config().Logger().Debugf("- URL: %s\n", peer.URL())
orgID := action.orgIDByPeer[peer.URL()]
if orgID == "" {
return errors.Errorf("unable to find org for peer: %s", peer.URL())
}
peersByOrg[orgID] = append(peersByOrg[orgID], peer)
}
action.peers = peers
action.peersByOrg = peersByOrg
action.printer = printer.NewBlockPrinterWithOpts(
printer.AsOutputFormat(cliconfig.Config().PrintFormat()),
printer.AsWriterType(cliconfig.Config().Writer()),
&printer.FormatterOpts{Base64Encode: cliconfig.Config().Base64()})
return nil
}
// Terminate closes any open connections. This function should be called at the end of every command invocation.
func (action *Action) Terminate() {
if action.sdk != nil {
cliconfig.Config().Logger().Info("Closing SDK")
action.sdk.Close()
}
}
// Flags returns the flag-set
func (action *Action) Flags() *pflag.FlagSet {
return action.flags
}
// EndpointConfig returns the endpoint configuration
func (action *Action) EndpointConfig() fab.EndpointConfig {
return action.endpointConfig
}
// ChannelClient creates a new channel client
func (action *Action) ChannelClient(...channel.ClientOption) (*channel.Client, error) {
user, err := action.User()
if err != nil {
return nil, errors.Errorf("error getting user: %s", err)
}
session, err := action.context(user)
if err != nil {
return nil, errors.Errorf("error getting session for user [%s,%s]: %v", user.Identifier().MSPID, user.Identifier().ID, err)
}
channelProvider := func() (context.Channel, error) {
return contextImpl.NewChannel(session, cliconfig.Config().ChannelID())
}
return channel.New(channelProvider)
}
// OrgAdminChannelClient creates a new channel client for the given org in order to perform administrative functions
func (action *Action) OrgAdminChannelClient(orgID string) (*channel.Client, error) {
channelID := cliconfig.Config().ChannelID()
cliconfig.Config().Logger().Debugf("Creating new channel client for channel [%s] and org [%s] ...", channelID, orgID)
user, err := action.OrgAdminUser(orgID)
if err != nil {
return nil, err
}
channelClient, err := action.ClientForUser(channelID, user)
if err != nil {
return nil, errors.Errorf("error creating fabric client: %s", err)
}
return channelClient, nil
}
// AdminChannelClient creates a new channel client for performing administrative functions
func (action *Action) AdminChannelClient() (*channel.Client, error) {
return action.OrgAdminChannelClient(action.OrgID())
}
// Printer returns the Printer
func (action *Action) Printer() printer.Printer {
return action.printer
}
// LocalContext creates a new local context
func (action *Action) LocalContext() (context.Local, error) {
user, err := action.User()
if err != nil {
return nil, errors.Errorf("error getting user: %s", err)
}
contextProvider, err := action.context(user)
if err != nil {
return nil, errors.Errorf("error getting context for user [%s,%s]: %v", user.Identifier().MSPID, user.Identifier().ID, err)
}
return contextImpl.NewLocal(contextProvider)
}
// ChannelProvider returns the ChannelProvider
func (action *Action) ChannelProvider() (context.ChannelProvider, error) {
channelID := cliconfig.Config().ChannelID()
user, err := action.User()
if err != nil {
return nil, err
}
cliconfig.Config().Logger().Debugf("creating channel provider for user [%s] in org [%s]...", user.Identifier().ID, user.Identifier().MSPID)
clientContext, err := action.context(user)
if err != nil {
return nil, errors.Errorf("error getting client context for user [%s,%s]: %v", user.Identifier().MSPID, user.Identifier().ID, err)
}
channelProvider := func() (context.Channel, error) {
return contextImpl.NewChannel(clientContext, channelID)
}
return channelProvider, nil
}
// EventClient returns the event hub.
func (action *Action) EventClient(opts ...event.ClientOption) (*event.Client, error) {
channelProvider, err := action.ChannelProvider()
if err != nil {
return nil, errors.Errorf("error creating channel provider: %v", err)
}
c, err := event.New(channelProvider, opts...)
if err != nil {
return nil, errors.Errorf("error creating new event client: %v", err)
}
return c, nil
}
// LedgerClient returns the Fabric client for the current user
func (action *Action) LedgerClient() (*ledger.Client, error) {
channelProvider, err := action.ChannelProvider()
if err != nil {
return nil, errors.Errorf("error creating channel provider: %v", err)
}
c, err := ledger.New(channelProvider)
if err != nil {
return nil, errors.Errorf("error creating new ledger client: %v", err)
}
return c, nil
}
// Peer returns the first peer in the list of selected peers
func (action *Action) Peer() fab.Peer {
if len(action.peers) == 0 {
return nil
}
return action.peers[0]
}
// Peers returns the peers
func (action *Action) Peers() []fab.Peer {
return action.peers
}
// PeersByOrg returns the peers mapped by organization
func (action *Action) PeersByOrg() map[string][]fab.Peer {
return action.peersByOrg
}
// OrgOfPeer returns the organization ID of the given peer
func (action *Action) OrgOfPeer(peerURL string) (string, error) {
orgID, ok := action.orgIDByPeer[peerURL]
if !ok {
return "", errors.Errorf("org not found for peer %s", peerURL)
}
return orgID, nil
}
// Client returns the Fabric client for the current user
func (action *Action) Client(channelID string) (*channel.Client, error) {
user, err := action.User()
if err != nil {
return nil, err
}
return action.ClientForUser(channelID, user)
}
// ResourceMgmtClient returns a resource management client for the current user
func (action *Action) ResourceMgmtClient() (*resmgmt.Client, error) {
return action.ResourceMgmtClientForOrg(action.OrgID())
}
// ResourceMgmtClientForOrg returns a resource management client for the given org
func (action *Action) ResourceMgmtClientForOrg(orgID string) (*resmgmt.Client, error) {
user, err := action.OrgAdminUser(orgID)
if err != nil {
return nil, err
}
return action.ResourceMgmtClientForUser(user)
}
// ClientForUser returns the Channel client for the given user
func (action *Action) ClientForUser(channelID string, user mspapi.SigningIdentity) (*channel.Client, error) {
cliconfig.Config().Logger().Debugf("create resmgmt client for user [%s] in org [%s]...", user.Identifier().ID, user.Identifier().MSPID)
session, err := action.context(user)
if err != nil {
return nil, errors.Errorf("error getting session for user [%s,%s]: %v", user.Identifier().MSPID, user.Identifier().ID, err)
}
channelProvider := func() (context.Channel, error) {
return contextImpl.NewChannel(session, channelID)
}
c, err := channel.New(channelProvider)
if err != nil {
return nil, errors.Errorf("error creating new resmgmt client for user [%s,%s]: %v", user.Identifier().MSPID, user.Identifier().ID, err)
}
return c, nil
}
// ResourceMgmtClientForUser returns the Fabric client for the given user
func (action *Action) ResourceMgmtClientForUser(user mspapi.SigningIdentity) (*resmgmt.Client, error) {
cliconfig.Config().Logger().Debugf("create resmgmt client for user [%s] in org [%s]...", user.Identifier().ID, user.Identifier().MSPID)
session, err := action.context(user)
if err != nil {
return nil, errors.Errorf("error getting session for user [%s,%s]: %v", user.Identifier().MSPID, user.Identifier().ID, err)
}
c, err := resmgmt.New(session)
if err != nil {
return nil, errors.Errorf("error creating new resmgmt client for user [%s,%s]: %v", user.Identifier().MSPID, user.Identifier().ID, err)
}
return c, nil
}
// ChannelMgmtClientForUser returns the Fabric client for the given user
func (action *Action) ChannelMgmtClientForUser(channelID string, user mspapi.SigningIdentity) (*channel.Client, error) {
cliconfig.Config().Logger().Debugf("create channel client for user [%s] in org [%s]...", user.Identifier().ID, user.Identifier().MSPID)
session, err := action.context(user)
if err != nil {
return nil, errors.Errorf("error getting session for user [%s,%s]: %v", user.Identifier().MSPID, user.Identifier().ID, err)
}
channelProvider := func() (context.Channel, error) {
return contextImpl.NewChannel(session, channelID)
}
c, err := channel.New(channelProvider)
if err != nil {
return nil, errors.Errorf("error creating new channel client for user [%s,%s]: %v", user.Identifier().MSPID, user.Identifier().ID, err)
}
return c, nil
}
func (action *Action) context(user mspapi.SigningIdentity) (context.ClientProvider, error) {
key := user.Identifier().MSPID + "_" + user.Identifier().ID
session := action.sessions[key]
if session == nil {
session = action.sdk.Context(fabsdk.WithIdentity(user))
cliconfig.Config().Logger().Debugf("Created session for user [%s] in org [%s]", user.Identifier().ID, user.Identifier().MSPID)
action.sessions[key] = session
}
return session, nil
}
// OrgID returns the organization ID of the first peer in the list of peers
func (action *Action) OrgID() string {
if len(action.Peers()) == 0 {
// This shouldn't happen since we should already have passed validation
panic("no peers to choose from!")
}
peer := action.Peers()[0]
orgID, err := action.OrgOfPeer(peer.URL())
if err != nil {
// This shouldn't happen since we should already have passed validation
panic(err)
}
return orgID
}
// GetOrgID returns the organization ID for the given MSP ID
func (action *Action) GetOrgID(mspID string) (string, error) {
networkConfig := action.endpointConfig.NetworkConfig()
for orgID, orgConfig := range networkConfig.Organizations {
if mspID == orgConfig.MSPID {
return orgID, nil
}
}
return "", errors.Errorf("unable to find org ID for MSP [%s]", mspID)
}
// User returns the enrolled user. If the user doesn't exist then a new user is enrolled.
func (action *Action) User() (mspapi.SigningIdentity, error) {
userName := cliconfig.Config().UserName()
if userName == "" {
userName = defaultUser
}
return action.OrgUser(action.OrgID(), userName)
}
func (action *Action) newUser(orgID, username, pwd string) (mspapi.SigningIdentity, error) {
cliconfig.Config().Logger().Infof("Enrolling user %s...\n", username)
mspClient, err := msp.New(action.sdk.Context(), msp.WithOrg(orgID))
if err != nil {
return nil, errors.Errorf("error creating MSP client: %s", err)
}
cliconfig.Config().Logger().Infof("Creating new user %s...\n", username)
err = mspClient.Enroll(username, msp.WithSecret(pwd))
if err != nil {
return nil, errors.Errorf("Enroll returned error: %v", err)
}
user, err := mspClient.GetSigningIdentity(username)
if err != nil {
return nil, errors.Errorf("GetSigningIdentity returned error: %v", err)
}
cliconfig.Config().Logger().Infof("Returning user [%s], MSPID [%s]\n", user.Identifier().ID, user.Identifier().MSPID)
return user, nil
}
// OrgUser returns an already enrolled user for the given organization
func (action *Action) OrgUser(orgID, username string) (mspapi.SigningIdentity, error) {
if username == "" {
return nil, errors.Errorf("no username specified")
}
mspClient, err := msp.New(action.sdk.Context(), msp.WithOrg(orgID))
if err != nil {
return nil, errors.Errorf("error creating MSP client: %s", err)
}
user, err := mspClient.GetSigningIdentity(username)
if err != nil {
return nil, errors.Errorf("GetSigningIdentity returned error: %v", err)
}
cliconfig.Config().Logger().Infof("Returning user [%s], MSPID [%s]\n", user.Identifier().ID, user.Identifier().MSPID)
return user, nil
}
// OrgAdminUser returns the pre-enrolled administrative user for the given organization
func (action *Action) OrgAdminUser(orgID string) (mspapi.SigningIdentity, error) {
userName := cliconfig.Config().UserName()
if userName == "" {
userName = adminUser
}
return action.OrgUser(orgID, userName)
}
// PeerFromURL returns the peer for the given URL
func (action *Action) PeerFromURL(url string) (fab.Peer, bool) {
for _, peer := range action.peers {
if url == peer.URL() {
return peer, true
}
}
return nil, false
}
// Orderers returns all Orderers from the set of configured Orderers
func (action *Action) Orderers() ([]fab.Orderer, error) {
ordererConfigs := action.endpointConfig.OrderersConfig()
ordererURL := cliconfig.Config().OrdererURL()
var orderers []fab.Orderer
for _, ordererConfig := range ordererConfigs {
if ordererURL == "" || ordererConfig.URL == ordererURL {
newOrderer, err := orderer.New(action.endpointConfig, orderer.FromOrdererConfig(&ordererConfig))
if err != nil {
return nil, errors.WithMessage(err, "creating orderer failed")
}
orderers = append(orderers, newOrderer)
}
}
return orderers, nil
}
// RandomOrderer chooses a random Orderer from the set of configured Orderers
func (action *Action) RandomOrderer() (fab.Orderer, error) {
orderers, err := action.Orderers()
if err != nil {
return nil, err
}
if len(orderers) == 0 {
return nil, errors.New("No orders found")
}
return orderers[rand.Intn(len(orderers))], nil
}
// ArgsArray returns an array of args used in chaincode invocations
func ArgsArray() ([]ArgStruct, error) {
var argsArray []ArgStruct
argBytes := []byte(cliconfig.Config().Args())
if strings.HasPrefix(cliconfig.Config().Args(), "[") {
if err := json.Unmarshal(argBytes, &argsArray); err != nil {
return nil, errors.Errorf("Error unmarshaling JSON arg string: %v", err)
}
} else {
args := ArgStruct{}
if err := json.Unmarshal(argBytes, &args); err != nil {
return nil, errors.Errorf("Error unmarshaling JSON arg string: %v", err)
}
argsArray = append(argsArray, args)
}
return argsArray, nil
}
func levelFromName(levelName string) logging.Level {
switch levelName {
case "CRITICAL":
return logging.CRITICAL
case "ERROR":
return logging.ERROR
case "WARNING":
return logging.WARNING
case "INFO":
return logging.INFO
case "DEBUG":
return logging.DEBUG
default:
return logging.ERROR
}
}
func (action *Action) getPeers(allPeers []fab.Peer, peerURLs []string, orgIDs []string) ([]fab.Peer, error) {
selectAll := false
if len(peerURLs) == 0 && len(orgIDs) == 0 {
selectAll = true
}
var selectedPeers []fab.Peer
var allPeerURLs []string
for _, peer := range allPeers {
allPeerURLs = append(allPeerURLs, peer.URL())
orgID := action.orgIDByPeer[peer.URL()]
if selectAll || containsString(peerURLs, peer.URL()) || len(peerURLs) == 0 && containsString(orgIDs, orgID) {
selectedPeers = append(selectedPeers, peer)
}
}
for _, url := range peerURLs {
if !containsString(allPeerURLs, url) {
return nil, fmt.Errorf("invalid peer URL: %s", url)
}
}
return selectedPeers, nil
}
// PeerConfig returns the PeerConfig for the first peer in the current org
func (action *Action) PeerConfig() (*fab.PeerConfig, error) {
peersConfig, ok := action.endpointConfig.PeersConfig(action.OrgID())
if !ok {
return nil, errors.Errorf("Error reading peers config for %s: %v", action.OrgID())
}
peer := action.Peer()
for _, p := range peersConfig {
if peer.URL() == "" || p.URL == peer.URL() {
return &p, nil
}
}
return nil, errors.Errorf("No configuration found for peer %s", peer.URL())
}
// CreateDiscoveryService returns a new DiscoveryService for the given channel.
// This is an implementation of the DiscoveryProvider interface
func (action *Action) CreateDiscoveryService(channelID string) (fab.DiscoveryService, error) {
return action, nil
}
// GetPeers returns the peers in context.
// This is an implementation of the DiscoveryService interface
func (action *Action) GetPeers() ([]fab.Peer, error) {
return action.Peers(), nil
}
func containsString(sarr []string, s string) bool {
for _, str := range sarr {
if s == str {
return true
}
}
return false
}
// cryptoSuiteProviderFactory will provide custom cryptosuite (bccsp.BCCSP)
type cryptoSuiteProviderFactory struct {
defcore.ProviderFactory
}
// CreateCryptoSuiteProvider returns a new default implementation of BCCSP
func (f *cryptoSuiteProviderFactory) CreateCryptoSuiteProvider(config core.CryptoSuiteConfig) (core.CryptoSuite, error) {
return cryptosuiteimpl.GetSuiteByConfig(config)
}
================================================
FILE: fabric-cli/cmd/fabric-cli/action/svcproviderfactory.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package action
import (
"github.com/hyperledger/fabric-sdk-go/pkg/client/common/selection/dynamicselection"
"github.com/hyperledger/fabric-sdk-go/pkg/client/common/selection/fabricselection"
"github.com/hyperledger/fabric-sdk-go/pkg/client/common/selection/staticselection"
"github.com/hyperledger/fabric-sdk-go/pkg/common/options"
contextApi "github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/factory/defsvc"
"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk/provider/chpvdr"
"github.com/pkg/errors"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
)
// serviceProviderFactory is configured with either static or dynamic selection provider
type serviceProviderFactory struct {
defsvc.ProviderFactory
}
func newServiceProviderFactory() (*serviceProviderFactory, error) {
return &serviceProviderFactory{}, nil
}
type fabricSelectionChannelProvider struct {
fab.ChannelProvider
service fab.ChannelService
selection fab.SelectionService
}
type fabricSelectionChannelService struct {
fab.ChannelService
selection fab.SelectionService
}
// CreateChannelProvider returns a new default implementation of channel provider
func (f *serviceProviderFactory) CreateChannelProvider(config fab.EndpointConfig, opts ...options.Opt) (fab.ChannelProvider, error) {
chProvider, err := chpvdr.New(config, opts...)
if err != nil {
return nil, err
}
return &fabricSelectionChannelProvider{
ChannelProvider: chProvider,
}, nil
}
type closable interface {
Close()
}
// Close frees resources and caches.
func (cp *fabricSelectionChannelProvider) Close() {
if c, ok := cp.ChannelProvider.(closable); ok {
c.Close()
}
if cp.selection != nil {
if c, ok := cp.selection.(closable); ok {
c.Close()
}
}
}
type providerInit interface {
Initialize(providers contextApi.Providers) error
}
func (cp *fabricSelectionChannelProvider) Initialize(providers contextApi.Providers) error {
if init, ok := cp.ChannelProvider.(providerInit); ok {
return init.Initialize(providers)
}
return nil
}
// ChannelService creates a ChannelService for an identity
func (cp *fabricSelectionChannelProvider) ChannelService(ctx fab.ClientContext, channelID string) (fab.ChannelService, error) {
chService, err := cp.ChannelProvider.ChannelService(ctx, channelID)
if err != nil {
return nil, err
}
discovery, err := chService.Discovery()
if err != nil {
return nil, err
}
if cp.selection == nil {
switch cliconfig.Config().SelectionProvider() {
case cliconfig.StaticSelectionProvider:
cliconfig.Config().Logger().Debugf("Using static selection provider.")
cp.selection, err = staticselection.NewService(discovery)
case cliconfig.DynamicSelectionProvider:
cliconfig.Config().Logger().Debugf("Using dynamic selection provider.")
cp.selection, err = dynamicselection.NewService(ctx, channelID, discovery)
case cliconfig.FabricSelectionProvider:
cliconfig.Config().Logger().Debugf("Using Fabric selection provider.")
cp.selection, err = fabricselection.New(ctx, channelID, discovery)
default:
return nil, errors.Errorf("invalid selection provider: %s", cliconfig.Config().SelectionProvider())
}
if err != nil {
return nil, err
}
}
return &fabricSelectionChannelService{
ChannelService: chService,
selection: cp.selection,
}, nil
}
func (cs *fabricSelectionChannelService) Selection() (fab.SelectionService, error) {
return cs.selection, nil
}
================================================
FILE: fabric-cli/cmd/fabric-cli/chaincode/chaincodecmd.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package chaincode
import (
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/spf13/cobra"
)
var chaincodeCmd = &cobra.Command{
Use: "chaincode",
Short: "Chaincode commands",
Long: "Chaincode commands",
Run: func(cmd *cobra.Command, args []string) {
cmd.HelpFunc()(cmd, args)
},
}
// Cmd returns the chaincode command
func Cmd() *cobra.Command {
cliconfig.InitChannelID(chaincodeCmd.Flags())
chaincodeCmd.AddCommand(getInstallCmd())
chaincodeCmd.AddCommand(getInstantiateCmd())
chaincodeCmd.AddCommand(getInvokeCmd())
chaincodeCmd.AddCommand(getQueryCmd())
chaincodeCmd.AddCommand(getGetInfoCmd())
chaincodeCmd.AddCommand(getUpgradeCmd())
return chaincodeCmd
}
================================================
FILE: fabric-cli/cmd/fabric-cli/chaincode/getinfocmd.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package chaincode
import (
"fmt"
"strings"
"github.com/golang/protobuf/proto"
pb "github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric-sdk-go/pkg/client/channel"
"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/core/common/ccprovider"
"github.com/pkg/errors"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
const (
lifecycleSCC = "lscc"
getCCDataFunc = "getccdata"
getCollConfigFunc = "getcollectionsconfig"
)
var getInfoCmd = &cobra.Command{
Use: "info",
Short: "Get chaincode info",
Long: "Retrieves details about the chaincode",
Run: func(cmd *cobra.Command, args []string) {
if cliconfig.Config().ChaincodeID() == "" {
fmt.Printf("\nMust specify the chaincode ID\n\n")
cmd.HelpFunc()(cmd, args)
return
}
action, err := newGetInfoAction(cmd.Flags())
if err != nil {
cliconfig.Config().Logger().Errorf("Error while initializing getAction: %v", err)
return
}
defer action.Terminate()
err = action.invoke()
if err != nil {
cliconfig.Config().Logger().Errorf("Error while running getAction: %v", err)
}
},
}
func getGetInfoCmd() *cobra.Command {
flags := getInfoCmd.Flags()
cliconfig.InitPeerURL(flags)
cliconfig.InitChannelID(flags)
cliconfig.InitChaincodeID(flags)
return getInfoCmd
}
type getInfoAction struct {
action.Action
}
func newGetInfoAction(flags *pflag.FlagSet) (*getInfoAction, error) {
action := &getInfoAction{}
err := action.Initialize(flags)
if len(action.Peers()) == 0 {
return nil, errors.New("a peer must be specified")
}
return action, err
}
func (action *getInfoAction) invoke() error {
channelClient, err := action.ChannelClient()
if err != nil {
return errors.Errorf("error retrieving channel client: %v", err)
}
ccData, err := action.getCCData(channelClient)
if err != nil {
return errors.WithMessagef(err, "error querying for chaincode data")
}
collConfig, err := action.getCollConfig(channelClient)
if err != nil {
if !strings.Contains(errors.Cause(err).Error(), "collections config not defined for chaincode") {
return errors.WithMessagef(err, "error querying for collection config")
}
}
action.Printer().PrintChaincodeData(ccData, collConfig)
return nil
}
func (action *getInfoAction) getCCData(channelClient *channel.Client) (*ccprovider.ChaincodeData, error) {
var args [][]byte
args = append(args, []byte(cliconfig.Config().ChannelID()))
args = append(args, []byte(cliconfig.Config().ChaincodeID()))
peer := action.Peer()
fmt.Printf("querying chaincode info for %s on peer: %s...\n", cliconfig.Config().ChaincodeID(), peer.URL())
response, err := channelClient.Query(
channel.Request{ChaincodeID: lifecycleSCC, Fcn: getCCDataFunc, Args: args},
channel.WithTargetEndpoints(peer.URL()))
if err != nil {
return nil, errors.Errorf("error querying for chaincode info: %v", err)
}
ccData := &ccprovider.ChaincodeData{}
err = proto.Unmarshal(response.Payload, ccData)
if err != nil {
return nil, errors.Errorf("error unmarshalling chaincode data: %v", err)
}
return ccData, nil
}
func (action *getInfoAction) getCollConfig(channelClient *channel.Client) (*pb.CollectionConfigPackage, error) {
var args [][]byte
args = append(args, []byte(cliconfig.Config().ChaincodeID()))
peer := action.Peer()
fmt.Printf("querying collections config for %s on peer: %s...\n", cliconfig.Config().ChaincodeID(), peer.URL())
response, err := channelClient.Query(
channel.Request{ChaincodeID: lifecycleSCC, Fcn: getCollConfigFunc, Args: args},
channel.WithTargetEndpoints(peer.URL()))
if err != nil {
return nil, errors.Errorf("error querying for collections config: %v", err)
}
collConfig := &pb.CollectionConfigPackage{}
err = proto.Unmarshal(response.Payload, collConfig)
if err != nil {
return nil, errors.Errorf("error unmarshalling collections config: %v", err)
}
return collConfig, nil
}
================================================
FILE: fabric-cli/cmd/fabric-cli/chaincode/installcmd.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package chaincode
import (
"fmt"
"net/http"
"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/gopackager"
"github.com/pkg/errors"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var installCmd = &cobra.Command{
Use: "install",
Short: "Install chaincode.",
Long: "Install chaincode",
Run: func(cmd *cobra.Command, args []string) {
if cliconfig.Config().ChaincodeID() == "" {
fmt.Printf("\nMust specify the chaincode ID\n\n")
cmd.HelpFunc()(cmd, args)
return
}
if cliconfig.Config().ChaincodePath() == "" {
fmt.Printf("\nMust specify the path of the chaincode\n\n")
cmd.HelpFunc()(cmd, args)
return
}
action, err := newInstallAction(cmd.Flags())
if err != nil {
cliconfig.Config().Logger().Errorf("Error while initializing installAction: %v", err)
return
}
defer action.Terminate()
err = action.invoke()
if err != nil {
cliconfig.Config().Logger().Errorf("Error while running installAction: %v", err)
}
},
}
func getInstallCmd() *cobra.Command {
flags := installCmd.Flags()
cliconfig.InitPeerURL(flags, "", "The URL of the peer on which to install the chaincode, e.g. localhost:7051")
cliconfig.InitChannelID(flags)
cliconfig.InitChaincodeID(flags)
cliconfig.InitChaincodePath(flags)
cliconfig.InitChaincodeVersion(flags)
cliconfig.InitGoPath(flags)
return installCmd
}
type installAction struct {
action.Action
}
func newInstallAction(flags *pflag.FlagSet) (*installAction, error) {
action := &installAction{}
err := action.Initialize(flags)
return action, err
}
func (action *installAction) invoke() error {
var lastErr error
for orgID, peers := range action.PeersByOrg() {
fmt.Printf("Installing chaincode %s on org[%s] peers:\n", cliconfig.Config().ChaincodeID(), orgID)
for _, peer := range peers {
fmt.Printf("-- %s\n", peer.URL())
}
err := action.installChaincode(orgID, peers)
if err != nil {
lastErr = err
}
}
return lastErr
}
func (action *installAction) installChaincode(orgID string, targets []fab.Peer) error {
resMgmtClient, err := action.ResourceMgmtClientForOrg(orgID)
if err != nil {
return err
}
ccPkg, err := gopackager.NewCCPackage(cliconfig.Config().ChaincodePath(), cliconfig.Config().GoPath())
if err != nil {
return err
}
req := resmgmt.InstallCCRequest{
Name: cliconfig.Config().ChaincodeID(),
Path: cliconfig.Config().ChaincodePath(),
Version: cliconfig.Config().ChaincodeVersion(),
Package: ccPkg,
}
responses, err := resMgmtClient.InstallCC(req, resmgmt.WithTargets(targets...))
if err != nil {
return errors.Errorf("InstallChaincode returned error: %v", err)
}
ccIDVersion := cliconfig.Config().ChaincodeID() + "." + cliconfig.Config().ChaincodeVersion()
var errs []error
for _, resp := range responses {
if resp.Info == "already installed" {
fmt.Printf("Chaincode %s already installed on peer: %s.\n", ccIDVersion, resp.Target)
} else if resp.Status != http.StatusOK {
errs = append(errs, errors.Errorf("installCC returned error from peer %s: %s", resp.Target, resp.Info))
} else {
fmt.Printf("...successfuly installed chaincode %s on peer %s.\n", ccIDVersion, resp.Target)
}
}
if len(errs) > 0 {
cliconfig.Config().Logger().Warnf("Errors returned from InstallCC: %v\n", errs)
return errs[0]
}
return nil
}
================================================
FILE: fabric-cli/cmd/fabric-cli/chaincode/instantiatecmd.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package chaincode
import (
"encoding/json"
"fmt"
"io/ioutil"
"strings"
"github.com/hyperledger/fabric-protos-go/common"
pb "github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt"
"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/cauthdsl"
"github.com/pkg/errors"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/utils"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var instantiateCmd = &cobra.Command{
Use: "instantiate",
Short: "Instantiate chaincode.",
Long: "Instantiates the chaincode",
Run: func(cmd *cobra.Command, args []string) {
if cliconfig.Config().ChaincodeID() == "" {
fmt.Printf("\nMust specify the chaincode ID\n\n")
cmd.HelpFunc()(cmd, args)
return
}
if cliconfig.Config().ChaincodePath() == "" {
fmt.Printf("\nMust specify the path of the chaincode\n\n")
cmd.HelpFunc()(cmd, args)
return
}
action, err := newInstantiateAction(cmd.Flags())
if err != nil {
cliconfig.Config().Logger().Errorf("Error while initializing instantiateAction: %v", err)
return
}
defer action.Terminate()
err = action.invoke()
if err != nil {
cliconfig.Config().Logger().Errorf("Error while running instantiateAction: %v", err)
}
},
}
func getInstantiateCmd() *cobra.Command {
flags := instantiateCmd.Flags()
cliconfig.InitPeerURL(flags)
cliconfig.InitChannelID(flags)
cliconfig.InitChaincodeID(flags)
cliconfig.InitChaincodePath(flags)
cliconfig.InitChaincodeVersion(flags)
cliconfig.InitArgs(flags)
cliconfig.InitChaincodePolicy(flags)
cliconfig.InitCollectionConfigFile(flags)
cliconfig.InitTimeout(flags)
return instantiateCmd
}
type instantiateAction struct {
action.Action
}
func newInstantiateAction(flags *pflag.FlagSet) (*instantiateAction, error) {
action := &instantiateAction{}
err := action.Initialize(flags)
if len(action.Peers()) == 0 {
return nil, errors.Errorf("a peer must be specified")
}
return action, err
}
func (a *instantiateAction) invoke() error {
s := cliconfig.Config().Args()
argBytes := []byte(s)
args := &action.ArgStruct{}
if err := json.Unmarshal(argBytes, args); err != nil {
return errors.Errorf("Error unmarshalling JSON arg string: %v", err)
}
resMgmtClient, err := a.ResourceMgmtClient()
if err != nil {
return err
}
cliconfig.Config().Logger().Infof("Sending instantiate %s ...\n", cliconfig.Config().ChaincodeID())
chaincodePolicy, err := a.newChaincodePolicy()
if err != nil {
return err
}
// Private Data Collection Configuration
// - see fixtures/config/pvtdatacollection.json for sample config file
var collConfig []*pb.CollectionConfig
collConfigFile := cliconfig.Config().CollectionConfigFile()
if collConfigFile != "" {
collConfig, err = getCollectionConfigFromFile(cliconfig.Config().CollectionConfigFile())
if err != nil {
return errors.Wrapf(err, "error getting private data collection configuration from file [%s]", cliconfig.Config().CollectionConfigFile())
}
}
req := resmgmt.InstantiateCCRequest{
Name: cliconfig.Config().ChaincodeID(),
Path: cliconfig.Config().ChaincodePath(),
Version: cliconfig.Config().ChaincodeVersion(),
Args: utils.AsBytes(utils.NewContext(), args.Args),
Policy: chaincodePolicy,
CollConfig: collConfig,
}
_, err = resMgmtClient.InstantiateCC(cliconfig.Config().ChannelID(), req, resmgmt.WithTargets(a.Peer()))
if err != nil {
if strings.Contains(err.Error(), "chaincode exists "+cliconfig.Config().ChaincodeID()) {
// Ignore
cliconfig.Config().Logger().Infof("Chaincode %s already instantiated.", cliconfig.Config().ChaincodeID())
fmt.Printf("...chaincode %s already instantiated.\n", cliconfig.Config().ChaincodeID())
return nil
}
return errors.Errorf("error instantiating chaincode: %v", err)
}
fmt.Printf("...successfuly instantiated chaincode %s on channel %s.\n", cliconfig.Config().ChaincodeID(), cliconfig.Config().ChannelID())
return nil
}
func (a *instantiateAction) newChaincodePolicy() (*common.SignaturePolicyEnvelope, error) {
if cliconfig.Config().ChaincodePolicy() != "" {
// Create a signature policy from the policy expression passed in
return newChaincodePolicy(cliconfig.Config().ChaincodePolicy())
}
// Default policy is 'signed by any member' for all known orgs
return cauthdsl.AcceptAllPolicy, nil
}
func newChaincodePolicy(policyString string) (*common.SignaturePolicyEnvelope, error) {
ccPolicy, err := cauthdsl.FromString(policyString)
if err != nil {
return nil, errors.Errorf("invalid chaincode policy [%s]: %s", policyString, err)
}
return ccPolicy, nil
}
type collectionConfigJSON struct {
Name string `json:"name"`
Policy string `json:"policy"`
RequiredPeerCount int32 `json:"requiredPeerCount"`
MaxPeerCount int32 `json:"maxPeerCount"`
}
func getCollectionConfigFromFile(ccFile string) ([]*pb.CollectionConfig, error) {
fileBytes, err := ioutil.ReadFile(ccFile)
if err != nil {
return nil, errors.Wrapf(err, "could not read file [%s]", ccFile)
}
cconf := &[]collectionConfigJSON{}
if err = json.Unmarshal(fileBytes, cconf); err != nil {
return nil, errors.Wrapf(err, "error parsing collection configuration in file [%s]", ccFile)
}
return getCollectionConfig(*cconf)
}
func getCollectionConfig(cconf []collectionConfigJSON) ([]*pb.CollectionConfig, error) {
ccarray := make([]*pb.CollectionConfig, 0, len(cconf))
for _, cconfitem := range cconf {
p, err := cauthdsl.FromString(cconfitem.Policy)
if err != nil {
return nil, errors.WithMessage(err, fmt.Sprintf("invalid policy %s", cconfitem.Policy))
}
cpc := &pb.CollectionPolicyConfig{
Payload: &pb.CollectionPolicyConfig_SignaturePolicy{
SignaturePolicy: p,
},
}
cc := &pb.CollectionConfig{
Payload: &pb.CollectionConfig_StaticCollectionConfig{
StaticCollectionConfig: &pb.StaticCollectionConfig{
Name: cconfitem.Name,
MemberOrgsPolicy: cpc,
RequiredPeerCount: cconfitem.RequiredPeerCount,
MaximumPeerCount: cconfitem.MaxPeerCount,
},
},
}
ccarray = append(ccarray, cc)
}
return ccarray, nil
}
================================================
FILE: fabric-cli/cmd/fabric-cli/chaincode/invokecmd.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package chaincode
import (
"fmt"
"strconv"
"sync"
"time"
"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
"github.com/pkg/errors"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/invoketask"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/multitask"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/task"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/utils"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/executor"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var invokeCmd = &cobra.Command{
Use: "invoke",
Short: "invoke chaincode.",
Long: "invoke chaincode",
Run: func(cmd *cobra.Command, args []string) {
if cliconfig.Config().ChaincodeID() == "" {
fmt.Printf("\nMust specify the chaincode ID\n\n")
cmd.HelpFunc()(cmd, args)
return
}
action, err := newInvokeAction(cmd.Flags())
if err != nil {
cliconfig.Config().Logger().Errorf("Error while initializing invokeAction: %v", err)
return
}
defer action.Terminate()
err = action.invoke()
if err != nil {
cliconfig.Config().Logger().Errorf("Error while running invokeAction: %v", err)
}
},
}
func getInvokeCmd() *cobra.Command {
flags := invokeCmd.Flags()
cliconfig.InitPeerURL(flags)
cliconfig.InitChannelID(flags)
cliconfig.InitChaincodeID(flags)
cliconfig.InitArgs(flags)
cliconfig.InitIterations(flags)
cliconfig.InitSleepTime(flags)
cliconfig.InitTimeout(flags)
cliconfig.InitPrintPayloadOnly(flags)
cliconfig.InitConcurrency(flags)
cliconfig.InitMaxAttempts(flags)
cliconfig.InitInitialBackoff(flags)
cliconfig.InitMaxBackoff(flags)
cliconfig.InitBackoffFactor(flags)
cliconfig.InitVerbosity(flags)
cliconfig.InitSelectionProvider(flags)
return invokeCmd
}
type invokeAction struct {
action.Action
numInvoked uint32
done chan bool
}
func newInvokeAction(flags *pflag.FlagSet) (*invokeAction, error) {
action := &invokeAction{done: make(chan bool)}
err := action.Initialize(flags)
return action, err
}
func (a *invokeAction) invoke() error {
channelClient, err := a.ChannelClient()
if err != nil {
return errors.Errorf("Error getting channel client: %v", err)
}
argsArray, err := action.ArgsArray()
if err != nil {
return err
}
executor := executor.NewConcurrent("Invoke Chaincode", cliconfig.Config().Concurrency())
executor.Start()
defer executor.Stop(true)
success := 0
var errs []error
var successDurations []time.Duration
var failDurations []time.Duration
var targets []fab.Peer
if len(cliconfig.Config().PeerURL()) > 0 || len(cliconfig.Config().OrgIDs()) > 0 {
targets = a.Peers()
}
var wg sync.WaitGroup
var mutex sync.RWMutex
var tasks []task.Task
var taskID int
for i := 0; i < cliconfig.Config().Iterations(); i++ {
ctxt := utils.NewContext()
multiTask := multitask.New(wg.Done)
for _, args := range argsArray {
taskID++
var startTime time.Time
cargs := args
task := invoketask.New(
ctxt,
strconv.Itoa(taskID), channelClient, targets,
cliconfig.Config().ChaincodeID(),
&cargs, executor,
retry.Opts{
Attempts: cliconfig.Config().MaxAttempts(),
InitialBackoff: cliconfig.Config().InitialBackoff(),
MaxBackoff: cliconfig.Config().MaxBackoff(),
BackoffFactor: cliconfig.Config().BackoffFactor(),
RetryableCodes: retry.ChannelClientRetryableCodes,
},
cliconfig.Config().Verbose() || cliconfig.Config().Iterations() == 1,
cliconfig.Config().PrintPayloadOnly(), a.Printer(),
func() {
startTime = time.Now()
},
func(err error) {
duration := time.Since(startTime)
mutex.Lock()
defer mutex.Unlock()
if err != nil {
errs = append(errs, err)
failDurations = append(failDurations, duration)
} else {
success++
successDurations = append(successDurations, duration)
}
})
multiTask.Add(task)
}
tasks = append(tasks, multiTask)
}
wg.Add(len(tasks))
numInvocations := len(tasks) * len(argsArray)
done := make(chan bool)
go func() {
ticker := time.NewTicker(10 * time.Second)
for {
select {
case <-ticker.C:
mutex.RLock()
if len(errs) > 0 {
fmt.Printf("*** %d failed invocation(s) out of %d\n", len(errs), numInvocations)
}
fmt.Printf("*** %d successfull invocation(s) out of %d\n", success, numInvocations)
mutex.RUnlock()
case <-done:
return
}
}
}()
startTime := time.Now()
sleepTime := time.Duration(cliconfig.Config().SleepTime()) * time.Millisecond
for _, task := range tasks {
if err := executor.Submit(task); err != nil {
return errors.Errorf("error submitting task: %s", err)
}
if sleepTime > 0 {
time.Sleep(sleepTime)
}
}
// Wait for all tasks to complete
wg.Wait()
done <- true
duration := time.Now().Sub(startTime)
var allErrs []error
var attempts int
for _, task := range tasks {
attempts = attempts + task.Attempts()
if task.LastError() != nil {
allErrs = append(allErrs, task.LastError())
}
}
if len(errs) > 0 {
fmt.Printf("\n*** %d errors invoking chaincode:\n", len(errs))
for _, err := range errs {
fmt.Printf("%s\n", err)
}
} else if len(allErrs) > 0 {
fmt.Printf("\n*** %d transient errors invoking chaincode:\n", len(allErrs))
for _, err := range allErrs {
fmt.Printf("%s\n", err)
}
}
if numInvocations/len(argsArray) > 1 {
fmt.Printf("\n")
fmt.Printf("*** ---------- Summary: ----------\n")
fmt.Printf("*** - Invocations: %d\n", numInvocations)
fmt.Printf("*** - Concurrency: %d\n", cliconfig.Config().Concurrency())
fmt.Printf("*** - Successfull: %d\n", success)
fmt.Printf("*** - Total attempts: %d\n", attempts)
fmt.Printf("*** - Duration: %2.2fs\n", duration.Seconds())
fmt.Printf("*** - Rate: %2.2f/s\n", float64(numInvocations)/duration.Seconds())
fmt.Printf("*** - Average: %2.2fs\n", average(append(successDurations, failDurations...)))
fmt.Printf("*** - Average Success: %2.2fs\n", average(successDurations))
fmt.Printf("*** - Average Fail: %2.2fs\n", average(failDurations))
fmt.Printf("*** - Min Success: %2.2fs\n", min(successDurations))
fmt.Printf("*** - Max Success: %2.2fs\n", max(successDurations))
fmt.Printf("*** ------------------------------\n")
}
return nil
}
func average(durations []time.Duration) float64 {
if len(durations) == 0 {
return 0
}
var total float64
for _, duration := range durations {
total += duration.Seconds()
}
return total / float64(len(durations))
}
func min(durations []time.Duration) float64 {
min, _ := minMax(durations)
return min
}
func max(durations []time.Duration) float64 {
_, max := minMax(durations)
return max
}
func minMax(durations []time.Duration) (min float64, max float64) {
for _, duration := range durations {
if min == 0 || min > duration.Seconds() {
min = duration.Seconds()
}
if max == 0 || max < duration.Seconds() {
max = duration.Seconds()
}
}
return
}
================================================
FILE: fabric-cli/cmd/fabric-cli/chaincode/invokeerror/invokeerror.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package invokeerror
import "github.com/pkg/errors"
type ErrorCode int
const (
// PersistentError indicates that an unknown error occurred
// and a retry of the request would NOT be successful
PersistentError ErrorCode = iota
// TransientError indicates that a transient error occurred
// and a retry of the request could be successful
TransientError
// TimeoutOnCommit indicates that a timeout occurred while waiting
// for a TxStatus event
TimeoutOnCommit
)
// Error extends error with
// additional context
type Error interface {
error
// Status returns the error code
ErrorCode() ErrorCode
}
type invokeError struct {
error
code ErrorCode
}
// New returns a new Error
func New(code ErrorCode, msg string) Error {
return &invokeError{
error: errors.New(msg),
code: code,
}
}
// Wrap returns a new Error
func Wrap(code ErrorCode, cause error, msg string) Error {
return &invokeError{
error: errors.Wrap(cause, msg),
code: code,
}
}
// Wrapf returns a new Error
func Wrapf(code ErrorCode, cause error, fmt string, args ...interface{}) Error {
return &invokeError{
error: errors.Wrapf(cause, fmt, args...),
code: code,
}
}
// Errorf returns a new Error
func Errorf(code ErrorCode, fmt string, args ...interface{}) Error {
return &invokeError{
error: errors.Errorf(fmt, args...),
code: code,
}
}
// ErrorCode returns the error code
func (e *invokeError) ErrorCode() ErrorCode {
return e.code
}
================================================
FILE: fabric-cli/cmd/fabric-cli/chaincode/invoketask/invoketask.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package invoketask
import (
pb "github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric-sdk-go/pkg/client/channel"
"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
"github.com/pkg/errors"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/invokeerror"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/utils"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/executor"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/printer"
)
// Task is a Task that invokes a chaincode
type Task struct {
ctxt utils.Context
executor *executor.Executor
channelClient *channel.Client
targets []fab.Peer
id string
ccID string
args *action.ArgStruct
retryOpts retry.Opts
attempt int
lastErr error
startedCB func()
completedCB func(err error)
verbose bool
printer printer.Printer
txID string
payloadOnly bool
}
// New returns a new Task
func New(ctxt utils.Context, id string, channelClient *channel.Client, targets []fab.Peer, ccID string, args *action.ArgStruct,
executor *executor.Executor, retryOpts retry.Opts, verbose bool,
payloadOnly bool, p printer.Printer, startedCB func(), completedCB func(err error)) *Task {
return &Task{
ctxt: ctxt,
id: id,
channelClient: channelClient,
targets: targets,
printer: p,
ccID: ccID,
args: args,
executor: executor,
retryOpts: retryOpts,
startedCB: startedCB,
completedCB: completedCB,
attempt: 1,
verbose: verbose,
payloadOnly: payloadOnly,
}
}
// Attempts returns the number of invocation attempts that were made
// in order to achieve a successful response
func (t *Task) Attempts() int {
return t.attempt
}
// LastError returns the last error that was recorder
func (t *Task) LastError() error {
return t.lastErr
}
// Invoke invokes the task
func (t *Task) Invoke() {
t.startedCB()
if err := t.doInvoke(); err != nil {
t.lastErr = err
t.completedCB(err)
} else {
cliconfig.Config().Logger().Debugf("(%s) - Successfully invoked chaincode\n", t.id)
t.completedCB(nil)
}
}
func (t *Task) doInvoke() error {
cliconfig.Config().Logger().Debugf("(%s) - Invoking chaincode: %s, function: %s, args: %+v. Attempt #%d...\n",
t.id, t.ccID, t.args.Func, t.args.Args, t.attempt)
var opts []channel.RequestOption
opts = append(opts, channel.WithRetry(t.retryOpts))
opts = append(opts, channel.WithBeforeRetry(func(err error) {
t.attempt++
}))
if len(t.targets) > 0 {
opts = append(opts, channel.WithTargets(t.targets...))
}
response, err := t.channelClient.Execute(
channel.Request{
ChaincodeID: t.ccID,
Fcn: t.args.Func,
Args: utils.AsBytes(t.ctxt, t.args.Args),
},
opts...,
)
if err != nil {
return invokeerror.Errorf(invokeerror.TransientError, "SendTransactionProposal return error: %v", err)
}
if t.verbose {
t.printer.PrintTxProposalResponses(response.Responses, t.payloadOnly)
}
t.txID = string(response.TransactionID)
switch pb.TxValidationCode(response.TxValidationCode) {
case pb.TxValidationCode_VALID:
cliconfig.Config().Logger().Debugf("(%s) - Successfully committed transaction [%s] ...\n", t.id, response.TransactionID)
return nil
case pb.TxValidationCode_DUPLICATE_TXID, pb.TxValidationCode_MVCC_READ_CONFLICT, pb.TxValidationCode_PHANTOM_READ_CONFLICT:
cliconfig.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)
return invokeerror.Wrapf(invokeerror.TransientError, errors.New("Duplicate TxID"), "invoke Error received from eventhub for TxID [%s]. Code: %s", response.TransactionID, response.TxValidationCode)
default:
cliconfig.Config().Logger().Debugf("(%s) - Transaction commit failed for [%s] with code [%s].\n", t.id, response.TransactionID, response.TxValidationCode)
return invokeerror.Wrapf(invokeerror.PersistentError, errors.New("error"), "invoke Error received from eventhub for TxID [%s]. Code: %s", response.TransactionID, response.TxValidationCode)
}
}
================================================
FILE: fabric-cli/cmd/fabric-cli/chaincode/multitask/multitask.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package multitask
import "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/task"
// MultiTask contains a set of Tasks to be invoked synchronously
type MultiTask struct {
tasks []task.Task
completedCB func()
}
// New creates a new multi task
func New(completedCB func()) *MultiTask {
return &MultiTask{
completedCB: completedCB,
}
}
// Add adds a task
func (m *MultiTask) Add(task task.Task) {
m.tasks = append(m.tasks, task)
}
// Invoke invokes the task
func (m *MultiTask) Invoke() {
defer m.completedCB()
for _, task := range m.tasks {
task.Invoke()
}
}
// Attempts returns the number of invocation attempts that were made
// in order to achieve a successful response
func (m *MultiTask) Attempts() int {
var attempts int
for _, t := range m.tasks {
attempts += t.Attempts()
}
return attempts
}
// LastError returns the last error that was recorder
func (m *MultiTask) LastError() error {
for _, t := range m.tasks {
if t.LastError() != nil {
return t.LastError()
}
}
return nil
}
================================================
FILE: fabric-cli/cmd/fabric-cli/chaincode/querycmd.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package chaincode
import (
"fmt"
"strconv"
"sync"
"time"
"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
"github.com/pkg/errors"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/multitask"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/querytask"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/task"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/utils"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/executor"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var queryCmd = &cobra.Command{
Use: "query",
Short: "Query chaincode.",
Long: "Query chaincode",
Run: func(cmd *cobra.Command, args []string) {
if cliconfig.Config().ChaincodeID() == "" {
fmt.Printf("\nMust specify the chaincode ID\n\n")
cmd.HelpFunc()(cmd, args)
return
}
action, err := newQueryAction(cmd.Flags())
if err != nil {
cliconfig.Config().Logger().Errorf("Error while initializing queryAction: %v", err)
return
}
defer action.Terminate()
err = action.query()
if err != nil {
cliconfig.Config().Logger().Errorf("Error while running queryAction: %v", err)
}
},
}
func getQueryCmd() *cobra.Command {
flags := queryCmd.Flags()
cliconfig.InitPeerURL(flags)
cliconfig.InitChannelID(flags)
cliconfig.InitChaincodeID(flags)
cliconfig.InitArgs(flags)
cliconfig.InitIterations(flags)
cliconfig.InitSleepTime(flags)
cliconfig.InitTimeout(flags)
cliconfig.InitPrintPayloadOnly(flags)
cliconfig.InitConcurrency(flags)
cliconfig.InitVerbosity(flags)
cliconfig.InitSelectionProvider(flags)
cliconfig.InitValidate(flags)
return queryCmd
}
type queryAction struct {
action.Action
numInvoked uint32
done chan bool
}
func newQueryAction(flags *pflag.FlagSet) (*queryAction, error) {
action := &queryAction{done: make(chan bool)}
err := action.Initialize(flags)
return action, err
}
func (a *queryAction) query() error {
channelClient, err := a.ChannelClient()
if err != nil {
return errors.Errorf("Error getting channel client: %v", err)
}
argsArray, err := action.ArgsArray()
if err != nil {
return err
}
var targets []fab.Peer
if len(cliconfig.Config().PeerURL()) > 0 || len(cliconfig.Config().OrgIDs()) > 0 {
targets = a.Peers()
}
executor := executor.NewConcurrent("Query Chaincode", cliconfig.Config().Concurrency())
executor.Start()
defer executor.Stop(true)
verbose := cliconfig.Config().Verbose() || cliconfig.Config().Iterations() == 1
var mutex sync.RWMutex
var tasks []task.Task
var errs []error
var wg sync.WaitGroup
var taskID int
var success int
var successDurations []time.Duration
var failDurations []time.Duration
for i := 0; i < cliconfig.Config().Iterations(); i++ {
ctxt := utils.NewContext()
multiTask := multitask.New(wg.Done)
for _, args := range argsArray {
taskID++
var startTime time.Time
cargs := args
task := querytask.New(
ctxt,
strconv.Itoa(taskID), channelClient, targets, &cargs, a.Printer(),
retry.Opts{
Attempts: cliconfig.Config().MaxAttempts(),
InitialBackoff: cliconfig.Config().InitialBackoff(),
MaxBackoff: cliconfig.Config().MaxBackoff(),
BackoffFactor: cliconfig.Config().BackoffFactor(),
RetryableCodes: retry.ChannelClientRetryableCodes,
},
verbose,
cliconfig.Config().PrintPayloadOnly(),
cliconfig.Config().Validate(),
func() {
startTime = time.Now()
},
func(err error) {
duration := time.Since(startTime)
mutex.Lock()
if err != nil {
errs = append(errs, err)
} else {
success++
successDurations = append(successDurations, duration)
}
mutex.Unlock()
})
multiTask.Add(task)
}
tasks = append(tasks, multiTask)
}
wg.Add(len(tasks))
numInvocations := len(tasks) * len(argsArray)
done := make(chan bool)
go func() {
ticker := time.NewTicker(3 * time.Second)
for {
select {
case <-ticker.C:
mutex.RLock()
if len(errs) > 0 {
fmt.Printf("*** %d failed query(s) out of %d\n", len(errs), numInvocations)
}
fmt.Printf("*** %d successfull query(s) out of %d\n", success, numInvocations)
mutex.RUnlock()
case <-done:
return
}
}
}()
startTime := time.Now()
sleepTime := time.Duration(cliconfig.Config().SleepTime()) * time.Millisecond
for _, task := range tasks {
if err := executor.Submit(task); err != nil {
return errors.Errorf("error submitting task: %s", err)
}
if sleepTime > 0 {
time.Sleep(sleepTime)
}
}
// Wait for all tasks to complete
wg.Wait()
done <- true
duration := time.Now().Sub(startTime)
var allErrs []error
var attempts int
for _, task := range tasks {
attempts = attempts + task.Attempts()
if task.LastError() != nil {
allErrs = append(allErrs, task.LastError())
}
}
if len(errs) > 0 {
fmt.Printf("\n*** %d errors querying chaincode:\n", len(errs))
for _, err := range errs {
fmt.Printf("%s\n", err)
}
} else if len(allErrs) > 0 {
fmt.Printf("\n*** %d transient errors querying chaincode:\n", len(allErrs))
for _, err := range allErrs {
fmt.Printf("%s\n", err)
}
}
if numInvocations/len(argsArray) > 1 {
fmt.Printf("\n")
fmt.Printf("*** ---------- Summary: ----------\n")
fmt.Printf("*** - Queries: %d\n", numInvocations)
fmt.Printf("*** - Concurrency: %d\n", cliconfig.Config().Concurrency())
fmt.Printf("*** - Successfull: %d\n", success)
fmt.Printf("*** - Total attempts: %d\n", attempts)
fmt.Printf("*** - Duration: %2.2fs\n", duration.Seconds())
fmt.Printf("*** - Rate: %2.2f/s\n", float64(numInvocations)/duration.Seconds())
fmt.Printf("*** - Average: %2.2fs\n", average(append(successDurations, failDurations...)))
fmt.Printf("*** - Average Success: %2.2fs\n", average(successDurations))
fmt.Printf("*** - Average Fail: %2.2fs\n", average(failDurations))
fmt.Printf("*** - Min Success: %2.2fs\n", min(successDurations))
fmt.Printf("*** - Max Success: %2.2fs\n", max(successDurations))
fmt.Printf("*** ------------------------------\n")
}
return nil
}
================================================
FILE: fabric-cli/cmd/fabric-cli/chaincode/querytask/querytask.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package querytask
import (
"github.com/hyperledger/fabric-sdk-go/pkg/client/channel"
"github.com/hyperledger/fabric-sdk-go/pkg/client/channel/invoke"
"github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/utils"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/printer"
)
// Task is the query task
type Task struct {
ctxt utils.Context
channelClient *channel.Client
targets []fab.Peer
retryOpts retry.Opts
id string
args *action.ArgStruct
startedCB func()
completedCB func(err error)
printer printer.Printer
verbose bool
payloadOnly bool
validate bool
attempt int
lastErr error
}
// New creates a new query Task
func New(ctxt utils.Context, id string, channelClient *channel.Client, targets []fab.Peer, args *action.ArgStruct, printer printer.Printer,
retryOpts retry.Opts, verbose bool, payloadOnly bool, validate bool, startedCB func(), completedCB func(err error)) *Task {
return &Task{
ctxt: ctxt,
id: id,
channelClient: channelClient,
targets: targets,
retryOpts: retryOpts,
args: args,
startedCB: startedCB,
completedCB: completedCB,
attempt: 1,
printer: printer,
verbose: verbose,
payloadOnly: payloadOnly,
validate: validate,
}
}
// Invoke invokes the query task
func (t *Task) Invoke() {
t.startedCB()
var opts []channel.RequestOption
opts = append(opts, channel.WithRetry(t.retryOpts))
opts = append(opts, channel.WithBeforeRetry(func(err error) {
t.attempt++
}))
if len(t.targets) > 0 {
opts = append(opts, channel.WithTargets(t.targets...))
}
request := channel.Request{
ChaincodeID: cliconfig.Config().ChaincodeID(),
Fcn: t.args.Func,
Args: utils.AsBytes(t.ctxt, t.args.Args),
}
var additionalHandlers []invoke.Handler
if t.validate {
// Add the validation handlers
additionalHandlers = append(additionalHandlers,
invoke.NewEndorsementValidationHandler(
invoke.NewSignatureValidationHandler(),
),
)
}
response, err := t.channelClient.InvokeHandler(
invoke.NewProposalProcessorHandler(
invoke.NewEndorsementHandler(additionalHandlers...),
),
request, opts...)
if err != nil {
cliconfig.Config().Logger().Debugf("(%s) - Error querying chaincode: %s\n", t.id, err)
t.lastErr = err
t.completedCB(err)
} else {
cliconfig.Config().Logger().Debugf("(%s) - Chaincode query was successful\n", t.id)
if t.verbose {
t.printer.PrintTxProposalResponses(response.Responses, t.payloadOnly)
}
t.completedCB(nil)
}
}
// Attempts returns the number of invocation attempts that were made
// in order to achieve a successful response
func (t *Task) Attempts() int {
return t.attempt
}
// LastError returns the last error that was recorder
func (t *Task) LastError() error {
return t.lastErr
}
================================================
FILE: fabric-cli/cmd/fabric-cli/chaincode/task/task.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package task
// Task is an invocable unit of work
type Task interface {
// Invoke invokes the task
Invoke()
// Attempts returns the number of invocation attempts that were made
// in order to achieve a successful response
Attempts() int
// LastError returns the last error that occurred
LastError() error
}
================================================
FILE: fabric-cli/cmd/fabric-cli/chaincode/upgradecmd.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package chaincode
import (
"encoding/json"
"fmt"
"strings"
fabricCommon "github.com/hyperledger/fabric-protos-go/common"
pb "github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt"
"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/cauthdsl"
"github.com/pkg/errors"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode/utils"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var upgradeCmd = &cobra.Command{
Use: "upgrade",
Short: "Upgrade chaincode.",
Long: "Upgrades the chaincode",
Run: func(cmd *cobra.Command, args []string) {
if cliconfig.Config().ChaincodeID() == "" {
fmt.Printf("\nMust specify the chaincode ID\n\n")
cmd.HelpFunc()(cmd, args)
return
}
if cliconfig.Config().ChaincodePath() == "" {
fmt.Printf("\nMust specify the path of the chaincode\n\n")
cmd.HelpFunc()(cmd, args)
return
}
action, err := newUpgradeAction(cmd.Flags())
if err != nil {
cliconfig.Config().Logger().Errorf("Error while initializing upgradeAction: %v", err)
return
}
defer action.Terminate()
err = action.invoke()
if err != nil {
cliconfig.Config().Logger().Errorf("Error while running upgradeAction: %v", err)
}
},
}
func getUpgradeCmd() *cobra.Command {
flags := upgradeCmd.Flags()
cliconfig.InitPeerURL(flags)
cliconfig.InitChannelID(flags)
cliconfig.InitChaincodeID(flags)
cliconfig.InitChaincodePath(flags)
cliconfig.InitChaincodeVersion(flags)
cliconfig.InitArgs(flags)
cliconfig.InitChaincodePolicy(flags)
cliconfig.InitCollectionConfigFile(flags)
cliconfig.InitTimeout(flags)
return upgradeCmd
}
type upgradeAction struct {
action.Action
}
func newUpgradeAction(flags *pflag.FlagSet) (*upgradeAction, error) {
action := &upgradeAction{}
err := action.Initialize(flags)
if len(action.Peers()) == 0 {
return nil, errors.Errorf("a peer must be specified")
}
return action, err
}
func (a *upgradeAction) invoke() error {
argBytes := []byte(cliconfig.Config().Args())
args := &action.ArgStruct{}
if err := json.Unmarshal(argBytes, args); err != nil {
return errors.Errorf("Error unmarshalling JSON arg string: %v", err)
}
resMgmtClient, err := a.ResourceMgmtClient()
if err != nil {
return err
}
cliconfig.Config().Logger().Infof("Sending upgrade %s ...\n", cliconfig.Config().ChaincodeID())
chaincodePolicy, err := a.newChaincodePolicy()
if err != nil {
return err
}
// Private Data Collection Configuration
// - see fixtures/config/pvtdatacollection.json for sample config file
var collConfig []*pb.CollectionConfig
collConfigFile := cliconfig.Config().CollectionConfigFile()
if collConfigFile != "" {
collConfig, err = getCollectionConfigFromFile(cliconfig.Config().CollectionConfigFile())
if err != nil {
return errors.Wrapf(err, "error getting private data collection configuration from file [%s]", cliconfig.Config().CollectionConfigFile())
}
}
req := resmgmt.UpgradeCCRequest{
Name: cliconfig.Config().ChaincodeID(),
Path: cliconfig.Config().ChaincodePath(),
Version: cliconfig.Config().ChaincodeVersion(),
Args: utils.AsBytes(utils.NewContext(), args.Args),
Policy: chaincodePolicy,
CollConfig: collConfig,
}
_, err = resMgmtClient.UpgradeCC(cliconfig.Config().ChannelID(), req, resmgmt.WithTargets(a.Peers()...))
if err != nil {
if strings.Contains(err.Error(), "chaincode exists "+cliconfig.Config().ChaincodeID()) {
// Ignore
cliconfig.Config().Logger().Infof("Chaincode %s already instantiated.", cliconfig.Config().ChaincodeID())
fmt.Printf("...chaincode %s already instantiated.\n", cliconfig.Config().ChaincodeID())
return nil
}
return errors.Errorf("error instantiating chaincode: %v", err)
}
fmt.Printf("...successfuly upgraded chaincode %s on channel %s.\n", cliconfig.Config().ChaincodeID(), cliconfig.Config().ChannelID())
return nil
}
func (a *upgradeAction) newChaincodePolicy() (*fabricCommon.SignaturePolicyEnvelope, error) {
if cliconfig.Config().ChaincodePolicy() != "" {
// Create a signature policy from the policy expression passed in
return newChaincodePolicy(cliconfig.Config().ChaincodePolicy())
}
// Default policy is 'signed my any member' for all known orgs
var mspIDs []string
for _, orgID := range cliconfig.Config().OrgIDs() {
orgConfig, ok := a.EndpointConfig().NetworkConfig().Organizations[orgID]
if !ok {
return nil, errors.Errorf("Unable to get the MSP ID from org ID %s", orgID)
}
mspIDs = append(mspIDs, orgConfig.MSPID)
}
return cauthdsl.SignedByAnyMember(mspIDs), nil
}
================================================
FILE: fabric-cli/cmd/fabric-cli/chaincode/utils/test.json
================================================
{"Field1": "Value1"}
================================================
FILE: fabric-cli/cmd/fabric-cli/chaincode/utils/util.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package utils
import (
"fmt"
"github.com/pkg/errors"
"io/ioutil"
"math/rand"
"os"
"path/filepath"
"strconv"
"strings"
"sync/atomic"
"time"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
)
const (
randFunc = "$rand("
padFunc = "$pad("
seqFunc = "$seq("
setFunc = "$set("
fileFunc = "$file("
varExp = "${"
)
var (
sequence uint64
)
type Context interface {
SetVar(name, value string)
GetVar(name string) (string, bool)
}
// AsBytes converts the string array to an array of byte arrays.
// The args may contain functions $rand(n) or $pad(n,chars).
// The functions are evaluated before returning.
//
// Examples:
// - "key$rand(3)" -> "key0" or "key1" or "key2"
// - "val$pad(3,XYZ) -> "valXYZXYZXYZ"
// - "val$pad($rand(3),XYZ) -> "val" or "valXYZ" or "valXYZXYZ"
// - "key$seq()" -> "key1", "key2", "key2", ...
// - "val$pad($seq(),X)" -> "valX", "valXX", "valXX", "valXXX", ...
// - "Key_$set(x,$seq())=Val_${x}" -> Key_1=Val_1, Key_2=Val_2, ...
func AsBytes(ctxt Context, args []string) [][]byte {
rand := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
bytes := make([][]byte, len(args))
if cliconfig.Config().Verbose() {
fmt.Printf("Args:\n")
}
for i, a := range args {
arg := getArg(ctxt, rand, a)
if cliconfig.Config().Verbose() {
fmt.Printf("- [%d]=%s\n", i, arg)
}
bytes[i] = []byte(arg)
}
return bytes
}
func getArg(ctxt Context, r *rand.Rand, arg string) string {
arg = evaluateSeqExpression(arg)
arg = evaluateRandExpression(r, arg)
arg = evaluatePadExpression(arg)
arg = evaluateFileExpression(arg)
arg = evaluateSetExpression(ctxt, arg)
arg = evaluateVarExpression(ctxt, arg)
return arg
}
// evaluateSeqExpression replaces occurrences of $seq() with a sequential
// number starting at 1 and incrementing for each task
func evaluateSeqExpression(arg string) string {
return evaluateExpression(arg, seqFunc, ")",
func(expression string) (string, error) {
return strconv.FormatUint(atomic.AddUint64(&sequence, 1), 10), nil
})
}
// evaluateRandExpression replaces occurrences of $rand(n) with a random
// number between 0 and n (exclusive)
func evaluateRandExpression(r *rand.Rand, arg string) string {
return evaluateExpression(arg, randFunc, ")",
func(expression string) (string, error) {
n, err := strconv.ParseInt(expression, 10, 64)
if err != nil {
return "", errors.Errorf("invalid number %s in $rand expression\n", expression)
}
return strconv.FormatInt(r.Int63n(n), 10), nil
})
}
// evaluatePadExpression replaces occurrences of $pad(n,chars) with n of the given pad characters
func evaluatePadExpression(arg string) string {
return evaluateExpression(arg, padFunc, ")",
func(expression string) (string, error) {
s := strings.Split(expression, ",")
if len(s) != 2 {
return "", errors.Errorf("invalid $pad expression: '%s'. Expecting $pad(n,chars)", expression)
}
n, err := strconv.Atoi(s[0])
if err != nil {
return "", errors.Errorf("invalid number %s in $pad expression\n", s[0])
}
result := ""
for i := 0; i < n; i++ {
result += s[1]
}
return result, nil
})
}
// evaluateFileExpression replaces occurrences of $file(path) with the contents of the file
func evaluateFileExpression(arg string) string {
return evaluateExpression(arg, fileFunc, ")",
func(expression string) (string, error) {
return readFile(expression)
})
}
// evaluateSetExpression sets a variable to the given value using the syntax $set(var,expression).
// The variable may be used in a subsequent expression, ${var}.
// Example: $set(v,$rand(10)) sets variable "v" to a random value that may be accessed as ${v}
func evaluateSetExpression(ctxt Context, arg string) string {
return evaluateExpression(arg, setFunc, ")",
func(expression string) (string, error) {
s := strings.Split(expression, ",")
if len(s) != 2 {
return "", errors.Errorf("invalid $set expression: '%s'. Expecting $set(var,value)", expression)
}
variable := s[0]
value := s[1]
ctxt.SetVar(variable, value)
return value, nil
})
}
// evaluateVarExpression references a variable previously set with the $set(var,expression) expression.
// Example: ${someVar}
func evaluateVarExpression(ctxt Context, arg string) string {
return evaluateExpression(arg, varExp, "}",
func(varName string) (string, error) {
value, ok := ctxt.GetVar(varName)
if !ok {
return "", errors.Errorf("variable [%s] not set", varName)
}
return value, nil
})
}
func evaluateExpression(expression, funcType, endDelim string, evaluate func(string) (string, error)) string {
result := ""
for {
i := strings.Index(expression, funcType)
if i == -1 {
result += expression
break
}
j := strings.Index(expression[i:], endDelim)
if j == -1 {
fmt.Printf("expecting '%s' in expression '%s'", endDelim, expression)
result = expression
break
}
j = i + j
replacement, err := evaluate(expression[i+len(funcType) : j])
if err != nil {
fmt.Printf("%s\n", err)
result += expression[0 : j+1]
} else {
result += expression[0:i] + replacement
}
expression = expression[j+1:]
}
return result
}
func NewContext() Context {
return &defaultContext{
vars: make(map[string]string),
}
}
type defaultContext struct {
vars map[string]string
}
func (c *defaultContext) SetVar(k, v string) {
c.vars[k] = v
}
func (c *defaultContext) GetVar(k string) (string, bool) {
value, ok := c.vars[k]
return value, ok
}
func readFile(filePath string) (string, error) {
fmt.Printf("Reading file: [%s]", filePath)
file, err := os.Open(filepath.Clean(filePath))
if err != nil {
return "", errors.Wrapf(err, "error opening file [%s]", filePath)
}
defer func() {
fileErr := file.Close()
if fileErr != nil {
cliconfig.Config().Logger().Errorf("Failed to close file : %s", fileErr)
}
}()
configBytes, err := ioutil.ReadAll(file)
if err != nil {
return "", errors.Wrapf(err, "error reading config file [%s]", filePath)
}
return string(configBytes), nil
}
================================================
FILE: fabric-cli/cmd/fabric-cli/chaincode/utils/util_test.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package utils
import (
"fmt"
"github.com/stretchr/testify/assert"
"math/rand"
"testing"
"time"
)
func TestEvaluatePadExpression(t *testing.T) {
result := evaluatePadExpression("Value_$pad(3,XYZ)!")
assert.Equal(t, "Value_XYZXYZXYZ!", result)
result = evaluatePadExpression("Value_$pad(3,XYZ)_$pad(2,123)!")
assert.Equal(t, "Value_XYZXYZXYZ_123123!", result)
}
func TestFailEvaluatePadExpression(t *testing.T) {
result := evaluatePadExpression("Value_$pad(3,XYZ!")
assert.Equal(t, "Value_$pad(3,XYZ!", result)
result = evaluatePadExpression("Value_$pad3,XYZ)!")
assert.Equal(t, "Value_$pad3,XYZ)!", result)
result = evaluatePadExpression("Value_$pad(3)!")
assert.Equal(t, "Value_$pad(3)!", result)
result = evaluatePadExpression("Value_$pad(3)_$pad(3,X)!")
assert.Equal(t, "Value_$pad(3)_XXX!", result)
}
func TestEvaluateRandExpression(t *testing.T) {
rand := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
for i := 0; i < 5; i++ {
result := evaluateRandExpression(rand, "Value_$rand(2)!")
assert.True(t, result == "Value_0!" || result == "Value_1!")
result = evaluateRandExpression(rand, "Value_$rand(2)_$rand(1)!")
assert.True(t, result == "Value_0_0!" || result == "Value_1_0!")
}
}
func TestFailEvaluateRandExpression(t *testing.T) {
rand := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
result := evaluateRandExpression(rand, "Value_$rand(3,!")
assert.Equal(t, "Value_$rand(3,!", result)
result = evaluateRandExpression(rand, "Value_$rand3)!")
assert.Equal(t, "Value_$rand3)!", result)
result = evaluateRandExpression(rand, "Value_$rand(X)!")
assert.Equal(t, "Value_$rand(X)!", result)
result = evaluateRandExpression(rand, "Value_$rand(X)_$rand(1)!")
assert.Equal(t, "Value_$rand(X)_0!", result)
}
func TestEvaluateSeqExpression(t *testing.T) {
assert.Equal(t, "Value_1!", evaluateSeqExpression("Value_$seq()!"))
assert.Equal(t, "Value_2!", evaluateSeqExpression("Value_$seq()!"))
assert.Equal(t, "Value_3!", evaluateSeqExpression("Value_$seq()!"))
}
func TestFailEvaluateSeqExpression(t *testing.T) {
assert.Equal(t, "Value_$seq(!", evaluateSeqExpression("Value_$seq(!"))
}
func TestEvaluateFileExpression(t *testing.T) {
assert.Equal(t, `{"Field1": "Value1"}`, evaluateFileExpression("$file(./test.json)"))
}
func TestFailEvaluateFileExpression(t *testing.T) {
assert.Equal(t, "$file(./invalid.json)", evaluateSeqExpression("$file(./invalid.json)"))
}
func TestEvaluateSetExpression(t *testing.T) {
ctxt := NewContext()
assert.Equal(t, "Value_1000!", evaluateSetExpression(ctxt, "Value_$set(x,1000)!"))
assert.Equal(t, "Value_1000!", evaluateVarExpression(ctxt, "Value_${x}!"))
}
func TestFailEvaluateSetExpression(t *testing.T) {
ctxt := NewContext()
assert.Equal(t, "Value_$set(x,1000", evaluateSetExpression(ctxt, "Value_$set(x,1000"))
assert.Equal(t, "Value_${x", evaluateVarExpression(ctxt, "Value_${x"))
// Var not set
assert.Equal(t, "Value_${x}", evaluateVarExpression(NewContext(), "Value_${x}"))
}
func TestGetArg(t *testing.T) {
rand := rand.New(rand.NewSource(time.Now().UTC().UnixNano()))
result := getArg(NewContext(), rand, "Value_$pad(3,X)!")
assert.Equal(t, "Value_XXX!", result)
for i := 0; i < 5; i++ {
result := getArg(NewContext(), rand, "Value_$rand(2)!")
assert.True(t, result == "Value_0!" || result == "Value_1!")
}
for i := 0; i < 5; i++ {
result := getArg(NewContext(), rand, "Value_$pad(3,X)_$rand(2)!")
assert.True(t, result == "Value_XXX_0!" || result == "Value_XXX_1!")
}
for i := 0; i < 5; i++ {
result := getArg(NewContext(), rand, "Value_$pad($rand(3),X)!")
assert.True(t, result == "Value_!" || result == "Value_X!" || result == "Value_XX!")
}
n := sequence + 1
for i := n; i <= n+5; i++ {
result := getArg(NewContext(), rand, "Value_$seq()!")
assert.True(t, result == fmt.Sprintf("Value_%d!", i))
}
n = sequence + 1
for i := n; i <= n+5; i++ {
ctxt := NewContext()
assert.Equal(t, fmt.Sprintf("Key_%d=Val_%d", i, i), getArg(ctxt, rand, "Key_$set(x,$seq())=Val_${x}"))
assert.Equal(t, fmt.Sprintf("Value_%d!", i), getArg(ctxt, rand, "Value_${x}!"))
}
}
================================================
FILE: fabric-cli/cmd/fabric-cli/channel/channelcmd.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package channel
import (
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/spf13/cobra"
)
var channelCmd = &cobra.Command{
Use: "channel",
Short: "Channel commands",
Long: "Channel commands",
Run: func(cmd *cobra.Command, args []string) {
cmd.HelpFunc()(cmd, args)
},
}
// Cmd returns the channel command
func Cmd() *cobra.Command {
cliconfig.InitChannelID(channelCmd.Flags())
channelCmd.AddCommand(getChannelCreateCmd())
channelCmd.AddCommand(getChannelJoinCmd())
return channelCmd
}
================================================
FILE: fabric-cli/cmd/fabric-cli/channel/channelcreatecmd.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package channel
import (
"fmt"
"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp"
"github.com/pkg/errors"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var channelCreateCmd = &cobra.Command{
Use: "create",
Short: "Create Channel",
Long: "Create a new channel",
Run: func(cmd *cobra.Command, args []string) {
action, err := newChannelCreateAction(cmd.Flags())
if err != nil {
cliconfig.Config().Logger().Errorf("Error while initializing channelCreateAction: %v", err)
return
}
defer action.Terminate()
err = action.invoke()
if err != nil {
cliconfig.Config().Logger().Errorf("Error while running channelCreateAction: %v", err)
}
},
}
func getChannelCreateCmd() *cobra.Command {
flags := channelCreateCmd.Flags()
cliconfig.InitChannelID(flags)
cliconfig.InitOrdererURL(flags)
cliconfig.InitTxFile(flags)
return channelCreateCmd
}
type channelCreateAction struct {
action.Action
}
func newChannelCreateAction(flags *pflag.FlagSet) (*channelCreateAction, error) {
a := &channelCreateAction{}
err := a.Initialize(flags)
return a, err
}
func (a *channelCreateAction) invoke() error {
user, err := a.OrgAdminUser(a.OrgID())
if err != nil {
return err
}
chMgmtClient, err := a.ResourceMgmtClient()
if err != nil {
return err
}
fmt.Printf("Attempting to create/update channel: %s\n", cliconfig.Config().ChannelID())
req := resmgmt.SaveChannelRequest{
ChannelID: cliconfig.Config().ChannelID(),
ChannelConfigPath: cliconfig.Config().TxFile(),
SigningIdentities: []msp.SigningIdentity{user},
}
orderer, err := a.RandomOrderer()
if err != nil {
return err
}
_, err = chMgmtClient.SaveChannel(req, resmgmt.WithOrderer(orderer))
if err != nil {
return errors.Errorf("Error from save channel: %s", err.Error())
}
fmt.Printf("Channel created/updated: %s\n", cliconfig.Config().ChannelID())
return nil
}
================================================
FILE: fabric-cli/cmd/fabric-cli/channel/channeljoincmd.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package channel
import (
"fmt"
"github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
"github.com/pkg/errors"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var chainJoinCmd = &cobra.Command{
Use: "join",
Short: "Join Channel",
Long: "Join a channel",
Run: func(cmd *cobra.Command, args []string) {
action, err := newChannelJoinAction(cmd.Flags())
if err != nil {
cliconfig.Config().Logger().Errorf("Error while initializing channelJoinAction: %v", err)
return
}
defer action.Terminate()
err = action.invoke()
if err != nil {
cliconfig.Config().Logger().Errorf("Error while running channelJoinAction: %v", err)
}
},
}
func getChannelJoinCmd() *cobra.Command {
flags := chainJoinCmd.Flags()
cliconfig.InitChannelID(flags)
cliconfig.InitOrdererURL(flags)
cliconfig.InitPeerURL(flags)
return chainJoinCmd
}
type channelJoinAction struct {
action.Action
}
func newChannelJoinAction(flags *pflag.FlagSet) (*channelJoinAction, error) {
action := &channelJoinAction{}
err := action.Initialize(flags)
if err != nil {
return nil, err
}
if len(action.Peers()) == 0 {
return nil, errors.Errorf("at least one peer is required for join")
}
return action, nil
}
func (a *channelJoinAction) invoke() error {
fmt.Printf("Attempting to join channel: %s\n", cliconfig.Config().ChannelID())
var lastErr error
for orgID, peers := range a.PeersByOrg() {
fmt.Printf("Joining channel %s on org[%s] peers:\n", cliconfig.Config().ChannelID(), orgID)
for _, peer := range peers {
fmt.Printf("-- %s\n", peer.URL())
}
err := a.joinChannel(orgID, peers)
if err != nil {
lastErr = err
}
}
return lastErr
}
func (a *channelJoinAction) joinChannel(orgID string, peers []fab.Peer) error {
cliconfig.Config().Logger().Debugf("Joining channel [%s]...\n", cliconfig.Config().ChannelID())
fmt.Printf("==========> JOIN ORG: %s\n", orgID)
resMgmtClient, err := a.ResourceMgmtClientForOrg(orgID)
if err != nil {
return err
}
orderer, err := a.RandomOrderer()
if err != nil {
return err
}
err = resMgmtClient.JoinChannel(cliconfig.Config().ChannelID(), resmgmt.WithTargets(peers...), resmgmt.WithOrderer(orderer))
if err != nil {
return errors.WithMessage(err, "Could not join channel: %v")
}
fmt.Printf("Channel %s joined!\n", cliconfig.Config().ChannelID())
return nil
}
================================================
FILE: fabric-cli/cmd/fabric-cli/cmd/fabric-cli.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package cmd
import (
"os"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/chaincode"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/channel"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/event"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/query"
"github.com/spf13/cobra"
)
func newFabricCLICmd() *cobra.Command {
mainCmd := &cobra.Command{
Use: "fabric-cli",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
return nil
},
Run: func(cmd *cobra.Command, args []string) {
cmd.HelpFunc()(cmd, args)
},
}
flags := mainCmd.PersistentFlags()
cliconfig.InitConfigFile(flags)
cliconfig.InitLoggingLevel(flags)
cliconfig.InitUserName(flags)
cliconfig.InitUserPassword(flags)
cliconfig.InitOrdererTLSCertificate(flags)
cliconfig.InitPrintFormat(flags)
cliconfig.InitWriter(flags)
cliconfig.InitBase64(flags)
cliconfig.InitOrgIDs(flags)
mainCmd.AddCommand(chaincode.Cmd())
mainCmd.AddCommand(query.Cmd())
mainCmd.AddCommand(channel.Cmd())
mainCmd.AddCommand(event.Cmd())
return mainCmd
}
func Execute() {
if newFabricCLICmd().Execute() != nil {
os.Exit(1)
}
}
================================================
FILE: fabric-cli/cmd/fabric-cli/config/config.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package config
import (
"fmt"
"strconv"
"time"
"github.com/hyperledger/fabric-sdk-go/pkg/fab/events/deliverclient/seek"
"strings"
"github.com/spf13/pflag"
"os"
"github.com/hyperledger/fabric-sdk-go/pkg/common/logging"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/core"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
"github.com/hyperledger/fabric-sdk-go/pkg/core/config"
)
const (
loggerName = "fabriccli"
userStatePath = "/tmp/enroll_user"
// AutoDetectSelectionProvider indicates that a selection provider is to be automatically determined using channel capabilities
AutoDetectSelectionProvider = "auto"
// StaticSelectionProvider indicates that a static selection provider is to be used for selecting peers for invoke/query commands
StaticSelectionProvider = "static"
// DynamicSelectionProvider indicates that a dynamic selection provider is to be used for selecting peers for invoke/query commands
DynamicSelectionProvider = "dynamic"
// FabricSelectionProvider indicates that the Fabric selection provider is to be used for selecting peers for invoke/query commands
FabricSelectionProvider = "fabric"
)
// Flags
const (
UserFlag = "user"
userDescription = "The user"
defaultUser = ""
PasswordFlag = "pw"
passwordDescription = "The password of the user"
defaultPassword = ""
ChaincodeVersionFlag = "v"
chaincodeVersionDescription = "The chaincode version"
defaultChaincodeVersion = "v0"
LoggingLevelFlag = "logging-level"
loggingLevelDescription = "Logging level - ERROR, WARN, INFO, DEBUG"
defaultLoggingLevel = "ERROR"
OrgIDsFlag = "orgid"
orgIDsDescription = "A comma-separated list of organization IDs"
defaultOrgIDs = ""
ChannelIDFlag = "cid"
channelIDDescription = "The channel ID"
defaultChannelID = ""
ChaincodeIDFlag = "ccid"
chaincodeIDDescription = "The Chaincode ID"
defaultChaincodeID = ""
ChaincodePathFlag = "ccp"
chaincodePathDescription = "The chaincode path"
defaultChaincodePath = ""
ConfigFileFlag = "config"
configFileDescription = "The path of the config.yaml file"
defaultConfigFile = ""
PeerURLFlag = "peer"
peerURLDescription = "A comma-separated list of peer targets, e.g. 'grpcs://localhost:7051,grpcs://localhost:8051'"
defaultPeerURL = ""
OrdererFlag = "orderer"
ordererURLDescription = "The URL of the orderer, e.g. grpcs://localhost:7050"
defaultOrdererURL = ""
PrintFormatFlag = "format"
printFormatDescription = "The output format - display, json, raw"
WriterFlag = "writer"
writerDescription = "The writer - stdout, stderr, log"
Base64Flag = "base64"
base64Description = "If true then binary values are encoded in base64 (only applies to 'display' format)"
CertificateFileFlag = "cacert"
certificateDescription = "The path of the ca-cert.pem file"
defaultCertificate = ""
ArgsFlag = "args"
argsDescription = `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)"]}.`
IterationsFlag = "iterations"
iterationsDescription = "The number of times to invoke the chaincode"
defaultIterations = "1"
SleepFlag = "sleep"
sleepTimeDescription = "The number of milliseconds to sleep between invocations of the chaincode."
defaultSleepTime = "0"
TxFileFlag = "txfile"
txFileDescription = "The path of the channel.tx file"
defaultTxFile = ""
ChaincodeEventFlag = "event"
chaincodeEventDescription = "The name of the chaincode event to listen for"
defaultChaincodeEvent = ""
SeekTypeFlag = "seek"
seekTypeDescription = "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"
defaultSeekType = string(seek.Newest)
TxIDFlag = "txid"
txIDDescription = "The transaction ID"
defaultTxID = ""
BlockNumFlag = "num"
blockNumDescription = "The block number"
defaultBlockNum = "0"
BlockHashFlag = "hash"
blockHashDescription = "The block hash"
defaultBlockHash = ""
TraverseFlag = "traverse"
traverseDescription = "Blocks will be traversed starting with the given block in reverse order up to the given number of blocks"
defaultTraverse = "0"
ChaincodePolicyFlag = "policy"
chaincodePolicyDescription = "The chaincode policy, e.g. OutOf(1,'Org1MSP.admin','Org2MSP.admin',AND('Org3MSP.member','Org4MSP.member'))"
defaultChaincodePolicy = ""
CollectionConfigFileFlag = "collconfig"
collectionConfigFileDescription = "The path of the JSON file that contains the private data collection configuration for the chaincode"
defaultCollectionConfigFile = ""
TimeoutFlag = "timeout"
timeoutDescription = "The timeout (in milliseconds) for the operation"
defaultTimeout = "5000"
PrintPayloadOnlyFlag = "payload"
printPayloadOnlyDescription = "If specified then only the payload from the transaction proposal response(s) will be output"
defaultPrintPayloadOnly = "false"
ValidateFlag = "validate"
validateDescription = "If specified then endorsement responses from queries will be validated"
defaultValidate = "false"
ConcurrencyFlag = "concurrency"
concurrencyDescription = "Specifies the number of concurrent requests sent on an invoke or a query chaincode request"
defaultConcurrency = "1"
MaxAttemptsFlag = "attempts"
maxAttemptsDescription = "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."
defaultMaxAttempts = "3"
InitialBackoffFlag = "backoff"
initialBackoffDescription = "The initial backoff is the time (in milliseconds) to wait before resubmitting an invocation after a transient error"
defaultInitialBackoff = "1000"
MaxBackoffFlag = "maxbackoff"
maxBackoffDescription = "The maximum backoff time (in milliseconds)"
defaultMaxBackoff = "5000"
BackoffFactorFlag = "backofffactor"
backoffFactorDescription = "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"
defaultBackoffFactor = "2"
VerboseFlag = "verbose"
verboseDescription = "If specified then the transaction proposal responses will be output when iterations > 1, otherwise transaction proposal responses are only output when iterations = 1"
defaultVerbosity = "false"
SelectionProviderFlag = "selectprovider"
selectionProviderDescription = "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."
defaultSelectionProvider = AutoDetectSelectionProvider
GoPathFlag = "gopath"
goPathDescription = "GOPATH for chaincode install command. If not set, GOPATH is taken from the environment"
defaultGoPath = ""
)
var opts *options
var instance *CLIConfig
type options struct {
certificate string
user string
password string
loggingLevel string
orgIDsStr string
channelID string
chaincodeID string
chaincodePath string
chaincodeVersion string
peerURL string
ordererURL string
iterations int
sleepTime int64
configFile string
txFile string
txID string
printFormat string
writer string
base64 bool
args string
chaincodeEvent string
seekType string
blockHash string
blockNum uint64
traverse int
chaincodePolicy string
collectionConfigFile string
timeout int64
printPayloadOnly bool
validate bool
concurrency int
maxAttempts int
initialBackoff int64
maxBackoff int64
backoffFactor float64
verbose bool
selectionProvider string
goPath string
}
func init() {
opts = &options{
user: defaultUser,
password: defaultPassword,
loggingLevel: defaultLoggingLevel,
channelID: defaultChannelID,
orgIDsStr: defaultOrgIDs,
chaincodeVersion: defaultChaincodeVersion,
iterations: 1,
concurrency: 1,
args: getEmptyArgs(),
}
}
// CLIConfig overrides certain configuration values with those supplied on the command-line
type CLIConfig struct {
core.ConfigProvider
logger *logging.Logger
setFlags map[string]string
}
// InitConfig initializes the configuration
func InitConfig(flags *pflag.FlagSet) error {
instance = &CLIConfig{
logger: logging.NewLogger(loggerName),
setFlags: make(map[string]string),
}
flags.Visit(func(flag *pflag.Flag) {
instance.setFlags[flag.Name] = flag.Value.String()
})
cnfg := config.FromFile(opts.configFile)
instance.ConfigProvider = cnfg
return nil
}
// IsFlagSet indicates whether or not the given flag is set
func IsFlagSet(name string) bool {
_, ok := instance.setFlags[name]
return ok
}
// Provider returns the config provider
func Provider() core.ConfigProvider {
return instance.ConfigProvider
}
// Config returns the CLI configuration
func Config() *CLIConfig {
return instance
}
// Logger returns the Logger for the CLI tool
func (c *CLIConfig) Logger() *logging.Logger {
return c.logger
}
// LoggingLevel specifies the logging level (DEBUG, INFO, WARNING, ERROR, or CRITICAL)
func (c *CLIConfig) LoggingLevel() string {
return opts.loggingLevel
}
// InitLoggingLevel initializes the logging level from the provided arguments
func InitLoggingLevel(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultLoggingLevel, loggingLevelDescription, defaultValueAndDescription...)
flags.StringVar(&opts.loggingLevel, LoggingLevelFlag, defaultValue, description)
}
// InitConfigFile initializes the config file path from the provided arguments
func InitConfigFile(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultConfigFile, configFileDescription, defaultValueAndDescription...)
flags.StringVar(&opts.configFile, ConfigFileFlag, defaultValue, description)
}
// OrgID specifies the ID of the current organization. If multiple org IDs are specified then the first one is returned.
func (c *CLIConfig) OrgID() string {
if len(c.OrgIDs()) == 0 {
return ""
}
return c.OrgIDs()[0]
}
// OrgIDs returns a comma-separated list of organization IDs
func (c *CLIConfig) OrgIDs() []string {
var orgIDs []string
if len(strings.TrimSpace(opts.orgIDsStr)) > 0 {
s := strings.Split(opts.orgIDsStr, ",")
for _, orgID := range s {
orgIDs = append(orgIDs, orgID)
}
}
return orgIDs
}
// InitOrgIDs initializes the org IDs from the provided arguments
func InitOrgIDs(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultOrgIDs, orgIDsDescription, defaultValueAndDescription...)
flags.StringVar(&opts.orgIDsStr, OrgIDsFlag, defaultValue, description)
}
// ChannelID returns the channel ID
func (c *CLIConfig) ChannelID() string {
return opts.channelID
}
// InitChannelID initializes the channel ID from the provided arguments
func InitChannelID(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultChannelID, channelIDDescription, defaultValueAndDescription...)
flags.StringVar(&opts.channelID, ChannelIDFlag, defaultValue, description)
}
// UserName returns the name of the enrolled user
func (c *CLIConfig) UserName() string {
return opts.user
}
// InitUserName initializes the user name from the provided arguments
func InitUserName(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultUser, userDescription, defaultValueAndDescription...)
flags.StringVar(&opts.user, UserFlag, defaultValue, description)
}
// UserPassword is the password to use when enrolling a user
func (c *CLIConfig) UserPassword() string {
return opts.password
}
// InitUserPassword initializes the user password from the provided arguments
func InitUserPassword(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultPassword, passwordDescription, defaultValueAndDescription...)
flags.StringVar(&opts.password, PasswordFlag, defaultValue, description)
}
// ChaincodeID returns the chaicode ID
func (c *CLIConfig) ChaincodeID() string {
return opts.chaincodeID
}
// InitChaincodeID initializes the chaincode ID from the provided arguments
func InitChaincodeID(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultChaincodeID, chaincodeIDDescription, defaultValueAndDescription...)
flags.StringVar(&opts.chaincodeID, ChaincodeIDFlag, defaultValue, description)
}
// ChaincodeEvent the name of the chaincode event to listen for
func (c *CLIConfig) ChaincodeEvent() string {
return opts.chaincodeEvent
}
// InitChaincodeEvent initializes the chaincode event name from the provided arguments
func InitChaincodeEvent(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultChaincodeEvent, chaincodeEventDescription, defaultValueAndDescription...)
flags.StringVar(&opts.chaincodeEvent, ChaincodeEventFlag, defaultValue, description)
}
// SeekType the seek type for Deliver Events. Possible values:
// - Oldest - will deliver all blocks from the oldest block and will continue listening for new blocks
// - Newest - will deliver the newest block and will continue listening for new blocks
// - FromBlock - Delivers from the specific block, as specified by the "--num" flag
func (c *CLIConfig) SeekType() seek.Type {
return seek.Type(opts.seekType)
}
// InitSeekType initializes the seek type from the provided arguments
func InitSeekType(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultSeekType, seekTypeDescription, defaultValueAndDescription...)
flags.StringVar(&opts.seekType, SeekTypeFlag, defaultValue, description)
}
// ChaincodePath returns the source path of the chaincode to install/instantiate
func (c *CLIConfig) ChaincodePath() string {
return opts.chaincodePath
}
// InitChaincodePath initializes the chaincode install source path from the provided arguments
func InitChaincodePath(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultChaincodePath, chaincodePathDescription, defaultValueAndDescription...)
flags.StringVar(&opts.chaincodePath, ChaincodePathFlag, defaultValue, description)
}
// ChaincodeVersion returns the version of the chaincode
func (c *CLIConfig) ChaincodeVersion() string {
return opts.chaincodeVersion
}
// InitChaincodeVersion initializes the chaincode version from the provided arguments
func InitChaincodeVersion(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultChaincodeVersion, chaincodeVersionDescription, defaultValueAndDescription...)
flags.StringVar(&opts.chaincodeVersion, ChaincodeVersionFlag, defaultValue, description)
}
// PeerURL returns a comma-separated list of peers in the format host1:port1,host2:port2,...
func (c *CLIConfig) PeerURL() string {
return opts.peerURL
}
// PeerURLs returns a list of peer URLs
func (c *CLIConfig) PeerURLs() []string {
var urls []string
if len(strings.TrimSpace(opts.peerURL)) > 0 {
s := strings.Split(opts.peerURL, ",")
for _, orgID := range s {
urls = append(urls, orgID)
}
}
return urls
}
// InitPeerURL initializes the peer URL from the provided arguments
func InitPeerURL(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultPeerURL, peerURLDescription, defaultValueAndDescription...)
flags.StringVar(&opts.peerURL, PeerURLFlag, defaultValue, description)
}
// OrdererURL returns the URL of the orderer
func (c *CLIConfig) OrdererURL() string {
return opts.ordererURL
}
// InitOrdererURL initializes the orderer URL from the provided arguments
func InitOrdererURL(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultOrdererURL, ordererURLDescription, defaultValueAndDescription...)
flags.StringVar(&opts.ordererURL, OrdererFlag, defaultValue, description)
}
// Iterations returns the number of times that a chaincode should be invoked
func (c *CLIConfig) Iterations() int {
return opts.iterations
}
// InitIterations initializes the number of query/invoke iterations from the provided arguments
func InitIterations(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultIterations, iterationsDescription, defaultValueAndDescription...)
i, err := strconv.Atoi(defaultValue)
if err != nil {
fmt.Printf("Invalid number for %s: %s\n", IterationsFlag, defaultValue)
os.Exit(-1)
}
flags.IntVar(&opts.iterations, IterationsFlag, i, description)
}
// SleepTime returns the number of milliseconds to sleep between invocations of a chaincode
func (c *CLIConfig) SleepTime() int64 {
return opts.sleepTime
}
// InitSleepTime initializes the sleep time from the provided arguments
func InitSleepTime(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultSleepTime, sleepTimeDescription, defaultValueAndDescription...)
i, err := strconv.Atoi(defaultValue)
if err != nil {
fmt.Printf("Invalid number for %s: %s\n", SleepFlag, defaultValue)
os.Exit(-1)
}
flags.Int64Var(&opts.sleepTime, SleepFlag, int64(i), description)
}
// BlockNum returns the block number (where 0 is the first block)
func (c *CLIConfig) BlockNum() uint64 {
return opts.blockNum
}
// InitBlockNum initializes the bluck number from the provided arguments
func InitBlockNum(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultBlockNum, blockNumDescription, defaultValueAndDescription...)
i, err := strconv.ParseUint(defaultValue, 10, 64)
if err != nil {
fmt.Printf("Invalid number for %s: %s\n", BlockNumFlag, defaultValue)
os.Exit(-1)
}
flags.Uint64Var(&opts.blockNum, BlockNumFlag, i, description)
}
// BlockHash specifies the hash of the block
func (c *CLIConfig) BlockHash() string {
return opts.blockHash
}
// InitBlockHash initializes the block hash from the provided arguments
func InitBlockHash(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultBlockHash, blockHashDescription, defaultValueAndDescription...)
flags.StringVar(&opts.blockHash, BlockHashFlag, defaultValue, description)
}
// Traverse returns the number of blocks to traverse backwards in the query block command
func (c *CLIConfig) Traverse() int {
return opts.traverse
}
// InitTraverse initializes the 'traverse' flag from the provided arguments
func InitTraverse(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultTraverse, traverseDescription, defaultValueAndDescription...)
i, err := strconv.Atoi(defaultValue)
if err != nil {
fmt.Printf("Invalid number for %s: %s\n", TimeoutFlag, defaultValue)
i = 1
}
flags.IntVar(&opts.traverse, TraverseFlag, i, description)
}
// PrintFormat returns the print (output) format for a block
func (c *CLIConfig) PrintFormat() string {
return opts.printFormat
}
// InitPrintFormat initializes the print format from the provided arguments
func InitPrintFormat(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription("display", printFormatDescription, defaultValueAndDescription...)
flags.StringVar(&opts.printFormat, PrintFormatFlag, defaultValue, description)
}
// Writer returns the writer for output
func (c *CLIConfig) Writer() string {
return opts.writer
}
// InitWriter initializes the print writer from the provided arguments
func InitWriter(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription("stdout", writerDescription, defaultValueAndDescription...)
flags.StringVar(&opts.writer, WriterFlag, defaultValue, description)
}
// Base64 indicates whether binary values are to be encoded in base64. (Only applies to 'display' format.)
func (c *CLIConfig) Base64() bool {
return opts.base64
}
// InitBase64 initializes the base64 flag from the provided arguments
func InitBase64(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription("false", writerDescription, defaultValueAndDescription...)
flags.BoolVar(&opts.base64, Base64Flag, defaultValue == "true", description)
}
// OrdererTLSCertificate is the path of the orderer TLS certificate
func (c *CLIConfig) OrdererTLSCertificate() string {
return opts.certificate
}
// InitOrdererTLSCertificate initializes the orderer TLS certificate from the provided arguments
func InitOrdererTLSCertificate(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultCertificate, certificateDescription, defaultValueAndDescription...)
flags.StringVar(&opts.certificate, CertificateFileFlag, defaultValue, description)
}
// Args returns the chaincode invocation arguments as a JSON string in the format, {"Func":"function","Args":["arg1","arg2",...]}
func (c *CLIConfig) Args() string {
return opts.args
}
// InitArgs initializes the invoke/query args from the provided arguments
func InitArgs(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(getEmptyArgs(), argsDescription, defaultValueAndDescription...)
flags.StringVar(&opts.args, ArgsFlag, defaultValue, description)
}
// TxFile is the path of the .tx file used to create a channel
func (c *CLIConfig) TxFile() string {
return opts.txFile
}
// InitTxFile initializes the path of the .tx file used to create/update a channel from the provided arguments
func InitTxFile(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultTxFile, txFileDescription, defaultValueAndDescription...)
flags.StringVar(&opts.txFile, TxFileFlag, defaultValue, description)
}
// TxID returns the transaction ID
func (c *CLIConfig) TxID() string {
return opts.txID
}
// InitTxID initializes the transaction D from the provided arguments
func InitTxID(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultTxID, txIDDescription, defaultValueAndDescription...)
flags.StringVar(&opts.txID, TxIDFlag, defaultValue, description)
}
// ChaincodePolicy returns the chaincode policy string, e.g Nof(1,(SignedBy(Org1Msp),SignedBy(Org2MSP)))
func (c *CLIConfig) ChaincodePolicy() string {
return opts.chaincodePolicy
}
// InitChaincodePolicy initializes the chaincode policy from the provided arguments
func InitChaincodePolicy(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultChaincodePolicy, chaincodePolicyDescription, defaultValueAndDescription...)
flags.StringVar(&opts.chaincodePolicy, ChaincodePolicyFlag, defaultValue, description)
}
// CollectionConfigFile returns the path of the JSON file that contains the private data collection configuration for the chaincode to be instantiated/upgraded
func (c *CLIConfig) CollectionConfigFile() string {
return opts.collectionConfigFile
}
// InitCollectionConfigFile initializes the collection config file from the provided arguments
func InitCollectionConfigFile(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultCollectionConfigFile, collectionConfigFileDescription, defaultValueAndDescription...)
flags.StringVar(&opts.collectionConfigFile, CollectionConfigFileFlag, defaultValue, description)
}
// Timeout returns the timeout (in milliseconds) for various operations
func (c *CLIConfig) Timeout(timeoutType fab.TimeoutType) time.Duration {
// TODO use provided timoutType
return time.Duration(opts.timeout) * time.Millisecond
}
// InitTimeout initializes the timeout from the provided arguments
func InitTimeout(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultTimeout, timeoutDescription, defaultValueAndDescription...)
i, err := strconv.Atoi(defaultValue)
if err != nil {
fmt.Printf("Invalid number for %s: %s\n", TimeoutFlag, defaultValue)
i = 1000
}
flags.Int64Var(&opts.timeout, TimeoutFlag, int64(i), description)
}
// PrintPayloadOnly indicates whether only the payload or the entire
// transaction proposal response should be printed
func (c *CLIConfig) PrintPayloadOnly() bool {
return opts.printPayloadOnly
}
// InitPrintPayloadOnly initializes the PrintPayloadOnly flag from the provided arguments
func InitPrintPayloadOnly(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultPrintPayloadOnly, printPayloadOnlyDescription, defaultValueAndDescription...)
flags.BoolVar(&opts.printPayloadOnly, PrintPayloadOnlyFlag, defaultValue == "true", description)
}
// Validate indicates whether the endorsement responses from a query should be validated
func (c *CLIConfig) Validate() bool {
return opts.validate
}
// InitValidate initializes the Validate flag from the provided arguments
func InitValidate(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultValidate, validateDescription, defaultValueAndDescription...)
flags.BoolVar(&opts.validate, ValidateFlag, defaultValue == "true", description)
}
// Concurrency returns the number of concurrent invocations/queries
func (c *CLIConfig) Concurrency() uint16 {
return uint16(opts.concurrency)
}
// InitConcurrency initializes the 'concurrency' flag from the provided arguments
func InitConcurrency(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultConcurrency, concurrencyDescription, defaultValueAndDescription...)
i, err := strconv.Atoi(defaultValue)
if err != nil {
fmt.Printf("Invalid number for %s: %s\n", TimeoutFlag, defaultValue)
i = 1
}
flags.IntVar(&opts.concurrency, ConcurrencyFlag, i, description)
}
// MaxAttempts returns the maximum number of invocations attempts to be made
// for a single chaincode invocation request. If >1 then a retry will be attempted
// if a transient failure occurs.
func (c *CLIConfig) MaxAttempts() int {
return opts.maxAttempts
}
// InitMaxAttempts initializes the 'maxAttempts' flag from the provided arguments
func InitMaxAttempts(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultMaxAttempts, maxAttemptsDescription, defaultValueAndDescription...)
i, err := strconv.Atoi(defaultValue)
if err != nil {
fmt.Printf("Invalid number for %s: %s\n", TimeoutFlag, defaultValue)
i = 1
}
flags.IntVar(&opts.maxAttempts, MaxAttemptsFlag, i, description)
}
// InitialBackoff returns the time (in milliseconds) to wait
// before resubmitting an invocation after a transient error
func (c *CLIConfig) InitialBackoff() time.Duration {
return time.Duration(opts.initialBackoff) * time.Millisecond
}
// InitInitialBackoff initializes the initial backoff from the provided arguments
func InitInitialBackoff(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultInitialBackoff, initialBackoffDescription, defaultValueAndDescription...)
i, err := strconv.Atoi(defaultValue)
if err != nil {
fmt.Printf("Invalid number for %s: %s\n", TimeoutFlag, defaultValue)
i = 1000
}
flags.Int64Var(&opts.initialBackoff, InitialBackoffFlag, int64(i), description)
}
// MaxBackoff returns the number
func (c *CLIConfig) MaxBackoff() time.Duration {
return time.Duration(opts.maxBackoff) * time.Millisecond
}
// InitMaxBackoff initializes the maximum backoff from the provided arguments
func InitMaxBackoff(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultMaxBackoff, maxBackoffDescription, defaultValueAndDescription...)
i, err := strconv.Atoi(defaultValue)
if err != nil {
fmt.Printf("Invalid number for %s: %s\n", TimeoutFlag, defaultValue)
i = 1000
}
flags.Int64Var(&opts.maxBackoff, MaxBackoffFlag, int64(i), description)
}
// BackoffFactor returns 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
func (c *CLIConfig) BackoffFactor() float64 {
return opts.backoffFactor
}
// InitBackoffFactor initializes the backoff factor from the provided arguments
func InitBackoffFactor(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultBackoffFactor, backoffFactorDescription, defaultValueAndDescription...)
i, err := strconv.Atoi(defaultValue)
if err != nil {
fmt.Printf("Invalid number for %s: %s\n", TimeoutFlag, defaultValue)
i = 1000
}
flags.Float64Var(&opts.backoffFactor, BackoffFactorFlag, float64(i), description)
}
// Verbose indicates whether or not to print the transaction proposal responses
// when Iterations > 1
func (c *CLIConfig) Verbose() bool {
return opts.verbose
}
// InitVerbosity initializes the Verbose flag from the provided arguments
func InitVerbosity(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultVerbosity, verboseDescription, defaultValueAndDescription...)
flags.BoolVar(&opts.verbose, VerboseFlag, defaultValue == "true", description)
}
// SelectionProvider returns the peer selection provider - either static or dynamic
func (c *CLIConfig) SelectionProvider() string {
return opts.selectionProvider
}
// InitSelectionProvider initializes the peer selection provider from the provided arguments
func InitSelectionProvider(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultSelectionProvider, selectionProviderDescription, defaultValueAndDescription...)
flags.StringVar(&opts.selectionProvider, SelectionProviderFlag, defaultValue, description)
}
// InitGoPath initializes the gopath from the provided arguments
func InitGoPath(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
defaultValue, description := getDefaultValueAndDescription(defaultGoPath, goPathDescription, defaultValueAndDescription...)
flags.StringVar(&opts.goPath, GoPathFlag, defaultValue, description)
}
// GoPath returns the gopath
func (c *CLIConfig) GoPath() string {
gopath := opts.goPath
if !IsFlagSet(GoPathFlag) {
gopath = os.Getenv("GOPATH")
}
return gopath
}
// IsLoggingEnabledFor indicates whether the logger is enabled for the given logging level
func (c *CLIConfig) IsLoggingEnabledFor(level logging.Level) bool {
return logging.IsEnabledFor(loggerName, level)
}
// Utility functions...
func getEmptyArgs() string {
return "{}"
}
func getDefaultValueAndDescription(defaultValue string, defaultDescription string, overrides ...string) (value, description string) {
if len(overrides) > 0 {
value = overrides[0]
} else {
value = defaultValue
}
if len(overrides) > 1 {
description = overrides[1]
} else {
description = defaultDescription
}
return value, description
}
================================================
FILE: fabric-cli/cmd/fabric-cli/event/eventcmd.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package event
import (
"github.com/spf13/cobra"
)
var eventCmd = &cobra.Command{
Use: "event",
Short: "Event commands",
Long: "Event commands",
Run: func(cmd *cobra.Command, args []string) {
cmd.HelpFunc()(cmd, args)
},
}
// Cmd returns the events command
func Cmd() *cobra.Command {
eventCmd.AddCommand(getListenCCCmd())
eventCmd.AddCommand(getListenTXCmd())
eventCmd.AddCommand(getListenBlockCmd())
eventCmd.AddCommand(getListenFilteredBlockCmd())
return eventCmd
}
================================================
FILE: fabric-cli/cmd/fabric-cli/event/inputevent.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package event
import (
"bufio"
"os"
)
type inputEvent struct {
done chan bool
}
// WaitForEnter waits until the user presses Enter
func (c *inputEvent) WaitForEnter() chan bool {
go c.readFromCLI()
return c.done
}
func (c *inputEvent) readFromCLI() {
reader := bufio.NewReader(os.Stdin)
reader.ReadString('\n')
c.done <- true
}
================================================
FILE: fabric-cli/cmd/fabric-cli/event/listenblockcmd.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package event
import (
"fmt"
"github.com/hyperledger/fabric-sdk-go/pkg/client/event"
"github.com/pkg/errors"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var listenBlockCmd = &cobra.Command{
Use: "listenblock",
Short: "Listen to block events.",
Long: "Listen to block events",
Run: func(cmd *cobra.Command, args []string) {
action, err := newlistenBlockAction(cmd.Flags())
if err != nil {
cliconfig.Config().Logger().Errorf("Error while initializing listenBlockAction: %v", err)
return
}
defer action.Terminate()
err = action.invoke()
if err != nil {
cliconfig.Config().Logger().Errorf("Error while running listenBlockAction: %v", err)
}
},
}
func getListenBlockCmd() *cobra.Command {
flags := listenBlockCmd.Flags()
cliconfig.InitChannelID(flags)
cliconfig.InitPeerURL(flags, "", "The URL of the peer on which to listen for events, e.g. localhost:7051")
cliconfig.InitSeekType(flags)
cliconfig.InitBlockNum(flags)
return listenBlockCmd
}
type listenBlockAction struct {
action.Action
inputEvent
}
func newlistenBlockAction(flags *pflag.FlagSet) (*listenBlockAction, error) {
action := &listenBlockAction{inputEvent: inputEvent{done: make(chan bool)}}
err := action.Initialize(flags)
return action, err
}
func (a *listenBlockAction) invoke() error {
eventClient, err := a.EventClient(event.WithBlockEvents(), event.WithSeekType(cliconfig.Config().SeekType()), event.WithBlockNum(cliconfig.Config().BlockNum()))
if err != nil {
return err
}
fmt.Printf("Registering block event\n")
breg, beventch, err := eventClient.RegisterBlockEvent()
if err != nil {
return errors.WithMessage(err, "Error registering for block events")
}
defer eventClient.Unregister(breg)
enterch := a.WaitForEnter()
for {
select {
case _, _ = <-enterch:
return nil
case event, ok := <-beventch:
if !ok {
return errors.WithMessage(err, "unexpected closed channel while waiting for block event")
}
a.Printer().PrintBlock(event.Block)
fmt.Println("Press <enter> to terminate")
}
}
}
================================================
FILE: fabric-cli/cmd/fabric-cli/event/listencccmd.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package event
import (
"fmt"
"github.com/pkg/errors"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var listenccCmd = &cobra.Command{
Use: "listencc",
Short: "Listen to chaincode events.",
Long: "Listen to chaincode events",
Run: func(cmd *cobra.Command, args []string) {
if cliconfig.Config().ChaincodeID() == "" {
fmt.Printf("\nMust specify the chaincode ID\n\n")
cmd.HelpFunc()(cmd, args)
return
}
if cliconfig.Config().ChaincodeEvent() == "" {
fmt.Printf("\nMust specify the event name\n\n")
cmd.HelpFunc()(cmd, args)
return
}
action, err := newListenCCAction(cmd.Flags())
if err != nil {
fmt.Printf("\nError while initializing listenCCAction: %v\n", err)
return
}
defer action.Terminate()
err = action.invoke()
if err != nil {
fmt.Printf("\nError while running listenCCAction: %v\n", err)
}
},
}
func getListenCCCmd() *cobra.Command {
flags := listenccCmd.Flags()
cliconfig.InitChannelID(flags)
cliconfig.InitPeerURL(flags, "", "The URL of the peer on which to listen for events, e.g. grpcs://localhost:7051")
cliconfig.InitChaincodeID(flags)
cliconfig.InitChaincodeEvent(flags)
return listenccCmd
}
type listenccAction struct {
action.Action
inputEvent
}
func newListenCCAction(flags *pflag.FlagSet) (*listenccAction, error) {
action := &listenccAction{inputEvent: inputEvent{done: make(chan bool)}}
err := action.Initialize(flags)
return action, err
}
func (a *listenccAction) invoke() error {
fmt.Printf("Registering CC event on chaincode [%s] and event [%s]\n", cliconfig.Config().ChaincodeID(), cliconfig.Config().ChaincodeEvent())
eventHub, err := a.EventClient()
if err != nil {
return err
}
breg, beventch, err := eventHub.RegisterChaincodeEvent(cliconfig.Config().ChaincodeID(), cliconfig.Config().ChaincodeEvent())
if err != nil {
return errors.WithMessage(err, "Error registering for block events")
}
defer eventHub.Unregister(breg)
enterch := a.WaitForEnter()
for {
select {
case _, _ = <-enterch:
return nil
case event, ok := <-beventch:
if !ok {
return errors.WithMessage(err, "unexpected closed channel while waiting for block event")
}
a.Printer().PrintChaincodeEvent(event)
fmt.Println("Press <enter> to terminate")
}
}
}
================================================
FILE: fabric-cli/cmd/fabric-cli/event/listenfilteredblockcmd.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package event
import (
"fmt"
"github.com/hyperledger/fabric-sdk-go/pkg/client/event"
"github.com/pkg/errors"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var listenFilteredBlockCmd = &cobra.Command{
Use: "listenfilteredblock",
Short: "Listen to filtered block events.",
Long: "Listen to filtered block events",
Run: func(cmd *cobra.Command, args []string) {
action, err := newlistenFilteredBlockAction(cmd.Flags())
if err != nil {
cliconfig.Config().Logger().Errorf("Error while initializing listenFilteredBlockAction: %v", err)
return
}
defer action.Terminate()
err = action.invoke()
if err != nil {
cliconfig.Config().Logger().Errorf("Error while running listenFilteredBlockAction: %v", err)
}
},
}
func getListenFilteredBlockCmd() *cobra.Command {
flags := listenFilteredBlockCmd.Flags()
cliconfig.InitChannelID(flags)
cliconfig.InitPeerURL(flags, "", "The URL of the peer on which to listen for events, e.g. localhost:7051")
cliconfig.InitSeekType(flags)
cliconfig.InitBlockNum(flags)
return listenFilteredBlockCmd
}
type listenFilteredBlockAction struct {
action.Action
inputEvent
}
func newlistenFilteredBlockAction(flags *pflag.FlagSet) (*listenFilteredBlockAction, error) {
action := &listenFilteredBlockAction{inputEvent: inputEvent{done: make(chan bool)}}
err := action.Initialize(flags)
return action, err
}
func (a *listenFilteredBlockAction) invoke() error {
eventClient, err := a.EventClient(event.WithSeekType(cliconfig.Config().SeekType()), event.WithBlockNum(cliconfig.Config().BlockNum()))
if err != nil {
return err
}
fmt.Printf("Registering filtered block event\n")
breg, beventch, err := eventClient.RegisterFilteredBlockEvent()
if err != nil {
return errors.WithMessage(err, "Error registering for filtered block events")
}
defer eventClient.Unregister(breg)
enterch := a.WaitForEnter()
for {
select {
case _, _ = <-enterch:
return nil
case event, ok := <-beventch:
if !ok {
return errors.WithMessage(err, "unexpected closed channel while waiting for filtered block event")
}
a.Printer().PrintFilteredBlock(event.FilteredBlock)
fmt.Println("Press <enter> to terminate")
}
}
}
================================================
FILE: fabric-cli/cmd/fabric-cli/event/listentxcmd.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package event
import (
"fmt"
"github.com/pkg/errors"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/action"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var listenTxCmd = &cobra.Command{
Use: "listentx",
Short: "Listen to transaction events.",
Long: "Listen to transaction events",
Run: func(cmd *cobra.Command, args []string) {
if cliconfig.Config().TxID() == "" {
fmt.Printf("\nMust specify the transaction ID\n\n")
cmd.HelpFunc()(cmd, args)
return
}
action, err := newListenTXAction(cmd.Flags())
if err != nil {
cliconfig.Config().Logger().Errorf("Error while initializing listenTxAction: %v", err)
return
}
defer action.Terminate()
err = action.invoke()
if err != nil {
cliconfig.Config().Logger().Errorf("Error while running listenTxAction: %v", err)
}
},
}
func getListenTXCmd() *cobra.Command {
flags := listenTxCmd.Flags()
cliconfig.InitChannelID(flags)
cliconfig.InitTxID(flags)
cliconfig.InitPeerURL(flags, "", "The URL of the peer on which to listen for events, e.g. grpcs://localhost:7051")
return listenTxCmd
}
type listentxAction struct {
action.Action
inputEvent
}
func newListenTXAction(flags *pflag.FlagSet) (*listentxAction, error) {
action := &listentxAction{inputEvent: inputEvent{done: make(chan bool)}}
err := action.Initialize(flags)
return action, err
}
func (a *listentxAction) invoke() error {
eventHub, err := a.EventClient()
if err != nil {
return err
}
fmt.Printf("Registering TX event for TxID [%s]\n", cliconfig.Config().TxID())
reg, eventch, err := eventHub.RegisterTxStatusEvent(cliconfig.Config().TxID())
if err != nil {
return errors.WithMessage(err, "Error registering for block events")
}
defer eventHub.Unregister(reg)
enterch := a.WaitForEnter()
fmt.Println("Press <enter> to terminate")
select {
case _, _ = <-enterch:
return nil
case event, ok := <-eventch:
if !ok {
return errors.WithMessage(err, "unexpected closed channel while waiting for tx status event")
}
fmt.Printf("Received TX event. TxID: %s, Code: %s, Error: %s\n", event.TxID, event.TxValidationCode, err)
}
return nil
}
================================================
FILE: fabric-cli/cmd/fabric-cli/executor/executor.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package executor
import (
"fmt"
"math"
"sync"
"time"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/executor/worker"
)
// State is the state of the executor
type State uint8
const (
// NEW indicates that the executor is new and has not been started yet
NEW State = iota
// STARTED indicates that the executor is up and running
STARTED
// TERMINATED indicates that the executor has been shut down
TERMINATED
)
// Executor maintains a pool of workers that execute Tasks in separate Go routines. The caller submits
// a Task to the Executor, which is submitted to an available worker. If a worker is not available then
// the task is queue until one becomes available. The Executor is useful for throttling requests in order
// not to overload the application.
type Executor struct {
name string
state State
tasks chan worker.Task
terminating chan bool
pool *worker.Pool
wg sync.WaitGroup
}
// NewConcurrent creates a new, concurrent executor with the given concurrency.
// As tasks are submitted they are queued while waiting for a worker for execution.
//
// - name: The name of the executor (useful for debugging)
// - concurrency: The concurrency, i.e. the number of workers executing concurrently
func NewConcurrent(name string, concurrency uint16) *Executor {
return New(name, math.MaxInt16, worker.NewPool(name, concurrency))
}
// NewBoundedConcurrent creates a new, concurrent executor with the given concurrency
// and queue length. As tasks are submitted they are queued while waiting for a worker for execution. Once the
// number of queued tasks reaches the given queue length, the Submit operation will block until a worker becomes
// available.
//
// - name: The name of the executor (useful for debugging)
// - concurrency: The concurrency, i.e. the number of workers executing concurrently
// - queueLength: The maximum number of tasks allowed to be queued while waiting for a worker
func NewBoundedConcurrent(name string, concurrency uint16, queueLength uint16) *Executor {
return New(name, queueLength, worker.NewPool(name, concurrency))
}
// New creates a new, multi-threaded executor with the given options:
// - name: The name of the executor (useful for debugging)
// - queueLength: The maximum number of tasks allowed to be queued while waiting for a worker
// If queueSize == concurrency then the Submit() function will block until a worker becomes free,
// otherwise the task will be added to the queue and Submit() will not block.
// pool - The worker pool
func New(name string, queueLength uint16, pool *worker.Pool) *Executor {
return &Executor{
name: name,
state: NEW,
terminating: make(chan bool),
tasks: make(chan worker.Task, queueLength),
pool: pool,
}
}
// Start starts the Executor
func (e *Executor) Start() bool {
if e.state != NEW {
return false
}
// Start the worker pool
e.pool.Start()
// Start the task dispatcher
go e.dispatch()
e.state = STARTED
return true
}
// Submit submits a new task
func (e *Executor) Submit(task worker.Task) error {
if e.state != STARTED {
return fmt.Errorf("executor [%s] is not started", e.name)
}
// Submit the task to the dispatcher
cliconfig.Config().Logger().Debugf("Submit[%s] - submitting task...\n", e.name)
e.wg.Add(1)
e.tasks <- task
cliconfig.Config().Logger().Debugf("...Submit[%s] - submitted task\n", e.name)
return nil
}
// SubmitDelayed submits a new task in the future
func (e *Executor) SubmitDelayed(task worker.Task, delay time.Duration) error {
if e.state != STARTED {
return fmt.Errorf("executor [%s] is not started", e.name)
}
cliconfig.Config().Logger().Debugf("Submit[%s] - submitting task to execute in %s ...\n", e.name, delay)
e.wg.Add(1)
go func() {
<-time.After(delay)
e.Submit(task)
e.wg.Done()
}()
return nil
}
// Wait waits for all outstanding tasks to complete
func (e *Executor) Wait() {
e.wg.Wait()
}
// Stop stops the executor.
// - wait: If true then the call will block until all outstanding
// tasks have completed; otherwise the executor will shut down immediately
func (e *Executor) Stop(wait bool) bool {
if e.state != STARTED {
return false
}
e.state = TERMINATED
cliconfig.Config().Logger().Debugf("[%s] Stopping executor ...\n", e.name)
// Wait for the dispatcher to purge its queue
e.wg.Wait()
cliconfig.Config().Logger().Debugf("[%s] Stopping the dispatcher ...\n", e.name)
// Stop the dispatcher
e.terminating <- true
cliconfig.Config().Logger().Debugf("[%s] Stopping the worker pool ...\n", e.name)
// Stop the worker pool
e.pool.Stop(wait)
cliconfig.Config().Logger().Debugf("[%s] ... executor stopped.\n", e.name)
return true
}
func (e *Executor) dispatch() {
for {
select {
// Wait for a task
case task := <-e.tasks:
e.pool.Submit(task)
e.wg.Done()
case <-e.terminating:
cliconfig.Config().Logger().Debugf("[%s] ... executor dispatcher ended\n", e.name)
return
}
}
}
================================================
FILE: fabric-cli/cmd/fabric-cli/executor/worker/worker.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package worker
import (
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
)
// State is the state of a Worker
type State uint8
const (
// READY indicates that a worker is ready to accept a new task
READY State = iota
// STOPPED indicates that the worker has terminated
STOPPED
)
// Task is the task that the Worker invokes
type Task interface {
Invoke()
}
// Events receives event notifications from the worker
type Events interface {
// StateChange indicates the new state of the worker
StateChange(w *Worker, state State)
// TaskStarted indicates that the given worker has started executing the given task
TaskStarted(w *Worker, task Task)
// TaskCompleted indicates that the given worker has completed the given task
TaskCompleted(w *Worker, task Task)
}
// Worker invokes a Task
type Worker struct {
name string
events Events
task chan Task
done chan bool
}
func newWorker(name string, events Events) *Worker {
return &Worker{
name: name,
events: events,
task: make(chan Task),
done: make(chan bool),
}
}
// Name returns the name of the worker (useful for debugging)
func (w *Worker) Name() string {
return w.name
}
// Submit submits a task
func (w *Worker) Submit(task Task) {
w.task <- task
}
func (w *Worker) invoke(task Task) {
cliconfig.Config().Logger().Debugf("Worker[%s].invoke ...\n", w.name)
defer w.events.TaskCompleted(w, task)
w.events.TaskStarted(w, task)
task.Invoke()
cliconfig.Config().Logger().Debugf("Worker[%s].invoke done.\n", w.name)
}
// Start starts the worker
func (w *Worker) Start() {
cliconfig.Config().Logger().Debugf("Worker[%s] starting...\n", w.name)
go func() {
for {
cliconfig.Config().Logger().Debugf("Worker[%s] waiting for task...\n", w.name)
// Inform the events that I'm available
w.events.StateChange(w, READY)
select {
case task := <-w.task:
w.invoke(task)
case <-w.done:
w.events.StateChange(w, STOPPED)
cliconfig.Config().Logger().Debugf("Worker[%s] stopped\n", w.name)
return
}
}
}()
}
// Stop stops the worker
func (w *Worker) Stop() {
cliconfig.Config().Logger().Debugf("Worker[%s] stopping...\n", w.name)
w.done <- true
}
================================================
FILE: fabric-cli/cmd/fabric-cli/executor/worker/workerpool.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package worker
import (
"fmt"
"sync"
cliconfig "github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/config"
)
// Pool contains a pool of workers that can each execute a Task
type Pool struct {
name string
workers []*Worker
availableWorker chan *Worker
taskWg sync.WaitGroup
wg sync.WaitGroup
}
// NewPool creates a worker Pool with the given Factory
func NewPool(name string, concurrency uint16) *Pool {
pool := &Pool{
name: name,
availableWorker: make(chan *Worker, concurrency),
workers: make([]*Worker, concurrency),
}
// Create the workers
for i := 0; i < int(concurrency); i++ {
pool.workers[i] = newWorker(fmt.Sprintf("%s-%d", name, i), pool)
}
return pool
}
// Name returns the name of the pool
func (p *Pool) Name() string {
return p.name
}
// Start starts the pool
func (p *Pool) Start() {
p.wg.Add(len(p.workers))
// Start the workers
for _, w := range p.workers {
w.Start()
}
}
// Stop stops the pool and optionally waits until all tasks have completed
func (p *Pool) Stop(wait bool) {
cliconfig.Config().Logger().Debugf("[%s] Stopping worker pool ...\n", p.name)
if wait {
// Wait for all the tasks to complete
cliconfig.Config().Logger().Debugf("[%s] ... waiting for tasks to complete ...\n", p.name)
p.taskWg.Wait()
} else {
cliconfig.Config().Logger().Debugf("[%s] ... forcing all tasks to stop ...\n", p.name)
}
// Shut down the workers
cliconfig.Config().Logger().Debugf("[%s] ... stopping workers ...\n", p.name)
for i := 0; i < len(p.workers); i++ {
w := <-p.availableWorker
w.Stop()
}
// Wait for all of the workers to stop
p.wg.Wait()
}
// Submit submits a Task for execution
func (p *Pool) Submit(task Task) {
cliconfig.Config().Logger().Debugf("worker pool.Submit[%s] - waiting for available worker\n", p.name)
p.taskWg.Add(1)
// Wait for an available worker
w := <-p.availableWorker
cliconfig.Config().Logger().Debugf("worker pool.Submit[%s] - got worker [%s]. Submitting task...\n", p.name, w.Name())
// Submit the task to the worker
w.Submit(task)
cliconfig.Config().Logger().Debugf("worker pool.Submit[%s] - submitted task to worker[%s]\n", p.name, w.Name())
}
// StateChange is invoked when the state of the Worker changes
func (p *Pool) StateChange(w *Worker, state State) {
switch state {
case READY:
p.availableWorker <- w
break
case STOPPED:
cliconfig.Config().Logger().Debugf("...Worker[%s] stopped\n", w.Name())
p.wg.Done()
break
default:
cliconfig.Config().Logger().Warnf("Unsupported worker state: %d\n", state)
break
}
}
// TaskStarted is invoked when the given Worker begins executing the given Task
func (p *Pool) TaskStarted(w *Worker, task Task) {
// Nothing to do
}
// TaskCompleted is invoked when the given Worker completed executing the given Task
func (p *Pool) TaskCompleted(w *Worker, task Task) {
p.taskWg.Done()
}
================================================
FILE: fabric-cli/cmd/fabric-cli/fabric-cli.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package main
import (
"github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli/cmd"
)
func main() {
cmd.Execute()
}
================================================
FILE: fabric-cli/cmd/fabric-cli/go.mod
================================================
// Copyright SecureKey Technologies Inc. All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
module github.com/securekey/fabric-examples/fabric-cli/cmd/fabric-cli
require (
github.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5 // indirect
github.com/golang/protobuf v1.3.2
github.com/hyperledger/fabric-protos-go v0.0.0-20191121202242-f5500d5e3e85
github.com/hyperledger/fabric-sdk-go v1.0.0-beta1.0.20200106161850-8f3d32c9d1a6
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/magiconair/properties v1.8.0 // indirect
github.com/mitchellh/mapstructure v0.0.0-20180511142126-bb74f1db0675 // indirect
github.com/pelletier/go-toml v1.2.0 // indirect
github.com/pkg/errors v0.8.1
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e // indirect
github.com/prometheus/procfs v0.0.0-20180920065004-418d78d0b9a7 // indirect
github.com/spf13/afero v1.1.1 // indirect
github.com/spf13/cobra v0.0.3
github.com/spf13/pflag v1.0.1
github.com/stretchr/testify v1.3.0
)
go 1.13
================================================
FILE: fabric-cli/cmd/fabric-cli/go.sum
================================================
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Knetic/govaluate v3.0.0+incompatible h1:7o6+MAPhYTCF0+fdvoz1xDedhRb4f6s9Tn1Tt7/WTEg=
github.com/Knetic/govaluate v3.0.0+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
github.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5 h1:PqZ3bA4yzwywivzk7PBQWngJp2/PAS0bWRZerKteicY=
github.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/certificate-transparency-go v0.0.0-20180222191210-5ab67e519c93 h1:qdfmdGwtm13OVx+AxguOWUTbgmXGn2TbdUHipo3chMg=
github.com/google/certificate-transparency-go v0.0.0-20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce h1:xdsDDbiBDQTKASoGEZ+pEmF1OnWuu8AQ9I8iNbHNeno=
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hyperledger/fabric-lib-go v1.0.0 h1:UL1w7c9LvHZUSkIvHTDGklxFv2kTeva1QI2emOVc324=
github.com/hyperledger/fabric-lib-go v1.0.0/go.mod h1:H362nMlunurmHwkYqR5uHL2UDWbQdbfz74n8kbCFsqc=
github.com/hyperledger/fabric-protos-go v0.0.0-20191121202242-f5500d5e3e85 h1:bNgEcCg5NVRWs/T+VUEfhgh5Olx/N4VB+0+ybW+oSuA=
github.com/hyperledger/fabric-protos-go v0.0.0-20191121202242-f5500d5e3e85/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0=
github.com/hyperledger/fabric-sdk-go v1.0.0-beta1.0.20200106161850-8f3d32c9d1a6 h1:oEdHFGkrXcfoJdXmxem5fCyXS23SdfHc2UPt5g8o6HM=
github.com/hyperledger/fabric-sdk-go v1.0.0-beta1.0.20200106161850-8f3d32c9d1a6/go.mod h1:/s224b8NLvOJOCIqBvWd9O6u7GE33iuIOT6OfcTE1OE=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/pkcs11 v0.0.0-20190329070431-55f3fac3af27 h1:XA/VH+SzpYyukhgh7v2mTp8rZoKKITXR/x3FIizVEXs=
github.com/miekg/pkcs11 v0.0.0-20190329070431-55f3fac3af27/go.mod h1:WCBAbTOdfhHhz7YXujeZMF7owC4tPb1naKFsgfUISjo=
github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v0.0.0-20180511142126-bb74f1db0675 h1:/rdJjIiKG5rRdwG5yxHmSE/7ZREjpyC0kL7GxGT/qJw=
github.com/mitchellh/mapstructure v0.0.0-20180511142126-bb74f1db0675/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.8.0 h1:1921Yw9Gc3iSc4VQh3PIoOqgPCZS7G/4xQNVUp8Mda8=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/common v0.0.0-20180518154759-7600349dcfe1/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e h1:n/3MEhJQjQxrOUCzh1Y3Re6aJUUWRp2M9+Oc3eVn/54=
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/procfs v0.0.0-20180705121852-ae68e2d4c00f/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20180920065004-418d78d0b9a7 h1:NgR6WN8nQ4SmFC1sSUHY8SriLuWCZ6cCIQtH4vDZN3c=
github.com/prometheus/procfs v0.0.0-20180920065004-418d78d0b9a7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/spf13/afero v1.1.0/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.1.1 h1:Lt3ihYMlE+lreX1GS4Qw4ZsNpYQLxIXKBTEOXm3nt6I=
github.com/spf13/afero v1.1.1/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.2.0 h1:HHl1DSRbEQN2i8tJmtS6ViPyHx35+p51amrdsiTCrkg=
github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec h1:2ZXvIUGghLpdTVHR1UfvfrzoVlZaE/yOWC5LueIHZig=
github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.0.2 h1:Ncr3ZIuJn322w2k1qmzXDnkLAdQMlJqBa9kfAH+irso=
github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd h1:HuTn7WObtcDo9uEEU7rEqL0jYthdXAmZ6PP+meazmaU=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190327125643-d831d65fe17d h1:XB2jc5XQ9uhizGTS2vWcN01bc4dI6z3C4KY5MQm8SS8=
google.golang.org/genproto v0.0.0-20190327125643-d831d65fe17d/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
================================================
FILE: fabric-cli/cmd/fabric-cli/printer/blockprinter.go
================================================
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package printer
import (
"encoding/base64"
"fmt"
"net/http"
"reflect"
"strings"
"github.com/golang/protobuf/proto"
fabriccmn "github.com/hyperledger/fabric-protos-go/common"
"github.com/hyperledger/fabric-protos-go/ledger/rwset/kvrwset"
"github.com/hyperledger/fabric-protos-go/msp"
ab "github.com/hyperledger/fabric-protos-go/orderer"
pb "github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab"
"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/core/common/ccprovider"
"github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/rwsetutil"
ledgerUtil "github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/core/ledger/util"
"github.com/pkg/errors"
)
const (
// AnchorPeersKey is the key name for the AnchorPeers ConfigValue
AnchorPeersKey = "AnchorPeers"
// ReadersPolicyKey is the key used for the read policy
ReadersPolicyKey = "Readers"
// WritersPolicyKey is the key used for the read policy
WritersPolicyKey = "Writers"
// AdminsPolicyKey is the key used for the read policy
AdminsPolicyKey = "Admins"
// MSPKey is the org key used for MSP configuration
MSPKey = "MSP"
// ConsensusTypeKey is the cb.ConfigItem type key name for the ConsensusType message
ConsensusTypeKey = "ConsensusType"
// BatchSizeKey is the cb.ConfigItem type key name for the BatchSize message
BatchSizeKey = "BatchSize"
// BatchTimeoutKey is the cb.ConfigItem type key name for the BatchTimeout message
BatchTimeoutKey = "BatchTimeout"
// ChannelRestrictionsKey is the key name for the ChannelRestrictions message
ChannelRestrictionsKey = "ChannelRestrictions"
// KafkaBrokersKey is the cb.ConfigItem type key name for the KafkaBrokers message
KafkaBrokersKey = "KafkaBrokers"
// ChannelCreationPolicyKey is the key for the ChannelCreationPolicy value
ChannelCreationPolicyKey = "ChannelCreationPolicy"
// ConsortiumKey is the key for the cb.ConfigValue for the Consortium message
ConsortiumKey = "Consortium"
// HashingAlgorithmKey is the cb.ConfigItem type key name for the HashingAlgorithm message
HashingAlgorithmKey = "HashingAlgorithm"
// BlockDataHashingStructureKey is the cb.ConfigItem type key name for the BlockDataHashingStructure message
BlockDataHashingStructureKey = "BlockDataHashingStructure"
// OrdererAddressesKey is the cb.ConfigItem type key name for the OrdererAddresses message
OrdererAddressesKey = "OrdererAddresses"
// ChannelGroupKey is the name of the channel group
ChannelGroupKey = "Channel"
// CapabilitiesKey is the key for capabilities
CapabilitiesKey = "Capabilities"
collectionSeparator = "~"
)
// Printer is used for printing various data structures
type Printer interface {
// PrintBlockchainInfo outputs BlockchainInfo
PrintBlockchainInfo(info *fabriccmn.BlockchainInfo)
// PrintBlock outputs a Block
PrintBlock(block *fabriccmn.Block)
// PrintFilteredBlock outputs a Block
PrintFilteredBlock(block *pb.FilteredBlock)
// PrintChannels outputs the array of ChannelInfo
PrintChannels(channels []*pb.ChannelInfo)
// PrintChaincodes outputs the given array of ChaincodeInfo
PrintChaincodes(chaincodes []*pb.ChaincodeInfo)
// PrintProcessedTransaction outputs a ProcessedTransaction
PrintProcessedTransaction(tx *pb.ProcessedTransaction)
// PrintChaincodeData outputs ChaincodeData
PrintChaincodeData(ccdata *ccprovider.ChaincodeData, collConfig *pb.CollectionConfigPackage)
// PrintTxProposalResponses outputs the proposal responses
PrintTxProposalResponses(responses []*fab.TransactionProposalResponse, payloadOnly bool)
// PrintResponses outputs responses
PrintResponses(response []*pb.Response)
// PrintChaincodeEvent outputs a chaincode event
PrintChaincodeEvent(event *fab.CCEvent)
// PrintPeers outputs the array of Peers
PrintPeers(peers []fab.Peer)
// Print outputs a formatted string
Print(frmt string, vars ...interface{})
}
// BlockPrinter is an implementation of BlockPrinter
type BlockPrinter struct {
printer
}
// NewBlockPrinter returns a new Printer of the given OutputFormat and WriterType
func NewBlockPrinter(format OutputFormat, writerType WriterType) *BlockPrinter {
return &BlockPrinter{
printer: *newPrinter(format, writerType),
}
}
// NewBlockPrinterWithOpts returns a new Printer of the given OutputFormat and WriterType
func NewBlockPrinterWithOpts(format OutputFormat, writerType WriterType, opts *FormatterOpts) *BlockPrinter {
return &BlockPrinter{
printer: *newPrinterWithOpts(format, writerType, opts),
}
}
// PrintBlockchainInfo prints BlockchainInfo
func (p *BlockPrinter) PrintBlockchainInfo(info *fabriccmn.BlockchainInfo) {
if p.Formatter == nil {
fmt.Printf("%s\n", info)
return
}
p.PrintHeader()
p.Field("Height", info.Height)
p.Field("CurrentBlockHash", Base64URLEncode(info.CurrentBlockHash))
p.Field("PreviousBlockHash", Base64URLEncode(info.PreviousBlockHash))
p.PrintFooter()
}
// PrintBlock prints a Block
func (p *BlockPrinter) PrintBlock(block *fabriccmn.Block) {
if p.Formatter == nil {
fmt.Printf("%s\n", block)
return
}
p.PrintHeader()
p.Element("Header")
p.Field("Number", block.Header.Number)
p.Field("PreviousHash", Base64URLEncode(block.Header.PreviousHash))
p.Field("DataHash", Base64URLEncode(block.Header.DataHash))
p.ElementEnd()
p.Element("Metadata")
p.PrintBlockMetadata(block.Metadata)
p.ElementEnd()
p.Element("Data")
p.Array("Data")
for i := range block.Data.Data {
p.Item("Envelope", i)
p.PrintEnvelope(ExtractEnvelopeOrPanic(block, i))
p.ItemEnd()
}
p.ArrayEnd()
p.ElementEnd()
p.PrintFooter()
}
// PrintFilteredBlock prints a FilteredBlock
func (p *BlockPrinter) PrintFilteredBlock(block *pb.FilteredBlock) {
if p.Formatter == nil {
fmt.Printf("%s\n", block)
return
}
p.PrintHeader()
p.Field("ChannelID", block.ChannelId)
p.Field("Number", block.Number)
p.Element("FilteredTransactions")
p.Array("FilteredTransactions")
for _, tx := range block.FilteredTransactions {
p.PrintFilteredTransaction(tx)
}
p.ArrayEnd()
p.ElementEnd()
p.PrintFooter()
}
// PrintChannels prints the array of ChannelInfo
func (p *BlockPrinter) PrintChannels(channels []*pb.ChannelInfo) {
if p.Formatter == nil {
fmt.Printf("%s\n", channels)
return
}
p.PrintHeader()
p.Array("Channels")
for _, channel := range channels {
p.Field("ChannelId", channel.ChannelId)
}
p.ArrayEnd()
p.PrintFooter()
}
func (p *BlockPrinter) PrintPeers(peers []fab.Peer) {
if p.Formatter == nil {
fmt.Printf("%s\n", peers)
return
}
p.PrintHeader()
p.Array("Peers")
for _, peer := range peers {
p.Item("Peer", peer.URL())
p.PrintPeer(peer)
p.ItemEnd()
}
p.ArrayEnd()
p.PrintFooter()
}
// PrintChaincodes prints th
gitextract_8xm2cptt/
├── .gitignore
├── .gitreview
├── README.md
└── fabric-cli/
├── .gitignore
├── LICENSE
├── Makefile
├── README.md
├── cmd/
│ └── fabric-cli/
│ ├── action/
│ │ ├── action.go
│ │ └── svcproviderfactory.go
│ ├── chaincode/
│ │ ├── chaincodecmd.go
│ │ ├── getinfocmd.go
│ │ ├── installcmd.go
│ │ ├── instantiatecmd.go
│ │ ├── invokecmd.go
│ │ ├── invokeerror/
│ │ │ └── invokeerror.go
│ │ ├── invoketask/
│ │ │ └── invoketask.go
│ │ ├── multitask/
│ │ │ └── multitask.go
│ │ ├── querycmd.go
│ │ ├── querytask/
│ │ │ └── querytask.go
│ │ ├── task/
│ │ │ └── task.go
│ │ ├── upgradecmd.go
│ │ └── utils/
│ │ ├── test.json
│ │ ├── util.go
│ │ └── util_test.go
│ ├── channel/
│ │ ├── channelcmd.go
│ │ ├── channelcreatecmd.go
│ │ └── channeljoincmd.go
│ ├── cmd/
│ │ └── fabric-cli.go
│ ├── config/
│ │ └── config.go
│ ├── event/
│ │ ├── eventcmd.go
│ │ ├── inputevent.go
│ │ ├── listenblockcmd.go
│ │ ├── listencccmd.go
│ │ ├── listenfilteredblockcmd.go
│ │ └── listentxcmd.go
│ ├── executor/
│ │ ├── executor.go
│ │ └── worker/
│ │ ├── worker.go
│ │ └── workerpool.go
│ ├── fabric-cli.go
│ ├── go.mod
│ ├── go.sum
│ ├── printer/
│ │ ├── blockprinter.go
│ │ ├── formatter.go
│ │ ├── printer.go
│ │ ├── protoutils.go
│ │ └── writer.go
│ └── query/
│ ├── queryblockcmd.go
│ ├── querychannelscmd.go
│ ├── querycmd.go
│ ├── queryinfocmd.go
│ ├── queryinstalledcmd.go
│ ├── querylocalpeerscmd.go
│ ├── querypeerscmd.go
│ └── querytxcmd.go
└── test/
├── fixtures/
│ ├── config/
│ │ ├── config_test_local.yaml
│ │ └── pvtdatacollection.json
│ └── testdata/
│ └── src/
│ ├── github.com/
│ │ └── securekey/
│ │ ├── example2_cc/
│ │ │ └── example2_cc.go
│ │ └── example_cc/
│ │ └── example_cc.go
│ ├── go.mod
│ └── go.sum
└── integration/
├── fabric-cli_test.go
├── go.mod
└── go.sum
SYMBOL INDEX (735 symbols across 47 files)
FILE: fabric-cli/cmd/fabric-cli/action/action.go
constant defaultUser (line 43) | defaultUser = "User1"
constant adminUser (line 44) | adminUser = "Admin"
type ArgStruct (line 48) | type ArgStruct struct
type Action (line 54) | type Action struct
method Initialize (line 68) | func (action *Action) Initialize(flags *pflag.FlagSet) error {
method Terminate (line 171) | func (action *Action) Terminate() {
method Flags (line 179) | func (action *Action) Flags() *pflag.FlagSet {
method EndpointConfig (line 184) | func (action *Action) EndpointConfig() fab.EndpointConfig {
method ChannelClient (line 189) | func (action *Action) ChannelClient(...channel.ClientOption) (*channel...
method OrgAdminChannelClient (line 205) | func (action *Action) OrgAdminChannelClient(orgID string) (*channel.Cl...
method AdminChannelClient (line 223) | func (action *Action) AdminChannelClient() (*channel.Client, error) {
method Printer (line 228) | func (action *Action) Printer() printer.Printer {
method LocalContext (line 233) | func (action *Action) LocalContext() (context.Local, error) {
method ChannelProvider (line 246) | func (action *Action) ChannelProvider() (context.ChannelProvider, erro...
method EventClient (line 264) | func (action *Action) EventClient(opts ...event.ClientOption) (*event....
method LedgerClient (line 277) | func (action *Action) LedgerClient() (*ledger.Client, error) {
method Peer (line 290) | func (action *Action) Peer() fab.Peer {
method Peers (line 298) | func (action *Action) Peers() []fab.Peer {
method PeersByOrg (line 303) | func (action *Action) PeersByOrg() map[string][]fab.Peer {
method OrgOfPeer (line 308) | func (action *Action) OrgOfPeer(peerURL string) (string, error) {
method Client (line 317) | func (action *Action) Client(channelID string) (*channel.Client, error) {
method ResourceMgmtClient (line 326) | func (action *Action) ResourceMgmtClient() (*resmgmt.Client, error) {
method ResourceMgmtClientForOrg (line 331) | func (action *Action) ResourceMgmtClientForOrg(orgID string) (*resmgmt...
method ClientForUser (line 340) | func (action *Action) ClientForUser(channelID string, user mspapi.Sign...
method ResourceMgmtClientForUser (line 357) | func (action *Action) ResourceMgmtClientForUser(user mspapi.SigningIde...
method ChannelMgmtClientForUser (line 371) | func (action *Action) ChannelMgmtClientForUser(channelID string, user ...
method context (line 387) | func (action *Action) context(user mspapi.SigningIdentity) (context.Cl...
method OrgID (line 399) | func (action *Action) OrgID() string {
method GetOrgID (line 415) | func (action *Action) GetOrgID(mspID string) (string, error) {
method User (line 427) | func (action *Action) User() (mspapi.SigningIdentity, error) {
method newUser (line 435) | func (action *Action) newUser(orgID, username, pwd string) (mspapi.Sig...
method OrgUser (line 461) | func (action *Action) OrgUser(orgID, username string) (mspapi.SigningI...
method OrgAdminUser (line 481) | func (action *Action) OrgAdminUser(orgID string) (mspapi.SigningIdenti...
method PeerFromURL (line 490) | func (action *Action) PeerFromURL(url string) (fab.Peer, bool) {
method Orderers (line 500) | func (action *Action) Orderers() ([]fab.Orderer, error) {
method RandomOrderer (line 519) | func (action *Action) RandomOrderer() (fab.Orderer, error) {
method getPeers (line 565) | func (action *Action) getPeers(allPeers []fab.Peer, peerURLs []string,...
method PeerConfig (line 588) | func (action *Action) PeerConfig() (*fab.PeerConfig, error) {
method CreateDiscoveryService (line 607) | func (action *Action) CreateDiscoveryService(channelID string) (fab.Di...
method GetPeers (line 613) | func (action *Action) GetPeers() ([]fab.Peer, error) {
function ArgsArray (line 531) | func ArgsArray() ([]ArgStruct, error) {
function levelFromName (line 548) | func levelFromName(levelName string) logging.Level {
function containsString (line 617) | func containsString(sarr []string, s string) bool {
type cryptoSuiteProviderFactory (line 627) | type cryptoSuiteProviderFactory struct
method CreateCryptoSuiteProvider (line 632) | func (f *cryptoSuiteProviderFactory) CreateCryptoSuiteProvider(config ...
FILE: fabric-cli/cmd/fabric-cli/action/svcproviderfactory.go
type serviceProviderFactory (line 23) | type serviceProviderFactory struct
method CreateChannelProvider (line 43) | func (f *serviceProviderFactory) CreateChannelProvider(config fab.Endp...
function newServiceProviderFactory (line 27) | func newServiceProviderFactory() (*serviceProviderFactory, error) {
type fabricSelectionChannelProvider (line 31) | type fabricSelectionChannelProvider struct
method Close (line 58) | func (cp *fabricSelectionChannelProvider) Close() {
method Initialize (line 73) | func (cp *fabricSelectionChannelProvider) Initialize(providers context...
method ChannelService (line 81) | func (cp *fabricSelectionChannelProvider) ChannelService(ctx fab.Clien...
type fabricSelectionChannelService (line 37) | type fabricSelectionChannelService struct
method Selection (line 118) | func (cs *fabricSelectionChannelService) Selection() (fab.SelectionSer...
type closable (line 53) | type closable interface
type providerInit (line 69) | type providerInit interface
FILE: fabric-cli/cmd/fabric-cli/chaincode/chaincodecmd.go
function Cmd (line 24) | func Cmd() *cobra.Command {
FILE: fabric-cli/cmd/fabric-cli/chaincode/getinfocmd.go
constant lifecycleSCC (line 25) | lifecycleSCC = "lscc"
constant getCCDataFunc (line 27) | getCCDataFunc = "getccdata"
constant getCollConfigFunc (line 28) | getCollConfigFunc = "getcollectionsconfig"
function getGetInfoCmd (line 56) | func getGetInfoCmd() *cobra.Command {
type getInfoAction (line 64) | type getInfoAction struct
method invoke (line 77) | func (action *getInfoAction) invoke() error {
method getCCData (line 100) | func (action *getInfoAction) getCCData(channelClient *channel.Client) ...
method getCollConfig (line 123) | func (action *getInfoAction) getCollConfig(channelClient *channel.Clie...
function newGetInfoAction (line 68) | func newGetInfoAction(flags *pflag.FlagSet) (*getInfoAction, error) {
FILE: fabric-cli/cmd/fabric-cli/chaincode/installcmd.go
function getInstallCmd (line 53) | func getInstallCmd() *cobra.Command {
type installAction (line 64) | type installAction struct
method invoke (line 74) | func (action *installAction) invoke() error {
method installChaincode (line 90) | func (action *installAction) installChaincode(orgID string, targets []...
function newInstallAction (line 68) | func newInstallAction(flags *pflag.FlagSet) (*installAction, error) {
FILE: fabric-cli/cmd/fabric-cli/chaincode/instantiatecmd.go
function getInstantiateCmd (line 57) | func getInstantiateCmd() *cobra.Command {
type instantiateAction (line 71) | type instantiateAction struct
method invoke (line 84) | func (a *instantiateAction) invoke() error {
method newChaincodePolicy (line 141) | func (a *instantiateAction) newChaincodePolicy() (*common.SignaturePol...
function newInstantiateAction (line 75) | func newInstantiateAction(flags *pflag.FlagSet) (*instantiateAction, err...
function newChaincodePolicy (line 151) | func newChaincodePolicy(policyString string) (*common.SignaturePolicyEnv...
type collectionConfigJSON (line 159) | type collectionConfigJSON struct
function getCollectionConfigFromFile (line 166) | func getCollectionConfigFromFile(ccFile string) ([]*pb.CollectionConfig,...
function getCollectionConfig (line 178) | func getCollectionConfig(cconf []collectionConfigJSON) ([]*pb.Collection...
FILE: fabric-cli/cmd/fabric-cli/chaincode/invokecmd.go
function getInvokeCmd (line 54) | func getInvokeCmd() *cobra.Command {
type invokeAction (line 74) | type invokeAction struct
method invoke (line 86) | func (a *invokeAction) invoke() error {
function newInvokeAction (line 80) | func newInvokeAction(flags *pflag.FlagSet) (*invokeAction, error) {
function average (line 238) | func average(durations []time.Duration) float64 {
function min (line 250) | func min(durations []time.Duration) float64 {
function max (line 255) | func max(durations []time.Duration) float64 {
function minMax (line 260) | func minMax(durations []time.Duration) (min float64, max float64) {
FILE: fabric-cli/cmd/fabric-cli/chaincode/invokeerror/invokeerror.go
type ErrorCode (line 11) | type ErrorCode
constant PersistentError (line 16) | PersistentError ErrorCode = iota
constant TransientError (line 20) | TransientError
constant TimeoutOnCommit (line 24) | TimeoutOnCommit
type Error (line 29) | type Error interface
type invokeError (line 36) | type invokeError struct
method ErrorCode (line 74) | func (e *invokeError) ErrorCode() ErrorCode {
function New (line 42) | func New(code ErrorCode, msg string) Error {
function Wrap (line 50) | func Wrap(code ErrorCode, cause error, msg string) Error {
function Wrapf (line 58) | func Wrapf(code ErrorCode, cause error, fmt string, args ...interface{})...
function Errorf (line 66) | func Errorf(code ErrorCode, fmt string, args ...interface{}) Error {
FILE: fabric-cli/cmd/fabric-cli/chaincode/invoketask/invoketask.go
type Task (line 24) | type Task struct
method Attempts (line 67) | func (t *Task) Attempts() int {
method LastError (line 72) | func (t *Task) LastError() error {
method Invoke (line 77) | func (t *Task) Invoke() {
method doInvoke (line 88) | func (t *Task) doInvoke() error {
function New (line 44) | func New(ctxt utils.Context, id string, channelClient *channel.Client, t...
FILE: fabric-cli/cmd/fabric-cli/chaincode/multitask/multitask.go
type MultiTask (line 12) | type MultiTask struct
method Add (line 25) | func (m *MultiTask) Add(task task.Task) {
method Invoke (line 30) | func (m *MultiTask) Invoke() {
method Attempts (line 40) | func (m *MultiTask) Attempts() int {
method LastError (line 49) | func (m *MultiTask) LastError() error {
function New (line 18) | func New(completedCB func()) *MultiTask {
FILE: fabric-cli/cmd/fabric-cli/chaincode/querycmd.go
function getQueryCmd (line 54) | func getQueryCmd() *cobra.Command {
type queryAction (line 71) | type queryAction struct
method query (line 83) | func (a *queryAction) query() error {
function newQueryAction (line 77) | func newQueryAction(flags *pflag.FlagSet) (*queryAction, error) {
FILE: fabric-cli/cmd/fabric-cli/chaincode/querytask/querytask.go
type Task (line 21) | type Task struct
method Invoke (line 59) | func (t *Task) Invoke() {
method Attempts (line 109) | func (t *Task) Attempts() int {
method LastError (line 114) | func (t *Task) LastError() error {
function New (line 39) | func New(ctxt utils.Context, id string, channelClient *channel.Client, t...
FILE: fabric-cli/cmd/fabric-cli/chaincode/task/task.go
type Task (line 10) | type Task interface
FILE: fabric-cli/cmd/fabric-cli/chaincode/upgradecmd.go
function getUpgradeCmd (line 56) | func getUpgradeCmd() *cobra.Command {
type upgradeAction (line 70) | type upgradeAction struct
method invoke (line 83) | func (a *upgradeAction) invoke() error {
method newChaincodePolicy (line 139) | func (a *upgradeAction) newChaincodePolicy() (*fabricCommon.SignatureP...
function newUpgradeAction (line 74) | func newUpgradeAction(flags *pflag.FlagSet) (*upgradeAction, error) {
FILE: fabric-cli/cmd/fabric-cli/chaincode/utils/util.go
constant randFunc (line 25) | randFunc = "$rand("
constant padFunc (line 26) | padFunc = "$pad("
constant seqFunc (line 27) | seqFunc = "$seq("
constant setFunc (line 28) | setFunc = "$set("
constant fileFunc (line 29) | fileFunc = "$file("
constant varExp (line 30) | varExp = "${"
type Context (line 37) | type Context interface
function AsBytes (line 53) | func AsBytes(ctxt Context, args []string) [][]byte {
function getArg (line 70) | func getArg(ctxt Context, r *rand.Rand, arg string) string {
function evaluateSeqExpression (line 82) | func evaluateSeqExpression(arg string) string {
function evaluateRandExpression (line 91) | func evaluateRandExpression(r *rand.Rand, arg string) string {
function evaluatePadExpression (line 103) | func evaluatePadExpression(arg string) string {
function evaluateFileExpression (line 126) | func evaluateFileExpression(arg string) string {
function evaluateSetExpression (line 136) | func evaluateSetExpression(ctxt Context, arg string) string {
function evaluateVarExpression (line 154) | func evaluateVarExpression(ctxt Context, arg string) string {
function evaluateExpression (line 165) | func evaluateExpression(expression, funcType, endDelim string, evaluate ...
function NewContext (line 197) | func NewContext() Context {
type defaultContext (line 203) | type defaultContext struct
method SetVar (line 207) | func (c *defaultContext) SetVar(k, v string) {
method GetVar (line 211) | func (c *defaultContext) GetVar(k string) (string, bool) {
function readFile (line 216) | func readFile(filePath string) (string, error) {
FILE: fabric-cli/cmd/fabric-cli/chaincode/utils/util_test.go
function TestEvaluatePadExpression (line 17) | func TestEvaluatePadExpression(t *testing.T) {
function TestFailEvaluatePadExpression (line 25) | func TestFailEvaluatePadExpression(t *testing.T) {
function TestEvaluateRandExpression (line 39) | func TestEvaluateRandExpression(t *testing.T) {
function TestFailEvaluateRandExpression (line 50) | func TestFailEvaluateRandExpression(t *testing.T) {
function TestEvaluateSeqExpression (line 65) | func TestEvaluateSeqExpression(t *testing.T) {
function TestFailEvaluateSeqExpression (line 71) | func TestFailEvaluateSeqExpression(t *testing.T) {
function TestEvaluateFileExpression (line 75) | func TestEvaluateFileExpression(t *testing.T) {
function TestFailEvaluateFileExpression (line 79) | func TestFailEvaluateFileExpression(t *testing.T) {
function TestEvaluateSetExpression (line 83) | func TestEvaluateSetExpression(t *testing.T) {
function TestFailEvaluateSetExpression (line 89) | func TestFailEvaluateSetExpression(t *testing.T) {
function TestGetArg (line 98) | func TestGetArg(t *testing.T) {
FILE: fabric-cli/cmd/fabric-cli/channel/channelcmd.go
function Cmd (line 24) | func Cmd() *cobra.Command {
FILE: fabric-cli/cmd/fabric-cli/channel/channelcreatecmd.go
function getChannelCreateCmd (line 41) | func getChannelCreateCmd() *cobra.Command {
type channelCreateAction (line 49) | type channelCreateAction struct
method invoke (line 59) | func (a *channelCreateAction) invoke() error {
function newChannelCreateAction (line 53) | func newChannelCreateAction(flags *pflag.FlagSet) (*channelCreateAction,...
FILE: fabric-cli/cmd/fabric-cli/channel/channeljoincmd.go
function getChannelJoinCmd (line 41) | func getChannelJoinCmd() *cobra.Command {
type channelJoinAction (line 49) | type channelJoinAction struct
method invoke (line 65) | func (a *channelJoinAction) invoke() error {
method joinChannel (line 82) | func (a *channelJoinAction) joinChannel(orgID string, peers []fab.Peer...
function newChannelJoinAction (line 53) | func newChannelJoinAction(flags *pflag.FlagSet) (*channelJoinAction, err...
FILE: fabric-cli/cmd/fabric-cli/cmd/fabric-cli.go
function newFabricCLICmd (line 20) | func newFabricCLICmd() *cobra.Command {
function Execute (line 51) | func Execute() {
FILE: fabric-cli/cmd/fabric-cli/config/config.go
constant loggerName (line 29) | loggerName = "fabriccli"
constant userStatePath (line 30) | userStatePath = "/tmp/enroll_user"
constant AutoDetectSelectionProvider (line 33) | AutoDetectSelectionProvider = "auto"
constant StaticSelectionProvider (line 36) | StaticSelectionProvider = "static"
constant DynamicSelectionProvider (line 39) | DynamicSelectionProvider = "dynamic"
constant FabricSelectionProvider (line 42) | FabricSelectionProvider = "fabric"
constant UserFlag (line 47) | UserFlag = "user"
constant userDescription (line 48) | userDescription = "The user"
constant defaultUser (line 49) | defaultUser = ""
constant PasswordFlag (line 51) | PasswordFlag = "pw"
constant passwordDescription (line 52) | passwordDescription = "The password of the user"
constant defaultPassword (line 53) | defaultPassword = ""
constant ChaincodeVersionFlag (line 55) | ChaincodeVersionFlag = "v"
constant chaincodeVersionDescription (line 56) | chaincodeVersionDescription = "The chaincode version"
constant defaultChaincodeVersion (line 57) | defaultChaincodeVersion = "v0"
constant LoggingLevelFlag (line 59) | LoggingLevelFlag = "logging-level"
constant loggingLevelDescription (line 60) | loggingLevelDescription = "Logging level - ERROR, WARN, INFO, DEBUG"
constant defaultLoggingLevel (line 61) | defaultLoggingLevel = "ERROR"
constant OrgIDsFlag (line 63) | OrgIDsFlag = "orgid"
constant orgIDsDescription (line 64) | orgIDsDescription = "A comma-separated list of organization IDs"
constant defaultOrgIDs (line 65) | defaultOrgIDs = ""
constant ChannelIDFlag (line 67) | ChannelIDFlag = "cid"
constant channelIDDescription (line 68) | channelIDDescription = "The channel ID"
constant defaultChannelID (line 69) | defaultChannelID = ""
constant ChaincodeIDFlag (line 71) | ChaincodeIDFlag = "ccid"
constant chaincodeIDDescription (line 72) | chaincodeIDDescription = "The Chaincode ID"
constant defaultChaincodeID (line 73) | defaultChaincodeID = ""
constant ChaincodePathFlag (line 75) | ChaincodePathFlag = "ccp"
constant chaincodePathDescription (line 76) | chaincodePathDescription = "The chaincode path"
constant defaultChaincodePath (line 77) | defaultChaincodePath = ""
constant ConfigFileFlag (line 79) | ConfigFileFlag = "config"
constant configFileDescription (line 80) | configFileDescription = "The path of the config.yaml file"
constant defaultConfigFile (line 81) | defaultConfigFile = ""
constant PeerURLFlag (line 83) | PeerURLFlag = "peer"
constant peerURLDescription (line 84) | peerURLDescription = "A comma-separated list of peer targets, e.g. 'grpc...
constant defaultPeerURL (line 85) | defaultPeerURL = ""
constant OrdererFlag (line 87) | OrdererFlag = "orderer"
constant ordererURLDescription (line 88) | ordererURLDescription = "The URL of the orderer, e.g. grpcs://localhost:...
constant defaultOrdererURL (line 89) | defaultOrdererURL = ""
constant PrintFormatFlag (line 91) | PrintFormatFlag = "format"
constant printFormatDescription (line 92) | printFormatDescription = "The output format - display, json, raw"
constant WriterFlag (line 94) | WriterFlag = "writer"
constant writerDescription (line 95) | writerDescription = "The writer - stdout, stderr, log"
constant Base64Flag (line 97) | Base64Flag = "base64"
constant base64Description (line 98) | base64Description = "If true then binary values are encoded in base64 (o...
constant CertificateFileFlag (line 100) | CertificateFileFlag = "cacert"
constant certificateDescription (line 101) | certificateDescription = "The path of the ca-cert.pem file"
constant defaultCertificate (line 102) | defaultCertificate = ""
constant ArgsFlag (line 104) | ArgsFlag = "args"
constant argsDescription (line 105) | argsDescription = `The args in JSON format. Example: {"Func":"function",...
constant IterationsFlag (line 107) | IterationsFlag = "iterations"
constant iterationsDescription (line 108) | iterationsDescription = "The number of times to invoke the chaincode"
constant defaultIterations (line 109) | defaultIterations = "1"
constant SleepFlag (line 111) | SleepFlag = "sleep"
constant sleepTimeDescription (line 112) | sleepTimeDescription = "The number of milliseconds to sleep between invo...
constant defaultSleepTime (line 113) | defaultSleepTime = "0"
constant TxFileFlag (line 115) | TxFileFlag = "txfile"
constant txFileDescription (line 116) | txFileDescription = "The path of the channel.tx file"
constant defaultTxFile (line 117) | defaultTxFile = ""
constant ChaincodeEventFlag (line 119) | ChaincodeEventFlag = "event"
constant chaincodeEventDescription (line 120) | chaincodeEventDescription = "The name of the chaincode event to listen for"
constant defaultChaincodeEvent (line 121) | defaultChaincodeEvent = ""
constant SeekTypeFlag (line 123) | SeekTypeFlag = "seek"
constant seekTypeDescription (line 124) | seekTypeDescription = "The seek type. Possible values: oldest - delivers...
constant defaultSeekType (line 125) | defaultSeekType = string(seek.Newest)
constant TxIDFlag (line 127) | TxIDFlag = "txid"
constant txIDDescription (line 128) | txIDDescription = "The transaction ID"
constant defaultTxID (line 129) | defaultTxID = ""
constant BlockNumFlag (line 131) | BlockNumFlag = "num"
constant blockNumDescription (line 132) | blockNumDescription = "The block number"
constant defaultBlockNum (line 133) | defaultBlockNum = "0"
constant BlockHashFlag (line 135) | BlockHashFlag = "hash"
constant blockHashDescription (line 136) | blockHashDescription = "The block hash"
constant defaultBlockHash (line 137) | defaultBlockHash = ""
constant TraverseFlag (line 139) | TraverseFlag = "traverse"
constant traverseDescription (line 140) | traverseDescription = "Blocks will be traversed starting with the given ...
constant defaultTraverse (line 141) | defaultTraverse = "0"
constant ChaincodePolicyFlag (line 143) | ChaincodePolicyFlag = "policy"
constant chaincodePolicyDescription (line 144) | chaincodePolicyDescription = "The chaincode policy, e.g. OutOf(1,'Org1MS...
constant defaultChaincodePolicy (line 145) | defaultChaincodePolicy = ""
constant CollectionConfigFileFlag (line 147) | CollectionConfigFileFlag = "collconfig"
constant collectionConfigFileDescription (line 148) | collectionConfigFileDescription = "The path of the JSON file that contai...
constant defaultCollectionConfigFile (line 149) | defaultCollectionConfigFile = ""
constant TimeoutFlag (line 151) | TimeoutFlag = "timeout"
constant timeoutDescription (line 152) | timeoutDescription = "The timeout (in milliseconds) for the operation"
constant defaultTimeout (line 153) | defaultTimeout = "5000"
constant PrintPayloadOnlyFlag (line 155) | PrintPayloadOnlyFlag = "payload"
constant printPayloadOnlyDescription (line 156) | printPayloadOnlyDescription = "If specified then only the payload from t...
constant defaultPrintPayloadOnly (line 157) | defaultPrintPayloadOnly = "false"
constant ValidateFlag (line 159) | ValidateFlag = "validate"
constant validateDescription (line 160) | validateDescription = "If specified then endorsement responses from quer...
constant defaultValidate (line 161) | defaultValidate = "false"
constant ConcurrencyFlag (line 163) | ConcurrencyFlag = "concurrency"
constant concurrencyDescription (line 164) | concurrencyDescription = "Specifies the number of concurrent requests se...
constant defaultConcurrency (line 165) | defaultConcurrency = "1"
constant MaxAttemptsFlag (line 167) | MaxAttemptsFlag = "attempts"
constant maxAttemptsDescription (line 168) | maxAttemptsDescription = "Specifies the maximum number of attempts to be...
constant defaultMaxAttempts (line 169) | defaultMaxAttempts = "3"
constant InitialBackoffFlag (line 171) | InitialBackoffFlag = "backoff"
constant initialBackoffDescription (line 172) | initialBackoffDescription = "The initial backoff is the time (in millise...
constant defaultInitialBackoff (line 173) | defaultInitialBackoff = "1000"
constant MaxBackoffFlag (line 175) | MaxBackoffFlag = "maxbackoff"
constant maxBackoffDescription (line 176) | maxBackoffDescription = "The maximum backoff time (in milliseconds)"
constant defaultMaxBackoff (line 177) | defaultMaxBackoff = "5000"
constant BackoffFactorFlag (line 179) | BackoffFactorFlag = "backofffactor"
constant backoffFactorDescription (line 180) | backoffFactorDescription = "The factor by which the backoff time is mult...
constant defaultBackoffFactor (line 181) | defaultBackoffFactor = "2"
constant VerboseFlag (line 183) | VerboseFlag = "verbose"
constant verboseDescription (line 184) | verboseDescription = "If specified then the transaction proposal respons...
constant defaultVerbosity (line 185) | defaultVerbosity = "false"
constant SelectionProviderFlag (line 187) | SelectionProviderFlag = "selectprovider"
constant selectionProviderDescription (line 188) | selectionProviderDescription = "The peer selection provider for invoke/q...
constant defaultSelectionProvider (line 189) | defaultSelectionProvider = AutoDetectSelectionProvider
constant GoPathFlag (line 191) | GoPathFlag = "gopath"
constant goPathDescription (line 192) | goPathDescription = "GOPATH for chaincode install command. If not set, G...
constant defaultGoPath (line 193) | defaultGoPath = ""
type options (line 199) | type options struct
function init (line 240) | func init() {
type CLIConfig (line 255) | type CLIConfig struct
method Logger (line 296) | func (c *CLIConfig) Logger() *logging.Logger {
method LoggingLevel (line 301) | func (c *CLIConfig) LoggingLevel() string {
method OrgID (line 318) | func (c *CLIConfig) OrgID() string {
method OrgIDs (line 326) | func (c *CLIConfig) OrgIDs() []string {
method ChannelID (line 344) | func (c *CLIConfig) ChannelID() string {
method UserName (line 355) | func (c *CLIConfig) UserName() string {
method UserPassword (line 366) | func (c *CLIConfig) UserPassword() string {
method ChaincodeID (line 377) | func (c *CLIConfig) ChaincodeID() string {
method ChaincodeEvent (line 388) | func (c *CLIConfig) ChaincodeEvent() string {
method SeekType (line 402) | func (c *CLIConfig) SeekType() seek.Type {
method ChaincodePath (line 413) | func (c *CLIConfig) ChaincodePath() string {
method ChaincodeVersion (line 424) | func (c *CLIConfig) ChaincodeVersion() string {
method PeerURL (line 435) | func (c *CLIConfig) PeerURL() string {
method PeerURLs (line 440) | func (c *CLIConfig) PeerURLs() []string {
method OrdererURL (line 458) | func (c *CLIConfig) OrdererURL() string {
method Iterations (line 469) | func (c *CLIConfig) Iterations() int {
method SleepTime (line 485) | func (c *CLIConfig) SleepTime() int64 {
method BlockNum (line 501) | func (c *CLIConfig) BlockNum() uint64 {
method BlockHash (line 517) | func (c *CLIConfig) BlockHash() string {
method Traverse (line 528) | func (c *CLIConfig) Traverse() int {
method PrintFormat (line 544) | func (c *CLIConfig) PrintFormat() string {
method Writer (line 555) | func (c *CLIConfig) Writer() string {
method Base64 (line 566) | func (c *CLIConfig) Base64() bool {
method OrdererTLSCertificate (line 577) | func (c *CLIConfig) OrdererTLSCertificate() string {
method Args (line 588) | func (c *CLIConfig) Args() string {
method TxFile (line 599) | func (c *CLIConfig) TxFile() string {
method TxID (line 610) | func (c *CLIConfig) TxID() string {
method ChaincodePolicy (line 621) | func (c *CLIConfig) ChaincodePolicy() string {
method CollectionConfigFile (line 632) | func (c *CLIConfig) CollectionConfigFile() string {
method Timeout (line 643) | func (c *CLIConfig) Timeout(timeoutType fab.TimeoutType) time.Duration {
method PrintPayloadOnly (line 661) | func (c *CLIConfig) PrintPayloadOnly() bool {
method Validate (line 672) | func (c *CLIConfig) Validate() bool {
method Concurrency (line 683) | func (c *CLIConfig) Concurrency() uint16 {
method MaxAttempts (line 701) | func (c *CLIConfig) MaxAttempts() int {
method InitialBackoff (line 718) | func (c *CLIConfig) InitialBackoff() time.Duration {
method MaxBackoff (line 734) | func (c *CLIConfig) MaxBackoff() time.Duration {
method BackoffFactor (line 751) | func (c *CLIConfig) BackoffFactor() float64 {
method Verbose (line 768) | func (c *CLIConfig) Verbose() bool {
method SelectionProvider (line 779) | func (c *CLIConfig) SelectionProvider() string {
method GoPath (line 796) | func (c *CLIConfig) GoPath() string {
method IsLoggingEnabledFor (line 805) | func (c *CLIConfig) IsLoggingEnabledFor(level logging.Level) bool {
function InitConfig (line 262) | func InitConfig(flags *pflag.FlagSet) error {
function IsFlagSet (line 280) | func IsFlagSet(name string) bool {
function Provider (line 286) | func Provider() core.ConfigProvider {
function Config (line 291) | func Config() *CLIConfig {
function InitLoggingLevel (line 306) | func InitLoggingLevel(flags *pflag.FlagSet, defaultValueAndDescription ....
function InitConfigFile (line 312) | func InitConfigFile(flags *pflag.FlagSet, defaultValueAndDescription ......
function InitOrgIDs (line 338) | func InitOrgIDs(flags *pflag.FlagSet, defaultValueAndDescription ...stri...
function InitChannelID (line 349) | func InitChannelID(flags *pflag.FlagSet, defaultValueAndDescription ...s...
function InitUserName (line 360) | func InitUserName(flags *pflag.FlagSet, defaultValueAndDescription ...st...
function InitUserPassword (line 371) | func InitUserPassword(flags *pflag.FlagSet, defaultValueAndDescription ....
function InitChaincodeID (line 382) | func InitChaincodeID(flags *pflag.FlagSet, defaultValueAndDescription .....
function InitChaincodeEvent (line 393) | func InitChaincodeEvent(flags *pflag.FlagSet, defaultValueAndDescription...
function InitSeekType (line 407) | func InitSeekType(flags *pflag.FlagSet, defaultValueAndDescription ...st...
function InitChaincodePath (line 418) | func InitChaincodePath(flags *pflag.FlagSet, defaultValueAndDescription ...
function InitChaincodeVersion (line 429) | func InitChaincodeVersion(flags *pflag.FlagSet, defaultValueAndDescripti...
function InitPeerURL (line 452) | func InitPeerURL(flags *pflag.FlagSet, defaultValueAndDescription ...str...
function InitOrdererURL (line 463) | func InitOrdererURL(flags *pflag.FlagSet, defaultValueAndDescription ......
function InitIterations (line 474) | func InitIterations(flags *pflag.FlagSet, defaultValueAndDescription ......
function InitSleepTime (line 490) | func InitSleepTime(flags *pflag.FlagSet, defaultValueAndDescription ...s...
function InitBlockNum (line 506) | func InitBlockNum(flags *pflag.FlagSet, defaultValueAndDescription ...st...
function InitBlockHash (line 522) | func InitBlockHash(flags *pflag.FlagSet, defaultValueAndDescription ...s...
function InitTraverse (line 533) | func InitTraverse(flags *pflag.FlagSet, defaultValueAndDescription ...st...
function InitPrintFormat (line 549) | func InitPrintFormat(flags *pflag.FlagSet, defaultValueAndDescription .....
function InitWriter (line 560) | func InitWriter(flags *pflag.FlagSet, defaultValueAndDescription ...stri...
function InitBase64 (line 571) | func InitBase64(flags *pflag.FlagSet, defaultValueAndDescription ...stri...
function InitOrdererTLSCertificate (line 582) | func InitOrdererTLSCertificate(flags *pflag.FlagSet, defaultValueAndDesc...
function InitArgs (line 593) | func InitArgs(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
function InitTxFile (line 604) | func InitTxFile(flags *pflag.FlagSet, defaultValueAndDescription ...stri...
function InitTxID (line 615) | func InitTxID(flags *pflag.FlagSet, defaultValueAndDescription ...string) {
function InitChaincodePolicy (line 626) | func InitChaincodePolicy(flags *pflag.FlagSet, defaultValueAndDescriptio...
function InitCollectionConfigFile (line 637) | func InitCollectionConfigFile(flags *pflag.FlagSet, defaultValueAndDescr...
function InitTimeout (line 649) | func InitTimeout(flags *pflag.FlagSet, defaultValueAndDescription ...str...
function InitPrintPayloadOnly (line 666) | func InitPrintPayloadOnly(flags *pflag.FlagSet, defaultValueAndDescripti...
function InitValidate (line 677) | func InitValidate(flags *pflag.FlagSet, defaultValueAndDescription ...st...
function InitConcurrency (line 688) | func InitConcurrency(flags *pflag.FlagSet, defaultValueAndDescription .....
function InitMaxAttempts (line 706) | func InitMaxAttempts(flags *pflag.FlagSet, defaultValueAndDescription .....
function InitInitialBackoff (line 723) | func InitInitialBackoff(flags *pflag.FlagSet, defaultValueAndDescription...
function InitMaxBackoff (line 739) | func InitMaxBackoff(flags *pflag.FlagSet, defaultValueAndDescription ......
function InitBackoffFactor (line 756) | func InitBackoffFactor(flags *pflag.FlagSet, defaultValueAndDescription ...
function InitVerbosity (line 773) | func InitVerbosity(flags *pflag.FlagSet, defaultValueAndDescription ...s...
function InitSelectionProvider (line 784) | func InitSelectionProvider(flags *pflag.FlagSet, defaultValueAndDescript...
function InitGoPath (line 790) | func InitGoPath(flags *pflag.FlagSet, defaultValueAndDescription ...stri...
function getEmptyArgs (line 811) | func getEmptyArgs() string {
function getDefaultValueAndDescription (line 815) | func getDefaultValueAndDescription(defaultValue string, defaultDescripti...
FILE: fabric-cli/cmd/fabric-cli/event/eventcmd.go
function Cmd (line 23) | func Cmd() *cobra.Command {
FILE: fabric-cli/cmd/fabric-cli/event/inputevent.go
type inputEvent (line 14) | type inputEvent struct
method WaitForEnter (line 19) | func (c *inputEvent) WaitForEnter() chan bool {
method readFromCLI (line 24) | func (c *inputEvent) readFromCLI() {
FILE: fabric-cli/cmd/fabric-cli/event/listenblockcmd.go
function getListenBlockCmd (line 40) | func getListenBlockCmd() *cobra.Command {
type listenBlockAction (line 49) | type listenBlockAction struct
method invoke (line 60) | func (a *listenBlockAction) invoke() error {
function newlistenBlockAction (line 54) | func newlistenBlockAction(flags *pflag.FlagSet) (*listenBlockAction, err...
FILE: fabric-cli/cmd/fabric-cli/event/listencccmd.go
function getListenCCCmd (line 50) | func getListenCCCmd() *cobra.Command {
type listenccAction (line 59) | type listenccAction struct
method invoke (line 70) | func (a *listenccAction) invoke() error {
function newListenCCAction (line 64) | func newListenCCAction(flags *pflag.FlagSet) (*listenccAction, error) {
FILE: fabric-cli/cmd/fabric-cli/event/listenfilteredblockcmd.go
function getListenFilteredBlockCmd (line 40) | func getListenFilteredBlockCmd() *cobra.Command {
type listenFilteredBlockAction (line 49) | type listenFilteredBlockAction struct
method invoke (line 60) | func (a *listenFilteredBlockAction) invoke() error {
function newlistenFilteredBlockAction (line 54) | func newlistenFilteredBlockAction(flags *pflag.FlagSet) (*listenFiltered...
FILE: fabric-cli/cmd/fabric-cli/event/listentxcmd.go
function getListenTXCmd (line 44) | func getListenTXCmd() *cobra.Command {
type listentxAction (line 52) | type listentxAction struct
method invoke (line 63) | func (a *listentxAction) invoke() error {
function newListenTXAction (line 57) | func newListenTXAction(flags *pflag.FlagSet) (*listentxAction, error) {
FILE: fabric-cli/cmd/fabric-cli/executor/executor.go
type State (line 20) | type State
constant NEW (line 24) | NEW State = iota
constant STARTED (line 27) | STARTED
constant TERMINATED (line 30) | TERMINATED
type Executor (line 37) | type Executor struct
method Start (line 84) | func (e *Executor) Start() bool {
method Submit (line 101) | func (e *Executor) Submit(task worker.Task) error {
method SubmitDelayed (line 116) | func (e *Executor) SubmitDelayed(task worker.Task, delay time.Duration...
method Wait (line 135) | func (e *Executor) Wait() {
method Stop (line 142) | func (e *Executor) Stop(wait bool) bool {
method dispatch (line 169) | func (e *Executor) dispatch() {
function NewConcurrent (line 51) | func NewConcurrent(name string, concurrency uint16) *Executor {
function NewBoundedConcurrent (line 63) | func NewBoundedConcurrent(name string, concurrency uint16, queueLength u...
function New (line 73) | func New(name string, queueLength uint16, pool *worker.Pool) *Executor {
FILE: fabric-cli/cmd/fabric-cli/executor/worker/worker.go
type State (line 14) | type State
constant READY (line 18) | READY State = iota
constant STOPPED (line 21) | STOPPED
type Task (line 25) | type Task interface
type Events (line 30) | type Events interface
type Worker (line 42) | type Worker struct
method Name (line 59) | func (w *Worker) Name() string {
method Submit (line 64) | func (w *Worker) Submit(task Task) {
method invoke (line 68) | func (w *Worker) invoke(task Task) {
method Start (line 78) | func (w *Worker) Start() {
method Stop (line 101) | func (w *Worker) Stop() {
function newWorker (line 49) | func newWorker(name string, events Events) *Worker {
FILE: fabric-cli/cmd/fabric-cli/executor/worker/workerpool.go
type Pool (line 17) | type Pool struct
method Name (line 42) | func (p *Pool) Name() string {
method Start (line 47) | func (p *Pool) Start() {
method Stop (line 57) | func (p *Pool) Stop(wait bool) {
method Submit (line 80) | func (p *Pool) Submit(task Task) {
method StateChange (line 97) | func (p *Pool) StateChange(w *Worker, state State) {
method TaskStarted (line 115) | func (p *Pool) TaskStarted(w *Worker, task Task) {
method TaskCompleted (line 120) | func (p *Pool) TaskCompleted(w *Worker, task Task) {
function NewPool (line 26) | func NewPool(name string, concurrency uint16) *Pool {
FILE: fabric-cli/cmd/fabric-cli/fabric-cli.go
function main (line 13) | func main() {
FILE: fabric-cli/cmd/fabric-cli/printer/blockprinter.go
constant AnchorPeersKey (line 31) | AnchorPeersKey = "AnchorPeers"
constant ReadersPolicyKey (line 34) | ReadersPolicyKey = "Readers"
constant WritersPolicyKey (line 37) | WritersPolicyKey = "Writers"
constant AdminsPolicyKey (line 40) | AdminsPolicyKey = "Admins"
constant MSPKey (line 43) | MSPKey = "MSP"
constant ConsensusTypeKey (line 46) | ConsensusTypeKey = "ConsensusType"
constant BatchSizeKey (line 49) | BatchSizeKey = "BatchSize"
constant BatchTimeoutKey (line 52) | BatchTimeoutKey = "BatchTimeout"
constant ChannelRestrictionsKey (line 55) | ChannelRestrictionsKey = "ChannelRestrictions"
constant KafkaBrokersKey (line 58) | KafkaBrokersKey = "KafkaBrokers"
constant ChannelCreationPolicyKey (line 61) | ChannelCreationPolicyKey = "ChannelCreationPolicy"
constant ConsortiumKey (line 64) | ConsortiumKey = "Consortium"
constant HashingAlgorithmKey (line 67) | HashingAlgorithmKey = "HashingAlgorithm"
constant BlockDataHashingStructureKey (line 70) | BlockDataHashingStructureKey = "BlockDataHashingStructure"
constant OrdererAddressesKey (line 73) | OrdererAddressesKey = "OrdererAddresses"
constant ChannelGroupKey (line 76) | ChannelGroupKey = "Channel"
constant CapabilitiesKey (line 79) | CapabilitiesKey = "Capabilities"
constant collectionSeparator (line 81) | collectionSeparator = "~"
type Printer (line 85) | type Printer interface
type BlockPrinter (line 124) | type BlockPrinter struct
method PrintBlockchainInfo (line 143) | func (p *BlockPrinter) PrintBlockchainInfo(info *fabriccmn.BlockchainI...
method PrintBlock (line 157) | func (p *BlockPrinter) PrintBlock(block *fabriccmn.Block) {
method PrintFilteredBlock (line 187) | func (p *BlockPrinter) PrintFilteredBlock(block *pb.FilteredBlock) {
method PrintChannels (line 208) | func (p *BlockPrinter) PrintChannels(channels []*pb.ChannelInfo) {
method PrintPeers (line 223) | func (p *BlockPrinter) PrintPeers(peers []fab.Peer) {
method PrintChaincodes (line 241) | func (p *BlockPrinter) PrintChaincodes(chaincodes []*pb.ChaincodeInfo) {
method PrintProcessedTransaction (line 259) | func (p *BlockPrinter) PrintProcessedTransaction(tx *pb.ProcessedTrans...
method PrintChaincodeData (line 272) | func (p *BlockPrinter) PrintChaincodeData(ccData *ccprovider.Chaincode...
method doPrintChaincodeData (line 286) | func (p *BlockPrinter) doPrintChaincodeData(ccData *ccprovider.Chainco...
method doPrintCollConfig (line 312) | func (p *BlockPrinter) doPrintCollConfig(collConfig *pb.CollectionConf...
method printStaticCollectionConfig (line 327) | func (p *BlockPrinter) printStaticCollectionConfig(config *pb.StaticCo...
method PrintTxProposalResponses (line 341) | func (p *BlockPrinter) PrintTxProposalResponses(responses []*fab.Trans...
method PrintChaincodeEvent (line 361) | func (p *BlockPrinter) PrintChaincodeEvent(event *fab.CCEvent) {
method PrintTxProposalResponse (line 377) | func (p *BlockPrinter) PrintTxProposalResponse(response *fab.Transacti...
method PrintProposalResponse (line 396) | func (p *BlockPrinter) PrintProposalResponse(response *pb.ProposalResp...
method PrintResponses (line 417) | func (p *BlockPrinter) PrintResponses(responses []*pb.Response) {
method PrintResponse (line 437) | func (p *BlockPrinter) PrintResponse(response *pb.Response) {
method PrintCDSData (line 444) | func (p *BlockPrinter) PrintCDSData(cdsData *ccprovider.CDSData) {
method PrintEnvelope (line 450) | func (p *BlockPrinter) PrintEnvelope(envelope *fabriccmn.Envelope) {
method PrintPayload (line 460) | func (p *BlockPrinter) PrintPayload(payload *fabriccmn.Payload) {
method PrintChannelHeader (line 490) | func (p *BlockPrinter) PrintChannelHeader(chdr *fabriccmn.ChannelHeade...
method PrintChaincodeHeaderExtension (line 507) | func (p *BlockPrinter) PrintChaincodeHeaderExtension(ccHdrExt *pb.Chai...
method PrintChaincodeID (line 514) | func (p *BlockPrinter) PrintChaincodeID(ccID *pb.ChaincodeID) {
method PrintChaincodeInfo (line 524) | func (p *BlockPrinter) PrintChaincodeInfo(ccInfo *pb.ChaincodeInfo) {
method PrintSignatureHeader (line 534) | func (p *BlockPrinter) PrintSignatureHeader(sigHdr *fabriccmn.Signatur...
method PrintData (line 540) | func (p *BlockPrinter) PrintData(headerType fabriccmn.HeaderType, data...
method PrintConfigEnvelope (line 568) | func (p *BlockPrinter) PrintConfigEnvelope(envelope *fabriccmn.ConfigE...
method PrintConfigUpdateEnvelope (line 578) | func (p *BlockPrinter) PrintConfigUpdateEnvelope(envelope *fabriccmn.C...
method PrintTransaction (line 598) | func (p *BlockPrinter) PrintTransaction(tx *pb.Transaction) {
method PrintFilteredTransaction (line 609) | func (p *BlockPrinter) PrintFilteredTransaction(tx *pb.FilteredTransac...
method PrintTXAction (line 626) | func (p *BlockPrinter) PrintTXAction(action *pb.TransactionAction) {
method PrintFilteredCCAction (line 649) | func (p *BlockPrinter) PrintFilteredCCAction(action *pb.FilteredChainc...
method PrintChaincodeActionPayload (line 658) | func (p *BlockPrinter) PrintChaincodeActionPayload(chaPayload *pb.Chai...
method PrintChaincodeProposalPayload (line 676) | func (p *BlockPrinter) PrintChaincodeProposalPayload(cpp *pb.Chaincode...
method PrintChaincodeInvocationSpec (line 697) | func (p *BlockPrinter) PrintChaincodeInvocationSpec(cis *pb.ChaincodeI...
method PrintAction (line 704) | func (p *BlockPrinter) PrintAction(action *pb.ChaincodeEndorsedAction) {
method PrintProposalResponsePayload (line 722) | func (p *BlockPrinter) PrintProposalResponsePayload(prp *pb.ProposalRe...
method PrintChaincodeAction (line 733) | func (p *BlockPrinter) PrintChaincodeAction(chaincodeAction *pb.Chainc...
method PrintTxReadWriteSet (line 759) | func (p *BlockPrinter) PrintTxReadWriteSet(txRWSet *rwsetutil.TxRwSet) {
method PrintNsReadWriteSet (line 770) | func (p *BlockPrinter) PrintNsReadWriteSet(nsRWSet *rwsetutil.NsRwSet) {
method PrintKvRwSet (line 783) | func (p *BlockPrinter) PrintKvRwSet(kvRWSet *kvrwset.KVRWSet, namespac...
method PrintCollHashedRwSets (line 814) | func (p *BlockPrinter) PrintCollHashedRwSets(collHashedRwSets []*rwset...
method PrintCollHashedRwSet (line 825) | func (p *BlockPrinter) PrintCollHashedRwSet(collHashedRwSet *rwsetutil...
method PrintHashedRwSet (line 835) | func (p *BlockPrinter) PrintHashedRwSet(hashedRwSet *kvrwset.HashedRWS...
method PrintHashedReads (line 841) | func (p *BlockPrinter) PrintHashedReads(hashedReads []*kvrwset.KVReadH...
method PrintHashedWrites (line 852) | func (p *BlockPrinter) PrintHashedWrites(hashedWrites []*kvrwset.KVWri...
method PrintHashedRead (line 863) | func (p *BlockPrinter) PrintHashedRead(hashedRead *kvrwset.KVReadHash) {
method PrintHashedWrite (line 869) | func (p *BlockPrinter) PrintHashedWrite(hashedWrite *kvrwset.KVWriteHa...
method PrintRangeQueryInfo (line 876) | func (p *BlockPrinter) PrintRangeQueryInfo(rqi *kvrwset.RangeQueryInfo) {
method PrintReadsInfo (line 886) | func (p *BlockPrinter) PrintReadsInfo(ri interface{}) {
method PrintRawReads (line 899) | func (p *BlockPrinter) PrintRawReads(qr *kvrwset.QueryReads) {
method PrintReadsMerkleHashes (line 910) | func (p *BlockPrinter) PrintReadsMerkleHashes(qr *kvrwset.QueryReadsMe...
method PrintRead (line 922) | func (p *BlockPrinter) PrintRead(r *kvrwset.KVRead) {
method PrintVersion (line 930) | func (p *BlockPrinter) PrintVersion(version *kvrwset.Version) {
method PrintWrite (line 940) | func (p *BlockPrinter) PrintWrite(w *kvrwset.KVWrite) {
method PrintLSCCWrite (line 947) | func (p *BlockPrinter) PrintLSCCWrite(w *kvrwset.KVWrite) {
method printChaincodeData (line 960) | func (p *BlockPrinter) printChaincodeData(value []byte) {
method printCollectionConfig (line 971) | func (p *BlockPrinter) printCollectionConfig(value []byte) {
method PrintChaincodeResponse (line 982) | func (p *BlockPrinter) PrintChaincodeResponse(response *pb.Response) {
method PrintChaincodeEventFromBlock (line 989) | func (p *BlockPrinter) PrintChaincodeEventFromBlock(chaincodeEvent *pb...
method PrintEndorsement (line 997) | func (p *BlockPrinter) PrintEndorsement(endorsement *pb.Endorsement) {
method PrintConfig (line 1003) | func (p *BlockPrinter) PrintConfig(config *fabriccmn.Config) {
method PrintConfigGroup (line 1011) | func (p *BlockPrinter) PrintConfigGroup(configGroup *fabriccmn.ConfigG...
method PrintConfigPolicy (line 1044) | func (p *BlockPrinter) PrintConfigPolicy(policy *fabriccmn.ConfigPolic...
method PrintCapabilities (line 1079) | func (p *BlockPrinter) PrintCapabilities(capabilities *fabriccmn.Capab...
method PrintImplicitMetaPolicy (line 1086) | func (p *BlockPrinter) PrintImplicitMetaPolicy(impMetaPolicy *fabriccm...
method PrintSignaturePolicyEnvelope (line 1092) | func (p *BlockPrinter) PrintSignaturePolicyEnvelope(sigPolicyEnv *fabr...
method PrintMSPPrincipal (line 1107) | func (p *BlockPrinter) PrintMSPPrincipal(principal *msp.MSPPrincipal) {
method PrintSignaturePolicy (line 1134) | func (p *BlockPrinter) PrintSignaturePolicy(sigPolicy *fabriccmn.Signa...
method PrintSignaturePolicySignedBy (line 1148) | func (p *BlockPrinter) PrintSignaturePolicySignedBy(sigPolicy *fabricc...
method PrintSignaturePolicyNOutOf (line 1153) | func (p *BlockPrinter) PrintSignaturePolicyNOutOf(sigPolicy *fabriccmn...
method PrintConfigValue (line 1165) | func (p *BlockPrinter) PrintConfigValue(name string, value *fabriccmn....
method PrintBatchSize (line 1276) | func (p *BlockPrinter) PrintBatchSize(batchSize *ab.BatchSize) {
method PrintMSPConfig (line 1293) | func (p *BlockPrinter) PrintMSPConfig(mspConfig *msp.MSPConfig) {
method PrintFabricMSPConfig (line 1312) | func (p *BlockPrinter) PrintFabricMSPConfig(mspConfig *msp.FabricMSPCo...
method PrintAnchorPeers (line 1322) | func (p *BlockPrinter) PrintAnchorPeers(anchorPeers *pb.AnchorPeers) {
method PrintAnchorPeer (line 1333) | func (p *BlockPrinter) PrintAnchorPeer(anchorPeer *pb.AnchorPeer) {
method PrintConfigSignature (line 1339) | func (p *BlockPrinter) PrintConfigSignature(sig *fabriccmn.ConfigSigna...
method PrintConfigUpdate (line 1353) | func (p *BlockPrinter) PrintConfigUpdate(configUpdate *fabriccmn.Confi...
method PrintBlockMetadata (line 1364) | func (p *BlockPrinter) PrintBlockMetadata(blockMetaData *fabriccmn.Blo...
method PrintSignaturesMetadata (line 1372) | func (p *BlockPrinter) PrintSignaturesMetadata(metadata *fabriccmn.Met...
method PrintLastConfigMetadata (line 1387) | func (p *BlockPrinter) PrintLastConfigMetadata(metadata *fabriccmn.Met...
method PrintTransactionsFilterMetadata (line 1398) | func (p *BlockPrinter) PrintTransactionsFilterMetadata(txFilter ledger...
method PrintOrdererMetadata (line 1407) | func (p *BlockPrinter) PrintOrdererMetadata(metadata *fabriccmn.Metada...
method PrintChaincodeDeploymentSpec (line 1412) | func (p *BlockPrinter) PrintChaincodeDeploymentSpec(depSpec *pb.Chainc...
method PrintChaincodeSpec (line 1419) | func (p *BlockPrinter) PrintChaincodeSpec(ccSpec *pb.ChaincodeSpec) {
method PrintChaincodeInput (line 1433) | func (p *BlockPrinter) PrintChaincodeInput(ccInput *pb.ChaincodeInput) {
method PrintPeer (line 1447) | func (p *BlockPrinter) PrintPeer(peer fab.Peer) {
function NewBlockPrinter (line 129) | func NewBlockPrinter(format OutputFormat, writerType WriterType) *BlockP...
function NewBlockPrinterWithOpts (line 136) | func NewBlockPrinterWithOpts(format OutputFormat, writerType WriterType,...
type ProviderType (line 1283) | type ProviderType
constant FABRIC (line 1287) | FABRIC ProviderType = iota
constant IDEMIX (line 1288) | IDEMIX
constant OTHER (line 1289) | OTHER
function getMetadataOrPanic (line 1457) | func getMetadataOrPanic(blockMetaData *fabriccmn.BlockMetadata, index fa...
function unmarshalOrPanic (line 1466) | func unmarshalOrPanic(buf []byte, pb proto.Message) {
function Base64URLEncode (line 1474) | func Base64URLEncode(data []byte) string {
function Base64URLDecode (line 1479) | func Base64URLDecode(data string) ([]byte, error) {
function isCollectionConfigKey (line 1488) | func isCollectionConfigKey(key string) bool {
FILE: fabric-cli/cmd/fabric-cli/printer/formatter.go
type OutputFormat (line 15) | type OutputFormat
method String (line 28) | func (f OutputFormat) String() string {
constant RAW (line 19) | RAW OutputFormat = iota
constant JSON (line 22) | JSON
constant DISPLAY (line 25) | DISPLAY
function AsOutputFormat (line 42) | func AsOutputFormat(f string) OutputFormat {
type Formatter (line 54) | type Formatter interface
type FormatterOpts (line 93) | type FormatterOpts struct
function NewFormatter (line 100) | func NewFormatter(format OutputFormat, writerType WriterType) Formatter {
function NewFormatterWithOpts (line 106) | func NewFormatterWithOpts(format OutputFormat, writerType WriterType, op...
type formatter (line 117) | type formatter struct
method write (line 121) | func (f *formatter) write(format string, a ...interface{}) error {
type displayFormatter (line 125) | type displayFormatter struct
method Print (line 131) | func (p *displayFormatter) Print(frmt string, vars ...interface{}) {
method Field (line 136) | func (p *displayFormatter) Field(field string, value interface{}) {
method Element (line 144) | func (p *displayFormatter) Element(element string) {
method ElementEnd (line 151) | func (p *displayFormatter) ElementEnd() {
method Array (line 155) | func (p *displayFormatter) Array(element string) {
method ArrayEnd (line 162) | func (p *displayFormatter) ArrayEnd() {
method Item (line 167) | func (p *displayFormatter) Item(element string, index interface{}) {
method ItemEnd (line 174) | func (p *displayFormatter) ItemEnd() {
method ItemValue (line 178) | func (p *displayFormatter) ItemValue(element string, index interface{}...
method Value (line 184) | func (p *displayFormatter) Value(value interface{}) {
method PrintHeader (line 188) | func (p *displayFormatter) PrintHeader() {
method PrintFooter (line 192) | func (p *displayFormatter) PrintFooter() {
method prefix (line 196) | func (p *displayFormatter) prefix() string {
method encodeValue (line 204) | func (p *displayFormatter) encodeValue(value interface{}) interface{} {
type jsonFormatter (line 216) | type jsonFormatter struct
method Print (line 221) | func (p *jsonFormatter) Print(frmt string, vars ...interface{}) {
method Field (line 225) | func (p *jsonFormatter) Field(field string, value interface{}) {
method Element (line 239) | func (p *jsonFormatter) Element(element string) {
method ElementEnd (line 251) | func (p *jsonFormatter) ElementEnd() {
method Array (line 256) | func (p *jsonFormatter) Array(element string) {
method ArrayEnd (line 268) | func (p *jsonFormatter) ArrayEnd() {
method Item (line 273) | func (p *jsonFormatter) Item(element string, index interface{}) {
method ItemEnd (line 281) | func (p *jsonFormatter) ItemEnd() {
method ItemValue (line 285) | func (p *jsonFormatter) ItemValue(element string, index interface{}, v...
method Value (line 293) | func (p *jsonFormatter) Value(value interface{}) {
method PrintHeader (line 300) | func (p *jsonFormatter) PrintHeader() {
method PrintFooter (line 305) | func (p *jsonFormatter) PrintFooter() {
method encodeValue (line 311) | func (p *jsonFormatter) encodeValue(value interface{}) interface{} {
FILE: fabric-cli/cmd/fabric-cli/printer/printer.go
constant indentSize (line 12) | indentSize = 3
type printer (line 15) | type printer struct
method Print (line 30) | func (p *printer) Print(frmt string, vars ...interface{}) {
method Field (line 39) | func (p *printer) Field(Field string, value interface{}) {
method Element (line 44) | func (p *printer) Element(element string) {
method ElementEnd (line 49) | func (p *printer) ElementEnd() {
method Array (line 54) | func (p *printer) Array(element string) {
method ArrayEnd (line 59) | func (p *printer) ArrayEnd() {
method Item (line 64) | func (p *printer) Item(element string, index interface{}) {
method ItemEnd (line 69) | func (p *printer) ItemEnd() {
method ItemValue (line 74) | func (p *printer) ItemValue(element string, index interface{}, value i...
method Value (line 79) | func (p *printer) Value(value interface{}) {
method PrintHeader (line 84) | func (p *printer) PrintHeader() {
method PrintFooter (line 89) | func (p *printer) PrintFooter() {
function newPrinter (line 20) | func newPrinter(format OutputFormat, writerType WriterType) *printer {
function newPrinterWithOpts (line 25) | func newPrinterWithOpts(format OutputFormat, writerType WriterType, opts...
FILE: fabric-cli/cmd/fabric-cli/printer/protoutils.go
function ExtractEnvelopeOrPanic (line 20) | func ExtractEnvelopeOrPanic(block *cb.Block, index int) *cb.Envelope {
function ExtractEnvelope (line 30) | func ExtractEnvelope(block *cb.Block, index int) (*cb.Envelope, error) {
function GetEnvelopeFromBlock (line 46) | func GetEnvelopeFromBlock(data []byte) (*cb.Envelope, error) {
function ExtractPayloadOrPanic (line 59) | func ExtractPayloadOrPanic(envelope *cb.Envelope) *cb.Payload {
function ExtractPayload (line 68) | func ExtractPayload(envelope *cb.Envelope) (*cb.Payload, error) {
function UnmarshalChannelHeader (line 76) | func UnmarshalChannelHeader(bytes []byte) (*cb.ChannelHeader, error) {
function GetSignatureHeader (line 83) | func GetSignatureHeader(bytes []byte) (*cb.SignatureHeader, error) {
function GetTransaction (line 90) | func GetTransaction(txBytes []byte) (*peer.Transaction, error) {
function GetChaincodeActionPayload (line 98) | func GetChaincodeActionPayload(capBytes []byte) (*peer.ChaincodeActionPa...
FILE: fabric-cli/cmd/fabric-cli/printer/writer.go
type WriterType (line 18) | type WriterType
method String (line 37) | func (f WriterType) String() string {
constant STDOUT (line 22) | STDOUT WriterType = iota
constant STDERR (line 25) | STDERR
constant LOG (line 28) | LOG
constant stdout (line 32) | stdout = "stdout"
constant stderr (line 33) | stderr = "stderr"
constant log (line 34) | log = "log"
function AsWriterType (line 51) | func AsWriterType(t string) WriterType {
type Writer (line 63) | type Writer interface
function NewWriter (line 68) | func NewWriter(writerType WriterType) Writer {
type stdOutWriter (line 79) | type stdOutWriter struct
method Write (line 82) | func (w *stdOutWriter) Write(format string, a ...interface{}) error {
type stdErrWriter (line 87) | type stdErrWriter struct
method Write (line 90) | func (w *stdErrWriter) Write(format string, a ...interface{}) error {
type logWriter (line 95) | type logWriter struct
method Write (line 98) | func (w *logWriter) Write(format string, a ...interface{}) error {
FILE: fabric-cli/cmd/fabric-cli/query/queryblockcmd.go
function getQueryBlockCmd (line 42) | func getQueryBlockCmd() *cobra.Command {
type queryBlockAction (line 52) | type queryBlockAction struct
method invoke (line 62) | func (a *queryBlockAction) invoke() error {
method traverse (line 98) | func (a *queryBlockAction) traverse(ledgerClient *ledger.Client, curre...
function newQueryBlockAction (line 56) | func newQueryBlockAction(flags *pflag.FlagSet) (*queryBlockAction, error) {
function Base64URLDecode (line 117) | func Base64URLDecode(data string) ([]byte, error) {
FILE: fabric-cli/cmd/fabric-cli/query/querychannelscmd.go
function getQueryChannelsCmd (line 45) | func getQueryChannelsCmd() *cobra.Command {
type queryChannelsAction (line 50) | type queryChannelsAction struct
method run (line 60) | func (a *queryChannelsAction) run() error {
function newQueryChannelsAction (line 54) | func newQueryChannelsAction(flags *pflag.FlagSet) (*queryChannelsAction,...
FILE: fabric-cli/cmd/fabric-cli/query/querycmd.go
function Cmd (line 24) | func Cmd() *cobra.Command {
FILE: fabric-cli/cmd/fabric-cli/query/queryinfocmd.go
function getQueryInfoCmd (line 44) | func getQueryInfoCmd() *cobra.Command {
type queryInfoAction (line 52) | type queryInfoAction struct
method run (line 62) | func (a *queryInfoAction) run() error {
function newQueryInfoAction (line 56) | func newQueryInfoAction(flags *pflag.FlagSet) (*queryInfoAction, error) {
FILE: fabric-cli/cmd/fabric-cli/query/queryinstalledcmd.go
function getQueryInstalledCmd (line 46) | func getQueryInstalledCmd() *cobra.Command {
type queryInstalledAction (line 51) | type queryInstalledAction struct
method run (line 61) | func (a *queryInstalledAction) run() error {
function newqueryInstalledAction (line 55) | func newqueryInstalledAction(flags *pflag.FlagSet) (*queryInstalledActio...
FILE: fabric-cli/cmd/fabric-cli/query/querylocalpeerscmd.go
function getQueryLocalPeersCmd (line 43) | func getQueryLocalPeersCmd() *cobra.Command {
type queryLocalPeersAction (line 50) | type queryLocalPeersAction struct
method run (line 60) | func (a *queryLocalPeersAction) run() error {
function newQueryLocalPeersAction (line 54) | func newQueryLocalPeersAction(flags *pflag.FlagSet) (*queryLocalPeersAct...
FILE: fabric-cli/cmd/fabric-cli/query/querypeerscmd.go
function getQueryPeersCmd (line 43) | func getQueryPeersCmd() *cobra.Command {
type queryPeersAction (line 50) | type queryPeersAction struct
method run (line 60) | func (a *queryPeersAction) run() error {
function newQueryPeersAction (line 54) | func newQueryPeersAction(flags *pflag.FlagSet) (*queryPeersAction, error) {
FILE: fabric-cli/cmd/fabric-cli/query/querytxcmd.go
function getQueryTXCmd (line 45) | func getQueryTXCmd() *cobra.Command {
type queryTXAction (line 53) | type queryTXAction struct
method run (line 64) | func (a *queryTXAction) run() error {
function newQueryTXAction (line 57) | func newQueryTXAction(flags *pflag.FlagSet) (*queryTXAction, error) {
FILE: fabric-cli/test/fixtures/testdata/src/github.com/securekey/example2_cc/example2_cc.go
type invokeFunc (line 18) | type invokeFunc
type funcMap (line 19) | type funcMap
constant getFunc (line 22) | getFunc = "get"
constant putFunc (line 23) | putFunc = "put"
constant delFunc (line 24) | delFunc = "del"
constant putPrivateFunc (line 25) | putPrivateFunc = "putprivate"
constant getPrivateFunc (line 26) | getPrivateFunc = "getprivate"
constant delPrivateFunc (line 27) | delPrivateFunc = "delprivate"
constant putBothFunc (line 28) | putBothFunc = "putboth"
constant getAndPutBothFunc (line 29) | getAndPutBothFunc = "getandputboth"
constant invokeCCFunc (line 30) | invokeCCFunc = "invokecc"
type ExampleCC (line 34) | type ExampleCC struct
method Init (line 39) | func (cc *ExampleCC) Init(stub shim.ChaincodeStubInterface) pb.Response {
method Invoke (line 44) | func (cc *ExampleCC) Invoke(stub shim.ChaincodeStubInterface) pb.Respo...
method put (line 59) | func (cc *ExampleCC) put(stub shim.ChaincodeStubInterface, args []stri...
method get (line 82) | func (cc *ExampleCC) get(stub shim.ChaincodeStubInterface, args []stri...
method del (line 97) | func (cc *ExampleCC) del(stub shim.ChaincodeStubInterface, args []stri...
method putPrivate (line 112) | func (cc *ExampleCC) putPrivate(stub shim.ChaincodeStubInterface, args...
method getPrivate (line 128) | func (cc *ExampleCC) getPrivate(stub shim.ChaincodeStubInterface, args...
method delPrivate (line 144) | func (cc *ExampleCC) delPrivate(stub shim.ChaincodeStubInterface, args...
method putBoth (line 160) | func (cc *ExampleCC) putBoth(stub shim.ChaincodeStubInterface, args []...
method getAndPutBoth (line 181) | func (cc *ExampleCC) getAndPutBoth(stub shim.ChaincodeStubInterface, a...
method invokeCC (line 229) | func (cc *ExampleCC) invokeCC(stub shim.ChaincodeStubInterface, args [...
method initRegistry (line 249) | func (cc *ExampleCC) initRegistry() {
method functions (line 262) | func (cc *ExampleCC) functions() []string {
type argStruct (line 217) | type argStruct struct
function asBytes (line 221) | func asBytes(args []string) [][]byte {
function main (line 270) | func main() {
FILE: fabric-cli/test/fixtures/testdata/src/github.com/securekey/example_cc/example_cc.go
type SimpleChaincode (line 28) | type SimpleChaincode struct
method Init (line 32) | func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Re...
method Query (line 78) | func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface) pb.R...
method Invoke (line 84) | func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb....
method move (line 129) | func (t *SimpleChaincode) move(stub shim.ChaincodeStubInterface, args ...
method delete (line 192) | func (t *SimpleChaincode) delete(stub shim.ChaincodeStubInterface, arg...
method query (line 209) | func (t *SimpleChaincode) query(stub shim.ChaincodeStubInterface, args...
method put (line 236) | func (t *SimpleChaincode) put(stub shim.ChaincodeStubInterface, args [...
method get (line 259) | func (t *SimpleChaincode) get(stub shim.ChaincodeStubInterface, args [...
function main (line 274) | func main() {
FILE: fabric-cli/test/integration/fabric-cli_test.go
function run (line 22) | func run(cmd string) {
function header (line 30) | func header(h string) {
function TestCreate_a_channel (line 40) | func TestCreate_a_channel(t *testing.T) {
function TestJoin_org1_peer_to_a_channel (line 47) | func TestJoin_org1_peer_to_a_channel(t *testing.T) {
function TestJoin_org2_peer_to_a_channel (line 52) | func TestJoin_org2_peer_to_a_channel(t *testing.T) {
function TestJoin_all_peers_in_org1_to_a_channel (line 57) | func TestJoin_all_peers_in_org1_to_a_channel(t *testing.T) {
function TestJoin_all_peers_in_org2_to_a_channel (line 62) | func TestJoin_all_peers_in_org2_to_a_channel(t *testing.T) {
function TestJoin_all_peers_to_a_channel (line 67) | func TestJoin_all_peers_to_a_channel(t *testing.T) {
function TestInstall_chaincode_on_all_peers_of_org1 (line 74) | func TestInstall_chaincode_on_all_peers_of_org1(t *testing.T) {
function TestInstall_chaincode_on_all_peers_of_org2 (line 79) | func TestInstall_chaincode_on_all_peers_of_org2(t *testing.T) {
function TestInstall_chaincode_on_all_peers (line 84) | func TestInstall_chaincode_on_all_peers(t *testing.T) {
function TestInstall_chaincode_on_all_peers_v1 (line 89) | func TestInstall_chaincode_on_all_peers_v1(t *testing.T) {
function TestInstantiate_chaincode_with_default_endorsement_policy (line 96) | func TestInstantiate_chaincode_with_default_endorsement_policy(t *testin...
function TestInstantiate_chaincode_with_specified_endorsement_policy (line 101) | func TestInstantiate_chaincode_with_specified_endorsement_policy(t *test...
function TestInstantiate_chaincode_with_specified_private_data_collection_configuration (line 106) | func TestInstantiate_chaincode_with_specified_private_data_collection_co...
function TestUpgrade_chaincode_to_v1 (line 113) | func TestUpgrade_chaincode_to_v1(t *testing.T) {
function TestQuery_info (line 121) | func TestQuery_info(t *testing.T) {
function TestQuery_block_by_block_number (line 126) | func TestQuery_block_by_block_number(t *testing.T) {
function TestQuery_block_by_hash (line 131) | func TestQuery_block_by_hash(t *testing.T) {
function TestQuery_block_output_in_JSON_format (line 137) | func TestQuery_block_output_in_JSON_format(t *testing.T) {
function TestQuery_transaction (line 142) | func TestQuery_transaction(t *testing.T) {
function TestQuery_channels_joined_by_a_peer (line 147) | func TestQuery_channels_joined_by_a_peer(t *testing.T) {
function TestQuery_installed_chaincodes_on_a_peer (line 152) | func TestQuery_installed_chaincodes_on_a_peer(t *testing.T) {
function TestRetrieve_chaincode_deployment_info (line 159) | func TestRetrieve_chaincode_deployment_info(t *testing.T) {
function TestQuery_chaincode_on_a_set_of_peers (line 166) | func TestQuery_chaincode_on_a_set_of_peers(t *testing.T) {
function TestQuery_chaincode_and_view_payloads_only (line 171) | func TestQuery_chaincode_and_view_payloads_only(t *testing.T) {
function TestInvoke_chaincode (line 178) | func TestInvoke_chaincode(t *testing.T) {
function TestInvoke_chaincode_5_times (line 183) | func TestInvoke_chaincode_5_times(t *testing.T) {
function TestInvoke_chaincode_100_times_in_8_Go_routines (line 188) | func TestInvoke_chaincode_100_times_in_8_Go_routines(t *testing.T) {
function TestInvoke_chaincode_with_two_sets_of_args (line 193) | func TestInvoke_chaincode_with_two_sets_of_args(t *testing.T) {
function TestInvoke_chaincode_using_dynamic_selection_provider (line 198) | func TestInvoke_chaincode_using_dynamic_selection_provider(t *testing.T) {
function TestListen_for_block_events (line 205) | func TestListen_for_block_events(t *testing.T) {
function TestListen_for_filtered_block_events (line 210) | func TestListen_for_filtered_block_events(t *testing.T) {
function TestListen_for_chaincode_events (line 215) | func TestListen_for_chaincode_events(t *testing.T) {
Condensed preview — 63 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (343K chars).
[
{
"path": ".gitignore",
"chars": 204,
"preview": "#\n# Copyright SecureKey Technologies Inc. All Rights Reserved.\n#\n# SPDX-License-Identifier: Apache-2.0\n#\n*.db\n*report.xm"
},
{
"path": ".gitreview",
"chars": 70,
"preview": "[gerrit]\nhost=gerrit.securekey.com\nport=29418\nproject=fabric-examples\n"
},
{
"path": "README.md",
"chars": 16,
"preview": "fabric-examples\n"
},
{
"path": "fabric-cli/.gitignore",
"chars": 128,
"preview": "#\n# Copyright SecureKey Technologies Inc. All Rights Reserved.\n#\n# SPDX-License-Identifier: Apache-2.0\n#\nvendor/\nfabric-"
},
{
"path": "fabric-cli/LICENSE",
"chars": 11358,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "fabric-cli/Makefile",
"chars": 1493,
"preview": "#\n# Copyright SecureKey Technologies Inc. All Rights Reserved.\n#\n# SPDX-License-Identifier: Apache-2.0\n#\n\n# Supported Ta"
},
{
"path": "fabric-cli/README.md",
"chars": 15781,
"preview": "# Fabric CLI Sample Application\n\nFabric CLI is a sample command-line interface built using Fabric SDK GO. It provides th"
},
{
"path": "fabric-cli/cmd/fabric-cli/action/action.go",
"chars": 20712,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage action\n\ni"
},
{
"path": "fabric-cli/cmd/fabric-cli/action/svcproviderfactory.go",
"chars": 3676,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage action\n\ni"
},
{
"path": "fabric-cli/cmd/fabric-cli/chaincode/chaincodecmd.go",
"chars": 832,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage chaincode"
},
{
"path": "fabric-cli/cmd/fabric-cli/chaincode/getinfocmd.go",
"chars": 4178,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage chaincode"
},
{
"path": "fabric-cli/cmd/fabric-cli/chaincode/installcmd.go",
"chars": 3702,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage chaincode"
},
{
"path": "fabric-cli/cmd/fabric-cli/chaincode/instantiatecmd.go",
"chars": 6471,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage chaincode"
},
{
"path": "fabric-cli/cmd/fabric-cli/chaincode/invokecmd.go",
"chars": 7408,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage chaincode"
},
{
"path": "fabric-cli/cmd/fabric-cli/chaincode/invokeerror/invokeerror.go",
"chars": 1551,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage invokeerr"
},
{
"path": "fabric-cli/cmd/fabric-cli/chaincode/invoketask/invoketask.go",
"chars": 4595,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage invoketas"
},
{
"path": "fabric-cli/cmd/fabric-cli/chaincode/multitask/multitask.go",
"chars": 1152,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage multitask"
},
{
"path": "fabric-cli/cmd/fabric-cli/chaincode/querycmd.go",
"chars": 6538,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage chaincode"
},
{
"path": "fabric-cli/cmd/fabric-cli/chaincode/querytask/querytask.go",
"chars": 3298,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage querytask"
},
{
"path": "fabric-cli/cmd/fabric-cli/chaincode/task/task.go",
"chars": 420,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage task\n\n// "
},
{
"path": "fabric-cli/cmd/fabric-cli/chaincode/upgradecmd.go",
"chars": 4900,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage chaincode"
},
{
"path": "fabric-cli/cmd/fabric-cli/chaincode/utils/test.json",
"chars": 20,
"preview": "{\"Field1\": \"Value1\"}"
},
{
"path": "fabric-cli/cmd/fabric-cli/chaincode/utils/util.go",
"chars": 6168,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage utils\n\nim"
},
{
"path": "fabric-cli/cmd/fabric-cli/chaincode/utils/util_test.go",
"chars": 4228,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage utils\n\nim"
},
{
"path": "fabric-cli/cmd/fabric-cli/channel/channelcmd.go",
"chars": 653,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage channel\n\n"
},
{
"path": "fabric-cli/cmd/fabric-cli/channel/channelcreatecmd.go",
"chars": 2224,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage channel\n\n"
},
{
"path": "fabric-cli/cmd/fabric-cli/channel/channeljoincmd.go",
"chars": 2676,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage channel\n\n"
},
{
"path": "fabric-cli/cmd/fabric-cli/cmd/fabric-cli.go",
"chars": 1373,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage cmd\n\nimpo"
},
{
"path": "fabric-cli/cmd/fabric-cli/config/config.go",
"chars": 33498,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage config\n\ni"
},
{
"path": "fabric-cli/cmd/fabric-cli/event/eventcmd.go",
"chars": 591,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage event\n\nim"
},
{
"path": "fabric-cli/cmd/fabric-cli/event/inputevent.go",
"chars": 443,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage event\n\nim"
},
{
"path": "fabric-cli/cmd/fabric-cli/event/listenblockcmd.go",
"chars": 2317,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage event\n\nim"
},
{
"path": "fabric-cli/cmd/fabric-cli/event/listencccmd.go",
"chars": 2536,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage event\n\nim"
},
{
"path": "fabric-cli/cmd/fabric-cli/event/listenfilteredblockcmd.go",
"chars": 2465,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage event\n\nim"
},
{
"path": "fabric-cli/cmd/fabric-cli/event/listentxcmd.go",
"chars": 2339,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage event\n\nim"
},
{
"path": "fabric-cli/cmd/fabric-cli/executor/executor.go",
"chars": 5198,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage executor\n"
},
{
"path": "fabric-cli/cmd/fabric-cli/executor/worker/worker.go",
"chars": 2318,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage worker\n\ni"
},
{
"path": "fabric-cli/cmd/fabric-cli/executor/worker/workerpool.go",
"chars": 3042,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage worker\n\ni"
},
{
"path": "fabric-cli/cmd/fabric-cli/fabric-cli.go",
"chars": 230,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage main\n\nimp"
},
{
"path": "fabric-cli/cmd/fabric-cli/go.mod",
"chars": 1031,
"preview": "// Copyright SecureKey Technologies Inc. All Rights Reserved.\n//\n// SPDX-License-Identifier: Apache-2.0\n\nmodule github.c"
},
{
"path": "fabric-cli/cmd/fabric-cli/go.sum",
"chars": 14938,
"preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ngithub.com/BurntSushi/toml v0.3.1 h1:"
},
{
"path": "fabric-cli/cmd/fabric-cli/printer/blockprinter.go",
"chars": 42242,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage printer\n\n"
},
{
"path": "fabric-cli/cmd/fabric-cli/printer/formatter.go",
"chars": 6603,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage printer\n\n"
},
{
"path": "fabric-cli/cmd/fabric-cli/printer/printer.go",
"chars": 2363,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage printer\n\n"
},
{
"path": "fabric-cli/cmd/fabric-cli/printer/protoutils.go",
"chars": 3227,
"preview": "/*\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"
},
{
"path": "fabric-cli/cmd/fabric-cli/printer/writer.go",
"chars": 1738,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage printer\n\n"
},
{
"path": "fabric-cli/cmd/fabric-cli/query/queryblockcmd.go",
"chars": 3102,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage query\n\nim"
},
{
"path": "fabric-cli/cmd/fabric-cli/query/querychannelscmd.go",
"chars": 2146,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage query\n\nim"
},
{
"path": "fabric-cli/cmd/fabric-cli/query/querycmd.go",
"chars": 842,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage query\n\nim"
},
{
"path": "fabric-cli/cmd/fabric-cli/query/queryinfocmd.go",
"chars": 1689,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage query\n\nim"
},
{
"path": "fabric-cli/cmd/fabric-cli/query/queryinstalledcmd.go",
"chars": 2148,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage query\n\nim"
},
{
"path": "fabric-cli/cmd/fabric-cli/query/querylocalpeerscmd.go",
"chars": 1684,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage query\n\nim"
},
{
"path": "fabric-cli/cmd/fabric-cli/query/querypeerscmd.go",
"chars": 1760,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage query\n\nim"
},
{
"path": "fabric-cli/cmd/fabric-cli/query/querytxcmd.go",
"chars": 1886,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage query\n\nim"
},
{
"path": "fabric-cli/test/fixtures/config/config_test_local.yaml",
"chars": 17667,
"preview": "#\n# Copyright SecureKey Technologies Inc. All Rights Reserved.\n#\n# SPDX-License-Identifier: Apache-2.0\n#\n#\n# The network"
},
{
"path": "fabric-cli/test/fixtures/config/pvtdatacollection.json",
"chars": 297,
"preview": "[\n {\n \"name\": \"coll1\",\n \"policy\": \"OR('Org1MSP.member', 'Org2MSP.member')\",\n \"requiredPeerCount\""
},
{
"path": "fabric-cli/test/fixtures/testdata/src/github.com/securekey/example2_cc/example2_cc.go",
"chars": 7590,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage main\n\nimp"
},
{
"path": "fabric-cli/test/fixtures/testdata/src/github.com/securekey/example_cc/example_cc.go",
"chars": 7222,
"preview": "/*\nCopyright IBM Corp. 2016 All Rights Reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou ma"
},
{
"path": "fabric-cli/test/fixtures/testdata/src/go.mod",
"chars": 212,
"preview": "// Copyright SecureKey Technologies Inc. All Rights Reserved.\n//\n// SPDX-License-Identifier: Apache-2.0\n\nmodule github.c"
},
{
"path": "fabric-cli/test/fixtures/testdata/src/go.sum",
"chars": 92,
"preview": "github.com/hyperledger/fabric v1.4.0/go.mod h1:tGFAOCT696D3rG0Vofd2dyWYLySHlh0aQjf7Q1HAju0=\n"
},
{
"path": "fabric-cli/test/integration/fabric-cli_test.go",
"chars": 10427,
"preview": "/*\nCopyright SecureKey Technologies Inc. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage integrati"
},
{
"path": "fabric-cli/test/integration/go.mod",
"chars": 336,
"preview": "// Copyright SecureKey Technologies Inc. All Rights Reserved.\n//\n// SPDX-License-Identifier: Apache-2.0\n\nmodule github.c"
},
{
"path": "fabric-cli/test/integration/go.sum",
"chars": 15852,
"preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ngithub.com/BurntSushi/toml v0.3.1 h1:"
}
]
About this extraction
This page contains the full source code of the securekey/fabric-examples GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 63 files (310.4 KB), approximately 91.8k tokens, and a symbol index with 735 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.