为什么不能同时调用Hyperledger Fabric 1.0中的链代码?

时间:2017-05-04 06:16:42

标签: hyperledger-fabric

在注册,安装和实例化chaincode fabric / example / chaincode / go / chaincode_example02之后,我运行以下步骤。

peer chaincode instantiate --orderer orderer0:7050 --tls true --path example02 --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem --chainID mychannel --name example02cc --version 1.0 --ctor '{"Args":["init","A","1000","B","2000"]}' 

peer chaincode query --chainID mychannel --name example02cc --ctor '{"Args":["query","A"]}'

peer chaincode query --chainID mychannel --name example02cc --ctor '{"Args":["query","B"]}'

到目前为止,我确认A等于1000且B等于2000.之后,如果我使用不同的时间调用以下步骤,结果将是可变的。

peer chaincode invoke --orderer orderer0:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem --chainID mychannel --name example02cc --ctor '{"Args":["invoke","A","B","1"]}'

具体来说,如果我以10秒的暂停运行上一步两次,A将等于998,B将等于2002。 A将等于990,如果我执行上一步十次,每步之间暂停10秒,则B将等于2010。但是,没有任何暂停,如果我执行上一步两次,A将等于999,B将等于2001。如果我在每一步之间没有停顿地运行上一步十次,则A等于999,B等于2001。

我用不同的论点多次测试过。此外,我测试了其他链码。看起来链代码只接受第一个调用请求,并丢弃后续的调用请求。所以,问题是:

  1. 这是一种防止双重支出的机制吗?还是只是一个弱点?
  2. 如何解决限制交易率的问题。
  3. 我认为链代码应该支持并发调用。链码实际上可以支持并发调用吗?
  4. 单个链代码可以在一个块周期内调用多个请求吗?

2 个答案:

答案 0 :(得分:2)

链码需要进行认可,然后在下次调用之前将其提交给分类帐状态。

当您致电peer chaincode invoke ...时,在认可结束后快速回复结构。但提交仍需要一些时间。如果在第一次调用后直接运行第二次调用,第二次调用将正确认可,但没有提交。

所以,对于你的问题:

  1. 您可以尝试通过java-sdk或node-sdk调用chaincode。以javasdk为例,进度是首先将transactionProposalRequest发送到chaincode,这是Fabric中的认可过程。在认可结束后,您的终止政策正确通过。该事务由sdk-client发送给fabirc,此API将返回CompletableFuture<BlockEvent.TransactionEvent>,类似于js中的Promise。当事务完成时,CompletableFuture.thenApply()被触发。例如,您可以查看src / test / java / org.hyperledger.fabric.sdkintergration / End2endIT.java。

  2. 您可以在链代码中编写批处理。这可以立即支持多个调用和查询,它在一定程度上解决了您的问题。该批处理设计如下,在您的cc中新建m map[string]stringtoDelete []string,当调用将您的键/值对放在m中时,以及当查询从{{1获取key / val时首先,如果没有找到,则从存根中查询,当删除需求时,从m删除并将密钥放到m,在完成所有要求后,在toDelete中提交所有数据和m一次。我在我的项目中尝试了这种机制,它运作良好。

  3. 区块链不是为高并发而设计的。它专为保密性,可扩展性和安全性而设计。

  4. 见2

答案 1 :(得分:1)

从面料的角度来看,这实际上是正常的行为 - 虽然看起来有点违反直觉。

您看到的内容逻辑上来自documented transaction flow(+知道在订货人上执行了批量超时的批量处理)。让我们假设在模拟(认可)期间,读取变量A,然后通过链码模拟标记为重新设置。读取了什么值以及您希望变量集成为建议事务的一部分的值(+代言人是否接受事务+加密内容)。然后我们通过提交给orderer +发布到通道对等体+通道对等体检查(以及其他)原始&#34;读取值假设&#34;该提案仍然有效。 (参见5:对引用的同行进行验证。)如果A的值已经改变&#34;自仿真&#34;以来,该交易将无效。

时间对此的影响如下。如果有足够的&#34;余地&#34;在两次调用之间,会发生以下情况:

  • Call1 - 使用原始A值创建的提案
  • Call1提案获得批准,发送给订单者,获得批处理
  • 经过一段时间后,同行从订货人处获得有序认可的Tx,检查,发现没问题,A的价值被修改(提交给Ledger)按要求
  • Call2 - 使用新的A值读取等创建的提案

关键是,如果您创建并提交第二个提案之前会发生什么,第一个提案的效果会提交给Ledger。 (所以没有&#34;等待足够的&#34;。)

  • Call2模拟仍然看到原始的A值,代言是根据
  • 计算的
  • 这是捆绑在&#34;读取值&#34;交易财产
  • 当它到达通道对等方进行提交时,A的值已经被Call1修改
  • 因此,此交易无效且对分类帐
  • 无效

这种效果并不是全新的,我们确实被织物0.6的类似东西所咬。幸运的是,有一些&#34;清洁&#34;摆脱这种方式;我建议阅读&#34;标记化&#34;在区块链上下文中。在example02的上下文中,您可以创建所有&#34;单位&#34;拥有GUID并基本上跟踪所有权向量;或者你可以去完整的UTXO,比特币风格。选项b)可以将Tx请求本身写入分类帐(Tx1:+ 20,Tx2:-40,Tx3:+ 65,...)并基于&#34;当前帐户状态&#34;在Ledger存储的Tx日志中,虽然这可能会有点混乱。

请注意,只要&#34;工作集&#34;&#34;工作集&#34; Tx请求不重叠。对于许多领域,这是可能的;例如对于加密货币来说,它不是像热土豆一样传递的货币单位,而是一大堆具有许多交易的货币单位,但是在它们之间平衡了。

关于您的具体问题:

  1. 见上文
  2. 见上面的两条建议
  3. 取决于并发调用的含义,但结构1.0体系结构的核心是在所有已批准的请求上设置完整排序,并且在验证和分类帐更新期间强制执行此排序。大量同行同时要求事物 - 当然; &#34;可重入链代码&#34; - 不,不是。
  4. Chaincodes不会调用请求&#34;。如果你的意思是单个链代码是否可以在一个块中有多个事务:确定,例如,使用&#34; sell_cars&#34;销售100辆不同的汽车chaincode。