在上一小节对Fabric 2.x链码有了基本了解之后,本节以学生信息上链为例,说明Fabric 2.x链码的综合应用。代码如下,内容包括:学生信息上链、查询学生信息(依据key)、查询key区间的学生信息、修改学生信息、获取历史信息等内容。

package mainimport ("encoding/json""fmt""github.com/hyperledger/fabric-contract-api-go/contractapi""strconv""time"
)// 定义一个对象,继承合约对象
type Student struct {contractapi.Contract
}// 上链信息(对象)
type StudentInfo struct {Number  string `json:"number"`Name    string `json:"name"`Age     string `json:"age"`Address string `json:"address"`
}// QueryResult structure used for handling result of query
type QueryResult struct {Key    string `json:"Key"`Record *StudentInfo
}
type QueryHistoryResult struct {TxId string `json:"tx_id"`Value string `json:"value"`IsDel string `json:"is_del"`OnChainTime string `json:"on_chain_time"`
}
// 初始化账本
func (s *Student) InitLedger(ctx contractapi.TransactionContextInterface) error {StudentInfos := []StudentInfo{{Number: "2020001", Name: "张三", Age: "23", Address: "北京"},{Number: "2020002", Name: "李四", Age: "24", Address: "上海"},{Number: "2020003", Name: "王五", Age: "25", Address: "广州"},{Number: "2020004", Name: "赵六", Age: "26", Address: "深圳"},{Number: "2020005", Name: "田七", Age: "27", Address: "天津"},{Number: "2020006", Name: "阿香", Age: "28", Address: "重庆"},{Number: "2020007", Name: "阿凯", Age: "29", Address: "杭州"},{Number: "2020008", Name: "阿兰", Age: "30", Address: "南京"},{Number: "2020009", Name: "旺财", Age: "31", Address: "成都"},{Number: "2020010", Name: "小明", Age: "32", Address: "西安"},}for _, StudentInfo := range StudentInfos {StudentInfoAsBytes, _ := json.Marshal(StudentInfo)err := ctx.GetStub().PutState(StudentInfo.Number, StudentInfoAsBytes)if err != nil {return fmt.Errorf("Failed to put to world state. %s", err.Error())}}return nil
}// 上链学生信息
func (s *Student) CreateStudentInfo(ctx contractapi.TransactionContextInterface, number string, name string, age string, address string) error {StudentInfo := StudentInfo{Number:  number,Name:    name,Age:     age,Address: address,}StudentInfoAsBytes, _ := json.Marshal(StudentInfo)return ctx.GetStub().PutState(StudentInfo.Number, StudentInfoAsBytes)
}//查询学生信息
func (s *Student) QueryStudentInfo(ctx contractapi.TransactionContextInterface, StudentInfoNumber string) (*StudentInfo, error) {StudentInfoAsBytes, err := ctx.GetStub().GetState(StudentInfoNumber)if err != nil {return nil, fmt.Errorf("Failed to read from world state. %s", err.Error())}if StudentInfoAsBytes == nil {return nil, fmt.Errorf("%s does not exist", StudentInfoNumber)}stuInfo := new(StudentInfo)//注意: Unmarshal(data []byte, v interface{})的第二个参数为指针类型(结构体地址)err = json.Unmarshal(StudentInfoAsBytes, stuInfo) //stuInfo := new(StudentInfo),stuInfo本身就是指针if err != nil {return nil, fmt.Errorf("Failed to read from world state. %s", err.Error())}return stuInfo, nil
}// 查询学生信息(查询的key末尾是数字,有对应的区间)
func (s *Student) QueryAllStudentInfos(ctx contractapi.TransactionContextInterface, startNum, endNum string) ([]QueryResult, error) {resultsIterator, err := ctx.GetStub().GetStateByRange(startNum, endNum)if err != nil {return nil, err}defer resultsIterator.Close()results := []QueryResult{}for resultsIterator.HasNext() {queryResponse, err := resultsIterator.Next()if err != nil {return nil, err}StudentInfo := new(StudentInfo)_ = json.Unmarshal(queryResponse.Value, StudentInfo)queryResult := QueryResult{Key: queryResponse.Key, Record: StudentInfo}results = append(results, queryResult)}return results, nil
}// 修改学生信息
func (s *Student) ChangeStudentInfo(ctx contractapi.TransactionContextInterface, number string, name string, age string, address string) error {stuInfo, err := s.QueryStudentInfo(ctx, number)if err != nil {return err}stuInfo.Number = numberstuInfo.Name = namestuInfo.Age = agestuInfo.Address = addressStudentInfoAsBytes, _ := json.Marshal(stuInfo)return ctx.GetStub().PutState(number, StudentInfoAsBytes)
}//获取历史信息
func (s *Student) GetHistory(ctx contractapi.TransactionContextInterface, number string) ([]QueryHistoryResult, error) {resultsIterator, err := ctx.GetStub().GetHistoryForKey(number)if err != nil {return nil, err}defer resultsIterator.Close()//results := []QueryResult{}//results := make([]QueryResult, 0)results := make([]QueryHistoryResult, 0)for resultsIterator.HasNext() {if queryResponse, err := resultsIterator.Next();err==nil{res := QueryHistoryResult{}res.TxId=queryResponse.TxIdres.Value=string(queryResponse.Value)res.IsDel=strconv.FormatBool(queryResponse.IsDelete)res.OnChainTime=time.Unix(queryResponse.Timestamp.Seconds,0).Format("2006-01-02 15:04:05")results= append(results, res)}if err!=nil {return nil,err}}return results, nil
}func main() {chaincode, err := contractapi.NewChaincode(new(Student))if err != nil {fmt.Printf("Error create fabStudentInfo chaincode: %s", err.Error())return}if err := chaincode.Start(); err != nil {fmt.Printf("Error starting fabStudentInfo chaincode: %s", err.Error())}
}

