是否可以在常规程序中设置世界状态(分类帐)?

时间:2017-03-06 03:18:57

标签: hyperledger hyperledger-fabric

我想在init之后开始每天检查和更改世界状态的例程。

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
    stub.PutState("xiaoming_wallet", []byte("50"))
    stub.PutState("xiaoming_toy", []byte("0"))
    go monthly_check(&stub)
    return nil, nil
}

功能就像这样

func monthly_check(stub *shim.ChaincodeStubInterface)  {
    tc:=time.Tick(24*time.Hour)
    for range tc{
          ...
          ...
          (*stub).PutState(..,..)
          ...
          ...   }}

但是putstate函数返回

  

put state error无法在查询上下文中放置状态

似乎与分类帐的所有交互都必须是外部事务的一部分,这意味着我无法在go例程中更改存根? 有什么方法可以实现这个目标吗?

3 个答案:

答案 0 :(得分:2)

智能合约用Go或Java编写,并通过垫片连接到对等体(对等体中的代理,合同中的存根 - 通常称为链代码)。链代码在其自己的docker容器中运行,从代理到stub和back的cannection使用gRPC和protobufs。当链代码空闲一段时间后,其容器可以关闭,并在下一个事务或查询到达时再次启动。

因此,无法在内存中存储任何状态。所有状态必须在事务结束时以存储在世界状态中,并在下一个事务或查询中检索。 (注意:在v1结构中,查询是有效的事务,尽管它们不会写状态。)显然,这将扩展到定期唤醒线程并轮询世界状态中的值。

相反,您可以一起使用两种技术:

1)让链代码从事务中发出事件,以便近乎实时地为您的应用程序提供信息。

2)将轮询间隔设置为事件的备份,以便轮流轮询您想要跟踪的状态。

(2)必须存在,因为(1)尚未保证交付。

答案 1 :(得分:1)

从链码中运行计时器是不可能的,因为每个节点都必须就它的时间达成共识等。可以完成的是你可以有一个外部具有适当权限的计时器,定期调用链代码函数。

答案 2 :(得分:1)

不是在常规程序中。一段时间回答了类似的问题。 请看看。的 cannot-put-state-in-query-context