func (handler *Handler) serialSend(msg *pb.ChaincodeMessage) error {
	handler.serialLock.Lock()
	defer handler.serialLock.Unlock()
	var err error
	if err = handler.ChatStream.Send(msg); err != nil {
		err = fmt.Errorf("[%s]Error sending %s: %s", shorttxid(msg.Txid), msg.Type.String(), err)
		chaincodeLogger.Errorf("%s", err)
	}
	return err
}
serialSend serializes msgs so gRPC will be happy
package chaincode
import (
	"bytes"
	"fmt"
	"io"
	"sync"
	"time"
	"encoding/json"
	"math/big"
	"github.com/golang/protobuf/proto"
	"github.com/inklabsfoundation/inkchain/common/flogging"
	commonledger "github.com/inklabsfoundation/inkchain/common/ledger"
	"github.com/inklabsfoundation/inkchain/common/policies"
	"github.com/inklabsfoundation/inkchain/common/util"
	"github.com/inklabsfoundation/inkchain/core/common/ccprovider"
	"github.com/inklabsfoundation/inkchain/core/common/sysccprovider"
	"github.com/inklabsfoundation/inkchain/core/container/ccintf"
	"github.com/inklabsfoundation/inkchain/core/ledger"
	"github.com/inklabsfoundation/inkchain/core/peer"
	"github.com/inklabsfoundation/inkchain/core/policy"
	"github.com/inklabsfoundation/inkchain/core/wallet"
	"github.com/inklabsfoundation/inkchain/msp/mgmt"
	"github.com/inklabsfoundation/inkchain/protos/ledger/transet/kvtranset"
	pb "github.com/inklabsfoundation/inkchain/protos/peer"
	"github.com/looplab/fsm"
	"github.com/op/go-logging"
	"golang.org/x/net/context"
	"github.com/inklabsfoundation/inkchain/core/wallet/ink/impl"
	"strconv"
	"strings"
)
const (
	createdstate     = "created"      
	establishedstate = "established"  
	readystate       = "ready"        
	endstate         = "end"          
)
var chaincodeLogger = flogging.MustGetLogger("chaincode")
type MessageHandler interface {
	HandleMessage(msg *pb.ChaincodeMessage) error
	SendMessage(msg *pb.ChaincodeMessage) error
}
type transactionContext struct {
	chainID          string
	signedProp       *pb.SignedProposal
	proposal         *pb.Proposal
	responseNotifier chan *pb.ChaincodeMessage
	queryIteratorMap map[string]commonledger.ResultsIterator
	txsimulator          ledger.TxSimulator
	historyQueryExecutor ledger.HistoryQueryExecutor
}
type nextStateInfo struct {
	msg      *pb.ChaincodeMessage
	sendToCC bool
	sendSync bool
}
type Handler struct {
	sync.RWMutex
	serialLock  sync.Mutex
	ChatStream  ccintf.ChaincodeStream
	FSM         *fsm.FSM
	ChaincodeID *pb.ChaincodeID
	ccInstance  *sysccprovider.ChaincodeInstance
	chaincodeSupport *ChaincodeSupport
	registered       bool
	readyNotify      chan bool
	txCtxs map[string]*transactionContext
	txidMap map[string]bool
	nextState chan *nextStateInfo
	policyChecker policy.PolicyChecker
}
func shorttxid(txid string) string {
	if len(txid) < 8 {
		return txid
	}
	return txid[0:8]
}
func (handler *Handler) decomposeRegisteredName(cid *pb.ChaincodeID) {
	handler.ccInstance = getChaincodeInstance(cid.Name)
}
func getChaincodeInstance(ccName string) *sysccprovider.ChaincodeInstance {
	b := []byte(ccName)
	ci := &sysccprovider.ChaincodeInstance{}
	i := bytes.IndexByte(b, '/')
	if i >= 0 {
		if i < len(b)-1 {
			ci.ChainID = string(b[i+1:])
		}
		b = b[:i]
	}
	i = bytes.IndexByte(b, ':')
	if i >= 0 {
		if i < len(b)-1 {
			ci.ChaincodeVersion = string(b[i+1:])
		}
		b = b[:i]
	}
	ci.ChaincodeName = string(b)
	return ci
}
func (handler *Handler) getCCRootName() string {
	return handler.ccInstance.ChaincodeName
}