Fabric 2.x链码之综合应用相关推荐

  1. Hyperledger Fabric资产案例-链码实例

    案例分析 功能 开户和销户 资产登记,资产上链,与具体的用户绑定 资产转让,资产所有权变更 查询功能,用户查询,资产查询,资产变更的历史查询 业务实体 用户: 名字.身份证(标识).资产列表 资产:名 ...

  2. Hyperledger Fabric 实战(七):链码 shim API 详解

    为什么80%的码农都做不了架构师?>>>    用 Go 的链码的 shim API 主要方法详解 GetFunctionAndParameters 获取方法名和参数 invoke的 ...

  3. HyperLeger Fabric开发(七)——HyperLeger Fabric链码开发

    HyperLeger Fabric开发(七)--HyperLeger Fabric链码开发 一.链码开发模式 1.链码开发模式简介 Fabric的链码开发调试比较繁琐.在不使用链码开发模式的情况下,链 ...

  4. Fabric 系统链码

    什么是系统链码 fabric 自 1.0 版本开始,将链码分为系统链码和普通链码两种.普通链码(智能合约)用于实现业务逻辑,而系统链码则是用于系统管理,例如 lscc.qscc等. 与普通链码需要独立 ...

  5. Fabric系列 - 链码 ChainCode

    链码(chaincode)是 Hyperledger Fabric 提供的智能合约,是上层应用与底层区块链平台交互的媒介.现阶段,Fabric 提供 Go.Java.Node.js 等语言编写的链码 ...

  6. HyperLeger Fabric学习(一)

    HyperLeger Fabric学习(一) 一.HyperLeger简介 1.HyperLeger简介 2.Hyperledger社区组织结构 3.Hyperledger顶级项目 二.Hyperle ...

  7. 基于超级账本Fabric的供应链跟踪解决方案【开源】

    2019独角兽企业重金招聘Python工程师标准>>> 本项目为基于Hyperledger Fabric区块链的供应链资产跟踪解决方案,项目主要包括链码和Web应用两部分.Fabri ...

  8. fabric shim安装合约_智能合约简介_智能合约开发_Hyperledger Fabric_开发指南_区块链服务 BaaS - 阿里云...

    概述 在 Hyperledger Fabric 中,链码(Chaincode)又称为智能合约(下文中我们统一称为链码),是用Go,node.js或Java编写的程序,主要用于操作账本上的数据.用户的应 ...

  9. 《区块链原理、设计与应用》 – 基于超级账本 Fabric 2.x(学习分享2.1-HyperLedger项目细分)

    废话不多说,直接进入学习分享正题: Hyperledger是全球三大开源软件基金会Linux Foundation其下的一个子项目,它是一组软件的集合,分别从框架平台.工具.类库三个层次进行互相协作. ...

最新文章

  1. Vivado各个过程产生的文件与ISE的对比
  2. mysql user.isd_如何实现MySQL中的用户管理
  3. python中write的用法_Python中操作文件之write()方法的使用教程
  4. 2021年《环球科学》十大科学新闻:“天宫”空间站、火星探索位列前二
  5. 结构体前置申明未定义问题
  6. python自动答题免费_直播答题?Python助你自动搜题之新手篇!
  7. 横向扩展你的ASP.NET Core SignalR 应用
  8. MySQL(9)主从复制和读写分离
  9. Python 编写代码出现 process finished with exit code 0
  10. [Linux] Ubuntu13.04 搭建OK6410-A开发板的开发环境
  11. Java_String_01_由转义字符串得到其原本字符串
  12. windows 10 安装EasyDarwin流服务器推流、本地存储
  13. 一步一步理解CPU芯片漏洞:Meltdown与Spectre
  14. SDOI2015寻宝游戏
  15. weight decay
  16. Android在xml文件中设置颜色透明度
  17. NAO学习第二周——NAOqi Audio
  18. 连米哈游都成了第二,这个一刀999的页游大王把老外吃透了。
  19. 没有 RunInstallerAttribute.Yes 的公共安装程序
  20. 数据结构与算法笔记:分治策略之Greatest Slice,2-Way Merge,Counting Inversions,linearSelect,Diameter,Closest Pair

热门文章

  1. 12平键标准尺寸规格表_普通平键规格尺寸表
  2. 国潮零食王小卤,获评2021年度十大风格化新品牌广告片
  3. 15 STM32F429 DMA
  4. python矩阵对角线求和numpy_以numpy计算对角线和(更快)
  5. 跟我学JAVA -- 什么是面向对象的程序设计
  6. 三只小猪-初遇大灰狼
  7. C#+AE地图文档的相关操作,包括新建打开保存等
  8. 阅读React官方文档
  9. [转]【流媒體】H264—MP4格式及在MP4文件中提取H264的SPS、PPS及码流
  10. QoS 服务质量介绍说明