mirror of
https://github.com/hyperledger/fabric-samples.git
synced 2026-06-26 03:25:09 +00:00
Fixed json.Marsal usage per review comments, Improved DeleteAsset validation
Added owner collection check for DeleteAsset chaincode JS app now demos a new expected error on DeleteAsset by a non-owner org Signed-off-by: Sijo Cherian <sijo@ibm.com>
This commit is contained in:
parent
62f0dd391f
commit
d5415f3fd1
2 changed files with 46 additions and 18 deletions
|
|
@ -153,7 +153,21 @@ async function main() {
|
||||||
result = await contractOrg1.evaluateTransaction('ReadAssetPrivateDetails', org1PrivateCollectionName, assetID1);
|
result = await contractOrg1.evaluateTransaction('ReadAssetPrivateDetails', org1PrivateCollectionName, assetID1);
|
||||||
console.log(' result: ' + prettyJSONString(result.toString()));
|
console.log(' result: ' + prettyJSONString(result.toString()));
|
||||||
|
|
||||||
|
// Attempt Transfer the asset to Org2 , without Org2 adding AgreeToTransfer //
|
||||||
|
// Transaction should return an error: "failed transfer verification ..."
|
||||||
|
let buyerDetails = { assetID: assetID1, buyerMSP: mspOrg2 };
|
||||||
|
try {
|
||||||
|
console.log('\n--> Attempt Submit Transaction: TransferAsset ' + assetID1);
|
||||||
|
statefulTxn = contractOrg1.createTransaction('TransferAsset');
|
||||||
|
tmapData = Buffer.from(JSON.stringify(buyerDetails));
|
||||||
|
statefulTxn.setTransient({
|
||||||
|
asset_owner: tmapData
|
||||||
|
});
|
||||||
|
result = await statefulTxn.submit();
|
||||||
|
console.log('******** FAILED: above operation expected to return an error');
|
||||||
|
} catch (error) {
|
||||||
|
console.log(` Successfully caught the error: \n ${error}`);
|
||||||
|
}
|
||||||
console.log('\n~~~~~~~~~~~~~~~~ As Org2 Client ~~~~~~~~~~~~~~~~');
|
console.log('\n~~~~~~~~~~~~~~~~ As Org2 Client ~~~~~~~~~~~~~~~~');
|
||||||
console.log('\n--> Evaluate Transaction: ReadAsset ' + assetID1);
|
console.log('\n--> Evaluate Transaction: ReadAsset ' + assetID1);
|
||||||
result = await contractOrg2.evaluateTransaction('ReadAsset', assetID1);
|
result = await contractOrg2.evaluateTransaction('ReadAsset', assetID1);
|
||||||
|
|
@ -194,7 +208,7 @@ async function main() {
|
||||||
// Transfer the asset to Org2 //
|
// Transfer the asset to Org2 //
|
||||||
// To transfer the asset, the owner needs to pass the MSP ID of new asset owner, and initiate the transfer
|
// To transfer the asset, the owner needs to pass the MSP ID of new asset owner, and initiate the transfer
|
||||||
console.log('\n--> Submit Transaction: TransferAsset ' + assetID1);
|
console.log('\n--> Submit Transaction: TransferAsset ' + assetID1);
|
||||||
let buyerDetails = { assetID: assetID1, buyerMSP: mspOrg2 };
|
|
||||||
statefulTxn = contractOrg1.createTransaction('TransferAsset');
|
statefulTxn = contractOrg1.createTransaction('TransferAsset');
|
||||||
tmapData = Buffer.from(JSON.stringify(buyerDetails));
|
tmapData = Buffer.from(JSON.stringify(buyerDetails));
|
||||||
statefulTxn.setTransient({
|
statefulTxn.setTransient({
|
||||||
|
|
@ -202,7 +216,6 @@ async function main() {
|
||||||
});
|
});
|
||||||
result = await statefulTxn.submit();
|
result = await statefulTxn.submit();
|
||||||
|
|
||||||
|
|
||||||
//Again ReadAsset : results will show that the buyer identity now owns the asset:
|
//Again ReadAsset : results will show that the buyer identity now owns the asset:
|
||||||
console.log('\n--> Evaluate Transaction: ReadAsset ' + assetID1);
|
console.log('\n--> Evaluate Transaction: ReadAsset ' + assetID1);
|
||||||
result = await contractOrg1.evaluateTransaction('ReadAsset', assetID1);
|
result = await contractOrg1.evaluateTransaction('ReadAsset', assetID1);
|
||||||
|
|
@ -221,11 +234,23 @@ async function main() {
|
||||||
console.log(' result: ' + prettyJSONString(result.toString()));
|
console.log(' result: ' + prettyJSONString(result.toString()));
|
||||||
|
|
||||||
console.log('\n********* Demo deleting asset **************');
|
console.log('\n********* Demo deleting asset **************');
|
||||||
// Delete Asset2
|
|
||||||
console.log('--> Submit Transaction: DeleteAsset ' + assetID2);
|
|
||||||
statefulTxn = contractOrg1.createTransaction('DeleteAsset');
|
|
||||||
|
|
||||||
let dataForDelete = { assetID: assetID2 };
|
let dataForDelete = { assetID: assetID2 };
|
||||||
|
try {
|
||||||
|
//Non-owner Org2 should not be able to DeleteAsset. Expect an error from DeleteAsset
|
||||||
|
console.log('--> Attempt Transaction: as Org2 DeleteAsset ' + assetID2);
|
||||||
|
statefulTxn = contractOrg2.createTransaction('DeleteAsset');
|
||||||
|
tmapData = Buffer.from(JSON.stringify(dataForDelete));
|
||||||
|
statefulTxn.setTransient({
|
||||||
|
asset_delete: tmapData
|
||||||
|
});
|
||||||
|
result = await statefulTxn.submit();
|
||||||
|
console.log('******** FAILED : expected to return an error');
|
||||||
|
} catch (error) {
|
||||||
|
console.log(` Successfully caught the error: \n ${error}`);
|
||||||
|
}
|
||||||
|
// Delete Asset2 as Org1
|
||||||
|
console.log('--> Submit Transaction: as Org1 DeleteAsset ' + assetID2);
|
||||||
|
statefulTxn = contractOrg1.createTransaction('DeleteAsset');
|
||||||
tmapData = Buffer.from(JSON.stringify(dataForDelete));
|
tmapData = Buffer.from(JSON.stringify(dataForDelete));
|
||||||
statefulTxn.setTransient({
|
statefulTxn.setTransient({
|
||||||
asset_delete: tmapData
|
asset_delete: tmapData
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,7 @@ func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface)
|
||||||
Size: assetInput.Size,
|
Size: assetInput.Size,
|
||||||
Owner: clientID,
|
Owner: clientID,
|
||||||
}
|
}
|
||||||
assetJSONasBytes, err := json.Marshal(&asset)
|
assetJSONasBytes, err := json.Marshal(asset)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to marshal asset into JSON: %v", err)
|
return fmt.Errorf("failed to marshal asset into JSON: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -143,7 +143,7 @@ func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface)
|
||||||
AppraisedValue: assetInput.AppraisedValue,
|
AppraisedValue: assetInput.AppraisedValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
assetPrivateDetailsAsBytes, err := json.Marshal(&assetPrivateDetails) // marshal asset details to JSON
|
assetPrivateDetailsAsBytes, err := json.Marshal(assetPrivateDetails) // marshal asset details to JSON
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to marshal into JSON: %v", err)
|
return fmt.Errorf("failed to marshal into JSON: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -443,10 +443,18 @@ func (s *SmartContract) DeleteAsset(ctx contractapi.TransactionContextInterface)
|
||||||
return fmt.Errorf("asset not found: %v", assetDeleteInput.ID)
|
return fmt.Errorf("asset not found: %v", assetDeleteInput.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
var assetToDelete Asset
|
ownerCollection, err := getCollectionName(ctx) // Get owners collection
|
||||||
err = json.Unmarshal([]byte(valAsbytes), &assetToDelete)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to unmarshal JSON: %v", err)
|
return fmt.Errorf("failed to infer private collection name for the org: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
//check the asset is in the caller org's private collection
|
||||||
|
valAsbytes, err = ctx.GetStub().GetPrivateData(ownerCollection, assetDeleteInput.ID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to read asset from owner's Collection: %v", err)
|
||||||
|
}
|
||||||
|
if valAsbytes == nil {
|
||||||
|
return fmt.Errorf("asset not found in owner's private Collection %v: %v", ownerCollection, assetDeleteInput.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the asset from state
|
// delete the asset from state
|
||||||
|
|
@ -456,12 +464,7 @@ func (s *SmartContract) DeleteAsset(ctx contractapi.TransactionContextInterface)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, delete private details of asset
|
// Finally, delete private details of asset
|
||||||
ownerCollection, err := getCollectionName(ctx) // Get owners collection
|
err = ctx.GetStub().DelPrivateData(ownerCollection, assetDeleteInput.ID)
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to infer private collection name for the org: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ctx.GetStub().DelPrivateData(ownerCollection, assetDeleteInput.ID) // Delete the asset
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue