My idea to do this was to use the MSPID. So I would get the MSPID of the organisation, if it is the wrong MSPID then it will return an error message and if it is the right MSPID then continue. In my code I only did it in the DeleteAsset function however I would like to do it in the CreateAsset, UpdateAsset, TransferAsset and DeleteAsset functions.
The problem is that when I go to use the CreateAsset function on the command line it gives me this error:
peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n basic -c '{"function":"CreateAsset","Args":["Asset1","Andrew Faure","20","None","O+", "Penicilin", "None", "Family Doctor", "Fractured Leg", "10/05/2022"]}' Error: endorsement failure during invoke. response: status:500 message:"error in simulation: failed to execute transaction 9446e0c320832b92f06ea56f577a29e9a5ec94c276329cb1d31bb8a85581138d: could not launch chaincode basic_1.0:605aa3a69a8107c9c7b5fc22072554235d3ea827b0eefbffae29f0c9998bf0e6: chaincode registration failed: container exited with 2"
Without the MSPID the system works fine. However, I need the MSPID in order to create access rights to organisations.
I'm new to Hyperledger and Go lang. Would really appreciate it if anyone can help
package chaincode
import (
"encoding/json"
"fmt"
"github.com/hyperledger/fabric-chaincode-go/pkg/cid"
"github.com/hyperledger/fabric-chaincode-go/shim"
"github.com/hyperledger/fabric-contract-api-go/contractapi"
)
// SmartContract provides functions for managing an Asset
type SmartContract struct {
contractapi.Contract
}
type Asset struct {
ID string `json:"ID"`
Owner string `json:"Owner"`
Age int `json:"Age"`
MedicalFamilyHistory string `json:"MedicalFamilyHistory"`
BloodType string `json:"BloodType"`
Allergies string `json:"Allergies"`
Medication string `json:"Medication"`
DataSharedWith string `json:"DataSharedWith"`
CurrentIssue string `json:"CurrentIssue"`
Date string `json:"Date"`
}
func (s *SmartContract) CreateAsset(ctx contractapi.TransactionContextInterface, id
string, owner string, age int, medicalFamilyHistory string, bloodType string,
allergies string, medication string, dataSharedWith string, currentIssue
string, date string) error {
exists, err := s.AssetExists(ctx, id)
if err != nil {
return err
}
if exists {
return fmt.Errorf("the asset %s already exists", id)
}
asset := Asset{
ID: id,
Owner: owner,
Age: age,
MedicalFamilyHistory: medicalFamilyHistory,
BloodType: bloodType,
Allergies: allergies,
Medication: medication,
DataSharedWith: dataSharedWith,
CurrentIssue: currentIssue,
Date: date,
}
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}
return ctx.GetStub().PutState(id, assetJSON)
}
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
}
func (s *SmartContract) UpdateAsset(ctx contractapi.TransactionContextInterface, id
string, owner string, age int, medicalFamilyHistory string, bloodType string,
allergies string, medication string, dataSharedWith string, currentIssue string, date
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)
}
// overwriting original asset with new asset
asset := Asset{
ID: id,
Owner: owner,
Age: age,
MedicalFamilyHistory: medicalFamilyHistory,
BloodType: bloodType,
Allergies: allergies,
Medication: medication,
DataSharedWith: dataSharedWith,
CurrentIssue: currentIssue,
Date: date,
}
assetJSON, err := json.Marshal(asset)
if err != nil {
return err
}
return ctx.GetStub().PutState(id, assetJSON)
}
func (s *SmartContract) DeleteAsset(ctx contractapi.TransactionContextInterface, stub
shim.ChaincodeStubInterface, id string) error {
msp, err := s.GetMSPID(stub)
if err != nil {
return err
}
// The error is with "Org1MSP" becuase I found out that mspid is Org1MSP
if msp != "org1MSP" {
return fmt.Errorf("Wrong Organisation, this organisation does not have access
to this function")
}
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)
}
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
}
func (s *SmartContract) TransferAsset(ctx contractapi.TransactionContextInterface, id
string, newOwner string) (string, error) {
asset, err := s.ReadAsset(ctx, id)
if err != nil {
return "", err
}
oldOwner := asset.Owner
asset.Owner = newOwner
assetJSON, err := json.Marshal(asset)
if err != nil {
return "", err
}
err = ctx.GetStub().PutState(id, assetJSON)
if err != nil {
return "", err
}
return oldOwner, nil
}
func (s *SmartContract) GetAllAssets(ctx contractapi.TransactionContextInterface)
([]*Asset, error) {
// range query with empty string for startKey and endKey does an
// open-ended query of all assets in the chaincode namespace.
resultsIterator, err := ctx.GetStub().GetStateByRange("", "")
if err != nil {
return nil, err
}
defer resultsIterator.Close()
var assets []*Asset
for resultsIterator.HasNext() {
queryResponse, err := resultsIterator.Next()
if err != nil {
return nil, err
}
var asset Asset
err = json.Unmarshal(queryResponse.Value, &asset)
if err != nil {
return nil, err
}
assets = append(assets, &asset)
}
return assets, nil
}
func (s *SmartContract) GetMSPID(stub shim.ChaincodeStubInterface) (string, error) {
// Get the Client ID object
clientId, err := cid.New(stub)
if err != nil {
// Handle error
}
mspid, err := clientId.GetMSPID()
if err != nil {
// Handle error
}
// mspId, err := cid.GetMSPID(stub)
// if err != nil {
// return err
// }
// The error is with "Org1MSP" becuase I found out that mspid is Org1MSP
// if mspId != "Org1MSP" {
// return fmt.Errorf(mspId)
// }
return mspid, nil
}
Please look into below fabric sample chaincode. In this smart contract , they are validating MSPID.
https://github.com/hyperledger/fabric-samples/blob/main/asset-transfer-private-data/chaincode-go/chaincode/asset_transfer.go[![enter image description here]1]1