为什么链码查询会写入账本? (仅限 Marbles 私人样本链代码)

Why do chaincode queries write to ledger? (Marbles Private Sample Chaincode only)

我正在使用 Fabric Marble Private Chaincode sample 测试私有数据集合,遇到了一个令人费解的问题:对等日志似乎显示在执行查询时新块被添加到分类帐中。

当我调用“ReadMarble”链代码函数时:

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile /home/user/fabric-samples/test-network/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n marblesp -c '{"Args":["ReadMarble","marble1"]}'

Org1 和 Org2 Peer 日志均显示以下消息:

2020-11-26 17:20:23.034 UTC [gossip.privdata] StoreBlock -> INFO 080 Received block [7] from buffer channel=mychannel
2020-11-26 17:20:23.036 UTC [committer.txvalidator] Validate -> INFO 081 [mychannel] Validated block [7] in 1ms
2020-11-26 17:20:23.056 UTC [kvledger] commit -> INFO 082 [mychannel] Committed block [7] with 1 transaction(s) in 19ms (state_validation=0ms block_and_pvtdata_commit=5ms state_commit=12ms) commitHash=[93f46d1c133896b222d3dfa4dd7571704aec625332c503a296e918bf7765e2c1]

根据默认集合配置,从 Org1 私有集合进行 3 次交易后,大理石私有价格数据消失这一事实证实了新区块正在提交到分类帐中。 此外,此行为仅在调用 initMarble 之后发生。如果在将弹珠添加到分类帐之前调用 ReadMarble,则不会写入新块。 调用“GetMarblesByRange" and "ReadMarblePrivateDetails”函数时也会观察到相同的行为(新块似乎已写入)。 (但是,无论是否已调用 initMarble,调用“GetMarblesByRange”都会导致写入额外的块。)

我正在使用最新的面料样本 (v2.3) 并参考了此 page 中的教程。

我尝试使用 2.3 Private Data tutorial which uses the asset-transfer-private chaincode sample 而不是 Private Marbles 示例,但无法重现此问题;使用 Asset-transfer-Private 示例链代码时,不会在调用查询时创建新块。我没有注意到这些示例链代码之间有任何明显的差异可以解释这种行为差异,但我也没有编程背景。

我认为问题出在您用于执行调用的 CLI 命令上。你是运行peer chaincode invoke。此命令的帮助说明:

Invoke the specified chaincode. It will try to commit the endorsed transaction to the network.

请注意,您链接的链代码顶部的注释建议使用此命令查询弹珠:

peer chaincode query -C mychannel -n marblesp -c '{"Args":["ReadMarble","marble1"]}'

peer chaincode query 命令的帮助如下:

Get endorsed result of chaincode function call and print it. It won't generate transaction.

peer chaincode query命令只是向节点发送一个提议以获得交易结果。 peer chaincode invoke 命令向 peer(s) 发送提案以收集背书响应,然后将提案和这些背书发送到排序节点,以作为交易提交到账本。这里有关于此流程的更多详细信息:

https://hyperledger-fabric.readthedocs.io/en/release-2.2/peers/peers.html#phase-1-proposal