Thursday, April 23, 2020

Hyperledger Fabric chaincode "strange bug" Part 2

According to the previous blog post, we learn that the getState() function would always return the state before the chaincode execution due to the logic of the transaction flow. If we want to query the intermediate state, we may need some utils to help us.


package killa

import (
 "github.com/hyperledger/fabric/core/chaincode/shim"
)

// StateManager is a bridge for fabric world state with cache ability
type StateManager struct {
 APIstub shim.ChaincodeStubInterface
 cache   map[string][]byte
}

// NewStateManager is the constructor of StateManager
func NewStateManager(APIstub shim.ChaincodeStubInterface) *StateManager {
 ret := new(StateManager)
 ret.APIstub = APIstub
 ret.cache = make(map[string][]byte)
 return ret
}

// GetState is used to get fabric world state
func (state *StateManager) GetState(key string) ([]byte, error) {
 ret := state.cache[key]
 if ret != nil {
  return ret, nil
 }
 return state.APIstub.GetState(key)
}

// PutState is used to set fabric world state
func (state *StateManager) PutState(key string, value []byte) error {
 err := state.APIstub.PutState(key, value)
 if err == nil {
  state.cache[key] = value
 }
 return err
}


So now we can use the StateManager to interact with the blockchain state instead.
func update(APIstub shim.ChaincodeStubInterface, args []string) peer.Response {
  state := killa.NewStateManager(APIstub)
  state.PutState("state", []byte(args[0]))
  bytes, _ := state.GetState("state")
  return shim.Success(bytes)
}

No comments:

Post a Comment