Fabric 2.x Go链码JSON序列化返回schema不匹配问题咨询
问题根因与解决方案
报错根因
你遇到的报错是Fabric 2.x Go合约contractapi包的自动Schema校验机制导致的:
contractapi会自动根据交易方法的输入、返回值结构体生成JSON Schema,对交易返回结果做合法性校验- 你定义的
Asset结构体字段仅加了json:"field1,omitempty"标签,你使用的contractapi版本在解析JSON标签时,没有正确剥离逗号后的omitempty参数,错误将field1,omitempty整体识别为返回字段的名称 - 最终生成的校验Schema要求返回字段必须为
field1,omitempty、field2,omitempty,但你实际返回的JSON字段是field1、field2,因此触发了两类错误:既识别实际返回的field1为非法额外字段,又提示要求的field1,omitempty字段不存在。
修复方案
修改Asset结构体的标签,通过metadata标签显式指定字段名和可选属性,避免contractapi识别错误:
type Asset struct { Field1 string `json:"field1,omitempty" metadata:"field1,optional"` Field2 string `json:"field2,omitempty" metadata:"field2,optional"` }
如果不需要序列化时忽略空值,也可以直接去掉omitempty参数,简化标签写法:
type Asset struct { Field1 string `json:"field1" metadata:",optional"` Field2 string `json:"field2" metadata:",optional"` }
序列化/反序列化相关疑问解答
- 你完全可以直接将前端传入的JSON字符串转成字节数组存入世界状态,不需要额外做Unmarshal/Marshal操作,只要你不需要在链码层处理资产的具体字段逻辑,这种方式是可以正常运行的。
- 链码中做Unmarshal/Marshal的作用不只是数据校验,还包括:
- 业务逻辑处理支持:如果需要在链码中判断字段值、修改字段内容,必须将JSON转成结构体才能高效操作,直接处理字符串/字节数组难度更高、容易出错
- 数据格式统一:如果用户传入的JSON存在多余空格、字段顺序混乱、多余字段等问题,转结构体再序列化可以保证存入世界状态的数据格式一致,避免后续查询、对账出现格式类问题
- 合法性校验:可以提前拦截不符合结构要求的非法数据写入,避免脏数据存入世界状态
- 如果你选择直接存JSON字符串,注意需要修改
ReadAsset方法的返回值为string或者[]byte,不要返回*Asset,否则仍然会触发返回值的Schema校验规则。
内容的提问来源于stack exchange,提问作者Matias Salimbene
相关产品推荐
相关产品推荐

