Skip to content

Commit 9facb42

Browse files
author
Simon Stone
committed
[FAB-12851] Add fabcar contract w/ new prog model (JS)
Add new FabCar contract sample using the new programming model, written in JavaScript. Add the new contract sample alongside the existing one written in the old programming model, which will be removed in a subsequent change request. Change-Id: Iea46b0a616dbd072b5bd7227ada827a26560f153 Signed-off-by: Simon Stone <sstone1@uk.ibm.com>
1 parent 1c82113 commit 9facb42

File tree

7 files changed

+349
-0
lines changed

7 files changed

+349
-0
lines changed
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
5+
root = true
6+
7+
[*]
8+
indent_style = space
9+
indent_size = 4
10+
end_of_line = lf
11+
charset = utf-8
12+
trim_trailing_whitespace = true
13+
insert_final_newline = true
14+
15+
[*.md]
16+
trim_trailing_whitespace = false
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
5+
coverage
+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*/
4+
5+
module.exports = {
6+
env: {
7+
node: true,
8+
mocha: true
9+
},
10+
parserOptions: {
11+
ecmaVersion: 8,
12+
sourceType: 'script'
13+
},
14+
extends: "eslint:recommended",
15+
rules: {
16+
indent: ['error', 4],
17+
'linebreak-style': ['error', 'unix'],
18+
quotes: ['error', 'single'],
19+
semi: ['error', 'always'],
20+
'no-unused-vars': ['error', { args: 'none' }],
21+
'no-console': 'off',
22+
curly: 'error',
23+
eqeqeq: 'error',
24+
'no-throw-literal': 'error',
25+
strict: 'error',
26+
'no-var': 'error',
27+
'dot-notation': 'error',
28+
'no-tabs': 'error',
29+
'no-trailing-spaces': 'error',
30+
'no-use-before-define': 'error',
31+
'no-useless-call': 'error',
32+
'no-with': 'error',
33+
'operator-linebreak': 'error',
34+
yoda: 'error',
35+
'quote-props': ['error', 'as-needed'],
36+
'no-constant-condition': ["error", { "checkLoops": false }]
37+
}
38+
};
+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
5+
# Logs
6+
logs
7+
*.log
8+
npm-debug.log*
9+
yarn-debug.log*
10+
yarn-error.log*
11+
12+
# Runtime data
13+
pids
14+
*.pid
15+
*.seed
16+
*.pid.lock
17+
18+
# Directory for instrumented libs generated by jscoverage/JSCover
19+
lib-cov
20+
21+
# Coverage directory used by tools like istanbul
22+
coverage
23+
24+
# nyc test coverage
25+
.nyc_output
26+
27+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
28+
.grunt
29+
30+
# Bower dependency directory (https://bower.io/)
31+
bower_components
32+
33+
# node-waf configuration
34+
.lock-wscript
35+
36+
# Compiled binary addons (https://nodejs.org/api/addons.html)
37+
build/Release
38+
39+
# Dependency directories
40+
node_modules/
41+
jspm_packages/
42+
43+
# TypeScript v1 declaration files
44+
typings/
45+
46+
# Optional npm cache directory
47+
.npm
48+
49+
# Optional eslint cache
50+
.eslintcache
51+
52+
# Optional REPL history
53+
.node_repl_history
54+
55+
# Output of 'npm pack'
56+
*.tgz
57+
58+
# Yarn Integrity file
59+
.yarn-integrity
60+
61+
# dotenv environment variables file
62+
.env
63+
64+
# parcel-bundler cache (https://parceljs.org/)
65+
.cache
66+
67+
# next.js build output
68+
.next
69+
70+
# nuxt.js build output
71+
.nuxt
72+
73+
# vuepress build output
74+
.vuepress/dist
75+
76+
# Serverless directories
77+
.serverless

