Monday, April 20, 2020

Hyperledger Fabric chaincode "strange bug" Part 1

When your application grows and your business logic becomes more and more complicated, have you tried the getState() function didn't return the value as you expected?

Here is a very simple chaincode function, the API store your argument to the blockchain, and return the latest value back.

func update(APIstub shim.ChaincodeStubInterface, args []string) peer.Response {
  APIstub.PutState("state", []byte(args[0]))
  bytes, _ := APIstub.GetState("state")
  return shim.Success(bytes)
}


Can you see what's going wrong?
Actually, it will return the state before it has been updated, not after. This "strange bug" is coming from people treat blockchain as a database, or they have a misunderstanding of how chaincode and fabric transactions work. According to the official document, the transaction flow can briefly define as 6 phases:
1. Initiate transaction
2. Execute transaction
3. Inspect proposal response

4. Assemble endorsements
5. Validate transaction
6. Update blockchain

You may discover that the chaincode execution happens in phase 2, while the update happens in phase 6. Therefore no matter how do you update the state in your chaincode, the SDK is going to get the state before this transaction happens, not the intermediate state.
As a fabric developer, we should always keep this flow in our mind, because it may cause many "strange bugs".

No comments:

Post a Comment