From d9f2e947759532ca8c40837f0ddf520af40b1942 Mon Sep 17 00:00:00 2001 From: sapthasurendran Date: Fri, 20 May 2022 15:31:23 +0530 Subject: [PATCH] contract wrapper refactor moved interfaces from utils to contract wrapper Signed-off-by: sapthasurendran --- .../application-gateway-typescript/src/app.ts | 42 ++--- .../src/contractWrapper.ts | 153 +++++++++++------- .../src/utils.ts | 44 ----- 3 files changed, 120 insertions(+), 119 deletions(-) diff --git a/asset-transfer-secured-agreement/application-gateway-typescript/src/app.ts b/asset-transfer-secured-agreement/application-gateway-typescript/src/app.ts index 3aa35db1..70ed7383 100644 --- a/asset-transfer-secured-agreement/application-gateway-typescript/src/app.ts +++ b/asset-transfer-secured-agreement/application-gateway-typescript/src/app.ts @@ -57,9 +57,9 @@ async function main(): Promise { const contractWrapperOrg2 = new ContractWrapper(contractOrg2, mspIdOrg2); // Create an asset by organization Org1, this only requires the owning organization to endorse. - await contractWrapperOrg1.createAsset({ AssetId: assetKey, - OwnerOrg: mspIdOrg1, - PublicDescription: `Asset ${assetKey} owned by ${mspIdOrg1} is not for sale`}, { ObjectType: 'asset_properties', Color: 'blue', Size: 35 }); + await contractWrapperOrg1.createAsset({ assetId: assetKey, + ownerOrg: mspIdOrg1, + publicDescription: `Asset ${assetKey} owned by ${mspIdOrg1} is not for sale`}, { ObjectType: 'asset_properties', Color: 'blue', Size: 35 }); // Read the public details by org1. await contractWrapperOrg1.readAsset(assetKey, mspIdOrg1); @@ -78,9 +78,9 @@ async function main(): Promise { } // Org1 updates the assets public description. - await contractWrapperOrg1.changePublicDescription({AssetId: assetKey, - OwnerOrg: mspIdOrg1, - PublicDescription: `Asset ${assetKey} owned by ${mspIdOrg1} is for sale`}); + await contractWrapperOrg1.changePublicDescription({assetId: assetKey, + ownerOrg: mspIdOrg1, + publicDescription: `Asset ${assetKey} owned by ${mspIdOrg1} is for sale`}); // Read the public details by org1. await contractWrapperOrg1.readAsset(assetKey, mspIdOrg1); @@ -91,9 +91,9 @@ async function main(): Promise { // This is an update to the public state and requires the owner(Org1) to endorse and sent by the owner org client (Org1). // Since the client is from Org2, which is not the owner, this will fail. try{ - await contractWrapperOrg2.changePublicDescription({AssetId: assetKey, - OwnerOrg: mspIdOrg1, - PublicDescription: `Asset ${assetKey} owned by ${mspIdOrg2} is NOT for sale`}); + await contractWrapperOrg2.changePublicDescription({assetId: assetKey, + ownerOrg: mspIdOrg1, + publicDescription: `Asset ${assetKey} owned by ${mspIdOrg2} is NOT for sale`}); } catch(e) { console.log(`${RED}*** Failed: changePublicDescription - ${e}${RESET}`); } @@ -106,19 +106,19 @@ async function main(): Promise { // Agree to a sell by org1. await contractWrapperOrg1.agreeToSell({ - AssetId: assetKey, - Price: 110, - TradeId: now, + assetId: assetKey, + price: 110, + tradeId: now, }); // Check the private information about the asset from Org2. Org1 would have to send Org2 asset details, // so the hash of the details may be checked by the chaincode. - await contractWrapperOrg2.verifyAssetProperties({ AssetId:assetKey, Color:'blue', Size:35}); + await contractWrapperOrg2.verifyAssetProperties({ assetId:assetKey, color:'blue', size:35}); // Agree to a buy by org2. - await contractWrapperOrg2.agreeToBuy( {AssetId: assetKey, - Price: 100, - TradeId: now}); + await contractWrapperOrg2.agreeToBuy( {assetId: assetKey, + price: 100, + tradeId: now}); // Org1 should be able to read the sale price of this asset. await contractWrapperOrg1.getAssetSalesPrice(assetKey, mspIdOrg1); @@ -142,12 +142,12 @@ async function main(): Promise { // Org1 will try to transfer the asset to Org2 // This will fail due to the sell price and the bid price are not the same. try{ - await contractWrapperOrg1.transferAsset({ObjectType: 'asset_properties', Color: 'blue', Size: 35}, { AssetId: assetKey, Price: 110, TradeId: now}, [ mspIdOrg1, mspIdOrg2 ], mspIdOrg1, mspIdOrg2); + await contractWrapperOrg1.transferAsset({ObjectType: 'asset_properties', Color: 'blue', Size: 35}, { assetId: assetKey, price: 110, tradeId: now}, [ mspIdOrg1, mspIdOrg2 ], mspIdOrg1, mspIdOrg2); } catch(e) { console.log(`${RED}*** Failed: transferAsset - ${e}${RESET}`); } // Agree to a sell by Org1, the seller will agree to the bid price of Org2. - await contractWrapperOrg1.agreeToSell({AssetId:assetKey, Price:100, TradeId:now}); + await contractWrapperOrg1.agreeToSell({assetId:assetKey, price:100, tradeId:now}); // Read the public details by org1. await contractWrapperOrg1.readAsset(assetKey, mspIdOrg1); @@ -167,14 +167,14 @@ async function main(): Promise { // Org2 user will try to transfer the asset to Org1. // This will fail as the owner is Org1. try{ - await contractWrapperOrg2.transferAsset({ObjectType: 'asset_properties', Color: 'blue', Size: 35}, { AssetId: assetKey, Price: 100, TradeId: now}, [ mspIdOrg1, mspIdOrg2 ], mspIdOrg1, mspIdOrg2); + await contractWrapperOrg2.transferAsset({ObjectType: 'asset_properties', Color: 'blue', Size: 35}, { assetId: assetKey, price: 100, tradeId: now}, [ mspIdOrg1, mspIdOrg2 ], mspIdOrg1, mspIdOrg2); } catch(e) { console.log(`${RED}*** Failed: transferAsset - ${e}${RESET}`); } // Org1 will transfer the asset to Org2. // This will now complete as the sell price and the bid price are the same. - await contractWrapperOrg1.transferAsset({ObjectType: 'asset_properties', Color: 'blue', Size: 35}, { AssetId: assetKey, Price: 100, TradeId: now}, [ mspIdOrg1, mspIdOrg2 ], mspIdOrg1, mspIdOrg2); + await contractWrapperOrg1.transferAsset({ObjectType: 'asset_properties', Color: 'blue', Size: 35}, { assetId: assetKey, price: 100, tradeId: now}, [ mspIdOrg1, mspIdOrg2 ], mspIdOrg1, mspIdOrg2); // Read the public details by org1. await contractWrapperOrg1.readAsset(assetKey, mspIdOrg2); @@ -194,7 +194,7 @@ async function main(): Promise { // This is an update to the public state and requires only the owner to endorse. // Org2 wants to indicate that the items is no longer for sale. - await contractWrapperOrg2.changePublicDescription( {AssetId: assetKey, OwnerOrg: mspIdOrg2, PublicDescription: `Asset ${assetKey} owned by ${mspIdOrg2} is NOT for sale`}); + await contractWrapperOrg2.changePublicDescription( {assetId: assetKey, ownerOrg: mspIdOrg2, publicDescription: `Asset ${assetKey} owned by ${mspIdOrg2} is NOT for sale`}); // Read the public details by org1. await contractWrapperOrg1.readAsset(assetKey, mspIdOrg2); diff --git a/asset-transfer-secured-agreement/application-gateway-typescript/src/contractWrapper.ts b/asset-transfer-secured-agreement/application-gateway-typescript/src/contractWrapper.ts index 004e0812..b27ab417 100644 --- a/asset-transfer-secured-agreement/application-gateway-typescript/src/contractWrapper.ts +++ b/asset-transfer-secured-agreement/application-gateway-typescript/src/contractWrapper.ts @@ -5,11 +5,56 @@ */ import { Contract } from '@hyperledger/fabric-gateway'; import { TextDecoder } from 'util'; -import { Asset, AssetJSON, AssetPrice, AssetPriceJSON, AssetPrivateData, AssetProperties, AssetPropertiesJSON, GREEN, parse, RED, RESET } from './utils'; +import { GREEN, parse, RED, RESET } from './utils'; import crpto from 'crypto'; const randomBytes = crpto.randomBytes(256).toString('hex'); +interface AssetJSON { + objectType: string; + assetID: string; + ownerOrg: string; + publicDescription: string; +} + +interface AssetPropertiesJSON { + objectType: string; + assetID: string; + color: string; + size: number; + salt: string; +} + +interface AssetPriceJSON { + assetID: string; + price: number; + tradeID: string; +} + +interface AssetPrivateData { + ObjectType: string; + Color: string; + Size: number; +} + +interface Asset { + assetId: string; + ownerOrg: string; + publicDescription: string; +} + +interface AssetProperties { + assetId: string; + color: string; + size: number; +} + +interface AssetPrice { + assetId: string; + price: number; + tradeId: string; +} + export class ContractWrapper { readonly #contract: Contract; @@ -23,24 +68,24 @@ export class ContractWrapper { } public async createAsset(asset: Asset, privateData: AssetPrivateData): Promise { - console.log(`${GREEN}--> Submit Transaction: CreateAsset, ${asset.AssetId} as ${asset.OwnerOrg} - endorsed by Org1${RESET}`); + console.log(`${GREEN}--> Submit Transaction: CreateAsset, ${asset.assetId} as ${asset.ownerOrg} - endorsed by Org1.${RESET}`); const assetPropertiesJSON: AssetPropertiesJSON = { objectType: 'asset_properties', - assetID: asset.AssetId, + assetID: asset.assetId, color: privateData.Color, size: privateData.Size, salt: this.#randomBytes }; await this.#contract.submit('CreateAsset', { - arguments: [asset.AssetId, asset.PublicDescription], + arguments: [asset.assetId, asset.publicDescription], transientData: { asset_properties: JSON.stringify(assetPropertiesJSON)}, }); - console.log(`*** Result: committed, asset ${asset.AssetId} is owned by Org1`); + console.log(`*** Result: committed, asset ${asset.assetId} is owned by Org1`); } public async readAsset(assetKey: string, ownerOrg: string): Promise { - console.log(`${GREEN}--> Evaluate Transactions: ReadAsset as ${this.#org}, - ${assetKey} should be owned by ${ownerOrg}${RESET}`); + console.log(`${GREEN}--> Evaluate Transactions: ReadAsset as ${this.#org}, - ${assetKey} should be owned by ${ownerOrg}.${RESET}`); const resultBytes = await this.#contract.evaluateTransaction('ReadAsset', assetKey); @@ -50,7 +95,7 @@ export class ContractWrapper { if (json.ownerOrg === ownerOrg) { console.log(`*** Result from ${this.#org} - asset ${json.assetID} owned by ${json.ownerOrg} DESC: ${json.publicDescription}`); } else { - console.log(`${RED}*** Failed owner check from ${this.#org} - asset ${json.assetID} owned by ${json.ownerOrg} DESC:${json.publicDescription}${RESET}`); + console.log(`${RED}*** Failed owner check from ${this.#org} - asset ${json.assetID} owned by ${json.ownerOrg} DESC:${json.publicDescription}.${RESET}`); } } else { throw new Error('No Asset Found'); @@ -58,7 +103,7 @@ export class ContractWrapper { } public async getAssetPrivateProperties(assetKey: string, ownerOrg: string): Promise { - console.log(`${GREEN}--> Evaluate Transaction: GetAssetPrivateProperties, - ${assetKey} from organization ${this.#org}${RESET}`); + console.log(`${GREEN}--> Evaluate Transaction: GetAssetPrivateProperties, - ${assetKey} from organization ${this.#org}.${RESET}`); if(this.#org !== ownerOrg) { console.log(`${GREEN}* Expected to fail as ${this.#org} is not the owner and does not have the private details.${RESET}`); } @@ -68,51 +113,51 @@ export class ContractWrapper { const resultString = this.#utf8Decoder.decode(resultBytes); const json = parse(resultString); const result: AssetProperties = { - AssetId: json.assetID, - Color: json.color, - Size: json.size, + assetId: json.assetID, + color: json.color, + size: json.size, }; console.log('*** Result:', result); } public async changePublicDescription(asset: Asset): Promise { - console.log(`${GREEN}--> Submit Transaction: ChangePublicDescription ${asset.AssetId}, as ${this.#org} - endorse by ${this.#org} ${RESET}`); - if (asset.OwnerOrg !== this.#org) { + console.log(`${GREEN}--> Submit Transaction: ChangePublicDescription ${asset.assetId}, as ${this.#org} - endorse by ${this.#org}.${RESET}`); + if (asset.ownerOrg !== this.#org) { console.log(`${GREEN}* Expected to fail as ${this.#org} is not the owner.${RESET}`); } await this.#contract.submit('ChangePublicDescription', { - arguments:[asset.AssetId, asset.PublicDescription], + arguments:[asset.assetId, asset.publicDescription], }); - console.log(`*** Result: committed, Desc: ${asset.PublicDescription}`); + console.log(`*** Result: committed, Desc: ${asset.publicDescription}`); } public async agreeToSell(assetPrice: AssetPrice): Promise { - console.log(`${GREEN}--> Submit Transaction: AgreeToSell, ${assetPrice.AssetId} as ${this.#org} - endorsed by ${this.#org}${RESET}`); + console.log(`${GREEN}--> Submit Transaction: AgreeToSell, ${assetPrice.assetId} as ${this.#org} - endorsed by ${this.#org}.${RESET}`); const assetPriceJSON: AssetPriceJSON = { - assetID:assetPrice.AssetId, - price:assetPrice.Price, - tradeID:assetPrice.TradeId + assetID:assetPrice.assetId, + price:assetPrice.price, + tradeID:assetPrice.tradeId }; await this.#contract.submit('AgreeToSell', { - arguments:[assetPrice.AssetId], + arguments:[assetPrice.assetId], transientData: {asset_price: JSON.stringify(assetPriceJSON)} }); - console.log(`*** Result: committed, ${this.#org} has agreed to sell asset ${assetPrice.AssetId} for ${assetPrice.Price}`); + console.log(`*** Result: committed, ${this.#org} has agreed to sell asset ${assetPrice.assetId} for ${assetPrice.price}`); } public async verifyAssetProperties(assetProperties: AssetProperties): Promise { - console.log(`${GREEN}--> Evalute: VerifyAssetProperties, ${assetProperties.AssetId} as ${this.#org} - endorsed by ${this.#org}${RESET}`); - const assetPropertiesJSON: AssetPropertiesJSON = Object.assign({}, {objectType: 'asset_properties', - assetID: assetProperties.AssetId, - color: assetProperties.Color, - size: assetProperties.Size, - salt: this.#randomBytes }); + console.log(`${GREEN}--> Evalute: VerifyAssetProperties, ${assetProperties.assetId} as ${this.#org} - endorsed by ${this.#org}.${RESET}`); + const assetPropertiesJSON: AssetPropertiesJSON = {objectType: 'asset_properties', + assetID: assetProperties.assetId, + color: assetProperties.color, + size: assetProperties.size, + salt: this.#randomBytes }; const resultBytes = await this.#contract.evaluate('VerifyAssetProperties', { arguments:[assetPropertiesJSON.assetID], @@ -123,42 +168,42 @@ export class ContractWrapper { if (resultString.length !== 0) { const json = parse(resultString); const result: AssetProperties = { - AssetId: json.assetID, - Color: json.color, - Size: json.size + assetId: json.assetID, + color: json.color, + size: json.size }; if (result) { - console.log(`*** Success VerifyAssetProperties, private information about asset ${assetProperties.AssetId} has been verified by ${this.#org}`); + console.log(`*** Success VerifyAssetProperties, private information about asset ${assetProperties.assetId} has been verified by ${this.#org}`); } else { - console.log(`*** Failed: VerifyAssetProperties, private information about asset ${assetProperties.AssetId} has not been verified by ${this.#org}`); + console.log(`*** Failed: VerifyAssetProperties, private information about asset ${assetProperties.assetId} has not been verified by ${this.#org}`); } } else { - throw new Error(`Private information about asset ${assetProperties.AssetId} has not been verified by ${this.#org}`); + throw new Error(`Private information about asset ${assetProperties.assetId} has not been verified by ${this.#org}`); } } public async agreeToBuy(assetPrice: AssetPrice, ): Promise { - console.log(`${GREEN}--> Submit Transaction: AgreeToBuy, ${assetPrice.AssetId} as ${this.#org} - endorsed by ${this.#org}${RESET}`); + console.log(`${GREEN}--> Submit Transaction: AgreeToBuy, ${assetPrice.assetId} as ${this.#org} - endorsed by ${this.#org}.${RESET}`); const assetPriceJSON: AssetPriceJSON = { - assetID: assetPrice.AssetId, - price: assetPrice.Price, - tradeID: assetPrice.TradeId + assetID: assetPrice.assetId, + price: assetPrice.price, + tradeID: assetPrice.tradeId }; await this.#contract.submit('AgreeToBuy', { - arguments:[assetPrice.AssetId], + arguments:[assetPrice.assetId], transientData: {asset_price: JSON.stringify(assetPriceJSON)} }); - console.log(`*** Result: committed, ${this.#org} has agreed to buy asset ${assetPrice.AssetId} for 100`); + console.log(`*** Result: committed, ${this.#org} has agreed to buy asset ${assetPrice.assetId} for 100`); } public async getAssetSalesPrice(assetKey: string, ownerOrg: string): Promise { - console.log(`${GREEN}--> Evaluate Transaction: GetAssetSalesPrice, - ${assetKey} from organization ${this.#org}${RESET}`); + console.log(`${GREEN}--> Evaluate Transaction: GetAssetSalesPrice, - ${assetKey} from organization ${this.#org}.${RESET}`); if(this.#org !== ownerOrg) { console.log(`${GREEN}* Expected to fail as ${this.#org} has not set a sale price.${RESET}`); } @@ -169,9 +214,9 @@ export class ContractWrapper { const json = parse(resultString); const result: AssetPrice = { - AssetId: json.assetID, - Price: json.price, - TradeId: json.tradeID + assetId: json.assetID, + price: json.price, + tradeId: json.tradeID }; console.log('*** Result: GetAssetSalesPrice', result); @@ -179,7 +224,7 @@ export class ContractWrapper { public async getAssetBidPrice(assetKey: string, buyerOrgID: string): Promise { - console.log(`${GREEN}--> Evaluate Transaction: GetAssetBidPrice, - ${assetKey} from organization ${this.#org}${RESET}`); + console.log(`${GREEN}--> Evaluate Transaction: GetAssetBidPrice, - ${assetKey} from organization ${this.#org}.${RESET}`); if(this.#org !== buyerOrgID){ console.log(`${GREEN}* Expected to fail as ${this.#org} has not agreed to buy.${RESET}`); } @@ -189,9 +234,9 @@ export class ContractWrapper { const resultString = this.#utf8Decoder.decode(resultBytes); const json = parse(resultString); const result: AssetPrice = { - AssetId: json.assetID, - Price: json.price, - TradeId: json.tradeID, + assetId: json.assetID, + price: json.price, + tradeId: json.tradeID, }; console.log('*** Result: GetAssetBidPrice', result); @@ -199,21 +244,21 @@ export class ContractWrapper { public async transferAsset( privateData: AssetPrivateData, assetPrice: AssetPrice, endorsingOrganizations: string[], ownerOrgID: string, buyerOrgID: string): Promise { - console.log(`${GREEN}--> Submit Transaction: TransferAsset, ${assetPrice.AssetId} as ${this.#org } - endorsed by ${this.#org}${RESET}`); + console.log(`${GREEN}--> Submit Transaction: TransferAsset, ${assetPrice.assetId} as ${this.#org } - endorsed by ${this.#org}.${RESET}`); if (this.#org !== ownerOrgID) { console.log(`${GREEN}* Expected to fail as the owner is ${ownerOrgID}.${RESET}`); - } else if (assetPrice.Price === 110) { + } else if (assetPrice.price === 110) { console.log(`${GREEN}* Expected to fail as sell price and the bid price are not the same.${RESET}`); } - const assetPropertiesJSON: AssetPropertiesJSON = Object.assign({}, {objectType: 'asset_properties', - assetID: assetPrice.AssetId, + const assetPropertiesJSON: AssetPropertiesJSON = {objectType: 'asset_properties', + assetID: assetPrice.assetId, color: privateData.Color, size: privateData.Size, - salt: this.#randomBytes }); + salt: this.#randomBytes }; - const assetPriceJSON: AssetPriceJSON = { assetID: assetPrice.AssetId, price:assetPrice.Price, tradeID:assetPrice.TradeId}; + const assetPriceJSON: AssetPriceJSON = { assetID: assetPrice.assetId, price:assetPrice.price, tradeID:assetPrice.tradeId}; await this.#contract.submit('TransferAsset', { arguments:[assetPropertiesJSON.assetID, buyerOrgID], @@ -223,6 +268,6 @@ export class ContractWrapper { endorsingOrganizations:endorsingOrganizations }); - console.log(`${GREEN}*** Result: committed, ${this.#org} has transfered the asset ${assetPrice.AssetId} to ${buyerOrgID} ${RESET}`); + console.log(`${GREEN}*** Result: committed, ${this.#org} has transfered the asset ${assetPrice.assetId} to ${buyerOrgID}.${RESET}`); } } \ No newline at end of file diff --git a/asset-transfer-secured-agreement/application-gateway-typescript/src/utils.ts b/asset-transfer-secured-agreement/application-gateway-typescript/src/utils.ts index 73b9ec6a..6ff968fb 100644 --- a/asset-transfer-secured-agreement/application-gateway-typescript/src/utils.ts +++ b/asset-transfer-secured-agreement/application-gateway-typescript/src/utils.ts @@ -8,50 +8,6 @@ export const RED = '\x1b[31m\n'; export const GREEN = '\x1b[32m\n'; export const RESET = '\x1b[0m'; -export interface AssetJSON { - objectType: string; - assetID: string; - ownerOrg: string; - publicDescription: string; -} - -export interface AssetPropertiesJSON { - objectType: string; - assetID: string; - color: string; - size: number; - salt: string; -} - -export interface AssetPriceJSON { - assetID: string; - price: number; - tradeID: string; -} - -export interface AssetPrivateData { - ObjectType: string; - Color: string; - Size: number; -} -export interface Asset { - AssetId: string; - OwnerOrg: string; - PublicDescription: string; -} - -export interface AssetProperties { - AssetId: string; - Color: string; - Size: number; -} - -export interface AssetPrice { - AssetId: string; - Price: number; - TradeId: string; -} - export function parse(data: string): T { return JSON.parse(data); }