fabric-samples/asset-transfer-sbe/chaincode-javascript/lib/asset-contract.js
Francesco Vlacancich f95fbbe3d0 final draft for JSON determinm task, using Genson instead of object mapper
Remore extra .class files

Signed-off-by: fraVlaca <ocsenarf@outlook.com>
2021-09-01 13:37:27 +01:00

149 lines
6.2 KiB
JavaScript

/*
* 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;