mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-26 11:35:10 +00:00
Revert "final draft for JSON determinm task, using Genson instead of object mapper"
This reverts commit cc0f8c7bbba3ef1a0be1a9291e6c0a594b281933. revert wrong commit cc0f8c7bbba3ef1a0be1a9291e6c0a594b281933 Signed-off-by: fraVlaca <ocsenarf@outlook.com>
This commit is contained in:
parent
f95fbbe3d0
commit
944c23d8a1
135 changed files with 989 additions and 2999 deletions
|
|
@ -1,19 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
arguments=
|
||||
auto.sync=false
|
||||
build.scans.enabled=false
|
||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
||||
gradle.user.home=
|
||||
java.home=/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home
|
||||
jvm.arguments=
|
||||
offline.mode=false
|
||||
override.workspace.settings=true
|
||||
show.console.view=true
|
||||
show.executions.view=true
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,11 +0,0 @@
|
|||
import { Context, Contract } from 'fabric-contract-api';
|
||||
export declare class AssetTransferContract extends Contract {
|
||||
CreateAsset(ctx: Context, id: string, color: string, size: number, appraisedValue: number): Promise<void>;
|
||||
ReadAsset(ctx: Context, id: string): Promise<string>;
|
||||
UpdateAsset(ctx: Context, id: string, color: string, size: number, appraisedValue: number): Promise<void>;
|
||||
DeleteAsset(ctx: Context, id: string): Promise<void>;
|
||||
AssetExists(ctx: Context, id: string): Promise<boolean>;
|
||||
TransferAsset(ctx: Context, id: string, newOwner: string): Promise<void>;
|
||||
GetAllAssets(ctx: Context): Promise<string>;
|
||||
GetSubmittingClientIdentity(ctx: Context): Promise<string>;
|
||||
}
|
||||
|
|
@ -1,186 +0,0 @@
|
|||
"use strict";
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AssetTransferContract = void 0;
|
||||
const fabric_contract_api_1 = require("fabric-contract-api");
|
||||
const fabric_shim_1 = require("fabric-shim");
|
||||
let AssetTransferContract = class AssetTransferContract extends fabric_contract_api_1.Contract {
|
||||
// CreateAsset issues a new asset to the world state with given details.
|
||||
async CreateAsset(ctx, id, color, size, appraisedValue) {
|
||||
let err = new fabric_shim_1.ClientIdentity(ctx.stub).assertAttributeValue("abac.creator", "true"); // "stub" is the ChaincodeStub object passed to Init() and Invoke() methods
|
||||
if (!err) {
|
||||
throw new Error("Client not autorized, set abac.creature=true");
|
||||
}
|
||||
const exists = await this.AssetExists(ctx, id);
|
||||
if (exists) {
|
||||
throw new Error(`The asset ${id} already exists`);
|
||||
}
|
||||
const clientID = this.GetSubmittingClientIdentity(ctx);
|
||||
const asset = {
|
||||
ID: id,
|
||||
Color: color,
|
||||
Size: size,
|
||||
Owner: clientID,
|
||||
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, appraisedValue) {
|
||||
const exists = await this.AssetExists(ctx, id);
|
||||
if (!exists) {
|
||||
throw new Error(`The asset ${id} does not exist`);
|
||||
}
|
||||
const clientID = this.GetSubmittingClientIdentity(ctx);
|
||||
const assetString = await this.ReadAsset(ctx, id);
|
||||
const asset = JSON.parse(assetString);
|
||||
if (clientID != asset.getOwner()) {
|
||||
throw new Error("Client not autorized, set abac.creature=true");
|
||||
}
|
||||
// overwriting original asset with new asset
|
||||
const updatedAsset = {
|
||||
ID: id,
|
||||
Color: color,
|
||||
Size: size,
|
||||
Owner: clientID,
|
||||
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`);
|
||||
}
|
||||
const clientID = this.GetSubmittingClientIdentity(ctx);
|
||||
const assetString = await this.ReadAsset(ctx, id);
|
||||
const asset = JSON.parse(assetString);
|
||||
if (clientID != asset.getOwner()) {
|
||||
throw new Error("Client not autorized, set abac.creature=true");
|
||||
}
|
||||
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);
|
||||
return assetJSON && assetJSON.length > 0;
|
||||
}
|
||||
// TransferAsset updates the owner field of asset with given id in the world state.
|
||||
async TransferAsset(ctx, id, newOwner) {
|
||||
const assetString = await this.ReadAsset(ctx, id);
|
||||
const asset = JSON.parse(assetString);
|
||||
const clientID = this.GetSubmittingClientIdentity(ctx);
|
||||
if (clientID != asset.getOwner()) {
|
||||
throw new Error("Client not autorized, set abac.creature=true");
|
||||
}
|
||||
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.
|
||||
const iterator = await ctx.stub.getStateByRange('', '');
|
||||
let result = await iterator.next();
|
||||
while (!result.done) {
|
||||
const strValue = Buffer.from(result.value.value.toString()).toString('utf8');
|
||||
let record;
|
||||
try {
|
||||
record = JSON.parse(strValue);
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
record = strValue;
|
||||
}
|
||||
allResults.push({ Key: result.value.key, Record: record });
|
||||
result = await iterator.next();
|
||||
}
|
||||
return JSON.stringify(allResults);
|
||||
}
|
||||
// GetSubmittingClientIdentity returns the name and issuer of the identity that
|
||||
// invokes the smart contract. This function base64 decodes the identity string
|
||||
// before returning the value to the client or smart contract.
|
||||
async GetSubmittingClientIdentity(ctx) {
|
||||
const b64ID = new fabric_shim_1.ClientIdentity(ctx.stub).getID();
|
||||
if (b64ID == null) {
|
||||
throw new Error("failed to retrieve Client ID");
|
||||
}
|
||||
const decodeID = atob(b64ID);
|
||||
return String(decodeID);
|
||||
}
|
||||
};
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String, String, Number, Number]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferContract.prototype, "CreateAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(false),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferContract.prototype, "ReadAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String, String, Number, Number]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferContract.prototype, "UpdateAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferContract.prototype, "DeleteAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(false),
|
||||
fabric_contract_api_1.Returns('boolean'),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferContract.prototype, "AssetExists", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferContract.prototype, "TransferAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(false),
|
||||
fabric_contract_api_1.Returns('string'),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferContract.prototype, "GetAllAssets", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(false),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferContract.prototype, "GetSubmittingClientIdentity", null);
|
||||
AssetTransferContract = __decorate([
|
||||
fabric_contract_api_1.Info({ title: 'AssetTransfer', description: 'Smart contract for trading assets' })
|
||||
], AssetTransferContract);
|
||||
exports.AssetTransferContract = AssetTransferContract;
|
||||
//# sourceMappingURL=asset-contract.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"asset-contract.js","sourceRoot":"","sources":["../src/asset-contract.ts"],"names":[],"mappings":"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"}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
export declare class Asset {
|
||||
docType?: string;
|
||||
ID: string;
|
||||
Color: string;
|
||||
Size: number;
|
||||
Owner: string;
|
||||
AppraisedValue: number;
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
"use strict";
|
||||
/*
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Asset = void 0;
|
||||
const fabric_contract_api_1 = require("fabric-contract-api");
|
||||
let Asset = class Asset {
|
||||
};
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", String)
|
||||
], Asset.prototype, "docType", void 0);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", String)
|
||||
], Asset.prototype, "ID", void 0);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", String)
|
||||
], Asset.prototype, "Color", void 0);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", Number)
|
||||
], Asset.prototype, "Size", void 0);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", String)
|
||||
], Asset.prototype, "Owner", void 0);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", Number)
|
||||
], Asset.prototype, "AppraisedValue", void 0);
|
||||
Asset = __decorate([
|
||||
fabric_contract_api_1.Object()
|
||||
], Asset);
|
||||
exports.Asset = Asset;
|
||||
//# sourceMappingURL=asset.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"asset.js","sourceRoot":"","sources":["../src/asset.ts"],"names":[],"mappings":";AAAA;;EAEE;;;;;;;;;;;;AAEF,6DAAqD;AAGrD,IAAa,KAAK,GAAlB,MAAa,KAAK;CAkBjB,CAAA;AAhBG;IADC,8BAAQ,EAAE;;sCACa;AAGxB;IADC,8BAAQ,EAAE;;iCACO;AAGlB;IADC,8BAAQ,EAAE;;oCACU;AAGrB;IADC,8BAAQ,EAAE;;mCACS;AAGpB;IADC,8BAAQ,EAAE;;oCACU;AAGrB;IADC,8BAAQ,EAAE;;6CACmB;AAjBrB,KAAK;IADjB,4BAAM,EAAE;GACI,KAAK,CAkBjB;AAlBY,sBAAK"}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
import { Context, Contract } from 'fabric-contract-api';
|
||||
export declare class AssetTransferContract extends Contract {
|
||||
CreateAsset(ctx: Context, id: string, color: string, size: number, appraisedValue: number): Promise<void>;
|
||||
ReadAsset(ctx: Context, id: string): Promise<string>;
|
||||
UpdateAsset(ctx: Context, id: string, color: string, size: number, appraisedValue: number): Promise<void>;
|
||||
DeleteAsset(ctx: Context, id: string): Promise<void>;
|
||||
AssetExists(ctx: Context, id: string): Promise<boolean>;
|
||||
TransferAsset(ctx: Context, id: string, newOwner: string): Promise<void>;
|
||||
GetAllAssets(ctx: Context): Promise<string>;
|
||||
GetSubmittingClientIdentity(ctx: Context): Promise<string>;
|
||||
}
|
||||
|
|
@ -1,186 +0,0 @@
|
|||
"use strict";
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AssetTransferContract = void 0;
|
||||
const fabric_contract_api_1 = require("fabric-contract-api");
|
||||
const fabric_shim_1 = require("fabric-shim");
|
||||
let AssetTransferContract = class AssetTransferContract extends fabric_contract_api_1.Contract {
|
||||
// CreateAsset issues a new asset to the world state with given details.
|
||||
async CreateAsset(ctx, id, color, size, appraisedValue) {
|
||||
let err = new fabric_shim_1.ClientIdentity(ctx.stub).assertAttributeValue("abac.creator", "true"); // "stub" is the ChaincodeStub object passed to Init() and Invoke() methods
|
||||
if (!err) {
|
||||
throw new Error("Client not autorized, set abac.creature=true");
|
||||
}
|
||||
const exists = await this.AssetExists(ctx, id);
|
||||
if (exists) {
|
||||
throw new Error(`The asset ${id} already exists`);
|
||||
}
|
||||
const clientID = this.GetSubmittingClientIdentity(ctx);
|
||||
const asset = {
|
||||
ID: id,
|
||||
Color: color,
|
||||
Size: size,
|
||||
Owner: clientID,
|
||||
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, appraisedValue) {
|
||||
const exists = await this.AssetExists(ctx, id);
|
||||
if (!exists) {
|
||||
throw new Error(`The asset ${id} does not exist`);
|
||||
}
|
||||
const clientID = this.GetSubmittingClientIdentity(ctx);
|
||||
const assetString = await this.ReadAsset(ctx, id);
|
||||
const asset = JSON.parse(assetString);
|
||||
if (clientID != asset.getOwner()) {
|
||||
throw new Error("Client not autorized, set abac.creature=true");
|
||||
}
|
||||
// overwriting original asset with new asset
|
||||
const updatedAsset = {
|
||||
ID: id,
|
||||
Color: color,
|
||||
Size: size,
|
||||
Owner: clientID,
|
||||
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`);
|
||||
}
|
||||
const clientID = this.GetSubmittingClientIdentity(ctx);
|
||||
const assetString = await this.ReadAsset(ctx, id);
|
||||
const asset = JSON.parse(assetString);
|
||||
if (clientID != asset.getOwner()) {
|
||||
throw new Error("Client not autorized, set abac.creature=true");
|
||||
}
|
||||
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);
|
||||
return assetJSON && assetJSON.length > 0;
|
||||
}
|
||||
// TransferAsset updates the owner field of asset with given id in the world state.
|
||||
async TransferAsset(ctx, id, newOwner) {
|
||||
const assetString = await this.ReadAsset(ctx, id);
|
||||
const asset = JSON.parse(assetString);
|
||||
const clientID = this.GetSubmittingClientIdentity(ctx);
|
||||
if (clientID != asset.getOwner()) {
|
||||
throw new Error("Client not autorized, set abac.creature=true");
|
||||
}
|
||||
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.
|
||||
const iterator = await ctx.stub.getStateByRange('', '');
|
||||
let result = await iterator.next();
|
||||
while (!result.done) {
|
||||
const strValue = Buffer.from(result.value.value.toString()).toString('utf8');
|
||||
let record;
|
||||
try {
|
||||
record = JSON.parse(strValue);
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
record = strValue;
|
||||
}
|
||||
allResults.push({ Key: result.value.key, Record: record });
|
||||
result = await iterator.next();
|
||||
}
|
||||
return JSON.stringify(allResults);
|
||||
}
|
||||
// GetSubmittingClientIdentity returns the name and issuer of the identity that
|
||||
// invokes the smart contract. This function base64 decodes the identity string
|
||||
// before returning the value to the client or smart contract.
|
||||
async GetSubmittingClientIdentity(ctx) {
|
||||
const b64ID = new fabric_shim_1.ClientIdentity(ctx.stub).getID();
|
||||
if (b64ID == null) {
|
||||
throw new Error("failed to retrieve Client ID");
|
||||
}
|
||||
const decodeID = atob(b64ID);
|
||||
return String(decodeID);
|
||||
}
|
||||
};
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String, String, Number, Number]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferContract.prototype, "CreateAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(false),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferContract.prototype, "ReadAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String, String, Number, Number]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferContract.prototype, "UpdateAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferContract.prototype, "DeleteAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(false),
|
||||
fabric_contract_api_1.Returns('boolean'),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferContract.prototype, "AssetExists", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferContract.prototype, "TransferAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(false),
|
||||
fabric_contract_api_1.Returns('string'),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferContract.prototype, "GetAllAssets", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(false),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferContract.prototype, "GetSubmittingClientIdentity", null);
|
||||
AssetTransferContract = __decorate([
|
||||
fabric_contract_api_1.Info({ title: 'AssetTransfer', description: 'Smart contract for trading assets' })
|
||||
], AssetTransferContract);
|
||||
exports.AssetTransferContract = AssetTransferContract;
|
||||
//# sourceMappingURL=assetTransfer.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"assetTransfer.js","sourceRoot":"","sources":["../src/assetTransfer.ts"],"names":[],"mappings":"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"}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
export { AssetTransferContract } from './assetTransfer';
|
||||
export declare const contracts: any[];
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
"use strict";
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.contracts = void 0;
|
||||
const assetTransfer_1 = require("./assetTransfer");
|
||||
var assetTransfer_2 = require("./assetTransfer");
|
||||
Object.defineProperty(exports, "AssetTransferContract", { enumerable: true, get: function () { return assetTransfer_2.AssetTransferContract; } });
|
||||
exports.contracts = [assetTransfer_1.AssetTransferContract];
|
||||
//# sourceMappingURL=index.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,mDAAwD;AACxD,iDAAwD;AAA/C,sHAAA,qBAAqB,OAAA;AAEjB,QAAA,SAAS,GAAU,CAAE,qCAAqB,CAAE,CAAC"}
|
||||
|
|
@ -16,7 +16,6 @@ type SmartContract struct {
|
|||
|
||||
// Insert struct field in alphabetic order => to achieve determinism accross languages
|
||||
// golang keeps the order when marshal to json but doesn't order automatically
|
||||
// The encoding/json package marshals maps in sorted key order and structs in the order that the fields are declared.
|
||||
type Asset struct {
|
||||
AppraisedValue int `json:"AppraisedValue"`
|
||||
Color string `json:"Color"`
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
||||
|
|
|
|||
6
asset-transfer-basic/chaincode-java/.gitattributes
vendored
Normal file
6
asset-transfer-basic/chaincode-java/.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#
|
||||
# https://help.github.com/articles/dealing-with-line-endings/
|
||||
#
|
||||
# These are explicitly windows files and should use crlf
|
||||
*.bat text eol=crlf
|
||||
|
||||
Binary file not shown.
|
|
@ -1,32 +1,80 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id 'com.github.johnrengelman.shadow' version '5.2.0'
|
||||
id 'java'
|
||||
id 'com.github.johnrengelman.shadow' version '5.1.0'
|
||||
id 'application'
|
||||
id 'checkstyle'
|
||||
id 'jacoco'
|
||||
}
|
||||
|
||||
version '0.0.1'
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven {
|
||||
url 'https://jitpack.io'
|
||||
}
|
||||
}
|
||||
group 'org.hyperledger.fabric.samples'
|
||||
version '1.0-SNAPSHOT'
|
||||
|
||||
dependencies {
|
||||
implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.2.0'
|
||||
implementation 'com.owlike:genson:1.6'
|
||||
implementation 'com.google.code.gson:gson:2.8.7'
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.8.9'
|
||||
implementation 'io.vertx:vertx-core:3.5.3'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter:5.4.2'
|
||||
testImplementation 'org.assertj:assertj-core:3.11.1'
|
||||
testImplementation 'org.mockito:mockito-core:2.+'
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url "https://hyperledger.jfrog.io/hyperledger/fabric-maven"
|
||||
}
|
||||
jcenter()
|
||||
maven {
|
||||
url 'https://jitpack.io'
|
||||
}
|
||||
}
|
||||
|
||||
application {
|
||||
mainClass = 'org.hyperledger.fabric.contract.ContractRouter'
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion '8.21'
|
||||
configFile file("config/checkstyle/checkstyle.xml")
|
||||
}
|
||||
|
||||
checkstyleMain {
|
||||
source ='src/main/java'
|
||||
}
|
||||
|
||||
checkstyleTest {
|
||||
source ='src/test/java'
|
||||
}
|
||||
|
||||
jacocoTestReport {
|
||||
dependsOn test
|
||||
}
|
||||
|
||||
jacocoTestCoverageVerification {
|
||||
violationRules {
|
||||
rule {
|
||||
limit {
|
||||
minimum = 0.9
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finalizedBy jacocoTestReport
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
events "passed", "skipped", "failed"
|
||||
}
|
||||
}
|
||||
|
||||
mainClassName = 'org.hyperledger.fabric.contract.ContractRouter'
|
||||
|
||||
shadowJar {
|
||||
baseName = 'chaincode'
|
||||
version = null
|
||||
|
|
@ -37,14 +85,5 @@ shadowJar {
|
|||
}
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
events "passed", "skipped", "failed"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" << "-parameters"
|
||||
}
|
||||
check.dependsOn jacocoTestCoverageVerification
|
||||
installDist.dependsOn check
|
||||
|
|
|
|||
|
|
@ -0,0 +1,171 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
||||
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||
|
||||
<!--
|
||||
|
||||
Checkstyle configuration that matches the Eclipse formatter
|
||||
|
||||
Checkstyle is very configurable. Be sure to read the documentation at
|
||||
http://checkstyle.sourceforge.net (or in your downloaded distribution).
|
||||
|
||||
Most Checks are configurable, be sure to consult the documentation.
|
||||
|
||||
To completely disable a check, just comment it out or delete it from the file.
|
||||
|
||||
Finally, it is worth reading the documentation.
|
||||
|
||||
-->
|
||||
|
||||
<module name="Checker">
|
||||
<!--
|
||||
If you set the basedir property below, then all reported file
|
||||
names will be relative to the specified directory. See
|
||||
https://checkstyle.org/5.x/config.html#Checker
|
||||
|
||||
<property name="basedir" value="${basedir}"/>
|
||||
-->
|
||||
|
||||
<property name="fileExtensions" value="java, properties, xml"/>
|
||||
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="${config_loc}/suppressions.xml"/>
|
||||
<property name="optional" value="false"/>
|
||||
</module>
|
||||
|
||||
<!-- Excludes all 'module-info.java' files -->
|
||||
<!-- See https://checkstyle.org/config_filefilters.html -->
|
||||
<module name="BeforeExecutionExclusionFileFilter">
|
||||
<property name="fileNamePattern" value="module\-info\.java$"/>
|
||||
</module>
|
||||
|
||||
<!-- Checks that a package-info.java file exists for each package. -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_javadoc.html#JavadocPackage -->
|
||||
<!-- <module name="JavadocPackage"/> -->
|
||||
|
||||
<!-- Checks whether files end with a new line. -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_misc.html#NewlineAtEndOfFile -->
|
||||
<module name="NewlineAtEndOfFile"/>
|
||||
|
||||
<!-- Checks that property files contain the same keys. -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_misc.html#Translation -->
|
||||
<module name="Translation"/>
|
||||
|
||||
<!-- Checks for Size Violations. -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_sizes.html -->
|
||||
<module name="FileLength"/>
|
||||
|
||||
<!-- Checks for whitespace -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_whitespace.html -->
|
||||
<module name="FileTabCharacter"/>
|
||||
|
||||
<!-- Miscellaneous other checks. -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_misc.html -->
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="\s+$"/>
|
||||
<property name="minimum" value="0"/>
|
||||
<property name="maximum" value="0"/>
|
||||
<property name="message" value="Line has trailing spaces."/>
|
||||
</module>
|
||||
|
||||
<!-- Checks for Headers -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_header.html -->
|
||||
<!-- <module name="Header"> -->
|
||||
<!-- <property name="headerFile" value="${checkstyle.header.file}"/> -->
|
||||
<!-- <property name="fileExtensions" value="java"/> -->
|
||||
<!-- </module> -->
|
||||
|
||||
<module name="TreeWalker">
|
||||
|
||||
<!-- Checks for Javadoc comments. -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_javadoc.html -->
|
||||
<!-- <module name="JavadocMethod"/> -->
|
||||
<!-- <module name="JavadocType"/> -->
|
||||
<!-- <module name="JavadocVariable"/> -->
|
||||
<!-- <module name="JavadocStyle"/> -->
|
||||
<!-- <module name="MissingJavadocMethod"/> -->
|
||||
|
||||
<!-- Checks for Naming Conventions. -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_naming.html -->
|
||||
<module name="ConstantName"/>
|
||||
<module name="LocalFinalVariableName"/>
|
||||
<module name="LocalVariableName"/>
|
||||
<module name="PackageName"/>
|
||||
<module name="StaticVariableName"/>
|
||||
<module name="TypeName"/>
|
||||
|
||||
<!-- Checks for imports -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_import.html -->
|
||||
<module name="AvoidStarImport"/>
|
||||
<module name="IllegalImport"/> <!-- defaults to sun.* packages -->
|
||||
<module name="RedundantImport"/>
|
||||
<module name="UnusedImports">
|
||||
<property name="processJavadoc" value="false"/>
|
||||
</module>
|
||||
|
||||
<!-- Checks for Size Violations. -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_sizes.html -->
|
||||
<module name="MethodLength"/>
|
||||
<module name="ParameterNumber"/>
|
||||
|
||||
<!-- Checks for whitespace -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_whitespace.html -->
|
||||
<module name="EmptyForIteratorPad"/>
|
||||
<module name="GenericWhitespace"/>
|
||||
<module name="MethodParamPad"/>
|
||||
<module name="NoWhitespaceAfter"/>
|
||||
<module name="NoWhitespaceBefore"/>
|
||||
<module name="OperatorWrap"/>
|
||||
<module name="ParenPad"/>
|
||||
<module name="TypecastParenPad"/>
|
||||
<module name="WhitespaceAfter"/>
|
||||
<module name="WhitespaceAround"/>
|
||||
|
||||
<!-- Modifier Checks -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_modifiers.html -->
|
||||
<module name="ModifierOrder"/>
|
||||
<module name="RedundantModifier"/>
|
||||
|
||||
<!-- Checks for blocks. You know, those {}'s -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_blocks.html -->
|
||||
<module name="AvoidNestedBlocks"/>
|
||||
<module name="EmptyBlock"/>
|
||||
<module name="LeftCurly"/>
|
||||
<module name="NeedBraces"/>
|
||||
<module name="RightCurly"/>
|
||||
|
||||
<!-- Checks for common coding problems -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_coding.html -->
|
||||
<module name="EmptyStatement"/>
|
||||
<module name="EqualsHashCode"/>
|
||||
<module name="HiddenField">
|
||||
<property name="ignoreConstructorParameter" value="true"/>
|
||||
</module>
|
||||
<module name="IllegalInstantiation"/>
|
||||
<module name="InnerAssignment"/>
|
||||
<module name="MissingSwitchDefault"/>
|
||||
<module name="MultipleVariableDeclarations"/>
|
||||
<module name="SimplifyBooleanExpression"/>
|
||||
<module name="SimplifyBooleanReturn"/>
|
||||
|
||||
<!-- Checks for class design -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_design.html -->
|
||||
<module name="DesignForExtension"/>
|
||||
<module name="FinalClass"/>
|
||||
<module name="HideUtilityClassConstructor"/>
|
||||
<module name="InterfaceIsType"/>
|
||||
<module name="VisibilityModifier">
|
||||
<property name="allowPublicFinalFields" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- Miscellaneous other checks. -->
|
||||
<!-- See http://checkstyle.sourceforge.net/config_misc.html -->
|
||||
<module name="ArrayTypeStyle"/>
|
||||
<module name="FinalParameters"/>
|
||||
<module name="TodoComment"/>
|
||||
<module name="UpperEll"/>
|
||||
|
||||
</module>
|
||||
|
||||
</module>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!DOCTYPE suppressions PUBLIC
|
||||
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
|
||||
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
|
||||
|
||||
<suppressions>
|
||||
<suppress files="ChaincodeTest.java" checks="ParameterNumber" />
|
||||
</suppressions>
|
||||
Binary file not shown.
|
|
@ -1,5 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
|||
22
asset-transfer-basic/chaincode-java/gradlew
vendored
22
asset-transfer-basic/chaincode-java/gradlew
vendored
|
|
@ -1,5 +1,21 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
|
|
@ -28,7 +44,7 @@ APP_NAME="Gradle"
|
|||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
|
@ -109,8 +125,8 @@ if $darwin; then
|
|||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
|
|
|||
18
asset-transfer-basic/chaincode-java/gradlew.bat
vendored
18
asset-transfer-basic/chaincode-java/gradlew.bat
vendored
|
|
@ -1,3 +1,19 @@
|
|||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
|
|
@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0
|
|||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
rootProject.name = 'java'
|
||||
|
||||
rootProject.name = 'basic'
|
||||
|
|
|
|||
|
|
@ -91,4 +91,3 @@ public final class Asset {
|
|||
+ color + ", size=" + size + ", owner=" + owner + ", appraisedValue=" + appraisedValue + "]";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,12 @@ package org.hyperledger.fabric.samples.assettransfer;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.hyperledger.fabric.contract.Context;
|
||||
import org.hyperledger.fabric.contract.ContractInterface;
|
||||
|
|
@ -19,7 +25,10 @@ import org.hyperledger.fabric.shim.ChaincodeException;
|
|||
import org.hyperledger.fabric.shim.ChaincodeStub;
|
||||
import org.hyperledger.fabric.shim.ledger.KeyValue;
|
||||
import org.hyperledger.fabric.shim.ledger.QueryResultsIterator;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.owlike.genson.Genson;
|
||||
|
||||
@Contract(
|
||||
|
|
@ -38,8 +47,8 @@ import com.owlike.genson.Genson;
|
|||
@Default
|
||||
public final class AssetTransfer implements ContractInterface {
|
||||
|
||||
//Genson library is a good tool for achieving JSON determinsm as it produces consistent JSON in alphabetic oreder.
|
||||
private final Genson genson = new Genson();
|
||||
private ObjectMapper om = new ObjectMapper().configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);;
|
||||
|
||||
private enum AssetTransferErrors {
|
||||
ASSET_NOT_FOUND,
|
||||
|
|
@ -52,7 +61,7 @@ public final class AssetTransfer implements ContractInterface {
|
|||
* @param ctx the transaction context
|
||||
*/
|
||||
@Transaction(intent = Transaction.TYPE.SUBMIT)
|
||||
public void InitLedger(final Context ctx) {
|
||||
public void InitLedger(final Context ctx) throws JsonProcessingException{
|
||||
ChaincodeStub stub = ctx.getStub();
|
||||
|
||||
CreateAsset(ctx, "asset1", "blue", 5, "Tomoko", 300);
|
||||
|
|
@ -77,7 +86,7 @@ public final class AssetTransfer implements ContractInterface {
|
|||
*/
|
||||
@Transaction(intent = Transaction.TYPE.SUBMIT)
|
||||
public Asset CreateAsset(final Context ctx, final String assetID, final String color, final int size,
|
||||
final String owner, final int appraisedValue) {
|
||||
final String owner, final int appraisedValue) throws JsonProcessingException{
|
||||
ChaincodeStub stub = ctx.getStub();
|
||||
|
||||
if (AssetExists(ctx, assetID)) {
|
||||
|
|
@ -87,9 +96,10 @@ public final class AssetTransfer implements ContractInterface {
|
|||
}
|
||||
|
||||
Asset asset = new Asset(assetID, color, size, owner, appraisedValue);
|
||||
//Genson order automatically the JSON string alphabetically
|
||||
String assetJSON = genson.serialize(asset);
|
||||
stub.putStringState(assetID, assetJSON);
|
||||
|
||||
//Use a Jackson ObjectMapper to conver the Asset into string, sort it alphabetically and serialize it into a json string
|
||||
String sortedJson = om.writeValueAsString(asset);
|
||||
stub.putStringState(assetID, sortedJson);
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
|
@ -102,7 +112,7 @@ public final class AssetTransfer implements ContractInterface {
|
|||
* @return the asset found on the ledger if there was one
|
||||
*/
|
||||
@Transaction(intent = Transaction.TYPE.EVALUATE)
|
||||
public Asset ReadAsset(final Context ctx, final String assetID) {
|
||||
public Asset ReadAsset(final Context ctx, final String assetID) throws JsonProcessingException,IOException{
|
||||
ChaincodeStub stub = ctx.getStub();
|
||||
String assetJSON = stub.getStringState(assetID);
|
||||
|
||||
|
|
@ -129,7 +139,7 @@ public final class AssetTransfer implements ContractInterface {
|
|||
*/
|
||||
@Transaction(intent = Transaction.TYPE.SUBMIT)
|
||||
public Asset UpdateAsset(final Context ctx, final String assetID, final String color, final int size,
|
||||
final String owner, final int appraisedValue) {
|
||||
final String owner, final int appraisedValue) throws JsonProcessingException{
|
||||
ChaincodeStub stub = ctx.getStub();
|
||||
|
||||
if (!AssetExists(ctx, assetID)) {
|
||||
|
|
@ -139,9 +149,10 @@ public final class AssetTransfer implements ContractInterface {
|
|||
}
|
||||
|
||||
Asset newAsset = new Asset(assetID, color, size, owner, appraisedValue);
|
||||
//Genson order automatically the JSON string alphabetically
|
||||
String newAssetJSON = genson.serialize(newAsset);
|
||||
stub.putStringState(assetID, newAssetJSON);
|
||||
|
||||
//Use a Jackson ObjectMapper to conver the Asset into string, sort it alphabetically and serialize it into a json string
|
||||
String sortedJson = om.writeValueAsString(newAsset);
|
||||
stub.putStringState(assetID, sortedJson);
|
||||
|
||||
return newAsset;
|
||||
}
|
||||
|
|
@ -189,7 +200,7 @@ public final class AssetTransfer implements ContractInterface {
|
|||
* @return the updated asset
|
||||
*/
|
||||
@Transaction(intent = Transaction.TYPE.SUBMIT)
|
||||
public Asset TransferAsset(final Context ctx, final String assetID, final String newOwner) {
|
||||
public Asset TransferAsset(final Context ctx, final String assetID, final String newOwner) throws JsonProcessingException{
|
||||
ChaincodeStub stub = ctx.getStub();
|
||||
String assetJSON = stub.getStringState(assetID);
|
||||
|
||||
|
|
@ -199,12 +210,13 @@ public final class AssetTransfer implements ContractInterface {
|
|||
throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString());
|
||||
}
|
||||
|
||||
//Asset asset = gson.fromJson(assetJSON, Asset.class);
|
||||
Asset asset = genson.deserialize(assetJSON, Asset.class);
|
||||
|
||||
Asset newAsset = new Asset(asset.getAssetID(), asset.getColor(), asset.getSize(), newOwner, asset.getAppraisedValue());
|
||||
//Genson order automatically the JSON string alphabetically
|
||||
String newAssetJSON = genson.serialize(newAsset);
|
||||
stub.putStringState(assetID, newAssetJSON);
|
||||
|
||||
//Use a Jackson ObjectMapper to conver the Asset into string, sort it alphabetically and serialize it into a json string
|
||||
String sortedJson = om.writeValueAsString(newAsset);
|
||||
stub.putStringState(assetID, sortedJson);
|
||||
|
||||
return newAsset;
|
||||
}
|
||||
|
|
@ -216,7 +228,7 @@ public final class AssetTransfer implements ContractInterface {
|
|||
* @return array of assets found on the ledger
|
||||
*/
|
||||
@Transaction(intent = Transaction.TYPE.EVALUATE)
|
||||
public String GetAllAssets(final Context ctx) {
|
||||
public String GetAllAssets(final Context ctx) throws JsonProcessingException,IOException{
|
||||
ChaincodeStub stub = ctx.getStub();
|
||||
|
||||
List<Asset> queryResults = new ArrayList<Asset>();
|
||||
|
|
@ -229,12 +241,12 @@ public final class AssetTransfer implements ContractInterface {
|
|||
|
||||
for (KeyValue result: results) {
|
||||
Asset asset = genson.deserialize(result.getStringValue(), Asset.class);
|
||||
System.out.println(asset);
|
||||
queryResults.add(asset);
|
||||
System.out.println(asset.toString());
|
||||
}
|
||||
|
||||
//Set pretty printing of json
|
||||
final String response = genson.serialize(queryResults);
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
52
asset-transfer-basic/java/build.gradle
Normal file
52
asset-transfer-basic/java/build.gradle
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
plugins {
|
||||
id 'com.github.johnrengelman.shadow' version '5.2.0'
|
||||
id 'java'
|
||||
}
|
||||
|
||||
version '0.0.1'
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven {
|
||||
url 'https://jitpack.io'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.2.0'
|
||||
implementation 'com.owlike:genson:1.6'
|
||||
implementation 'com.google.code.gson:gson:2.8.7'
|
||||
implementation 'com.fasterxml.jackson.core:jackson-databind:2.8.9'
|
||||
implementation 'io.vertx:vertx-core:3.5.3'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter:5.4.2'
|
||||
testImplementation 'org.assertj:assertj-core:3.11.1'
|
||||
testImplementation 'org.mockito:mockito-core:2.+'
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
baseName = 'chaincode'
|
||||
version = null
|
||||
classifier = null
|
||||
|
||||
manifest {
|
||||
attributes 'Main-Class': 'org.hyperledger.fabric.contract.ContractRouter'
|
||||
}
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
testLogging {
|
||||
events "passed", "skipped", "failed"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" << "-parameters"
|
||||
}
|
||||
BIN
asset-transfer-basic/java/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
asset-transfer-basic/java/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
asset-transfer-basic/java/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
asset-transfer-basic/java/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
172
asset-transfer-basic/java/gradlew
vendored
Executable file
172
asset-transfer-basic/java/gradlew
vendored
Executable file
|
|
@ -0,0 +1,172 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
84
asset-transfer-basic/java/gradlew.bat
vendored
Normal file
84
asset-transfer-basic/java/gradlew.bat
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
5
asset-transfer-basic/java/settings.gradle
Normal file
5
asset-transfer-basic/java/settings.gradle
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
rootProject.name = 'java'
|
||||
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.hyperledger.fabric.samples.assettransfer;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.hyperledger.fabric.contract.annotation.DataType;
|
||||
import org.hyperledger.fabric.contract.annotation.Property;
|
||||
|
||||
import com.owlike.genson.annotation.JsonProperty;
|
||||
|
||||
@DataType()
|
||||
public final class Asset {
|
||||
|
||||
@Property()
|
||||
private final String assetID;
|
||||
|
||||
@Property()
|
||||
private final String color;
|
||||
|
||||
@Property()
|
||||
private final int size;
|
||||
|
||||
@Property()
|
||||
private final String owner;
|
||||
|
||||
@Property()
|
||||
private final int appraisedValue;
|
||||
|
||||
public String getAssetID() {
|
||||
return assetID;
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public int getAppraisedValue() {
|
||||
return appraisedValue;
|
||||
}
|
||||
|
||||
public Asset(@JsonProperty("assetID") final String assetID, @JsonProperty("color") final String color,
|
||||
@JsonProperty("size") final int size, @JsonProperty("owner") final String owner,
|
||||
@JsonProperty("appraisedValue") final int appraisedValue) {
|
||||
this.assetID = assetID;
|
||||
this.color = color;
|
||||
this.size = size;
|
||||
this.owner = owner;
|
||||
this.appraisedValue = appraisedValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((obj == null) || (getClass() != obj.getClass())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Asset other = (Asset) obj;
|
||||
|
||||
return Objects.deepEquals(
|
||||
new String[] {getAssetID(), getColor(), getOwner()},
|
||||
new String[] {other.getAssetID(), other.getColor(), other.getOwner()})
|
||||
&&
|
||||
Objects.deepEquals(
|
||||
new int[] {getSize(), getAppraisedValue()},
|
||||
new int[] {other.getSize(), other.getAppraisedValue()});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getAssetID(), getColor(), getSize(), getOwner(), getAppraisedValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.getClass().getSimpleName() + "@" + Integer.toHexString(hashCode()) + " [assetID=" + assetID + ", color="
|
||||
+ color + ", size=" + size + ", owner=" + owner + ", appraisedValue=" + appraisedValue + "]";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.hyperledger.fabric.samples.assettransfer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.hyperledger.fabric.contract.Context;
|
||||
import org.hyperledger.fabric.contract.ContractInterface;
|
||||
import org.hyperledger.fabric.contract.annotation.Contact;
|
||||
import org.hyperledger.fabric.contract.annotation.Contract;
|
||||
import org.hyperledger.fabric.contract.annotation.Default;
|
||||
import org.hyperledger.fabric.contract.annotation.Info;
|
||||
import org.hyperledger.fabric.contract.annotation.License;
|
||||
import org.hyperledger.fabric.contract.annotation.Transaction;
|
||||
import org.hyperledger.fabric.shim.ChaincodeException;
|
||||
import org.hyperledger.fabric.shim.ChaincodeStub;
|
||||
import org.hyperledger.fabric.shim.ledger.KeyValue;
|
||||
import org.hyperledger.fabric.shim.ledger.QueryResultsIterator;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.owlike.genson.Genson;
|
||||
|
||||
@Contract(
|
||||
name = "basic",
|
||||
info = @Info(
|
||||
title = "Asset Transfer",
|
||||
description = "The hyperlegendary asset transfer",
|
||||
version = "0.0.1-SNAPSHOT",
|
||||
license = @License(
|
||||
name = "Apache 2.0 License",
|
||||
url = "http://www.apache.org/licenses/LICENSE-2.0.html"),
|
||||
contact = @Contact(
|
||||
email = "a.transfer@example.com",
|
||||
name = "Adrian Transfer",
|
||||
url = "https://hyperledger.example.com")))
|
||||
@Default
|
||||
public final class AssetTransfer implements ContractInterface {
|
||||
|
||||
private final Genson genson = new Genson();
|
||||
private ObjectMapper om = new ObjectMapper().configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);;
|
||||
|
||||
private enum AssetTransferErrors {
|
||||
ASSET_NOT_FOUND,
|
||||
ASSET_ALREADY_EXISTS
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates some initial assets on the ledger.
|
||||
*
|
||||
* @param ctx the transaction context
|
||||
*/
|
||||
@Transaction(intent = Transaction.TYPE.SUBMIT)
|
||||
public void InitLedger(final Context ctx) throws JsonProcessingException{
|
||||
ChaincodeStub stub = ctx.getStub();
|
||||
|
||||
CreateAsset(ctx, "asset1", "blue", 5, "Tomoko", 300);
|
||||
CreateAsset(ctx, "asset2", "red", 5, "Brad", 400);
|
||||
CreateAsset(ctx, "asset3", "green", 10, "Jin Soo", 500);
|
||||
CreateAsset(ctx, "asset4", "yellow", 10, "Max", 600);
|
||||
CreateAsset(ctx, "asset5", "black", 15, "Adrian", 700);
|
||||
CreateAsset(ctx, "asset6", "white", 15, "Michel", 700);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new asset on the ledger.
|
||||
*
|
||||
* @param ctx the transaction context
|
||||
* @param assetID the ID of the new asset
|
||||
* @param color the color of the new asset
|
||||
* @param size the size for the new asset
|
||||
* @param owner the owner of the new asset
|
||||
* @param appraisedValue the appraisedValue of the new asset
|
||||
* @return the created asset
|
||||
*/
|
||||
@Transaction(intent = Transaction.TYPE.SUBMIT)
|
||||
public Asset CreateAsset(final Context ctx, final String assetID, final String color, final int size,
|
||||
final String owner, final int appraisedValue) throws JsonProcessingException{
|
||||
ChaincodeStub stub = ctx.getStub();
|
||||
|
||||
if (AssetExists(ctx, assetID)) {
|
||||
String errorMessage = String.format("Asset %s already exists", assetID);
|
||||
System.out.println(errorMessage);
|
||||
throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_ALREADY_EXISTS.toString());
|
||||
}
|
||||
|
||||
Asset asset = new Asset(assetID, color, size, owner, appraisedValue);
|
||||
|
||||
//Use a Jackson ObjectMapper to conver the Asset into string, sort it alphabetically and serialize it into a json string
|
||||
String sortedJson = om.writeValueAsString(asset);
|
||||
stub.putStringState(assetID, sortedJson);
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an asset with the specified ID from the ledger.
|
||||
*
|
||||
* @param ctx the transaction context
|
||||
* @param assetID the ID of the asset
|
||||
* @return the asset found on the ledger if there was one
|
||||
*/
|
||||
@Transaction(intent = Transaction.TYPE.EVALUATE)
|
||||
public Asset ReadAsset(final Context ctx, final String assetID) throws JsonProcessingException,IOException{
|
||||
ChaincodeStub stub = ctx.getStub();
|
||||
String assetJSON = stub.getStringState(assetID);
|
||||
|
||||
if (assetJSON == null || assetJSON.isEmpty()) {
|
||||
String errorMessage = String.format("Asset %s does not exist", assetID);
|
||||
System.out.println(errorMessage);
|
||||
throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString());
|
||||
}
|
||||
|
||||
Asset asset = genson.deserialize(assetJSON, Asset.class);
|
||||
return asset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the properties of an asset on the ledger.
|
||||
*
|
||||
* @param ctx the transaction context
|
||||
* @param assetID the ID of the asset being updated
|
||||
* @param color the color of the asset being updated
|
||||
* @param size the size of the asset being updated
|
||||
* @param owner the owner of the asset being updated
|
||||
* @param appraisedValue the appraisedValue of the asset being updated
|
||||
* @return the transferred asset
|
||||
*/
|
||||
@Transaction(intent = Transaction.TYPE.SUBMIT)
|
||||
public Asset UpdateAsset(final Context ctx, final String assetID, final String color, final int size,
|
||||
final String owner, final int appraisedValue) throws JsonProcessingException{
|
||||
ChaincodeStub stub = ctx.getStub();
|
||||
|
||||
if (!AssetExists(ctx, assetID)) {
|
||||
String errorMessage = String.format("Asset %s does not exist", assetID);
|
||||
System.out.println(errorMessage);
|
||||
throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString());
|
||||
}
|
||||
|
||||
Asset newAsset = new Asset(assetID, color, size, owner, appraisedValue);
|
||||
|
||||
//Use a Jackson ObjectMapper to conver the Asset into string, sort it alphabetically and serialize it into a json string
|
||||
String sortedJson = om.writeValueAsString(newAsset);
|
||||
stub.putStringState(assetID, sortedJson);
|
||||
|
||||
return newAsset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes asset on the ledger.
|
||||
*
|
||||
* @param ctx the transaction context
|
||||
* @param assetID the ID of the asset being deleted
|
||||
*/
|
||||
@Transaction(intent = Transaction.TYPE.SUBMIT)
|
||||
public void DeleteAsset(final Context ctx, final String assetID) {
|
||||
ChaincodeStub stub = ctx.getStub();
|
||||
|
||||
if (!AssetExists(ctx, assetID)) {
|
||||
String errorMessage = String.format("Asset %s does not exist", assetID);
|
||||
System.out.println(errorMessage);
|
||||
throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString());
|
||||
}
|
||||
|
||||
stub.delState(assetID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the existence of the asset on the ledger
|
||||
*
|
||||
* @param ctx the transaction context
|
||||
* @param assetID the ID of the asset
|
||||
* @return boolean indicating the existence of the asset
|
||||
*/
|
||||
@Transaction(intent = Transaction.TYPE.EVALUATE)
|
||||
public boolean AssetExists(final Context ctx, final String assetID) {
|
||||
ChaincodeStub stub = ctx.getStub();
|
||||
String assetJSON = stub.getStringState(assetID);
|
||||
|
||||
return (assetJSON != null && !assetJSON.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the owner of a asset on the ledger.
|
||||
*
|
||||
* @param ctx the transaction context
|
||||
* @param assetID the ID of the asset being transferred
|
||||
* @param newOwner the new owner
|
||||
* @return the updated asset
|
||||
*/
|
||||
@Transaction(intent = Transaction.TYPE.SUBMIT)
|
||||
public Asset TransferAsset(final Context ctx, final String assetID, final String newOwner) throws JsonProcessingException{
|
||||
ChaincodeStub stub = ctx.getStub();
|
||||
String assetJSON = stub.getStringState(assetID);
|
||||
|
||||
if (assetJSON == null || assetJSON.isEmpty()) {
|
||||
String errorMessage = String.format("Asset %s does not exist", assetID);
|
||||
System.out.println(errorMessage);
|
||||
throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString());
|
||||
}
|
||||
|
||||
//Asset asset = gson.fromJson(assetJSON, Asset.class);
|
||||
Asset asset = genson.deserialize(assetJSON, Asset.class);
|
||||
Asset newAsset = new Asset(asset.getAssetID(), asset.getColor(), asset.getSize(), newOwner, asset.getAppraisedValue());
|
||||
|
||||
//Use a Jackson ObjectMapper to conver the Asset into string, sort it alphabetically and serialize it into a json string
|
||||
String sortedJson = om.writeValueAsString(newAsset);
|
||||
stub.putStringState(assetID, sortedJson);
|
||||
|
||||
return newAsset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all assets from the ledger.
|
||||
*
|
||||
* @param ctx the transaction context
|
||||
* @return array of assets found on the ledger
|
||||
*/
|
||||
@Transaction(intent = Transaction.TYPE.EVALUATE)
|
||||
public String GetAllAssets(final Context ctx) throws JsonProcessingException,IOException{
|
||||
ChaincodeStub stub = ctx.getStub();
|
||||
|
||||
List<Asset> queryResults = new ArrayList<Asset>();
|
||||
|
||||
// To retrieve all assets from the ledger use getStateByRange with empty startKey & endKey.
|
||||
// Giving empty startKey & endKey is interpreted as all the keys from beginning to end.
|
||||
// As another example, if you use startKey = 'asset0', endKey = 'asset9' ,
|
||||
// then getStateByRange will retrieve asset with keys between asset0 (inclusive) and asset9 (exclusive) in lexical order.
|
||||
QueryResultsIterator<KeyValue> results = stub.getStateByRange("", "");
|
||||
|
||||
for (KeyValue result: results) {
|
||||
Asset asset = genson.deserialize(result.getStringValue(), Asset.class);
|
||||
System.out.println(asset);
|
||||
queryResults.add(asset);
|
||||
}
|
||||
|
||||
//Set pretty printing of json
|
||||
final String response = genson.serialize(queryResults);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
arguments=
|
||||
auto.sync=false
|
||||
build.scans.enabled=false
|
||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
||||
gradle.user.home=
|
||||
java.home=/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home
|
||||
jvm.arguments=
|
||||
offline.mode=false
|
||||
override.workspace.settings=true
|
||||
show.console.view=true
|
||||
show.executions.view=true
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,8 +0,0 @@
|
|||
import { Context, Contract } from 'fabric-contract-api';
|
||||
export declare class AssetTransferEvents extends Contract {
|
||||
CreateAsset(ctx: Context, id: string, color: string, size: number, owner: string, appraisedValue: number): Promise<void>;
|
||||
TransferAsset(ctx: any, id: any, newOwner: any): Promise<any>;
|
||||
ReadAsset(ctx: Context, id: string): Promise<String>;
|
||||
UpdateAsset(ctx: Context, id: string, color: string, size: number, owner: string, appraisedValue: number): Promise<void>;
|
||||
DeleteAsset(ctx: Context, assetId: string): Promise<void>;
|
||||
}
|
||||
|
|
@ -1,144 +0,0 @@
|
|||
"use strict";
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AssetTransferEvents = void 0;
|
||||
const fabric_contract_api_1 = require("fabric-contract-api");
|
||||
async function savePrivateData(ctx, assetKey) {
|
||||
const clientOrg = ctx.clientIdentity.getMSPID();
|
||||
const peerOrg = ctx.stub.getMspID();
|
||||
const collection = '_implicit_org_' + peerOrg;
|
||||
if (clientOrg === peerOrg) {
|
||||
const transientMap = ctx.stub.getTransient();
|
||||
if (transientMap) {
|
||||
const properties = transientMap.get('asset_properties');
|
||||
if (properties) {
|
||||
await ctx.stub.putPrivateData(collection, assetKey, properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
async function removePrivateData(ctx, assetKey) {
|
||||
const clientOrg = ctx.clientIdentity.getMSPID();
|
||||
const peerOrg = ctx.stub.getMspID();
|
||||
const collection = '_implicit_org_' + peerOrg;
|
||||
if (clientOrg === peerOrg) {
|
||||
const propertiesBuffer = await ctx.stub.getPrivateData(collection, assetKey);
|
||||
if (propertiesBuffer && propertiesBuffer.length > 0) {
|
||||
await ctx.stub.deletePrivateData(collection, assetKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
async function addPrivateData(ctx, assetKey, asset) {
|
||||
const clientOrg = ctx.clientIdentity.getMSPID();
|
||||
const peerOrg = ctx.stub.getMspID();
|
||||
const collection = '_implicit_org_' + peerOrg;
|
||||
if (clientOrg === peerOrg) {
|
||||
const propertiesBuffer = await ctx.stub.getPrivateData(collection, assetKey);
|
||||
if (propertiesBuffer && propertiesBuffer.length > 0) {
|
||||
const properties = JSON.parse(propertiesBuffer.toString());
|
||||
asset.asset_properties = properties;
|
||||
}
|
||||
}
|
||||
}
|
||||
async function readState(ctx, id) {
|
||||
const assetBuffer = await ctx.stub.getState(id); // get the asset from chaincode state
|
||||
if (!assetBuffer || assetBuffer.length === 0) {
|
||||
throw new Error(`The asset ${id} does not exist`);
|
||||
}
|
||||
const assetString = assetBuffer.toString();
|
||||
const asset = JSON.parse(assetString);
|
||||
return asset;
|
||||
}
|
||||
let AssetTransferEvents = class AssetTransferEvents extends fabric_contract_api_1.Contract {
|
||||
// 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 savePrivateData(ctx, id);
|
||||
const assetBuffer = Buffer.from(JSON.stringify(asset));
|
||||
ctx.stub.setEvent('CreateAsset', assetBuffer);
|
||||
return ctx.stub.putState(id, assetBuffer);
|
||||
}
|
||||
// TransferAsset updates the owner field of an asset with the given id in
|
||||
// the world state.
|
||||
async TransferAsset(ctx, id, newOwner) {
|
||||
const asset = await readState(ctx, id);
|
||||
asset.Owner = newOwner;
|
||||
const assetBuffer = Buffer.from(JSON.stringify(asset));
|
||||
await savePrivateData(ctx, id);
|
||||
ctx.stub.setEvent('TransferAsset', assetBuffer);
|
||||
return ctx.stub.putState(id, assetBuffer);
|
||||
}
|
||||
// ReadAsset returns the asset stored in the world state with given id.
|
||||
async ReadAsset(ctx, id) {
|
||||
const asset = await readState(ctx, id);
|
||||
await addPrivateData(ctx, asset.ID, asset);
|
||||
return JSON.stringify(asset);
|
||||
}
|
||||
// UpdateAsset updates an existing asset in the world state with provided parameters.
|
||||
async UpdateAsset(ctx, id, color, size, owner, appraisedValue) {
|
||||
const asset = await readState(ctx, id);
|
||||
asset.Color = color;
|
||||
asset.Size = size;
|
||||
asset.Owner = owner;
|
||||
asset.AppraisedValue = appraisedValue;
|
||||
const assetBuffer = Buffer.from(JSON.stringify(asset));
|
||||
await savePrivateData(ctx, id);
|
||||
ctx.stub.setEvent('UpdateAsset', assetBuffer);
|
||||
return ctx.stub.putState(id, assetBuffer);
|
||||
}
|
||||
// DeleteAsset deletes an given asset from the world state.
|
||||
async DeleteAsset(ctx, assetId) {
|
||||
const asset = await readState(ctx, assetId);
|
||||
const assetBuffer = Buffer.from(JSON.stringify(asset));
|
||||
await removePrivateData(ctx, assetId);
|
||||
ctx.stub.setEvent('DeleteAsset', assetBuffer);
|
||||
return ctx.stub.deleteState(assetId);
|
||||
}
|
||||
};
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String, String, Number, String, Number]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferEvents.prototype, "CreateAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(false),
|
||||
fabric_contract_api_1.Returns('String'),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferEvents.prototype, "ReadAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String, String, Number, String, Number]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferEvents.prototype, "UpdateAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetTransferEvents.prototype, "DeleteAsset", null);
|
||||
AssetTransferEvents = __decorate([
|
||||
fabric_contract_api_1.Info({ title: 'AssetTransferEvents', description: 'Smart Contract for trading assets and generate events' })
|
||||
], AssetTransferEvents);
|
||||
exports.AssetTransferEvents = AssetTransferEvents;
|
||||
//# sourceMappingURL=asset-contract.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"asset-contract.js","sourceRoot":"","sources":["../src/asset-contract.ts"],"names":[],"mappings":"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"}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
export declare class Asset {
|
||||
docType?: string;
|
||||
ID: string;
|
||||
Color: string;
|
||||
Size: number;
|
||||
Owner: string;
|
||||
AppraisedValue: number;
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
"use strict";
|
||||
/*
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Asset = void 0;
|
||||
const fabric_contract_api_1 = require("fabric-contract-api");
|
||||
let Asset = class Asset {
|
||||
};
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", String)
|
||||
], Asset.prototype, "docType", void 0);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", String)
|
||||
], Asset.prototype, "ID", void 0);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", String)
|
||||
], Asset.prototype, "Color", void 0);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", Number)
|
||||
], Asset.prototype, "Size", void 0);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", String)
|
||||
], Asset.prototype, "Owner", void 0);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", Number)
|
||||
], Asset.prototype, "AppraisedValue", void 0);
|
||||
Asset = __decorate([
|
||||
fabric_contract_api_1.Object()
|
||||
], Asset);
|
||||
exports.Asset = Asset;
|
||||
//# sourceMappingURL=asset.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"asset.js","sourceRoot":"","sources":["../src/asset.ts"],"names":[],"mappings":";AAAA;;EAEE;;;;;;;;;;;;AAEF,6DAAqD;AAGrD,IAAa,KAAK,GAAlB,MAAa,KAAK;CAkBjB,CAAA;AAhBG;IADC,8BAAQ,EAAE;;sCACa;AAGxB;IADC,8BAAQ,EAAE;;iCACO;AAGlB;IADC,8BAAQ,EAAE;;oCACU;AAGrB;IADC,8BAAQ,EAAE;;mCACS;AAGpB;IADC,8BAAQ,EAAE;;oCACU;AAGrB;IADC,8BAAQ,EAAE;;6CACmB;AAjBrB,KAAK;IADjB,4BAAM,EAAE;GACI,KAAK,CAkBjB;AAlBY,sBAAK"}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
export { AssetTransferEvents } from './asset-contract';
|
||||
export declare const contracts: any[];
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
"use strict";
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.contracts = void 0;
|
||||
const asset_contract_1 = require("./asset-contract");
|
||||
var asset_contract_2 = require("./asset-contract");
|
||||
Object.defineProperty(exports, "AssetTransferEvents", { enumerable: true, get: function () { return asset_contract_2.AssetTransferEvents; } });
|
||||
exports.contracts = [asset_contract_1.AssetTransferEvents];
|
||||
//# sourceMappingURL=index.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,qDAAuD;AACvD,mDAAuD;AAA9C,qHAAA,mBAAmB,OAAA;AAEf,QAAA,SAAS,GAAU,CAAE,oCAAmB,CAAE,CAAC"}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
arguments=
|
||||
auto.sync=false
|
||||
build.scans.enabled=false
|
||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
||||
gradle.user.home=
|
||||
java.home=/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home
|
||||
jvm.arguments=
|
||||
offline.mode=false
|
||||
override.workspace.settings=true
|
||||
show.console.view=true
|
||||
show.executions.view=true
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,19 +0,0 @@
|
|||
# initialize root logger with level ERROR for stdout and fout
|
||||
log4j.rootLogger=ERROR,stdout,fout
|
||||
# set the log level for these components
|
||||
log4j.logger.com.endeca=INFO
|
||||
log4j.logger.com.endeca.itl.web.metrics=INFO
|
||||
|
||||
# add a ConsoleAppender to the logger stdout to write to the console
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
# use a simple message format
|
||||
log4j.appender.stdout.layout.ConversionPattern=%m%n
|
||||
|
||||
# add a FileAppender to the logger fout
|
||||
log4j.appender.fout=org.apache.log4j.FileAppender
|
||||
# create a log file
|
||||
log4j.appender.fout.File=crawl.log
|
||||
log4j.appender.fout.layout=org.apache.log4j.PatternLayout
|
||||
# use a more detailed message pattern
|
||||
log4j.appender.fout.layout.ConversionPattern=%p\t%d{ISO8601}\t%r\t%c\t[%t]\t%m%n
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
arguments=
|
||||
auto.sync=false
|
||||
build.scans.enabled=false
|
||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
||||
gradle.user.home=
|
||||
java.home=/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home
|
||||
jvm.arguments=
|
||||
offline.mode=false
|
||||
override.workspace.settings=true
|
||||
show.console.view=true
|
||||
show.executions.view=true
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,19 +0,0 @@
|
|||
import { Context, Contract } from 'fabric-contract-api';
|
||||
import { Iterators } from 'fabric-shim-api';
|
||||
export declare class AssetContract extends Contract {
|
||||
CreateAsset(ctx: Context, assetID: string, color: string, size: number, owner: string, appraisedValue: number): Promise<void>;
|
||||
ReadAsset(ctx: Context, id: string): Promise<string>;
|
||||
DeleteAsset(ctx: Context, id: string): Promise<void>;
|
||||
TransferAsset(ctx: Context, assetName: string, newOwner: string): Promise<void>;
|
||||
GetAssetsByRange(ctx: Context, startKey: string, endKey: string): Promise<string>;
|
||||
TransferAssetByColor(ctx: Context, color: string, newOwner: string): Promise<void>;
|
||||
QueryAssetsByOwner(ctx: Context, owner: string): Promise<string>;
|
||||
QueryAssets(ctx: Context, queryString: string): Promise<string>;
|
||||
GetQueryResultForQueryString(ctx: Context, queryString: string): Promise<string>;
|
||||
GetAssetsByRangeWithPagination(ctx: Context, startKey: string, endKey: string, pageSize: number, bookmark: string): Promise<string>;
|
||||
QueryAssetsWithPagination(ctx: Context, queryString: string, pageSize: number, bookmark: string): Promise<string>;
|
||||
GetAssetHistory(ctx: Context, assetName: string): Promise<string>;
|
||||
AssetExists(ctx: Context, assetName: string): Promise<boolean>;
|
||||
GetAllResults(iterator: Iterators.CommonIterator<any>, isHistory: boolean): Promise<any[]>;
|
||||
InitLedger(ctx: Context): Promise<void>;
|
||||
}
|
||||
|
|
@ -1,452 +0,0 @@
|
|||
"use strict";
|
||||
/*
|
||||
* Copyright IBM Corp. All Rights Reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AssetContract = void 0;
|
||||
// ====CHAINCODE EXECUTION SAMPLES (CLI) ==================
|
||||
// ==== Invoke assets ====
|
||||
// peer chaincode invoke -C CHANNEL_NAME -n asset_transfer -c '{"Args":["CreateAsset","asset1","blue","35","Tom","100"]}'
|
||||
// peer chaincode invoke -C CHANNEL_NAME -n asset_transfer -c '{"Args":["CreateAsset","asset2","red","50","Tom","150"]}'
|
||||
// peer chaincode invoke -C CHANNEL_NAME -n asset_transfer -c '{"Args":["CreateAsset","asset3","blue","70","Tom","200"]}'
|
||||
// peer chaincode invoke -C CHANNEL_NAME -n asset_transfer -c '{"Args":["TransferAsset","asset2","jerry"]}'
|
||||
// peer chaincode invoke -C CHANNEL_NAME -n asset_transfer -c '{"Args":["TransferAssetsBasedOnColor","blue","jerry"]}'
|
||||
// peer chaincode invoke -C CHANNEL_NAME -n asset_transfer -c '{"Args":["DeleteAsset","asset1"]}'
|
||||
// ==== Query assets ====
|
||||
// peer chaincode query -C CHANNEL_NAME -n asset_transfer -c '{"Args":["ReadAsset","asset1"]}'
|
||||
// peer chaincode query -C CHANNEL_NAME -n asset_transfer -c '{"Args":["GetAssetsByRange","asset1","asset3"]}'
|
||||
// peer chaincode query -C CHANNEL_NAME -n asset_transfer -c '{"Args":["GetAssetHistory","asset1"]}'
|
||||
// Rich Query (Only supported if CouchDB is used as state database):
|
||||
// peer chaincode query -C CHANNEL_NAME -n asset_transfer -c '{"Args":["QueryAssetsByOwner","Tom"]}' output issue
|
||||
// peer chaincode query -C CHANNEL_NAME -n asset_transfer -c '{"Args":["QueryAssets","{\"selector\":{\"owner\":\"Tom\"}}"]}'
|
||||
// Rich Query with Pagination (Only supported if CouchDB is used as state database):
|
||||
// peer chaincode query -C CHANNEL_NAME -n asset_transfer -c '{"Args":["QueryAssetsWithPagination","{\"selector\":{\"owner\":\"Tom\"}}","3",""]}'
|
||||
// INDEXES TO SUPPORT COUCHDB RICH QUERIES
|
||||
//
|
||||
// Indexes in CouchDB are required in order to make JSON queries efficient and are required for
|
||||
// any JSON query with a sort. Indexes may be packaged alongside
|
||||
// chaincode in a META-INF/statedb/couchdb/indexes directory. Each index must be defined in its own
|
||||
// text file with extension *.json with the index definition formatted in JSON following the
|
||||
// CouchDB index JSON syntax as documented at:
|
||||
// http://docs.couchdb.org/en/2.3.1/api/database/find.html#db-index
|
||||
//
|
||||
// This asset transfer ledger example chaincode demonstrates a packaged
|
||||
// index which you can find in META-INF/statedb/couchdb/indexes/indexOwner.json.
|
||||
//
|
||||
// If you have access to the your peer's CouchDB state database in a development environment,
|
||||
// you may want to iteratively test various indexes in support of your chaincode queries. You
|
||||
// can use the CouchDB Fauxton interface or a command line curl utility to create and update
|
||||
// indexes. Then once you finalize an index, include the index definition alongside your
|
||||
// chaincode in the META-INF/statedb/couchdb/indexes directory, for packaging and deployment
|
||||
// to managed environments.
|
||||
//
|
||||
// In the examples below you can find index definitions that support asset transfer ledger
|
||||
// chaincode queries, along with the syntax that you can use in development environments
|
||||
// to create the indexes in the CouchDB Fauxton interface or a curl command line utility.
|
||||
//
|
||||
// Index for docType, owner.
|
||||
//
|
||||
// Example curl command line to define index in the CouchDB channel_chaincode database
|
||||
// curl -i -X POST -H "Content-Type: application/json" -d "{\"index\":{\"fields\":[\"docType\",\"owner\"]},\"name\":\"indexOwner\",\"ddoc\":\"indexOwnerDoc\",\"type\":\"json\"}" http://hostname:port/myc1_assets/_index
|
||||
//
|
||||
// Index for docType, owner, size (descending order).
|
||||
//
|
||||
// Example curl command line to define index in the CouchDB channel_chaincode database
|
||||
// curl -i -X POST -H "Content-Type: application/json" -d "{\"index\":{\"fields\":[{\"size\":\"desc\"},{\"docType\":\"desc\"},{\"owner\":\"desc\"}]},\"ddoc\":\"indexSizeSortDoc\", \"name\":\"indexSizeSortDesc\",\"type\":\"json\"}" http://hostname:port/myc1_assets/_index
|
||||
// Rich Query with index design doc and index name specified (Only supported if CouchDB is used as state database):
|
||||
// peer chaincode query -C CHANNEL_NAME -n asset_transfer -c '{"Args":["QueryAssets","{\"selector\":{\"docType\":\"asset\",\"owner\":\"Tom\"}, \"use_index\":[\"_design/indexOwnerDoc\", \"indexOwner\"]}"]}'
|
||||
// Rich Query with index design doc specified only (Only supported if CouchDB is used as state database):
|
||||
// peer chaincode query -C CHANNEL_NAME -n asset_transfer -c '{"Args":["QueryAssets","{\"selector\":{\"docType\":{\"$eq\":\"asset\"},\"owner\":{\"$eq\":\"Tom\"},\"size\":{\"$gt\":0}},\"fields\":[\"docType\",\"owner\",\"size\"],\"sort\":[{\"size\":\"desc\"}],\"use_index\":\"_design/indexSizeSortDoc\"}"]}'
|
||||
const fabric_contract_api_1 = require("fabric-contract-api");
|
||||
let AssetContract = class AssetContract extends fabric_contract_api_1.Contract {
|
||||
// CreateAsset - create a new asset, store into chaincode state
|
||||
async CreateAsset(ctx, assetID, color, size, owner, appraisedValue) {
|
||||
const exists = await this.AssetExists(ctx, assetID);
|
||||
if (exists) {
|
||||
throw new Error(`The asset ${assetID} already exists`);
|
||||
}
|
||||
// ==== Create asset object and marshal to JSON ====
|
||||
const asset = {
|
||||
docType: 'asset',
|
||||
ID: assetID,
|
||||
Color: color,
|
||||
Size: size,
|
||||
Owner: owner,
|
||||
AppraisedValue: appraisedValue,
|
||||
};
|
||||
// === Save asset to state ===
|
||||
await ctx.stub.putState(assetID, Buffer.from(JSON.stringify(asset)));
|
||||
let indexName = 'color~name';
|
||||
let colorNameIndexKey = await ctx.stub.createCompositeKey(indexName, [asset.Color, asset.ID]);
|
||||
// Save index entry to state. Only the key name is needed, no need to store a duplicate copy of the marble.
|
||||
// Note - passing a 'nil' value will effectively delete the key from state, therefore we pass null character as value
|
||||
await ctx.stub.putState(colorNameIndexKey, Buffer.from('\u0000'));
|
||||
}
|
||||
// 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(`Asset ${id} does not exist`);
|
||||
}
|
||||
return assetJSON.toString();
|
||||
}
|
||||
// delete - remove a asset key/value pair from state
|
||||
async DeleteAsset(ctx, id) {
|
||||
if (!id) {
|
||||
throw new Error('Asset name must not be empty');
|
||||
}
|
||||
let exists = await this.AssetExists(ctx, id);
|
||||
if (!exists) {
|
||||
throw new Error(`Asset ${id} does not exist`);
|
||||
}
|
||||
// to maintain the color~name index, we need to read the asset first and get its color
|
||||
let valAsbytes = await ctx.stub.getState(id); // get the asset from chaincode state
|
||||
let jsonResp = {};
|
||||
if (!valAsbytes) {
|
||||
jsonResp.error = `Asset does not exist: ${id}`;
|
||||
throw new Error(jsonResp);
|
||||
}
|
||||
let assetJSON;
|
||||
try {
|
||||
assetJSON = JSON.parse(valAsbytes.toString());
|
||||
}
|
||||
catch (err) {
|
||||
jsonResp = {};
|
||||
jsonResp.error = `Failed to decode JSON of: ${id}`;
|
||||
throw new Error(jsonResp);
|
||||
}
|
||||
await ctx.stub.deleteState(id); //remove the asset from chaincode state
|
||||
// delete the index
|
||||
let indexName = 'color~name';
|
||||
let colorNameIndexKey = ctx.stub.createCompositeKey(indexName, [assetJSON.color, assetJSON.assetID]);
|
||||
if (!colorNameIndexKey) {
|
||||
throw new Error(' Failed to create the createCompositeKey');
|
||||
}
|
||||
// Delete index entry to state.
|
||||
await ctx.stub.deleteState(colorNameIndexKey);
|
||||
}
|
||||
// TransferAsset transfers a asset by setting a new owner name on the asset
|
||||
async TransferAsset(ctx, assetName, newOwner) {
|
||||
let assetAsBytes = await ctx.stub.getState(assetName);
|
||||
if (!assetAsBytes || !assetAsBytes.toString()) {
|
||||
throw new Error(`Asset ${assetName} does not exist`);
|
||||
}
|
||||
let assetToTransfer = {};
|
||||
try {
|
||||
assetToTransfer = JSON.parse(assetAsBytes.toString()); //unmarshal
|
||||
}
|
||||
catch (err) {
|
||||
let jsonResp = {};
|
||||
jsonResp.error = 'Failed to decode JSON of: ' + assetName;
|
||||
throw new Error(jsonResp);
|
||||
}
|
||||
assetToTransfer.owner = newOwner; //change the owner
|
||||
let assetJSONasBytes = Buffer.from(JSON.stringify(assetToTransfer));
|
||||
await ctx.stub.putState(assetName, assetJSONasBytes); //rewrite the asset
|
||||
}
|
||||
// GetAssetsByRange performs a range query based on the start and end keys provided.
|
||||
// Read-only function results are not typically submitted to ordering. If the read-only
|
||||
// results are submitted to ordering, or if the query is used in an update transaction
|
||||
// and submitted to ordering, then the committing peers will re-execute to guarantee that
|
||||
// result sets are stable between endorsement time and commit time. The transaction is
|
||||
// invalidated by the committing peers if the result set has changed between endorsement
|
||||
// time and commit time.
|
||||
// Therefore, range queries are a safe option for performing update transactions based on query results.
|
||||
async GetAssetsByRange(ctx, startKey, endKey) {
|
||||
let resultsIterator = await ctx.stub.getStateByRange(startKey, endKey);
|
||||
let results = await this.GetAllResults(resultsIterator, false);
|
||||
return JSON.stringify(results);
|
||||
}
|
||||
// TransferAssetBasedOnColor will transfer assets of a given color to a certain new owner.
|
||||
// Uses a GetStateByPartialCompositeKey (range query) against color~name 'index'.
|
||||
// Committing peers will re-execute range queries to guarantee that result sets are stable
|
||||
// between endorsement time and commit time. The transaction is invalidated by the
|
||||
// committing peers if the result set has changed between endorsement time and commit time.
|
||||
// Therefore, range queries are a safe option for performing update transactions based on query results.
|
||||
// Example: GetStateByPartialCompositeKey/RangeQuery
|
||||
async TransferAssetByColor(ctx, color, newOwner) {
|
||||
// Query the color~name index by color
|
||||
// This will execute a key range query on all keys starting with 'color'
|
||||
let coloredAssetResultsIterator = await ctx.stub.getStateByPartialCompositeKey('color~name', [color]);
|
||||
// Iterate through result set and for each asset found, transfer to newOwner
|
||||
let responseRange = await coloredAssetResultsIterator.next();
|
||||
while (!responseRange.done) {
|
||||
if (!responseRange || !responseRange.value || !responseRange.value.key) {
|
||||
return;
|
||||
}
|
||||
let objectType;
|
||||
let attributes;
|
||||
({ objectType, attributes } = await ctx.stub.splitCompositeKey(responseRange.value.key));
|
||||
console.log(objectType);
|
||||
let returnedAssetName = attributes[1];
|
||||
// Now call the transfer function for the found asset.
|
||||
// Re-use the same function that is used to transfer individual assets
|
||||
await this.TransferAsset(ctx, returnedAssetName, newOwner);
|
||||
responseRange = await coloredAssetResultsIterator.next();
|
||||
}
|
||||
}
|
||||
// QueryAssetsByOwner queries for assets based on a passed in owner.
|
||||
// This is an example of a parameterized query where the query logic is baked into the chaincode,
|
||||
// and accepting a single query parameter (owner).
|
||||
// Only available on state databases that support rich query (e.g. CouchDB)
|
||||
// Example: Parameterized rich query
|
||||
async QueryAssetsByOwner(ctx, owner) {
|
||||
let queryString = {};
|
||||
queryString.selector = {};
|
||||
queryString.selector.docType = 'asset';
|
||||
queryString.selector.owner = owner;
|
||||
return await this.GetQueryResultForQueryString(ctx, JSON.stringify(queryString)); //shim.success(queryResults);
|
||||
}
|
||||
// Example: Ad hoc rich query
|
||||
// QueryAssets uses a query string to perform a query for assets.
|
||||
// Query string matching state database syntax is passed in and executed as is.
|
||||
// Supports ad hoc queries that can be defined at runtime by the client.
|
||||
// If this is not desired, follow the QueryAssetsForOwner example for parameterized queries.
|
||||
// Only available on state databases that support rich query (e.g. CouchDB)
|
||||
async QueryAssets(ctx, queryString) {
|
||||
return await this.GetQueryResultForQueryString(ctx, queryString);
|
||||
}
|
||||
// GetQueryResultForQueryString executes the passed in query string.
|
||||
// Result set is built and returned as a byte array containing the JSON results.
|
||||
async GetQueryResultForQueryString(ctx, queryString) {
|
||||
let resultsIterator = await ctx.stub.getQueryResult(queryString);
|
||||
let results = await this.GetAllResults(resultsIterator, false);
|
||||
return JSON.stringify(results);
|
||||
}
|
||||
// Example: Pagination with Range Query
|
||||
// GetAssetsByRangeWithPagination performs a range query based on the start & end key,
|
||||
// page size and a bookmark.
|
||||
// The number of fetched records will be equal to or lesser than the page size.
|
||||
// Paginated range queries are only valid for read only transactions.
|
||||
async GetAssetsByRangeWithPagination(ctx, startKey, endKey, pageSize, bookmark) {
|
||||
const { iterator, metadata } = await ctx.stub.getStateByRangeWithPagination(startKey, endKey, pageSize, bookmark);
|
||||
const records = await this.GetAllResults(iterator, false);
|
||||
var results = {
|
||||
Records: records,
|
||||
RecordsCount: metadata.fetchedRecordsCount,
|
||||
Bookmark: metadata.bookmark,
|
||||
};
|
||||
return JSON.stringify(results);
|
||||
}
|
||||
// Example: Pagination with Ad hoc Rich Query
|
||||
// QueryAssetsWithPagination uses a query string, page size and a bookmark to perform a query
|
||||
// for assets. Query string matching state database syntax is passed in and executed as is.
|
||||
// The number of fetched records would be equal to or lesser than the specified page size.
|
||||
// Supports ad hoc queries that can be defined at runtime by the client.
|
||||
// If this is not desired, follow the QueryAssetsForOwner example for parameterized queries.
|
||||
// Only available on state databases that support rich query (e.g. CouchDB)
|
||||
// Paginated queries are only valid for read only transactions.
|
||||
async QueryAssetsWithPagination(ctx, queryString, pageSize, bookmark) {
|
||||
const { iterator, metadata } = await ctx.stub.getQueryResultWithPagination(queryString, pageSize, bookmark);
|
||||
const records = await this.GetAllResults(iterator, false);
|
||||
var results = {
|
||||
Records: records,
|
||||
RecordsCount: metadata.fetchedRecordsCount,
|
||||
Bookmark: metadata.bookmark,
|
||||
};
|
||||
return JSON.stringify(results);
|
||||
}
|
||||
// GetAssetHistory returns the chain of custody for an asset since issuance.
|
||||
async GetAssetHistory(ctx, assetName) {
|
||||
let resultsIterator = await ctx.stub.getHistoryForKey(assetName);
|
||||
let results = await this.GetAllResults(resultsIterator, true);
|
||||
return JSON.stringify(results);
|
||||
}
|
||||
// AssetExists returns true when asset with given ID exists in world state
|
||||
async AssetExists(ctx, assetName) {
|
||||
// ==== Check if asset already exists ====
|
||||
let assetState = await ctx.stub.getState(assetName);
|
||||
return assetState && assetState.length > 0;
|
||||
}
|
||||
// This is JavaScript so without Funcation Decorators, all functions are assumed
|
||||
// to be transaction functions
|
||||
//
|
||||
// For internal functions... prefix them with _
|
||||
async GetAllResults(iterator, isHistory) {
|
||||
let allResults = [];
|
||||
let res = await iterator.next();
|
||||
while (!res.done) {
|
||||
if (res.value && res.value.value.toString()) {
|
||||
let jsonRes = {};
|
||||
console.log(res.value.value.toString('utf8'));
|
||||
if (isHistory) {
|
||||
jsonRes.TxId = res.value.txId;
|
||||
jsonRes.Timestamp = res.value.timestamp;
|
||||
try {
|
||||
jsonRes.Value = JSON.parse(res.value.value.toString('utf8'));
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
jsonRes.Value = res.value.value.toString('utf8');
|
||||
}
|
||||
}
|
||||
else {
|
||||
jsonRes.Key = res.value.key;
|
||||
try {
|
||||
jsonRes.Record = JSON.parse(res.value.value.toString('utf8'));
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
jsonRes.Record = res.value.value.toString('utf8');
|
||||
}
|
||||
}
|
||||
allResults.push(jsonRes);
|
||||
}
|
||||
res = await iterator.next();
|
||||
}
|
||||
return allResults;
|
||||
}
|
||||
// InitLedger creates sample assets in the ledger
|
||||
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 (const asset of assets) {
|
||||
asset.docType = 'asset';
|
||||
await ctx.stub.putState(asset.ID, Buffer.from(JSON.stringify(asset)));
|
||||
console.info(`Asset ${asset.ID} initialized`);
|
||||
}
|
||||
}
|
||||
};
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String, String, Number, String, Number]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetContract.prototype, "CreateAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(false),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetContract.prototype, "ReadAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetContract.prototype, "DeleteAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetContract.prototype, "TransferAsset", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetContract.prototype, "GetAssetsByRange", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetContract.prototype, "TransferAssetByColor", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(false),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetContract.prototype, "QueryAssetsByOwner", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(false),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetContract.prototype, "QueryAssets", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(false),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetContract.prototype, "GetQueryResultForQueryString", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(false),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String, String, Number, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetContract.prototype, "GetAssetsByRangeWithPagination", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(false),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String, Number, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetContract.prototype, "QueryAssetsWithPagination", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetContract.prototype, "GetAssetHistory", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(false),
|
||||
fabric_contract_api_1.Returns('boolean'),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context, String]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetContract.prototype, "AssetExists", null);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Transaction(),
|
||||
__metadata("design:type", Function),
|
||||
__metadata("design:paramtypes", [fabric_contract_api_1.Context]),
|
||||
__metadata("design:returntype", Promise)
|
||||
], AssetContract.prototype, "InitLedger", null);
|
||||
AssetContract = __decorate([
|
||||
fabric_contract_api_1.Info({ title: 'AssetContract', description: 'My Smart Contract' })
|
||||
], AssetContract);
|
||||
exports.AssetContract = AssetContract;
|
||||
//# sourceMappingURL=asset-contract.js.map
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,8 +0,0 @@
|
|||
export declare class Asset {
|
||||
docType?: string;
|
||||
ID: string;
|
||||
Color: string;
|
||||
Size: number;
|
||||
Owner: string;
|
||||
AppraisedValue: number;
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
"use strict";
|
||||
/*
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __metadata = (this && this.__metadata) || function (k, v) {
|
||||
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Asset = void 0;
|
||||
const fabric_contract_api_1 = require("fabric-contract-api");
|
||||
let Asset = class Asset {
|
||||
};
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", String)
|
||||
], Asset.prototype, "docType", void 0);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", String)
|
||||
], Asset.prototype, "ID", void 0);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", String)
|
||||
], Asset.prototype, "Color", void 0);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", Number)
|
||||
], Asset.prototype, "Size", void 0);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", String)
|
||||
], Asset.prototype, "Owner", void 0);
|
||||
__decorate([
|
||||
fabric_contract_api_1.Property(),
|
||||
__metadata("design:type", Number)
|
||||
], Asset.prototype, "AppraisedValue", void 0);
|
||||
Asset = __decorate([
|
||||
fabric_contract_api_1.Object()
|
||||
], Asset);
|
||||
exports.Asset = Asset;
|
||||
//# sourceMappingURL=asset.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"asset.js","sourceRoot":"","sources":["../src/asset.ts"],"names":[],"mappings":";AAAA;;EAEE;;;;;;;;;;;;AAEF,6DAAqD;AAGrD,IAAa,KAAK,GAAlB,MAAa,KAAK;CAkBjB,CAAA;AAhBG;IADC,8BAAQ,EAAE;;sCACa;AAGxB;IADC,8BAAQ,EAAE;;iCACO;AAGlB;IADC,8BAAQ,EAAE;;oCACU;AAGrB;IADC,8BAAQ,EAAE;;mCACS;AAGpB;IADC,8BAAQ,EAAE;;oCACU;AAGrB;IADC,8BAAQ,EAAE;;6CACmB;AAjBrB,KAAK;IADjB,4BAAM,EAAE;GACI,KAAK,CAkBjB;AAlBY,sBAAK"}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
export { AssetContract } from './asset-contract';
|
||||
export declare const contracts: any[];
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
"use strict";
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.contracts = void 0;
|
||||
const asset_contract_1 = require("./asset-contract");
|
||||
var asset_contract_2 = require("./asset-contract");
|
||||
Object.defineProperty(exports, "AssetContract", { enumerable: true, get: function () { return asset_contract_2.AssetContract; } });
|
||||
exports.contracts = [asset_contract_1.AssetContract];
|
||||
//# sourceMappingURL=index.js.map
|
||||
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,qDAAiD;AACjD,mDAAiD;AAAxC,+GAAA,aAAa,OAAA;AAET,QAAA,SAAS,GAAU,CAAE,8BAAa,CAAE,CAAC"}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="bin/main" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="main"/>
|
||||
<attribute name="gradle_used_by_scope" value="main,test"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="bin/test" path="src/test/resources">
|
||||
<attributes>
|
||||
<attribute name="gradle_scope" value="test"/>
|
||||
<attribute name="gradle_used_by_scope" value="test"/>
|
||||
<attribute name="test" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin/default"/>
|
||||
</classpath>
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
arguments=
|
||||
auto.sync=false
|
||||
build.scans.enabled=false
|
||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
||||
gradle.user.home=
|
||||
java.home=/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home
|
||||
jvm.arguments=
|
||||
offline.mode=false
|
||||
override.workspace.settings=true
|
||||
show.console.view=true
|
||||
show.executions.view=true
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
mock-maker-inline
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,16 +0,0 @@
|
|||
#
|
||||
# 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
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
coverage
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* 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],
|
||||
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']
|
||||
}
|
||||
};
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
#
|
||||
# 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
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
# don't package the connection details
|
||||
local_fabric
|
||||
|
||||
# don't package the tests
|
||||
test
|
||||
functionalTests
|
||||
|
||||
# don't package config files
|
||||
.vscode
|
||||
.editorconfig
|
||||
.eslintignore
|
||||
.eslintrc.js
|
||||
.gitignore
|
||||
.npmignore
|
||||
.nyc_output
|
||||
coverage
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue