从账本获取数据在清单 8 中,第 1 行上的 GetLoanApplication 方法接受两个参数。第一个参数是 ChaincodeStubInterface,它拥有实用的 API 来与区块链账本、交易上下文、调用方证书等交互。第二个参数是一个字符串数组,该方法的调用方可使用该数组传入需要的参数。
第 2-7 行记录和验证了输入参数。
在第 9 行上,检索了贷款申请的 Id 值,该值将用作从账本中检索实际贷款申请对象的键。
在第 10 行上,通过传入 loanApplicationId 键,调用 stub.GetState 方法以字节数组格式检索贷款申请 JSON 内容。请注意,存储在键值存储中的值必须始终是字节数组。因此,在存储到账本之前,贷款申请 JSON 字符串首先被转换为字节数组。
清单 8. 从账本中获取数据的代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| func GetLoanApplication(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
fmt.Println("Entering GetLoanApplication")
if len(args) < 1 {
fmt.Println("Invalid number of arguments")
return nil, errors.New("Missing loan application ID")
}
var loanApplicationId = args[0]
bytes, err := stub.GetState(loanApplicationId)
if err != nil {
fmt.Println("Could not fetch loan application with id "+loanApplicationId+" from ledger", err)
return nil, err
}
return bytes, nil
}
|
备注:也可以使用传统关系数据模型处理数据。例如,ChaincodeStubInterface 能够创建表格并处理行和列。但这只是一种逻辑抽象,而且数据将作为键值对存储在 RocksDB 中。在撰写本文时,Hyperledger Fabric 1.0 版正在开发之中,而且表数据结构已被弃用。因此,本教程不会讨论它,以便最大限度地减少链代码开发人员从 v0.6 过渡到 v1.0 所需执行的更改。
在 golang 结构与 JSON 字符串之间编组和解组数据如清单 7 和清单 8 中所示,stub.PutState 和 stub.GetState 方法只处理字节数组。所以,能够将链代码中使用的常规结构对象与 JSON 字符串进行相互转换很重要。
清单 9 展示了如何将一种结构编组为可存储在账本中的 JSON 字符串字节数组。第 2 行创建了 PersonalInfo 对象的一个实例。第 3 行使用 json 包将对象编组为 JSON 字符串,并返回同一个字符串的字节数组。
可以通过将 "encoding/json" 包含在顶部的 import 代码块中来导入 json 包。然后此字节数组可以使用清单 7 中给出的 stub.PutState 方法来存储到账本中。
清单 9. 将一种结构编组为 JSON 字符串字节数组的代码1
2
3
4
5
6
7
8
| var personalInfo PersonalInfo
personalInfo = PersonalInfo{"Varun", "Ojha", "dob", "varun@gmail.com", "9999999999"}
bytes, err ;= json.Marshal (&personalInfo)
if err != nil {
fmt.Println("Could not marshal personal info object", err)
return nil, err
}
err = stub.PutState("key", bytes)
|
清单 10 展示如何将一种结构从字节数组解组为已填充的结构。第 1 行使用关联的键从账本中获取 PersonalInfo JSON 字符串字节。第 3 行将第 1 行中检索的字节解组为变量 personalInfo 所引用的 PersonalInfo 对象。
现在可以使用第 4 行所示的点记法来访问和修改 personalInfo 对象。
清单 10. 将一种结构从字节数组解组为已填充的结构的代码1
2
3
4
| piBytes, err := stub.GetState(la1)
var personalInfo PersonalInfo
err = json.Unmarshal(piBytes, &personalInfo)
fmt.Println(personalInfo.Firstname)
|
|