diff --git a/asset-transfer-abac/chaincode-java/.classpath b/asset-transfer-abac/chaincode-java/.classpath
new file mode 100644
index 00000000..7a7f31fe
--- /dev/null
+++ b/asset-transfer-abac/chaincode-java/.classpath
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/asset-transfer-abac/chaincode-java/.settings/org.eclipse.buildship.core.prefs b/asset-transfer-abac/chaincode-java/.settings/org.eclipse.buildship.core.prefs
new file mode 100644
index 00000000..98515123
--- /dev/null
+++ b/asset-transfer-abac/chaincode-java/.settings/org.eclipse.buildship.core.prefs
@@ -0,0 +1,13 @@
+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
diff --git a/asset-transfer-abac/chaincode-java/.settings/org.eclipse.jdt.core.prefs b/asset-transfer-abac/chaincode-java/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..35068d95
--- /dev/null
+++ b/asset-transfer-abac/chaincode-java/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,4 @@
+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
diff --git a/asset-transfer-abac/chaincode-java/bin/main/org/example/Asset.class b/asset-transfer-abac/chaincode-java/bin/main/org/example/Asset.class
new file mode 100644
index 00000000..38f6ef82
Binary files /dev/null and b/asset-transfer-abac/chaincode-java/bin/main/org/example/Asset.class differ
diff --git a/asset-transfer-abac/chaincode-java/bin/main/org/example/AssetTransfer$AssetTransferErrors.class b/asset-transfer-abac/chaincode-java/bin/main/org/example/AssetTransfer$AssetTransferErrors.class
new file mode 100644
index 00000000..0bad4926
Binary files /dev/null and b/asset-transfer-abac/chaincode-java/bin/main/org/example/AssetTransfer$AssetTransferErrors.class differ
diff --git a/asset-transfer-abac/chaincode-java/bin/main/org/example/AssetTransfer.class b/asset-transfer-abac/chaincode-java/bin/main/org/example/AssetTransfer.class
new file mode 100644
index 00000000..1b2142ff
Binary files /dev/null and b/asset-transfer-abac/chaincode-java/bin/main/org/example/AssetTransfer.class differ
diff --git a/asset-transfer-abac/chaincode-typescript/dist/asset-contract.d.ts b/asset-transfer-abac/chaincode-typescript/dist/asset-contract.d.ts
new file mode 100644
index 00000000..0476f4e5
--- /dev/null
+++ b/asset-transfer-abac/chaincode-typescript/dist/asset-contract.d.ts
@@ -0,0 +1,11 @@
+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;
+ ReadAsset(ctx: Context, id: string): Promise;
+ UpdateAsset(ctx: Context, id: string, color: string, size: number, appraisedValue: number): Promise;
+ DeleteAsset(ctx: Context, id: string): Promise;
+ AssetExists(ctx: Context, id: string): Promise;
+ TransferAsset(ctx: Context, id: string, newOwner: string): Promise;
+ GetAllAssets(ctx: Context): Promise;
+ GetSubmittingClientIdentity(ctx: Context): Promise;
+}
diff --git a/asset-transfer-abac/chaincode-typescript/dist/asset-contract.js b/asset-transfer-abac/chaincode-typescript/dist/asset-contract.js
new file mode 100644
index 00000000..798e1431
--- /dev/null
+++ b/asset-transfer-abac/chaincode-typescript/dist/asset-contract.js
@@ -0,0 +1,186 @@
+"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
\ No newline at end of file
diff --git a/asset-transfer-abac/chaincode-typescript/dist/asset-contract.js.map b/asset-transfer-abac/chaincode-typescript/dist/asset-contract.js.map
new file mode 100644
index 00000000..f2439eec
--- /dev/null
+++ b/asset-transfer-abac/chaincode-typescript/dist/asset-contract.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"asset-contract.js","sourceRoot":"","sources":["../src/asset-contract.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/asset-transfer-abac/chaincode-typescript/dist/asset.d.ts b/asset-transfer-abac/chaincode-typescript/dist/asset.d.ts
new file mode 100644
index 00000000..76258663
--- /dev/null
+++ b/asset-transfer-abac/chaincode-typescript/dist/asset.d.ts
@@ -0,0 +1,8 @@
+export declare class Asset {
+ docType?: string;
+ ID: string;
+ Color: string;
+ Size: number;
+ Owner: string;
+ AppraisedValue: number;
+}
diff --git a/asset-transfer-abac/chaincode-typescript/dist/asset.js b/asset-transfer-abac/chaincode-typescript/dist/asset.js
new file mode 100644
index 00000000..959731c8
--- /dev/null
+++ b/asset-transfer-abac/chaincode-typescript/dist/asset.js
@@ -0,0 +1,47 @@
+"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
\ No newline at end of file
diff --git a/asset-transfer-abac/chaincode-typescript/dist/asset.js.map b/asset-transfer-abac/chaincode-typescript/dist/asset.js.map
new file mode 100644
index 00000000..4ea75c0b
--- /dev/null
+++ b/asset-transfer-abac/chaincode-typescript/dist/asset.js.map
@@ -0,0 +1 @@
+{"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"}
\ No newline at end of file
diff --git a/asset-transfer-abac/chaincode-typescript/dist/assetTransfer.d.ts b/asset-transfer-abac/chaincode-typescript/dist/assetTransfer.d.ts
new file mode 100644
index 00000000..0476f4e5
--- /dev/null
+++ b/asset-transfer-abac/chaincode-typescript/dist/assetTransfer.d.ts
@@ -0,0 +1,11 @@
+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;
+ ReadAsset(ctx: Context, id: string): Promise;
+ UpdateAsset(ctx: Context, id: string, color: string, size: number, appraisedValue: number): Promise;
+ DeleteAsset(ctx: Context, id: string): Promise;
+ AssetExists(ctx: Context, id: string): Promise;
+ TransferAsset(ctx: Context, id: string, newOwner: string): Promise;
+ GetAllAssets(ctx: Context): Promise;
+ GetSubmittingClientIdentity(ctx: Context): Promise;
+}
diff --git a/asset-transfer-abac/chaincode-typescript/dist/assetTransfer.js b/asset-transfer-abac/chaincode-typescript/dist/assetTransfer.js
new file mode 100644
index 00000000..ac1b3891
--- /dev/null
+++ b/asset-transfer-abac/chaincode-typescript/dist/assetTransfer.js
@@ -0,0 +1,186 @@
+"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
\ No newline at end of file
diff --git a/asset-transfer-abac/chaincode-typescript/dist/assetTransfer.js.map b/asset-transfer-abac/chaincode-typescript/dist/assetTransfer.js.map
new file mode 100644
index 00000000..4b44feb5
--- /dev/null
+++ b/asset-transfer-abac/chaincode-typescript/dist/assetTransfer.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"assetTransfer.js","sourceRoot":"","sources":["../src/assetTransfer.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/asset-transfer-abac/chaincode-typescript/dist/index.d.ts b/asset-transfer-abac/chaincode-typescript/dist/index.d.ts
new file mode 100644
index 00000000..277788eb
--- /dev/null
+++ b/asset-transfer-abac/chaincode-typescript/dist/index.d.ts
@@ -0,0 +1,2 @@
+export { AssetTransferContract } from './assetTransfer';
+export declare const contracts: any[];
diff --git a/asset-transfer-abac/chaincode-typescript/dist/index.js b/asset-transfer-abac/chaincode-typescript/dist/index.js
new file mode 100644
index 00000000..6d2f6aab
--- /dev/null
+++ b/asset-transfer-abac/chaincode-typescript/dist/index.js
@@ -0,0 +1,11 @@
+"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
\ No newline at end of file
diff --git a/asset-transfer-abac/chaincode-typescript/dist/index.js.map b/asset-transfer-abac/chaincode-typescript/dist/index.js.map
new file mode 100644
index 00000000..611c4a00
--- /dev/null
+++ b/asset-transfer-abac/chaincode-typescript/dist/index.js.map
@@ -0,0 +1 @@
+{"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"}
\ No newline at end of file
diff --git a/asset-transfer-basic/chaincode-go/chaincode/smartcontract.go b/asset-transfer-basic/chaincode-go/chaincode/smartcontract.go
index ced42c4c..8b3f725f 100644
--- a/asset-transfer-basic/chaincode-go/chaincode/smartcontract.go
+++ b/asset-transfer-basic/chaincode-go/chaincode/smartcontract.go
@@ -16,6 +16,7 @@ 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"`
@@ -59,7 +60,7 @@ func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface,
if exists {
return fmt.Errorf("the asset %s already exists", id)
}
-
+
asset := Asset{
ID: id,
Color: color,
@@ -185,4 +186,4 @@ func (s *SmartContract) GetAllAssets(ctx contractapi.TransactionContextInterface
}
return assets, nil
-}
\ No newline at end of file
+}
diff --git a/asset-transfer-basic/chaincode-java/.classpath b/asset-transfer-basic/chaincode-java/.classpath
index 9f9cc9f1..7a7f31fe 100644
--- a/asset-transfer-basic/chaincode-java/.classpath
+++ b/asset-transfer-basic/chaincode-java/.classpath
@@ -13,7 +13,7 @@
-
+
diff --git a/asset-transfer-basic/java/.fabricignore b/asset-transfer-basic/chaincode-java/.fabricignore
similarity index 100%
rename from asset-transfer-basic/java/.fabricignore
rename to asset-transfer-basic/chaincode-java/.fabricignore
diff --git a/asset-transfer-basic/chaincode-java/.gitattributes b/asset-transfer-basic/chaincode-java/.gitattributes
deleted file mode 100644
index 00a51aff..00000000
--- a/asset-transfer-basic/chaincode-java/.gitattributes
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# https://help.github.com/articles/dealing-with-line-endings/
-#
-# These are explicitly windows files and should use crlf
-*.bat text eol=crlf
-
diff --git a/asset-transfer-basic/java/.gitignore b/asset-transfer-basic/chaincode-java/.gitignore
similarity index 100%
rename from asset-transfer-basic/java/.gitignore
rename to asset-transfer-basic/chaincode-java/.gitignore
diff --git a/asset-transfer-basic/chaincode-java/bin/main/org/hyperledger/fabric/samples/assettransfer/AssetTransfer.class b/asset-transfer-basic/chaincode-java/bin/main/org/hyperledger/fabric/samples/assettransfer/AssetTransfer.class
index 58279bfc..670bc356 100644
Binary files a/asset-transfer-basic/chaincode-java/bin/main/org/hyperledger/fabric/samples/assettransfer/AssetTransfer.class and b/asset-transfer-basic/chaincode-java/bin/main/org/hyperledger/fabric/samples/assettransfer/AssetTransfer.class differ
diff --git a/asset-transfer-basic/chaincode-java/build.gradle b/asset-transfer-basic/chaincode-java/build.gradle
index 73c92a5c..aebae462 100644
--- a/asset-transfer-basic/chaincode-java/build.gradle
+++ b/asset-transfer-basic/chaincode-java/build.gradle
@@ -1,80 +1,32 @@
/*
* SPDX-License-Identifier: Apache-2.0
*/
-
plugins {
- id 'com.github.johnrengelman.shadow' version '5.1.0'
- id 'application'
- id 'checkstyle'
- id 'jacoco'
+ id 'com.github.johnrengelman.shadow' version '5.2.0'
+ id 'java'
}
-group 'org.hyperledger.fabric.samples'
-version '1.0-SNAPSHOT'
+version '0.0.1'
-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.+'
-}
+sourceCompatibility = 1.8
repositories {
- maven {
- url "https://hyperledger.jfrog.io/hyperledger/fabric-maven"
- }
- jcenter()
+ mavenLocal()
+ mavenCentral()
maven {
url 'https://jitpack.io'
}
}
-application {
- mainClass = 'org.hyperledger.fabric.contract.ContractRouter'
+dependencies {
+ implementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.2.0'
+ implementation 'com.owlike:genson:1.6'
+ 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.+'
}
-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
@@ -85,5 +37,14 @@ shadowJar {
}
}
-check.dependsOn jacocoTestCoverageVerification
-installDist.dependsOn check
+test {
+ useJUnitPlatform()
+ testLogging {
+ events "passed", "skipped", "failed"
+ }
+}
+
+
+tasks.withType(JavaCompile) {
+ options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" << "-parameters"
+}
diff --git a/asset-transfer-basic/chaincode-java/config/checkstyle/checkstyle.xml b/asset-transfer-basic/chaincode-java/config/checkstyle/checkstyle.xml
deleted file mode 100644
index acd5df44..00000000
--- a/asset-transfer-basic/chaincode-java/config/checkstyle/checkstyle.xml
+++ /dev/null
@@ -1,171 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/asset-transfer-basic/chaincode-java/config/checkstyle/suppressions.xml b/asset-transfer-basic/chaincode-java/config/checkstyle/suppressions.xml
deleted file mode 100644
index 8c44b0a0..00000000
--- a/asset-transfer-basic/chaincode-java/config/checkstyle/suppressions.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
diff --git a/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.jar b/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.jar
index 5c2d1cf0..f6b961fd 100644
Binary files a/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.jar and b/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.properties b/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.properties
index bb8b2fc2..7c4388a9 100644
--- a/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.properties
+++ b/asset-transfer-basic/chaincode-java/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/asset-transfer-basic/chaincode-java/gradlew b/asset-transfer-basic/chaincode-java/gradlew
index 83f2acfd..cccdd3d5 100755
--- a/asset-transfer-basic/chaincode-java/gradlew
+++ b/asset-transfer-basic/chaincode-java/gradlew
@@ -1,21 +1,5 @@
#!/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
@@ -44,7 +28,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='"-Xmx64m" "-Xms64m"'
+DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@@ -125,8 +109,8 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+# 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"`
diff --git a/asset-transfer-basic/chaincode-java/gradlew.bat b/asset-transfer-basic/chaincode-java/gradlew.bat
index 9618d8d9..f9553162 100644
--- a/asset-transfer-basic/chaincode-java/gradlew.bat
+++ b/asset-transfer-basic/chaincode-java/gradlew.bat
@@ -1,19 +1,3 @@
-@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
@@ -30,7 +14,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="-Xmx64m" "-Xms64m"
+set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
diff --git a/asset-transfer-basic/chaincode-java/settings.gradle b/asset-transfer-basic/chaincode-java/settings.gradle
index 2633c4b9..2182e899 100644
--- a/asset-transfer-basic/chaincode-java/settings.gradle
+++ b/asset-transfer-basic/chaincode-java/settings.gradle
@@ -1,5 +1,5 @@
/*
* SPDX-License-Identifier: Apache-2.0
*/
+rootProject.name = 'java'
-rootProject.name = 'basic'
diff --git a/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/Asset.java b/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/Asset.java
index 803f22fb..fb850f61 100644
--- a/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/Asset.java
+++ b/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/Asset.java
@@ -91,3 +91,4 @@ public final class Asset {
+ color + ", size=" + size + ", owner=" + owner + ", appraisedValue=" + appraisedValue + "]";
}
}
+
diff --git a/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/AssetTransfer.java b/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/AssetTransfer.java
index 798cfde5..d115e993 100644
--- a/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/AssetTransfer.java
+++ b/asset-transfer-basic/chaincode-java/src/main/java/org/hyperledger/fabric/samples/assettransfer/AssetTransfer.java
@@ -6,12 +6,6 @@ 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;
@@ -24,11 +18,8 @@ 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 org.hyperledger.fabric.shim.ledger.QueryResultsIterator;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.owlike.genson.Genson;
@Contract(
@@ -47,8 +38,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,
@@ -61,7 +52,7 @@ public final class AssetTransfer implements ContractInterface {
* @param ctx the transaction context
*/
@Transaction(intent = Transaction.TYPE.SUBMIT)
- public void InitLedger(final Context ctx) throws JsonProcessingException{
+ public void InitLedger(final Context ctx) {
ChaincodeStub stub = ctx.getStub();
CreateAsset(ctx, "asset1", "blue", 5, "Tomoko", 300);
@@ -86,7 +77,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) throws JsonProcessingException{
+ final String owner, final int appraisedValue) {
ChaincodeStub stub = ctx.getStub();
if (AssetExists(ctx, assetID)) {
@@ -96,10 +87,9 @@ public final class AssetTransfer implements ContractInterface {
}
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);
+ //Genson order automatically the JSON string alphabetically
+ String assetJSON = genson.serialize(asset);
+ stub.putStringState(assetID, assetJSON);
return asset;
}
@@ -112,7 +102,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) throws JsonProcessingException,IOException{
+ public Asset ReadAsset(final Context ctx, final String assetID) {
ChaincodeStub stub = ctx.getStub();
String assetJSON = stub.getStringState(assetID);
@@ -121,7 +111,7 @@ public final class AssetTransfer implements ContractInterface {
System.out.println(errorMessage);
throw new ChaincodeException(errorMessage, AssetTransferErrors.ASSET_NOT_FOUND.toString());
}
-
+
Asset asset = genson.deserialize(assetJSON, Asset.class);
return asset;
}
@@ -139,7 +129,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) throws JsonProcessingException{
+ final String owner, final int appraisedValue) {
ChaincodeStub stub = ctx.getStub();
if (!AssetExists(ctx, assetID)) {
@@ -149,10 +139,9 @@ public final class AssetTransfer implements ContractInterface {
}
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);
+ //Genson order automatically the JSON string alphabetically
+ String newAssetJSON = genson.serialize(newAsset);
+ stub.putStringState(assetID, newAssetJSON);
return newAsset;
}
@@ -200,7 +189,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) throws JsonProcessingException{
+ public Asset TransferAsset(final Context ctx, final String assetID, final String newOwner) {
ChaincodeStub stub = ctx.getStub();
String assetJSON = stub.getStringState(assetID);
@@ -210,13 +199,12 @@ 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());
- //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);
+ 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);
return newAsset;
}
@@ -228,7 +216,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) throws JsonProcessingException,IOException{
+ public String GetAllAssets(final Context ctx) {
ChaincodeStub stub = ctx.getStub();
List queryResults = new ArrayList();
@@ -241,12 +229,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;
}
}
\ No newline at end of file
diff --git a/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTest.java b/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTest.java
index 7da94caa..7bcaa8ae 100644
--- a/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTest.java
+++ b/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTest.java
@@ -71,4 +71,4 @@ public final class AssetTest {
assertThat(asset.toString()).isEqualTo("Asset@e04f6c53 [assetID=asset1, color=Blue, size=20, owner=Guy, appraisedValue=100]");
}
-}
+}
\ No newline at end of file
diff --git a/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTransferTest.java b/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTransferTest.java
index cbbb172f..7fecfff3 100644
--- a/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTransferTest.java
+++ b/asset-transfer-basic/chaincode-java/src/test/java/org/hyperledger/fabric/samples/assettransfer/AssetTransferTest.java
@@ -302,4 +302,4 @@ public final class AssetTransferTest {
assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo("ASSET_NOT_FOUND".getBytes());
}
}
-}
+}
\ No newline at end of file
diff --git a/asset-transfer-basic/java/transaction_data/my-asset-transactions.txdata b/asset-transfer-basic/chaincode-java/transaction_data/my-asset-transactions.txdata
similarity index 100%
rename from asset-transfer-basic/java/transaction_data/my-asset-transactions.txdata
rename to asset-transfer-basic/chaincode-java/transaction_data/my-asset-transactions.txdata
diff --git a/asset-transfer-basic/java/build.gradle b/asset-transfer-basic/java/build.gradle
deleted file mode 100644
index a02eb79a..00000000
--- a/asset-transfer-basic/java/build.gradle
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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"
-}
diff --git a/asset-transfer-basic/java/gradle/wrapper/gradle-wrapper.jar b/asset-transfer-basic/java/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index f6b961fd..00000000
Binary files a/asset-transfer-basic/java/gradle/wrapper/gradle-wrapper.jar and /dev/null differ
diff --git a/asset-transfer-basic/java/gradle/wrapper/gradle-wrapper.properties b/asset-transfer-basic/java/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index 7c4388a9..00000000
--- a/asset-transfer-basic/java/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-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
diff --git a/asset-transfer-basic/java/gradlew b/asset-transfer-basic/java/gradlew
deleted file mode 100755
index cccdd3d5..00000000
--- a/asset-transfer-basic/java/gradlew
+++ /dev/null
@@ -1,172 +0,0 @@
-#!/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" "$@"
diff --git a/asset-transfer-basic/java/gradlew.bat b/asset-transfer-basic/java/gradlew.bat
deleted file mode 100644
index e95643d6..00000000
--- a/asset-transfer-basic/java/gradlew.bat
+++ /dev/null
@@ -1,84 +0,0 @@
-@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
diff --git a/asset-transfer-basic/java/settings.gradle b/asset-transfer-basic/java/settings.gradle
deleted file mode 100644
index 2182e899..00000000
--- a/asset-transfer-basic/java/settings.gradle
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- */
-rootProject.name = 'java'
-
diff --git a/asset-transfer-basic/java/src/main/java/org/example/Asset.java b/asset-transfer-basic/java/src/main/java/org/example/Asset.java
deleted file mode 100644
index fb850f61..00000000
--- a/asset-transfer-basic/java/src/main/java/org/example/Asset.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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 + "]";
- }
-}
-
diff --git a/asset-transfer-basic/java/src/main/java/org/example/AssetTransfer.java b/asset-transfer-basic/java/src/main/java/org/example/AssetTransfer.java
deleted file mode 100644
index 798cfde5..00000000
--- a/asset-transfer-basic/java/src/main/java/org/example/AssetTransfer.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * 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 queryResults = new ArrayList();
-
- // 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 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;
- }
-}
\ No newline at end of file
diff --git a/asset-transfer-events/chaincode-java/.classpath b/asset-transfer-events/chaincode-java/.classpath
new file mode 100644
index 00000000..e16509f7
--- /dev/null
+++ b/asset-transfer-events/chaincode-java/.classpath
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/asset-transfer-events/chaincode-java/.settings/org.eclipse.buildship.core.prefs b/asset-transfer-events/chaincode-java/.settings/org.eclipse.buildship.core.prefs
new file mode 100644
index 00000000..98515123
--- /dev/null
+++ b/asset-transfer-events/chaincode-java/.settings/org.eclipse.buildship.core.prefs
@@ -0,0 +1,13 @@
+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
diff --git a/asset-transfer-events/chaincode-java/bin/main/org/hyperledger/fabric/samples/events/Asset.class b/asset-transfer-events/chaincode-java/bin/main/org/hyperledger/fabric/samples/events/Asset.class
new file mode 100644
index 00000000..ef76e16b
Binary files /dev/null and b/asset-transfer-events/chaincode-java/bin/main/org/hyperledger/fabric/samples/events/Asset.class differ
diff --git a/asset-transfer-events/chaincode-java/bin/main/org/hyperledger/fabric/samples/events/AssetTransfer$AssetTransferErrors.class b/asset-transfer-events/chaincode-java/bin/main/org/hyperledger/fabric/samples/events/AssetTransfer$AssetTransferErrors.class
new file mode 100644
index 00000000..f2f4f159
Binary files /dev/null and b/asset-transfer-events/chaincode-java/bin/main/org/hyperledger/fabric/samples/events/AssetTransfer$AssetTransferErrors.class differ
diff --git a/asset-transfer-events/chaincode-java/bin/main/org/hyperledger/fabric/samples/events/AssetTransfer.class b/asset-transfer-events/chaincode-java/bin/main/org/hyperledger/fabric/samples/events/AssetTransfer.class
new file mode 100644
index 00000000..ffa4fa4b
Binary files /dev/null and b/asset-transfer-events/chaincode-java/bin/main/org/hyperledger/fabric/samples/events/AssetTransfer.class differ
diff --git a/asset-transfer-events/chaincode-typescript/dist/asset-contract.d.ts b/asset-transfer-events/chaincode-typescript/dist/asset-contract.d.ts
new file mode 100644
index 00000000..a93041eb
--- /dev/null
+++ b/asset-transfer-events/chaincode-typescript/dist/asset-contract.d.ts
@@ -0,0 +1,8 @@
+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;
+ TransferAsset(ctx: any, id: any, newOwner: any): Promise;
+ ReadAsset(ctx: Context, id: string): Promise;
+ UpdateAsset(ctx: Context, id: string, color: string, size: number, owner: string, appraisedValue: number): Promise;
+ DeleteAsset(ctx: Context, assetId: string): Promise;
+}
diff --git a/asset-transfer-events/chaincode-typescript/dist/asset-contract.js b/asset-transfer-events/chaincode-typescript/dist/asset-contract.js
new file mode 100644
index 00000000..a3a901c0
--- /dev/null
+++ b/asset-transfer-events/chaincode-typescript/dist/asset-contract.js
@@ -0,0 +1,144 @@
+"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
\ No newline at end of file
diff --git a/asset-transfer-events/chaincode-typescript/dist/asset-contract.js.map b/asset-transfer-events/chaincode-typescript/dist/asset-contract.js.map
new file mode 100644
index 00000000..2bde6b52
--- /dev/null
+++ b/asset-transfer-events/chaincode-typescript/dist/asset-contract.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"asset-contract.js","sourceRoot":"","sources":["../src/asset-contract.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/asset-transfer-events/chaincode-typescript/dist/asset.d.ts b/asset-transfer-events/chaincode-typescript/dist/asset.d.ts
new file mode 100644
index 00000000..76258663
--- /dev/null
+++ b/asset-transfer-events/chaincode-typescript/dist/asset.d.ts
@@ -0,0 +1,8 @@
+export declare class Asset {
+ docType?: string;
+ ID: string;
+ Color: string;
+ Size: number;
+ Owner: string;
+ AppraisedValue: number;
+}
diff --git a/asset-transfer-events/chaincode-typescript/dist/asset.js b/asset-transfer-events/chaincode-typescript/dist/asset.js
new file mode 100644
index 00000000..959731c8
--- /dev/null
+++ b/asset-transfer-events/chaincode-typescript/dist/asset.js
@@ -0,0 +1,47 @@
+"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
\ No newline at end of file
diff --git a/asset-transfer-events/chaincode-typescript/dist/asset.js.map b/asset-transfer-events/chaincode-typescript/dist/asset.js.map
new file mode 100644
index 00000000..4ea75c0b
--- /dev/null
+++ b/asset-transfer-events/chaincode-typescript/dist/asset.js.map
@@ -0,0 +1 @@
+{"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"}
\ No newline at end of file
diff --git a/asset-transfer-events/chaincode-typescript/dist/index.d.ts b/asset-transfer-events/chaincode-typescript/dist/index.d.ts
new file mode 100644
index 00000000..35e4999b
--- /dev/null
+++ b/asset-transfer-events/chaincode-typescript/dist/index.d.ts
@@ -0,0 +1,2 @@
+export { AssetTransferEvents } from './asset-contract';
+export declare const contracts: any[];
diff --git a/asset-transfer-events/chaincode-typescript/dist/index.js b/asset-transfer-events/chaincode-typescript/dist/index.js
new file mode 100644
index 00000000..c80d3b40
--- /dev/null
+++ b/asset-transfer-events/chaincode-typescript/dist/index.js
@@ -0,0 +1,11 @@
+"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
\ No newline at end of file
diff --git a/asset-transfer-events/chaincode-typescript/dist/index.js.map b/asset-transfer-events/chaincode-typescript/dist/index.js.map
new file mode 100644
index 00000000..93647a7b
--- /dev/null
+++ b/asset-transfer-events/chaincode-typescript/dist/index.js.map
@@ -0,0 +1 @@
+{"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"}
\ No newline at end of file
diff --git a/asset-transfer-ledger-queries/application-java/.classpath b/asset-transfer-ledger-queries/application-java/.classpath
new file mode 100644
index 00000000..6d924d76
--- /dev/null
+++ b/asset-transfer-ledger-queries/application-java/.classpath
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/asset-transfer-ledger-queries/application-java/.settings/org.eclipse.buildship.core.prefs b/asset-transfer-ledger-queries/application-java/.settings/org.eclipse.buildship.core.prefs
new file mode 100644
index 00000000..98515123
--- /dev/null
+++ b/asset-transfer-ledger-queries/application-java/.settings/org.eclipse.buildship.core.prefs
@@ -0,0 +1,13 @@
+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
diff --git a/asset-transfer-ledger-queries/application-java/bin/main/application/java/App.class b/asset-transfer-ledger-queries/application-java/bin/main/application/java/App.class
new file mode 100644
index 00000000..0a6f753a
Binary files /dev/null and b/asset-transfer-ledger-queries/application-java/bin/main/application/java/App.class differ
diff --git a/asset-transfer-ledger-queries/application-java/bin/main/application/java/EnrollAdmin.class b/asset-transfer-ledger-queries/application-java/bin/main/application/java/EnrollAdmin.class
new file mode 100644
index 00000000..261f9032
Binary files /dev/null and b/asset-transfer-ledger-queries/application-java/bin/main/application/java/EnrollAdmin.class differ
diff --git a/asset-transfer-ledger-queries/application-java/bin/main/application/java/RegisterUser.class b/asset-transfer-ledger-queries/application-java/bin/main/application/java/RegisterUser.class
new file mode 100644
index 00000000..c400f7b5
Binary files /dev/null and b/asset-transfer-ledger-queries/application-java/bin/main/application/java/RegisterUser.class differ
diff --git a/asset-transfer-ledger-queries/application-java/bin/main/log4j.properties b/asset-transfer-ledger-queries/application-java/bin/main/log4j.properties
new file mode 100644
index 00000000..f1f841fe
--- /dev/null
+++ b/asset-transfer-ledger-queries/application-java/bin/main/log4j.properties
@@ -0,0 +1,19 @@
+# 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
diff --git a/asset-transfer-ledger-queries/chaincode-java/.classpath b/asset-transfer-ledger-queries/chaincode-java/.classpath
new file mode 100644
index 00000000..7a7f31fe
--- /dev/null
+++ b/asset-transfer-ledger-queries/chaincode-java/.classpath
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/asset-transfer-ledger-queries/chaincode-java/.settings/org.eclipse.buildship.core.prefs b/asset-transfer-ledger-queries/chaincode-java/.settings/org.eclipse.buildship.core.prefs
new file mode 100644
index 00000000..98515123
--- /dev/null
+++ b/asset-transfer-ledger-queries/chaincode-java/.settings/org.eclipse.buildship.core.prefs
@@ -0,0 +1,13 @@
+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
diff --git a/asset-transfer-ledger-queries/chaincode-java/.settings/org.eclipse.jdt.core.prefs b/asset-transfer-ledger-queries/chaincode-java/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..35068d95
--- /dev/null
+++ b/asset-transfer-ledger-queries/chaincode-java/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,4 @@
+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
diff --git a/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/Asset.class b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/Asset.class
new file mode 100644
index 00000000..70f6c39e
Binary files /dev/null and b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/Asset.class differ
diff --git a/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$1$1.class b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$1$1.class
new file mode 100644
index 00000000..33330fae
Binary files /dev/null and b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$1$1.class differ
diff --git a/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$1.class b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$1.class
new file mode 100644
index 00000000..b6e50e6c
Binary files /dev/null and b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$1.class differ
diff --git a/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$2.class b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$2.class
new file mode 100644
index 00000000..7e485d63
Binary files /dev/null and b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$2.class differ
diff --git a/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$3.class b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$3.class
new file mode 100644
index 00000000..617c3678
Binary files /dev/null and b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$3.class differ
diff --git a/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$4.class b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$4.class
new file mode 100644
index 00000000..fd0f8fc3
Binary files /dev/null and b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$4.class differ
diff --git a/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$5.class b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$5.class
new file mode 100644
index 00000000..095a2f30
Binary files /dev/null and b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$5.class differ
diff --git a/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$AssetTransferErrors.class b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$AssetTransferErrors.class
new file mode 100644
index 00000000..a8f68d18
Binary files /dev/null and b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract$AssetTransferErrors.class differ
diff --git a/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract.class b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract.class
new file mode 100644
index 00000000..89994790
Binary files /dev/null and b/asset-transfer-ledger-queries/chaincode-java/bin/main/org/example/AssetContract.class differ
diff --git a/asset-transfer-ledger-queries/chaincode-typescript/dist/asset-contract.d.ts b/asset-transfer-ledger-queries/chaincode-typescript/dist/asset-contract.d.ts
new file mode 100644
index 00000000..a239cf90
--- /dev/null
+++ b/asset-transfer-ledger-queries/chaincode-typescript/dist/asset-contract.d.ts
@@ -0,0 +1,19 @@
+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;
+ ReadAsset(ctx: Context, id: string): Promise;
+ DeleteAsset(ctx: Context, id: string): Promise;
+ TransferAsset(ctx: Context, assetName: string, newOwner: string): Promise;
+ GetAssetsByRange(ctx: Context, startKey: string, endKey: string): Promise;
+ TransferAssetByColor(ctx: Context, color: string, newOwner: string): Promise;
+ QueryAssetsByOwner(ctx: Context, owner: string): Promise;
+ QueryAssets(ctx: Context, queryString: string): Promise;
+ GetQueryResultForQueryString(ctx: Context, queryString: string): Promise;
+ GetAssetsByRangeWithPagination(ctx: Context, startKey: string, endKey: string, pageSize: number, bookmark: string): Promise;
+ QueryAssetsWithPagination(ctx: Context, queryString: string, pageSize: number, bookmark: string): Promise;
+ GetAssetHistory(ctx: Context, assetName: string): Promise;
+ AssetExists(ctx: Context, assetName: string): Promise;
+ GetAllResults(iterator: Iterators.CommonIterator, isHistory: boolean): Promise;
+ InitLedger(ctx: Context): Promise;
+}
diff --git a/asset-transfer-ledger-queries/chaincode-typescript/dist/asset-contract.js b/asset-transfer-ledger-queries/chaincode-typescript/dist/asset-contract.js
new file mode 100644
index 00000000..9919ee64
--- /dev/null
+++ b/asset-transfer-ledger-queries/chaincode-typescript/dist/asset-contract.js
@@ -0,0 +1,452 @@
+"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
\ No newline at end of file
diff --git a/asset-transfer-ledger-queries/chaincode-typescript/dist/asset-contract.js.map b/asset-transfer-ledger-queries/chaincode-typescript/dist/asset-contract.js.map
new file mode 100644
index 00000000..c4566538
--- /dev/null
+++ b/asset-transfer-ledger-queries/chaincode-typescript/dist/asset-contract.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"asset-contract.js","sourceRoot":"","sources":["../src/asset-contract.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/asset-transfer-ledger-queries/chaincode-typescript/dist/asset.d.ts b/asset-transfer-ledger-queries/chaincode-typescript/dist/asset.d.ts
new file mode 100644
index 00000000..76258663
--- /dev/null
+++ b/asset-transfer-ledger-queries/chaincode-typescript/dist/asset.d.ts
@@ -0,0 +1,8 @@
+export declare class Asset {
+ docType?: string;
+ ID: string;
+ Color: string;
+ Size: number;
+ Owner: string;
+ AppraisedValue: number;
+}
diff --git a/asset-transfer-ledger-queries/chaincode-typescript/dist/asset.js b/asset-transfer-ledger-queries/chaincode-typescript/dist/asset.js
new file mode 100644
index 00000000..959731c8
--- /dev/null
+++ b/asset-transfer-ledger-queries/chaincode-typescript/dist/asset.js
@@ -0,0 +1,47 @@
+"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
\ No newline at end of file
diff --git a/asset-transfer-ledger-queries/chaincode-typescript/dist/asset.js.map b/asset-transfer-ledger-queries/chaincode-typescript/dist/asset.js.map
new file mode 100644
index 00000000..4ea75c0b
--- /dev/null
+++ b/asset-transfer-ledger-queries/chaincode-typescript/dist/asset.js.map
@@ -0,0 +1 @@
+{"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"}
\ No newline at end of file
diff --git a/asset-transfer-ledger-queries/chaincode-typescript/dist/index.d.ts b/asset-transfer-ledger-queries/chaincode-typescript/dist/index.d.ts
new file mode 100644
index 00000000..a6682c7a
--- /dev/null
+++ b/asset-transfer-ledger-queries/chaincode-typescript/dist/index.d.ts
@@ -0,0 +1,2 @@
+export { AssetContract } from './asset-contract';
+export declare const contracts: any[];
diff --git a/asset-transfer-ledger-queries/chaincode-typescript/dist/index.js b/asset-transfer-ledger-queries/chaincode-typescript/dist/index.js
new file mode 100644
index 00000000..449966d9
--- /dev/null
+++ b/asset-transfer-ledger-queries/chaincode-typescript/dist/index.js
@@ -0,0 +1,11 @@
+"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
\ No newline at end of file
diff --git a/asset-transfer-ledger-queries/chaincode-typescript/dist/index.js.map b/asset-transfer-ledger-queries/chaincode-typescript/dist/index.js.map
new file mode 100644
index 00000000..2e429a9c
--- /dev/null
+++ b/asset-transfer-ledger-queries/chaincode-typescript/dist/index.js.map
@@ -0,0 +1 @@
+{"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"}
\ No newline at end of file
diff --git a/asset-transfer-private-data/chaincode-java/.classpath b/asset-transfer-private-data/chaincode-java/.classpath
new file mode 100644
index 00000000..c1735d38
--- /dev/null
+++ b/asset-transfer-private-data/chaincode-java/.classpath
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/asset-transfer-private-data/chaincode-java/.settings/org.eclipse.buildship.core.prefs b/asset-transfer-private-data/chaincode-java/.settings/org.eclipse.buildship.core.prefs
new file mode 100644
index 00000000..98515123
--- /dev/null
+++ b/asset-transfer-private-data/chaincode-java/.settings/org.eclipse.buildship.core.prefs
@@ -0,0 +1,13 @@
+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
diff --git a/asset-transfer-private-data/chaincode-java/bin/main/org/hyperledger/fabric/samples/privatedata/Asset.class b/asset-transfer-private-data/chaincode-java/bin/main/org/hyperledger/fabric/samples/privatedata/Asset.class
new file mode 100644
index 00000000..3a89a695
Binary files /dev/null and b/asset-transfer-private-data/chaincode-java/bin/main/org/hyperledger/fabric/samples/privatedata/Asset.class differ
diff --git a/asset-transfer-private-data/chaincode-java/bin/main/org/hyperledger/fabric/samples/privatedata/AssetPrivateDetails.class b/asset-transfer-private-data/chaincode-java/bin/main/org/hyperledger/fabric/samples/privatedata/AssetPrivateDetails.class
new file mode 100644
index 00000000..c281e587
Binary files /dev/null and b/asset-transfer-private-data/chaincode-java/bin/main/org/hyperledger/fabric/samples/privatedata/AssetPrivateDetails.class differ
diff --git a/asset-transfer-private-data/chaincode-java/bin/main/org/hyperledger/fabric/samples/privatedata/AssetTransfer$AssetTransferErrors.class b/asset-transfer-private-data/chaincode-java/bin/main/org/hyperledger/fabric/samples/privatedata/AssetTransfer$AssetTransferErrors.class
new file mode 100644
index 00000000..6733823f
Binary files /dev/null and b/asset-transfer-private-data/chaincode-java/bin/main/org/hyperledger/fabric/samples/privatedata/AssetTransfer$AssetTransferErrors.class differ
diff --git a/asset-transfer-private-data/chaincode-java/bin/main/org/hyperledger/fabric/samples/privatedata/AssetTransfer.class b/asset-transfer-private-data/chaincode-java/bin/main/org/hyperledger/fabric/samples/privatedata/AssetTransfer.class
new file mode 100644
index 00000000..64bc57b6
Binary files /dev/null and b/asset-transfer-private-data/chaincode-java/bin/main/org/hyperledger/fabric/samples/privatedata/AssetTransfer.class differ
diff --git a/asset-transfer-private-data/chaincode-java/bin/main/org/hyperledger/fabric/samples/privatedata/TransferAgreement.class b/asset-transfer-private-data/chaincode-java/bin/main/org/hyperledger/fabric/samples/privatedata/TransferAgreement.class
new file mode 100644
index 00000000..76199837
Binary files /dev/null and b/asset-transfer-private-data/chaincode-java/bin/main/org/hyperledger/fabric/samples/privatedata/TransferAgreement.class differ
diff --git a/asset-transfer-private-data/chaincode-java/bin/test/mockito-extensions/org.mockito.plugins.MockMaker b/asset-transfer-private-data/chaincode-java/bin/test/mockito-extensions/org.mockito.plugins.MockMaker
new file mode 100644
index 00000000..1f0955d4
--- /dev/null
+++ b/asset-transfer-private-data/chaincode-java/bin/test/mockito-extensions/org.mockito.plugins.MockMaker
@@ -0,0 +1 @@
+mock-maker-inline
diff --git a/asset-transfer-private-data/chaincode-java/bin/test/org/hyperledger/fabric/samples/privatedata/AssetTransferTest$InvokeWriteTransaction.class b/asset-transfer-private-data/chaincode-java/bin/test/org/hyperledger/fabric/samples/privatedata/AssetTransferTest$InvokeWriteTransaction.class
new file mode 100644
index 00000000..d290d548
Binary files /dev/null and b/asset-transfer-private-data/chaincode-java/bin/test/org/hyperledger/fabric/samples/privatedata/AssetTransferTest$InvokeWriteTransaction.class differ
diff --git a/asset-transfer-private-data/chaincode-java/bin/test/org/hyperledger/fabric/samples/privatedata/AssetTransferTest$QueryReadAssetTransaction.class b/asset-transfer-private-data/chaincode-java/bin/test/org/hyperledger/fabric/samples/privatedata/AssetTransferTest$QueryReadAssetTransaction.class
new file mode 100644
index 00000000..2c77c409
Binary files /dev/null and b/asset-transfer-private-data/chaincode-java/bin/test/org/hyperledger/fabric/samples/privatedata/AssetTransferTest$QueryReadAssetTransaction.class differ
diff --git a/asset-transfer-private-data/chaincode-java/bin/test/org/hyperledger/fabric/samples/privatedata/AssetTransferTest.class b/asset-transfer-private-data/chaincode-java/bin/test/org/hyperledger/fabric/samples/privatedata/AssetTransferTest.class
new file mode 100644
index 00000000..0a630bc4
Binary files /dev/null and b/asset-transfer-private-data/chaincode-java/bin/test/org/hyperledger/fabric/samples/privatedata/AssetTransferTest.class differ
diff --git a/asset-transfer-private-data/chaincode-javascript/.editorconfig b/asset-transfer-private-data/chaincode-javascript/.editorconfig
new file mode 100755
index 00000000..75a13be2
--- /dev/null
+++ b/asset-transfer-private-data/chaincode-javascript/.editorconfig
@@ -0,0 +1,16 @@
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+root = true
+
+[*]
+indent_style = space
+indent_size = 4
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/asset-transfer-private-data/chaincode-javascript/.eslintignore b/asset-transfer-private-data/chaincode-javascript/.eslintignore
new file mode 100644
index 00000000..15958470
--- /dev/null
+++ b/asset-transfer-private-data/chaincode-javascript/.eslintignore
@@ -0,0 +1,5 @@
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+coverage
diff --git a/asset-transfer-private-data/chaincode-javascript/.eslintrc.js b/asset-transfer-private-data/chaincode-javascript/.eslintrc.js
new file mode 100644
index 00000000..dce49042
--- /dev/null
+++ b/asset-transfer-private-data/chaincode-javascript/.eslintrc.js
@@ -0,0 +1,36 @@
+/*
+ * 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']
+ }
+};
diff --git a/asset-transfer-private-data/chaincode-javascript/.gitignore b/asset-transfer-private-data/chaincode-javascript/.gitignore
new file mode 100644
index 00000000..a00ca941
--- /dev/null
+++ b/asset-transfer-private-data/chaincode-javascript/.gitignore
@@ -0,0 +1,77 @@
+#
+# 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
diff --git a/asset-transfer-private-data/chaincode-javascript/.npmignore b/asset-transfer-private-data/chaincode-javascript/.npmignore
new file mode 100644
index 00000000..9f5fab92
--- /dev/null
+++ b/asset-transfer-private-data/chaincode-javascript/.npmignore
@@ -0,0 +1,20 @@
+#
+# 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
diff --git a/asset-transfer-private-data/chaincode-javascript/index.js b/asset-transfer-private-data/chaincode-javascript/index.js
new file mode 100644
index 00000000..85198ba8
--- /dev/null
+++ b/asset-transfer-private-data/chaincode-javascript/index.js
@@ -0,0 +1,10 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+'use strict';
+
+const AssetContract = require('./lib/asset-contract');
+
+module.exports.AssetContract = AssetContract;
+module.exports.contracts = [ AssetContract ];
diff --git a/asset-transfer-private-data/chaincode-javascript/lib/asset-contract.js b/asset-transfer-private-data/chaincode-javascript/lib/asset-contract.js
new file mode 100644
index 00000000..4ec03182
--- /dev/null
+++ b/asset-transfer-private-data/chaincode-javascript/lib/asset-contract.js
@@ -0,0 +1,156 @@
+/*
+ * Copyright IBM Corp. All Rights Reserved.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+'use strict';
+
+const { Contract } = require('fabric-contract-api');
+
+class AssetContract extends Contract {
+
+ async InitLedger(ctx) {
+ const assets = [
+ {
+ ID: 'asset1',
+ Color: 'blue',
+ Size: 5,
+ Owner: 'Tomoko',
+ AppraisedValue: 300,
+ },
+ {
+ ID: 'asset2',
+ Color: 'red',
+ Size: 5,
+ Owner: 'Brad',
+ AppraisedValue: 400,
+ },
+ {
+ ID: 'asset3',
+ Color: 'green',
+ Size: 10,
+ Owner: 'Jin Soo',
+ AppraisedValue: 500,
+ },
+ {
+ ID: 'asset4',
+ Color: 'yellow',
+ Size: 10,
+ Owner: 'Max',
+ AppraisedValue: 600,
+ },
+ {
+ ID: 'asset5',
+ Color: 'black',
+ Size: 15,
+ Owner: 'Adriana',
+ AppraisedValue: 700,
+ },
+ {
+ ID: 'asset6',
+ Color: 'white',
+ Size: 15,
+ Owner: 'Michel',
+ AppraisedValue: 800,
+ },
+ ];
+
+ for (const asset of assets) {
+ asset.docType = 'asset';
+ await ctx.stub.putState(asset.ID, Buffer.from(JSON.stringify(asset)));
+ console.info(`Asset ${asset.ID} initialized`);
+ }
+ }
+
+ // CreateAsset issues a new asset to the world state with given details.
+ async CreateAsset(ctx, id, color, size, owner, appraisedValue) {
+ const exists = await this.AssetExists(ctx, id);
+ if (exists) {
+ throw new Error(`The asset ${id} already exists`);
+ }
+
+ const asset = {
+ ID: id,
+ Color: color,
+ Size: size,
+ Owner: owner,
+ AppraisedValue: appraisedValue,
+ };
+ await ctx.stub.putState(id, Buffer.from(JSON.stringify(asset)));
+ return JSON.stringify(asset);
+ }
+
+ // ReadAsset returns the asset stored in the world state with given id.
+ async ReadAsset(ctx, id) {
+ const assetJSON = await ctx.stub.getState(id); // get the asset from chaincode state
+ if (!assetJSON || assetJSON.length === 0) {
+ throw new Error(`The asset ${id} does not exist`);
+ }
+ return assetJSON.toString();
+ }
+
+ // UpdateAsset updates an existing asset in the world state with provided parameters.
+ async UpdateAsset(ctx, id, color, size, owner, appraisedValue) {
+ const exists = await this.AssetExists(ctx, id);
+ if (!exists) {
+ throw new Error(`The asset ${id} does not exist`);
+ }
+
+ // overwriting original asset with new asset
+ const updatedAsset = {
+ ID: id,
+ Color: color,
+ Size: size,
+ Owner: owner,
+ AppraisedValue: appraisedValue,
+ };
+ return ctx.stub.putState(id, Buffer.from(JSON.stringify(updatedAsset)));
+ }
+
+ // DeleteAsset deletes an given asset from the world state.
+ async DeleteAsset(ctx, id) {
+ const exists = await this.AssetExists(ctx, id);
+ if (!exists) {
+ throw new Error(`The asset ${id} does not exist`);
+ }
+ return ctx.stub.deleteState(id);
+ }
+
+ // AssetExists returns true when asset with given ID exists in world state.
+ async AssetExists(ctx, id) {
+ const assetJSON = await ctx.stub.getState(id);
+ 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);
+ asset.Owner = newOwner;
+ return 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);
+ }
+}
+
+module.exports = AssetContract;
diff --git a/asset-transfer-private-data/chaincode-javascript/package.json b/asset-transfer-private-data/chaincode-javascript/package.json
new file mode 100644
index 00000000..372ab15c
--- /dev/null
+++ b/asset-transfer-private-data/chaincode-javascript/package.json
@@ -0,0 +1,50 @@
+{
+ "name": "chaincode-javascript",
+ "version": "0.0.1",
+ "description": "My Smart Contract",
+ "main": "index.js",
+ "engines": {
+ "node": ">=8",
+ "npm": ">=5"
+ },
+ "scripts": {
+ "lint": "eslint .",
+ "pretest": "npm run lint",
+ "test": "nyc mocha --recursive",
+ "start": "fabric-chaincode-node start"
+ },
+ "engineStrict": true,
+ "author": "John Doe",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "fabric-contract-api": "^2.2.0",
+ "fabric-shim": "^2.2.0"
+ },
+ "devDependencies": {
+ "chai": "^4.2.0",
+ "chai-as-promised": "^7.1.1",
+ "eslint": "^6.8.0",
+ "mocha": "^7.1.1",
+ "nyc": "^15.0.0",
+ "sinon": "^9.0.1",
+ "sinon-chai": "^3.5.0",
+ "winston": "^3.2.1"
+ },
+ "nyc": {
+ "exclude": [
+ ".eslintrc.js",
+ "coverage/**",
+ "test/**"
+ ],
+ "reporter": [
+ "text-summary",
+ "html"
+ ],
+ "all": true,
+ "check-coverage": true,
+ "statements": 100,
+ "branches": 100,
+ "functions": 100,
+ "lines": 100
+ }
+}
diff --git a/asset-transfer-private-data/chaincode-javascript/test/asset-contract.js b/asset-transfer-private-data/chaincode-javascript/test/asset-contract.js
new file mode 100644
index 00000000..d522b702
--- /dev/null
+++ b/asset-transfer-private-data/chaincode-javascript/test/asset-contract.js
@@ -0,0 +1,108 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+'use strict';
+
+const { ChaincodeStub, ClientIdentity } = require('fabric-shim');
+const { AssetContract } = require('..');
+const winston = require('winston');
+
+const chai = require('chai');
+const chaiAsPromised = require('chai-as-promised');
+const sinon = require('sinon');
+const sinonChai = require('sinon-chai');
+
+chai.should();
+chai.use(chaiAsPromised);
+chai.use(sinonChai);
+
+class TestContext {
+
+ constructor() {
+ this.stub = sinon.createStubInstance(ChaincodeStub);
+ this.clientIdentity = sinon.createStubInstance(ClientIdentity);
+ this.logger = {
+ getLogger: sinon.stub().returns(sinon.createStubInstance(winston.createLogger().constructor)),
+ setLevel: sinon.stub(),
+ };
+ }
+
+}
+
+describe('AssetContract', () => {
+
+ let contract;
+ let ctx;
+
+ beforeEach(() => {
+ contract = new AssetContract();
+ ctx = new TestContext();
+ ctx.stub.getState.withArgs('1001').resolves(Buffer.from('{"value":"asset 1001 value"}'));
+ ctx.stub.getState.withArgs('1002').resolves(Buffer.from('{"value":"asset 1002 value"}'));
+ });
+
+ describe('#assetExists', () => {
+
+ it('should return true for a asset', async () => {
+ await contract.assetExists(ctx, '1001').should.eventually.be.true;
+ });
+
+ it('should return false for a asset that does not exist', async () => {
+ await contract.assetExists(ctx, '1003').should.eventually.be.false;
+ });
+
+ });
+
+ describe('#createAsset', () => {
+
+ it('should create a asset', async () => {
+ await contract.createAsset(ctx, '1003', 'asset 1003 value');
+ ctx.stub.putState.should.have.been.calledOnceWithExactly('1003', Buffer.from('{"value":"asset 1003 value"}'));
+ });
+
+ it('should throw an error for a asset that already exists', async () => {
+ await contract.createAsset(ctx, '1001', 'myvalue').should.be.rejectedWith(/The asset 1001 already exists/);
+ });
+
+ });
+
+ describe('#readAsset', () => {
+
+ it('should return a asset', async () => {
+ await contract.readAsset(ctx, '1001').should.eventually.deep.equal({ value: 'asset 1001 value' });
+ });
+
+ it('should throw an error for a asset that does not exist', async () => {
+ await contract.readAsset(ctx, '1003').should.be.rejectedWith(/The asset 1003 does not exist/);
+ });
+
+ });
+
+ describe('#updateAsset', () => {
+
+ it('should update a asset', async () => {
+ await contract.updateAsset(ctx, '1001', 'asset 1001 new value');
+ ctx.stub.putState.should.have.been.calledOnceWithExactly('1001', Buffer.from('{"value":"asset 1001 new value"}'));
+ });
+
+ it('should throw an error for a asset that does not exist', async () => {
+ await contract.updateAsset(ctx, '1003', 'asset 1003 new value').should.be.rejectedWith(/The asset 1003 does not exist/);
+ });
+
+ });
+
+ describe('#deleteAsset', () => {
+
+ it('should delete a asset', async () => {
+ await contract.deleteAsset(ctx, '1001');
+ ctx.stub.deleteState.should.have.been.calledOnceWithExactly('1001');
+ });
+
+ it('should throw an error for a asset that does not exist', async () => {
+ await contract.deleteAsset(ctx, '1003').should.be.rejectedWith(/The asset 1003 does not exist/);
+ });
+
+ });
+
+});
diff --git a/asset-transfer-private-data/chaincode-javascript/transaction_data/asset-transactions.txdata b/asset-transfer-private-data/chaincode-javascript/transaction_data/asset-transactions.txdata
new file mode 100644
index 00000000..79e48107
--- /dev/null
+++ b/asset-transfer-private-data/chaincode-javascript/transaction_data/asset-transactions.txdata
@@ -0,0 +1,44 @@
+[
+ {
+ "transactionName": "assetExists",
+ "transactionLabel": "A test assetExists transaction",
+ "arguments": [
+ "001"
+ ],
+ "transientData": {}
+ },
+ {
+ "transactionName": "createAsset",
+ "transactionLabel": "A test createAsset transaction",
+ "arguments": [
+ "001",
+ "some value"
+ ],
+ "transientData": {}
+ },
+ {
+ "transactionName": "readAsset",
+ "transactionLabel": "A test readAsset transaction",
+ "arguments": [
+ "001"
+ ],
+ "transientData": {}
+ },
+ {
+ "transactionName": "updateAsset",
+ "transactionLabel": "A test updateAsset transaction",
+ "arguments": [
+ "001",
+ "some other value"
+ ],
+ "transientData": {}
+ },
+ {
+ "transactionName": "deleteAsset",
+ "transactionLabel": "A test deleteAsset transaction",
+ "arguments": [
+ "001"
+ ],
+ "transientData": {}
+ }
+]
diff --git a/asset-transfer-sbe/chaincode-go/asset-contract.go b/asset-transfer-sbe/chaincode-go/asset-contract.go
new file mode 100644
index 00000000..0d077504
--- /dev/null
+++ b/asset-transfer-sbe/chaincode-go/asset-contract.go
@@ -0,0 +1,198 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "sort"
+
+ "github.com/hyperledger/fabric-contract-api-go/contractapi"
+)
+
+// SmartContract provides functions for managing an Asset
+type SmartContract struct {
+ contractapi.Contract
+}
+
+// CreateAsset issues a new asset to the world state with given details.
+func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, id string, value string, owner string) error {
+ exists, err := s.AssetExists(ctx, id)
+ if err != nil {
+ return err
+ }
+ if exists {
+ return fmt.Errorf("the asset %s already exists", id)
+ }
+ ownerOrg, err := s.getClientOrgId(ctx)
+ if err != nil {
+ return err
+ }
+
+ asset := Asset{
+ ID: id,
+ Value: value,
+ Owner: owner,
+ OwnerOrg: ownerOrg,
+ }
+ assetJSON, err := json.Marshal(asset)
+ if err != nil {
+ return err
+ } // Set the endorsement policy of the assetId Key, such that current owner Org is required to endorse future updates
+ setStateBasedEndorsement(ctx, id, ownerOrg)
+
+ // Optionally, set the endorsement policy of the assetId Key, such that any 1 Org (N) out of the specified Orgs can endorse future updates
+ // setStateBasedEndorsementNOutOf(ctx, assetId, 1, new String[]{"Org1MSP", "Org2MSP"});
+
+ return ctx.GetStub().PutState(id, assetJSON)
+}
+
+// ReadAsset returns the asset stored in the world state with given id.
+func (s *SmartContract) ReadAsset(ctx contractapi.TransactionContextInterface, id string) (*Asset, error) {
+ assetJSON, err := ctx.GetStub().GetState(id)
+ if err != nil {
+ return nil, fmt.Errorf("failed to read from world state: %v", err)
+ }
+ if assetJSON == nil {
+ return nil, fmt.Errorf("the asset %s does not exist", id)
+ }
+
+ var asset Asset
+ err = json.Unmarshal(assetJSON, &asset)
+ if err != nil {
+ return nil, err
+ }
+
+ return &asset, nil
+}
+
+// UpdateAsset updates an existing asset in the world state with provided parameters.
+// Needs an endorsement of current owner Org Peer.
+func (s *SmartContract) UpdateAsset(ctx contractapi.TransactionContextInterface, id string, value string, owner string) error {
+ exists, err := s.AssetExists(ctx, id)
+ if err != nil {
+ return err
+ }
+ if !exists {
+ return fmt.Errorf("the asset %s does not exist", id)
+ }
+ ownerOrg, err := s.getClientOrgId(ctx)
+ if err != nil {
+ return err
+ }
+ // overwriting original asset with new asset
+ asset := Asset{
+ ID: id,
+ Value: value,
+ Owner: owner,
+ OwnerOrg: ownerOrg,
+ }
+ assetJSON, err := json.Marshal(asset)
+ if err != nil {
+ return err
+ }
+
+ return ctx.GetStub().PutState(id, assetJSON)
+}
+
+// DeleteAsset deletes an given asset from the world state.
+//Needs an endorsement of current owner Org Peer.
+func (s *SmartContract) DeleteAsset(ctx contractapi.TransactionContextInterface, id string) error {
+ exists, err := s.AssetExists(ctx, id)
+ if err != nil {
+ return err
+ }
+ if !exists {
+ return fmt.Errorf("the asset %s does not exist", id)
+ }
+
+ return ctx.GetStub().DelState(id)
+}
+
+// AssetExists returns true when asset with given ID exists in world state
+func (s *SmartContract) AssetExists(ctx contractapi.TransactionContextInterface, id string) (bool, error) {
+ assetJSON, err := ctx.GetStub().GetState(id)
+ if err != nil {
+ return false, fmt.Errorf("failed to read from world state: %v", err)
+ }
+
+ return assetJSON != nil, nil
+}
+
+// TransferAsset updates the owner field of asset with given id in world state.
+// Needs an endorsement of current owner Org Peer.
+// Re-sets the endorsement policy of the assetId Key, such that new owner Org Peer is required to endorse future updates.
+func (s *SmartContract) TransferAsset(ctx contractapi.TransactionContextInterface, id string, newOwner string, newOwnerOrg string) error {
+ asset, err := s.ReadAsset(ctx, id)
+ if err != nil {
+ return err
+ }
+
+ asset.Owner = newOwner
+ asset.OwnerOrg = newOwnerOrg
+ assetJSON, err := json.Marshal(asset)
+ if err != nil {
+ return err
+ }
+ // Re-Set the endorsement policy of the assetId Key, such that a new owner Org Peer is required to endorse future updates
+ setStateBasedEndorsement(ctx, id, newOwnerOrg)
+
+ // Optionally, set the endorsement policy of the assetId Key, such that any 1 Org (N) out of the specified Orgs can endorse future updates
+ // setStateBasedEndorsementNOutOf(ctx, assetId, 1, new String[]{"Org1MSP", "Org2MSP"});
+
+ return ctx.GetStub().PutState(id, assetJSON)
+}
+
+// Retrieves the client's OrgId (MSPID)
+func (s *SmartContract) getClientOrgId(ctx contractapi.TransactionContextInterface) (string, error) {
+ return ctx.GetClientIdentity().GetMSPID()
+}
+
+// Sets an endorsement policy to the assetId Key.
+// Enforces that the owner Org must endorse future update transactions for the specified assetId Key.
+func setStateBasedEndorsement(ctx contractapi.TransactionContextInterface, assetId string, ownerOrgs string) {
+ var ep KeyEndorsementPolicy
+ ep.AddOrgs("MEMBER", ownerOrgs)
+ ctx.GetStub().SetStateValidationParameter(assetId, ep.getPolicy())
+}
+
+// Sets an endorsement policy to the assetId Key.
+// Enforces that a given number of Orgs (N) out of the specified Orgs must endorse future update transactions for the specified assetId Key.
+func setStateBasedEndorsementNOutOf(ctx contractapi.TransactionContextInterface, assetId string, nOrgs int, ownerOrgs []string) {
+ ctx.GetStub().SetStateValidationParameter(assetId, policy(nOrgs, ownerOrgs))
+}
+
+// Create a policy that requires a given number (N) of Org principals signatures out of the provided list of Orgs
+func policy(nOrgs int, mspids []string) []byte {
+ sort.Strings(mspids)
+ var principals []string
+ var signPolicy []string
+ for i := 0; i < len(mspids); i++ {
+ mspid := mspids[i]
+ var mspRole MSPRole
+ mspRole := MSPRole{
+ mspId,
+ MSPRole.MSPRoleType.MEMBER}
+ var MSPPrincipal principals
+ principal := MSPPrincipal{
+ fabprotos.common.MSPPrincipal.Classification.ROLE,
+ fabprotos.common.MSPRole.encode(mspRole).finish()}
+ principals = append(principals, MspPrincipal.MSPPrincipal.newBuilder().setPrincipalClassification(MspPrincipal.MSPPrincipal.Classification.ROLE).setPrincipal(MspPrincipal.MSPRole.newBuilder().setMspIdentifier(mspid).setRole(MspPrincipal.MSPRole.MSPRoleType.MEMBER).build().toByteString()).build())
+ var signedBy SignaturePolicy_SignedBy
+ signedBy := SignaturePolicy_SignedBy{i}
+ signPolicy = append(signPolicy, signedBy)
+ }
+ // create the policy such that it requires any N signature's from all of the principals provided
+ var allOf SignaturePolicy_NOutOf
+ allOf := SignaturePolicy_NOutOf{nOrgs, signPolicies}
+ var nOutof SignaturePolicy_NOutOf_
+ noutof := SignaturePolicy_NOutOf_{allOf}
+ var spe SignaturePolicyEnvelope
+ spe := SignaturePolicyEnvelope{
+ version: 0,
+ rule: noutof,
+ identities: principals}
+ return
+}
diff --git a/asset-transfer-sbe/chaincode-go/asset.go b/asset-transfer-sbe/chaincode-go/asset.go
new file mode 100644
index 00000000..a97fd910
--- /dev/null
+++ b/asset-transfer-sbe/chaincode-go/asset.go
@@ -0,0 +1,9 @@
+package main
+
+// Asset describes basic details of what makes up a simple asset
+type Asset struct {
+ ID string `json:"ID"`
+ Value string `json:"color"`
+ Owner string `json:"owner"`
+ OwnerOrg string `json:"appraisedValue"`
+}
diff --git a/asset-transfer-sbe/chaincode-go/go.mod b/asset-transfer-sbe/chaincode-go/go.mod
new file mode 100644
index 00000000..4595bdae
--- /dev/null
+++ b/asset-transfer-sbe/chaincode-go/go.mod
@@ -0,0 +1,9 @@
+module chaincode-go
+
+go 1.13
+
+require (
+ github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212
+ github.com/hyperledger/fabric-contract-api-go v1.1.0
+ github.com/stretchr/testify v1.5.1
+)
diff --git a/asset-transfer-sbe/chaincode-go/go.sum b/asset-transfer-sbe/chaincode-go/go.sum
new file mode 100644
index 00000000..94a66455
--- /dev/null
+++ b/asset-transfer-sbe/chaincode-go/go.sum
@@ -0,0 +1,138 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/DATA-DOG/go-txdb v0.1.3/go.mod h1:DhAhxMXZpUJVGnT+p9IbzJoRKvlArO2pkHjnGX7o0n0=
+github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
+github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
+github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
+github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
+github.com/cucumber/godog v0.8.0/go.mod h1:Cp3tEV1LRAyH/RuCThcxHS/+9ORZ+FMzPva2AZ5Ki+A=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
+github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
+github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
+github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w=
+github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
+github.com/go-openapi/spec v0.19.4 h1:ixzUSnHTd6hCemgtAJgluaTSGYpLNpJY4mA2DIkdOAo=
+github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
+github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
+github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
+github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/gobuffalo/envy v1.7.0 h1:GlXgaiBkmrYMHco6t4j7SacKO4XUjvh5pwXh0f4uxXU=
+github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
+github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs=
+github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4=
+github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q=
+github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg=
+github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk=
+github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
+github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212 h1:1i4lnpV8BDgKOLi1hgElfBqdHXjXieSuj8629mwBZ8o=
+github.com/hyperledger/fabric-chaincode-go v0.0.0-20200424173110-d7076418f212/go.mod h1:N7H3sA7Tx4k/YzFq7U0EPdqJtqvM4Kild0JoCc7C0Dc=
+github.com/hyperledger/fabric-contract-api-go v1.1.0 h1:K9uucl/6eX3NF0/b+CGIiO1IPm1VYQxBkpnVGJur2S4=
+github.com/hyperledger/fabric-contract-api-go v1.1.0/go.mod h1:nHWt0B45fK53owcFpLtAe8DH0Q5P068mnzkNXMPSL7E=
+github.com/hyperledger/fabric-protos-go v0.0.0-20190919234611-2a87503ac7c9/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0=
+github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e h1:9PS5iezHk/j7XriSlNuSQILyCOfcZ9wZ3/PiucmSE8E=
+github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0=
+github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
+github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
+github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
+github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
+github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
+github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
+github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
+github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
+github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
+github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
+github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
+golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM=
+golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542 h1:6ZQFf1D2YYDDI7eSwW8adlkkavTB9sw5I24FVtEvNUQ=
+golang.org/x/sys v0.0.0-20190710143415-6ec70d6a5542/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190624180213-70d37148ca0c/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20180831171423-11092d34479b h1:lohp5blsw53GBXtLyLNaTXPXS9pJ1tiTw61ZHUoE9Qw=
+google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A=
+google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
+gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/asset-transfer-sbe/chaincode-go/main.go b/asset-transfer-sbe/chaincode-go/main.go
new file mode 100644
index 00000000..8a94fdc9
--- /dev/null
+++ b/asset-transfer-sbe/chaincode-go/main.go
@@ -0,0 +1,34 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+package main
+
+import (
+ "github.com/hyperledger/fabric-contract-api-go/contractapi"
+ "github.com/hyperledger/fabric-contract-api-go/metadata"
+)
+
+func main() {
+ assetContract := new(AssetContract)
+ assetContract.Info.Version = "0.0.1"
+ assetContract.Info.Description = "My Smart Contract"
+ assetContract.Info.License = new(metadata.LicenseMetadata)
+ assetContract.Info.License.Name = "Apache-2.0"
+ assetContract.Info.Contact = new(metadata.ContactMetadata)
+ assetContract.Info.Contact.Name = "John Doe"
+
+ chaincode, err := contractapi.NewChaincode(assetContract)
+ chaincode.Info.Title = "chaincode-go chaincode"
+ chaincode.Info.Version = "0.0.1"
+
+ if err != nil {
+ panic("Could not create chaincode from AssetContract." + err.Error())
+ }
+
+ err = chaincode.Start()
+
+ if err != nil {
+ panic("Failed to start chaincode. " + err.Error())
+ }
+}
diff --git a/asset-transfer-sbe/chaincode-go/transaction_data/my-transactions.txdata b/asset-transfer-sbe/chaincode-go/transaction_data/my-transactions.txdata
new file mode 100644
index 00000000..b6eba614
--- /dev/null
+++ b/asset-transfer-sbe/chaincode-go/transaction_data/my-transactions.txdata
@@ -0,0 +1,44 @@
+[
+ {
+ "transactionName": "AssetExists",
+ "transactionLabel": "A test AssetExists transaction",
+ "arguments": [
+ "001"
+ ],
+ "transientData": {}
+ },
+ {
+ "transactionName": "CreateAsset",
+ "transactionLabel": "A test CreateAsset transaction",
+ "arguments": [
+ "001",
+ "some value"
+ ],
+ "transientData": {}
+ },
+ {
+ "transactionName": "ReadAsset",
+ "transactionLabel": "A test ReadAsset transaction",
+ "arguments": [
+ "001"
+ ],
+ "transientData": {}
+ },
+ {
+ "transactionName": "UpdateAsset",
+ "transactionLabel": "A test UpdateAsset transaction",
+ "arguments": [
+ "001",
+ "some other value"
+ ],
+ "transientData": {}
+ },
+ {
+ "transactionName": "DeleteAsset",
+ "transactionLabel": "A test DeleteAsset transaction",
+ "arguments": [
+ "001"
+ ],
+ "transientData": {}
+ }
+]
diff --git a/asset-transfer-sbe/chaincode-javascript/.editorconfig b/asset-transfer-sbe/chaincode-javascript/.editorconfig
new file mode 100755
index 00000000..75a13be2
--- /dev/null
+++ b/asset-transfer-sbe/chaincode-javascript/.editorconfig
@@ -0,0 +1,16 @@
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+root = true
+
+[*]
+indent_style = space
+indent_size = 4
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/asset-transfer-sbe/chaincode-javascript/.eslintignore b/asset-transfer-sbe/chaincode-javascript/.eslintignore
new file mode 100644
index 00000000..15958470
--- /dev/null
+++ b/asset-transfer-sbe/chaincode-javascript/.eslintignore
@@ -0,0 +1,5 @@
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+coverage
diff --git a/asset-transfer-sbe/chaincode-javascript/.eslintrc.js b/asset-transfer-sbe/chaincode-javascript/.eslintrc.js
new file mode 100644
index 00000000..dce49042
--- /dev/null
+++ b/asset-transfer-sbe/chaincode-javascript/.eslintrc.js
@@ -0,0 +1,36 @@
+/*
+ * 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']
+ }
+};
diff --git a/asset-transfer-sbe/chaincode-javascript/.gitignore b/asset-transfer-sbe/chaincode-javascript/.gitignore
new file mode 100644
index 00000000..a00ca941
--- /dev/null
+++ b/asset-transfer-sbe/chaincode-javascript/.gitignore
@@ -0,0 +1,77 @@
+#
+# 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
diff --git a/asset-transfer-sbe/chaincode-javascript/.npmignore b/asset-transfer-sbe/chaincode-javascript/.npmignore
new file mode 100644
index 00000000..9f5fab92
--- /dev/null
+++ b/asset-transfer-sbe/chaincode-javascript/.npmignore
@@ -0,0 +1,20 @@
+#
+# 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
diff --git a/asset-transfer-sbe/chaincode-javascript/index.js b/asset-transfer-sbe/chaincode-javascript/index.js
new file mode 100644
index 00000000..85198ba8
--- /dev/null
+++ b/asset-transfer-sbe/chaincode-javascript/index.js
@@ -0,0 +1,10 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+'use strict';
+
+const AssetContract = require('./lib/asset-contract');
+
+module.exports.AssetContract = AssetContract;
+module.exports.contracts = [ AssetContract ];
diff --git a/asset-transfer-sbe/chaincode-javascript/lib/asset-contract.js b/asset-transfer-sbe/chaincode-javascript/lib/asset-contract.js
new file mode 100644
index 00000000..2c2cd003
--- /dev/null
+++ b/asset-transfer-sbe/chaincode-javascript/lib/asset-contract.js
@@ -0,0 +1,149 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+'use strict';
+
+const { Context } = require('fabric-contract-api');
+const { KeyEndorsementPolicy } = require('fabric-shim');
+import * as fabprotos from 'fabric-shim/bundle';
+
+class AssetContract extends Contract {
+
+ // CreateAsset creates a new asset
+ // CreateAsset sets the endorsement policy of the assetId Key, such that current owner Org Peer is required to endorse future updates
+ async CreateAsset(ctx, assetId, value, owner) {
+ const exists = await this.AssetExists(ctx, assetId);
+ if (exists) {
+ throw new Error(`The asset ${assetId} already exists`);
+ }
+ const ownerOrg = AssetContract.getClientOrgId(ctx);
+ const asset = new Asset();
+ asset.ID = assetId;
+ asset.Value = value;
+ asset.Owner = owner;
+ asset.OwnerOrg = ownerOrg;
+ const buffer = Buffer.from(JSON.stringify(asset));
+ // Create the asset
+ await ctx.stub.putState(assetId, buffer);
+
+ // Set the endorsement policy of the assetId Key, such that current owner Org is required to endorse future updates
+ await AssetContract.setStateBasedEndorsement(ctx, assetId, [ownerOrg]);
+
+ // Optionally, set the endorsement policy of the assetId Key, such that any 1 Org (N) out of the specified Orgs can endorse future updates
+ // await AssetContract.setStateBasedEndorsementNOutOf(ctx, assetId, 1, ["Org1MSP", "Org2MSP"]);
+ }
+
+ // ReadAsset returns asset with given assetId
+ async ReadAsset(ctx, assetId) {
+ const exists = await this.AssetExists(ctx, assetId);
+ if (!exists) {
+ throw new Error(`The asset ${assetId} does not exist`);
+ }
+ // Read the asset
+ const assetJSON = await ctx.stub.getState(assetId);
+ return assetJSON.toString();
+ }
+
+ // UpdateAsset updates an existing asset
+ // UpdateAsset needs an endorsement of current owner Org Peer
+ async UpdateAsset(ctx, assetId, newValue) {
+ const assetString = await this.ReadAsset(ctx, assetId);
+ const asset = JSON.parse(assetString);
+ asset.Value = newValue;
+ const buffer = Buffer.from(JSON.stringify(asset));
+ // Update the asset
+ await ctx.stub.putState(assetId, buffer);
+ }
+
+ // DeleteAsset deletes an given asset
+ // DeleteAsset needs an endorsement of current owner Org Peer
+ async DeleteAsset(ctx, assetId) {
+ const exists = await this.AssetExists(ctx, assetId);
+ if (!exists) {
+ throw new Error(`The asset ${assetId} does not exist`);
+ }
+ // Delete the asset
+ await ctx.stub.deleteState(assetId);
+ }
+
+ // TransferAsset updates the Owner & OwnerOrg field of asset with given assetId, OwnerOrg must be a valid Org MSP Id
+ // TransferAsset needs an endorsement of current owner Org Peer
+ // TransferAsset re-sets the endorsement policy of the assetId Key, such that new owner Org Peer is required to endorse future updates
+ async TransferAsset(ctx, assetId, newOwner, newOwnerOrg) {
+ const assetString = await this.ReadAsset(ctx, assetId);
+ const asset = JSON.parse(assetString);
+ asset.Owner = newOwner;
+ asset.OwnerOrg = newOwnerOrg;
+ // Update the asset
+ await ctx.stub.putState(assetId, Buffer.from(JSON.stringify(asset)));
+ // Re-Set the endorsement policy of the assetId Key, such that a new owner Org Peer is required to endorse future updates
+ await AssetContract.setStateBasedEndorsement(ctx, asset.ID, [newOwnerOrg]);
+
+ // Optionally, set the endorsement policy of the assetId Key, such that any 1 Org (N) out of the specified Orgs can endorse future updates
+ // await AssetContract.setStateBasedEndorsementNOutOf(ctx, assetId, 1, ["Org1MSP", "Org2MSP"]);
+ }
+
+ // AssetExists returns true when asset with given ID exists
+ async AssetExists(ctx, assetId){
+ const buffer = await ctx.stub.getState(assetId);
+ return (!!buffer && buffer.length > 0);
+ }
+
+ // getClientOrgId gets the client's OrgId (MSPID)
+ static getClientOrgId(ctx){
+ return ctx.clientIdentity.getMSPID();
+ }
+
+ // setStateBasedEndorsement sets an endorsement policy to the assetId Key
+ // setStateBasedEndorsement enforces that the owner Org must endorse future update transactions for the specified assetId Key
+ static async setStateBasedEndorsement(ctx, assetId, ownerOrgs){
+ const ep = new KeyEndorsementPolicy();
+ ep.addOrgs('MEMBER', ...ownerOrgs);
+ await ctx.stub.setStateValidationParameter(assetId, ep.getPolicy());
+ }
+
+ // setStateBasedEndorsementNOutOf sets an endorsement policy to the assetId Key
+ // setStateBasedEndorsementNOutOf enforces that a given number of Orgs (N) out of the specified Orgs must endorse future update transactions for the specified assetId Key.
+ async setStateBasedEndorsementNOutOf(ctx, assetId, nOrgs, ownerOrgs) {
+ await ctx.stub.setStateValidationParameter(assetId, AssetContract.policy(nOrgs, ownerOrgs));
+ }
+
+ // Create a policy that requires a given number (N) of Org principals signatures out of the provided list of Orgs
+ static policy(nOrgs, mspIds) {
+ const principals = [];
+ const sigsPolicies = [];
+ mspIds.forEach((mspId, i) => {
+ const mspRole = {
+ role: fabprotos.common.MSPRole.MSPRoleType.MEMBER,
+ mspIdentifier: mspId
+ };
+ const principal = {
+ principalClassification: fabprotos.common.MSPPrincipal.Classification.ROLE,
+ principal: fabprotos.common.MSPRole.encode(mspRole).finish()
+ };
+ principals.push(principal);
+ const signedBy = {
+ signedBy: i,
+ };
+ sigsPolicies.push(signedBy);
+ });
+
+ // create the policy such that it requires any N signature's from all of the principals provided
+ const allOf = {
+ n: nOrgs,
+ rules: sigsPolicies
+ };
+ const noutof = {
+ nOutOf: allOf
+ };
+ const spe = {
+ version: 0,
+ rule: noutof,
+ identities: principals
+ };
+ return fabprotos.common.SignaturePolicyEnvelope.encode(spe).finish();
+ }
+}
+
+module.exports = AssetContract;
diff --git a/asset-transfer-sbe/chaincode-javascript/package.json b/asset-transfer-sbe/chaincode-javascript/package.json
new file mode 100644
index 00000000..372ab15c
--- /dev/null
+++ b/asset-transfer-sbe/chaincode-javascript/package.json
@@ -0,0 +1,50 @@
+{
+ "name": "chaincode-javascript",
+ "version": "0.0.1",
+ "description": "My Smart Contract",
+ "main": "index.js",
+ "engines": {
+ "node": ">=8",
+ "npm": ">=5"
+ },
+ "scripts": {
+ "lint": "eslint .",
+ "pretest": "npm run lint",
+ "test": "nyc mocha --recursive",
+ "start": "fabric-chaincode-node start"
+ },
+ "engineStrict": true,
+ "author": "John Doe",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "fabric-contract-api": "^2.2.0",
+ "fabric-shim": "^2.2.0"
+ },
+ "devDependencies": {
+ "chai": "^4.2.0",
+ "chai-as-promised": "^7.1.1",
+ "eslint": "^6.8.0",
+ "mocha": "^7.1.1",
+ "nyc": "^15.0.0",
+ "sinon": "^9.0.1",
+ "sinon-chai": "^3.5.0",
+ "winston": "^3.2.1"
+ },
+ "nyc": {
+ "exclude": [
+ ".eslintrc.js",
+ "coverage/**",
+ "test/**"
+ ],
+ "reporter": [
+ "text-summary",
+ "html"
+ ],
+ "all": true,
+ "check-coverage": true,
+ "statements": 100,
+ "branches": 100,
+ "functions": 100,
+ "lines": 100
+ }
+}
diff --git a/asset-transfer-sbe/chaincode-javascript/test/asset-contract.js b/asset-transfer-sbe/chaincode-javascript/test/asset-contract.js
new file mode 100644
index 00000000..d522b702
--- /dev/null
+++ b/asset-transfer-sbe/chaincode-javascript/test/asset-contract.js
@@ -0,0 +1,108 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+'use strict';
+
+const { ChaincodeStub, ClientIdentity } = require('fabric-shim');
+const { AssetContract } = require('..');
+const winston = require('winston');
+
+const chai = require('chai');
+const chaiAsPromised = require('chai-as-promised');
+const sinon = require('sinon');
+const sinonChai = require('sinon-chai');
+
+chai.should();
+chai.use(chaiAsPromised);
+chai.use(sinonChai);
+
+class TestContext {
+
+ constructor() {
+ this.stub = sinon.createStubInstance(ChaincodeStub);
+ this.clientIdentity = sinon.createStubInstance(ClientIdentity);
+ this.logger = {
+ getLogger: sinon.stub().returns(sinon.createStubInstance(winston.createLogger().constructor)),
+ setLevel: sinon.stub(),
+ };
+ }
+
+}
+
+describe('AssetContract', () => {
+
+ let contract;
+ let ctx;
+
+ beforeEach(() => {
+ contract = new AssetContract();
+ ctx = new TestContext();
+ ctx.stub.getState.withArgs('1001').resolves(Buffer.from('{"value":"asset 1001 value"}'));
+ ctx.stub.getState.withArgs('1002').resolves(Buffer.from('{"value":"asset 1002 value"}'));
+ });
+
+ describe('#assetExists', () => {
+
+ it('should return true for a asset', async () => {
+ await contract.assetExists(ctx, '1001').should.eventually.be.true;
+ });
+
+ it('should return false for a asset that does not exist', async () => {
+ await contract.assetExists(ctx, '1003').should.eventually.be.false;
+ });
+
+ });
+
+ describe('#createAsset', () => {
+
+ it('should create a asset', async () => {
+ await contract.createAsset(ctx, '1003', 'asset 1003 value');
+ ctx.stub.putState.should.have.been.calledOnceWithExactly('1003', Buffer.from('{"value":"asset 1003 value"}'));
+ });
+
+ it('should throw an error for a asset that already exists', async () => {
+ await contract.createAsset(ctx, '1001', 'myvalue').should.be.rejectedWith(/The asset 1001 already exists/);
+ });
+
+ });
+
+ describe('#readAsset', () => {
+
+ it('should return a asset', async () => {
+ await contract.readAsset(ctx, '1001').should.eventually.deep.equal({ value: 'asset 1001 value' });
+ });
+
+ it('should throw an error for a asset that does not exist', async () => {
+ await contract.readAsset(ctx, '1003').should.be.rejectedWith(/The asset 1003 does not exist/);
+ });
+
+ });
+
+ describe('#updateAsset', () => {
+
+ it('should update a asset', async () => {
+ await contract.updateAsset(ctx, '1001', 'asset 1001 new value');
+ ctx.stub.putState.should.have.been.calledOnceWithExactly('1001', Buffer.from('{"value":"asset 1001 new value"}'));
+ });
+
+ it('should throw an error for a asset that does not exist', async () => {
+ await contract.updateAsset(ctx, '1003', 'asset 1003 new value').should.be.rejectedWith(/The asset 1003 does not exist/);
+ });
+
+ });
+
+ describe('#deleteAsset', () => {
+
+ it('should delete a asset', async () => {
+ await contract.deleteAsset(ctx, '1001');
+ ctx.stub.deleteState.should.have.been.calledOnceWithExactly('1001');
+ });
+
+ it('should throw an error for a asset that does not exist', async () => {
+ await contract.deleteAsset(ctx, '1003').should.be.rejectedWith(/The asset 1003 does not exist/);
+ });
+
+ });
+
+});
diff --git a/asset-transfer-sbe/chaincode-javascript/transaction_data/asset-transactions.txdata b/asset-transfer-sbe/chaincode-javascript/transaction_data/asset-transactions.txdata
new file mode 100644
index 00000000..79e48107
--- /dev/null
+++ b/asset-transfer-sbe/chaincode-javascript/transaction_data/asset-transactions.txdata
@@ -0,0 +1,44 @@
+[
+ {
+ "transactionName": "assetExists",
+ "transactionLabel": "A test assetExists transaction",
+ "arguments": [
+ "001"
+ ],
+ "transientData": {}
+ },
+ {
+ "transactionName": "createAsset",
+ "transactionLabel": "A test createAsset transaction",
+ "arguments": [
+ "001",
+ "some value"
+ ],
+ "transientData": {}
+ },
+ {
+ "transactionName": "readAsset",
+ "transactionLabel": "A test readAsset transaction",
+ "arguments": [
+ "001"
+ ],
+ "transientData": {}
+ },
+ {
+ "transactionName": "updateAsset",
+ "transactionLabel": "A test updateAsset transaction",
+ "arguments": [
+ "001",
+ "some other value"
+ ],
+ "transientData": {}
+ },
+ {
+ "transactionName": "deleteAsset",
+ "transactionLabel": "A test deleteAsset transaction",
+ "arguments": [
+ "001"
+ ],
+ "transientData": {}
+ }
+]
diff --git a/commercial-paper/organization/magnetocorp/application-java/.classpath b/commercial-paper/organization/magnetocorp/application-java/.classpath
new file mode 100644
index 00000000..c0837943
--- /dev/null
+++ b/commercial-paper/organization/magnetocorp/application-java/.classpath
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/commercial-paper/organization/magnetocorp/application-java/.settings/org.eclipse.jdt.apt.core.prefs b/commercial-paper/organization/magnetocorp/application-java/.settings/org.eclipse.jdt.apt.core.prefs
new file mode 100644
index 00000000..d4313d4b
--- /dev/null
+++ b/commercial-paper/organization/magnetocorp/application-java/.settings/org.eclipse.jdt.apt.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.apt.aptEnabled=false
diff --git a/commercial-paper/organization/magnetocorp/contract-java/.classpath b/commercial-paper/organization/magnetocorp/contract-java/.classpath
new file mode 100644
index 00000000..4857be40
--- /dev/null
+++ b/commercial-paper/organization/magnetocorp/contract-java/.classpath
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/commercial-paper/organization/magnetocorp/contract-java/.settings/org.eclipse.jdt.core.prefs b/commercial-paper/organization/magnetocorp/contract-java/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000..35068d95
--- /dev/null
+++ b/commercial-paper/organization/magnetocorp/contract-java/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,4 @@
+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
diff --git a/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/CommercialPaper.class b/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/CommercialPaper.class
new file mode 100644
index 00000000..41b49dff
Binary files /dev/null and b/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/CommercialPaper.class differ
diff --git a/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/CommercialPaperContext.class b/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/CommercialPaperContext.class
new file mode 100644
index 00000000..34b318f7
Binary files /dev/null and b/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/CommercialPaperContext.class differ
diff --git a/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/CommercialPaperContract.class b/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/CommercialPaperContract.class
new file mode 100644
index 00000000..e857e224
Binary files /dev/null and b/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/CommercialPaperContract.class differ
diff --git a/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/PaperList.class b/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/PaperList.class
new file mode 100644
index 00000000..a4ce9885
Binary files /dev/null and b/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/PaperList.class differ
diff --git a/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/ledgerapi/State.class b/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/ledgerapi/State.class
new file mode 100644
index 00000000..e318ab7c
Binary files /dev/null and b/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/ledgerapi/State.class differ
diff --git a/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/ledgerapi/StateDeserializer.class b/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/ledgerapi/StateDeserializer.class
new file mode 100644
index 00000000..e65b7287
Binary files /dev/null and b/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/ledgerapi/StateDeserializer.class differ
diff --git a/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/ledgerapi/StateList.class b/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/ledgerapi/StateList.class
new file mode 100644
index 00000000..80b9a857
Binary files /dev/null and b/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/ledgerapi/StateList.class differ
diff --git a/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/ledgerapi/impl/StateListImpl.class b/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/ledgerapi/impl/StateListImpl.class
new file mode 100644
index 00000000..cbbe8555
Binary files /dev/null and b/commercial-paper/organization/magnetocorp/contract-java/bin/main/org/example/ledgerapi/impl/StateListImpl.class differ