chaincode/fabcar/javascript/index.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*/
4+
5+
'use strict';
6+
7+
const FabCar = require('./lib/fabcar');
8+
9+
module.exports.FabCar = FabCar;
10+
module.exports.contracts = [ FabCar ];
+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*/
4+
5+
'use strict';
6+
7+
const { Contract } = require('fabric-contract-api');
8+
9+
class FabCar extends Contract {
10+
11+
async initLedger(ctx) {
12+
console.info('============= START : Initialize Ledger ===========');
13+
const cars = [
14+
{
15+
color: 'blue',
16+
make: 'Toyota',
17+
model: 'Prius',
18+
owner: 'Tomoko',
19+
},
20+
{
21+
color: 'red',
22+
make: 'Ford',
23+
model: 'Mustang',
24+
owner: 'Brad',
25+
},
26+
{
27+
color: 'green',
28+
make: 'Hyundai',
29+
model: 'Tucson',
30+
owner: 'Jin Soo',
31+
},
32+
{
33+
color: 'yellow',
34+
make: 'Volkswagen',
35+
model: 'Passat',
36+
owner: 'Max',
37+
},
38+
{
39+
color: 'black',
40+
make: 'Tesla',
41+
model: 'S',
42+
owner: 'Adriana',
43+
},
44+
{
45+
color: 'purple',
46+
make: 'Peugeot',
47+
model: '205',
48+
owner: 'Michel',
49+
},
50+
{
51+
color: 'white',
52+
make: 'Chery',
53+
model: 'S22L',
54+
owner: 'Aarav',
55+
},
56+
{
57+
color: 'violet',
58+
make: 'Fiat',
59+
model: 'Punto',
60+
owner: 'Pari',
61+
},
62+
{
63+
color: 'indigo',
64+
make: 'Tata',
65+
model: 'Nano',
66+
owner: 'Valeria',
67+
},
68+
{
69+
color: 'brown',
70+
make: 'Holden',
71+
model: 'Barina',
72+
owner: 'Shotaro',
73+
},
74+
];
75+
76+
for (let i = 0; i < cars.length; i++) {
77+
cars[i].docType = 'car';
78+
await ctx.stub.putState('CAR' + i, Buffer.from(JSON.stringify(cars[i])));
79+
console.info('Added <--> ', cars[i]);
80+
}
81+
console.info('============= END : Initialize Ledger ===========');
82+
}
83+
84+
async queryCar(ctx, carNumber) {
85+
const carAsBytes = await ctx.stub.getState(carNumber); // get the car from chaincode state
86+
if (!carAsBytes || carAsBytes.length === 0) {
87+
throw new Error(`${carNumber} does not exist`);
88+
}
89+
console.log(carAsBytes.toString());
90+
return carAsBytes.toString();
91+
}
92+
93+
async createCar(ctx, carNumber, make, model, color, owner) {
94+
console.info('============= START : Create Car ===========');
95+
96+
const car = {
97+
color,
98+
docType: 'car',
99+
make,
100+
model,
101+
owner,
102+
};
103+
104+
await ctx.stub.putState(carNumber, Buffer.from(JSON.stringify(car)));
105+
console.info('============= END : Create Car ===========');
106+
}
107+
108+
async queryAllCars(ctx) {
109+
const startKey = 'CAR0';
110+
const endKey = 'CAR999';
111+
112+
const iterator = await ctx.stub.getStateByRange(startKey, endKey);
113+
114+
const allResults = [];
115+
while (true) {
116+
const res = await iterator.next();
117+
118+
if (res.value && res.value.value.toString()) {
119+
console.log(res.value.value.toString('utf8'));
120+
121+
const Key = res.value.key;
122+
let Record;
123+
try {
124+
Record = JSON.parse(res.value.value.toString('utf8'));
125+
} catch (err) {
126+
console.log(err);
127+
Record = res.value.value.toString('utf8');
128+
}
129+
allResults.push({ Key, Record });
130+
}
131+
if (res.done) {
132+
console.log('end of data');
133+
await iterator.close();
134+
console.info(allResults);
135+
return JSON.stringify(allResults);
136+
}
137+
}
138+
}
139+
140+
async changeCarOwner(ctx, carNumber, newOwner) {
141+
console.info('============= START : changeCarOwner ===========');
142+
143+
const carAsBytes = await ctx.stub.getState(carNumber); // get the car from chaincode state
144+
if (!carAsBytes || carAsBytes.length === 0) {
145+
throw new Error(`${carNumber} does not exist`);
146+
}
147+
const car = JSON.parse(carAsBytes.toString());
148+
car.owner = newOwner;
149+
150+
await ctx.stub.putState(carNumber, Buffer.from(JSON.stringify(car)));
151+
console.info('============= END : changeCarOwner ===========');
152+
}
153+
154+
}
155+
156+
module.exports = FabCar;
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"name": "fabcar",
3+
"version": "1.0.0",
4+
"description": "FabCar contract implemented in JavaScript",
5+
"main": "index.js",
6+
"engines": {
7+
"node": ">=8",
8+
"npm": ">=5"
9+
},
10+
"scripts": {
11+
"lint": "eslint .",
12+
"pretest": "npm run lint",
13+
"test": "nyc mocha --recursive",
14+
"start": "fabric-chaincode-node start"
15+
},
16+
"engineStrict": true,
17+
"author": "Hyperledger",
18+
"license": "Apache-2.0",
19+
"dependencies": {
20+
"fabric-contract-api": "1.4.0-beta",
21+
"fabric-shim": "1.4.0-beta"
22+
},
23+
"devDependencies": {
24+
"chai": "^4.1.2",
25+
"eslint": "^4.19.1",
26+
"mocha": "^5.2.0",
27+
"nyc": "^12.0.2",
28+
"sinon": "^6.0.0",
29+
"sinon-chai": "^3.2.0"
30+
},
31+
"nyc": {
32+
"exclude": [
33+
"coverage/**",
34+
"test/**"
35+
],
36+
"reporter": [
37+
"text-summary",
38+
"html"
39+
],
40+
"all": true,
41+
"check-coverage": true,
42+
"statements": 100,
43+
"branches": 100,
44+
"functions": 100,
45+
"lines": 100
46+
}
47+
}

0 commit comments

Comments
 (0)