Hyperledger Fabric 2.2 NodeJS客户端sendProposal报ChaincodeId is nil错误求助
Hyperledger Fabric 提案签名与背书调用问题解决
问题背景
后端实现Fabric链码调用流程如下:
- 创建未签名提案并获取提案缓冲区
const proposal = new Endorsement(this.config.chaincodeId, this.channel) const user = User.createUser( enrollmentId, enrollmentId, this.config.userMspId, certificate ) const identityContext = new IdentityContext(user, this.channel.client) const proposalBuffer = proposal.build(identityContext, { fcn, args, }) const digest = createHash('sha256').update(proposalBuffer).digest('hex')
- 用户对摘要签名后,后端将签名提案发送给背书节点,但调用
sendProposal时抛出ChaincodeId is nil错误,当前实现是将signedProposal对象JSON字符串化后转Buffer传入方法。
错误原因
sendProposal方法要求传入protobuf序列化后的SignedProposal二进制Buffer,而非JSON字符串转义的Buffer。JSON序列化的格式完全不符合Fabric gRPC接口的解析要求,导致背书节点无法从传入数据中解析出ChaincodeId等关键字段,从而抛出错误。
正确实现步骤
1. 引入Fabric Protobuf定义
首先需要导入Fabric官方的protobuf模块,用于构造和序列化SignedProposal:
const { protos } = require('fabric-protos');
2. 构造并序列化SignedProposal
替换原有的signedProposal构造和发送逻辑:
// 基于protobuf定义构造SignedProposal对象 const signedProposal = protos.SignedProposal.create({ signature: Buffer.from(signature, 'base64'), proposal_bytes: proposalBuffer }); // 将对象序列化为符合要求的二进制Buffer const signedProposalBuffer = protos.SignedProposal.encode(signedProposal).finish(); // 获取背书节点并发送提案 const endorser = this.channel.getEndorsers(this.config.userMspId)[0]; const response = await endorser.sendProposal(signedProposalBuffer);
额外验证点
- 确认初始化
Endorsement时传入的chaincodeId不为空,确保proposal.build生成的proposalBuffer中包含有效的ChaincodeId信息。 - 验证
User对象的身份信息(MSP ID、证书)正确,避免签名或提案构造环节出现隐性错误。
SignedProposal 定义说明
Hyperledger Fabric中SignedProposal的protobuf定义来自protos/peer/proposal.proto,结构如下:
message SignedProposal { // 客户端对Proposal生成的签名二进制数据 bytes signature = 1; // 原始提案的二进制数据(即流程第一步生成的proposalBuffer),包含ChaincodeId、调用参数、身份上下文等核心信息 bytes proposal_bytes = 2; }
其中proposal_bytes是已经完成构造的Proposal对象的序列化结果,背书节点会从中解析出ChaincodeId、调用方法等信息,再结合signature验证提案的合法性。
内容的提问来源于stack exchange,提问作者Uros Malesevic
相关产品推荐
相关产品推荐

