Fabric 2.x 智能合约开发记录
表象:Return schema invalid. required items must be unique [recovered]
虽然 Fabric v2.2 已经发布了很久了,但之前因为项目历史问题,一直使用的都是 Fabric v1.4.8,所以智能合约也一直使用的都是 github.com/hyperledger/fabric/core/chaincode/shim 包。
在合约开发过程中,我一般都是使用下面的接口格式来定义合约的业务逻辑:
func create(stub shim.ChaincodeStubInterface, payload string) ([]byte, error)
在开发 Fabric v2.2 的智能合约时, 使用 github.com/hyperledger/fabric-contract-api-go/contractapi 替换 github.com/hyperledger/fabric/core/chaincode/shim,接口格式如下:
func create(ctx contractapi.TransactionContextInterface, payload string) ([]byte, error)
然而这样的接口在合约示例化的时候翻车了:
Error compiling schema for SmartContract [create]. Return schema invalid. required items must be unique [recovered]
翻阅 github.com/hyperledger/fabric-contract-api-go 时,在其使用教程发现一些限制:
- 合同的函数只能接受以下类型的参数:
- string
- bool
- int(包括 int8、int16、int32 和 int64)
- uint(包括 uint8、uint16、uint32 和 uint64)
- float32
- float64
- time.Time
- 任何允许类型的数组/切片
- 结构体(其公共字段全部属于允许类型或另一个结构体)
- 指向结构体的指针
- 具有键类型为 string 和值为任何允许类型的映射
- interface{}(仅当直接传入时才允许,在通过事务调用时将接收一个 string 类型)
- 合同的函数还可以接受事务上下文,前提是:
- 它作为第一个参数传入
- 二选一:
- 它要么是类型为 *contractapi.TransactionContext 的对象,要么是在链码中定义的自定义事务上下文,用于合同的使用
- 它是一个接口,用于合同的事务上下文类型符合该接口,例如 contractapi.TransactionContextInterface。
- 合同的函数只能返回零、一个或两个值:
- 如果函数被定义为返回零值,那么对该合同函数的所有调用将返回成功响应
- 如果函数被定义为返回一个值,那么该值可以是参数列表中列出的任何允许类型之一(除了 interface{}),或者是错误。
- 如果函数被定义为返回两个值,那么第一个值可以是参数列表中列出的任何允许类型之一(除了 interface{}),第二个值必须是错误。
仔细阅读会发现 func create(ctx contractapi.TransactionContextInterface, payload string) ([]byte, error) 并没有违法上面的规则,但示例化的时候就是无法通过。
上面的报错信息也明确说了是返回值不对,那就改下接口的返回值:
func create(ctx contractapi.TransactionContextInterface, payload string) (string, error)
func create(ctx contractapi.TransactionContextInterface, payload string) (*Company, error)
func create(ctx contractapi.TransactionContextInterface, payload string) (int, error)
修改后在进行实例化,这次不再报错了。
但是明明之前的也没有违反规则,为什么会报错呢?想不通为什么,所以准备给官方提个Issue,万一真是个bug呢?
结果就在issues里发现了这个Possible issues with byte[] as return type,一看日期Oct 20, 2021,快两年了也没官方的回应......
结论
最后搜了一圈也没找到原因,查看源码,感觉问题可能是出在 contractFunctionReturns,具体还得等研究完源码之后才能有答案
type contractChaincodeContract struct {
info metadata.InfoMetadata
functions map[string]*internal.ContractFunction
unknownTransaction *internal.TransactionHandler
beforeTransaction *internal.TransactionHandler
afterTransaction *internal.TransactionHandler
transactionContextHandler reflect.Type
}
// ContractChaincode a struct to meet the chaincode interface and provide routing of calls to contracts
type ContractChaincode struct {
DefaultContract string
contracts map[string]contractChaincodeContract
metadata metadata.ContractChaincodeMetadata
Info metadata.InfoMetadata
TransactionSerializer serializer.TransactionSerializer
}
// ContractFunction contains a description of a function so that it can be called by a chaincode
type ContractFunction struct {
function reflect.Value
callType CallType
params contractFunctionParams
returns contractFunctionReturns
}
type contractFunctionReturns struct {
success reflect.Type
error bool
}
声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意
Fabric 2.x 智能合约开发记录的更多相关文章
- Hyperledger Fabric 智能合约开发及 fabric-sdk-go/fabric-gateway 使用示例
前言 在上个实验 Hyperledger Fabric 多组织多排序节点部署在多个主机上 中,我们已经实现了多组织多排序节点部署在多个主机上,但到目前为止,我们所有的实验都只是研究了联盟链的网络配置方 ...
- Hyperledger Fabric 使用 CouchDB 和复杂智能合约开发
前言 在上个实验中,我们已经实现了简单智能合约实现及客户端开发,但该实验中智能合约只有基础的增删改查功能,且其中的数据管理功能与传统 MySQL 比相差甚远.本文将在前面实验的基础上,将 Hyperl ...
- 智能合约开发环境搭建及Hello World合约
如果你对于以太坊智能合约开发还没有概念(本文会假设你已经知道这些概念),建议先阅读入门篇. 就先学习任何编程语言一样,入门的第一个程序都是Hello World.今天我们来一步一步从搭建以太坊智能合约 ...
- 智能合约开发solidity编程语言开发一个以太坊应用区块链投票实例
智能合约开发用solidity编程语言部署在以太坊这个区块链平台,本文提供一个官方实战示例快速入门,用例子深入浅出智能合约开发,体会以太坊构建去中心化可信交易技术魅力.智能合约其实是"执行合 ...
- NEO智能合约开发(二)再续不可能的任务
NEO智能合约开发中,应用合约比较简单,是的你没看错,应用合约比较简单. 应用合约三部曲,发布.调用.看结果.除了看结果工具比较缺乏,发布调用neogui最起码可以支撑你测试. 鉴权合约比较麻 ...
- 搭建智能合约开发环境Remix IDE及使用
目前开发智能的IDE, 首推还是Remix, 而Remix官网, 总是由于各种各样的(网络)原因无法使用,本文就来介绍一下如何在本地搭建智能合约开发环境remix-ide并介绍Remix的使用. 写在 ...
- [转] 智能合约开发环境搭建及Hello World合约
[From] http://www.cnblogs.com/tinyxiong/p/7898599.html 如果你对于以太坊智能合约开发还没有概念(本文会假设你已经知道这些概念),建议先阅读入门篇. ...
- EOS智能合约开发(四):智能合约部署及调试(附编程示例)
EOS智能合约开发(一):EOS环境搭建和创建节点 EOS智能合约开发(二):EOS创建和管理钱包 EOS智能合约开发(三):EOS创建和管理账号 部署智能合约的示例代码如下: $ cleos set ...
- EOS智能合约开发(三):EOS创建和管理账号
没有看前面文章的小伙伴可以看一下 EOS智能合约开发(一):EOS环境搭建和启动节点 EOS智能合约开发(二):EOS创建和管理钱包 创建好钱包.密钥之后,接下来你就可以创建账号了,账号是什么?账号保 ...
- 以太坊智能合约开发,Web3.js API 中文文档 ethereum web3.js入门说明
以太坊智能合约开发,Web3.js API 中文文档 ethereum web3.js入门说明 为了让你的Ðapp运行上以太坊,一种选择是使用web3.js library提供的web3.对象.底层实 ...
随机推荐
- .NET周报 【5月第3期 2023-05-21】
国内文章 C# 实现 Linux 视频会议(源码,支持信创环境,银河麒麟,统信UOS) https://www.cnblogs.com/shawshank/p/17390248.html 信创是现阶段 ...
- day08-SpringCloud Gateway-服务网关
SpringCloud Gateway-服务网关 1.Gateway介绍 1.1引出问题 没有使用网关服务时: 使用网关服务后: 1.2Gateway网络拓扑图 1.3Gateway是什么 官网:Sp ...
- Python之Excel表格数据处理
正式开讲之前,我们需要先了解几个基本的知识点:1.Python字典(Dictionary) 的setdefault()方法描述:如果键不存在于字典中,将会添加键并将值设为默认值.语法:dict.set ...
- S32DS学习日志:debug文件和烧录的.hex文件
工程导入之后先clean一下,重新编译生成的文件默认在Production文件下面,得重新设置 折腾半天用jlink烧录没反应,原来是这里错了. production下的文件是用来用来集成bootlo ...
- 用声明式宏解析 Rust 语法之 enum parser
上一篇用声明式宏解析 Rust 语法 我们的 "macro parser" 解析了 function 和 struct, 这篇来尝试 parse 一下更复杂的 enum 为什么说 ...
- 前端Vue自定义顶部搜索框 热门搜索 历史搜索 用于搜索跳转使用
前端Vue自定义顶部搜索框 热门搜索 历史搜索 用于搜索跳转使用, 下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13128 效 ...
- PostgreSQL 12 文档: 系统表
第 51 章 系统目录 目录 51.1. 概述 51.2. pg_aggregate 51.3. pg_am 51.4. pg_amop 51.5. pg_amproc 51.6. pg_attrde ...
- 使用Ajax进行数据请求
一.Ajax开源库有很多选择,大家可以根据需求自己选择 jQuery:jQuery是一个广泛应用的JavaScript库,它提供了简洁而强大的API来处理Ajax请求.通过$.ajax()方法或其 ...
- 解决github网站打不开
方法一(此方法无效则选 方法二) 发现github经常打不开无法访问,最近尝试了下改host发现效果挺好,方法如下(windows电脑): 进入站长工具网站的域名解析网址:http://tool.ch ...
- iOS 百度导航没有语音播报
1.百度地图没有语音播报 可以尝试如下方式: 1.tts确认相关key正确,可以放入官方demo测试 2.setting中 Product Name 尝试设置成英文,在info.plist设置Bund ...