Fabric 2.x链码之综合应用
在上一小节对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链码之综合应用相关推荐
- Hyperledger Fabric资产案例-链码实例
案例分析 功能 开户和销户 资产登记,资产上链,与具体的用户绑定 资产转让,资产所有权变更 查询功能,用户查询,资产查询,资产变更的历史查询 业务实体 用户: 名字.身份证(标识).资产列表 资产:名 ...
- Hyperledger Fabric 实战(七):链码 shim API 详解
为什么80%的码农都做不了架构师?>>> 用 Go 的链码的 shim API 主要方法详解 GetFunctionAndParameters 获取方法名和参数 invoke的 ...
- HyperLeger Fabric开发(七)——HyperLeger Fabric链码开发
HyperLeger Fabric开发(七)--HyperLeger Fabric链码开发 一.链码开发模式 1.链码开发模式简介 Fabric的链码开发调试比较繁琐.在不使用链码开发模式的情况下,链 ...
- Fabric 系统链码
什么是系统链码 fabric 自 1.0 版本开始,将链码分为系统链码和普通链码两种.普通链码(智能合约)用于实现业务逻辑,而系统链码则是用于系统管理,例如 lscc.qscc等. 与普通链码需要独立 ...
- Fabric系列 - 链码 ChainCode
链码(chaincode)是 Hyperledger Fabric 提供的智能合约,是上层应用与底层区块链平台交互的媒介.现阶段,Fabric 提供 Go.Java.Node.js 等语言编写的链码 ...
- HyperLeger Fabric学习(一)
HyperLeger Fabric学习(一) 一.HyperLeger简介 1.HyperLeger简介 2.Hyperledger社区组织结构 3.Hyperledger顶级项目 二.Hyperle ...
- 基于超级账本Fabric的供应链跟踪解决方案【开源】
2019独角兽企业重金招聘Python工程师标准>>> 本项目为基于Hyperledger Fabric区块链的供应链资产跟踪解决方案,项目主要包括链码和Web应用两部分.Fabri ...
- fabric shim安装合约_智能合约简介_智能合约开发_Hyperledger Fabric_开发指南_区块链服务 BaaS - 阿里云...
概述 在 Hyperledger Fabric 中,链码(Chaincode)又称为智能合约(下文中我们统一称为链码),是用Go,node.js或Java编写的程序,主要用于操作账本上的数据.用户的应 ...
- 《区块链原理、设计与应用》 – 基于超级账本 Fabric 2.x(学习分享2.1-HyperLedger项目细分)
废话不多说,直接进入学习分享正题: Hyperledger是全球三大开源软件基金会Linux Foundation其下的一个子项目,它是一组软件的集合,分别从框架平台.工具.类库三个层次进行互相协作. ...
最新文章
- 试编写一个汇编语言程序,大写---小写 要求对键盘输入的大写字母用小写字母显示出来。
- Google Code Jam Round 1A 2015 解题报告
- 背景图页面缩小会变形_社团招新迎新海报背景图第321期
- 最流畅的手机,性能、跑分却弱爆了?2019年上半年手机数据报告出炉
- VK Cup 2012 Round 1 D. Distance in Tree (树形dp)
- Apache Ranger——Hadoop ACL控制工具
- Tomcat详解(八)——Tomcat与Nginx实现动静分离
- 数据结构与算法之递推算法 C++与PHP实现
- 毕设题目:Matlab图像修复
- ad怎么批量改元器件封装_在AD软件中的PCB界面如何批量修改封装?
- VirtualBox 新建虚拟机
- python 识别二维码内容
- 在小写与大写之间加下划线
- 【论文解读 WSDM 2020 | KRF】Integrating Knowledge Relations into Style Correlations for 多标签音乐风格分类
- UVA10306 - e-Coins(二维完全背包)
- leetcode 思路——64. 最小路径和——174. 地下城游戏
- English马力-Lesson1(MY MYSELF,IRENE)
- 软件战场加速剧变!诚迈科技成为Elektrobit中国区增值代理经销商
- 7-14 然后是几点(C语言)
- 苹果ios APP怎么打包?
热门文章
- mysql connect 超时_MySQL修改connect_timeout(连接超时)全局变量
- R语言使用levels()函数来查看factor因子变量水平级别(levels)、使用levels参数重新排序因子水平级别、并可视化柱状图
- 创世纪牛人科技外汇交易跟单社区一键绑定跟随即可月收益20%-50%
- SPSS正版中文版 | SPSS软件下载安装| SPSS软件功能使用
- Maya 提高渲染质量的技巧总结
- recordset.recordcount的问题
- USB2.0 HUB眼图调试经验总结
- OctopusWallets(章鱼钱包)是什么
- 用友nc开发,添加附件上传按钮
- 为什么我说你不爱我了!