mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-21 09:05:10 +00:00
Adding chaincode-js to asset-transfer-basic
Signed-off-by: Chongxin Luo <Chongxin.Luo@ibm.com>
This commit is contained in:
parent
22bcf8cfa4
commit
bee5f6e07f
6 changed files with 273 additions and 0 deletions
5
asset-transfer-basic/chaincode-javascript/.eslintignore
Normal file
5
asset-transfer-basic/chaincode-javascript/.eslintignore
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
coverage
|
||||||
38
asset-transfer-basic/chaincode-javascript/.eslintrc.js
Normal file
38
asset-transfer-basic/chaincode-javascript/.eslintrc.js
Normal file
|
|
@ -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 }]
|
||||||
|
}
|
||||||
|
};
|
||||||
12
asset-transfer-basic/chaincode-javascript/.gitignore
vendored
Normal file
12
asset-transfer-basic/chaincode-javascript/.gitignore
vendored
Normal file
|
|
@ -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
|
||||||
12
asset-transfer-basic/chaincode-javascript/index.js
Normal file
12
asset-transfer-basic/chaincode-javascript/index.js
Normal file
|
|
@ -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];
|
||||||
159
asset-transfer-basic/chaincode-javascript/lib/assetTransfer.js
Normal file
159
asset-transfer-basic/chaincode-javascript/lib/assetTransfer.js
Normal file
|
|
@ -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;
|
||||||
47
asset-transfer-basic/chaincode-javascript/package.json
Normal file
47
asset-transfer-basic/chaincode-javascript/package.json
Normal file
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue