如何编写仅在链代码内部使用的函数(任何对等方都没有调用操作)?
How to write a function to be used inside chaincode only (no invoke operation by any peer)?
示例场景
我已经存储了用户的密码,以用户名为关键字。我想使用一个函数作为辅助函数来获取该密码。
这样我就不用每次想获取密码时都进行错误处理,以匹配用户在其他功能中输入的密码。
示例代码:
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
}
可以做什么,以便只有当前链代码可以使用辅助函数。为了额外的安全性,比如 Java.
中的私有方法
go 合约 api 遵循 GoLang 使用的 public/private 模式,即如果方法以大写字母开头,则它会公开并可以作为事务调用,如果它以小写字母则不暴露,不能称为交易。因此,创建一个方法,例如 getPasswordHelper
并让您的交易使用
当您使用 ctx.GetStub().GetState(_username)
时,它是由属于部署此链代码的通道的组织访问某些特定密钥(参见 World State for additional details),而不是通过链代码直接访问。 Chaincode 无法访问 Key。它只是一个具有 public 方法的代理。每个 public 方法每次都必须由某个外部用户(组织)或由外部用户调用的其他 public 方法作为 TX 调用。
在以组织身份访问密钥时,您还可以使用称为背书策略的 Hyperledger Fabric 功能。背书策略是一种特殊的规则,通常定义在 Chaincode 级别,以强制指定的批准者批准 TX 提案。使用 fabric-cli 定义的背书策略示例如下:OR(Org1, Org2)
。这意味着 Org1 或 Org2 必须认可 TX 提案。
您还可以为特定资产(密钥)设置背书策略,这将强制写入特定密钥的 TX 提案具有所需的最低批准数量。注意:这也适用于“读取”特定密钥的 TX,但我只有 99% 的把握。请独立验证。
因此您可以创建一种权限 table 来限制能够读取或修改密码的组织。
考虑到您的情况的建议方案:只有创建密码的组织才能修改或读取与密码相关的密钥。
您可以将此作为单独的场景应用,甚至可以将其与 @david-k 答案结合使用。
请refer to Fabric doc熟悉如何设置密钥级别背书策略
示例场景
我已经存储了用户的密码,以用户名为关键字。我想使用一个函数作为辅助函数来获取该密码。
这样我就不用每次想获取密码时都进行错误处理,以匹配用户在其他功能中输入的密码。
示例代码:
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
}
可以做什么,以便只有当前链代码可以使用辅助函数。为了额外的安全性,比如 Java.
中的私有方法go 合约 api 遵循 GoLang 使用的 public/private 模式,即如果方法以大写字母开头,则它会公开并可以作为事务调用,如果它以小写字母则不暴露,不能称为交易。因此,创建一个方法,例如 getPasswordHelper
并让您的交易使用
当您使用 ctx.GetStub().GetState(_username)
时,它是由属于部署此链代码的通道的组织访问某些特定密钥(参见 World State for additional details),而不是通过链代码直接访问。 Chaincode 无法访问 Key。它只是一个具有 public 方法的代理。每个 public 方法每次都必须由某个外部用户(组织)或由外部用户调用的其他 public 方法作为 TX 调用。
在以组织身份访问密钥时,您还可以使用称为背书策略的 Hyperledger Fabric 功能。背书策略是一种特殊的规则,通常定义在 Chaincode 级别,以强制指定的批准者批准 TX 提案。使用 fabric-cli 定义的背书策略示例如下:OR(Org1, Org2)
。这意味着 Org1 或 Org2 必须认可 TX 提案。
您还可以为特定资产(密钥)设置背书策略,这将强制写入特定密钥的 TX 提案具有所需的最低批准数量。注意:这也适用于“读取”特定密钥的 TX,但我只有 99% 的把握。请独立验证。
因此您可以创建一种权限 table 来限制能够读取或修改密码的组织。 考虑到您的情况的建议方案:只有创建密码的组织才能修改或读取与密码相关的密钥。
您可以将此作为单独的场景应用,甚至可以将其与 @david-k 答案结合使用。
请refer to Fabric doc熟悉如何设置密钥级别背书策略