From bee5f6e07f3ec2bd247af6ba4595d2413feb2b1b Mon Sep 17 00:00:00 2001 From: Chongxin Luo Date: Mon, 15 Jun 2020 16:43:27 -0400 Subject: [PATCH] Adding chaincode-js to asset-transfer-basic Signed-off-by: Chongxin Luo --- .../chaincode-javascript/.eslintignore | 5 + .../chaincode-javascript/.eslintrc.js | 38 +++++ .../chaincode-javascript/.gitignore | 12 ++ .../chaincode-javascript/index.js | 12 ++ .../chaincode-javascript/lib/assetTransfer.js | 159 ++++++++++++++++++ .../chaincode-javascript/package.json | 47 ++++++ 6 files changed, 273 insertions(+) create mode 100644 asset-transfer-basic/chaincode-javascript/.eslintignore create mode 100644 asset-transfer-basic/chaincode-javascript/.eslintrc.js create mode 100644 asset-transfer-basic/chaincode-javascript/.gitignore create mode 100644 asset-transfer-basic/chaincode-javascript/index.js create mode 100644 asset-transfer-basic/chaincode-javascript/lib/assetTransfer.js create mode 100644 asset-transfer-basic/chaincode-javascript/package.json diff --git a/asset-transfer-basic/chaincode-javascript/.eslintignore b/asset-transfer-basic/chaincode-javascript/.eslintignore new file mode 100644 index 00000000..15958470 --- /dev/null +++ b/asset-transfer-basic/chaincode-javascript/.eslintignore @@ -0,0 +1,5 @@ +# +# SPDX-License-Identifier: Apache-2.0 +# + +coverage diff --git a/asset-transfer-basic/chaincode-javascript/.eslintrc.js b/asset-transfer-basic/chaincode-javascript/.eslintrc.js new file mode 100644 index 00000000..6d5751a5 --- /dev/null +++ b/asset-transfer-basic/chaincode-javascript/.eslintrc.js @@ -0,0 +1,38 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +module.exports = { + env: { + node: true, + mocha: true + }, + parserOptions: { + ecmaVersion: 8, + sourceType: 'script' + }, + extends: "eslint:recommended", + rules: { + indent: ['error', 4], + 'linebreak-style': ['error', 'unix'], + quotes: ['error', 'single'], + semi: ['error', 'always'], + 'no-unused-vars': ['error', { args: 'none' }], + 'no-console': 'off', + curly: 'error', + eqeqeq: 'error', + 'no-throw-literal': 'error', + strict: 'error', + 'no-var': 'error', + 'dot-notation': 'error', + 'no-tabs': 'error', + 'no-trailing-spaces': 'error', + 'no-use-before-define': 'error', + 'no-useless-call': 'error', + 'no-with': 'error', + 'operator-linebreak': 'error', + yoda: 'error', + 'quote-props': ['error', 'as-needed'], + 'no-constant-condition': ["error", { "checkLoops": false }] + } +}; diff --git a/asset-transfer-basic/chaincode-javascript/.gitignore b/asset-transfer-basic/chaincode-javascript/.gitignore new file mode 100644 index 00000000..60611a46 --- /dev/null +++ b/asset-transfer-basic/chaincode-javascript/.gitignore @@ -0,0 +1,12 @@ +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Coverage directory used by tools like istanbul +coverage + +# Dependency directories +node_modules/ +jspm_packages/ + +package-lock.json diff --git a/asset-transfer-basic/chaincode-javascript/index.js b/asset-transfer-basic/chaincode-javascript/index.js new file mode 100644 index 00000000..55a0dcfb --- /dev/null +++ b/asset-transfer-basic/chaincode-javascript/index.js @@ -0,0 +1,12 @@ +/* + * Copyright IBM Corp. All Rights Reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict'; + +const assetTransfer = require('./lib/assetTransfer'); + +module.exports.AssetTransfer = assetTransfer; +module.exports.contracts = [assetTransfer]; diff --git a/asset-transfer-basic/chaincode-javascript/lib/assetTransfer.js b/asset-transfer-basic/chaincode-javascript/lib/assetTransfer.js new file mode 100644 index 00000000..f3f3fc77 --- /dev/null +++ b/asset-transfer-basic/chaincode-javascript/lib/assetTransfer.js @@ -0,0 +1,159 @@ +/* + * Copyright IBM Corp. All Rights Reserved. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +'use strict'; + +const { Contract } = require('fabric-contract-api'); + +class AssetTransfer extends Contract { + + async initLedger(ctx) { + const assets = [ + { + ID: 'asset1', + Color: 'blue', + Size: 5, + Owner: 'Tomoko', + AppraisedValue: 300, + }, + { + ID: 'asset2', + Color: 'red', + Size: 5, + Owner: 'Brad', + AppraisedValue: 400, + }, + { + ID: 'asset3', + Color: 'green', + Size: 10, + Owner: 'Jin Soo', + AppraisedValue: 500, + }, + { + ID: 'asset4', + Color: 'yellow', + Size: 10, + Owner: 'Max', + AppraisedValue: 600, + }, + { + ID: 'asset5', + Color: 'black', + Size: 15, + Owner: 'Adriana', + AppraisedValue: 700, + }, + { + ID: 'asset6', + Color: 'white', + Size: 15, + Owner: 'Michel', + AppraisedValue: 800, + }, + ]; + + for (let i = 0; i < assets.length; i++) { + assets[i].docType = 'asset'; + await ctx.stub.putState(assets[i].ID, Buffer.from(JSON.stringify(assets[i]))); + console.info('Added <--> ', assets[i]); + } + } + + // createAsset issues a new asset to the world state with given details. + async createAsset(ctx, id, color, size, owner, appraisedValue) { + const asset = { + ID: id, + Color: color, + Size: size, + Owner: owner, + AppraisedValue: appraisedValue, + }; + + await ctx.stub.putState(id, Buffer.from(JSON.stringify(asset))); + } + + // readAsset returns the asset stored in the world state with given id. + async readAsset(ctx, id) { + const assetJSON = await ctx.stub.getState(id); // get the asset from chaincode state + if (!assetJSON || assetJSON.length === 0) { + throw new Error(`The asset ${id} does not exist`); + } + + return assetJSON.toString(); + } + + // updateAsset updates an existing asset in the world state with provided parameters. + async updateAsset(ctx, id, color, size, owner, appraisedValue) { + const exists = await this.assetExists(ctx, id); + if (!exists) { + throw new Error(`The asset ${id} does not exist`); + } + + // overwritting original asset with new asset + let updatedAsset = { + ID: id, + Color: color, + Size: size, + Owner: owner, + AppraisedValue: appraisedValue, + }; + + return ctx.stub.putState(id, Buffer.from(JSON.stringify(updatedAsset))); + } + + // deleteAsset deletes an given asset from the world state. + async deleteAsset(ctx, id) { + const exists = await this.assetExists(ctx, id); + if (!exists) { + throw new Error(`The asset ${id} does not exist`); + } + + return ctx.stub.deleteState(id); + } + + // assetExists returns true when asset with given ID exists in world state. + async assetExists(ctx, id) { + const assetJSON = await ctx.stub.getState(id); + if (!assetJSON || assetJSON.length === 0) { + return false; + } + return true; + } + + // transferAsset updates the owner field of asset with given id in the world state. + async transferAsset(ctx, id, newOwner) { + let assetString = await this.readAsset(ctx, id); + + let asset = JSON.parse(assetString); + asset.Owner = newOwner; + + await ctx.stub.putState(id, Buffer.from(JSON.stringify(asset))); + } + + // getAllAssets returns all assets found in the world state. + async getAllAssets(ctx) { + const allResults = []; + // range query with empty string for startKey and endKey does an open-ended query of all assets in the chaincode namespace. + for await (const { key, value } of ctx.stub.getStateByRange("", "")) { + const strValue = Buffer.from(value).toString('utf8'); + let record; + try { + record = JSON.parse(strValue); + } catch (err) { + console.log(err); + record = strValue; + } + allResults.push({ Key: key, Record: record }); + } + console.info(allResults); + return JSON.stringify(allResults); + } + + +} + +module.exports = AssetTransfer; diff --git a/asset-transfer-basic/chaincode-javascript/package.json b/asset-transfer-basic/chaincode-javascript/package.json new file mode 100644 index 00000000..fabc3180 --- /dev/null +++ b/asset-transfer-basic/chaincode-javascript/package.json @@ -0,0 +1,47 @@ +{ + "name": "asset-transfer-basic", + "version": "1.0.0", + "description": "Asset-Transfer-Basic contract implemented in JavaScript", + "main": "index.js", + "engines": { + "node": ">=12", + "npm": ">=5" + }, + "scripts": { + "lint": "eslint .", + "pretest": "npm run lint", + "test": "nyc mocha --recursive", + "start": "fabric-chaincode-node start" + }, + "engineStrict": true, + "author": "Hyperledger", + "license": "Apache-2.0", + "dependencies": { + "fabric-contract-api": "^2.0.0", + "fabric-shim": "^2.0.0" + }, + "devDependencies": { + "chai": "^4.1.2", + "eslint": "^4.19.1", + "mocha": "^8.0.1", + "nyc": "^14.1.1", + "sinon": "^6.0.0", + "sinon-chai": "^3.2.0" + }, + "nyc": { + "exclude": [ + "coverage/**", + "test/**" + ], + "reporter": [ + "text-summary", + "html" + ], + "all": true, + "check-coverage": true, + "statements": 100, + "branches": 100, + "functions": 100, + "lines": 100 + } +}