Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/scan.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
ref: ${{ inputs.ref }}
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with:
node-version: 18
node-version: "lts/*"
- name: Install
run: node common/scripts/install-run-rush.js install
- name: Build packages
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with:
node-version: "18.x"
node-version: "20.x"
- name: Install/Rebuild/UnitTest
run: |
set -xev
Expand Down Expand Up @@ -80,7 +80,7 @@ jobs:
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0
with:
node-version: "18.x"
node-version: "20.x"
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
name: nodeenv-docker-image
Expand Down
3 changes: 2 additions & 1 deletion COMPATIBILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ This table shows the summary of the compatibility of the Node chaincode packages
| v2.2 | 12 | 12 | amd64 |
| v2.5.0 - v2.5.4 | 18 | 18 | amd64, arm64 |
| v2.5.5 - v2.5.7 | 18 | 20 | amd64, arm64 |
| v2.5.8+ | 18 | 22 | amd64, arm64 |
| v2.5.8 | 18 | 22 | amd64, arm64 |
| v2.5.9+ | 20 | 24 | amd64, arm64 |

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.

Expand Down
43 changes: 19 additions & 24 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,52 +22,47 @@ The following [Rush categories](https://rushjs.io/pages/maintainer/add_to_repo/)

### Pre-requisites

* node v18 => recommend to use [nvm](https://github.com/nvm-sh/nvm)
* rush => `npm install -g @microsoft/rush`
- node 20+ => recommend to use [nvm](https://github.com/nvm-sh/nvm)
- rush => `npm install -g @microsoft/rush`

> As an alternative to installing rush on your system, you can also have node install it for executing single commands similar to what is done in CI, for example from the `libraries/fabric-shim` directory you could add or update a dependency by running `node ../../common/scripts/install-run-rush.js add --package @grpc/grpc-js@latest`

> Note that npm v6 has some bugs that mean adding new dependencies etc are not properly picked up. Longer term we should consider moving to yarn or pnpm. However in practice this isn't a serious problem and has been possible to be worked around by issuing `rm ./common/config/rush/npm-shrinkwrap.json` and then `rush update`

The fv and e2e tests require a set of docker images of Fabric Peers, Orderers and CAs. To ensure you have the correct images ensure these have been dowloaded and tagged. `rush edge-docker` will do this for you.

They also need to have the `nodeenv` image present - this is build as part of the `rush rebuild` so please ensure this has been run first. It is advisable to clean up the docker containers and images between test runs to avoid any odd behaviour. Commands to help do this are below.
They also need to have the `nodeenv` image present - this is build as part of the `rush rebuild` so please ensure this has been run first. It is advisable to clean up the docker containers and images between test runs to avoid any odd behaviour. Commands to help do this are below.

## Using the repo

* Clone the repo, and ensure you are using node v18, and have rush installed
* `rush update` is needed to ensure everything is correctly linked and updated.
- For example, after updating dependencies in `libraries/fabric-shim/package.json` run `rush update` which will delegate to `pnpm` to update the appropriate project files.
- Note - you could also use `rush add` to have rush manage the `package.json` updates.
* `rush edge-docker` will pull down and tag the very latest docker images for the peers, orderes etc to test against
- Clone the repo, and ensure you are using node v18, and have rush installed
- `rush update` is needed to ensure everything is correctly linked and updated.
- For example, after updating dependencies in `libraries/fabric-shim/package.json` run `rush update` which will delegate to `pnpm` to update the appropriate project files.
- Note - you could also use `rush add` to have rush manage the `package.json` updates.

At this point the repo is fully ready for use and running tests, etc. A full sequence of build-test that is equivalent to the CI pipeline is

* `rush rebuild` will run the linting, and unit tests across the codebase, as well as building the docker images, and jsdoc API docs
* `rush start-verdaccio` & `rush stop-verdaccio` will start/stop verdaccio (used for local hosting of NPM modules)
* `rush start-fabric` & `rush stop-fabric` will start/stop the test fabric ready for running FV tests
* `rush test:fv` will run the fv tests, ensure that both the fabric and verdaccio have already been started
* `rush test:e2e` to run e2e tests across the repos
- `rush rebuild` will run the linting, and unit tests across the codebase, as well as building the docker images, and jsdoc API docs
- `rush start-verdaccio` & `rush stop-verdaccio` will start/stop verdaccio (used for local hosting of NPM modules)
- `rush start-fabric` & `rush stop-fabric` will start/stop the test fabric ready for running FV tests
- `rush test:fv` will run the fv tests, ensure that both the fabric and verdaccio have already been started
- `rush test:e2e` to run e2e tests across the repos

For more specific purposes during development the following are useful:

* `rush publish --include-all --pack --release-folder ./tarballs --publish`
If you want to get a set of `.tar.gz` files of the node modules to use for local testing this command will put them into the `tarballs` directory
* `rush rebuild --to fvtests` to run the unit tests for the core modules, but not the docker or jsdoc
* `rush rebuild --to fabric-contract-api` to build, lint and run just the `fabric-contract-api`
* `rush logs` will show the location of all the log files
- `rush publish --include-all --pack --release-folder ./tarballs --publish`
If you want to get a set of `.tar.gz` files of the node modules to use for local testing this command will put them into the `tarballs` directory
- `rush rebuild --to fvtests` to run the unit tests for the core modules, but not the docker or jsdoc
- `rush rebuild --to fabric-contract-api` to build, lint and run just the `fabric-contract-api`
- `rush logs` will show the location of all the log files

To clean up docker

* `docker kill $(docker ps -q) && docker rm $(docker ps -aq)` will remove the running containers
* `docker rmi $(docker images 'dev-*' -q) --force` will remove the images for the chaincode containers
- `docker kill $(docker ps -q) && docker rm $(docker ps -aq)` will remove the running containers
- `docker rmi $(docker images 'dev-*' -q) --force` will remove the images for the chaincode containers

## Mechanics of Contributing

The codebase is maintained in [github](https://github.com/hyperledger/fabric-chaincode-node), with a CI pipeline run with [Github Actions](https://github.com/hyperledger/fabric-chaincode-node/actions). Issues are handled in [Github Issues](https://github.com/hyperledger/fabric-chaincode-node/issues).



## Code of Conduct Guidelines <a name="conduct"></a>

See our [Code of Conduct Guidelines](https://github.com/hyperledger/fabric-chaincode-node/blob/main/CODE_OF_CONDUCT.md).
Expand Down
36 changes: 17 additions & 19 deletions TUTORIAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The dependencies of `fabric-contract-api` and `fabric-shim` will be required.
"name": "chaincode",
"description": "My first exciting chaincode implemented in node.js",
"engines": {
"node": ">=18"
"node": ">=20"
},
"scripts": {
"test": "mocha....."
Expand All @@ -33,6 +33,7 @@ The dependencies of `fabric-contract-api` and `fabric-shim` will be required.
}

```

Remember to add in any additional business logic, and testing libraries needed

Adding `fabric-shim` as a dependency, gives a command `fabric-chaincode-node` that is the script to run for `npm start`.
Expand All @@ -45,7 +46,6 @@ Adding `fabric-shim` as a dependency, gives a command `fabric-chaincode-node` th
},
```


### 2: How is chaincode deployed?

Chaincode is deployed by the peer in response to issuing a number of (usually CLI) commands. For node.js chaincode the location of the chaincode npm project is required (the directory that the package.json is in). This does not need to be an installed project, but has to have all the code, and the package.json.
Expand All @@ -54,7 +54,7 @@ A docker image is built for this chaincode, the package.json and code copied in.

After the install there is a 'bootstrap' process that starts the chaincode up (more details later). The constructors of the exported Contracts will be run at this point; these constructors are for setting the name and optional setup of the 'error/monitoring functions', (again more later). This instance of the contract will existing whilst this chaincode docker image is up.

When chaincode is instantiated or updated, the `init()` function in the chaincode is called. As with the `invoke()` call from the client, a fn name and parameters can be passed. Remember therefore to have specific functions to call on `init()` and `update()` in order to do any data initialisation or migration that might be needed. These two functions have been abstracted away to focus on specific function implementations.
When chaincode is instantiated or updated, the `init()` function in the chaincode is called. As with the `invoke()` call from the client, a fn name and parameters can be passed. Remember therefore to have specific functions to call on `init()` and `update()` in order to do any data initialisation or migration that might be needed. These two functions have been abstracted away to focus on specific function implementations.

It is strongly recommended to use the npm shrinkwrap mechanism so the versions of the modules that are used are fixed.

Expand All @@ -77,7 +77,7 @@ module.exports.contracts = [UpdateValues, RemoveValues];
```

This exports two classes that together form the Contract. There can be other code that within the model that is used in a support role.
*Note that the 'contracts' word is mandatory.*
_Note that the 'contracts' word is mandatory._

### 4: What do these classes need to contain?

Expand Down Expand Up @@ -159,15 +159,13 @@ Then you can invoke the chaincode via this command.
$ peer chaincode invoke --orderer localhost:7050 --channelID mychannel -c '{"Args":["UpdateValuesContract:getAssetValue"]}' -n mycontract4
```


## Additional support provided by the SmartContract class

In case you ask for a function to be executed, it could be that this doesn't exist.
If so, you can provide you own function to be executed, the default is to throw and error but you're able to customise this if you wish.

For example


```
/**
* Sets a name so that the functions in this particular class can
Expand Down Expand Up @@ -206,14 +204,14 @@ async aroundTransaction(ctx, fn, parameters) {

### Structure of the Transaction Context

In Fabric, there is a *stub* api that provides chaincode with functionality.
In Fabric, there is a _stub_ api that provides chaincode with functionality.
No functionality has been removed, but a new approach to providing abstractions on this to facilitate programming.

*user additions*: additional properties can be added to the object to support for example common handling of the data serialization.
_user additions_: additional properties can be added to the object to support for example common handling of the data serialization.

The context object contains

- `ctx.stub` the same stub instance as in earlier versions for compatibility
- `ctx.stub` the same stub instance as in earlier versions for compatibility
- `ctx.identity` and instance of the Client Identity object

You are at liberty to create a subclass of the Context to provide additional functions, or per-transaction context storage. For example
Expand Down Expand Up @@ -249,29 +247,29 @@ class ScenarioContext extends Context {

Definitions as per https://www.ietf.org/rfc/rfc2119.txt

- All the functions that are present in the prototype of a class that extends *Contract* will be invokable
- The exports from the node module *MUST* include *contracts* that is an array of constructors (1 or more)
- Each class *MAY* call in it's constructor pass a name. This is prefixed to each of the function names by an _ (underscore)
- Each class *MAY* define functions that are executed before and functions that are executed after the invoked function.
- All the functions that are present in the prototype of a class that extends _Contract_ will be invokable
- The exports from the node module _MUST_ include _contracts_ that is an array of constructors (1 or more)
- Each class _MAY_ call in it's constructor pass a name. This is prefixed to each of the function names by an \_ (underscore)
- Each class _MAY_ define functions that are executed before and functions that are executed after the invoked function.
- These are part of the same fabric transaction
- They are scoped per name
- Each class *MAY* define a function that would be executed if a matching function name does not exist; otherwise a 'no function exists' error will be thrown
- Each class _MAY_ define a function that would be executed if a matching function name does not exist; otherwise a 'no function exists' error will be thrown
- If too many parameters are passed, they will be discarded
- If too few parameters are passed, the remainder will be set to undefined
- as per node.js language standard
- as per node.js language standard
- Having duplicate function names in a single class is an error
- Any function that is dynamically added will not be registered as an invokable function
- There is no specific function that is invoked per Fabric's *init* chaincode spi. The instantiate flow can pass function name and parameters; therefore consider
a dedicated function that will be called for new chaincode deployments, and for upgrade deployments.
- There is no specific function that is invoked per Fabric's _init_ chaincode spi. The instantiate flow can pass function name and parameters; therefore consider
a dedicated function that will be called for new chaincode deployments, and for upgrade deployments.

## Restrictions on programming in side a Contract function

Hyperledger Fabric's consensus algorithm permits the ability to use general purpose languages; rather than a more restrictive language. But the following restrictions apply

- Functions should not create random variables, or use any function whose return values are functions of the current time or location of execution
- i.e. the function will be executed in another context (i.e. peer process). This could potentially be in a different time zone in a different locale.
- i.e. the function will be executed in another context (i.e. peer process). This could potentially be in a different time zone in a different locale.
- Functions should be aware that they may read state, and write state. But they are producing a set of changes that will be applied to the state. The implication is that updates to the state
may not be read back.
may not be read back.

```
let v1 = getState("key");
Expand Down
4 changes: 2 additions & 2 deletions apis/fabric-contract-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"Fabric Shim"
],
"engines": {
"node": ">=18"
"node": ">=20"
},
"license": "Apache-2.0",
"types": "./types/index.d.ts",
Expand Down Expand Up @@ -70,6 +70,6 @@
"typescript": "~5.8.3",
"typescript-eslint": "^8.46.0",
"@eslint/js": "^9.37.0",
"@tsconfig/node18": "~18.2.4"
"@tsconfig/node20": "~20.1.6"
}
}
2 changes: 1 addition & 1 deletion apis/fabric-contract-api/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@tsconfig/node18/tsconfig.json",
"extends": "@tsconfig/node20/tsconfig.json",
"compilerOptions": {
"types": ["./types/"],
"declaration": true,
Expand Down
5 changes: 3 additions & 2 deletions apis/fabric-shim-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@
"Fabric Shim"
],
"engines": {
"node": ">=18"
"node": ">=20"
},
"types": "./types/index.d.ts",
"license": "Apache-2.0",
"devDependencies": {
"@types/long": "^4.0.1",
"eslint": "^9.37.0",
"@eslint/js": "^9.37.0"
"@eslint/js": "^9.37.0",
"@tsconfig/node20": "~20.1.6"
}
}
31 changes: 13 additions & 18 deletions apis/fabric-shim-api/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,17 @@
* SPDX-License-Identifier: Apache-2.0
*/
{
"compilerOptions": {
"types": ["./types/"],
"alwaysStrict": true,
"module": "commonjs",
"declaration": true,
"sourceMap": true,
"strict": true,
"target": "es2017",
"lib": [
"esnext",
]
},
"files": [
"types/index.d.ts"
],
"exclude": [
"node_modules/**/*"
]
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@tsconfig/node20/tsconfig.json",
"compilerOptions": {
"types": ["./types/"],
"declaration": true,
"declarationMap": true,
"erasableSyntaxOnly": true,
"isolatedModules": true,
"sourceMap": true,
"strict": true
},
"files": ["types/index.d.ts"],
"exclude": ["node_modules/**/*"]
}
Loading
Loading