Is it possible to set the world state(ledger) in a go routine?

青春壹個敷衍的年華 提交于 2019-12-11 09:27:49

问题


I want to start a go routine to check and change the world state daily after 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
}

the function is like this

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

but the putstate function returns

put state error Cannot put state in query context

It seems all interactions with the ledger have to be part of an external transaction, which means I can't change the stub in a go routine? Is there any way i can achieve this?


回答1:


A smart contract is written in either Go or Java and connects to the peer via a shim (proxy in the peer, stub in the contract -- generally called chaincode). The chaincode runs in its own docker container and the cannection from proxy to stub and back uses gRPC and protobufs. When a chaincode is idle for a while, its container can shut down, and be started up again when the next transaction or query arrives.

For this reason, you cannot store any state in memory. All state must be stored in world state at the end of a transaction and retrieved in the next transaction or query. (Note: in v1 fabric, queries are transactions effectively, although they don't write state.) Obviously, this would extend to periodically waking up a thread and polling a value in world state.

Instead, you can use two techniques together:

1) Have the chaincode emit an event from transactions to feed your application in near-real-time.

2) Set up a polling interval as a backup to the events to poll the state you want to track now and again.

(2) must exist because (1) is not yet guaranteed delivery.




回答2:


Not from within a go routine. A similar question was answered confirming this a while back. Kindly take a look. cannot-put-state-in-query-context




回答3:


It would not be possible to run a timer from within a chaincode because then each node would have to be in consensus about what time it is etc. What can be done is you could have an external timer with the appropriate permissions that invokes a chaincode function periodically.



来源:https://stackoverflow.com/questions/42617003/is-it-possible-to-set-the-world-stateledger-in-a-go-routine

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!