func (s *ChaincodeStub) PutState(key string, value []byte) error {
	if key == "" {
		return errors.New("key must not be an empty string")
	}
	collection := ""
	return s.handler.handlePutState(collection, key, value, s.ChannelID, s.TxID)
}
PutState documentation can be found in interfaces.go
package shim
import (
	"crypto/sha256"
	"encoding/binary"
	"errors"
	"fmt"
	"os"
	"unicode/utf8"
	"github.com/golang/protobuf/proto"
	"github.com/golang/protobuf/ptypes/timestamp"
	"github.com/hyperledger/fabric-protos-go/common"
	"github.com/hyperledger/fabric-protos-go/ledger/queryresult"
	pb "github.com/hyperledger/fabric-protos-go/peer"
)
type ChaincodeStub struct {
	TxID                       string
	ChannelID                  string
	chaincodeEvent             *pb.ChaincodeEvent
	args                       [][]byte
	handler                    *Handler
	signedProposal             *pb.SignedProposal
	proposal                   *pb.Proposal
	validationParameterMetakey string
	creator   []byte
	transient map[string][]byte
	binding   []byte
	decorations map[string][]byte
}
func newChaincodeStub(handler *Handler, channelID, txid string, input *pb.ChaincodeInput, signedProposal *pb.SignedProposal) (*ChaincodeStub, error) {
	stub := &ChaincodeStub{
		TxID:                       txid,
		ChannelID:                  channelID,
		args:                       input.Args,
		handler:                    handler,
		signedProposal:             signedProposal,
		decorations:                input.Decorations,
		validationParameterMetakey: pb.MetaDataKeys_VALIDATION_PARAMETER.String(),
	}
	if signedProposal != nil {
		var err error
		stub.proposal = &pb.Proposal{}
		err = proto.Unmarshal(signedProposal.ProposalBytes, stub.proposal)
		if err != nil {
			return nil, fmt.Errorf("failed to extract Proposal from SignedProposal: %s", err)
		}
		if len(stub.proposal.GetHeader()) == 0 {
			return nil, errors.New("failed to extract Proposal fields: proposal header is nil")
		}
		hdr := &common.Header{}
		if err := proto.Unmarshal(stub.proposal.GetHeader(), hdr); err != nil {
			return nil, fmt.Errorf("failed to extract proposal header: %s", err)
		}
		chdr := &common.ChannelHeader{}
		if err := proto.Unmarshal(hdr.ChannelHeader, chdr); err != nil {
			return nil, fmt.Errorf("failed to extract channel header: %s", err)
		}
		validTypes := map[common.HeaderType]bool{
			common.HeaderType_ENDORSER_TRANSACTION: true,
			common.HeaderType_CONFIG:               true,
		}
		if !validTypes[common.HeaderType(chdr.GetType())] {
			return nil, fmt.Errorf(
				"invalid channel header type. Expected %s or %s, received %s",
				common.HeaderType_ENDORSER_TRANSACTION,
				common.HeaderType_CONFIG,
				common.HeaderType(chdr.GetType()),
			)
		}
		shdr := &common.SignatureHeader{}
		if err := proto.Unmarshal(hdr.GetSignatureHeader(), shdr); err != nil {
			return nil, fmt.Errorf("failed to extract signature header: %s", err)
		}
		stub.creator = shdr.GetCreator()
		payload := &pb.ChaincodeProposalPayload{}
		if err := proto.Unmarshal(stub.proposal.GetPayload(), payload); err != nil {
			return nil, fmt.Errorf("failed to extract proposal payload: %s", err)
		}
		stub.transient = payload.GetTransientMap()
		epoch := make([]byte, 8)
		binary.LittleEndian.PutUint64(epoch, chdr.GetEpoch())
		digest := sha256.Sum256(append(append(shdr.GetNonce(), stub.creator...), epoch...))
		stub.binding = digest[:]
	}
	return stub, nil
}
func (s *ChaincodeStub) GetTxID() string {
	return s.TxID
}
func (s *ChaincodeStub) GetChannelID() string {
	return s.ChannelID
}
func (s *ChaincodeStub) GetDecorations() map[string][]byte {
	return s.decorations
}
func GetMSPID() (string, error) {
	mspid := os.Getenv("CORE_PEER_LOCALMSPID")
	if mspid == "" {
		return "", errors.New("'CORE_PEER_LOCALMSPID' is not set")
	}
	return mspid, nil
}
func (s *ChaincodeStub) InvokeChaincode(chaincodeName string, args [][]byte, channel string) pb.Response {
	if channel != "" {
		chaincodeName = chaincodeName + "/" + channel
	}
	return s.handler.handleInvokeChaincode(chaincodeName, args, s.ChannelID, s.TxID)
}
func (s *ChaincodeStub) GetState(key string) ([]byte, error) {
	collection := ""
	return s.handler.handleGetState(collection, key, s.ChannelID, s.TxID)
}
func (s *ChaincodeStub) SetStateValidationParameter(key string, ep []byte) error {
	return s.handler.handlePutStateMetadataEntry("", key, s.validationParameterMetakey, ep, s.ChannelID, s.TxID)
}
func (s *ChaincodeStub) GetStateValidationParameter(key string) ([]byte, error) {
	md, err := s.handler.handleGetStateMetadata("", key, s.ChannelID, s.TxID)
	if err != nil {
		return nil, err
	}
	if ep, ok := md[s.validationParameterMetakey]; ok {
		return ep, nil
	}
	return nil, nil
}