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

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

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

Init 方法Init 方法                在链代码首次部署到区块链网络时调用,将由部署自己的链代码实例的每个对等节点执行。此方法可用于任何与初始化、引导或设置相关的任务。
清单 3. Init()
1
2
3
func (t *SampleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
    return nil, nil
}




Query 方法只要在区块链状态上执行任何读取/获取/查询操作,就会调用 Query                方法。根据链代码的复杂性,此方法含有您的读取/获取/查询逻辑,或者它可以外包给可从 Query                方法内调用的不同方法。
Query 方法不会更改底层链代码的状态,因此它不会在交易上下文内运行。如果尝试在 Query                方法内修改区块链的状态,将出现一个错误显示缺少交易上下文。另外,因为此方法仅用于读取区块链的状态,所以对它的调用不会记录在区块链上。
清单 4. Query()
1
2
3
func (t *SampleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
    return nil, nil
}




Invoke 方法只要修改区块链的状态,就会调用 Invoke 方法。简言之,所有创建、更新和删除操作都应封装在                Invoke 方法内。因为此方法将修改区块链的状态,所以区块链 Fabric                代码会自动创建一个交易上下文,以便此方法在其中执行。对此方法的所有调用都会在区块链上记录为交易,这些交易最终被写入区块中。
清单 5. Invoke()
1
2
3
func (t *SampleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
    return nil, nil
}




链代码中的数据模型Hyperledger 账本包含两部分:
  • World State,存储在一个键值存储中。这个键值存储由 RocksDB                    提供支持。这个键值存储获取一个字节数组作为值,该值可用于存储序列化 JSON                    结构。基本上讲,这个键值存储可用于存储您的智能合约正常运行所需的所有自定义数据模型/模式。
  • 区块链,由一系列区块组成,每个区块包含许多交易。每个区块包含 World State 的哈希值,并被链接到前一个区块。区块链采用仅附加模式                    (append-only)。
清单 6 展示了如何创建自定义数据模型/模式。它定义了住房贷款申请所需的数据模型。主要模型称为                    LoanApplication,它拥有原始数据类型和复杂数据类型,也就是 Personal 和                Financial Info。
因为我们的键值存储将数据存储为 JSON,所以这些数据模型最终需要转换为 JSON 字符串。每个字段(如                    json:"id")的注释的作用类似于编组 (marshal) /解组                (unmarshal) API 的元数据,该 API 将使用这些注释将每个字段映射到相应的 JSON 字符串等效表示。
清单 6. 创建自定义数据模型/模式的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//custom data models
type PersonalInfo struct {
    Firstname string `json:"firstname"`
    Lastname  string `json:"lastname"`
    DOB       string `json:"DOB"`
    Email     string `json:"email"`
    Mobile    string `json:"mobile"`
}

type FinancialInfo struct {
    MonthlySalary      int `json:"monthlySalary"`
    MonthlyRent        int `json:"monthlyRent"`
    OtherExpenditure   int `json:"otherExpenditure"`
    MonthlyLoanPayment int `json:"monthlyLoanPayment"`
}

type LoanApplication struct {
    ID                     string        `json:"id"`
    PropertyId             string        `json:"propertyId"`
    LandId                 string        `json:"landId"`
    PermitId               string        `json:"permitId"`
    BuyerId                string        `json:"buyerId"`
    SalesContractId        string        `json:"salesContractId"`
    PersonalInfo           PersonalInfo  `json:"personalInfo"`
    FinancialInfo          FinancialInfo `json:"financialInfo"`
    Status                 string        `json:"status"`
    RequestedAmount        int           `json:"requestedAmount"`
    FairMarketValue        int           `json:"fairMarketValue"`
    ApprovedAmount         int           `json:"approvedAmount"`
    ReviewerId             string        `json:"reviewerId"`
    LastModifiedDate       string        `json:"lastModifiedDate"`
}




存储和检索数据清单 7 和清单 8 中的代码展示了如何将数据存储到账本中以及如何从账本中获取数据。
将数据存储到账本中清单 7 中第 1 行 上的 CreateLoanApplication 接受两个参数。第一个参数是                ChaincodeStubInterface,它拥有实用的 API                来与区块链账本、交易上下文、调用方证书等交互。第二个参数是一个字符串数组,该方法的调用方可以使用该数组传入所需的参数。
第 2-8 行记录和验证了输入参数。
第 9 行上,检索了贷款申请的 Id 值,该值将用作存储实际贷款申请对象的键。
第 10 行上,以 JSON                字符串格式检索了实际贷款申请内容。例如,‘{"propertyId":"prop1","landId":"land1","permitId":"permit1","buyerId":"vojha24","personalInfo":{"firstname":"Varun","lastname":"Ojha","dob":"dob","email":"varun@gmail.com","mobile":"99999999"},"financialInfo":{"monthlySalary":10000,"otherExpenditure":0,"monthlyRent":1000,"monthlyLoanPayment":1000},"status":"Submitted","requestedAmount":40000,"fairMarketValue":58000,"approvedAmount":40000,"reviewedBy":"abc1","lastModifiedDate":"21/09/2016                2:30pm"}’
第 12 行上,调用了 stub.PutState 方法,以便将贷款申请 id                和实际的贷款申请 JSON 内容作为一个键值对存储到区块链账本中。请注意,存储在键值存储中的值必须始终是字节数组。因此,在存储到账本之前,贷款申请                JSON 字符串首先被转换为字节数组。
清单 7. 将数据存储到账本中的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
func CreateLoanApplication(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
    fmt.Println("Entering CreateLoanApplication")

    if len(args) < 2 {
        fmt.Println("Invalid number of args")
        return nil, errors.New("Expected at least two arguments for loan application creation")
    }

    var loanApplicationId = args[0]
    var loanApplicationInput = args[1]

    err := stub.PutState(loanApplicationId, []byte(loanApplicationInput))
    if err != nil {
        fmt.Println("Could not save loan application to ledger", err)
        return nil, err
    }

    fmt.Println("Successfully saved loan application")
    return nil, nil
}

返回列表