mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-18 16:05:10 +00:00
[FAB-12852] Add fabcar contract w/ new prog model (TS)
Add new FabCar contract sample using the new programming model, written in TypeScript. 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: I47e5f16b475c68f9a1c4752af2623f090fbf12c9 Signed-off-by: Simon Stone <sstone1@uk.ibm.com>
This commit is contained in:
parent
fad8ee1e50
commit
4fb3b57e6b
8 changed files with 368 additions and 0 deletions
16
chaincode/fabcar/typescript/.editorconfig
Executable file
16
chaincode/fabcar/typescript/.editorconfig
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
81
chaincode/fabcar/typescript/.gitignore
vendored
Normal file
81
chaincode/fabcar/typescript/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# next.js build output
|
||||
.next
|
||||
|
||||
# nuxt.js build output
|
||||
.nuxt
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless
|
||||
|
||||
# Compiled TypeScript files
|
||||
dist
|
||||
|
||||
62
chaincode/fabcar/typescript/package.json
Normal file
62
chaincode/fabcar/typescript/package.json
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"name": "fabcar",
|
||||
"version": "1.0.0",
|
||||
"description": "FabCar contract implemented in TypeScript",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"engines": {
|
||||
"node": ">=8",
|
||||
"npm": ">=5"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "tslint -c tslint.json 'src/**/*.ts'",
|
||||
"pretest": "npm run lint",
|
||||
"test": "nyc mocha -r ts-node/register src/**/*.spec.ts",
|
||||
"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": "1.4.0-beta",
|
||||
"fabric-shim": "1.4.0-beta"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.1.4",
|
||||
"@types/mocha": "^5.2.3",
|
||||
"@types/node": "^10.3.6",
|
||||
"@types/sinon": "^5.0.1",
|
||||
"@types/sinon-chai": "^3.2.0",
|
||||
"chai": "^4.1.2",
|
||||
"mocha": "^5.2.0",
|
||||
"nyc": "^12.0.2",
|
||||
"sinon": "^6.0.0",
|
||||
"sinon-chai": "^3.2.0",
|
||||
"ts-node": "^7.0.0",
|
||||
"tslint": "^5.10.0",
|
||||
"typescript": "^2.9.2"
|
||||
},
|
||||
"nyc": {
|
||||
"extension": [
|
||||
".ts",
|
||||
".tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"coverage/**",
|
||||
"dist/**"
|
||||
],
|
||||
"reporter": [
|
||||
"text-summary",
|
||||
"html"
|
||||
],
|
||||
"all": true,
|
||||
"check-coverage": true,
|
||||
"statements": 100,
|
||||
"branches": 100,
|
||||
"functions": 100,
|
||||
"lines": 100
|
||||
}
|
||||
}
|
||||
11
chaincode/fabcar/typescript/src/car.ts
Normal file
11
chaincode/fabcar/typescript/src/car.ts
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
export class Car {
|
||||
public docType?: string;
|
||||
public color: string;
|
||||
public make: string;
|
||||
public model: string;
|
||||
public owner: string;
|
||||
}
|
||||
153
chaincode/fabcar/typescript/src/fabcar.ts
Normal file
153
chaincode/fabcar/typescript/src/fabcar.ts
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { Context, Contract } from 'fabric-contract-api';
|
||||
import { Car } from './car';
|
||||
|
||||
export class FabCar extends Contract {
|
||||
|
||||
public async initLedger(ctx: Context) {
|
||||
console.info('============= START : Initialize Ledger ===========');
|
||||
const cars: Car[] = [
|
||||
{
|
||||
color: 'blue',
|
||||
make: 'Toyota',
|
||||
model: 'Prius',
|
||||
owner: 'Tomoko',
|
||||
},
|
||||
{
|
||||
color: 'red',
|
||||
make: 'Ford',
|
||||
model: 'Mustang',
|
||||
owner: 'Brad',
|
||||
},
|
||||
{
|
||||
color: 'green',
|
||||
make: 'Hyundai',
|
||||
model: 'Tucson',
|
||||
owner: 'Jin Soo',
|
||||
},
|
||||
{
|
||||
color: 'yellow',
|
||||
make: 'Volkswagen',
|
||||
model: 'Passat',
|
||||
owner: 'Max',
|
||||
},
|
||||
{
|
||||
color: 'black',
|
||||
make: 'Tesla',
|
||||
model: 'S',
|
||||
owner: 'Adriana',
|
||||
},
|
||||
{
|
||||
color: 'purple',
|
||||
make: 'Peugeot',
|
||||
model: '205',
|
||||
owner: 'Michel',
|
||||
},
|
||||
{
|
||||
color: 'white',
|
||||
make: 'Chery',
|
||||
model: 'S22L',
|
||||
owner: 'Aarav',
|
||||
},
|
||||
{
|
||||
color: 'violet',
|
||||
make: 'Fiat',
|
||||
model: 'Punto',
|
||||
owner: 'Pari',
|
||||
},
|
||||
{
|
||||
color: 'indigo',
|
||||
make: 'Tata',
|
||||
model: 'Nano',
|
||||
owner: 'Valeria',
|
||||
},
|
||||
{
|
||||
color: 'brown',
|
||||
make: 'Holden',
|
||||
model: 'Barina',
|
||||
owner: 'Shotaro',
|
||||
},
|
||||
];
|
||||
|
||||
for (let i = 0; i < cars.length; i++) {
|
||||
cars[i].docType = 'car';
|
||||
await ctx.stub.putState('CAR' + i, Buffer.from(JSON.stringify(cars[i])));
|
||||
console.info('Added <--> ', cars[i]);
|
||||
}
|
||||
console.info('============= END : Initialize Ledger ===========');
|
||||
}
|
||||
|
||||
public async queryCar(ctx: Context, carNumber: string): Promise<string> {
|
||||
const carAsBytes = await ctx.stub.getState(carNumber); // get the car from chaincode state
|
||||
if (!carAsBytes || carAsBytes.length === 0) {
|
||||
throw new Error(`${carNumber} does not exist`);
|
||||
}
|
||||
console.log(carAsBytes.toString());
|
||||
return carAsBytes.toString();
|
||||
}
|
||||
|
||||
public async createCar(ctx: Context, carNumber: string, make: string, model: string, color: string, owner: string) {
|
||||
console.info('============= START : Create Car ===========');
|
||||
|
||||
const car: Car = {
|
||||
color,
|
||||
docType: 'car',
|
||||
make,
|
||||
model,
|
||||
owner,
|
||||
};
|
||||
|
||||
await ctx.stub.putState(carNumber, Buffer.from(JSON.stringify(car)));
|
||||
console.info('============= END : Create Car ===========');
|
||||
}
|
||||
|
||||
public async queryAllCars(ctx: Context): Promise<string> {
|
||||
const startKey = 'CAR0';
|
||||
const endKey = 'CAR999';
|
||||
|
||||
const iterator = await ctx.stub.getStateByRange(startKey, endKey);
|
||||
|
||||
const allResults = [];
|
||||
while (true) {
|
||||
const res = await iterator.next();
|
||||
|
||||
if (res.value && res.value.value.toString()) {
|
||||
console.log(res.value.value.toString('utf8'));
|
||||
|
||||
const Key = res.value.key;
|
||||
let Record;
|
||||
try {
|
||||
Record = JSON.parse(res.value.value.toString('utf8'));
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
Record = res.value.value.toString('utf8');
|
||||
}
|
||||
allResults.push({ Key, Record });
|
||||
}
|
||||
if (res.done) {
|
||||
console.log('end of data');
|
||||
await iterator.close();
|
||||
console.info(allResults);
|
||||
return JSON.stringify(allResults);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async changeCarOwner(ctx: Context, carNumber: string, newOwner: string) {
|
||||
console.info('============= START : changeCarOwner ===========');
|
||||
|
||||
const carAsBytes = await ctx.stub.getState(carNumber); // get the car from chaincode state
|
||||
if (!carAsBytes || carAsBytes.length === 0) {
|
||||
throw new Error(`${carNumber} does not exist`);
|
||||
}
|
||||
const car: Car = JSON.parse(carAsBytes.toString());
|
||||
car.owner = newOwner;
|
||||
|
||||
await ctx.stub.putState(carNumber, Buffer.from(JSON.stringify(car)));
|
||||
console.info('============= END : changeCarOwner ===========');
|
||||
}
|
||||
|
||||
}
|
||||
8
chaincode/fabcar/typescript/src/index.ts
Normal file
8
chaincode/fabcar/typescript/src/index.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { FabCar } from './fabcar';
|
||||
export { FabCar } from './fabcar';
|
||||
|
||||
export const contracts: any[] = [ FabCar ];
|
||||
16
chaincode/fabcar/typescript/tsconfig.json
Normal file
16
chaincode/fabcar/typescript/tsconfig.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"target": "es2017",
|
||||
"moduleResolution": "node",
|
||||
"module": "commonjs",
|
||||
"declaration": true,
|
||||
"sourceMap": true
|
||||
},
|
||||
"include": [
|
||||
"./src/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"./src/**/*.spec.ts"
|
||||
]
|
||||
}
|
||||
21
chaincode/fabcar/typescript/tslint.json
Normal file
21
chaincode/fabcar/typescript/tslint.json
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"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": []
|
||||
}
|
||||
Loading…
Reference in a new issue