fabric-contract-api-go快速上手

2024-02-19 12:12
文章标签 go 快速 api fabric contract

本文主要是介绍fabric-contract-api-go快速上手,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

hi,好久没有更新Fabric相关文章,今天给大家带来fabric-contract-api-go快速上手,相较于原文省略较多,希望深入理解的小伙伴可以点原文学习。

背景

Fabric提供了大量的API来开发智能合约,支持 Go, Node.js, 和Java。本文对fabric-contract-api-go进行简单梳理,可以使读者快速上手。

原文:https://github.com/hyperledger/fabric-contract-api-go/blob/main/tutorials/getting-started.md

一、环境准备

装好Docker、Go的ubuntu,版本尽量新一点。详细请参考原文。

二、contractapi 简述

contractapi 通过打包一个或多个合约打包成一个chaincode(链码),在链码中使用的合约需要实现 contractapi.ContractInterface接口(实现接口相当于继承其中的方法与属性),最简单的方式就是在我们自己创建的合约中嵌入contractapi.Contract结构体。代码示例:

package main
import ("errors""fmt""github.com/hyperledger/fabric-contract-api-go/contractapi"
)
// SimpleContract contract for handling writing and reading from the world state
type SimpleContract struct {contractapi.Contract
}
三、合约函数编写的一些规则

合约仅可以返回0个、1个或2个值。0个值的情况下,所有调用都返回成功;1个值的情况下可以返回规定中的任意类型或error;2个值的情况下,第一个值是数据,第二个值是error。

四、Create合约函数解释

Create函数可以在Fabric的world state中存储键值对。因为需要和world state交互,我们需要传入交易的上下文,在示例代码中使用了默认的contractapi.TransactionContextInterfaceTransactionContextInterface是一个接口类型,实现该接口的交易上下文可以传入。然后交易上下文获取

// Create adds a new key with value to the world state
func (sc *SimpleContract) Create(ctx contractapi.TransactionContextInterface, key string, value string) error {existing, err := ctx.GetStub().GetState(key)if err != nil {return errors.New("Unable to interact with world state")}if existing != nil {return fmt.Errorf("Cannot create world state pair with key %s. Already exists", key)}err = ctx.GetStub().PutState(key, []byte(value))if err != nil {return errors.New("Unable to interact with world state")}return nil
}

附上package shim的官方解释:

// Package shim provides APIs for the chaincode to access its state
// variables, transaction context and call other chaincodes.

stub的官方解释:

// ChaincodeStub is an object passed to chaincode for shim side handling of
// APIs.

个人理解:我们在编写合约时使用stub来对账本进行操作,shim提供了API进行实际的操作,即链码与peer节点之间的通信。

五、完整的合约:
package mainimport ("errors""fmt""github.com/hyperledger/fabric-contract-api-go/contractapi"
)// SimpleContract contract for handling writing and reading from the world state
type SimpleContract struct {contractapi.Contract
}// Create adds a new key with value to the world state
func (sc *SimpleContract) Create(ctx contractapi.TransactionContextInterface, key string, value string) error {existing, err := ctx.GetStub().GetState(key)if err != nil {return errors.New("Unable to interact with world state")}if existing != nil {return fmt.Errorf("Cannot create world state pair with key %s. Already exists", key)}err = ctx.GetStub().PutState(key, []byte(value))if err != nil {return errors.New("Unable to interact with world state")}return nil
}// Update changes the value with key in the world state
func (sc *SimpleContract) Update(ctx contractapi.TransactionContextInterface, key string, value string) error {existing, err := ctx.GetStub().GetState(key)if err != nil {return errors.New("Unable to interact with world state")}if existing == nil {return fmt.Errorf("Cannot update world state pair with key %s. Does not exist", key)}err = ctx.GetStub().PutState(key, []byte(value))if err != nil {return errors.New("Unable to interact with world state")}return nil
}// Read returns the value at key in the world state
func (sc *SimpleContract) Read(ctx contractapi.TransactionContextInterface, key string) (string, error) {existing, err := ctx.GetStub().GetState(key)if err != nil {return "", errors.New("Unable to interact with world state")}if existing == nil {return "", fmt.Errorf("Cannot read world state pair with key %s. Does not exist", key)}return string(existing), nil
}
六、使用合约

在同一个文件夹中创建一个main.go,添加main函数。通过 contractapi.NewChaincode()方法使用先前的合约创建出来一个chaincode。

package mainimport ("github.com/hyperledger/fabric-contract-api-go/contractapi"
)func main() {simpleContract := new(SimpleContract)cc, err := contractapi.NewChaincode(simpleContract)if err != nil {panic(err.Error())}if err := cc.Start(); err != nil {panic(err.Error())}
}

这篇关于fabric-contract-api-go快速上手的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/724620

相关文章

Go标准库常见错误分析和解决办法

《Go标准库常见错误分析和解决办法》Go语言的标准库为开发者提供了丰富且高效的工具,涵盖了从网络编程到文件操作等各个方面,然而,标准库虽好,使用不当却可能适得其反,正所谓工欲善其事,必先利其器,本文将... 目录1. 使用了错误的time.Duration2. time.After导致的内存泄漏3. jsO

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

go中空接口的具体使用

《go中空接口的具体使用》空接口是一种特殊的接口类型,它不包含任何方法,本文主要介绍了go中空接口的具体使用,具有一定的参考价值,感兴趣的可以了解一下... 目录接口-空接口1. 什么是空接口?2. 如何使用空接口?第一,第二,第三,3. 空接口几个要注意的坑坑1:坑2:坑3:接口-空接口1. 什么是空接

springboot security快速使用示例详解

《springbootsecurity快速使用示例详解》:本文主要介绍springbootsecurity快速使用示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录创www.chinasem.cn建spring boot项目生成脚手架配置依赖接口示例代码项目结构启用s

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

C++快速排序超详细讲解

《C++快速排序超详细讲解》快速排序是一种高效的排序算法,通过分治法将数组划分为两部分,递归排序,直到整个数组有序,通过代码解析和示例,详细解释了快速排序的工作原理和实现过程,需要的朋友可以参考下... 目录一、快速排序原理二、快速排序标准代码三、代码解析四、使用while循环的快速排序1.代码代码1.由快

Go语言中最便捷的http请求包resty的使用详解

《Go语言中最便捷的http请求包resty的使用详解》go语言虽然自身就有net/http包,但是说实话用起来没那么好用,resty包是go语言中一个非常受欢迎的http请求处理包,下面我们一起来学... 目录安装一、一个简单的get二、带查询参数三、设置请求头、body四、设置表单数据五、处理响应六、超

Win32下C++实现快速获取硬盘分区信息

《Win32下C++实现快速获取硬盘分区信息》这篇文章主要为大家详细介绍了Win32下C++如何实现快速获取硬盘分区信息,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实现代码CDiskDriveUtils.h#pragma once #include <wtypesbase

Spring AI与DeepSeek实战一之快速打造智能对话应用

《SpringAI与DeepSeek实战一之快速打造智能对话应用》本文详细介绍了如何通过SpringAI框架集成DeepSeek大模型,实现普通对话和流式对话功能,步骤包括申请API-KEY、项目搭... 目录一、概述二、申请DeepSeek的API-KEY三、项目搭建3.1. 开发环境要求3.2. mav