From 8c9fd980b9740d077fb3033ef85eff704277e355 Mon Sep 17 00:00:00 2001 From: Sijo Cherian Date: Thu, 19 Nov 2020 10:37:49 -0500 Subject: [PATCH] go chaincode now sets the Asset owner as client identity certificate string (instead of base64 str) go chaincode now sets the Asset owner as client identity certificate string (instead of base64 str) Reason for the update: "GetClientIdentity().GetID()" api in go chaincode returns base64 string, while same api in java chaincode returns the same data as string go & java chaincode sets same owner string updated js app verify method Signed-off-by: Sijo Cherian --- .../application-javascript/app.js | 18 ++++++------ .../chaincode-go/README.md | 2 +- .../chaincode-go/chaincode/asset_transfer.go | 28 ++++++++++++++----- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/asset-transfer-private-data/application-javascript/app.js b/asset-transfer-private-data/application-javascript/app.js index 0c861514..77ac59fa 100644 --- a/asset-transfer-private-data/application-javascript/app.js +++ b/asset-transfer-private-data/application-javascript/app.js @@ -22,8 +22,6 @@ const mspOrg1 = 'Org1MSP'; const mspOrg2 = 'Org2MSP'; const Org1UserId = 'appUser1'; const Org2UserId = 'appUser2'; -const userOrg1IdentityString = `x509::CN=${Org1UserId},OU=client+OU=org1+OU=department1::CN=ca.org1.example.com,O=org1.example.com,L=Durham,ST=North Carolina,C=US`; -const userOrg2IdentityString = `x509::CN=${Org2UserId},OU=client+OU=org2+OU=department1::CN=ca.org2.example.com,O=org2.example.com,L=Hursley,ST=Hampshire,C=UK`; const RED = '\x1b[31m\n'; const RESET = '\x1b[0m'; @@ -42,7 +40,7 @@ function doFail(msgString) { process.exit(1); } -function verifyAssetData(org, resultBuffer, expectedId, color, size, owner, appraisedValue) { +function verifyAssetData(org, resultBuffer, expectedId, color, size, ownerUserId, appraisedValue) { let asset; if (resultBuffer) { @@ -63,11 +61,11 @@ function verifyAssetData(org, resultBuffer, expectedId, color, size, owner, appr if (asset.size !== size) { doFail(`Failed size check - asset ${asset.assetID} has size of ${asset.size}, expected value ${size}`); } - let assetsOwner = Buffer.from(asset.owner, 'base64').toString(); - if (assetsOwner === owner) { - console.log(`\tasset ${asset.assetID} owner: ${assetsOwner}`); + + if (asset.owner.includes(ownerUserId)) { + console.log(`\tasset ${asset.assetID} owner: ${asset.owner}`); } else { - doFail(`Failed owner check from ${org} - asset ${asset.assetID} owned by ${assetsOwner}, expected value ${owner}`); + doFail(`Failed owner check from ${org} - asset ${asset.assetID} owned by ${asset.owner}, expected userId ${ownerUserId}`); } if (appraisedValue) { if (asset.appraisedValue !== appraisedValue) { @@ -243,7 +241,7 @@ async function main() { console.log('\n--> Evaluate Transaction: ReadAsset ' + assetID1); result = await contractOrg2.evaluateTransaction('ReadAsset', assetID1); console.log(`<-- result: ${prettyJSONString(result.toString())}`); - verifyAssetData(mspOrg2, result, assetID1, 'green', 20, userOrg1IdentityString); + verifyAssetData(mspOrg2, result, assetID1, 'green', 20, Org1UserId); // Org2 cannot ReadAssetPrivateDetails from Org1's private collection due to Collection policy @@ -291,7 +289,7 @@ async function main() { console.log('\n--> Evaluate Transaction: ReadAsset ' + assetID1); result = await contractOrg1.evaluateTransaction('ReadAsset', assetID1); console.log(`<-- result: ${prettyJSONString(result.toString())}`); - verifyAssetData(mspOrg1, result, assetID1, 'green', 20, userOrg2IdentityString); + verifyAssetData(mspOrg1, result, assetID1, 'green', 20, Org2UserId); //Confirm that transfer removed the private details from the Org1 collection: console.log('\n--> Evaluate Transaction: ReadAssetPrivateDetails'); @@ -304,7 +302,7 @@ async function main() { console.log('\n--> Evaluate Transaction: ReadAsset ' + assetID2); result = await contractOrg1.evaluateTransaction('ReadAsset', assetID2); console.log(`<-- result: ${prettyJSONString(result.toString())}`); - verifyAssetData(mspOrg1, result, assetID2, 'blue', 35, userOrg1IdentityString); + verifyAssetData(mspOrg1, result, assetID2, 'blue', 35, Org1UserId); console.log('\n********* Demo deleting asset **************'); let dataForDelete = { assetID: assetID2 }; diff --git a/asset-transfer-private-data/chaincode-go/README.md b/asset-transfer-private-data/chaincode-go/README.md index de65bbf4..f87a95c6 100644 --- a/asset-transfer-private-data/chaincode-go/README.md +++ b/asset-transfer-private-data/chaincode-go/README.md @@ -1 +1 @@ -[Using Private Data tutorial](https://hyperledger-fabric.readthedocs.io/en/latest/private_data_tutorial.html) \ No newline at end of file +[Using Private Data tutorial](https://hyperledger-fabric.readthedocs.io/en/latest/private_data_tutorial.html) diff --git a/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer.go b/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer.go index 2e7c197c..59eae2ae 100644 --- a/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer.go +++ b/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer.go @@ -8,6 +8,7 @@ package chaincode import ( "bytes" + "encoding/base64" "encoding/json" "fmt" "log" @@ -102,9 +103,9 @@ func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface) } // Get ID of submitting client identity - clientID, err := ctx.GetClientIdentity().GetID() + clientID, err := submittingClientIdentity(ctx) if err != nil { - return fmt.Errorf("failed to get verified OrgID: %v", err) + return err } // Verify that the client is submitting request to peer in their organization @@ -131,7 +132,8 @@ func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface) // Save asset to private data collection // Typical logger, logs to stdout/file in the fabric managed docker container, running this chaincode // Look for container name like dev-peer0.org1.example.com-{chaincodename_version}-xyz - log.Printf("CreateAsset Put: collection %v, ID %v", assetCollection, assetInput.ID) + log.Printf("CreateAsset Put: collection %v, ID %v, owner %v", assetCollection, assetInput.ID, clientID) + err = ctx.GetStub().PutPrivateData(assetCollection, assetInput.ID, assetJSONasBytes) if err != nil { return fmt.Errorf("failed to put asset into private data collecton: %v", err) @@ -170,9 +172,9 @@ func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface) func (s *SmartContract) AgreeToTransfer(ctx contractapi.TransactionContextInterface) error { // Get ID of submitting client identity - clientID, err := ctx.GetClientIdentity().GetID() + clientID, err := submittingClientIdentity(ctx) if err != nil { - return fmt.Errorf("failed to get verified OrgID: %v", err) + return err } // Value is private, therefore it gets passed in transient field @@ -355,9 +357,9 @@ func (s *SmartContract) verifyAgreement(ctx contractapi.TransactionContextInterf // Check 1: verify that the transfer is being initiatied by the owner // Get ID of submitting client identity - clientID, err := ctx.GetClientIdentity().GetID() + clientID, err := submittingClientIdentity(ctx) if err != nil { - return fmt.Errorf("failed to get verified OrgID: %v", err) + return err } if clientID != owner { @@ -574,3 +576,15 @@ func verifyClientOrgMatchesPeerOrg(ctx contractapi.TransactionContextInterface) return nil } + +func submittingClientIdentity(ctx contractapi.TransactionContextInterface) (string, error) { + b64ID, err := ctx.GetClientIdentity().GetID() + if err != nil { + return "", fmt.Errorf("Failed to read clientID: %v", err) + } + decodeID, err := base64.StdEncoding.DecodeString(b64ID) + if err != nil { + return "", fmt.Errorf("failed to base64 decode clientID: %v", err) + } + return string(decodeID), nil +}