├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .gitattributes
├── .github
├── settings.yml
└── workflows
│ ├── pull_request.yaml
│ ├── push.yaml
│ ├── release.yaml
│ ├── scan.yaml
│ ├── schedule.yaml
│ ├── test.yaml
│ └── vulnerability-scan.yaml
├── .gitignore
├── CHANGELOG.md
├── CODEOWNERS
├── CODE_OF_CONDUCT.md
├── COMPATIBILITY.md
├── CONTRIBUTING.md
├── LICENSE
├── MAINTAINERS.md
├── README.md
├── RELEASING.md
├── SECURITY.md
├── TUTORIAL.md
├── apis
├── fabric-contract-api
│ ├── .npmignore
│ ├── LICENSE
│ ├── README.md
│ ├── index.js
│ ├── lib
│ │ ├── annotations
│ │ │ ├── default.js
│ │ │ ├── index.js
│ │ │ ├── info.js
│ │ │ ├── object.js
│ │ │ ├── transaction.js
│ │ │ └── utils.js
│ │ ├── context.js
│ │ ├── contract.js
│ │ ├── jsontransactionserializer.js
│ │ └── logger.js
│ ├── package.json
│ ├── schema
│ │ ├── contract-schema.json
│ │ ├── data.json
│ │ ├── example-full.json
│ │ ├── helloworld.json
│ │ └── testschema.json
│ ├── test
│ │ ├── typescript
│ │ │ └── smartcontract.ts
│ │ └── unit
│ │ │ ├── annotations
│ │ │ ├── default.js
│ │ │ ├── info.js
│ │ │ ├── object.js
│ │ │ ├── transaction.js
│ │ │ └── utils.js
│ │ │ ├── context.js
│ │ │ ├── contract.js
│ │ │ ├── data.json
│ │ │ ├── index.js
│ │ │ ├── jsontransactionserializer.js
│ │ │ ├── logger.js
│ │ │ └── metadata.json
│ ├── tsconfig.json
│ └── types
│ │ └── index.d.ts
└── fabric-shim-api
│ ├── LICENSE
│ ├── README.md
│ ├── index.js
│ ├── package.json
│ ├── tsconfig.json
│ └── types
│ └── index.d.ts
├── common
├── config
│ └── rush
│ │ ├── command-line.json
│ │ └── pnpm-lock.yaml
└── scripts
│ ├── install-run-rush-pnpm.js
│ ├── install-run-rush.js
│ ├── install-run-rushx.js
│ └── install-run.js
├── docker
└── fabric-nodeenv
│ ├── Dockerfile
│ ├── README.md
│ ├── build.sh
│ ├── docker.js
│ ├── package.json
│ └── start.sh
├── docs
├── 404.md
├── README.md
├── _config.yml
├── _includes
│ ├── apidocs.html
│ ├── footer.html
│ └── header.html
├── _jsdoc.json
├── _jsdoc
│ ├── index.md
│ ├── static
│ │ └── contract-schema.json
│ └── tutorials
│ │ ├── annotated-contract-metadata.md
│ │ ├── data-types-and-contracts.md
│ │ ├── deep-dive-contract-interface.md
│ │ ├── tutorials.json
│ │ ├── using-chaincodeinterface.md
│ │ ├── using-contractinterface.md
│ │ ├── using-iterators.md
│ │ └── using-typescript-decorators.md
├── index.md
└── package.json
├── libraries
├── fabric-ledger
│ ├── .eslintignore
│ ├── .eslintrc.js
│ ├── .npmignore
│ ├── package.json
│ ├── src
│ │ ├── Collection.ts
│ │ ├── Ledger.ts
│ │ └── index.ts
│ ├── test
│ │ └── unit
│ │ │ └── Ledger.spec.ts
│ └── tsconfig.json
└── fabric-shim
│ ├── .npmignore
│ ├── LICENSE
│ ├── README.md
│ ├── cli.js
│ ├── index.js
│ ├── lib
│ ├── chaincode.js
│ ├── cmds
│ │ ├── metadata.js
│ │ ├── metadata
│ │ │ ├── generateCommand.js
│ │ │ └── lib
│ │ │ │ └── generate.js
│ │ ├── serverCommand.js
│ │ └── startCommand.js
│ ├── contract-spi
│ │ ├── bootstrap.js
│ │ ├── chaincodefromcontract.js
│ │ ├── datamarshall.js
│ │ └── systemcontract.js
│ ├── handler.js
│ ├── iterators.js
│ ├── logger.js
│ ├── server.js
│ ├── stub.js
│ └── utils
│ │ ├── statebased.js
│ │ └── utils.js
│ ├── package.json
│ ├── startup.sh
│ ├── test
│ ├── typescript
│ │ └── chaincode.ts
│ └── unit
│ │ ├── chaincode.js
│ │ ├── cli.js
│ │ ├── client-identity.js
│ │ ├── cmds
│ │ ├── chaincode.js
│ │ ├── metadata.js
│ │ ├── metadata
│ │ │ ├── generateCommand.js
│ │ │ └── lib
│ │ │ │ └── generate.js
│ │ └── serverCommand.js
│ │ ├── contract-spi
│ │ ├── bootstrap.js
│ │ ├── chaincodefromcontract.js
│ │ ├── datamarshall.js
│ │ └── systemcontract.js
│ │ ├── handler.js
│ │ ├── iterators.js
│ │ ├── logger.js
│ │ ├── module.js
│ │ ├── server.js
│ │ ├── stub.js
│ │ ├── test-ca.base64
│ │ ├── test-ca.pem
│ │ ├── test-cert.base64
│ │ ├── test-cert.pem
│ │ ├── test-key.base64
│ │ ├── test-key.pem
│ │ └── utils
│ │ ├── statebased.js
│ │ └── utils.js
│ ├── tsconfig.json
│ └── types
│ └── index.d.ts
├── release_notes
├── v1.1.0-alpha.txt
├── v1.1.0-preview.txt
├── v1.1.0.txt
├── v1.2.0.txt
├── v1.3.0.txt
├── v1.4.0-beta.txt
├── v1.4.0.txt
├── v2.0.0-alpha.txt
├── v2.0.0-beta.txt
├── v2.0.0.txt
├── v2.1.0.txt
├── v2.1.1.txt
├── v2.1.2.txt
├── v2.1.3.txt
├── v2.1.4.txt
├── v2.2.0.txt
├── v2.3.0.txt
├── v2.4.0-beta.txt
├── v2.4.0.txt
├── v2.4.1.txt
├── v2.4.2.txt
├── v2.5.0.txt
├── v2.5.1.txt
└── v2.5.2.txt
├── rush.json
├── test
├── chaincodes
│ ├── annotations
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── index.ts
│ │ │ └── test_contract
│ │ │ │ ├── expected-metadata.json
│ │ │ │ └── test_contract.ts
│ │ └── tsconfig.json
│ ├── clientidentity
│ │ ├── chaincode.js
│ │ ├── index.js
│ │ └── package.json
│ ├── crosschaincode
│ │ ├── chaincode.js
│ │ ├── index.js
│ │ └── package.json
│ ├── crosschaincode2
│ │ ├── chaincode.js
│ │ ├── index.js
│ │ └── package.json
│ ├── crud
│ │ ├── chaincode.js
│ │ ├── index.js
│ │ └── package.json
│ ├── events
│ │ ├── chaincode.js
│ │ ├── index.js
│ │ └── package.json
│ ├── ledger
│ │ ├── chaincode.js
│ │ ├── index.js
│ │ └── package.json
│ ├── privateData
│ │ ├── chaincode.js
│ │ ├── collection-config
│ │ │ └── collection.json
│ │ ├── index.js
│ │ └── package.json
│ ├── query
│ │ ├── chaincode.js
│ │ ├── index.js
│ │ └── package.json
│ ├── scenario
│ │ ├── index.js
│ │ ├── package.json
│ │ ├── removevalues.js
│ │ ├── scenariocontext.js
│ │ └── updatevalues.js
│ └── server
│ │ ├── .dockerignore
│ │ ├── Dockerfile
│ │ ├── index.js
│ │ └── package
│ │ ├── connection.json
│ │ └── metadata.json
├── constants.js
├── e2e
│ ├── package.json
│ ├── scenario.js
│ └── server.js
├── fixtures
│ ├── channel-init.sh
│ └── kill-chaincode-node.sh
└── fv
│ ├── annotations.js
│ ├── clientidentity.js
│ ├── crosschaincode.js
│ ├── crosschaincode2.js
│ ├── crud.js
│ ├── events.js
│ ├── ledger.js
│ ├── package.json
│ ├── privateData.js
│ ├── query.js
│ └── utils.js
└── tools
├── getEdgeDocker.sh
├── logfiles.sh
├── monitordocker.sh
├── scripts
├── changelog.sh
├── gittag.sh
├── multiarch.sh
├── startFabric.sh
└── updateversions.sh
└── toolchain
├── fabric.js
├── index.js
├── network
├── README.md
├── crypto-material
│ ├── configtx.yaml
│ ├── core.yaml
│ ├── crypto-config.yaml
│ └── rename_sk.sh
├── docker-compose
│ ├── docker-compose-base.yaml
│ ├── docker-compose-cli.yaml
│ ├── docker-compose-tls.yaml
│ └── docker-compose.yaml
└── external
│ ├── build
│ ├── detect
│ └── release
├── package.json
├── shell
├── cmd.js
├── docker.js
└── npm.js
├── test
├── devmode.js
└── inversionOfControl.js
├── utils.js
└── verdaccio
├── config.yaml
└── index.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 | #
14 |
15 | root = true
16 |
17 | [*]
18 | indent_style = space
19 | indent_size = 4
20 | end_of_line = lf
21 | charset = utf-8
22 | trim_trailing_whitespace = true
23 | insert_final_newline = true
24 |
25 | [*.md]
26 | indent_size = 2
27 |
28 | [*.{yaml,yml}]
29 | indent_size = 2
30 |
31 | [*.{mj,cj,j,t}s]
32 | quote_type = single
33 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | bundle.js
2 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "es6": true,
4 | "node": true,
5 | "mocha": true
6 | },
7 | "extends": [ "eslint:recommended", "@rushstack/eslint-config"],
8 | "overrides": [
9 | {
10 | "files": ["**/test/typescript/*.ts"],
11 | "rules": {
12 | "no-unused-vars": "off",
13 | "@typescript-eslint/no-unused-vars": "off",
14 | "@typescript-eslint/no-floating-promises": "off"
15 | }
16 | },
17 | {
18 | "files": ["**/index.d.ts"],
19 | "rules": {
20 | "max-len": "warn"
21 | }
22 | }
23 | ],
24 | "parserOptions": {
25 | "ecmaVersion": 9,
26 | "sourceType": "module"
27 | },
28 | "rules": {
29 | "array-bracket-spacing": ["error", "never"],
30 | "arrow-spacing": ["error"],
31 | "brace-style": ["error"],
32 | "comma-spacing": ["error"],
33 | "curly": ["error"],
34 | "dot-notation": ["error"],
35 | "eqeqeq": ["error"],
36 | "indent": [
37 | "error",
38 | 4,
39 | {
40 | "SwitchCase": 1
41 | }
42 | ],
43 | "keyword-spacing": "error",
44 | "linebreak-style": ["error", "unix"],
45 | "max-len": [
46 | "error",
47 | {
48 | "code": 150,
49 | "ignoreTrailingComments": true,
50 | "ignoreUrls": true,
51 | "ignoreStrings": true,
52 | "ignoreTemplateLiterals": true,
53 | "ignoreRegExpLiterals": true
54 | }
55 | ],
56 | "no-console": ["warn"],
57 | "no-shadow": ["error"],
58 | "no-throw-literal": ["error"],
59 | "no-trailing-spaces": ["error"],
60 | "no-useless-call": ["error"],
61 | "no-unused-vars": [
62 | "error",
63 | {
64 | "args": "none"
65 | }
66 | ],
67 | "no-var": ["error"],
68 | "no-with": ["error"],
69 | "object-curly-spacing": ["error", "never"],
70 | "operator-linebreak": ["error"],
71 | "prefer-const": ["error"],
72 | "quotes": ["error", "single"],
73 | "semi": ["error", "always"],
74 | "spaced-comment": ["error", "always"],
75 | "space-before-blocks": [
76 | "error",
77 | {
78 | "functions": "always",
79 | "keywords": "always",
80 | "classes": "always"
81 | }
82 | ],
83 | "space-infix-ops": ["error"],
84 | "space-in-parens": ["error", "never"],
85 | "yoda": "error",
86 | "@typescript-eslint/no-explicit-any": "warn",
87 | "@typescript-eslint/explicit-member-accessibility": "off",
88 | "@typescript-eslint/explicit-function-return-type": "off",
89 | "@typescript-eslint/interface-name-prefix": "off",
90 | "@typescript-eslint/no-namespace": "off",
91 | "@typescript-eslint/typedef": "off"
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.json linguist-language=JSON-with-Comments
--------------------------------------------------------------------------------
/.github/settings.yml:
--------------------------------------------------------------------------------
1 | repository:
2 | name: fabric-chaincode-node
3 | description: Hyperledger Fabric Node.js Smart Contracts issues in JIRA please
4 | https://jira.hyperledger.org
5 | homepage: https://wiki.hyperledger.org/display/fabric
6 | default_branch: main
7 | has_downloads: true
8 | has_issues: true
9 | has_projects: false
10 | has_wiki: false
11 | archived: false
12 | private: false
13 | allow_squash_merge: true
14 | allow_merge_commit: false
15 | allow_rebase_merge: true
16 |
--------------------------------------------------------------------------------
/.github/workflows/pull_request.yaml:
--------------------------------------------------------------------------------
1 | # Copyright the Hyperledger Fabric contributors. All rights reserved.
2 | # SPDX-License-Identifier: Apache-2.0
3 |
4 | name: Pull request
5 |
6 | on:
7 | pull_request:
8 | branches:
9 | - main
10 | workflow_dispatch:
11 |
12 | concurrency:
13 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
14 | cancel-in-progress: true
15 |
16 | jobs:
17 | test:
18 | uses: ./.github/workflows/test.yaml
19 |
20 | scan:
21 | uses: ./.github/workflows/scan.yaml
22 |
23 | pull-request:
24 | needs: test
25 | name: Pull request success
26 | runs-on: ubuntu-latest
27 | steps:
28 | - run: "true"
29 |
--------------------------------------------------------------------------------
/.github/workflows/push.yaml:
--------------------------------------------------------------------------------
1 | # Copyright the Hyperledger Fabric contributors. All rights reserved.
2 | # SPDX-License-Identifier: Apache-2.0
3 |
4 | name: Push
5 |
6 | on:
7 | push:
8 | branches:
9 | - main
10 | workflow_dispatch:
11 |
12 | jobs:
13 | test:
14 | uses: ./.github/workflows/test.yaml
15 |
--------------------------------------------------------------------------------
/.github/workflows/scan.yaml:
--------------------------------------------------------------------------------
1 | name: "Security vulnerability scan"
2 |
3 | on:
4 | workflow_call:
5 | inputs:
6 | ref:
7 | description: Branch, tag or SHA to scan.
8 | type: string
9 | required: false
10 | default: ""
11 |
12 | permissions:
13 | contents: read
14 |
15 | jobs:
16 | # Job to handle the auditing of the code
17 | # NPM audit is run on a 'fake' installation of the libraries
18 | # Pulling in all the dependencies it will be able to run NPM AUDIT, and if that returns a
19 | # error code the job will fail.
20 | scan:
21 | runs-on: ubuntu-latest
22 | steps:
23 | - uses: actions/checkout@v4
24 | with:
25 | ref: ${{ inputs.ref }}
26 | - uses: actions/setup-node@v4
27 | with:
28 | node-version: 18
29 | - name: Install
30 | run: node common/scripts/install-run-rush.js install
31 | - name: Build packages
32 | run: node common/scripts/install-run-rush.js publish --include-all --pack --release-folder tgz --publish
33 | - name: Start local NPM registry
34 | run: node common/scripts/install-run-rush.js start-verdaccio # script will check for the ci variable and use built images
35 | - name: Deploy scan project
36 | run: |
37 | mkdir -p audit
38 | cd audit
39 | npm init --yes
40 | npm install --save --package-lock-only --registry http://localhost:4873 fabric-shim fabric-shim-api fabric-contract-api
41 | - name: Scan
42 | working-directory: audit
43 | run: npm audit --omit=dev
44 |
--------------------------------------------------------------------------------
/.github/workflows/schedule.yaml:
--------------------------------------------------------------------------------
1 | # Copyright the Hyperledger Fabric contributors. All rights reserved.
2 | # SPDX-License-Identifier: Apache-2.0
3 |
4 | name: Scheduled build
5 |
6 | on:
7 | schedule:
8 | - cron: "5 2 * * 6"
9 | workflow_dispatch:
10 |
11 | jobs:
12 | test:
13 | uses: ./.github/workflows/test.yaml
14 |
--------------------------------------------------------------------------------
/.github/workflows/vulnerability-scan.yaml:
--------------------------------------------------------------------------------
1 | name: "Security vulnerability scan"
2 |
3 | on:
4 | schedule:
5 | - cron: "55 2 * * *"
6 | workflow_dispatch:
7 |
8 | permissions:
9 | contents: read
10 |
11 | jobs:
12 | latest-release-version:
13 | name: Get latest release tag
14 | runs-on: ubuntu-latest
15 | outputs:
16 | tag_name: ${{ steps.tag-name.outputs.value }}
17 | steps:
18 | - id: tag-name
19 | run: echo "value=$(curl --location --silent --fail "https://api.github.com/repos/${GITHUB_REPOSITORY}/releases/latest" | jq --raw-output '.tag_name')" >> "${GITHUB_OUTPUT}"
20 |
21 | scan:
22 | name: Scan ${{ needs.latest-release-version.outputs.tag_name }}
23 | needs: latest-release-version
24 | uses: ./.github/workflows/scan.yaml
25 | with:
26 | ref: ${{ needs.latest-release-version.outputs.tag_name }}
27 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | coverage
2 | node_modules
3 | **/node_modules/*
4 | npm-debug.log
5 | .DS_Store
6 | test/.DS_Store
7 | # ignore vscode config
8 | .vscode
9 | # ignore webstorm config
10 | .idea
11 | yarn.lock
12 | .nyc_output
13 | **/typescript/*.js
14 | **/typescript/*.js.map
15 |
16 | fabric*.tgz
17 | install-fabric.sh
18 |
19 | libraries/fabric-ledger/lib
20 |
21 | # Crypto material
22 | tools/toolchain/network/crypto-material/*.block
23 | tools/toolchain/network/crypto-material/*.tx
24 | tools/toolchain/network/crypto-material/crypto-config
25 | tools/toolchain/network/crypto-material/core.yaml
26 |
27 | # Rush files
28 | common/temp/**
29 | **/.rush/temp/**
30 | **/*.build.error.log
31 | **/*.build.log
32 | **/*.test_fv.log
33 |
34 | package-deps.json
35 | test-results.xml
36 | docker.log
37 |
38 | # jsdoc output
39 | docs/gen
40 | fabric-samples
41 |
--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # SPDX-License-Identifier: Apache-2.0
2 |
3 | # Fabric Chaincode Node maintainers
4 | * @hyperledger/fabric-chaincode-node-maintainers
5 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | Code of Conduct Guidelines
2 | ==========================
3 |
4 | Please review the Hyperledger [Code of
5 | Conduct](https://wiki.hyperledger.org/community/hyperledger-project-code-of-conduct)
6 | before participating. It is important that we keep things civil.
7 |
8 | 
This work is licensed under a Creative Commons Attribution 4.0 International License.
9 |
--------------------------------------------------------------------------------
/COMPATIBILITY.md:
--------------------------------------------------------------------------------
1 | # Support and Compatibility
2 |
3 | Github is used for code base management and [issue](https://github.com/hyperledger/fabric-chaincode-node/issues) tracking.
4 |
5 | ## Summary of Compatibility
6 |
7 | This table shows the summary of the compatibility of the Node chaincode packages, together with the Node.js runtime they require.
8 |
9 | | Node chaincode version | Minimum supported Node.js | Node.js runtime | Docker image platforms |
10 | | ---------------------- | ------------------------- | --------------- | ---------------------- |
11 | | v1.4 | 8 | 8 | amd64 |
12 | | v2.2 | 12 | 12 | amd64 |
13 | | v2.5.0 - v2.5.4 | 18 | 18 | amd64, arm64 |
14 | | v2.5.5 - v2.5.7 | 18 | 20 | amd64, arm64 |
15 | | v2.5.8+ | 18 | 22 | amd64, arm64 |
16 |
17 | The Node runtime provided by the chaincode Docker image determines the maximum Node version (and features) that smart contract code can exploit when using the default Node chaincode container.
18 |
19 | Subject to a suitable runtime environment, the Node chaincode libraries can be used to communicate with Fabric peers at different LTS versions. The level of functionality is determined by the Fabric version in use and channel capabilities.
20 |
21 | All Docker images, chaincode libraries and tools are tested using amd64 (x86-64) only.
22 |
23 | ## Chaincode builder
24 |
25 | The default Fabric chaincode builder creates a Docker container to run deployed smart contracts. Node chaincode Docker containers are built using the `hyperledger/fabric-nodeenv` Docker image, tagged with the same major and minor version as the Fabric peer version. For example, Fabric v2.5 creates Node chaincode containers using the `hyperledger/fabric-nodeenv:2.5` Docker image. Fabric v3 continues to use the v2.5 Node chaincode image.
26 |
27 | A different chaincode Docker image can be specified using the CORE_CHAINCODE_NODE_RUNTIME environment variable on the Fabric peer. For example, CORE_CHAINCODE_NODE_RUNTIME=example/customNodeRuntime:latest.
28 |
29 | With Fabric v2 and later, an alternative chaincode builder can be configured on the Fabric peer. In this case the configured chaincode builder controls how chaincode is launched. See the [Fabric documentation](https://hyperledger-fabric.readthedocs.io/en/release-2.5/cc_launcher.html) for further details.
30 |
31 | ## Chaincode packaging
32 |
33 | When using the `hyperledger/fabric-nodeenv` Node chaincode Docker images at v2 (and later), deployed chaincode is installed with npm as follows:
34 |
35 | - If a `package-lock.json` or a `npm-shrinkwrap.json` file is present, `npm ci --only=production` will be used.
36 | - Otherwise, `npm install --production` will be used.
37 |
38 | When using the v1.4 `hyperledger/fabric-nodeenv` Node chaincode Docker images, deployed chaincode is installed with `npm install --production`.
39 |
--------------------------------------------------------------------------------
/MAINTAINERS.md:
--------------------------------------------------------------------------------
1 | # Maintainers
2 |
3 | **Active maintainers**
4 |
5 | | Name | GitHub | Chat | email |
6 | | ------------ | ---------------------------------- | --------------- | -------------------------- |
7 | | Dave Enyeart | [denyeart][denyeart] | denyeart | |
8 | | Mark Lewis | [bestbeforetoday][bestbeforetoday] | bestbeforetoday | |
9 |
10 | **Emeritus maintainers**
11 |
12 | | Name | GitHub | Chat | email |
13 | | --------------- | -------------------------- | ------------ | -------------------------- |
14 | | Matthew B White | [mbwhite][mbwhite] | mbwhite | |
15 | | James Taylor | [jt-nti][jt-nti] | jtonline | |
16 | | Andrew Hurt | [awjh-ibm][awjh-ibm] | awjh-ibm | |
17 | | Bret Harrison | [harrisob][harrisob] | bretharrison | |
18 | | Chaoyi Zhao | [zhaochy1990][zhaochy1990] | zhaochy | |
19 | | David Kelsey | [davidkel][davidkel] | davidkel | |
20 |
21 | Also: Please see the [Release Manager section](https://github.com/hyperledger/fabric/blob/main/MAINTAINERS.md)
22 |
23 | 
This work is licensed under a Creative Commons Attribution 4.0 International License.
24 |
25 | [awjh-ibm]: https://github.com/awjh-ibm
26 | [harrisob]: https://github.com/harrisob
27 | [zhaochy1990]: https://github.com/zhaochy1990
28 | [davidkel]: https://github.com/davidkel
29 | [mbwhite]: https://github.com/mbwhite
30 | [jt-nti]: https://github.com/jt-nti
31 | [bestbeforetoday]: https://github.com/bestbeforetoday
32 | [denyeart]: https://github.com/denyeart
33 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Hyperledger Fabric - Node.js Contracts
2 |
3 | [](https://dev.azure.com/Hyperledger/Fabric-Chaincode-Node/_build/latest?definitionId=33&branchName=main)
4 | [](https://www.npmjs.com/package/fabric-contract-api)
5 | [](https://www.npmjs.com/package/fabric-shim)
6 | [](https://www.npmjs.com/package/fabric-shim-api)
7 | [](https://discordapp.com/channels/905194001349627914/943090527920877598)
8 |
9 | This is the project to support the writing of Contracts with the node.js runtime.
10 |
11 | ## Documentation
12 |
13 | As an application developer, to learn about how to implement **"Smart Contracts"** for Hyperledger Fabric using Node.js, please visit the [API documentation](https://hyperledger.github.io/fabric-chaincode-node/) and follow the tutorial links.
14 |
15 | - [API documentation](https://hyperledger.github.io/fabric-chaincode-node/)
16 | - [Full Documenation on Hyperledger Fabric](https://hyperledger-fabric.readthedocs.io/)
17 | - [Samples repository](https://github.com/hyperledger/fabric-samples)
18 | - [Quick-start tutorial](TUTORIAL.md)
19 |
20 | ## Compatibility
21 |
22 | For details on what Nodejs runtime and versions of Hyperledger Fabric can be used please see the [compatibility document](COMPATIBILITY.md).
23 |
24 | ## npm Shrinkwrap
25 |
26 | In line with the advice from [npm on shrinkwrap](https://docs.npmjs.com/cli/v8/configuring-npm/npm-shrinkwrap-json) the modules published do not contain a `npm-shrinkwrap.json` file.
27 |
28 | It is **STRONGLY** recommended therefore that after testing, and before putting your contract into production a `npm-shrinkwrap.json` file is created. When the chaincode is install it will be via a `npm install --production` command.
29 |
30 | ## Contributing
31 |
32 | If you are interested in contributing updates to this project, please start with the [contributing guide](CONTRIBUTING.md).
33 |
34 | There is also a [release guide](RELEASING.md) describing the process for publishing new versions.
35 |
36 | ---
37 |
38 | ## License
39 |
40 | Hyperledger Project source code files are made available under the Apache
41 | License, Version 2.0 (Apache-2.0), located in the [LICENSE](LICENSE) file.
42 | Hyperledger Project documentation files are made available under the Creative
43 | Commons Attribution 4.0 International License (CC-BY-4.0), available at http://creativecommons.org/licenses/by/4.0/.
44 |
--------------------------------------------------------------------------------
/RELEASING.md:
--------------------------------------------------------------------------------
1 | # Releasing
2 |
3 | The following artifacts are created as a result of releasing Fabric Chaincode Node:
4 |
5 | - docker images
6 | - [fabric-nodeenv](https://hub.docker.com/r/hyperledger/fabric-nodeenv)
7 | - npm modules
8 | - [fabric-contract-api](https://www.npmjs.com/package/fabric-contract-api)
9 | - [fabric-shim](https://www.npmjs.com/package/fabric-shim)
10 | - [fabric-shim-api](https://www.npmjs.com/package/fabric-shim-api)
11 |
12 | **Note:** A docker image with a matching V.R version is required before releasing a new version of Fabric.
13 |
14 | ## Before releasing
15 |
16 | It's useful to create an issue to keep track of each release, for example [FABCN-377 Release v2.0.0 chaincode-node](https://jira.hyperledger.org/browse/FABCN-377).
17 |
18 | The following tasks are required before releasing:
19 |
20 | - Update version numbers in package.json files to the required version
21 | - Update `tag` in package.json files to the required value, e.g. `beta`, or `latest`
22 | - Update test, sample, and docs files to match the new version
23 | - Create a new release notes file
24 | - Update the `CHANGELOG.md` file
25 |
26 | The `changelog.sh` script in `tools/scripts` will prepopulate the changelog but you must check and edit the file manually afterwards as required
27 |
28 | The `tools/scripts/updateversions.sh` script will update the version in all the `package.json` files. Pass the new version as the first argument.
29 |
30 | ```bash
31 | ./tools/scripts/updateversions.sh 2.4.1
32 | ```
33 |
34 | See the [Prepare 2.1.4 release](https://github.com/hyperledger/fabric-chaincode-node/pull/174) pull request for an example, although be careful to search for all versions in the codebase as they're easy to miss and things change!
35 |
36 | ## Create release
37 |
38 | Creating a GitHub release on the [releases page](https://github.com/hyperledger/fabric-chaincode-node/releases) will trigger the build to publish the new release.
39 |
40 | When drafting the release, create a new tag for the new version (with a `v` prefix), e.g. `v2.1.4`
41 |
42 | See previous releases for examples of the title and description.
43 |
44 | ## After releasing
45 |
46 | - Update version numbers in package.json files to the next version appended with a `-unstable` pre-release label. e.g. `1.2.3-unstable`
47 | - Update `tag` in package.json files to `unstable`
48 | - Update test, sample, and docs files to match the new version
49 |
50 | See the [Bump version to 2.1.5](https://github.com/hyperledger/fabric-chaincode-node/pull/175) pull request for an example. It should include almost all the files changed to prepare for the release, except for the release notes and changelog which do not need updating.
51 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Hyperledger Security Policy
2 |
3 | ## Reporting a Security Bug
4 |
5 | If you think you have discovered a security issue in any of the Hyperledger projects, we'd love to hear from you. We will take all security bugs seriously and if confirmed upon investigation we will patch it within a reasonable amount of time and release a public security bulletin discussing the impact and credit the discoverer.
6 |
7 | There are two ways to report a security bug. The easiest is to email a description of the flaw and any related information (e.g. reproduction steps, version) to [security at hyperledger dot org](mailto:security@hyperledger.org).
8 |
9 | The other way is to file a confidential security bug in our [JIRA bug tracking system](https://jira.hyperledger.org). Be sure to set the “Security Level” to “Security issue”.
10 |
11 | The process by which the Hyperledger Security Team handles security bugs is documented further in our [Defect Response page](https://wiki.hyperledger.org/display/SEC/Defect+Response) on our [wiki](https://wiki.hyperledger.org).
12 |
13 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/.npmignore:
--------------------------------------------------------------------------------
1 | test
2 | fabric-contract-api*.tgz
--------------------------------------------------------------------------------
/apis/fabric-contract-api/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 |
8 | /**
9 | * This is the class that all contracts should extend. A Smart Contract will consist of one or more of these
10 | * @see {@link fabric-contract-api.Contract}
11 | */
12 | module.exports.Contract = require('./lib/contract.js');
13 | module.exports.Context = require('./lib/context.js');
14 |
15 | Object.assign(module.exports, require('./lib/annotations'));
16 |
17 | module.exports.JSONSerializer = require('./lib/jsontransactionserializer.js');
18 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/lib/annotations/default.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | const Logger = require('../logger');
8 | const logger = Logger.getLogger('./lib/annotations/default.js');
9 | require('reflect-metadata');
10 |
11 | module.exports.Default = function Default () {
12 |
13 | return (target) => {
14 | logger.info('@Default args:', 'Target ->', target.name);
15 |
16 | let dflt = Reflect.getMetadata('fabric:default', global);
17 |
18 | logger.debug('Existing fabric:default', dflt);
19 |
20 | if (dflt) {
21 | throw new Error('A default has already been specified');
22 | }
23 |
24 | const contract = new(target);
25 |
26 | dflt = contract.getName();
27 |
28 | Reflect.defineMetadata('fabric:default', dflt, global);
29 |
30 | logger.debug('Updated fabric:default', dflt);
31 | };
32 | };
33 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/lib/annotations/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | 'use strict';
8 | Object.assign(module.exports, require('./transaction'), require('./object'), require('./info'), require('./default'));
9 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/lib/annotations/info.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | const Logger = require('../logger');
8 | const logger = Logger.getLogger('./lib/annotations/info.js');
9 | require('reflect-metadata');
10 |
11 | module.exports.Info = function Info (info = {}) {
12 | return (target) => {
13 | logger.info('@Info args:', `Info -> ${info},`, 'Target ->', target.name);
14 |
15 | const data = Reflect.getMetadata('fabric:info', global) || {};
16 |
17 | logger.debug('Existing fabric:info', data);
18 |
19 | if (!info.name) {
20 | info.name = target.name;
21 | }
22 | if (!info.version) {
23 | info.version = '';
24 | }
25 |
26 | data[target.name] = {};
27 | Object.assign(data[target.name], info);
28 |
29 | Reflect.defineMetadata('fabric:info', data, global);
30 |
31 | logger.debug('Updated fabric:info', data);
32 | };
33 | };
34 |
35 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/lib/annotations/object.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | const Logger = require('../logger');
8 | const logger = Logger.getLogger('./lib/annotations/object.js');
9 | const utils = require('./utils');
10 | require('reflect-metadata');
11 |
12 | const getProto = function (prototype) {
13 | return Object.getPrototypeOf(prototype);
14 | };
15 |
16 | module.exports.Object = function Object (opts) {
17 | return (target) => {
18 | logger.info('@Object args: Target -> %s', target.constructor.name);
19 |
20 | const objects = Reflect.getMetadata('fabric:objects', global) || {};
21 |
22 | logger.debug('Existing fabric:objects %s', objects);
23 |
24 | const properties = Reflect.getMetadata('fabric:object-properties', target.prototype) || {};
25 |
26 | logger.debug('Existing fabric:object-properties for target', properties);
27 |
28 | // check for the presence of a supertype
29 | const supertype = getProto(target.prototype).constructor.name;
30 |
31 | if (supertype === 'Object') {
32 | objects[target.name] = {
33 | '$id': target.name,
34 | type: 'object',
35 | cnstr: target,
36 | properties: properties
37 | };
38 |
39 | // add in the discriminator property name if one has been supplied in the object annotations
40 | if (opts && opts.discriminator) {
41 | objects[target.name].discriminator = {propertyName: opts.discriminator};
42 | }
43 | } else {
44 | objects[target.name] = {
45 | '$id': target.name,
46 | cnstr: target,
47 | allOf: [
48 | {
49 | type: 'object',
50 | properties: properties
51 | },
52 | {
53 | '$ref': `${supertype}`
54 | }
55 | ]
56 | };
57 | }
58 |
59 | Reflect.defineMetadata('fabric:objects', objects, global);
60 |
61 | logger.debug('Updated fabric:objects', objects);
62 | };
63 | };
64 |
65 | module.exports.Property = function Property (name, type) {
66 | return (target, propertyKey) => {
67 | logger.debug('@Property args:', `Property Key -> ${propertyKey}, Name -> ${name}, Type -> ${type},`, 'Target ->', target.constructor.name);
68 |
69 | const properties = Reflect.getOwnMetadata('fabric:object-properties', target) || {};
70 |
71 | logger.debug('Existing fabric:object-properties for target', properties);
72 |
73 | if (!name || !type) {
74 | name = propertyKey;
75 |
76 | const metaType = Reflect.getMetadata('design:type', target, propertyKey);
77 | type = typeof metaType === 'function' ? metaType.name : metaType.toString();
78 | }
79 |
80 | properties[name] = utils.generateSchema(type, false);
81 |
82 | Reflect.defineMetadata('fabric:object-properties', properties, target);
83 |
84 | logger.debug('Updated fabric:object-properties for target', properties);
85 | };
86 | };
87 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/lib/annotations/utils.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | const refPath = '#/components/schemas/';
8 |
9 | module.exports.appendOrUpdate = function appendOrUpdate(arr, primaryField, id, data) {
10 | const objExists = arr.some((obj) => {
11 | if (obj[primaryField] === id) {
12 | Object.assign(obj, data);
13 | return true;
14 | }
15 | });
16 |
17 | if (!objExists) {
18 | const obj = data;
19 | data[primaryField] = id;
20 | arr.push(obj);
21 | }
22 | };
23 |
24 | module.exports.findByValue = function findByValue(arr, primaryField, id) {
25 | for (const el of arr) {
26 | if (el[primaryField] === id) {
27 | return el;
28 | }
29 | }
30 |
31 | return null;
32 | };
33 |
34 | const generateSchema = (type, fullPath = true) => {
35 | if (isPrimitive(type)) {
36 | return {
37 | type: type.toLowerCase()
38 | };
39 | } else if (isArray(type)) {
40 | const subType = getSubArray(type);
41 |
42 | return {
43 | type: 'array',
44 | items: generateSchema(subType, fullPath)
45 | };
46 | } else if (isMap(type)) {
47 | const subType = getSubMap(type);
48 |
49 | return {
50 | type: 'object',
51 | additionalProperties: generateSchema(subType, fullPath)
52 | };
53 | }
54 |
55 | return {
56 | $ref: (fullPath ? refPath : '') + type
57 | };
58 | };
59 | module.exports.generateSchema = generateSchema;
60 |
61 | // there appears to be confusions within the meta data handling
62 | // whether string or String is correct.
63 | // string is the preferred for JSON Schema
64 | function isPrimitive(type) {
65 | const lowerCase = type.toLowerCase();
66 | switch (lowerCase) {
67 | case 'string':
68 | case 'number':
69 | case 'boolean':
70 | return lowerCase;
71 |
72 | default:
73 | return undefined;
74 | }
75 | }
76 |
77 | // Like Array
78 | function isArrowedArray(type) {
79 | return /^Array<[A-z].*>$/.test(type);
80 | }
81 |
82 | // Like number[]
83 | function isBracketArray(type) {
84 | return /^[A-z].*(\[\])+?/.test(type);
85 | }
86 |
87 | // determine if string representation of type
88 | // is in format of an arrray descriptor
89 | function isArray(type) {
90 | return isArrowedArray(type) || isBracketArray(type);
91 | }
92 |
93 | function getSubArray(type) {
94 | if (isArrowedArray(type)) {
95 | return type.replace('Array<', '').replace('>', '');
96 | }
97 |
98 | return type.replace('[]', '');
99 | }
100 |
101 | function isMap(type) {
102 | return /^Map<[A-z].*,\s?[A-z].*>$/.test(type);
103 | }
104 |
105 | function getSubMap(type) {
106 | return type.replace(/^Map<[A-z].*?,\s?/, '').replace('>', '');
107 | }
108 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/lib/context.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | 'use strict';
8 |
9 | /**
10 | * The Context class provides the transactional context per a transactional execution.
11 | *
12 | * This can be subclassed to provided additional functional behaviour to support
13 | * smart contract execution.
14 | *
15 | * An example would be to provide additional help to map application object ids to world state
16 | * composite keys.
17 | *
18 | * In the constructor, do not reference the stub or clientidentity functions.
19 | *
20 | * @example
21 | * class ScenarioContext extends Context{
22 |
23 | constructor(){
24 | super();
25 | }
26 |
27 |
28 | generateKey(){
29 | return this.stub.createCompositeKey('type',['keyvalue']);
30 | }
31 |
32 | }
33 | *
34 | * @memberof fabric-contract-api
35 | */
36 | class Context {
37 |
38 | constructor() {
39 | }
40 |
41 | /**
42 | * This sets the chaincode stub object with api to use for worldstate access.
43 | * MUST NOT BE CALLED FROM SMART CONTRACT CODE
44 | *
45 | * @param {ChaincodeStub} stub chaincode stub instance
46 | */
47 | setChaincodeStub(stub) {
48 | this.stub = stub;
49 | }
50 |
51 | /**
52 | * This sets the ClientIdentity object to use for information on the transaction invoking identity
53 | * MUST NOT BE CALLED FROM SMART CONTRACT CODE
54 | *
55 | * @param {ClientIdentity} clientIdentity chaincode stub instance
56 | */
57 | setClientIdentity(clientIdentity) {
58 | this.clientIdentity = clientIdentity;
59 | }
60 | }
61 |
62 | module.exports = Context;
63 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fabric-contract-api",
3 | "version": "2.5.9",
4 | "tag": "latest",
5 | "description": "A node.js implementation of Hyperledger Fabric chaincode shim, to allow endorsing peers and user-provided chaincodes to communicate with each other",
6 | "main": "index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "https://github.com/hyperledger/fabric-chaincode-node"
10 | },
11 | "scripts": {
12 | "buildt": "tsc --project test/typescript",
13 | "test": "nyc mocha --recursive 'test/unit/**/*.js'",
14 | "build": "npm run lint && npm run test:unit && npm run test:schema",
15 | "lint": "eslint ./lib ./types ./test/typescript/*.ts --ext .js --ext .ts",
16 | "test:unit": "npm run test",
17 | "test:schema": "ajv compile -s ./schema/contract-schema.json && ajv validate -s ./schema/contract-schema.json -d ./schema/example-full.json"
18 | },
19 | "keywords": [
20 | "fabric-shim",
21 | "Hyperledger Fabric",
22 | "Fabric Shim"
23 | ],
24 | "engines": {
25 | "node": ">=18"
26 | },
27 | "license": "Apache-2.0",
28 | "types": "./types/index.d.ts",
29 | "nyc": {
30 | "exclude": [
31 | "coverage/**",
32 | "test/**",
33 | "gulpfile.js"
34 | ],
35 | "reporter": [
36 | "text-summary",
37 | "html",
38 | "cobertura"
39 | ],
40 | "all": true,
41 | "check-coverage": true,
42 | "statements": 100,
43 | "branches": 100,
44 | "functions": 100,
45 | "lines": 100
46 | },
47 | "dependencies": {
48 | "fabric-shim-api": "2.5.9",
49 | "class-transformer": "^0.4.0",
50 | "fast-safe-stringify": "^2.1.1",
51 | "get-params": "^0.1.2",
52 | "reflect-metadata": "^0.1.13",
53 | "winston": "^3.7.2"
54 | },
55 | "devDependencies": {
56 | "ajv": "^6.12.2",
57 | "ajv-cli": "^3.2.1",
58 | "ajv-formats": "2.1.1",
59 | "chai": "^4.3.4",
60 | "chai-as-promised": "^7.1.1",
61 | "chai-things": "^0.2.0",
62 | "eslint": "^6.6.0",
63 | "gulp": "^4.0.2",
64 | "gulp-debug": "~4.0.0",
65 | "gulp-eslint": "~6.0.0",
66 | "mocha": "9.1.3",
67 | "nyc": "15.1.0",
68 | "rewire": "6.0.0",
69 | "sinon": "13.0.1",
70 | "typescript": "4.4.4"
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/schema/data.json:
--------------------------------------------------------------------------------
1 | {
2 | "firstName": "John",
3 | "lastName": "Doe",
4 | "age": 21
5 | }
--------------------------------------------------------------------------------
/apis/fabric-contract-api/schema/helloworld.json:
--------------------------------------------------------------------------------
1 | {
2 | "contracts": {
3 | "Greeting": {
4 | "name": "Greeting",
5 | "contractInstance": {
6 | "name": "Greeting"
7 | },
8 | "transactions": [
9 | {
10 | "tag": [
11 | "SUBMIT",
12 | "submitTx"
13 | ],
14 | "parameters": [],
15 | "name": "instantiate"
16 | },
17 | {
18 | "tag": [
19 | "SUBMIT",
20 | "submitTx"
21 | ],
22 | "parameters": [
23 | {
24 | "name": "text",
25 | "description": "",
26 | "schema": {
27 | "type": "string"
28 | }
29 | }
30 | ],
31 | "name": "setGreetingText"
32 | },
33 | {
34 | "tag": [
35 | "SUBMIT",
36 | "submitTx"
37 | ],
38 | "parameters": [
39 | {
40 | "name": "greeting",
41 | "description": "",
42 | "schema": {
43 | "$ref": "#/components/schemas/greeting"
44 | }
45 | }
46 | ],
47 | "name": "setGreeting"
48 | },
49 | {
50 | "returns": [
51 | {
52 | "name": "success",
53 | "schema": {
54 | "$ref": "#/components/schemas/greeting"
55 | }
56 | }
57 | ],
58 | "name": "getGreeting",
59 | "tag": [
60 | "SUBMIT",
61 | "submitTx"
62 | ],
63 | "parameters": []
64 | }
65 | ],
66 | "info": {
67 | "title": "",
68 | "version": ""
69 | }
70 | },
71 | "org.hyperledger.fabric": {
72 | "name": "org.hyperledger.fabric",
73 | "contractInstance": {
74 | "name": "org.hyperledger.fabric"
75 | },
76 | "transactions": [
77 | {
78 | "name": "setMetadata"
79 | },
80 | {
81 | "name": "GetMetadata"
82 | }
83 | ],
84 | "info": {
85 | "title": "",
86 | "version": ""
87 | }
88 | }
89 | },
90 | "info": {
91 | "version": "0.0.1",
92 | "title": "helloworld-ts"
93 | },
94 | "components": {
95 | "schemas": {
96 | "Greeting": {
97 | "$id": "Greeting",
98 | "properties": [
99 | {
100 | "name": "text",
101 | "schema": {
102 | "type": "string"
103 | }
104 | }
105 | ]
106 | }
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/schema/testschema.json:
--------------------------------------------------------------------------------
1 | {
2 | "$id": "https://example.com/person.schema.json",
3 | "$schema": "http://json-schema.org/draft-04/schema#",
4 | "title": "Person",
5 | "type": "object",
6 | "properties": {
7 | "firstName": {
8 | "type": "string",
9 | "description": "The person's first name."
10 | },
11 | "lastName": {
12 | "type": "string",
13 | "description": "The person's last name."
14 | },
15 | "age": {
16 | "description": "Age in years which must be equal to or greater than zero.",
17 | "type": "integer",
18 | "minimum": 0
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/test/typescript/smartcontract.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2018 IBM All Rights Reserved.
3 |
4 | SPDX-License-Identifier: Apache-2.0
5 |
6 | */
7 |
8 | import {Contract, Context} from 'fabric-contract-api';
9 | import {ChaincodeStub, ClientIdentity} from 'fabric-shim-api';
10 |
11 | export class ScenarioContext extends Context {
12 | customFunction(): void {
13 |
14 | }
15 | }
16 |
17 | export default class TestContractOne extends Contract {
18 | constructor() {
19 | super('org.papernet.commercialpaper');
20 | }
21 |
22 | beforeTransaction(ctx: ScenarioContext) {
23 | // test that the context super class properties are available
24 | const stubApi: ChaincodeStub = ctx.stub;
25 | const clientIdentity: ClientIdentity = ctx.clientIdentity;
26 |
27 | // tests that the functions in the subclasses context be called
28 | ctx.customFunction();
29 |
30 | // This proves that typescript is enforcing the
31 | // return type of Promise
32 | return Promise.resolve();
33 | }
34 |
35 | afterTransaction(ctx: ScenarioContext, result: any) {
36 | // This proves that typescript is enforcing the
37 | // return type of Promise
38 | return Promise.resolve();
39 | }
40 |
41 | aroundTransaction(ctx: ScenarioContext, fn: Function, parameters: any) {
42 | // This proves that typescript is enforcing the
43 | // return type of Promise
44 | return super.aroundTransaction(ctx, fn, parameters);
45 | }
46 |
47 | unknownTransaction(ctx: ScenarioContext) {
48 | // This proves that typescript is enforcing the
49 | // return type of Promise
50 | return Promise.resolve();
51 | }
52 |
53 | createContext() {
54 | return new ScenarioContext();
55 | }
56 |
57 | async Transaction(ctx: ScenarioContext) {
58 | // test that the context super class properties are available
59 | const stubApi: ChaincodeStub = ctx.stub;
60 | const clientIdentity: ClientIdentity = ctx.clientIdentity;
61 |
62 | // test that the name returns a string
63 | const ns: string = this.getName();
64 | }
65 | }
66 |
67 | export class TestContractTwo extends Contract {
68 | constructor() {
69 | super();
70 | }
71 |
72 | async Transaction(ctx: Context) {
73 | const stubApi: ChaincodeStub = ctx.stub;
74 | const clientIdentity: ClientIdentity = ctx.clientIdentity;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/test/unit/annotations/default.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | const sinon = require('sinon');
8 | const rewire = require('rewire');
9 |
10 | const chai = require('chai');
11 | const expect = chai.expect;
12 |
13 | const DefaultAnnotations = rewire('./../../../lib/annotations/default');
14 | const Default = DefaultAnnotations.Default;
15 |
16 | describe ('Default.js', () => {
17 |
18 | const mockTarget = class {
19 | constructor() {}
20 |
21 | getName() {
22 | return 'jeremy';
23 | }
24 | };
25 |
26 | let defineMetadataStub;
27 | let getMetadataStub;
28 | beforeEach(() => {
29 | getMetadataStub = sinon.stub(Reflect, 'getMetadata');
30 | defineMetadataStub = sinon.stub(Reflect, 'defineMetadata');
31 | });
32 |
33 | afterEach(() => {
34 | getMetadataStub.restore();
35 | defineMetadataStub.restore();
36 | });
37 |
38 | describe('Default', () => {
39 |
40 | let dflt;
41 |
42 | beforeEach(() => {
43 | dflt = Default();
44 | });
45 |
46 | it ('should add set value for default when none set', () => {
47 | getMetadataStub
48 | .onFirstCall().returns(undefined);
49 |
50 | dflt(mockTarget);
51 |
52 | sinon.assert.calledOnce(getMetadataStub);
53 | sinon.assert.calledWith(getMetadataStub, 'fabric:default', global);
54 | sinon.assert.calledOnce(defineMetadataStub);
55 | sinon.assert.calledWith(defineMetadataStub, 'fabric:default',
56 | 'jeremy'
57 | );
58 | });
59 |
60 | it ('should error when default already set', () => {
61 | getMetadataStub
62 | .onFirstCall().returns('theresa');
63 |
64 | expect(() => {
65 | dflt(mockTarget);
66 | }).to.throw('A default has already been specified');
67 |
68 | sinon.assert.calledOnce(getMetadataStub);
69 | sinon.assert.calledWith(getMetadataStub, 'fabric:default', global);
70 | sinon.assert.notCalled(defineMetadataStub);
71 | });
72 | });
73 | });
74 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/test/unit/annotations/info.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | const sinon = require('sinon');
8 | const rewire = require('rewire');
9 |
10 | const InfoAnnotations = rewire('./../../../lib/annotations/info');
11 | const Info = InfoAnnotations.Info;
12 |
13 |
14 | describe ('Info.js', () => {
15 |
16 | const mockTarget = {
17 | name: 'steve'
18 | };
19 |
20 | let defineMetadataStub;
21 | let getMetadataStub;
22 | beforeEach(() => {
23 | getMetadataStub = sinon.stub(Reflect, 'getMetadata');
24 | defineMetadataStub = sinon.stub(Reflect, 'defineMetadata');
25 | });
26 |
27 | afterEach(() => {
28 | getMetadataStub.restore();
29 | defineMetadataStub.restore();
30 | });
31 |
32 | describe('Info', () => {
33 |
34 | let info;
35 |
36 | beforeEach(() => {
37 | info = Info();
38 | });
39 |
40 | it ('should add object as key when no objects exist for global yet', () => {
41 | getMetadataStub
42 | .onFirstCall().returns(undefined);
43 |
44 | info(mockTarget);
45 |
46 | sinon.assert.calledOnce(getMetadataStub);
47 | sinon.assert.calledWith(getMetadataStub, 'fabric:info', global);
48 | sinon.assert.calledOnce(defineMetadataStub);
49 | sinon.assert.calledWith(defineMetadataStub, 'fabric:info',
50 | {steve: {name: 'steve', version: ''}}
51 | );
52 | });
53 |
54 | it ('should add object as key when objects exist for global', () => {
55 | getMetadataStub
56 | .onFirstCall().returns({'object1': {}});
57 |
58 | info(mockTarget);
59 |
60 | sinon.assert.calledOnce(getMetadataStub);
61 | sinon.assert.calledWith(getMetadataStub, 'fabric:info', global);
62 | sinon.assert.calledOnce(defineMetadataStub);
63 | sinon.assert.calledWith(defineMetadataStub, 'fabric:info', {
64 | 'object1': {},
65 | 'steve': {name: 'steve', version: ''}
66 | });
67 | });
68 | });
69 | describe('Info with data', () => {
70 |
71 | let info;
72 |
73 | beforeEach(() => {
74 | info = Info({name: 'bill', version: '1.0.1'});
75 | });
76 |
77 | it ('should add object as key when no objects exist for global yet', () => {
78 | getMetadataStub
79 | .onFirstCall().returns(undefined);
80 |
81 | info(mockTarget);
82 |
83 | sinon.assert.calledOnce(getMetadataStub);
84 | sinon.assert.calledWith(getMetadataStub, 'fabric:info', global);
85 | sinon.assert.calledOnce(defineMetadataStub);
86 | sinon.assert.calledWith(defineMetadataStub, 'fabric:info',
87 | {steve: {name: 'bill', version: '1.0.1'}}
88 | );
89 | });
90 |
91 | it ('should add object as key when objects exist for global', () => {
92 | getMetadataStub
93 | .onFirstCall().returns({'object1': {}});
94 |
95 | info(mockTarget);
96 |
97 | sinon.assert.calledOnce(getMetadataStub);
98 | sinon.assert.calledWith(getMetadataStub, 'fabric:info', global);
99 | sinon.assert.calledOnce(defineMetadataStub);
100 | sinon.assert.calledWith(defineMetadataStub, 'fabric:info', {
101 | 'object1': {},
102 | 'steve': {name: 'bill', version: '1.0.1'}
103 | });
104 | });
105 | });
106 | });
107 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/test/unit/context.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /* global describe it beforeEach afterEach */
8 | 'use strict';
9 |
10 | const chai = require('chai');
11 | chai.should();
12 |
13 | chai.use(require('chai-as-promised'));
14 | chai.use(require('chai-things'));
15 | const sinon = require('sinon');
16 |
17 | const path = require('path');
18 | // class under test
19 | const pathToRoot = '../../..';
20 |
21 | const Context = require(path.join(pathToRoot, 'fabric-contract-api/lib/context'));
22 |
23 | describe('contract.js', () => {
24 |
25 | let sandbox;
26 |
27 | beforeEach('Sandbox creation', () => {
28 | sandbox = sinon.createSandbox();
29 | });
30 |
31 | afterEach('Sandbox restoration', () => {
32 | sandbox.restore();
33 | });
34 |
35 | describe('#constructor', () => {
36 |
37 | it ('should create plain object ok', () => {
38 | const sc0 = new Context();
39 | sc0.should.be.an.instanceOf(Context);
40 | });
41 |
42 | it ('should have set* methods', () => {
43 | const sc0 = new Context();
44 | sc0.setChaincodeStub('a stub');
45 | sc0.stub.should.equal('a stub');
46 | sc0.setClientIdentity('a client identity');
47 | sc0.clientIdentity.should.equal('a client identity');
48 | });
49 |
50 | });
51 |
52 | });
53 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/test/unit/data.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger/fabric-chaincode-node/96d934ee63fc7fc19de817dc5eb05f04b0306b55/apis/fabric-contract-api/test/unit/data.json
--------------------------------------------------------------------------------
/apis/fabric-contract-api/test/unit/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | 'use strict';
8 |
9 | require('../../index.js');
10 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/tsconfig.json:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 IBM All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 | {
7 | "compilerOptions": {
8 | "types": ["./types/"],
9 | "alwaysStrict": true,
10 | "module": "commonjs",
11 | "declaration": true,
12 | "sourceMap": true,
13 | "strict": true,
14 | "target": "es2017",
15 | "lib": [
16 | "esnext",
17 | ]
18 | },
19 | "include": [
20 | "lib/**/*",
21 | "test/**/*"
22 | ],
23 | "exclude": [
24 | "node_modules/**/*"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/apis/fabric-contract-api/types/index.d.ts:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2018 IBM All Rights Reserved.
3 |
4 | SPDX-License-Identifier: Apache-2.0
5 |
6 | */
7 |
8 | declare module 'fabric-contract-api' {
9 | import {Logger} from 'winston';
10 | import {ChaincodeStub, ClientIdentity} from 'fabric-shim-api';
11 |
12 | export class Context {
13 | stub: ChaincodeStub;
14 | clientIdentity: ClientIdentity;
15 | logging: {
16 | setLevel: (level: string) => void,
17 | getLogger: (name?: string) => Logger
18 | }
19 | }
20 |
21 | export class Contract {
22 | constructor(name?: string);
23 |
24 | static _isContract(): boolean;
25 |
26 | beforeTransaction(ctx : Context): Promise;
27 | afterTransaction(ctx : Context, result: any): Promise;
28 | aroundTransaction(ctx : Context, fn : Function, parameters: any): Promise;
29 |
30 | unknownTransaction(ctx : Context): Promise;
31 |
32 | createContext(): Context;
33 | getName(): string;
34 |
35 | }
36 |
37 |
38 | export class JSONSerializer {
39 | toBuffer(result: any, schema:any, loggerPrefix?:string): Buffer;
40 | fromBuffer(data: Buffer, schema:any, loggerPrefix?:string): any;
41 | }
42 |
43 | export function Transaction(commit?: boolean): (target: any, propertyKey: string | symbol) => void;
44 | export function Param(paramName: string, paramType: string, description?: string): (target: any, propertyKey: string | symbol) => void;
45 | export function Returns(returnType?: string): (target: any, propertyKey: string | symbol) => void;
46 | export function Object(opts?: object): (target: any) => void;
47 | export function Info(info?: object): (target: any) => void;
48 | export function Property(name?: string, type?: string): (target: any, propertyKey: string | symbol) => void;
49 | export function Default(): (target: any) => void;
50 | }
51 |
--------------------------------------------------------------------------------
/apis/fabric-shim-api/README.md:
--------------------------------------------------------------------------------
1 | [](https://nodei.co/npm/fabric-shim-api/)
2 |
3 |
4 | [](http://badge.fury.io/js/fabric-shim-api)
5 |
6 | This `fabric-shim-api` library provides type definitions for the `fabric-shim` module. It is also a dependency of the `fabric-contract-api` As this is a pure interface module it allows the `fabric-contract-api` annotations to be used in client application without the need to pull in unneeded required dependencies.
7 |
8 | Detailed explanation on the concepts and programming model can be found here: [https://hyperledger-fabric.readthedocs.io/en/latest/smartcontract/smartcontract.html](https://hyperledger-fabric.readthedocs.io/en/latest/smartcontract/smartcontract.html).
9 |
10 |
11 | ## License
12 |
13 | This package is distributed under the
14 | [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0),
15 | see LICENSE for more information.
16 |
--------------------------------------------------------------------------------
/apis/fabric-shim-api/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
--------------------------------------------------------------------------------
/apis/fabric-shim-api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fabric-shim-api",
3 | "version": "2.5.9",
4 | "tag": "latest",
5 | "description": "A node.js API of Hyperledger Fabric chaincode shim, to allow endorsing peers and user-provided chaincodes to communicate with each other",
6 | "main": "index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "https://github.com/hyperledger/fabric-chaincode-node"
10 | },
11 | "scripts": {
12 | "lint": "eslint ./types/ --ext .ts",
13 | "build": "echo No Build needed"
14 | },
15 | "keywords": [
16 | "fabric-shim",
17 | "Hyperledger Fabric",
18 | "Fabric Shim"
19 | ],
20 | "engines": {
21 | "node": ">=18",
22 | "eslint": "^6.6.0"
23 | },
24 | "types": "./types/index.d.ts",
25 | "license": "Apache-2.0",
26 | "devDependencies": {
27 | "@types/long": "^4.0.1",
28 | "eslint": "^6.6.0"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/apis/fabric-shim-api/tsconfig.json:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 IBM All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 | {
7 | "compilerOptions": {
8 | "types": ["./types/"],
9 | "alwaysStrict": true,
10 | "module": "commonjs",
11 | "declaration": true,
12 | "sourceMap": true,
13 | "strict": true,
14 | "target": "es2017",
15 | "lib": [
16 | "esnext",
17 | ]
18 | },
19 | "files": [
20 | "types/index.d.ts"
21 | ],
22 | "exclude": [
23 | "node_modules/**/*"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/common/scripts/install-run-rush-pnpm.js:
--------------------------------------------------------------------------------
1 | // THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED.
2 | //
3 | // This script is intended for usage in an automated build environment where the Rush command may not have
4 | // been preinstalled, or may have an unpredictable version. This script will automatically install the version of Rush
5 | // specified in the rush.json configuration file (if not already installed), and then pass a command-line to the
6 | // rush-pnpm command.
7 | //
8 | // An example usage would be:
9 | //
10 | // node common/scripts/install-run-rush-pnpm.js pnpm-command
11 | //
12 | // For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/
13 |
14 | /******/ (() => { // webpackBootstrap
15 | /******/ "use strict";
16 | var __webpack_exports__ = {};
17 | /*!*****************************************************!*\
18 | !*** ./lib-esnext/scripts/install-run-rush-pnpm.js ***!
19 | \*****************************************************/
20 |
21 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
22 | // See LICENSE in the project root for license information.
23 | require('./install-run-rush');
24 | //# sourceMappingURL=install-run-rush-pnpm.js.map
25 | module.exports = __webpack_exports__;
26 | /******/ })()
27 | ;
28 | //# sourceMappingURL=install-run-rush-pnpm.js.map
--------------------------------------------------------------------------------
/common/scripts/install-run-rushx.js:
--------------------------------------------------------------------------------
1 | // THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED.
2 | //
3 | // This script is intended for usage in an automated build environment where the Rush command may not have
4 | // been preinstalled, or may have an unpredictable version. This script will automatically install the version of Rush
5 | // specified in the rush.json configuration file (if not already installed), and then pass a command-line to the
6 | // rushx command.
7 | //
8 | // An example usage would be:
9 | //
10 | // node common/scripts/install-run-rushx.js custom-command
11 | //
12 | // For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/
13 |
14 | /******/ (() => { // webpackBootstrap
15 | /******/ "use strict";
16 | var __webpack_exports__ = {};
17 | /*!*************************************************!*\
18 | !*** ./lib-esnext/scripts/install-run-rushx.js ***!
19 | \*************************************************/
20 |
21 | // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
22 | // See LICENSE in the project root for license information.
23 | require('./install-run-rush');
24 | //# sourceMappingURL=install-run-rushx.js.map
25 | module.exports = __webpack_exports__;
26 | /******/ })()
27 | ;
28 | //# sourceMappingURL=install-run-rushx.js.map
--------------------------------------------------------------------------------
/docker/fabric-nodeenv/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright IBM Corp. All Rights Reserved.
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 | ARG NODE_IMAGE_TAG=22-alpine
6 | FROM node:${NODE_IMAGE_TAG}
7 | RUN apk add --no-cache \
8 | make \
9 | python3 \
10 | g++
11 | RUN mkdir -p /chaincode/input \
12 | && mkdir -p /chaincode/output \
13 | && mkdir -p /usr/local/src
14 | ADD build.sh start.sh /chaincode/
15 |
--------------------------------------------------------------------------------
/docker/fabric-nodeenv/README.md:
--------------------------------------------------------------------------------
1 | # Quick reference
2 |
3 | - **Maintained by**:
4 | [The Fabric Node chaincode maintainers](https://github.com/hyperledger/fabric-chaincode-node)
5 |
6 | # Overview
7 |
8 | This image is used by the default [Hyperledger Fabric](https://hyperledger-fabric.readthedocs.io/) chaincode builder when deploying Node (TypeScript or JavaScript) smart contracts. It is not intended for use independently of Hyperledger Fabric.
9 |
10 | # Image variants
11 |
12 | Detailed information on image tags, interoperability, and supported Node versions can be found in the [compatibility](https://github.com/hyperledger/fabric-chaincode-node/blob/main/COMPATIBILITY.md) documentation.
13 |
14 | # License
15 |
16 | This image is provided under the [Apache-2.0](https://github.com/hyperledger/fabric-chaincode-node/blob/main/LICENSE) license.
17 |
--------------------------------------------------------------------------------
/docker/fabric-nodeenv/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 | set -ex
6 | INPUT_DIR=/chaincode/input
7 | OUTPUT_DIR=/chaincode/output
8 | cp -R ${INPUT_DIR}/src/. ${OUTPUT_DIR}
9 | cd ${OUTPUT_DIR}
10 | if [ -f package-lock.json ] || [ -f npm-shrinkwrap.json ]; then
11 | npm ci --omit=dev
12 | else
13 | npm install --omit=dev
14 | fi
15 |
--------------------------------------------------------------------------------
/docker/fabric-nodeenv/docker.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /* eslint-disable no-console*/
8 | 'use strict';
9 |
10 | const fs = require('node:fs');
11 | const git = require('git-rev-sync');
12 | const path = require('node:path');
13 | const { execSync } = require('node:child_process');
14 | const process = require('node:process');
15 |
16 | const version = JSON.parse(fs.readFileSync(path.join(__dirname,'package.json'))).version;
17 | const build_dir = path.join(__dirname);
18 | const tag = version + '-' + git.short();
19 | const imageName = 'hyperledger/fabric-nodeenv'
20 |
21 | // reg exp the sort tag versions
22 | const regex = /^(\d+\.\d+)/
23 | const shortVersion = version.match(regex);
24 |
25 | function runCmd(command) {
26 | console.log(command);
27 | execSync(command, {
28 | stdio: 'inherit',
29 | });
30 | }
31 |
32 | // build and tag the fabric-nodeenv image
33 | function imageBuild() {
34 | runCmd(`docker build -t ${imageName}:${tag} -f ${path.join(build_dir, 'Dockerfile')} ${build_dir} 2>&1`);
35 | runCmd(`docker tag ${imageName}:${tag} ${imageName}:${version}`);
36 | runCmd(`docker tag ${imageName}:${tag} ${imageName}:${shortVersion[shortVersion.index]}`);
37 | runCmd(`docker tag ${imageName}:${tag} ${imageName}:latest`);
38 | };
39 |
40 | // remove fabric-nodeenv images
41 | function imageClean() {
42 | runCmd(`docker images -q --filter=reference="${imageName}:${version}*" | uniq | xargs -r docker rmi -f`);
43 | };
44 |
45 | try {
46 | imageClean();
47 | imageBuild();
48 | } catch (e) {
49 | console.error(e);
50 | process.exitCode = 1;
51 | }
52 |
--------------------------------------------------------------------------------
/docker/fabric-nodeenv/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fabric-nodeenv",
3 | "version": "2.5.9",
4 | "description": "",
5 | "main": "docker.js",
6 | "scripts": {
7 | "build": "node docker.js"
8 | },
9 | "keywords": [],
10 | "author": "",
11 | "license": "Apache-2.0",
12 | "dependencies": {
13 | "git-rev-sync": "3.0.2"
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/docker/fabric-nodeenv/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 | set -ex
6 | CHAINCODE_DIR=/usr/local/src
7 | cd ${CHAINCODE_DIR}
8 | npm start -- "$@"
--------------------------------------------------------------------------------
/docs/404.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "404 - Page Not Found"
3 | permalink: /404.html
4 | ---
5 |
6 | ## The page you wanted does not exist
7 |
8 | If you were looking for JSDoc, try one of the releases below:
9 |
10 | {% include apidocs.html %}
11 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | [You probably want to look here](https://hyperledger.github.io/fabric-chaincode-node/)
2 |
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | theme: minima
2 | title: "fabric-chaincode-node"
3 | releases:
4 | - main
5 | - release-1.4
6 | - release-2.2
7 |
--------------------------------------------------------------------------------
/docs/_includes/apidocs.html:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/docs/_includes/footer.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/hyperledger/fabric-chaincode-node/96d934ee63fc7fc19de817dc5eb05f04b0306b55/docs/_includes/footer.html
--------------------------------------------------------------------------------
/docs/_includes/header.html:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/docs/_jsdoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "source": {
3 | "include": [
4 | "./_jsdoc/index.md",
5 | "../libraries/fabric-shim/lib/chaincode.js",
6 | "../libraries/fabric-shim/lib/stub.js",
7 | "../libraries/fabric-shim/lib/iterators.js",
8 | "../apis/fabric-contract-api/lib"
9 | ]
10 | },
11 | "sourceType": "module",
12 | "opts": {
13 | "destination": "./gen",
14 | "recurse": true,
15 | "template": "./node_modules/ink-docstrap/template",
16 | "tutorials": "./_jsdoc/tutorials"
17 | },
18 | "templates": {
19 | "systemName": "Hyperledger Fabric Contract API",
20 | "theme": "cosmo",
21 | "default": {
22 | "staticFiles": {
23 | "include": [
24 | "./_jsdoc/static"
25 | ]
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/docs/_jsdoc/tutorials/data-types-and-contracts.md:
--------------------------------------------------------------------------------
1 | # How are data types handling with Contracts?
2 | This document deals with JavaScript and TypeScript contracts
3 |
4 | ## Function parameters
5 |
6 | ### JavaScript - no metadata
7 |
8 | This is the lowest common denominator; all data that is sent to the transaction function from the client is represented as strings.
9 | Therefore the conversion that takes place in the lack of any metadata is
10 |
11 | ```
12 | json = JSON.parse(data.toString());
13 | ```
14 |
15 | If the json has a property of 'type' and that equals 'Buffer' then a byte buffer is constructed. The standard JSON.stringify() form of a byte buffer is to add the type field.
16 |
17 | It is then left to JavaScript to be able to coerce the data as per standard language rules
18 |
19 | ### JavaScript - with metadata
20 |
21 | If the metadata for the property specifies a String or a Number, then conversion to a String or Number takes place.
22 | Otherwise, the same conversion takes place as with 'no-metadata'
23 |
24 |
25 | ### Typescript
26 | Typescript needs to have no annotations for types, (other than arrays). The metadata is inferred with sufficient detail.
27 | For arrays, the `@Param(,,[])` needs to be used to mark the type that is in the array.
28 |
29 |
30 | ## Return types
31 |
32 | A transaction function is free to return anything it wishes. (Strictly speaking it must return a promise, and that can be resolved or rejected with anything).
33 |
34 | With the Node.js runtime, either JavaScript or TypeScript can be used. For both languages you can supply additional metadata, either as annotations, or as a JSON file.
35 |
36 | ### JavaScript - no metadata
37 |
38 | This is the lowest common denominator; if no metadata is either provided by annotations, file, or inferred by introspection this is behaviour.
39 | All return values will be processed as follows:
40 |
41 | ```javascript
42 | Buffer.from(JSON.stringify(functionsReturnValue))
43 | ```
44 |
45 | The data will be stringified, then converted to a buffer to be returned. The buffer conversion is required by the shim api to communicate with the peer. This will be 'reversed' in the client SDK so that clients are given a string.
46 |
47 | ### JavaScript with metadata
48 |
49 | It is beneficial to supply metadata; specifically in the case of JavaScript to identify strings and numbers from objects.
50 |
51 | By doing this means that the transaction functions can
52 |
53 | - Return strings and numbers directly. Numbers are converted to their textual form eg 42 becomes "42"
54 | - Anything else is returned by being stringified first
55 |
56 | ## Typescript
57 |
58 | Without the '@return' annotations and/or metadata Typescript introspection can not provide enough details about the return type. Primarily as this is a Promise that resolves a type introspection only indicates the promise aspect.
59 |
60 | Metadata can be explicitly provided or the `@Returns()` can be used to indicate the type. The annotation needs to have the type name specified as a string value.
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/docs/_jsdoc/tutorials/tutorials.json:
--------------------------------------------------------------------------------
1 | {
2 | "using-chaincodeinterface":{
3 | "title":"Using the Chaincode Interface"
4 | },
5 | "using-contractinterface":{
6 | "title":"Using the Contract Interface"
7 | },
8 | "annotated-contract-metadata":{
9 | "title":"Walkthrough of annotated metadata.json"
10 | },
11 | "deep-dive-contract-interface":{
12 | "title":"Deep dive on Contract Interface"
13 | },
14 | "using-typescript-decorators":{
15 | "title":"Using TypeScript Decorators"
16 | },
17 | "data-types-and-contracts":{
18 | "title":"Details of type handling"
19 | },
20 | "using-iterators": {
21 | "title":"Working with apis that return iterators"
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/docs/_jsdoc/tutorials/using-typescript-decorators.md:
--------------------------------------------------------------------------------
1 | # Summary of the Typescript Decorators
2 |
3 | When using Typescript to code the Contract implementations, Typescript Decorators can be used to provide additional metadata; together with the type information that can be introspected, a very detailed set of metadata can be put within the source code directly.
4 |
5 | ## Decorators available
6 |
7 | - @Info
8 | - Supplies information about the following contract such as license terms or author.
9 | - This takes as a parameter an object that has the key-value pairs as defined on the OpenAPI v3 [Info object spec](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#infoObject)
10 | - @Transaction
11 | - Defines the following function to be a callable transaction function
12 | - Takes a boolean parameter; true indicates that this function is intended to be called with the 'submit' semantics, false indicates that this is intended to be called with the evaluate semantics. (Submit means submit to the orderer to be recorded on the ledger)
13 | - Default is true
14 | - @Returns
15 | - Takes a string that is the name of the type that is being returned by this function
16 | - This is present as required as Typescript does not give back the complete return type
17 | - @Object
18 | - Defines the class that represents one of the complex types that can be returned or passed to the transaction functions
19 | - @Property
20 | - Defines a property of the a class (identified by @Object) that should be passed within the object
21 | - @Param
22 | - Permits additional information such as a type and description to provided for parameters. (Note type is only useful in weakly typed languages)
23 |
24 | **Note that emitDecoratorMetadata property in *tsconfig.json* file is mandatory.**
25 |
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: home
3 | ---
4 |
5 | Hyperledger Fabric offers a number of SDKs to support developing smart contracts (chaincode)
6 | in various programming languages. There are two other smart contract SDKs available for Java, and Go, in addition to this Node.js SDK:
7 |
8 | * [Java SDK documentation](https://hyperledger.github.io/fabric-chaincode-java/)
9 | * [Go SDK documentation](https://godoc.org/github.com/hyperledger/fabric-chaincode-go)
10 |
11 | ## Documentation
12 |
13 | Detailed explanation on the concepts and programming model for smart contracts can be found in the [Smart Contracts and Chaincode section in the Hyperledger Fabric documentation](https://hyperledger-fabric.readthedocs.io/en/latest/smartcontract/smartcontract.html).
14 |
15 | API documentation is available for each release:
16 |
17 | {% include apidocs.html %}
18 |
19 | ## Download
20 |
21 | The following packages are available from the npm Registry:
22 |
23 | - [fabric-contract-api](https://www.npmjs.com/package/fabric-contract-api)
24 | - [fabric-shim](https://www.npmjs.com/package/fabric-shim)
25 | - [fabric-shim-api](https://www.npmjs.com/package/fabric-shim-api)
26 |
27 | Check the [release notes](https://github.com/hyperledger/fabric-chaincode-node/releases) for the changes in each version.
28 |
29 | ## Samples
30 |
31 | Node.js chaincode samples for commercial paper and fabcar can be found in the [fabric-samples repository](https://github.com/hyperledger/fabric-samples)
32 |
--------------------------------------------------------------------------------
/docs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fabric-shim-docs",
3 | "version": "2.5.9",
4 | "description": "",
5 | "private": true,
6 | "scripts": {
7 | "build": "npm run docs",
8 | "docs": "rimraf ./gen && jsdoc -c ./_jsdoc.json"
9 | },
10 | "dependencies": {
11 | "fabric-ledger": "2.5.9"
12 | },
13 | "devDependencies": {
14 | "ink-docstrap": "^1.3.2",
15 | "jsdoc": "^3.6.3",
16 | "rimraf": "^3.0.2"
17 | },
18 | "keywords": [],
19 | "author": "",
20 | "license": "Apache-2.0"
21 | }
22 |
--------------------------------------------------------------------------------
/libraries/fabric-ledger/.eslintignore:
--------------------------------------------------------------------------------
1 | # don't ever lint node_modules
2 | node_modules
3 |
4 | # don't lint build output (make sure it's set to your correct build folder name)
5 | dist
6 |
7 | # don't lint nyc coverage output
8 | coverage
9 |
--------------------------------------------------------------------------------
/libraries/fabric-ledger/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // This is a workaround for https://github.com/eslint/eslint/issues/3458
2 | require("@rushstack/eslint-config/patch-eslint6");
3 |
4 | module.exports = {
5 | extends: [ "@rushstack/eslint-config" ],
6 | parserOptions: { tsconfigRootDir: __dirname }
7 | };
8 |
--------------------------------------------------------------------------------
/libraries/fabric-ledger/.npmignore:
--------------------------------------------------------------------------------
1 | # Copyright IBM Corp. All Rights Reserved.
2 | # SPDX-License-Identifier: Apache-2.0
3 |
4 | # OS generated files #
5 | .DS_Store
6 |
7 | # Node Files #
8 | /node_modules
9 | npm-debug.log
10 |
11 | # Coverage #
12 | /coverage
13 |
14 | # Test Files #
15 | /test
16 |
17 | # Source files #
18 | /src
19 |
--------------------------------------------------------------------------------
/libraries/fabric-ledger/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fabric-ledger",
3 | "version": "2.5.9",
4 | "tag": "latest",
5 | "description": "A node.js implementation of Hyperledger Fabric ledger api, to allow access to ledger data from smart contracts",
6 | "main": "lib/index.js",
7 | "types": "lib/index.d.ts",
8 | "scripts": {
9 | "build": "npm run test",
10 | "compile": "tsc",
11 | "precompile": "npm run eslint",
12 | "pretest": "npm run compile",
13 | "test": "nyc mocha --require ts-node/register --recursive 'test/unit/**/*.spec.ts' --reporter spec-junit-splitter-mocha-reporter",
14 | "eslint": "eslint src --ext .ts"
15 | },
16 | "repository": {
17 | "type": "git",
18 | "url": "https://github.com/hyperledger/fabric-chaincode-node"
19 | },
20 | "keywords": [
21 | "fabric-ledger",
22 | "Hyperledger Fabric",
23 | "Fabric Ledger"
24 | ],
25 | "engines": {
26 | "node": ">=18"
27 | },
28 | "license": "Apache-2.0",
29 | "nyc": {
30 | "exclude": [
31 | "coverage/**",
32 | "test/**",
33 | ".eslintrc.js"
34 | ],
35 | "extension": [
36 | ".ts"
37 | ],
38 | "reporter": [
39 | "text-summary",
40 | "cobertura",
41 | "html"
42 | ],
43 | "all": true,
44 | "check-coverage": true,
45 | "statements": 100,
46 | "branches": 100,
47 | "functions": 100,
48 | "lines": 100
49 | },
50 | "dependencies": {
51 | "fabric-contract-api": "2.5.9",
52 | "winston": "^3.7.2"
53 | },
54 | "devDependencies": {
55 | "@types/chai": "^4.2.22",
56 | "@types/chai-as-promised": "^7.1.4",
57 | "@types/mocha": "^9.0.0",
58 | "@rushstack/eslint-config": "^0.5.1",
59 | "chai": "^4.3.4",
60 | "chai-as-promised": "^7.1.1",
61 | "cpx": "^1.5.0",
62 | "eslint": "^6.6.0",
63 | "mocha": "9.1.3",
64 | "mockery": "^2.1.0",
65 | "nyc": "15.1.0",
66 | "rewire": "6.0.0",
67 | "rimraf": "^3.0.2",
68 | "sinon": "13.0.1",
69 | "ts-node": "^10.2.1",
70 | "ts-mockito": "^2.6.1",
71 | "typescript": "4.4.4",
72 | "spec-junit-splitter-mocha-reporter": "1.0.1"
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/libraries/fabric-ledger/src/Collection.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 IBM All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | export enum CollectionNames {
8 | WORLD = 'worldstate'
9 | }
10 |
11 | /**
12 | * Collection placeholder.
13 | *
14 | * @memberof module:fabric-ledger
15 | */
16 | export class Collection { }
17 |
--------------------------------------------------------------------------------
/libraries/fabric-ledger/src/Ledger.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 IBM All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | import {Collection, CollectionNames} from './Collection';
8 |
9 | import {Context} from 'fabric-contract-api';
10 |
11 | /**
12 | * Entrypoint for the Ledger API.
13 | *
14 | * @memberof module:fabric-ledger
15 | */
16 | export class Ledger {
17 |
18 | private readonly _ctx: Context;
19 |
20 | private constructor (ctx: Context) {
21 | this._ctx = ctx;
22 | }
23 |
24 | /**
25 | * Get a Ledger instance which represents the current ledger state.
26 | *
27 | * @param {Context} ctx The transaction context
28 | * @returns {Promise} A new Ledger instance
29 | */
30 | public static async getLedger (ctx: Context): Promise {
31 | return new Ledger(ctx);
32 | }
33 |
34 | /**
35 | * Get a Collection instance for the named collection.
36 | *
37 | * @param {string} collectionName The name of the collection
38 | * @returns {Promise} A new Collection instance
39 | */
40 | public async getCollection (collectionName: string): Promise {
41 | return new Collection();
42 | }
43 |
44 | /**
45 | * Get a Collection instance representing the default world state.
46 | *
47 | * @returns {Promise} A new Collection instance
48 | */
49 | public async getDefaultCollection (): Promise {
50 | return this.getCollection(CollectionNames.WORLD);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/libraries/fabric-ledger/src/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2020 IBM All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | export {Collection} from './Collection';
8 | export {Ledger} from './Ledger';
9 |
--------------------------------------------------------------------------------
/libraries/fabric-ledger/test/unit/Ledger.spec.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 IBM All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | import {Context} from 'fabric-contract-api';
8 | import {mock} from 'ts-mockito';
9 |
10 | import {Collection} from '../../src/Collection';
11 | import {Ledger} from '../../src/Ledger';
12 |
13 | import chai = require('chai');
14 | import chaiAsPromised = require('chai-as-promised');
15 | chai.use(chaiAsPromised);
16 | const expect = chai.expect;
17 |
18 |
19 | describe('Ledger', () => {
20 |
21 | describe('getLedger()', () => {
22 | it('should return a Ledger instance', async () => {
23 | const ctxMock: Context = mock(Context);
24 | const ledger = await Ledger.getLedger(ctxMock);
25 | expect(ledger).to.exist;
26 | expect(ledger).to.be.instanceOf(Ledger);
27 | });
28 |
29 | it('should always return a new instance', async () => {
30 | const ctxMock: Context = mock(Context);
31 | const ledger1 = await Ledger.getLedger(ctxMock);
32 | const ledger2 = await Ledger.getLedger(ctxMock);
33 | expect(ledger1).to.not.equal(ledger2);
34 | });
35 | });
36 |
37 | describe('getCollection()', () => {
38 | it('should return a Collection instance', async () => {
39 | const ctxMock: Context = mock(Context);
40 | const ledger = await Ledger.getLedger(ctxMock);
41 | const collection = await ledger.getCollection('mycollection');
42 | expect(collection).to.exist;
43 | expect(collection).to.be.instanceOf(Collection);
44 | });
45 |
46 | it('should always return a new instance', async () => {
47 | const ctxMock: Context = mock(Context);
48 | const ledger = await Ledger.getLedger(ctxMock);
49 | const collection1 = await ledger.getCollection('mycollection');
50 | const collection2 = await ledger.getCollection('mycollection');
51 | expect(collection1).to.not.equal(collection2);
52 | });
53 | });
54 |
55 | describe('getDefaultCollection()', () => {
56 | it('should return a Collection instance', async () => {
57 | const ctxMock: Context = mock(Context);
58 | const ledger = await Ledger.getLedger(ctxMock);
59 | const collection = await ledger.getDefaultCollection();
60 | expect(collection).to.exist;
61 | expect(collection).to.be.instanceOf(Collection);
62 | });
63 |
64 | it('should always return a new instance', async () => {
65 | const ctxMock: Context = mock(Context);
66 | const ledger = await Ledger.getLedger(ctxMock);
67 | const collection1 = await ledger.getDefaultCollection();
68 | const collection2 = await ledger.getDefaultCollection();
69 | expect(collection1).to.not.equal(collection2);
70 | });
71 | });
72 | });
73 |
--------------------------------------------------------------------------------
/libraries/fabric-ledger/tsconfig.json:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 IBM All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 | {
7 | "compilerOptions": {
8 | "alwaysStrict": true,
9 | "module": "commonjs",
10 | "declaration": true,
11 | "outDir": "lib",
12 | "rootDir": "src",
13 | "sourceMap": true,
14 | "strict": true,
15 | "target": "es2017",
16 | "lib": [
17 | "esnext",
18 | "esnext.asynciterable"
19 | ]
20 | },
21 | "include": [
22 | "src/**/*"
23 | ],
24 | "exclude": [
25 | "node_modules/**/*"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/.npmignore:
--------------------------------------------------------------------------------
1 | test
2 | fabric-shim*.tgz
--------------------------------------------------------------------------------
/libraries/fabric-shim/README.md:
--------------------------------------------------------------------------------
1 | [](https://nodei.co/npm/fabric-contract-api/)
2 |
3 |
4 |
5 | [](http://badge.fury.io/js/fabric-shim)
6 |
7 |
8 | The `fabric-shim` provides the *chaincode interface*, a lower level API for implementing "Smart Contracts". To confirm that this is the same as the `fabric-shim` in previous versions of Hyperledger Fabric.
9 |
10 | Detailed explanation on the concept and programming model can be found here: [https://hyperledger-fabric.readthedocs.io/en/latest/smartcontract/smartcontract.html](https://hyperledger-fabric.readthedocs.io/en/latest/smartcontract/smartcontract.html).
11 |
12 |
13 | ## Chaincode Interface
14 |
15 | ### Installation
16 | ```sh
17 | npm install --save fabric-shim
18 | ```
19 |
20 | ### Usage
21 | The [chaincode interface](https://hyperledger.github.io/fabric-chaincode-node/main/api/fabric-shim.ChaincodeInterface.html) contains two methods to be implemented:
22 | ```javascript
23 | const shim = require('fabric-shim');
24 |
25 | const Chaincode = class {
26 | async Init(stub) {
27 | // use the instantiate input arguments to decide initial chaincode state values
28 |
29 | // save the initial states
30 | await stub.putState(key, Buffer.from(aStringValue));
31 |
32 | return shim.success(Buffer.from('Initialized Successfully!'));
33 | }
34 |
35 | async Invoke(stub) {
36 | // use the invoke input arguments to decide intended changes
37 |
38 | // retrieve existing chaincode states
39 | let oldValue = await stub.getState(key);
40 |
41 | // calculate new state values and saves them
42 | let newValue = oldValue + delta;
43 | await stub.putState(key, Buffer.from(newValue));
44 |
45 | return shim.success(Buffer.from(newValue.toString()));
46 | }
47 | };
48 | ```
49 |
50 | Start the chaincode process and listen for incoming endorsement requests:
51 | ```javascript
52 | shim.start(new Chaincode());
53 | ```
54 |
55 | ### API Reference
56 | Visit [API Reference](https://hyperledger.github.io/fabric-chaincode-node/main/api/) and click on "Classes" link in the navigation bar on the top to view the list of class APIs.
57 |
58 | ## Support
59 | Tested with node.js 8.9.0 (LTS).
60 |
61 | ## License
62 |
63 | This package is distributed under the
64 | [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0),
65 | see LICENSE.txt for more information.
66 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/cli.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | /*
3 | * Copyright IBM Corp. All Rights Reserved.
4 | *
5 | * SPDX-License-Identifier: Apache-2.0
6 | */
7 |
8 | const version = 'v' + require('./package.json').version;
9 | const Logger = require('./lib/logger');
10 |
11 | const logger = Logger.getLogger('fabric-shim/cli');
12 |
13 |
14 | const main = async () => {
15 | const results = await require('yargs')
16 | .parserConfiguration({ 'dot-notation': false })
17 | .commandDir('./lib/cmds')
18 | .demandCommand()
19 | .help()
20 | .wrap(null)
21 | .alias('v', 'version')
22 | .version(version)
23 | .describe('v', 'show version information')
24 | .env('CORE')
25 | .argv;
26 |
27 | logger.info("Bootstrap process completed")
28 | }
29 |
30 | main().catch( (e)=> {
31 | console.error("Major failure to start fabic-chaincode-node");
32 | console.error(e);
33 | process.exitCode = 1;
34 | });
35 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | module.exports = require('./lib/chaincode.js');
8 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/lib/cmds/metadata.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | /*
5 | # Copyright IBM Corp. All Rights Reserved.
6 | #
7 | # SPDX-License-Identifier: Apache-2.0
8 | */
9 |
10 | 'use strict';
11 |
12 | exports.command = 'metadata ';
13 | exports.desc = 'Command for handling metadata';
14 | exports.builder = function (yargs) {
15 | // apply commands in subdirectories, throws an error if an incorrect command is entered
16 | return yargs.demandCommand(1, 'Incorrect command. Please see the list of commands above.')
17 | .commandDir('metadata');
18 | };
19 | exports.handler = async (argv) => {};
20 |
21 | module.exports.Generate = require('./metadata/lib/generate');
22 |
23 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/lib/cmds/metadata/generateCommand.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | const Generate = require ('./lib/generate.js');
7 |
8 | 'use strict';
9 |
10 | module.exports.command = 'generate [options]';
11 | module.exports.desc = 'Generate a file containing the metadata from the deployed contract';
12 | module.exports.builder = (yargs) => {
13 | yargs.options({
14 | 'file': {alias: 'f', required: false, describe: 'The file name/path to save the generated metadata file, if no file is specified, it will print to stdout', type: 'string'},
15 | 'module-path': {alias: 'p', required: false, describe: 'The path to the directory of your smart contract project which contains your chaincode, default is your current working directory', type: 'string', default: process.cwd()}
16 | });
17 | yargs.usage('fabric-chaincode-node metadata generate --file "fileName"');
18 |
19 | return yargs;
20 | };
21 |
22 | module.exports.handler = async (argv) => {
23 | await Generate.handler(argv);
24 | };
25 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/lib/cmds/metadata/lib/generate.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 | const path = require('node:path');
8 | const {promises: fs} = require('node:fs');
9 | const ChaincodeFromContract = require('../../../contract-spi/chaincodefromcontract.js');
10 | const Bootstrap = require('../../../contract-spi/bootstrap.js');
11 | const Logger = require('../../../logger');
12 | const logger = Logger.getLogger('../../../cmds/metadata/lib/generate');
13 |
14 | /**
15 | * fabric-chaincode-node "metadata generate" command
16 | * @private
17 | */
18 | class Generate {
19 | /**
20 | * This is the main entry point for starting the user's chaincode
21 | * @ignore
22 | */
23 | static async handler(opts) {
24 | // load up the meta data that the user may have specified
25 | // this will need to passed in and rationalized with the code as implemented
26 | const fileMetadata = await Bootstrap.getMetadata(opts['module-path']);
27 | const {contracts, serializers, title, version} = Bootstrap.getInfoFromContract(opts['module-path']);
28 | const chaincode = new ChaincodeFromContract(contracts, serializers, fileMetadata, title, version);
29 | if (opts.file) {
30 | const fileName = path.extname(opts.file) === '' ? opts.file + '.json' : opts.file;
31 | const filePath = path.resolve(process.cwd(), fileName);
32 | await fs.writeFile(filePath, JSON.stringify(chaincode.metadata, null, 4));
33 | logger.info(`File containing metadata has been saved to ${filePath}`);
34 | } else {
35 | logger.info(JSON.stringify(chaincode.metadata, null, 4));
36 | }
37 | }
38 | }
39 | module.exports = Generate;
40 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/lib/cmds/startCommand.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright contributors to Hyperledger Fabric.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | 'use strict';
8 |
9 | const YargsParser = require('yargs-parser');
10 |
11 | const validOptions = {
12 | 'peer.address': {type: 'string', required: true},
13 | 'grpc.max_send_message_length': {type: 'number', default: -1},
14 | 'grpc.max_receive_message_length': {type: 'number', default: -1},
15 | 'grpc.keepalive_time_ms': {type: 'number', default: 110000},
16 | 'grpc.http2.min_time_between_pings_ms': {type: 'number', default: 110000},
17 | 'grpc.keepalive_timeout_ms': {type: 'number', default: 20000},
18 | 'grpc.http2.max_pings_without_data': {type: 'number', default: 0},
19 | 'grpc.keepalive_permit_without_calls': {type: 'number', default: 1},
20 | 'ssl-target-name-override': {type: 'string'},
21 | 'chaincode-id-name': {type: 'string', required: true},
22 | 'module-path': {type: 'string', default: process.cwd()}
23 | };
24 |
25 | module.exports.validOptions = validOptions;
26 |
27 | exports.command = 'start [options]';
28 | exports.desc = 'Start an empty chaincode';
29 | exports.builder = (yargs) => {
30 | yargs.options(validOptions);
31 |
32 | yargs.usage('fabric-chaincode-node start --peer.address localhost:7051 --chaincode-id-name mycc');
33 |
34 | return yargs;
35 | };
36 | exports.handler = async function (argv) {
37 | const Bootstrap = require('../contract-spi/bootstrap');
38 | await Bootstrap.bootstrap();
39 | };
40 |
41 | exports.getArgs = function (yargs) {
42 | let argv = yargs.argv;
43 |
44 | if (argv.$0 !== 'fabric-chaincode-node') {
45 |
46 | const defaults = {};
47 |
48 | const required = [];
49 |
50 | for (const key in validOptions) {
51 | if (validOptions[key].hasOwnProperty('default')) { // eslint-disable-line no-prototype-builtins
52 | defaults[key] = validOptions[key].default;
53 | }
54 |
55 | if (validOptions[key].hasOwnProperty('required') && validOptions[key].required) { // eslint-disable-line no-prototype-builtins
56 | required.push(key);
57 | }
58 | }
59 |
60 | argv = YargsParser(process.argv.slice(2), {
61 | default: defaults,
62 | configuration: {
63 | 'dot-notation': false
64 | },
65 | envPrefix: 'CORE'
66 | });
67 |
68 | argv['chaincode-id-name'] = argv.chaincodeIdName;
69 | argv['module-path'] = argv.modulePath;
70 |
71 | // eslint-disable-next-line eqeqeq
72 | if (argv.CORE_PEER_ADDRESS != null) {
73 | argv['peer.address'] = argv.CORE_PEER_ADDRESS;
74 | }
75 |
76 | required.forEach((argName) => {
77 | if (!argv.hasOwnProperty(argName) || typeof(argv[argName]) === 'undefined') { // eslint-disable-line no-prototype-builtins
78 | throw new Error('Missing required argument ' + argName);
79 | }
80 | });
81 | }
82 |
83 | return argv;
84 | };
85 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/lib/contract-spi/systemcontract.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 |
8 | const Contract = require('fabric-contract-api').Contract;
9 |
10 | /**
11 | * This is a contract that determines functions that can be invoked to provide general information
12 | *
13 | * @class
14 | * @memberof fabric-contract-api
15 | */
16 | class SystemContract extends Contract {
17 |
18 | constructor() {
19 | super('org.hyperledger.fabric');
20 | }
21 |
22 | /**
23 | *
24 | * @param {Object} chaincode
25 | */
26 | _setMetadata(metadata) {
27 | this.metadata = metadata;
28 | }
29 |
30 | /**
31 | * Gets meta data associated with this Chaincode deployment
32 | */
33 | async GetMetadata() {
34 | return this.metadata;
35 | }
36 |
37 | }
38 |
39 | module.exports = SystemContract;
40 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/lib/utils/utils.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | module.exports.generateLoggingPrefix = (channelId, txId) => {
8 | return `[${channelId}-${shortTxID(txId)}]`;
9 | };
10 |
11 | function shortTxID (txId) {
12 | return txId.substring(0, 8);
13 | }
14 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fabric-shim",
3 | "version": "2.5.9",
4 | "tag": "latest",
5 | "description": "A node.js implementation of Hyperledger Fabric chaincode shim, to allow endorsing peers and user-provided chaincodes to communicate with each other",
6 | "main": "index.js",
7 | "bin": {
8 | "fabric-chaincode-node": "cli.js"
9 | },
10 | "scripts": {
11 | "start": "./startup.sh",
12 | "compile": "tsc --project test/typescript",
13 | "test": "nyc mocha --recursive 'test/unit/**/*.js' --reporter spec-junit-splitter-mocha-reporter",
14 | "update:clean": "rimraf bundle.js bundle.d.ts protos && mkdirp protos",
15 | "update:copy": "cpx \"${GOPATH}/src/github.com/hyperledger/fabric-protos/**/*.proto\" protos --verbose",
16 | "update:pbjs": "pbjs -t static-module -p google-protos -p protos $(find google-protos protos -name \"*.proto\" -type f) -o bundle.js",
17 | "update:pbts": "pbts -o bundle.d.ts bundle.js",
18 | "update": "npm run update:clean && npm run update:copy && npm run update:pbjs && npm run update:pbts",
19 | "lint": "eslint ./lib ./types ./test/typescript/*.ts --ext .js --ext .ts",
20 | "build": "npm run lint & npm test 2>&1"
21 | },
22 | "repository": {
23 | "type": "git",
24 | "url": "https://github.com/hyperledger/fabric-chaincode-node"
25 | },
26 | "keywords": [
27 | "fabric-shim",
28 | "Hyperledger Fabric",
29 | "Fabric Shim"
30 | ],
31 | "engines": {
32 | "node": ">=18"
33 | },
34 | "types": "./types/index.d.ts",
35 | "license": "Apache-2.0",
36 | "nyc": {
37 | "exclude": [
38 | "coverage/**",
39 | "test/**",
40 | "gulpfile.js",
41 | "bundle.js"
42 | ],
43 | "reporter": [
44 | "text-summary",
45 | "cobertura",
46 | "html"
47 | ],
48 | "all": true,
49 | "check-coverage": true,
50 | "statements": 100,
51 | "branches": 100,
52 | "functions": 100,
53 | "lines": 100
54 | },
55 | "dependencies": {
56 | "@fidm/x509": "^1.2.1",
57 | "@grpc/grpc-js": "^1.11.0",
58 | "@hyperledger/fabric-protos": "^0.2.2",
59 | "@types/node": "^16.11.1",
60 | "ajv": "^6.12.2",
61 | "fabric-contract-api": "2.5.9",
62 | "fabric-shim-api": "2.5.9",
63 | "fast-safe-stringify": "^2.1.1",
64 | "long": "^5.2.3",
65 | "reflect-metadata": "^0.1.13",
66 | "winston": "^3.7.2",
67 | "yargs": "^17.4.0",
68 | "yargs-parser": "^21.0.1"
69 | },
70 | "devDependencies": {
71 | "chai": "^4.3.4",
72 | "chai-as-promised": "^7.1.1",
73 | "chai-things": "^0.2.0",
74 | "cpx": "^1.5.0",
75 | "eslint": "^6.6.0",
76 | "mocha": "9.1.3",
77 | "mockery": "^2.1.0",
78 | "nyc": "15.1.0",
79 | "rewire": "6.0.0",
80 | "rimraf": "^3.0.2",
81 | "sinon": "13.0.1",
82 | "spec-junit-splitter-mocha-reporter": "1.0.1",
83 | "caniuse-lite": "~1.0.30001325"
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/startup.sh:
--------------------------------------------------------------------------------
1 | DIR=$(pwd)
2 |
3 | # MAKE IT GO THROUGH THE ARGS ONE BY ONE AND IF IT IS THE LABEL --module-path THEN GET THE NEXT ARG AND USE THAT AS THE CD OVER THE ENV VAR
4 | GRAB_NEXT=false
5 | for var in "$@"; do
6 | if [ $var = "--module-path" ]; then
7 | GRAB_NEXT=true
8 | elif [ $GRAB_NEXT = true ]; then
9 | CORE_MODULE_PATH="$var"
10 | fi
11 | done
12 | cd $CORE_MODULE_PATH
13 |
14 | if grep -q "fabric-contract-api" package.json; then
15 | cd $DIR
16 | node cli.js start "$@"
17 | else
18 | npm start -- "$@"
19 | fi
--------------------------------------------------------------------------------
/libraries/fabric-shim/test/unit/cli.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /* global describe it beforeEach afterEach */
8 |
9 | 'use strict';
10 |
11 | const sinon = require('sinon');
12 |
13 | const yargs = require('yargs');
14 |
15 | const {execSync} = require('child_process');
16 |
17 | describe('fabric-chaincode-node cli', () => {
18 | let sandbox;
19 |
20 | beforeEach(() => {
21 |
22 | sandbox = sinon.createSandbox();
23 | sandbox.stub(yargs, 'parserConfiguration').returns(yargs);
24 | sandbox.stub(yargs, 'commandDir').returns(yargs);
25 | sandbox.stub(yargs, 'demandCommand').returns(yargs);
26 |
27 | sandbox.stub(yargs, 'help').returns(yargs);
28 | sandbox.stub(yargs, 'wrap').returns(yargs);
29 | sandbox.stub(yargs, 'alias').returns(yargs);
30 | sandbox.stub(yargs, 'version').returns(yargs);
31 |
32 | sandbox.stub(process, 'exit');
33 | execSync('cp ./cli.js ./cli2.js', () => {});
34 | execSync('sed 1d ./cli2.js > ./cli.js', () => {});
35 | });
36 |
37 | afterEach(() => {
38 | sandbox.restore();
39 | delete require.cache[require.resolve('../../cli.js')];
40 | execSync('rm ./cli.js', () => {});
41 | execSync('mv ./cli2.js ./cli.js', () => {});
42 | });
43 |
44 | describe('Main test', () => {
45 | it('should setup yargs correctly', () => {
46 | sandbox.stub(yargs, 'describe').returns(yargs);
47 | sandbox.stub(yargs, 'env').returns(yargs);
48 |
49 | require('../../cli.js');
50 |
51 | sinon.assert.calledOnce(yargs.commandDir);
52 | sinon.assert.calledWith(yargs.commandDir, './lib/cmds');
53 | sinon.assert.calledOnce(yargs.demandCommand);
54 | sinon.assert.calledOnce(yargs.help);
55 | sinon.assert.calledOnce(yargs.wrap);
56 | sinon.assert.calledOnce(yargs.alias);
57 | sinon.assert.calledOnce(yargs.version);
58 | sinon.assert.calledOnce(yargs.describe);
59 | sinon.assert.calledOnce(yargs.env);
60 | sinon.assert.calledWith(yargs.env, 'CORE');
61 | });
62 |
63 | it('should handle resolved promise correctly', () => {
64 | sandbox.stub(yargs, 'describe').returns(yargs);
65 | sandbox.stub(yargs, 'env').resolves("");
66 | require('../../cli.js');
67 | });
68 |
69 | it('should handle rejected promise correctly', () => {
70 | sandbox.stub(yargs, 'describe').returns(yargs);
71 | sandbox.stub(yargs, 'env').throws("Test Failure")
72 |
73 | require('../../cli.js');
74 | });
75 | });
76 | });
77 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/test/unit/cmds/metadata.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | 'use strict';
8 |
9 | const MetadataCommand = require('../../../lib/cmds/metadata');
10 | const yargs = require('yargs');
11 | require('chai').should();
12 | const chai = require('chai');
13 | const sinon = require('sinon');
14 | chai.should();
15 | chai.use(require('chai-things'));
16 | chai.use(require('chai-as-promised'));
17 | const mockery = require('mockery');
18 |
19 | describe('fabric-chaincode-node metadata cmd launcher', function () {
20 | let sandbox;
21 |
22 | beforeEach(() => {
23 |
24 | sandbox = sinon.createSandbox();
25 | sandbox.stub(yargs, 'usage').returns(yargs);
26 | sandbox.stub(yargs, 'options').returns(yargs);
27 | sandbox.stub(yargs, 'requiresArg').returns(yargs);
28 | sandbox.stub(yargs, 'demandCommand').returns(yargs);
29 | sandbox.stub(yargs, 'commandDir');
30 | });
31 |
32 | afterEach(() => {
33 | mockery.deregisterAll();
34 | sandbox.restore();
35 | });
36 |
37 | describe('cmd method tests', () => {
38 |
39 | it ('should have the correct command and description', function () {
40 | MetadataCommand.command.should.include('metadata');
41 | MetadataCommand.desc.should.include('metadata');
42 | });
43 |
44 | it ('should call yargs correctly', () => {
45 | MetadataCommand.builder(yargs);
46 | sinon.assert.calledOnce(yargs.commandDir);
47 | sinon.assert.calledWith(yargs.commandDir, 'metadata');
48 | MetadataCommand.handler();
49 | });
50 |
51 | });
52 |
53 |
54 | });
55 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/test/unit/cmds/metadata/generateCommand.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /* eslint-disable no-console */
8 | 'use strict';
9 |
10 | const yargs = require('yargs');
11 | require('chai').should();
12 | const chai = require('chai');
13 | const sinon = require('sinon');
14 | chai.should();
15 | chai.use(require('chai-as-promised'));
16 | chai.use(require('chai-things'));
17 |
18 | const rewire = require('rewire');
19 | // class under test
20 | const GenerateCommand = rewire('../../../../lib/cmds/metadata/generateCommand.js');
21 |
22 |
23 | describe('GenerateCommand', () => {
24 |
25 | let sandbox;
26 |
27 | beforeEach('Sandbox creation', () => {
28 | sandbox = sinon.createSandbox();
29 | });
30 |
31 | afterEach('Sandbox restoration', () => {
32 | sandbox.restore();
33 | });
34 |
35 | describe('#builder function', () => {
36 |
37 | beforeEach(() => {
38 | sandbox.stub(yargs, 'usage').returns(yargs);
39 | sandbox.stub(yargs, 'options').returns(yargs);
40 | sandbox.stub(yargs, 'strict').returns(yargs);
41 | sandbox.stub(yargs, 'requiresArg').returns(yargs);
42 | sandbox.stub(yargs, 'demandCommand').returns(yargs);
43 | sandbox.stub(yargs, 'commandDir');
44 | });
45 |
46 | it ('should have the correct command and description', function () {
47 | GenerateCommand.command.should.include('generate');
48 | GenerateCommand.desc.should.include('Generate');
49 | });
50 |
51 | it ('should call yargs correctly', () => {
52 | GenerateCommand.builder(yargs);
53 | sinon.assert.calledOnce(yargs.options);
54 | sinon.assert.calledWith(yargs.options, {
55 | 'file': {alias: 'f', required: false, describe: 'The file name/path to save the generated metadata file, if no file is specified, it will print to stdout', type: 'string'},
56 | 'module-path': {alias: 'p', required: false, describe: 'The path to the directory of your smart contract project which contains your chaincode, default is your current working directory', type: 'string', default: process.cwd()}
57 | });
58 | sinon.assert.calledOnce(yargs.usage);
59 | sinon.assert.calledWith(yargs.usage, 'fabric-chaincode-node metadata generate --file "fileName"');
60 | });
61 | });
62 |
63 | describe('#handler function', () => {
64 | let handlerStub;
65 | class FakeGenerate {
66 | static handler() {
67 | }
68 | }
69 | beforeEach(() => {
70 | handlerStub = sandbox.stub(FakeGenerate, 'handler');
71 | GenerateCommand.__set__('Generate', FakeGenerate);
72 | });
73 |
74 | afterEach(() => {
75 | sandbox.restore();
76 | });
77 |
78 | it ('should call the handler function correctly', () => {
79 | const argv = {random: 'something'};
80 | GenerateCommand.handler(argv);
81 | sinon.assert.calledOnce(handlerStub);
82 | sinon.assert.calledWithExactly(handlerStub, argv);
83 | });
84 | });
85 | });
86 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/test/unit/contract-spi/systemcontract.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | /* global describe it beforeEach afterEach */
8 | 'use strict';
9 |
10 | // test specific libraries
11 | const chai = require('chai');
12 | chai.should();
13 | const expect = chai.expect;
14 | const rewire = require('rewire');
15 | chai.use(require('chai-as-promised'));
16 | chai.use(require('chai-things'));
17 | const sinon = require('sinon');
18 |
19 | const path = require('path');
20 |
21 | // class under test
22 | const pathToRoot = '../../../..';
23 | const SystemContract = rewire(path.join(pathToRoot, 'fabric-shim/lib/contract-spi/systemcontract'));
24 |
25 | describe('SystemContract', () => {
26 |
27 | let sandbox;
28 |
29 | beforeEach('Sandbox creation', () => {
30 | sandbox = sinon.createSandbox();
31 |
32 | });
33 |
34 | afterEach('Sandbox restoration', () => {
35 | sandbox.restore();
36 | });
37 |
38 | describe('#constructor', () => {
39 |
40 | it ('should create correctly', () => {
41 | const meta = new SystemContract();
42 | expect(meta.getName()).to.equal('org.hyperledger.fabric');
43 | });
44 |
45 | });
46 |
47 | describe('#GetMetadata', () => {
48 |
49 | it ('should get the buffer', async () => {
50 | const meta = new SystemContract();
51 | meta._setMetadata({wibble:'good'});
52 | const md = await meta.GetMetadata();
53 | expect(md).to.deep.equal({wibble:'good'});
54 |
55 | });
56 |
57 |
58 | });
59 |
60 |
61 | });
62 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/test/unit/module.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | /* global describe it */
7 |
8 | 'use strict';
9 |
10 | const chai = require('chai');
11 | const expect = chai.expect;
12 |
13 | const theModule = require('../../../fabric-shim');
14 |
15 | describe('Exports', () => {
16 | it ('should export the start function', () => {
17 | expect(typeof theModule.start).to.deep.equal('function');
18 | });
19 |
20 | it ('should export the success function', () => {
21 | expect(typeof theModule.success).to.deep.equal('function');
22 | });
23 |
24 | it ('should export the error function', () => {
25 | expect(typeof theModule.error).to.deep.equal('function');
26 | });
27 |
28 | it ('should export the Shim class', () => {
29 | expect(typeof theModule.Shim).to.deep.equal('function');
30 | });
31 |
32 | it ('should export the Stub class', () => {
33 | expect(typeof theModule.Stub).to.deep.equal('function');
34 | });
35 |
36 | it ('should export the ChaincodeInterface class', () => {
37 | expect(typeof theModule.ChaincodeInterface).to.deep.equal('function');
38 | });
39 |
40 | it ('should export the ClientIdentity class', () => {
41 | expect(typeof theModule.ClientIdentity).to.deep.equal('function');
42 | });
43 |
44 | it ('should export the Iterators.HistoryQueryIterator class', () => {
45 | expect(typeof theModule.Iterators.HistoryQueryIterator).to.deep.equal('function');
46 | });
47 |
48 | it ('should export the HistoryQueryIterator class', () => {
49 | expect(typeof theModule.HistoryQueryIterator).to.deep.equal('function');
50 | });
51 |
52 | it ('should export the Iterators.StateQueryIterator class', () => {
53 | expect(typeof theModule.Iterators.StateQueryIterator).to.deep.equal('function');
54 | });
55 |
56 | it ('should export the StateQueryIterator class', () => {
57 | expect(typeof theModule.StateQueryIterator).to.deep.equal('function');
58 | });
59 | });
60 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/test/unit/test-ca.base64:
--------------------------------------------------------------------------------
1 | LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJrekNCOVFJSkFKMFo4akZpUFBpOU1Bb0dD
2 | Q3FHU000OUJBTUNNQTR4RERBS0JnTlZCQU1NQTNSc2N6QWUKRncweU1EQTFNRGN4TmpNME1qRmFG
3 | dzB6TURBMU1EVXhOak0wTWpGYU1BNHhEREFLQmdOVkJBTU1BM1JzY3pDQgptekFRQmdjcWhrak9Q
4 | UUlCQmdVcmdRUUFJd09CaGdBRUFDb1VTM3pnOVFqNUNnUWVOQ1krOXNQTTJZV1lIVVVRClNCRS9v
5 | WXBncldWOEU4VHF0V2tXY2h3WFA0T29aQXE3Yk1KMmJOUUU1U3E2SVkrYlpyWXBPS2pmQVNweVM0
6 | cVIKNHhKZkN1bjdCSVpBallIdlZxbWN1RjhhSmFmaDhGOTNHQmprSUxIZ0hUcnRMTHNBcTZzQnB6
7 | RXVWSmxzdWYxaApMaEtuQ0FxdmZFdEMxSUJWTUFvR0NDcUdTTTQ5QkFNQ0E0R01BRENCaUFKQ0FO
8 | R1VwNDU5UDNhTWh0VFpkWEZxCm1jOFFWTTdySFIzWmxpOWttV3NHVmRKdmJVYnVIY1g2KzBBVTFT
9 | OFIyRGhQQThvZUJ1UVQ3ZGJvdllmd2V1VmIKUWZSM0FrSUFwYUtlc2lOOUxOeTlhclNCR1hURktK
10 | cXVCVDYzdjRiaTRmeUNOaGhkQzN3eEtldHNKMURDcElkcgpCbDhabmNKeFVNakNyZDdCTmxrQk5Q
11 | N2pDR2RLcFBrPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t
12 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/test/unit/test-ca.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIBkzCB9QIJAJ0Z8jFiPPi9MAoGCCqGSM49BAMCMA4xDDAKBgNVBAMMA3RsczAe
3 | Fw0yMDA1MDcxNjM0MjFaFw0zMDA1MDUxNjM0MjFaMA4xDDAKBgNVBAMMA3RsczCB
4 | mzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAEACoUS3zg9Qj5CgQeNCY+9sPM2YWYHUUQ
5 | SBE/oYpgrWV8E8TqtWkWchwXP4OoZAq7bMJ2bNQE5Sq6IY+bZrYpOKjfASpyS4qR
6 | 4xJfCun7BIZAjYHvVqmcuF8aJafh8F93GBjkILHgHTrtLLsAq6sBpzEuVJlsuf1h
7 | LhKnCAqvfEtC1IBVMAoGCCqGSM49BAMCA4GMADCBiAJCANGUp459P3aMhtTZdXFq
8 | mc8QVM7rHR3Zli9kmWsGVdJvbUbuHcX6+0AU1S8R2DhPA8oeBuQT7dbovYfweuVb
9 | QfR3AkIApaKesiN9LNy9arSBGXTFKJquBT63v4bi4fyCNhhdC3wxKetsJ1DCpIdr
10 | Bl8ZncJxUMjCrd7BNlkBNP7jCGdKpPk=
11 | -----END CERTIFICATE-----
--------------------------------------------------------------------------------
/libraries/fabric-shim/test/unit/test-cert.base64:
--------------------------------------------------------------------------------
1 | LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJrakNCOVFJSkFPZTRqL3NqV3ltRE1Bb0dDQ3FHU000OUJBTUNNQTR4RERBS0JnTlZCQU1NQTNSc2N6QWUKRncweU1EQTFNRGN4TmpNek5UUmFGdzB6TURBMU1EVXhOak16TlRSYU1BNHhEREFLQmdOVkJBTU1BM1JzY3pDQgptekFRQmdjcWhrak9QUUlCQmdVcmdRUUFJd09CaGdBRUFPcllIem5BZmVXZ3pVM3dVZ1Q1Ylk5NkUvT2ZMb3p4CitlUUFIL2Y5cDV3TUxuUzliMTJZczBHWitTNEdjSEYva1FBNlpoMVZBcFdKYnJ6MjFYVWhSbU5QQVRibDd3K2cKbytyazJ2cVZ5Y0E3dU1tUERlL0J2MVlldEh1WXZCd05vajVLVm9vVnVpUnJPOUlkU2N3ZUxkai9WOXoyQUkvQgpmUC9iN01aYWFwbUdUQjVFTUFvR0NDcUdTTTQ5QkFNQ0E0R0xBRENCaHdKQmVZQ1ZPclFWR3dmb1Q3OWRqRWpqCm1YVkVIL3hWcGk4b1ZhWkxVRm0yN2RldkYwb1ViZHowZSt2MzhZdkx6aERnWWh2MUtMQzhnYWxxaFdleTI2MmkKVVcwQ1FnRWRrUHFOYUZlbjF0WEQ5RWJoTjhSdVRyQWE3RGphNzZ3SWVMZUZSdFloZ0hCZlMvZmM0VWR3N1hWbgpQcG9nQ0xhM0ZMNkNDSUZIQWEyTU9kc3VMeld4V2c9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0t
--------------------------------------------------------------------------------
/libraries/fabric-shim/test/unit/test-cert.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIBkjCB9QIJAOe4j/sjWymDMAoGCCqGSM49BAMCMA4xDDAKBgNVBAMMA3RsczAe
3 | Fw0yMDA1MDcxNjMzNTRaFw0zMDA1MDUxNjMzNTRaMA4xDDAKBgNVBAMMA3RsczCB
4 | mzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAEAOrYHznAfeWgzU3wUgT5bY96E/OfLozx
5 | +eQAH/f9p5wMLnS9b12Ys0GZ+S4GcHF/kQA6Zh1VApWJbrz21XUhRmNPATbl7w+g
6 | o+rk2vqVycA7uMmPDe/Bv1YetHuYvBwNoj5KVooVuiRrO9IdScweLdj/V9z2AI/B
7 | fP/b7MZaapmGTB5EMAoGCCqGSM49BAMCA4GLADCBhwJBeYCVOrQVGwfoT79djEjj
8 | mXVEH/xVpi8oVaZLUFm27devF0oUbdz0e+v38YvLzhDgYhv1KLC8galqhWey262i
9 | UW0CQgEdkPqNaFen1tXD9EbhN8RuTrAa7Dja76wIeLeFRtYhgHBfS/fc4Udw7XVn
10 | PpogCLa3FL6CCIFHAa2MOdsuLzWxWg==
11 | -----END CERTIFICATE-----
--------------------------------------------------------------------------------
/libraries/fabric-shim/test/unit/test-key.base64:
--------------------------------------------------------------------------------
1 | LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1JSGNBZ0VCQkVJQmZXcmJQam9pdHcwd3AwUjA3dHdKeDhxaDZGenhpVFArekpFNEZHZ3EvTXh6Sy9kdUhIN2YKRjNzOWtmM1dkcWxYNlkwTnM2K3VRR2hmK2laODZtd01zaU9nQndZRks0RUVBQ09oZ1lrRGdZWUFCQURxMkI4NQp3SDNsb00xTjhGSUUrVzJQZWhQem55Nk04Zm5rQUIvMy9hZWNEQzUwdlc5ZG1MTkJtZmt1Qm5CeGY1RUFPbVlkClZRS1ZpVzY4OXRWMUlVWmpUd0UyNWU4UG9LUHE1TnI2bGNuQU83akpqdzN2d2I5V0hyUjdtTHdjRGFJK1NsYUsKRmJva2F6dlNIVW5NSGkzWS8xZmM5Z0NQd1h6LzIrekdXbXFaaGt3ZVJBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQ==
--------------------------------------------------------------------------------
/libraries/fabric-shim/test/unit/test-key.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN EC PRIVATE KEY-----
2 | MIHcAgEBBEIBfWrbPjoitw0wp0R07twJx8qh6FzxiTP+zJE4FGgq/MxzK/duHH7f
3 | F3s9kf3WdqlX6Y0Ns6+uQGhf+iZ86mwMsiOgBwYFK4EEACOhgYkDgYYABADq2B85
4 | wH3loM1N8FIE+W2PehPzny6M8fnkAB/3/aecDC50vW9dmLNBmfkuBnBxf5EAOmYd
5 | VQKViW689tV1IUZjTwE25e8PoKPq5Nr6lcnAO7jJjw3vwb9WHrR7mLwcDaI+SlaK
6 | FbokazvSHUnMHi3Y/1fc9gCPwXz/2+zGWmqZhkweRA==
7 | -----END EC PRIVATE KEY-----
--------------------------------------------------------------------------------
/libraries/fabric-shim/test/unit/utils/utils.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | const chai = require('chai');
8 | const expect = chai.expect;
9 |
10 | const utils = require('../../../lib/utils/utils');
11 |
12 | describe('utils', () => {
13 | describe('generateLoggingPrefix', () => {
14 | it ('should shorten txids over 8 letters', () => {
15 | expect(utils.generateLoggingPrefix('myc', '123456789')).to.deep.equal('[myc-12345678]');
16 | });
17 |
18 | it ('should leave txids shorter than 8 as was', () => {
19 | expect(utils.generateLoggingPrefix('myc', '1234567')).to.deep.equal('[myc-1234567]');
20 | });
21 |
22 | it ('should leave txids exactly 8 letters as was', () => {
23 | expect(utils.generateLoggingPrefix('myc', '12345678')).to.deep.equal('[myc-12345678]');
24 | });
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/libraries/fabric-shim/tsconfig.json:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 IBM All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 | {
7 | "compilerOptions": {
8 | "types": ["./types/"],
9 | "alwaysStrict": true,
10 | "module": "commonjs",
11 | "declaration": true,
12 | "sourceMap": true,
13 | "strict": true,
14 | "target": "es2017",
15 | "lib": [
16 | "esnext",
17 | ]
18 | },
19 | "include": [
20 | "lib/**/*",
21 | "test/**/*"
22 | ],
23 | "exclude": [
24 | "node_modules/**/*"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/release_notes/v1.1.0-alpha.txt:
--------------------------------------------------------------------------------
1 | v1.1.0-alpha January 25, 2018
2 | -----------------------------
3 |
4 | Release Notes
5 | -------------
6 | No changes since v1.1.0-preview release
7 |
8 | Known Vulnerabilities
9 | ---------------------
10 | none
11 |
12 | Resolved Vulnerabilities
13 | ------------------------
14 | none
15 |
16 | Known Issues & Workarounds
17 | --------------------------
18 | none
19 |
20 | Change Log
21 | ----------
22 | https://github.com/hyperledger/fabric-ca/blob/master/CHANGELOG.md#v110-alpha
23 |
--------------------------------------------------------------------------------
/release_notes/v1.1.0-preview.txt:
--------------------------------------------------------------------------------
1 | v1.1.0-preview November 1, 2017
2 | -------------------------------
3 |
4 | Release Notes
5 | -------------
6 | Initial release of Node.js chaincode support
7 | https://jira.hyperledger.org/browse/FAB-5371
8 |
9 | Known Vulnerabilities
10 | ---------------------
11 | none
12 |
13 | Resolved Vulnerabilities
14 | ------------------------
15 | none
16 |
17 | Known Issues & Workarounds
18 | --------------------------
19 | none
20 |
21 | Change Log
22 | ----------
23 | https://github.com/hyperledger/fabric-ca/blob/master/CHANGELOG.md#v110-preview
24 |
--------------------------------------------------------------------------------
/release_notes/v1.1.0.txt:
--------------------------------------------------------------------------------
1 | v1.1.0 March, 2018
2 | -----------------------------
3 |
4 | Release Notes
5 | -------------
6 | Initial GA release of Node.js chaincode support.
7 | Includes bug fixes since v1.1.0-alpha release.
8 |
9 | Known Vulnerabilities
10 | ---------------------
11 | none
12 |
13 | Resolved Vulnerabilities
14 | ------------------------
15 | none
16 |
17 | Known Issues & Workarounds
18 | --------------------------
19 | none
20 |
21 | Change Log
22 | ----------
23 | https://github.com/hyperledger/fabric-chaincode-node/blob/release-1.1/CHANGELOG.md#v110
24 |
--------------------------------------------------------------------------------
/release_notes/v1.2.0.txt:
--------------------------------------------------------------------------------
1 | v1.2.0 July 6, 2018
2 | -----------------------------
3 |
4 | Release Notes
5 | -------------
6 | Add support for private data APIs.
7 | Bug fixes.
8 |
9 |
10 | Known Vulnerabilities
11 | ---------------------
12 | none
13 |
14 | Resolved Vulnerabilities
15 | ------------------------
16 | none
17 |
18 | Known Issues & Workarounds
19 | --------------------------
20 | none
21 |
22 | Change Log
23 | ----------
24 | https://github.com/hyperledger/fabric-chaincode-node/blob/release-1.2/CHANGELOG.md#v120
25 |
--------------------------------------------------------------------------------
/release_notes/v1.3.0.txt:
--------------------------------------------------------------------------------
1 | v1.3.0 October 10, 2018
2 | -----------------------------
3 |
4 | Release Notes
5 | -------------
6 | Bug fixes.
7 | Paging support for query.
8 | Typescript definitions are now included.
9 |
10 |
11 | Known Vulnerabilities
12 | ---------------------
13 | none
14 |
15 | Resolved Vulnerabilities
16 | ------------------------
17 | none
18 |
19 | Known Issues & Workarounds
20 | --------------------------
21 | none
22 |
23 | Change Log
24 | ----------
25 | https://github.com/hyperledger/fabric-chaincode-node/blob/release-1.3/CHANGELOG.md#v130
26 |
--------------------------------------------------------------------------------
/release_notes/v1.4.0-beta.txt:
--------------------------------------------------------------------------------
1 | v1.4.0-beta November 1, 2018
2 | -----------------------------
3 |
4 | Release Notes
5 | -------------
6 | Bug fixes.
7 | Added the fabric contract API
8 |
9 |
10 | Known Vulnerabilities
11 | ---------------------
12 | none
13 |
14 | Resolved Vulnerabilities
15 | ------------------------
16 | none
17 |
18 | Known Issues & Workarounds
19 | --------------------------
20 | none
21 |
22 | Change Log
23 | ----------
24 | https://github.com/hyperledger/fabric-chaincode-node/blob/master/CHANGELOG.md#v140-beta
25 |
--------------------------------------------------------------------------------
/release_notes/v1.4.0.txt:
--------------------------------------------------------------------------------
1 | v1.4.0-beta November 1, 2018
2 | -----------------------------
3 |
4 | Release Notes
5 | -------------
6 | Fabric 1.4.0 introduces a new programming model designed to improve developer productivity and ease of use.
7 | A new NPM package `fabric-contract-api` is added that lets the developer focus on the functions they want to invoke
8 | within the chaincode. They can also modularize their applications into 'Contracts' by extending a Contract class.
9 |
10 | See https://hyperledger-fabric.readthedocs.io/en/developapps/developing_applications.html
11 |
12 | To help client applications, and tooling and to make working with the transaction functions easier, a defined
13 | schema of Contract Metadata has been introduced. Depending on language a large part of this can be automatically created.
14 | Typescript Annotations are provided that are very useful in creating this data.
15 |
16 | See https://fabric-shim.github.io/contract-schema.json
17 |
18 |
19 | On the client application side, a new NPM package `fabric-network` is added which contains the classes and methods for writing
20 | blockchain enabled applications in node.js using javascript or typescript.
21 |
22 | See https://fabric-sdk-node.github.io/module-fabric-network.html
23 |
24 |
25 | Bug fixes and documentation improvements.
26 |
27 | Known Vulnerabilities
28 | ---------------------
29 | none
30 |
31 | Resolved Vulnerabilities
32 | ------------------------
33 | none
34 |
35 | Known Issues & Workarounds
36 | --------------------------
37 | none
38 |
39 | Change Log
40 | ----------
41 | https://github.com/hyperledger/fabric-chaincode-node/blob/master/CHANGELOG.md#v140
42 |
--------------------------------------------------------------------------------
/release_notes/v2.0.0-alpha.txt:
--------------------------------------------------------------------------------
1 | v2.0.0-alpha April 5th, 2019
2 | -----------------------------
3 |
4 | Release Notes
5 | -------------
6 | The main change in the v2.0.0 alpha over v1.4.1 is the level of NodeJS runtime has moved up to version 10
7 | v2.0.0 has v1.4.1 level of base functionality
8 |
9 | Migration Notes
10 | ---------------
11 | Note that a change needed to be made to the metadata schema as it was in error; it had diverged from the JSONSchema standard
12 | so that it was not possible to validate complex objects.
13 |
14 | If you have custom metadata defined in the contract, then for the complex objects defined in the 'components' section
15 | the properties of this object where previously held as array; they now need to be held as a map with the key as the name
16 | of the property
17 |
18 | Return types on functions where returned as an array of schema objects. this has been modified to be a single object. i.e.
19 | the single value array is now just a single value.
20 |
21 | There is also a new nodeenv docker image that is used for hosting the chaincode rather than use the baseos image.
22 |
23 | Summary of the programming model
24 | -------------------------------
25 |
26 | This is designed to improve developer productivity and ease of use.
27 | For more information see https://hyperledger-fabric.readthedocs.io/en/developapps/developing_applications.html
28 |
29 | Known Vulnerabilities
30 | ---------------------
31 | none
32 |
33 | Resolved Vulnerabilities
34 | ------------------------
35 | none
36 |
37 | Known Issues & Workarounds
38 | --------------------------
39 | none
40 |
41 | Change Log
42 | ----------
43 | https://github.com/hyperledger/fabric-chaincode-node/blob/release-1.4/CHANGELOG.md#v141
44 |
--------------------------------------------------------------------------------
/release_notes/v2.0.0-beta.txt:
--------------------------------------------------------------------------------
1 | v2.0.0-beta, 12 December 2019
2 | -----------------------------
3 |
4 | Release Notes
5 | -------------
6 | The main change in the v2.0.0 beta is the level of NodeJS runtime has moved up to the latest LTS version of v12.13.0
7 | v2.0.0 beta has the fixes from v1.4.4 level.
8 |
9 | Migration Notes
10 | ---------------
11 | Note that a change needed to be made to the metadata schema as it was in error; it had diverged from the JSONSchema standard
12 | so that it was not possible to validate complex objects.
13 |
14 | If you have custom metadata defined in the contract, then for the complex objects defined in the 'components' section
15 | the properties of this object where previously held as array; they now need to be held as a map with the key as the name
16 | of the property
17 |
18 | Return types on functions where returned as an array of schema objects. this has been modified to be a single object. i.e.
19 | the single value array is now just a single value.
20 |
21 | There is also a new nodeenv docker image that is used for hosting the chaincode rather than use the baseos image as in V1.4
22 |
23 | In v1.4, the fabric-contract-api had a dependency on the fabric-shim. This has changed in this version to have a dependency
24 | on the new fabric-shim-api module. This allows the fabric-contract-api to be used client side for annotations.
25 |
26 | For contributors, the v2.0.0 repo is built using rush and is organized as a full mono-repo.
27 |
28 | The @Object annotation has been deprecated in favour of the @DataType annotation
29 |
30 | The x509 library used for parsing has changed; this should be parse the X509 certificates exactly the same way; this is a note that
31 | differences are observed in the parsed certificates please raise an issue.
32 |
33 | Summary of the programming model
34 | -------------------------------
35 |
36 | This is designed to improve developer productivity and ease of use.
37 | For more information see https://hyperledger-fabric.readthedocs.io/en/developapps/developing_applications.html
38 |
39 | Known Vulnerabilities
40 | ---------------------
41 | none
42 |
43 | Resolved Vulnerabilities
44 | ------------------------
45 | none
46 |
47 | Known Issues & Workarounds
48 | --------------------------
49 | none
50 |
51 | Change Log
52 | ----------
53 | https://github.com/hyperledger/fabric-chaincode-node/blob/release-1.4/CHANGELOG.md#v2.0.0-beta
54 |
--------------------------------------------------------------------------------
/release_notes/v2.0.0.txt:
--------------------------------------------------------------------------------
1 | v2.0.0, 22 January 2020
2 | -----------------------
3 |
4 | Release Notes
5 | -------------
6 | The main change in the v2.0.0 is the level of NodeJS runtime has moved up to the latest LTS version of v12.13.0
7 | v2.0.0 has the fixes from v1.4.4 level.
8 |
9 | Migration Notes
10 | ---------------
11 | Note that a change needed to be made to the metadata schema as it was in error; it had diverged from the JSONSchema standard
12 | so that it was not possible to validate complex objects.
13 |
14 | If you have custom metadata defined in the contract, then for the complex objects defined in the 'components' section
15 | the properties of this object where previously held as array; they now need to be held as a map with the key as the name
16 | of the property
17 |
18 | Return types on functions where returned as an array of schema objects. this has been modified to be a single object. i.e.
19 | the single value array is now just a single value.
20 |
21 | There is also a new nodeenv docker image that is used for hosting the chaincode rather than use the baseos image as in V1.4
22 |
23 | In v1.4, the fabric-contract-api had a dependency on the fabric-shim. This has changed in this version to have a dependency
24 | on the new fabric-shim-api module. This allows the fabric-contract-api to be used client side for annotations.
25 |
26 | For contributors, the v2.0.0 repo is built using rush and is organized as a full mono-repo.
27 |
28 | The @Object annotation has been deprecated in favour of the @DataType annotation
29 |
30 | The x509 library used for parsing has changed; this should be parse the X509 certificates exactly the same way; this is a note that
31 | differences are observed in the parsed certificates please raise an issue.
32 |
33 | Summary of the programming model
34 | -------------------------------
35 |
36 | This is designed to improve developer productivity and ease of use.
37 | For more information see https://hyperledger-fabric.readthedocs.io/en/developapps/developing_applications.html
38 |
39 | Known Vulnerabilities
40 | ---------------------
41 | none
42 |
43 | Resolved Vulnerabilities
44 | ------------------------
45 | none
46 |
47 | Known Issues & Workarounds
48 | --------------------------
49 | none
50 |
51 | Change Log
52 | ----------
53 | https://github.com/hyperledger/fabric-chaincode-node/blob/release-2.x/CHANGELOG.md#v2.0.0
54 |
--------------------------------------------------------------------------------
/release_notes/v2.1.0.txt:
--------------------------------------------------------------------------------
1 | v2.1.0
2 | ------
3 |
4 | Release Notes
5 | -------------
6 | There are minimal changes between v2.0.0 and v2.1.0, please see the change log for a full list of updates.
7 |
8 | The release-2.0 branch has been renamed to release-2.x; the v2.1.0 release supercedes v2.0.0.
9 | The release-1.4 branch is currently LTS, please see the proposed Fabric LTS strategy for more information:
10 | https://github.com/hyperledger/fabric-rfcs/pull/23
11 |
12 | - FABCN-373 Added a compatibility.md file, explaining support for node and fabric versions
13 | - FABCN-381 Exposes a new shim function for returning the CORE_PEER_LOCALMSPID peer environment variable
14 |
15 | Change Log
16 | ----------
17 | https://github.com/hyperledger/fabric-chaincode-node/blob/release-2.x/CHANGELOG.md#v2.1.0
18 |
--------------------------------------------------------------------------------
/release_notes/v2.1.1.txt:
--------------------------------------------------------------------------------
1 | v2.1.1
2 | ------
3 |
4 | Release Notes
5 | -------------
6 | There are minimal changes between v2.1.0 and v2.1.1, please see the change log for a full list of updates.
7 |
8 | The release-2.0 branch has been renamed to release-2.x; the v2.1.0 release supercedes v2.0.0.
9 | The release-1.4 branch is currently LTS, please see the proposed Fabric LTS strategy for more information:
10 | https://github.com/hyperledger/fabric-rfcs/pull/23
11 |
12 | - FABCN-394 fabric-shim incorrectly implements interface ChaincodeStub from fabric-shim-api
13 |
14 | Change Log
15 | ----------
16 | https://github.com/hyperledger/fabric-chaincode-node/blob/release-2.x/CHANGELOG.md#v2.1.1
17 |
--------------------------------------------------------------------------------
/release_notes/v2.1.2.txt:
--------------------------------------------------------------------------------
1 | v2.1.2
2 | ------
3 |
4 | Release Notes
5 | -------------
6 |
7 | This release fixs a bug when querying more than 100 assets.
8 |
9 | The release-2.0 branch has been renamed to release-2.x; the v2.1.0 release supercedes v2.0.0.
10 | The release-1.4 branch is currently LTS, please see the proposed Fabric LTS strategy for more information:
11 | https://github.com/hyperledger/fabric-rfcs/pull/23
12 |
13 | Change Log
14 | ----------
15 | https://github.com/hyperledger/fabric-chaincode-node/blob/release-2.x/CHANGELOG.md#v2.1.2
16 |
--------------------------------------------------------------------------------
/release_notes/v2.1.3.txt:
--------------------------------------------------------------------------------
1 | v2.1.3
2 | ------
3 |
4 | Release Notes
5 | -------------
6 |
7 | Locks the version of the @grpc/grpc-js library to 1.0.3
8 | The updated grpc lirbary of 1.1.0 prevents the chaincode from contacting the peer.
9 |
10 | The release-2.0 branch has been renamed to release-2.x; the v2.1.0 release supercedes v2.0.0.
11 | The release-1.4 branch is currently LTS, please see the proposed Fabric LTS strategy for more information:
12 | https://github.com/hyperledger/fabric-rfcs/pull/23
13 |
14 | Change Log
15 | ----------
16 | https://github.com/hyperledger/fabric-chaincode-node/blob/release-2.x/CHANGELOG.md#v2.1.3
17 |
--------------------------------------------------------------------------------
/release_notes/v2.1.4.txt:
--------------------------------------------------------------------------------
1 | v2.1.4
2 | ------
3 |
4 | Release Notes
5 | -------------
6 |
7 | - FABCN-418 Dependency unable to use git
8 |
9 | Locks the version of the winston library to 3.2.1
10 | The updated winston library after 3.3.0 prevents chaincode installing due to
11 | a new requirement for git which is not available in the
12 | hyperledger/fabric-nodeenv docker image.
13 |
14 | The release-2.0 branch has been renamed to release-2.x; the v2.1.0 release supercedes v2.0.0.
15 | The release-1.4 branch is currently LTS, please see the proposed Fabric LTS strategy for more information:
16 | https://github.com/hyperledger/fabric-rfcs/pull/23
17 |
18 | Change Log
19 | ----------
20 | https://github.com/hyperledger/fabric-chaincode-node/blob/release-2.x/CHANGELOG.md#v2.1.4
21 |
--------------------------------------------------------------------------------
/release_notes/v2.2.0.txt:
--------------------------------------------------------------------------------
1 | v2.2.0
2 | ------
3 |
4 | Release Notes
5 | -------------
6 |
7 | The v2.2.0 release is the LTS version of the fabric-chaincode-node
8 |
9 |
10 | Change Log
11 | ----------
12 | https://github.com/hyperledger/fabric-chaincode-node/blob/release-2.x/CHANGELOG.md#v2.2.0
13 |
--------------------------------------------------------------------------------
/release_notes/v2.3.0.txt:
--------------------------------------------------------------------------------
1 | v2.3.0
2 | ------
3 |
4 | Release Notes
5 | -------------
6 |
7 | - Updated class transformer dependency
8 | - Fixed type for timestamp.second
9 | - OOM on Large Arg Size
10 | - Removed to.be.ok
11 | - Updated typescript and @types/node
12 | - Added release guide
13 |
14 |
15 | Change Log
16 | ----------
17 | https://github.com/hyperledger/fabric-chaincode-node/blob/release-2.x/CHANGELOG.md#v2.3.0
18 |
--------------------------------------------------------------------------------
/release_notes/v2.4.0-beta.txt:
--------------------------------------------------------------------------------
1 | v2.4.0-beta
2 | ------
3 |
4 | Release Notes
5 | -------------
6 | This v2.4.0-beta Release is a bug fix release of the main branch.
7 |
8 | Change Log
9 | ----------
10 | https://github.com/hyperledger/fabric-chaincode-node/blob/release-2.x/CHANGELOG.md#v2.4.0-beta
11 |
--------------------------------------------------------------------------------
/release_notes/v2.4.0.txt:
--------------------------------------------------------------------------------
1 | v2.4.0
2 | ------
3 |
4 | Release Notes
5 | -------------
6 | This v2.4.0 Release is a bug fix release of the main branch.
7 |
8 | Note that version of Node.js is updated to 16.4.0. See the COMPATIBILITY.md file in the main branch for information.
9 |
10 | Change Log
11 | ----------
12 | https://github.com/hyperledger/fabric-chaincode-node/blob/release-2.x/CHANGELOG.md#v2.4.0-beta
13 |
--------------------------------------------------------------------------------
/release_notes/v2.4.1.txt:
--------------------------------------------------------------------------------
1 | v2.4.1
2 | ------
3 |
4 | Release Notes
5 | -------------
6 | This v2.4.1 is a release for fix the CI pipeline to properly release docker images.
7 |
8 | Note that version of Node.js is updated to 16.4.0. See the COMPATIBILITY.md file in the main branch for information.
9 |
10 | Change Log
11 | ----------
12 | https://github.com/hyperledger/fabric-chaincode-node/blob/release-2.x/CHANGELOG.md#v2.4.1
13 |
--------------------------------------------------------------------------------
/release_notes/v2.4.2.txt:
--------------------------------------------------------------------------------
1 | v2.4.2
2 | ------
3 |
4 | Release Notes
5 | -------------
6 |
7 | This release corrects the 2.4 nodeenv docker image to be Node 16, and removes the fabric-shim-crypto package.
8 |
9 | Note that version of Node.js is updated to 16.4.0. See the COMPATIBILITY.md file in the main branch for information.
10 |
11 | See the change log for a full list of updates.
12 |
13 | Change Log
14 | ----------
15 | https://github.com/hyperledger/fabric-chaincode-node/blob/main/CHANGELOG.md#v2.4.2
16 |
--------------------------------------------------------------------------------
/release_notes/v2.5.0.txt:
--------------------------------------------------------------------------------
1 | v2.5.0
2 | ------
3 |
4 | Release Notes
5 | -------------
6 | This is the LTS Release of of the v2.5 Fabric Chaincode Node. It replaces the previous v2.2 LTS.
7 |
8 | - the PurgePrivateData feature is exposed via a new `PurgePrivateData` API
9 |
10 | Change Log
11 | ----------
12 | https://github.com/hyperledger/fabric-chaincode-node/blob/main/CHANGELOG.md#v2.5.0
13 |
--------------------------------------------------------------------------------
/release_notes/v2.5.1.txt:
--------------------------------------------------------------------------------
1 | v2.5.1
2 | ------
3 |
4 | Release Notes
5 | -------------
6 | This is the LTS Release of of the v2.5 Fabric Chaincode Node. It replaces the previous v2.2 LTS.
7 |
8 | - the PurgePrivateData feature is exposed via a new `PurgePrivateData` API
9 | - the grpc-js dependency has been locked to 1.8.1
10 | - arm docker builds
11 |
12 | Change Log
13 | ----------
14 | https://github.com/hyperledger/fabric-chaincode-node/blob/main/CHANGELOG.md#v2.5.0
15 |
--------------------------------------------------------------------------------
/release_notes/v2.5.2.txt:
--------------------------------------------------------------------------------
1 | v2.5.2
2 | ------
3 |
4 | Release Notes
5 | -------------
6 | This is the LTS Release of of the v2.5 Fabric Chaincode Node. It replaces the previous v2.2 LTS.
7 |
8 | New in the version 2.5.2
9 |
10 | - Fixed the getHistory API returning a byte buffer rather than an JSON object
11 | - Setting a state endorsement policy functions correctly
12 |
13 | Other noteable 2.5 updates are
14 |
15 | - the PurgePrivateData feature is exposed via a new `PurgePrivateData` API
16 | - the grpc-js dependency has been locked to 1.8.1
17 | - arm docker builds
18 |
19 | Change Log
20 | ----------
21 | https://github.com/hyperledger/fabric-chaincode-node/blob/main/CHANGELOG.md#v2.5.2
22 |
--------------------------------------------------------------------------------
/test/chaincodes/annotations/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ts_chaincode",
3 | "description": "Chaincode testing typescript functionality and annotations",
4 | "engines": {
5 | "node": ">=18"
6 | },
7 | "scripts": {
8 | "build": "tsc",
9 | "start": "fabric-chaincode-node start",
10 | "prestart": "tsc"
11 | },
12 | "main": "dist/index.js",
13 | "typings": "dist/index.d.ts",
14 | "engine-strict": true,
15 | "engineStrict": true,
16 | "version": "2.5.9",
17 | "author": "",
18 | "license": "APACHE-2.0",
19 | "dependencies": {
20 | "@types/node": "^16.11.4",
21 | "fabric-contract-api": "2.5.9",
22 | "fabric-shim": "2.5.9",
23 | "ts-node": "^3.3.0",
24 | "tslint": "^5.6.0",
25 | "typescript": "^4.0.2"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/test/chaincodes/annotations/src/index.ts:
--------------------------------------------------------------------------------
1 | import TestContract from './test_contract/test_contract';
2 | export const contracts: any[] = [ TestContract ];
--------------------------------------------------------------------------------
/test/chaincodes/annotations/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "dist",
4 | "target": "es2017",
5 | "moduleResolution": "node",
6 | "module": "commonjs",
7 | "declaration": true,
8 | "experimentalDecorators": true,
9 | "emitDecoratorMetadata": true,
10 | "lib": [
11 | "esnext"
12 | ]
13 | }
14 | }
--------------------------------------------------------------------------------
/test/chaincodes/clientidentity/chaincode.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 |
8 | const {Contract} = require('fabric-contract-api');
9 | const shim = require('fabric-shim');
10 |
11 | class ClientIdentityChaincode extends Contract {
12 |
13 | constructor() {
14 | super('org.mynamespace.clientidentity');
15 | }
16 |
17 | async instantiate(ctx) {
18 | const stub = ctx.stub;
19 |
20 | await stub.putState('string', Buffer.from('string'));
21 | const names = ['ann', 'beth', 'cory'];
22 | const colors = ['black', 'red', 'yellow'];
23 | for (const n in names) {
24 | for (const c in colors) {
25 | const compositeKey = stub.createCompositeKey('name~color', [names[n], colors[c]]);
26 | await stub.putState(compositeKey, names[n] + colors[c]);
27 | }
28 | }
29 | for (let i = 0; i < 5; i++) {
30 | await stub.putState(`key${i}`, Buffer.from(`value${i}`));
31 | await stub.putState(`jsonkey${i}`, Buffer.from(JSON.stringify({value: `value${i}`})));
32 | }
33 | }
34 |
35 | async clientIdentityInstance({stub}) {
36 | const cid = new shim.ClientIdentity(stub);
37 | return {mspId: cid.mspId, id: cid.id};
38 | }
39 |
40 | async localMspID({stub}) {
41 | const localMspID = stub.getMspID();
42 | return {localMspID};
43 | }
44 |
45 | }
46 | module.exports = ClientIdentityChaincode;
--------------------------------------------------------------------------------
/test/chaincodes/clientidentity/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | 'use strict';
8 |
9 | const Chaincode = require('./chaincode');
10 |
11 | module.exports.contracts = [Chaincode];
12 |
--------------------------------------------------------------------------------
/test/chaincodes/clientidentity/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chaincode",
3 | "description": "Chaincode testing ClientIdentity functionality",
4 | "engines": {
5 | "node": ">=18"
6 | },
7 | "scripts": {
8 | "start": "fabric-chaincode-node start"
9 | },
10 | "main": "index.js",
11 | "engine-strict": true,
12 | "engineStrict": true,
13 | "version": "2.5.9",
14 | "author": "",
15 | "license": "Apache-2.0",
16 | "dependencies": {
17 | "fabric-shim": "2.5.9",
18 | "fabric-contract-api": "2.5.9"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/chaincodes/crosschaincode/chaincode.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 |
8 | const {Contract} = require('fabric-contract-api');
9 |
10 | class CrossChaincode extends Contract {
11 |
12 | constructor() {
13 | super('org.mynamespace.crosschaincode');
14 | }
15 |
16 | async instantiate(ctx) {
17 | const stub = ctx.stub;
18 |
19 | await stub.putState('string', Buffer.from('string'));
20 | const names = ['ann', 'beth', 'cory'];
21 | const colors = ['black', 'red', 'yellow'];
22 | for (const n in names) {
23 | for (const c in colors) {
24 | const compositeKey = stub.createCompositeKey('name~color', [names[n], colors[c]]);
25 | await stub.putState(compositeKey, names[n] + colors[c]);
26 | }
27 | }
28 | for (let i = 0; i < 5; i++) {
29 | await stub.putState(`key${i}`, Buffer.from(`value${i}`));
30 | await stub.putState(`jsonkey${i}`, Buffer.from(JSON.stringify({value: `value${i}`})));
31 | }
32 | }
33 |
34 | async invokeChaincode({stub}) {
35 | const {params} = stub.getFunctionAndParameters();
36 | const results = await stub.invokeChaincode('crosschaincode2', [params[0], params[1]]);
37 | return results.payload.toString();
38 | }
39 |
40 | async invokeChaincodeError({stub}) {
41 | const {params} = stub.getFunctionAndParameters();
42 | const results = await stub.invokeChaincode('crosschaincode2', [params[0]]);
43 | return results;
44 | }
45 |
46 | }
47 | module.exports = CrossChaincode;
48 |
--------------------------------------------------------------------------------
/test/chaincodes/crosschaincode/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | 'use strict';
8 |
9 | const Chaincode = require('./chaincode');
10 |
11 | module.exports.contracts = [Chaincode];
12 |
--------------------------------------------------------------------------------
/test/chaincodes/crosschaincode/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chaincode",
3 | "description": "Chaincode testing cross chaincode functionality",
4 | "engines": {
5 | "node": ">=18"
6 | },
7 | "scripts": {
8 | "start": "set -x && CORE_CHAINCODE_LOGGING_LEVEL=debug fabric-chaincode-node start"
9 | },
10 | "main": "index.js",
11 | "engine-strict": true,
12 | "engineStrict": true,
13 | "version": "2.5.9",
14 | "author": "",
15 | "license": "Apache-2.0",
16 | "dependencies": {
17 | "fabric-shim": "2.5.9",
18 | "fabric-contract-api": "2.5.9"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/chaincodes/crosschaincode2/chaincode.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 |
8 | const {Contract} = require('fabric-contract-api');
9 |
10 | class CrossChaincode2 extends Contract {
11 |
12 | constructor() {
13 | super('org.mynamespace.crosschaincode2');
14 | }
15 |
16 | async instantiate(ctx) {
17 | const stub = ctx.stub;
18 | await stub.putState('key1', Buffer.from('crosschaincode2'));
19 | }
20 |
21 | // useful helper transactions
22 | async getKey({stub}) {
23 | const {params} = stub.getFunctionAndParameters();
24 | if (params.length !== 1) {
25 | throw new Error('Incorrect no. of parameters');
26 | }
27 | const key = params[0];
28 | return (await stub.getState(key)).toString();
29 | }
30 |
31 | }
32 | module.exports = CrossChaincode2;
--------------------------------------------------------------------------------
/test/chaincodes/crosschaincode2/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 |
8 | const Chaincode = require('./chaincode');
9 |
10 | module.exports.contracts = [Chaincode];
11 |
--------------------------------------------------------------------------------
/test/chaincodes/crosschaincode2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chaincode",
3 | "description": "Chaincode testing cross chaincode functionality",
4 | "engines": {
5 | "node": ">=18"
6 | },
7 | "scripts": {
8 | "start": "fabric-chaincode-node start"
9 | },
10 | "main": "index.js",
11 | "engine-strict": true,
12 | "engineStrict": true,
13 | "version": "2.5.9",
14 | "author": "",
15 | "license": "Apache-2.0",
16 | "dependencies": {
17 | "fabric-shim": "2.5.9",
18 | "fabric-contract-api": "2.5.9"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/chaincodes/crud/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | 'use strict';
8 |
9 | const Chaincode = require('./chaincode');
10 |
11 | module.exports.contracts = [Chaincode];
12 |
--------------------------------------------------------------------------------
/test/chaincodes/crud/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chaincode",
3 | "description": "Chaincode testing crud functionality",
4 | "engines": {
5 | "node": ">=18"
6 | },
7 | "scripts": {
8 | "start": "set -x && CORE_CHAINCODE_LOGGING_LEVEL=debug fabric-chaincode-node start"
9 | },
10 | "main": "index.js",
11 | "engine-strict": true,
12 | "engineStrict": true,
13 | "version": "2.5.9",
14 | "author": "",
15 | "license": "Apache-2.0",
16 | "dependencies": {
17 | "fabric-shim": "2.5.9",
18 | "fabric-contract-api": "2.5.9"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/chaincodes/events/chaincode.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 |
8 | const {Contract} = require('fabric-contract-api');
9 |
10 | class EventsChaincode extends Contract {
11 |
12 | constructor() {
13 | super('org.mynamespace.events');
14 | this.logBuffer = {output: []};
15 | }
16 |
17 | async instantiate(ctx) {
18 |
19 | }
20 |
21 | async emit(ctx, value) {
22 | const buffer = Buffer.from(value);
23 | ctx.stub.setEvent('myevent', buffer);
24 | }
25 |
26 | }
27 | module.exports = EventsChaincode;
28 |
--------------------------------------------------------------------------------
/test/chaincodes/events/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | 'use strict';
8 |
9 | const Chaincode = require('./chaincode');
10 |
11 | module.exports.contracts = [Chaincode];
12 |
--------------------------------------------------------------------------------
/test/chaincodes/events/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chaincode",
3 | "description": "Chaincode testing events functionality",
4 | "engines": {
5 | "node": ">=18"
6 | },
7 | "scripts": {
8 | "start": "set -x && CORE_CHAINCODE_LOGGING_LEVEL=debug fabric-chaincode-node start"
9 | },
10 | "main": "index.js",
11 | "engine-strict": true,
12 | "engineStrict": true,
13 | "version": "2.5.9",
14 | "author": "",
15 | "license": "Apache-2.0",
16 | "dependencies": {
17 | "fabric-shim": "2.5.9",
18 | "fabric-contract-api": "2.5.9"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/chaincodes/ledger/chaincode.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 |
8 | const {Contract} = require('fabric-contract-api');
9 | const {Ledger} = require('fabric-ledger');
10 |
11 | class LedgerTestContract extends Contract {
12 |
13 | constructor() {
14 | super('org.example.ledger');
15 | this.logBuffer = {output: []};
16 | }
17 |
18 | async getLedger(ctx) {
19 | const ledger = Ledger.getLedger(ctx);
20 |
21 | return ledger?'success':'fail';
22 | }
23 | }
24 | module.exports = LedgerTestContract;
25 |
--------------------------------------------------------------------------------
/test/chaincodes/ledger/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | 'use strict';
8 |
9 | const Chaincode = require('./chaincode');
10 |
11 | module.exports.contracts = [Chaincode];
12 |
--------------------------------------------------------------------------------
/test/chaincodes/ledger/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chaincode",
3 | "description": "Chaincode testing ledger functionality",
4 | "engines": {
5 | "node": ">=18"
6 | },
7 | "scripts": {
8 | "start": "fabric-chaincode-node start"
9 | },
10 | "main": "index.js",
11 | "engine-strict": true,
12 | "engineStrict": true,
13 | "version": "2.5.9",
14 | "author": "",
15 | "license": "Apache-2.0",
16 | "dependencies": {
17 | "fabric-shim": "2.5.9",
18 | "fabric-contract-api": "2.5.9",
19 | "fabric-ledger": "2.5.9"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/test/chaincodes/privateData/chaincode.js:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | 'use strict';
6 |
7 | const { Contract } = require('fabric-contract-api');
8 | const crypto = require('crypto');
9 |
10 | class privateDataContract extends Contract {
11 |
12 | async assetExists(ctx, assetId) {
13 | const data = await ctx.stub.getPrivateDataHash("collection", assetId);
14 | return (!!data && data.length > 0);
15 | }
16 |
17 | async createAsset(ctx, assetId) {
18 | const exists = await this.assetExists(ctx, assetId);
19 | if (exists) {
20 | throw new Error(`The asset asset ${assetId} already exists`);
21 | }
22 |
23 | const privateAsset = {};
24 |
25 | const transientData = ctx.stub.getTransient();
26 | if (transientData.size === 0 || !transientData.has('privateValue')) {
27 | throw new Error('The privateValue key was not specified in transient data. Please try again.');
28 | }
29 | privateAsset.privateValue = transientData.get('privateValue').toString();
30 |
31 | await ctx.stub.putPrivateData("collection", assetId, Buffer.from(JSON.stringify(privateAsset)));
32 | }
33 |
34 | async readAsset(ctx, assetId) {
35 | const exists = await this.assetExists(ctx, assetId);
36 | if (!exists) {
37 | throw new Error(`The asset ${assetId} does not exist`);
38 | }
39 | let privateDataString;
40 | const privateData = await ctx.stub.getPrivateData("collection", assetId);
41 | privateDataString = JSON.parse(privateData.toString());
42 | return privateDataString;
43 | }
44 |
45 | async updateAsset(ctx, assetId) {
46 | const exists = await this.assetExists(ctx, assetId);
47 | if (!exists) {
48 | throw new Error(`The asset asset ${assetId} does not exist`);
49 | }
50 | const privateAsset = {};
51 |
52 | const transientData = ctx.stub.getTransient();
53 | if (transientData.size === 0 || !transientData.has('privateValue')) {
54 | throw new Error('The privateValue key was not specified in transient data. Please try again.');
55 | }
56 | privateAsset.privateValue = transientData.get('privateValue').toString();
57 |
58 | await ctx.stub.putPrivateData("collection", assetId, Buffer.from(JSON.stringify(privateAsset)));
59 | }
60 |
61 | async deleteAsset(ctx, assetId) {
62 | const exists = await this.assetExists(ctx, assetId);
63 | if (!exists) {
64 | throw new Error(`The asset asset ${assetId} does not exist`);
65 | }
66 | await ctx.stub.deletePrivateData("collection", assetId);
67 | }
68 |
69 | async purgeAsset(ctx, assetId) {
70 | const exists = await this.assetExists(ctx, assetId);
71 | if (!exists) {
72 | throw new Error(`The asset asset ${assetId} does not exist`);
73 | }
74 | await ctx.stub.purgePrivateData("collection", assetId);
75 | }
76 |
77 | async verifyAsset(ctx, mspid, assetId, objectToVerify) {
78 |
79 | const hashToVerify = crypto.createHash('sha256').update(objectToVerify).digest('hex');
80 | const pdHashBytes = await ctx.stub.getPrivateDataHash("collection", assetId);
81 | if (pdHashBytes.length === 0) {
82 | throw new Error('No private data hash with the key: ' + assetId);
83 | }
84 |
85 | const actualHash = Buffer.from(pdHashBytes).toString('hex');
86 |
87 | if (hashToVerify === actualHash) {
88 | return true;
89 | } else {
90 | return false;
91 | }
92 | }
93 | }
94 |
95 | module.exports = privateDataContract;
96 |
--------------------------------------------------------------------------------
/test/chaincodes/privateData/collection-config/collection.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "collection",
4 | "policy": "OR('Org1MSP.member', 'Org2MSP.member')",
5 | "requiredPeerCount": 1,
6 | "maxPeerCount": 1,
7 | "blockToLive":1000000,
8 | "memberOnlyRead": true,
9 | "memberOnlyWrite": true
10 | }
11 | ]
12 |
--------------------------------------------------------------------------------
/test/chaincodes/privateData/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | */
4 |
5 | 'use strict';
6 |
7 | const Chaincode = require('./chaincode');
8 |
9 | module.exports.contracts = [Chaincode];
10 |
11 |
--------------------------------------------------------------------------------
/test/chaincodes/privateData/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chaincode",
3 | "description": "Chaincode testing private data functionality",
4 | "engines": {
5 | "node": ">=18"
6 | },
7 | "scripts": {
8 | "start": "fabric-chaincode-node start"
9 | },
10 | "main": "index.js",
11 | "engine-strict": true,
12 | "engineStrict": true,
13 | "version": "2.5.9",
14 | "author": "",
15 | "license": "Apache-2.0",
16 | "dependencies": {
17 | "fabric-shim": "2.5.9",
18 | "fabric-contract-api": "2.5.9"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/chaincodes/query/chaincode.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 |
8 | const {Contract} = require('fabric-contract-api');
9 |
10 | async function getAllResults(iterator, getKeys) {
11 | const allResults = [];
12 | let loop = true;
13 | while (loop) {
14 | const res = await iterator.next();
15 | if (!res.value && res.done) {
16 | await iterator.close();
17 | return allResults;
18 | } else if (!res.value) {
19 | throw new Error('no value and not done (internal error?)');
20 | }
21 | const theVal = (getKeys) ? res.value.key : res.value.value.toString('utf8');
22 | allResults.push(JSON.parse(theVal));
23 | if (res.done) {
24 | await iterator.close();
25 | loop = false;
26 | return allResults;
27 | }
28 | }
29 | }
30 |
31 | class QueryChaincode extends Contract {
32 |
33 | async unknownTransaction({stub}) {
34 | throw new Error(`Could not find chaincode function: ${stub.getFunctionAndParameters()}`);
35 | }
36 |
37 | constructor() {
38 | super('org.mynamespace.query');
39 | }
40 |
41 | async instantiate(ctx) {
42 | const stub = ctx.stub;
43 |
44 | await stub.putState('string', Buffer.from('string'));
45 | const names = ['ann', 'beth', 'cory'];
46 | const colors = ['black', 'red', 'yellow'];
47 | for (const n in names) {
48 | for (const c in colors) {
49 | const compositeKey = stub.createCompositeKey('name~color', [names[n], colors[c]]);
50 | await stub.putState(compositeKey, names[n] + colors[c]);
51 | }
52 | }
53 | for (let i = 0; i < 5; i++) {
54 | await stub.putState(`jsonkey${i}`, Buffer.from(JSON.stringify({value: `value${i}`})));
55 | }
56 | }
57 |
58 | async query({stub}, query) {
59 | const iterator = await stub.getQueryResult(query);
60 | const results = await getAllResults(iterator);
61 | return JSON.stringify(results);
62 | }
63 |
64 | }
65 | module.exports = QueryChaincode;
66 |
--------------------------------------------------------------------------------
/test/chaincodes/query/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | 'use strict';
8 |
9 | const Chaincode = require('./chaincode');
10 |
11 | module.exports.contracts = [Chaincode];
12 |
--------------------------------------------------------------------------------
/test/chaincodes/query/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chaincode",
3 | "description": "Chaincode testing query functionality",
4 | "engines": {
5 | "node": ">=18"
6 | },
7 | "scripts": {
8 | "start": "fabric-chaincode-node start"
9 | },
10 | "main": "index.js",
11 | "engine-strict": true,
12 | "engineStrict": true,
13 | "version": "2.5.9",
14 | "author": "",
15 | "license": "Apache-2.0",
16 | "dependencies": {
17 | "fabric-shim": "2.5.9",
18 | "fabric-contract-api": "2.5.9"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/chaincodes/scenario/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | 'use strict';
8 |
9 | const UpdateValues = require('./updatevalues');
10 | const RemoveValues = require('./removevalues');
11 |
12 | // export the smart contracts
13 | module.exports.contracts = [UpdateValues, RemoveValues];
14 |
--------------------------------------------------------------------------------
/test/chaincodes/scenario/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chaincode",
3 | "description": "My first exciting chaincode implemented in node.js",
4 | "engines": {
5 | "node": ">=18"
6 | },
7 | "scripts": {
8 | "start": "fabric-chaincode-node start"
9 | },
10 | "main": "index.js",
11 | "engine-strict": true,
12 | "engineStrict": true,
13 | "version": "2.5.9",
14 | "author": "",
15 | "license": "Apache-2.0",
16 | "dependencies": {
17 | "fabric-shim": "2.5.9",
18 | "fabric-contract-api": "2.5.9"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/chaincodes/scenario/removevalues.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 | /* eslint-disable no-console */
8 | const {Contract} = require('fabric-contract-api');
9 |
10 | /**
11 | * Set of functions to support modifing the values
12 | */
13 | class RemoveValues extends Contract {
14 |
15 | constructor() {
16 | super('RemoveValues');
17 | // going to leave the default 'not known function' handling alone
18 | }
19 |
20 | /**
21 | *
22 | * @param {*} api
23 | */
24 | async quarterAssetValue({stub}) {
25 | console.info('Transaction ID: ' + stub.getTxID());
26 |
27 | const value = await stub.getState('dummyKey');
28 | if (Number.isNan(value)) {
29 | const str = `'Need to have numerc value set to quarter it, ${value}`;
30 | console.error(str);
31 | throw new Error(str);
32 | } else {
33 | const v = value / 4;
34 | await stub.putState('dummyKey', v);
35 | return v;
36 | }
37 | }
38 |
39 |
40 | async getAssetValue({stub}) {
41 | console.info('Transaction ID: ' + stub.getTxID());
42 |
43 | const value = await stub.getState('dummyKey');
44 | return value;
45 | }
46 |
47 | }
48 |
49 | module.exports = RemoveValues;
50 |
--------------------------------------------------------------------------------
/test/chaincodes/scenario/scenariocontext.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | 'use strict';
8 |
9 | const {Context} = require('fabric-contract-api');
10 |
11 | class ScenarioContext extends Context {
12 |
13 | constructor() {
14 | super();
15 | }
16 |
17 |
18 | generateKey() {
19 | return this.stub.createCompositeKey('type', ['keyvalue']);
20 | }
21 |
22 | }
23 |
24 | module.exports = ScenarioContext;
25 |
--------------------------------------------------------------------------------
/test/chaincodes/scenario/updatevalues.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright IBM Corp. All Rights Reserved.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | 'use strict';
8 |
9 | const {Contract} = require('fabric-contract-api');
10 |
11 | const ScenarioContext = require('./scenariocontext');
12 | /**
13 | * Support the Updating of values within the SmartContract
14 | */
15 | class UpdateValues extends Contract {
16 |
17 | _log(args) {
18 | this.logBuffer.output.push(`::[UpdateValues] ${args}`);
19 | }
20 | /**
21 | * Sets a name so that the functions in this particular class can
22 | * be separated from others.
23 | */
24 | constructor() {
25 | super('UpdateValues');
26 | this.logBuffer = {output: []};
27 | }
28 |
29 | /** The function to invoke if something unkown comes in.
30 | *
31 | */
32 | async unknownTransaction(ctx) {
33 | throw new Error('Big Friendly letters ->>> DON\'T PANIC');
34 | }
35 |
36 | async beforeTransaction(ctx) {
37 | this._log(`Transaction ID: ${ctx.stub.getTxID()}`);
38 | }
39 |
40 | /**
41 | * Custom context for use within this contract
42 | */
43 | createContext() {
44 | return new ScenarioContext();
45 | }
46 |
47 | /**
48 | * A function that will setup a starting value
49 | * Note that this is not expliclity called from init. IF you want it called from init, then
50 | * specifiy it in the fn name when init is invoked.
51 | */
52 | async setup(ctx) {
53 | await ctx.stub.putState(ctx.generateKey(), Buffer.from('Starting Value'));
54 |
55 | this._log('Put state success');
56 | return Buffer.from(JSON.stringify(this.logBuffer));
57 | }
58 |
59 | /**
60 | * @param {int|string} newAssetValue new asset value to set
61 | */
62 | async setNewAssetValue(ctx, newAssetValue) {
63 | this._log(`New Asset value will be ${newAssetValue}`);
64 | await ctx.stub.putState(ctx.generateKey(), Buffer.from(newAssetValue));
65 |
66 | return Buffer.from(JSON.stringify(this.logBuffer));
67 | }
68 |
69 | /**
70 | * Doubles the api if it is a number fail otherwise
71 | */
72 | async doubleAssetValue(ctx) {
73 | const value = await ctx.stub.getState(ctx.generateKey());
74 | if (isNaN(value)) {
75 | const str = `'Need to have numerc value set to double it, ${value}`;
76 | this._log(str);
77 | throw new Error(str);
78 | } else {
79 | const v = value * 2;
80 | await ctx.stub.putState(ctx.generateKey(), v);
81 | this.logBuffer.result = v;
82 | }
83 | return Buffer.from(JSON.stringify(this.logBuffer));
84 | }
85 |
86 | }
87 |
88 | module.exports = UpdateValues;
89 |
--------------------------------------------------------------------------------
/test/chaincodes/server/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | package.lock.json
3 | package
4 |
--------------------------------------------------------------------------------
/test/chaincodes/server/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM hyperledger/fabric-nodeenv:latest
2 |
3 | ADD . /opt/chaincode
4 | RUN cd /opt/chaincode; npm install
5 |
6 | WORKDIR /opt/chaincode
7 | ENTRYPOINT ["npm", "start"]
8 |
--------------------------------------------------------------------------------
/test/chaincodes/server/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright Hitachi America, Ltd. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | "use strict";
7 |
8 | const { Contract } = require('fabric-contract-api');
9 |
10 | class ServerTestChaincode extends Contract {
11 | async unknownTransaction({stub}) {
12 | const {fcn, params} = stub.getFunctionAndParameters();
13 | throw new Error(`Could not find chaincode function: ${fcn}`);
14 | }
15 |
16 | constructor() {
17 | super('org.mynamespace.server');
18 | }
19 |
20 | async putValue(ctx, value) {
21 | await ctx.stub.putState('state1', Buffer.from(JSON.stringify(value)));
22 | }
23 |
24 | async getValue(ctx) {
25 | const value = await ctx.stub.getState('state1');
26 | return JSON.parse(value.toString());
27 | }
28 | }
29 |
30 | exports.contracts = [ ServerTestChaincode ];
31 |
--------------------------------------------------------------------------------
/test/chaincodes/server/package/connection.json:
--------------------------------------------------------------------------------
1 | {
2 | "address": "cc-server:9999",
3 | "dial_timeout": "10s",
4 | "tls_required": false
5 | }
6 |
--------------------------------------------------------------------------------
/test/chaincodes/server/package/metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": "",
3 | "type": "external",
4 | "label": "server_v0"
5 | }
6 |
--------------------------------------------------------------------------------
/test/constants.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 |
8 | const peerAddress = 'peer0.org1.example.com:7052';
9 |
10 | module.exports.peerAddress = peerAddress;
11 |
--------------------------------------------------------------------------------
/test/e2e/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fabric-e2e-tests",
3 | "version": "2.5.9",
4 | "description": "",
5 | "main": "docker.js",
6 | "scripts": {
7 | "build": "",
8 | "test:e2e": "gulp -f ./scenario.js --reporter spec-junit-splitter-mocha-reporter 2>&1"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "Apache-2.0",
13 | "devDependencies": {
14 | "git-rev-sync": "3.0.1",
15 | "gulp": "^4.0.2",
16 | "toolchain": "1.0.0-dev",
17 | "delay": "5.0.0",
18 | "ip": "^1.1.5",
19 | "ajv": "^6.12.2",
20 | "ajv-cli": "^3.2.1",
21 | "spec-junit-splitter-mocha-reporter": "1.0.1"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/test/fixtures/channel-init.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright London Stock Exchange Group All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | #
6 | CHANNEL_NAME="$1"
7 | : ${CHANNEL_NAME:="mychannel"}
8 | : ${TIMEOUT:="60"}
9 | COUNTER=1
10 | MAX_RETRY=5
11 | GENESIS_LOCATION=/etc/hyperledger/config
12 | ORDERER_CA=/etc/hyperledger/config/crypto-config/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem
13 |
14 | echo "Channel name : "$CHANNEL_NAME
15 |
16 | verifyResult () {
17 | if [ $1 -ne 0 ] ; then
18 | echo "!!!!!!!!!!!!!!! "$2" !!!!!!!!!!!!!!!!"
19 | echo "================== ERROR !!! FAILED to execute Test Init =================="
20 | echo
21 | exit 1
22 | fi
23 | }
24 |
25 | ## Sometimes Join takes time hence RETRY atleast for 5 times
26 | joinWithRetry () {
27 | peer channel join -b $GENESIS_LOCATION/$CHANNEL_NAME.block >&log.txt
28 | res=$?
29 | cat log.txt
30 | if [ $res -ne 0 -a $COUNTER -lt $MAX_RETRY ]; then
31 | COUNTER=` expr $COUNTER + 1`
32 | echo "PEER0 failed to join the channel, Retry after 2 seconds"
33 | sleep 2
34 | joinWithRetry
35 | else
36 | COUNTER=1
37 | fi
38 | verifyResult $res "After $MAX_RETRY attempts, PEER0 has failed to Join the Channel"
39 | }
40 |
41 | joinChannel () {
42 | joinWithRetry
43 | echo "===================== PEER0 joined on the channel \"$CHANNEL_NAME\" ===================== "
44 | sleep 2
45 | echo
46 | }
47 |
48 | ## Join all the peers to the channel
49 | echo "Having all peers join the channel..."
50 | joinChannel
51 |
52 | exit 0
53 |
--------------------------------------------------------------------------------
/test/fixtures/kill-chaincode-node.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 |
6 | kill $(ps aux | awk '/--peer.address/ {print $1}')
7 | kill $(ps aux | awk '/--peer.address/ {print $2}')
--------------------------------------------------------------------------------
/test/fv/annotations.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use-strict';
7 |
8 | const fs = require('fs');
9 | const path = require('path');
10 | const Ajv = require('ajv');
11 | const chai = require('chai');
12 | chai.use(require('chai-as-promised'));
13 | const expect = chai.expect;
14 | const utils = require('./utils');
15 | const {SHORT_STEP, LONG_STEP} = utils.TIMEOUTS;
16 |
17 | describe('Typescript chaincode', () => {
18 | const suite = 'annotations';
19 | utils.registerAndEnroll();
20 |
21 | before(async function () {
22 | this.timeout(LONG_STEP);
23 | return utils.installAndInstantiate(suite);
24 | });
25 |
26 |
27 | describe('Scenario', () => {
28 |
29 | it('should write an asset', async function () {
30 | this.timeout(LONG_STEP);
31 | await utils.invoke(suite, 'TestContract:createAsset', ['GLD', 'GOLD_BAR', '100', 'EXTRA_ID', '50']);
32 | const payload = JSON.parse(await utils.query(suite, 'TestContract:getAsset', ['GLD']));
33 | expect(payload).to.eql({id: 'GLD', name: 'GOLD_BAR', value: 100, extra: {id: 'EXTRA_ID', value: 50}});
34 | });
35 |
36 | it('should update an asset', async function() {
37 | this.timeout(SHORT_STEP);
38 | await utils.invoke(suite, 'TestContract:updateAsset', [JSON.stringify({id: 'GLD', name: 'GOLD_BAR', value: 200, extra: {id: 'EXTRA_ID', value: 100}})]);
39 | const payload = JSON.parse(await utils.query(suite, 'TestContract:getAsset', ['GLD']));
40 | expect(payload).to.eql({id: 'GLD', name: 'GOLD_BAR', value: 200, extra: {id: 'EXTRA_ID', value: 100}});
41 | });
42 |
43 | it('should handle the getMetadata', async function () {
44 | this.timeout(SHORT_STEP);
45 | const payload = JSON.parse(await utils.query(suite, 'org.hyperledger.fabric:GetMetadata'));
46 |
47 | const schema = fs.readFileSync(path.join(__dirname, '../../apis/fabric-contract-api/schema/contract-schema.json'));
48 |
49 | const ajv = new Ajv({schemaId: 'id'});
50 | ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-04.json'));
51 |
52 | if (!ajv.validate(JSON.parse(schema), payload)) {
53 | throw new Error('Expected generated metadata to match the schema');
54 | }
55 |
56 | const expectedMetadata = fs.readFileSync(path.join(__dirname, '../chaincodes/annotations/src/test_contract/expected-metadata.json'));
57 | expect(payload).to.eql(JSON.parse(expectedMetadata));
58 | });
59 |
60 | });
61 |
62 | });
63 |
--------------------------------------------------------------------------------
/test/fv/clientidentity.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 |
8 | const chai = require('chai');
9 | chai.use(require('chai-as-promised'));
10 | const expect = chai.expect;
11 | const utils = require('./utils');
12 | const {MED_STEP, LONG_STEP} = utils.TIMEOUTS;
13 |
14 | describe('Chaincode clientidentity', () => {
15 | const suite = 'clientidentity';
16 |
17 | before(async function () {
18 | this.timeout(LONG_STEP);
19 |
20 | return utils.installAndInstantiate(suite, 'org.mynamespace.clientidentity:instantiate');
21 | });
22 |
23 | it('should create an instance of the client identity class', async function () {
24 | this.timeout(MED_STEP);
25 |
26 | const payload = JSON.parse(await utils.query(suite, 'org.mynamespace.clientidentity:clientIdentityInstance', []));
27 | expect(payload.mspId).to.equal('Org2MSP', 'Test mspId value');
28 | expect(payload.id).to.equal('x509::/C=US/ST=North Carolina/O=Hyperledger/OU=client/CN=buyer::/C=UK/ST=Hampshire/L=Hursley/O=org2.example.com/CN=ca.org2.example.com', 'Test getID()');
29 | });
30 |
31 | it('should be able to check the peer MSPID', async function () {
32 | this.timeout(MED_STEP);
33 |
34 | const payload = JSON.parse(await utils.query(suite, 'org.mynamespace.clientidentity:localMspID', []));
35 | expect(payload.localMspID).to.equal('Org2MSP', 'Test stub.getMspID()');
36 | });
37 |
38 | });
--------------------------------------------------------------------------------
/test/fv/crosschaincode.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 |
8 | const chai = require('chai');
9 | chai.use(require('chai-as-promised'));
10 | const expect = chai.expect;
11 | const utils = require('./utils');
12 | const {LONG_STEP, LONGEST_STEP} = utils.TIMEOUTS;
13 |
14 | describe('Chaincode crosschaincode', () => {
15 | const suite = 'crosschaincode';
16 | const suite2 = 'crosschaincode2';
17 |
18 | before(async function () {
19 | this.timeout(LONG_STEP);
20 |
21 | await utils.installAndInstantiate(suite, 'org.mynamespace.crosschaincode:instantiate');
22 | await utils.installAndInstantiate(suite2, 'org.mynamespace.crosschaincode2:instantiate');
23 |
24 | // kick crosschaincode2 on org2 - shouldn't need this!
25 | await utils.query(suite2, 'org.mynamespace.crosschaincode2:getKey', ['key1']);
26 | });
27 |
28 | describe('Invoke', () => {
29 |
30 | it('should invoke chaincode', async function () {
31 | this.timeout(LONGEST_STEP);
32 |
33 | const payload = await utils.query(suite, 'org.mynamespace.crosschaincode:invokeChaincode', ['getKey', 'key1']);
34 | expect(payload).to.equal('crosschaincode2');
35 | });
36 |
37 | it('should throw an error when invoking chaincode', async function () {
38 | this.timeout(LONGEST_STEP);
39 |
40 | const payload = await utils.query(suite, 'org.mynamespace.crosschaincode:invokeChaincodeError', ['getKey']);
41 | expect(payload).to.match(/Incorrect no. of parameters/);
42 | });
43 |
44 | });
45 |
46 | });
47 |
--------------------------------------------------------------------------------
/test/fv/crosschaincode2.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 |
8 | /*
9 | * Mock mocha file to allow for the packed modules to be copied correctly over.
10 | */
--------------------------------------------------------------------------------
/test/fv/events.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 |
8 | const chai = require('chai');
9 | chai.use(require('chai-as-promised'));
10 | const expect = chai.expect;
11 | const utils = require('./utils');
12 | const {LONG_STEP} = utils.TIMEOUTS;
13 |
14 | describe('Chaincode events', async function () {
15 | const suite = 'events';
16 |
17 | before(async function () {
18 | this.timeout(LONG_STEP);
19 |
20 | return utils.installAndInstantiate(suite, 'org.mynamespace.events:instantiate');
21 | });
22 |
23 | it('should publish an event', async function () {
24 | this.timeout(LONG_STEP);
25 |
26 | const date = new Date().toISOString();
27 | await utils.invoke(suite, 'org.mynamespace.events:emit', [`my event data @ ${date}`]);
28 | const block = await utils.getLastBlock();
29 | expect(block.data.data.length).to.equal(1); // only one transaction
30 | const transaction = block.data.data[0];
31 | const actions = transaction.payload.data.actions;
32 | expect(actions.length).to.equal(1); // only one action
33 | const action = actions[0];
34 | const proposalResponsePayload = action.payload.action.proposal_response_payload;
35 | const events = proposalResponsePayload.extension.events;
36 | expect(events.chaincode_id).to.equal('events');
37 | expect(events.event_name).to.equal('myevent');
38 | const payload = Buffer.from(events.payload, 'base64').toString();
39 | expect(payload).to.equal(`my event data @ ${date}`);
40 | });
41 |
42 | });
43 |
--------------------------------------------------------------------------------
/test/fv/ledger.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 |
8 | const chai = require('chai');
9 | chai.use(require('chai-as-promised'));
10 | const expect = chai.expect;
11 | const utils = require('./utils');
12 | const {SHORT_STEP, MED_STEP, LONG_STEP} = utils.TIMEOUTS;
13 |
14 | describe('Chaincode ledger', () => {
15 | const suite = 'ledger';
16 |
17 | before(async function () {
18 | this.timeout(LONG_STEP);
19 |
20 | return utils.installAndInstantiate(suite);
21 | });
22 |
23 | it('should be able to use the ledger API', async function () {
24 | this.timeout(LONG_STEP);
25 |
26 | const payload = await utils.query(suite, 'org.example.ledger:getLedger', ['']);
27 | expect(payload).to.equal('success');
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/test/fv/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fvtests",
3 | "version": "2.5.9",
4 | "description": "fv tests",
5 | "testFabricVersion": "main",
6 | "testFabricThirdParty": "0.4.15",
7 | "docsLatestVersion": "release-1.4",
8 | "engines": {
9 | "node": ">=18"
10 | },
11 | "engineStrict": true,
12 | "license": "Apache-2.0",
13 | "scripts": {
14 | "hello": "echo test fv project",
15 | "test:fv": "mocha *.js --reporter spec-junit-splitter-mocha-reporter 2>&1",
16 | "build": ""
17 | },
18 | "dependencies": {
19 | "@sinonjs/referee-sinon": "~5.0.0",
20 | "ajv": "^6.12.2",
21 | "ajv-cli": "^3.2.1",
22 | "chai": "^4.3.4",
23 | "chai-as-promised": "^7.1.1",
24 | "chai-things": "^0.2.0",
25 | "del": "^3.0.0",
26 | "delay": "5.0.0",
27 | "eslint": "^6.6.0",
28 | "fabric-contract-api": "2.5.9",
29 | "fabric-shim": "2.5.9",
30 | "fabric-shim-api": "2.5.9",
31 | "git-rev-sync": "3.0.1",
32 | "gulp": "^4.0.2",
33 | "ip": "^1.1.5",
34 | "istanbul-api": "^1.1.13",
35 | "jsverify": "~0.8.4",
36 | "mocha": "9.1.3",
37 | "mockery": "^2.1.0",
38 | "rewire": "6.0.0",
39 | "sinon": "13.0.1",
40 | "sinon-test": "^2.2.0",
41 | "spec-junit-splitter-mocha-reporter": "1.0.1"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/test/fv/privateData.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 |
8 | const chai = require('chai');
9 | chai.use(require('chai-as-promised'));
10 | const expect = chai.expect;
11 | const utils = require('./utils');
12 | const {MED_STEP, LONG_STEP} = utils.TIMEOUTS;
13 |
14 | describe('Chaincode privateData', () => {
15 | const suite = 'privateData';
16 |
17 | before(async function () {
18 | this.timeout(LONG_STEP);
19 | return utils.installAndInstantiate(suite, null, null, true);
20 | });
21 |
22 | it('should write and read an asset with private data', async function () {
23 | this.timeout(MED_STEP);
24 | const privateData = Buffer.from('privateData').toString('base64');
25 | await utils.invoke(suite, 'privateDataContract:createAsset', ['1'], `{"privateValue":"${privateData}"}`);
26 | const payload = await utils.query(suite, 'privateDataContract:readAsset', ['1']);
27 | expect(payload).to.eql('{"privateValue":"privateData"}');
28 | });
29 |
30 | it('should update an asset with private data', async function () {
31 | this.timeout(MED_STEP);
32 | let privateData = Buffer.from('privateData').toString('base64');
33 | await utils.invoke(suite, 'privateDataContract:createAsset', ['2'], `{"privateValue":"${privateData}"}`);
34 | privateData = Buffer.from('updatedPrivateData').toString('base64');
35 | await utils.invoke(suite, 'privateDataContract:updateAsset', ['2'], `{"privateValue":"${privateData}"}`);
36 | const payload = await utils.query(suite, 'privateDataContract:readAsset', ['2']);
37 | expect(payload).to.eql('{"privateValue":"updatedPrivateData"}');
38 | });
39 |
40 | it('should delete an asset with private data', async function () {
41 | this.timeout(MED_STEP);
42 | const privateData = Buffer.from('privateData').toString('base64');
43 | await utils.invoke(suite, 'privateDataContract:createAsset', ['3'], `{"privateValue":"${privateData}"}`);
44 | let payload = await utils.query(suite, 'privateDataContract:readAsset', ['3']);
45 | expect(payload).to.eql('{"privateValue":"privateData"}');
46 | await utils.invoke(suite, 'privateDataContract:deleteAsset', ['3']);
47 | payload = await utils.query(suite, 'privateDataContract:assetExists', ['3']);
48 | expect(payload).to.eql('false');
49 | });
50 |
51 | it('should call purge private data without failing', async function () {
52 | this.timeout(MED_STEP);
53 | const privateData = Buffer.from('privateData').toString('base64');
54 | await utils.invoke(suite, 'privateDataContract:createAsset', ['4'], `{"privateValue":"${privateData}"}`);
55 | let payload = await utils.query(suite, 'privateDataContract:readAsset', ['4']);
56 | expect(payload).to.eql('{"privateValue":"privateData"}');
57 | console.log(await utils.invoke(suite, 'privateDataContract:purgeAsset', ['4']));
58 | payload = await utils.query(suite, 'privateDataContract:assetExists', ['4']);
59 | expect(payload).to.eql('false');
60 | });
61 |
62 | });
--------------------------------------------------------------------------------
/test/fv/query.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | 'use strict';
7 |
8 | const chai = require('chai');
9 | chai.use(require('chai-as-promised'));
10 | const expect = chai.expect;
11 | const utils = require('./utils');
12 | const {MED_INC, LONG_STEP} = utils.TIMEOUTS;
13 |
14 |
15 | describe('Chaincode query', () => {
16 | const suite = 'query';
17 | before(async function () {
18 | this.timeout(LONG_STEP);
19 | return utils.installAndInstantiate(suite, 'org.mynamespace.query:instantiate');
20 | });
21 |
22 | it('should perform an equals query', async function () {
23 | this.timeout(MED_INC);
24 | const query = JSON.stringify({
25 | selector: {
26 | value: 'value0'
27 | }
28 | });
29 | const payload = await utils.query(suite, 'org.mynamespace.query:query', [query]);
30 | expect(payload).to.deep.equal(JSON.stringify([{value: 'value0'}]));
31 | });
32 |
33 | it('should perform an regex query', async function () {
34 | this.timeout(MED_INC);
35 | const query = JSON.stringify({
36 | selector: {
37 | value: {
38 | $regex: 'value[0-2]'
39 | }
40 | }
41 | });
42 | const payload = await utils.query(suite, 'org.mynamespace.query:query', [query]);
43 | expect(payload).to.deep.equal(JSON.stringify([
44 | {value: 'value0'},
45 | {value: 'value1'},
46 | {value: 'value2'}
47 | ]));
48 | });
49 | });
50 |
--------------------------------------------------------------------------------
/tools/getEdgeDocker.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright IBM Corp. All Rights Reserved.
4 | #
5 | # SPDX-License-Identifier: Apache-2.0
6 | #
7 | set -euo pipefail
8 |
9 | version=${FABRIC_VERSION:-2.5}
10 | docker_registry=docker.io
11 |
12 | for image in peer orderer baseos ccenv tools; do
13 | image_name="hyperledger/fabric-${image}"
14 | image_pull="${docker_registry}/${image_name}:${version}"
15 | docker pull -q "${image_pull}"
16 | docker tag "${image_pull}" "${image_name}"
17 | done
18 |
19 | docker pull -q couchdb:latest
20 | docker pull -q "${docker_registry}/hyperledger/fabric-ca:1.5"
21 | docker tag "${docker_registry}/hyperledger/fabric-ca:1.5" hyperledger/fabric-ca
22 |
--------------------------------------------------------------------------------
/tools/logfiles.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | # Grab the current directory
5 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )"/.. && pwd )"
6 | esc=$(printf '\033')
7 |
8 | files=$(find ${DIR} -name "*.build*.log")
9 | for LOG in ${files}; do
10 | realpath -q --relative-to="$(pwd)" ${LOG} | sed "s,.*error.*,${esc}[91m&${esc}[0m,"
11 | done
12 |
13 |
--------------------------------------------------------------------------------
/tools/monitordocker.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This script uses the logspout and http stream tools to let you watch the docker containers
4 | # in action.
5 | #
6 | # More information at https://github.com/gliderlabs/logspout/tree/master/httpstream
7 |
8 | if [ -z "$1" ]; then
9 | DOCKER_NETWORK=basicnetwork_basic
10 | else
11 | DOCKER_NETWORK="$1"
12 | fi
13 |
14 | echo Starting monitoring on all containers on the network ${DOCKER_NETWORK}
15 |
16 | docker kill logspout 2> /dev/null 1>&2 || true
17 | docker rm logspout 2> /dev/null 1>&2 || true
18 |
19 | docker run -d --name="logspout" \
20 | --volume=/var/run/docker.sock:/var/run/docker.sock \
21 | --publish=127.0.0.1:8000:80 \
22 | --network ${DOCKER_NETWORK} \
23 | gliderlabs/logspout
24 | sleep 3
25 | curl http://127.0.0.1:8000/logs
26 |
--------------------------------------------------------------------------------
/tools/scripts/changelog.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright IBM Corp. All Rights Reserved.
4 | #
5 | # SPDX-License-Identifier: Apache-2.0
6 | #
7 | set -ev
8 |
9 | PREVIOUS_TAG=$1
10 | NEW_VERSION=$2
11 |
12 | : ${PREVIOUS_TAG:?}
13 | : ${NEW_VERSION:?}
14 |
15 | echo "## ${NEW_VERSION}\n$(date)" >> CHANGELOG.new
16 | echo "" >> CHANGELOG.new
17 | git log ${PREVIOUS_TAG}..HEAD --oneline | grep -v Merge | sed -e "s/\[\{0,1\}\(FAB[^0-9]*-[0-9]*\)\]\{0,1\}/\[\1\](https:\/\/jira.hyperledger.org\/browse\/\1\)/" -e "s/\([0-9|a-z]*\)/* \[\1\](https:\/\/github.com\/hyperledger\/fabric-chaincode-node\/commit\/\1)/" >> CHANGELOG.new
18 | echo "" >> CHANGELOG.new
19 | cat CHANGELOG.md >> CHANGELOG.new
20 | mv -f CHANGELOG.new CHANGELOG.md
21 |
--------------------------------------------------------------------------------
/tools/scripts/gittag.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Exit on first error, print all commands.
4 | set -e
5 | set -o pipefail
6 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"
7 |
8 | # set to echo to do processing but not the git commands
9 | #DRYRUN=echo
10 |
11 | # release name
12 | RELEASE=release-1.4
13 |
14 | function abort {
15 | echo "!! Exiting shell script"
16 | echo "!!" "$1"
17 | exit -1
18 | }
19 |
20 | VERSION=$(jq '.version' ${DIR}/package.json | sed -r "s/\"([0-9]?[0-9]\.[0-9]?[0-9]\.[0-9]?[0-9]).*/\1/")
21 |
22 | echo New version string will be v${VERSION}
23 |
24 | # do the release notes for this new version exist?
25 | if [[ -f "${DIR}/release_notes/v${VERSION}.txt" ]]; then
26 | echo "Release notes exist, hope they make sense!"
27 | else
28 | abort "No releases notes under the file ${DIR}/release_notes/v${NEW_VERSION}.txt exist";
29 | fi
30 |
31 |
32 |
33 |
34 | ${DRYRUN} git checkout "${RELEASE}"
35 | ${DRYRUN} git pull
36 | ${DRYRUN} git tag -a "v${VERSION}" `git log -n 1 --pretty=oneline | head -c7` -F release_notes/"v${VERSION}".txt
37 | ${DRYRUN} git push origin v${VERSION} HEAD:refs/heads/${RELEASE}
--------------------------------------------------------------------------------
/tools/scripts/multiarch.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright IBM Corp. All Rights Reserved.
4 | #
5 | # SPDX-License-Identifier: Apache-2.0
6 | #
7 |
8 | usage() {
9 | echo "Usage: $0 "
10 | echo " and credentials for the repository"
11 | echo "ENV:"
12 | echo " NS=$NS"
13 | echo " VERSION=$VERSION"
14 | echo " TWO_DIGIT_VERSION=$TWO_DIGIT_VERSION"
15 | exit 1
16 | }
17 |
18 | missing() {
19 | echo "Error: some image(s) missing from registry"
20 | echo "ENV:"
21 | echo " NS=$NS"
22 | echo " VERSION=$VERSION"
23 | echo " TWO_DIGIT_VERSION=$TWO_DIGIT_VERSION"
24 | exit 1
25 | }
26 |
27 | failed() {
28 | echo "Error: multiarch manifest push failed"
29 | echo "ENV:"
30 | echo " NS=$NS"
31 | echo " VERSION=$VERSION"
32 | echo " TWO_DIGIT_VERSION=$TWO_DIGIT_VERSION"
33 | exit 1
34 | }
35 |
36 | USER=${1:-nobody}
37 | PASSWORD=${2:-nohow}
38 | NS=${NS:-hyperledger}
39 | VERSION=${BASE_VERSION:-1.3.0}
40 | TWO_DIGIT_VERSION=${TWO_DIGIT_VERSION:-1.3}
41 |
42 | if [ "$#" -ne 2 ]; then
43 | usage
44 | fi
45 |
46 | # verify that manifest-tool is installed and found on PATH
47 | which manifest-tool
48 | if [ "$?" -ne 0 ]; then
49 | echo "manifest-tool not installed or not found on PATH"
50 | exit 1
51 | fi
52 |
53 | IMAGES="fabric-nodeenv"
54 |
55 | # check that all images have been published
56 | for image in ${IMAGES}; do
57 | docker pull ${NS}/${image}:amd64-${VERSION} || missing
58 | docker pull ${NS}/${image}:s390x-${VERSION} || missing
59 | done
60 |
61 | # push the multiarch manifest and tag with just $VERSION and 'latest'
62 | for image in ${IMAGES}; do
63 | manifest-tool --username ${USER} --password ${PASSWORD} push from-args\
64 | --platforms linux/amd64,linux/s390x --template "${NS}/${image}:ARCH-${VERSION}"\
65 | --target "${NS}/${image}:${VERSION}"
66 | # manifest-tool --username ${USER} --password ${PASSWORD} push from-args\
67 | # --platforms linux/amd64,linux/s390x --template "${NS}/${image}:ARCH-${VERSION}"\
68 | # --target "${NS}/${image}:latest"
69 | manifest-tool --username ${USER} --password ${PASSWORD} push from-args\
70 | --platforms linux/amd64,linux/s390x --template "${NS}/${image}:ARCH-${VERSION}"\
71 | --target "${NS}/${image}:${TWO_DIGIT_VERSION}"
72 | done
73 |
74 | # test that manifest is working as expected
75 | for image in ${IMAGES}; do
76 | docker pull ${NS}/${image}:${VERSION} || failed
77 | docker pull ${NS}/${image}:${TWO_DIGIT_VERSION} || failed
78 | # docker pull ${NS}/${image}:latest || failed
79 | done
80 |
81 | echo "Successfully pushed multiarch manifest"
82 | exit 0
83 |
--------------------------------------------------------------------------------
/tools/scripts/startFabric.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # This starts up a Fabric Network for use by the integration tests
4 | # PLEASE NOTE - this pulls the latest 'edge' version of the binaries
5 | # Plans in place to update this a better version and to use the LTS 2.5 binaries once released
6 |
7 | # Exit on first error, print all commands.
8 | set -xeo pipefail
9 |
10 | ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"
11 |
12 | pushd "${ROOT_DIR}"
13 | rm -rf "${ROOT_DIR}/fabric-samples"
14 |
15 | curl -sSLO https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh \
16 | && chmod +x install-fabric.sh \
17 | && ./install-fabric.sh -f 2.5.0 samples
18 |
19 | pushd "${ROOT_DIR}/fabric-samples"
20 |
21 | find "${ROOT_DIR}/fabric-samples" -name configtx.yaml -exec yq -i '.Capabilities.Application.V2_5 = true | del(.Capabilities.Application.V2_0)' {} \;
22 |
23 | # get the edge binaries - these are the version 2.5
24 | # the latest docker images are pulled elsewhere
25 | curl -sSL https://hyperledger.jfrog.io/artifactory/fabric-binaries/hyperledger-fabric-ca-linux-amd64-2.5-stable.tar.gz | tar -xz
26 | curl -sSL https://hyperledger.jfrog.io/artifactory/fabric-binaries/hyperledger-fabric-linux-amd64-2.5-stable.tar.gz | tar -xz
27 |
28 |
29 | pushd "${ROOT_DIR}/fabric-samples/test-network"
30 | ./network.sh down
31 | ./network.sh up createChannel -ca -s couchdb
32 |
33 | # unwind the stack
34 | popd
35 | popd
36 | popd
--------------------------------------------------------------------------------
/tools/scripts/updateversions.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -eo pipefail
4 |
5 | if [ -z "$1" ]; then
6 | echo "Need to have the first arg set to the new package.json version"
7 | exit 1
8 | fi
9 |
10 | NEW_VERSION="$1"
11 | echo "Setting new version to '${NEW_VERSION}'"
12 |
13 | DEPENDENCIES=( fabric-contract-api fabric-shim-api fabric-shim fabric-ledger )
14 |
15 | updatePackageVersion() {
16 | npm --allow-same-version --no-git-tag-version version "$1"
17 | for dependency in "${DEPENDENCIES[@]}"; do
18 | updateDependencyVersion "${dependency}" "$1"
19 | done
20 | }
21 |
22 | updateDependencyVersion() {
23 | local packageJson
24 | packageJson=$(node -e "const pkg = require('./package.json'); if (pkg.dependencies?.['$1']) pkg.dependencies['$1'] = '$2'; console.log(JSON.stringify(pkg, undefined, 2))")
25 | echo "${packageJson}" > package.json
26 | }
27 |
28 | while read -r PACKAGE; do
29 | echo "Updating '${PACKAGE}'"
30 | ( cd "$(dirname "${PACKAGE}")" && updatePackageVersion "${NEW_VERSION}" )
31 | done <<< "$(find . -type d \( -name node_modules -o -name common -o -name tools \) -prune -o -type f -name package.json -print)"
32 |
33 | MAJOR_MINOR=$(cut -d. -f-2 <<< "${NEW_VERSION}")
34 |
35 | echo "Please also check these files containing ${MAJOR_MINOR}.n"
36 | # NB - the grep regexp syntax is a little different
37 | MAJOR_MINOR_REGEX="${MAJOR_MINOR/./\.}\.\?[0-9]"
38 | find ./test \
39 | -type d \( -name node_modules -o -name '.*' \) -prune \
40 | -o -type f -name package.json -prune \
41 | -o -type f \( -name '*.js' -o -name '*.json' \) -exec grep "${MAJOR_MINOR_REGEX}" {} +
42 |
--------------------------------------------------------------------------------
/tools/toolchain/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright contributors to Hyperledger Fabric.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | const {shell} = require('./shell/cmd');
8 | const {getTLSArgs, getPeerAddresses} = require('./utils');
9 |
10 | module.exports.shell = shell;
11 |
12 | module.exports.getTLSArgs = getTLSArgs;
13 | module.exports.getPeerAddresses = getPeerAddresses;
14 |
--------------------------------------------------------------------------------
/tools/toolchain/network/crypto-material/crypto-config.yaml:
--------------------------------------------------------------------------------
1 | # Copyright IBM Corp. All Rights Reserved.
2 | #
3 | # SPDX-License-Identifier: Apache-2.0
4 | #
5 |
6 | # ---------------------------------------------------------------------------
7 | # "OrdererOrgs" - Definition of organizations managing orderer nodes
8 | # ---------------------------------------------------------------------------
9 | OrdererOrgs:
10 | # ---------------------------------------------------------------------------
11 | # Orderer
12 | # ---------------------------------------------------------------------------
13 | - Name: Orderer
14 | Domain: example.com
15 | # ---------------------------------------------------------------------------
16 | # "Specs" - See PeerOrgs below for complete description
17 | # ---------------------------------------------------------------------------
18 | Specs:
19 | - Hostname: orderer
20 | # ---------------------------------------------------------------------------
21 | # "PeerOrgs" - Definition of organizations managing peer nodes
22 | # ---------------------------------------------------------------------------
23 | PeerOrgs:
24 | # ---------------------------------------------------------------------------
25 | # Org1
26 | # ---------------------------------------------------------------------------
27 | - Name: Org1
28 | Domain: org1.example.com
29 | Template:
30 | Count: 2
31 | Users:
32 | Count: 1
33 | # ---------------------------------------------------------------------------
34 | # Org2: See "Org1" for full specification
35 | # ---------------------------------------------------------------------------
36 | - Name: Org2
37 | Domain: org2.example.com
38 | Template:
39 | Count: 2
40 | Users:
41 | Count: 1
42 |
--------------------------------------------------------------------------------
/tools/toolchain/network/crypto-material/rename_sk.sh:
--------------------------------------------------------------------------------
1 | # Rename the key files we use to be key.pem instead of a uuid
2 | BASEDIR=$(dirname "$0")
3 |
4 | chmod -R og+rx ${BASEDIR}
5 |
6 | for KEY in $(find ${BASEDIR}/crypto-config -type f -name "*_sk"); do
7 | KEY_DIR=$(dirname ${KEY})
8 | mv ${KEY} ${KEY_DIR}/key.pem
9 | done
--------------------------------------------------------------------------------
/tools/toolchain/network/docker-compose/docker-compose-cli.yaml:
--------------------------------------------------------------------------------
1 | #
2 | # Licensed under the Apache License, Version 2.0 (the "License");
3 | # you may not use this file except in compliance with the License.
4 | # You may obtain a copy of the License at
5 | #
6 | # http://www.apache.org/licenses/LICENSE-2.0
7 | #
8 | # Unless required by applicable law or agreed to in writing, software
9 | # distributed under the License is distributed on an "AS IS" BASIS,
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | # See the License for the specific language governing permissions and
12 | # limitations under the License.
13 | #
14 |
15 | services:
16 | clinopeer:
17 | container_name: cli
18 | image: hyperledger/fabric-tools
19 | tty: true
20 | environment:
21 | - GOPATH=/opt/gopath
22 | - FABRIC_CFG_PATH=/etc/hyperledger/config
23 |
24 | # LOGGING SETTINGS
25 | - FABRIC_LOGGING_SPEC=INFO
26 |
27 | working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
28 | command: /bin/bash
29 | volumes:
30 | - /var/run/:/host/var/run/
31 | - ../crypto-material:/etc/hyperledger/config/
32 | - ../../../../test/chaincodes/privateData/collection-config:/collection-config
33 |
--------------------------------------------------------------------------------
/tools/toolchain/network/external/build:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright Hitachi America, Ltd. All Rights Reserved.
4 | #
5 | # SPDX-License-Identifier: Apache-2.0
6 |
7 | set -e
8 |
9 | SOURCE="$1"
10 | OUTPUT="$3"
11 |
12 | if [ ! -f "${SOURCE}/connection.json" ]; then
13 | echo "Error: ${SOURCE}/connection.json not found" 1>&2
14 | exit 1
15 | fi
16 |
17 | cp "${SOURCE}/connection.json" "${OUTPUT}/connection.json"
18 |
19 | if [ -d "${SOURCE}/metadata" ]; then
20 | cp -a ${SOURCE}/metadata ${OUTPUT}/metadata
21 | fi
22 |
23 | exit 0
24 |
--------------------------------------------------------------------------------
/tools/toolchain/network/external/detect:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright Hitachi America, Ltd. All Rights Reserved.
4 | #
5 | # SPDX-License-Identifier: Apache-2.0
6 |
7 | set -e
8 |
9 | METADIR="$2"
10 |
11 | if [ `jq -r .type "${METADIR}/metadata.json"` = "external" ]; then
12 | exit 0
13 | fi
14 |
15 | exit 1
16 |
--------------------------------------------------------------------------------
/tools/toolchain/network/external/release:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Copyright Hitachi America, Ltd. All Rights Reserved.
4 | #
5 | # SPDX-License-Identifier: Apache-2.0
6 |
7 | set -e
8 |
9 | BUILD="$1"
10 | RELEASE="$2"
11 |
12 | if [ -d "${BUILD}/metadata" ]; then
13 | cp -a "${BUILD}/metadata/*" "${RELEASE}/"
14 | fi
15 |
16 | if [ -f "${BUILD}/connection.json" ]; then
17 | mkdir -p "${RELEASE}/chaincode/server"
18 | cp "${BUILD}/connection.json" "${RELEASE}/chaincode/server"
19 |
20 | # TODO: TLS
21 |
22 | exit 0
23 | fi
24 |
--------------------------------------------------------------------------------
/tools/toolchain/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "toolchain",
3 | "version": "1.0.0-dev",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "build": "",
8 | "startfabric": "gulp startFabric",
9 | "stopfabric": "gulp stopFabric"
10 | },
11 | "author": "",
12 | "license": "Apache-2.0",
13 | "dependencies": {
14 | "delay": "5.0.0",
15 | "git-rev-sync": "3.0.1",
16 | "gulp-debug": "~4.0.0",
17 | "gulp-eslint": "~6.0.0",
18 | "gulp-rename": "~2.0.0",
19 | "gulp-shell": "~0.7.1",
20 | "merge-stream": "~2.0.0",
21 | "npm-cli-login": "~0.1.1",
22 | "ip": "^1.1.5",
23 | "gulp-cli": "2.3.0"
24 | },
25 | "devDependencies": {
26 | "gulp": "^4.0.2"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tools/toolchain/shell/cmd.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 | const spawn = require('child_process').spawn;
7 |
8 | // A general purpose structure that can be used for any command.
9 | // This defines the important 'spawn' command. This executes the command
10 | // with the arguments that have been specified.
11 | // It is set to inherit the environment variables, uses the default sell, and inherits the
12 | // stdio/stderr streams. (Inheriting means that the formating colour, etc is maintained)
13 | //
14 | // spawn() MUST be the last item chained sequence
15 | //
16 | // It also blanks the arguments supplied, so the instance of the cmd can be reused
17 | // It returns a promise that is resolved when the exit code is 0, and rejected for any other code
18 | const _cmd = {
19 | cmd: '',
20 | args: [],
21 | stdoutstr: [],
22 |
23 | // can override the cwd
24 | spawn: function (cwd = process.cwd()) {
25 | const promise = new Promise((resolve, reject) => {
26 | const _name = this.toString();
27 | // eslint-disable-next-line no-console
28 | console.log(`spawning:: ${_name} in ${cwd}`);
29 | const call = spawn(this.cmd, this.args, {env: process.env, shell: true, stdio: ['inherit', 'pipe', 'inherit'], cwd});
30 | this.args = [];
31 | this.stdoutstr = [];
32 | call.on('exit', (code) => {
33 | // eslint-disable-next-line no-console
34 | console.log(`spawning:: ${_name} code::${code}`);
35 | if (code === 0) {
36 | resolve(0);
37 | } else {
38 | reject(code);
39 | }
40 | });
41 | call.stdout.on('data', (data) => {
42 | const s = data.toString('utf8');
43 | console.log(s.slice(0, s.length - 1));
44 | this.stdoutstr.push(s);
45 | });
46 | return call;
47 | });
48 |
49 | return promise;
50 | },
51 | toString: function () {
52 | return `${this.cmd} ${this.args.join(' ')}`;
53 | }
54 | };
55 |
56 |
57 | const newCmd = (newcmd) => {
58 | // duplicate the generic cmd object
59 | const _new = Object.create(_cmd);
60 | _new.cmd = newcmd;
61 | _new.args = [];
62 | return _new;
63 | };
64 |
65 | module.exports = _cmd;
66 | module.exports.newCmd = newCmd;
67 | module.exports.shell = async (cmds) => {
68 | const retvals = [];
69 | for (const c of cmds) {
70 | const cmd = newCmd(c);
71 | await cmd.spawn();
72 | retvals.push(cmd.stdoutstr.join(' '));
73 | }
74 | return retvals;
75 |
76 | };
--------------------------------------------------------------------------------
/tools/toolchain/shell/docker.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | const _cmd = require('./cmd.js');
8 |
9 |
10 | // Function to create a new instance of the npm command.
11 | // This sets up the run, test, and prefix options
12 | // If you wish to add 'scripts' eg build compile etc, the useScript()
13 | // function can be used.
14 | function docker () {
15 |
16 | // duplicate the generic cmd object
17 | const _docker = Object.create(_cmd);
18 | _docker.cmd = 'docker';
19 | _docker.args = [];
20 |
21 | // function to use to add extra scripts
22 | // npm.useScript('compile','build')
23 | _docker.useScript = (...scripts) => {
24 | scripts.forEach((m) => {
25 | Object.defineProperty(_docker, m, {
26 | get: function () {
27 | this.args.push(m);
28 | return this;
29 | }
30 | });
31 | });
32 | return this;
33 | };
34 |
35 | return _docker;
36 | }
37 |
38 | // default export is the npm function to create instances of the npm command
39 | module.exports = docker;
40 |
--------------------------------------------------------------------------------
/tools/toolchain/shell/npm.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | const _cmd = require('./cmd.js');
8 |
9 |
10 | // Function to create a new instance of the npm command.
11 | // This sets up the run, test, and prefix options
12 | // If you wish to add 'scripts' eg build compile etc, the useScript()
13 | // function can be used.
14 | function npm () {
15 |
16 | // duplicate the generic cmd object
17 | const _npm = Object.create(_cmd);
18 | _npm.cmd = 'npm';
19 | _npm.args = [];
20 |
21 | // no-args
22 | const noargs = ['run', 'test', 'build', 'start', 'install'];
23 | noargs.forEach((m) => {
24 | Object.defineProperty(_npm, m, {
25 | get: function () {
26 | this.args.push(m);
27 | return this;
28 | }
29 | });
30 | });
31 |
32 | // single-arg fn
33 | ['prefix'].forEach((m) => {
34 | Object.defineProperty(_npm, m, {
35 | value: function (p) {
36 | this.args.push(`--${m}`, p);
37 | return this;
38 | }
39 | });
40 |
41 | });
42 |
43 | // function to use to add extra scripts
44 | // npm.useScript('compile','build')
45 | _npm.useScript = (...scripts) => {
46 | scripts.forEach((m) => {
47 | Object.defineProperty(_npm, m, {
48 | get: function () {
49 | this.args.push(m);
50 | return this;
51 | }
52 | });
53 | });
54 | return this;
55 | };
56 |
57 | return _npm;
58 | }
59 |
60 | // default export is the npm function to create instances of the npm command
61 | module.exports = npm;
62 | // singleton npm instance
63 | module.exports.npm = npm();
64 |
65 |
--------------------------------------------------------------------------------
/tools/toolchain/test/inversionOfControl.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | // remove once inversion of control in fabric as other tests will cover this
8 |
9 | /*
10 | # Copyright IBM Corp. All Rights Reserved.
11 | #
12 | # SPDX-License-Identifier: Apache-2.0
13 | */
14 | 'use strict';
15 | /* eslint-disable no-console */
16 |
17 | const gulp = require('gulp');
18 |
19 | const util = require('util');
20 |
21 | const childProcess = require('child_process');
22 | const exec = childProcess.exec;
23 |
24 | const peerAddress = require('../../test/constants').peerAddress;
25 |
26 | require('./scenario');
27 |
28 | gulp.task('inv-startup-chaincode', async (done) => {
29 | const script = util.format('docker exec org1_cli bash -c "cd %s; npm start -- --peer.address %s --chaincode-id-name %s --module-path %s"',
30 | // the /etc/hyperledger/config has been mapped to the
31 | // basic-network folder in the test setup for the CLI docker
32 | '/opt/gopath/src/github.com/chaincode/scenario/node_modules/fabric-shim',
33 | peerAddress,
34 | 'mysmartcontract:v0',
35 | '/opt/gopath/src/github.com/chaincode/scenario');
36 |
37 | try {
38 | await new Promise((resolve, reject) => {
39 | const child = exec(script);
40 |
41 | child.stdout.on('data', (data) => {
42 | if (Buffer.isBuffer(data)) {
43 | data = data.toString();
44 | }
45 |
46 | if (data.includes('Successfully established communication with peer node')) {
47 | resolve(child);
48 | }
49 | });
50 |
51 | child.stderr.on('data', (data) => {
52 | console.log('[STR] stderr "%s"', String(data));
53 | });
54 |
55 | child.on('close', (code, signal) => {
56 | reject('Starting up chaincode via CLI failed');
57 | });
58 | });
59 | } catch (err) {
60 | done(err);
61 | }
62 | });
63 |
64 | /**
65 | * Invoke all the smart contract functions - steals some commands from scenario as uses same contract
66 | */
67 |
68 | gulp.task('invokeAllFnsInvCtrl', gulp.series(
69 | [
70 | 'cli-install-chaincode',
71 |
72 | // Start chaincode
73 | 'inv-startup-chaincode',
74 |
75 | // install
76 | 'st-install_chaincode',
77 |
78 | // instantiate
79 | 'st-instantiate_chaincode',
80 | 'delay',
81 |
82 | // Check it didnt make docker images
83 | 'check-docker',
84 |
85 | // invoke all functions
86 | 'invoke_functions',
87 |
88 | // query the functions
89 | 'query_functions',
90 |
91 | // stop chaincode
92 | 'stop-cli-running-chaincode',
93 |
94 | 'dm-clean-up-chaincode'
95 | ]
96 | ));
97 |
98 | gulp.task('test-scenario-invctrl', gulp.series('invokeAllFnsInvCtrl'));
99 |
--------------------------------------------------------------------------------
/tools/toolchain/utils.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright contributors to Hyperledger Fabric.
3 | *
4 | * SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | const path = require('path');
8 |
9 | const ordererCA = '/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem';
10 | const org1CA = '/etc/hyperledger/config/crypto-config/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem';
11 | const org2CA = '/etc/hyperledger/config/crypto-config/peerOrganizations/org2.example.com/tlsca/tlsca.org2.example.com-cert.pem';
12 | const dir = path.join(__dirname, '..', '..', 'fabric-samples');
13 |
14 | const tls = process.env.TLS && process.env.TLS.toLowerCase() === 'true' ? true : false;
15 |
16 | exports.tls = tls;
17 |
18 | exports.getTLSArgs = () => {
19 | return `--tls true --cafile ${dir}` + ordererCA;
20 | };
21 |
22 | exports.getPeerAddresses = () => {
23 | if (tls) {
24 | return '--peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles ' + org1CA +
25 | ' --peerAddresses peer0.org2.example.com:8051 --tlsRootCertFiles ' + org2CA;
26 | } else {
27 | return '--peerAddresses peer0.org1.example.com:7051' +
28 | ' --peerAddresses peer0.org2.example.com:8051';
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/tools/toolchain/verdaccio/config.yaml:
--------------------------------------------------------------------------------
1 | #
2 | # This is the config file used for the docker images.
3 | # It allows all users to do anything, so don't use it on production systems.
4 | #
5 | # Do not configure host and port under `listen` in this file
6 | # as it will be ignored when using docker.
7 | # see https://verdaccio.org/docs/en/docker#docker-and-custom-port-configuration
8 | #
9 | # Look here for more config file examples:
10 | # https://github.com/verdaccio/verdaccio/tree/master/conf
11 | #
12 |
13 | # path to a directory with all packages
14 | storage: /verdaccio/storage/data
15 | # path to a directory with plugins to include
16 | plugins: /verdaccio/plugins
17 |
18 | web:
19 | # WebUI is enabled as default, if you want disable it, just uncomment this line
20 | #enable: false
21 | title: Verdaccio
22 | # comment out to disable gravatar support
23 | # gravatar: false
24 | # by default packages are ordercer ascendant (asc|desc)
25 | # sort_packages: asc
26 |
27 | auth:
28 | htpasswd:
29 | file: /verdaccio/storage/htpasswd
30 | # Maximum amount of users allowed to register, defaults to "+infinity".
31 | # You can set this to -1 to disable registration.
32 | # max_users: 1000
33 |
34 | security:
35 | api:
36 | jwt:
37 | sign:
38 | expiresIn: 60d
39 | notBefore: 1
40 | web:
41 | sign:
42 | expiresIn: 7d
43 | notBefore: 1
44 |
45 | # a list of other known repositories we can talk to
46 | uplinks:
47 | npmjs:
48 | url: https://registry.npmjs.org/
49 |
50 | packages:
51 | '@*/*':
52 | # scoped packages
53 | access: $all
54 | publish: $all
55 | unpublish: $all
56 | proxy: npmjs
57 |
58 | 'fabric-*':
59 | access: $all
60 | publish: $all
61 | unpublish: $all
62 |
63 | '**':
64 | # allow all users (including non-authenticated users) to read and
65 | # publish all packages
66 | #
67 | # you can specify usernames/groupnames (depending on your auth plugin)
68 | # and three keywords: "$all", "$anonymous", "$authenticated"
69 | access: $all
70 |
71 | # allow all known users to publish/publish packages
72 | # (anyone can register by default, remember?)
73 | publish: $all
74 | unpublish: $all
75 |
76 | # if package is not available locally, proxy requests to 'npmjs' registry
77 | proxy: npmjs
78 |
79 | middlewares:
80 | audit:
81 | enabled: true
82 |
83 | # log settings
84 | logs:
85 | - { type: stdout, format: pretty, level: http }
86 | #- {type: file, path: verdaccio.log, level: info}
87 |
--------------------------------------------------------------------------------
/tools/toolchain/verdaccio/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | # Copyright IBM Corp. All Rights Reserved.
3 | #
4 | # SPDX-License-Identifier: Apache-2.0
5 | */
6 |
7 | 'use strict';
8 |
9 | const gulp = require('gulp');
10 | const { shell: runcmds } = require('../shell/cmd');
11 | const util = require('util');
12 | const path = require('path');
13 | const ip = require('ip');
14 |
15 | // Install from the dirs for use within the development context
16 | const installDir = (commands) =>{
17 |
18 | const npm_packages = [{ category: 'apis', name: 'fabric-contract-api' },
19 | { category: 'apis', name: 'fabric-shim-api' },
20 | { category: 'libraries', name: 'fabric-ledger' },
21 | { category: 'libraries', name: 'fabric-shim' }];
22 |
23 |
24 | for (const npm_package of npm_packages) {
25 | const packageJSON = require(`../../../${npm_package.category}/${npm_package.name}/package.json`);
26 | const npm_tag = packageJSON.tag;
27 | const modulepath = path.resolve(`../../../${npm_package.category}/${npm_package.name}/`);
28 | commands.push(util.format(`npm publish --registry http://${ip.address()}:4873 %s --tag %s`, modulepath, npm_tag));
29 | commands.push(util.format(`npm view --registry http://${ip.address()}:4873 %s`, npm_package.name));
30 | }
31 |
32 | return commands;
33 | }
34 |
35 | // Install from a set of prebuild tgz for use within the pipline
36 | const installTGZ = (commands) =>{
37 |
38 | const npm_packages = [{ category: 'apis', name: 'fabric-contract-api' },
39 | { category: 'apis', name: 'fabric-shim-api' },
40 | { category: 'libraries', name: 'fabric-ledger' },
41 | { category: 'libraries', name: 'fabric-shim' }];
42 |
43 |
44 | for (const npm_package of npm_packages) {
45 | const packageJSON = require(`../../../${npm_package.category}/${npm_package.name}/package.json`);
46 | const npm_tag = packageJSON.tag;
47 | const name = `${npm_package.name}-${packageJSON.version}.tgz`;
48 | commands.push(util.format(`npm publish --registry http://${ip.address()}:4873 ../../../build/%s --tag %s`, name, npm_tag));
49 | commands.push(util.format(`npm view --registry http://${ip.address()}:4873 %s`, npm_package.name));
50 | }
51 |
52 |
53 | return commands;
54 | }
55 |
56 |
57 | const verdaccioStart = async () => {
58 | let commands = [
59 | 'docker rm -f verdaccio || true',
60 | util.format('docker run -d -p 4873:4873 -v %s/config.yaml:/verdaccio/conf/config.yaml --name verdaccio verdaccio/verdaccio', __dirname),
61 | 'sleep 5', // verdaccio takes a while to start
62 | `npm config delete //${ip.address()}:4873/:_authToken`,
63 | `npm-cli-login -u testuser -p testpass -e testuser@example.org -r http://${ip.address()}:4873`,
64 | 'sleep 5' // avoid "jwt not active" error
65 | ];
66 |
67 |
68 | let inPipeline = process.env.PIPELINE_WORKSPACE || false;
69 |
70 | if (inPipeline){
71 | commands = installTGZ(commands);
72 | } else {
73 | commands = installDir(commands);
74 | }
75 |
76 | await runcmds(commands);
77 | };
78 |
79 | const verdaccioStop = async () => {
80 | const commands = [
81 | util.format('docker rm -f verdaccio || true')
82 | ];
83 | await runcmds(commands);
84 | };
85 |
86 | exports.start = verdaccioStart;
87 | exports.stop = verdaccioStop;
--------------------------------------------------------------------------------