配置memberOnlyRead:false后,Org1仍无法读取Org2的HLF私有数据集合
问题解决:Org1无法读取Org2私有数据集合的问题
问题核心分析
- 集合名称拼写错误:Org2写入的集合是
testCollection,但Org1读取时用的是diagnosticReportCollection,名称不匹配直接导致查询失败。 - 私有数据分发范围限制:集合配置的
policy字段仅包含Org2MSP.member,意味着只有Org2的节点会存储这份私有数据副本。Org1的本地节点没有数据,即便memberOnlyRead设为false,也无法从本地节点读取到数据。 - 查询路由未指向持有数据的节点:如果不想修改分发范围,Org1的查询请求需要路由到Org2的节点,但当前应用网关可能默认只查询Org1自己的peer。
具体解决步骤
步骤1:修正集合名称拼写
将Org1读取代码中的集合名改为testCollection,与写入时一致:
const reportAsBytes = await ctx.stub.getPrivateData( `testCollection`, "1", );
步骤2:调整私有数据集合的分发Policy(方案一:让Org1节点存储数据)
修改集合配置的policy字段,将Org1MSP加入,这样数据会同步到Org1的节点:
[ { "name": "testCollection", "policy": "OR('Org2MSP.member', 'Org1MSP.member')", "requiredPeerCount": 0, "maxPeerCount": 1, "blockToLive":3, "memberOnlyRead": false, "memberOnlyWrite": true, "endorsementPolicy": { "signaturePolicy": "OR('Org2MSP.member')" } } ]
修改后重新打包并安装链码,Org2重新写入数据后,Org1即可从本地节点查询到数据。
步骤3:路由查询请求到Org2节点(方案二:不修改数据分发范围)
如果出于隐私考虑不想让Org1存储数据,需要在应用网关代码中指定查询目标为Org2的peer:
- 首先获取Org2的peer实例(需确保应用网关已配置Org2的连接信息)
- 提交查询交易时指定
targets参数为该peer
示例代码(基于Fabric Gateway SDK):
// 假设已获取到Org2的peer对象 const org2Peer = gateway.getNetwork('mychannel').getPeer('peer0.org2.example.com'); // 提交查询交易时指定目标peer const result = await contract.evaluateTransaction( 'yourQueryFunction', '1', { targets: [org2Peer] } );
这种方式下,Org1的请求会发送到Org2的peer查询数据,无需Org1本地存储副本。
关键概念说明
memberOnlyRead:控制是否只有集合成员能读取数据,仅做权限校验,不影响数据分发。policy:控制私有数据的分发范围,只有符合该policy的节点才会存储数据副本。
内容的提问来源于stack exchange,提问作者Zach De Nardi
相关产品推荐
相关产品推荐

