DEV Community

Cover image for How to write Chaincode Contract for Hyperledger Fabric in TypeScript
dani
dani

Posted on

How to write Chaincode Contract for Hyperledger Fabric in TypeScript

Hello developer, in this tutorial we will learn how to create Chaincode Contract for Hyperledger Fabric. This post is the first of a series dedicated to setting up a development environment for Hyperledger Fabric.

Create a folder and a package.json file

$ mkdir contracts/myFirstContract
$ cd contracts/myFirstContract
$ touch package.json
Enter fullscreen mode Exit fullscreen mode

Edit contracts/myFirstContract/package.json file (replace with this)

{
    "name": "myfirstcontract",
    "version": "0.1.0",
    "description": "Hyperledger Fabric Chaincode Contract",
    "main": "dist/index.js",
    "typings": "dist/index.d.ts",
    "engines": {
        "node": ">=8",
        "npm": ">=5"
    },
    "scripts": {
        "lint": "tslint -c tslint.json './**/*.ts'  -e './node_modules/**'",
        "pretest": "npm run lint",
        "start": "fabric-chaincode-node start",
        "build": "tsc",
        "build:watch": "tsc -w",
        "prepublishOnly": "npm run build"
    },
    "engineStrict": true,
    "author": "Hyperledger",
    "license": "Apache-2.0",
    "dependencies": {
        "fabric-contract-api": "^2.0.0",
        "fabric-shim": "^2.0.0",
        "hyperledger-fabric-chaincode-helper": "^0.0.14"
    },
    "devDependencies": {
        "@types/chai": "^4.1.7",
        "@types/mocha": "^5.2.5",
        "@types/node": "^10.12.10",
        "@types/sinon": "^5.0.7",
        "@types/sinon-chai": "^3.2.1",
        "chai": "^4.2.0",
        "mocha": "^5.2.0",
        "nyc": "^14.1.1",
        "sinon": "^7.1.1",
        "sinon-chai": "^3.3.0",
        "ts-node": "^7.0.1",
        "tslint": "^5.11.0",
        "typescript": "^3.1.6"
    },
    "nyc": {
        "extension": [
            ".ts",
            ".tsx"
        ],
        "exclude": [
            "coverage/**",
            "dist/**"
        ],
        "reporter": [
            "text-summary",
            "html"
        ],
        "all": true,
        "check-coverage": true,
        "statements": 100,
        "branches": 100,
        "functions": 100,
        "lines": 100
    },
    "resolutions": {
        "class-transformer": "^0.3.1",
        "minimist": "^0.2.1"
    }
}

Enter fullscreen mode Exit fullscreen mode
$ npm install
Enter fullscreen mode Exit fullscreen mode

Create: contracts/myFirstContract/typescript/tsconfig.json

$ touch typescript/tsconfig.json
Enter fullscreen mode Exit fullscreen mode
{
  "compilerOptions": {
      "outDir": "dist",
      "target": "es2017",
      "moduleResolution": "node",
      "module": "commonjs",
      "declaration": true,
      "sourceMap": true
  },
  "include": [
      "./**/*.ts"
  ],
  "exclude": [
      "./**/*.spec.ts"
  ]
}

Enter fullscreen mode Exit fullscreen mode

Create: contracts/myFirstContract/typescript/tslint.json

$ touch typescript/tslint.json
Enter fullscreen mode Exit fullscreen mode
{
  "defaultSeverity": "error",
  "extends": [
      "tslint:recommended"
  ],
  "jsRules": {},
  "rules": {
      "indent": [true, "spaces", 4],
      "linebreak-style": [true, "LF"],
      "quotemark": [true, "single"],
      "semicolon": [true, "always"],
      "no-console": false,
      "curly": true,
      "triple-equals": true,
      "no-string-throw": true,
      "no-var-keyword": true,
      "no-trailing-whitespace": true,
      "object-literal-key-quotes": [true, "as-needed"]
  },
  "rulesDirectory": []
}
Enter fullscreen mode Exit fullscreen mode

Create the entry file: contracts/myFirstContract/typescript/index.ts

$ touch typescript/index.ts
Enter fullscreen mode Exit fullscreen mode
'use strict';

import { MyFirstContract } from './lib/myfirstcontract';
export { MyFirstContract } from './lib/myfirstcontract';

export const contracts: any[] = [ MyFirstContract ];
Enter fullscreen mode Exit fullscreen mode

Create the main file: contracts/myFirstContract/typescript/lib/myfirstcontract.ts

$ touch typescript/lib/myfirstcontract.ts
Enter fullscreen mode Exit fullscreen mode
/*
 * SPDX-License-Identifier: Apache-2.0
 */

'use strict';

import { BlockotusContract } from 'hyperledger-fabric-chaincode-helper';

import type { Context } from 'fabric-contract-api';

export class MyFirstContract extends BlockotusContract {

    constructor(...args) {
        super(...args);
    }

    public async initLedger() {
        console.log('initLedger');
    }

    public helloWorld(ctx: Context) {
        const params = this.getParams(ctx);
        return `Hello ${params[0]}`;
    }

}

Enter fullscreen mode Exit fullscreen mode

Here we are, your first contract with no functionality is ready! 🍾

Discussion (0)