首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

使用 Go 编写智能合约(4)

使用 Go 编写智能合约(4)

实现访问控制和权限Hyperledger 与其他区块链结构的主要区别之一是,它有一个安全的、带许可的账本,该账本适合用于实现企业级解决方案。
成员服务Hyperledger 中的 “成员服务”                组件对在区块链网络中实现安全性和许可发挥着关键作用。它负责向用户发放登记和交易证书来响应注册和登记。
  • 登记证书:成员服务中的证书颁发机构将向希望在区块链上交易的用户发放一个登记证书,作为一种身份证明。
  • 交易证书:交易证书应用作一次性令牌,由调用方/调用应用程序连同对链代码的每个调用请求一起传递。交易证书是通过数学方式从父登记证书那里获得的,因此从理论上讲,可以利用父登记证书生成无限多个交易证书。在将交易数据存储在区块链中时,可以使用交易证书对该数据进行签名和加密。这可以确保只有拥有交易证书的用户或拥有父证书的监管者/审计者等人员,能够实际查看写入的交易内容。
  • 属性:每个交易证书可以包含一些由用户定义的属性。在从客户端应用程序发往证书颁发机构的注册请求中,可以提及这些属性。本系列的后续教程将从开发客户端应用程序的角度进行详细介绍。
清单 11                展示了如何从调用方的交易证书检索属性。前面已经提到过,用户或客户端应用程序需要在每个链代码调用请求中传入用户的证书,以便对区块链网络上的目标对等节点执行身份验证。HFC                SDK                负责自动在请求中传递证书。
清单 11 的第 11 行上的 Invoke                函数已经过修改,以便检查输入函数名称并将调用工作委托给合适的处理函数。此外,Invoke 函数还会验证发送                    CreateLoanApplication 调用请求的调用方的访问权限和角色。Invoke                函数调用自定义的 GetCertAttribute 函数从调用方的交易证书中检索特定属性。
GetCertAttribute 函数通过在第 3                行传入属性名称来获取属性值。
第 15 行检查调用方是否拥有 Bank Admin 角色并能调用                    CreateLoanApplication                函数。如果调用方没有所需的角色,则会返回相应的错误。这样就可以在链代码中实现基于属性的访问控制。
ChaincodeStubInterface 有一些实用程序函数可以处理属性,比如                    ReadCertAttributeVerifyAttribute 和                    VerifyAttributes。所有这些方法都依靠                    github.com/hyperledger/fabric/core/chaincode/shim/crypto/attr                包来创建和使用负责处理属性的 AttributeHandlerImpl。
在目前正在开发的 Hyperledger Fabric 版本 (v1.0) 中,这些实用程序函数已从 ChaincodeStubInterface                删除。因此在 v1.0 中,链代码开发人员需要直接使用 AttributeHandlerImpl 来处理属性。
清单 11. 从调用方的交易证书中检索属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
func GetCertAttribute(stub shim.ChaincodeStubInterface, attributeName string) (string, error) {
    fmt.Println("Entering GetCertAttribute")
    attr, err := stub.ReadCertAttribute(attributeName)
    if err != nil {
        return "", errors.New("Couldn't get attribute " + attributeName + ". Error: " + err.Error())
    }
    attrString := string(attr)
    return attrString, nil
}

func (t *SampleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
    if function == "CreateLoanApplication" {
        username, _ := GetCertAttribute(stub, "username")
        role, _ := GetCertAttribute(stub, "role")
        if role == "Bank_Home_Loan_Admin" {
            return CreateLoanApplication(stub, args)
        } else {
            return nil, errors.New(username + " with role " + role + " does not have access to create a loan application")
        }

    }
    return nil, nil
}

返回列表