1

Example scenario

I have stored the passwords of users, with usernames as key. I want to use a function as a helper function to get that password.

So that I don't have to do error handling every time I want to get password, for matching user entered password in other functions.

Example code:

type User struct {
    Password string `json:"password"`
    Name     string `json:"name"`
}

// Helper fucntion
func (s *SmartContract) GetPassword(ctx contractapi.TransactionContextInterface, _username string) (string, error) {

    dataAsBytes, err := ctx.GetStub().GetState(_username)

    if err != nil {
        return nil, fmt.Errorf("Failed to read from world state. %s", err.Error())
    }

    if dataAsBytes == nil {
        return nil, fmt.Errorf("%s does not exist", _username)
    }

    user := new(User)
    err = json.Unmarshal(dataAsBytes, &user)

    if err != nil {
        return nil, fmt.Errorf("Can't Unmarshal Data")
    }

    return user.Password, nil
}

// Here I used helper function, similarly I will use it in other functions
func (s *SmartContract) AddAsset(ctx contractapi.TransactionContextInterface, _username string, _password string, value string) error {

    temp_password, err := GetPassword(_username, _password)
    if err != nil { return err }
    
    if _password ==  temp_password {
        // Do something
    }

    return nil
}

What could be done, so that only the current chaincode can use the helper function. For additional security, like private methods in Java.

Rajan
  • 625
  • 7
  • 19

2 Answers2

2

The go contract api honours the public/private pattern that GoLang employs, ie if the method starts with an upper case letter it's exposed and can be called as a transaction, if it starts with a lower case letter then it's not exposed and cannot be called as a transaction. So create a method such as getPasswordHelper and have your transactions use that

david_k
  • 5,843
  • 2
  • 9
  • 16
0

When you using ctx.GetStub().GetState(_username) it is rather about accessing some specific Key (see World State for additional details) by an Organization that is belong to channel where this chaincode is deployed than about direct access by chaincode. Chaincode can not access Key. It is just a proxy with public methods. Each public method every time must be invoked as TX by some external user (Organization) or by other public method that is invoke by external user.

While accessing a Key as Organization you may also utilize Hyperledger Fabric feature called Endorsement policy. Endorsement policy is a special rule usually defined on Chaincode level to enforce that specified approvers approve a TX proposal. Example of endorsement policy defined using fabric-cli would be as follows: OR(Org1, Org2). It means that either Org1 or Org2 must endorse TX proposal.

Thing is that you can also set Endorsement policy for particular asset (Key) which would enforce that TX proposal that writes particular key has a minimum required number of approvals. Note: this also should work for TX that "reads" particular key, but I am only 99 % sure. Pls verify it independently.

Therefore you can create a kind of perms table restricting Orgs that are able to read password or modify it. Suggested scenario considering your case: only Org that created a password is able to amend or read the password related Key.

You can apply this one as separate scenario or even combine it with @david-k answer.

Pls refer to Fabric doc to get familiar how to set Key level Endorsement policy

Vitali Grabovski
  • 183
  • 1
  • 3
  • 14