func (state *State) ToProto() (*tmstate.State, error) {
	if state == nil {
		return nil, errors.New("state is nil")
	}
	sm := new(tmstate.State)
	sm.Version = state.Version.ToProto()
	sm.ChainID = state.ChainID
	sm.InitialHeight = state.InitialHeight
	sm.LastBlockHeight = state.LastBlockHeight
	sm.LastBlockID = state.LastBlockID.ToProto()
	sm.LastBlockTime = state.LastBlockTime
	vals, err := state.Validators.ToProto()
	if err != nil {
		return nil, err
	}
	sm.Validators = vals
	nVals, err := state.NextValidators.ToProto()
	if err != nil {
		return nil, err
	}
	sm.NextValidators = nVals
	if state.LastBlockHeight >= 1 {  
		lVals, err := state.LastValidators.ToProto()
		if err != nil {
			return nil, err
		}
		sm.LastValidators = lVals
	}
	sm.LastHeightValidatorsChanged = state.LastHeightValidatorsChanged
	sm.ConsensusParams = state.ConsensusParams.ToProto()
	sm.LastHeightConsensusParamsChanged = state.LastHeightConsensusParamsChanged
	sm.LastResultsHash = state.LastResultsHash
	sm.AppHash = state.AppHash
	return sm, nil
}
ToProto takes the local state type and returns the equivalent proto type
package state
import (
	"bytes"
	"errors"
	"fmt"
	"io/ioutil"
	"time"
	"github.com/gogo/protobuf/proto"
	tmbytes "github.com/tendermint/tendermint/libs/bytes"
	tmstate "github.com/tendermint/tendermint/proto/tendermint/state"
	tmversion "github.com/tendermint/tendermint/proto/tendermint/version"
	"github.com/tendermint/tendermint/types"
	"github.com/tendermint/tendermint/version"
)
type Version struct {
	Consensus version.Consensus ` json:"consensus"`
	Software  string            ` json:"software"`
}
var InitStateVersion = Version{
	Consensus: version.Consensus{
		Block: version.BlockProtocol,
		App:   0,
	},
	Software: version.TMVersion,
}
func (v *Version) ToProto() tmstate.Version {
	return tmstate.Version{
		Consensus: tmversion.Consensus{
			Block: v.Consensus.Block,
			App:   v.Consensus.App,
		},
		Software: v.Software,
	}
}
func VersionFromProto(v tmstate.Version) Version {
	return Version{
		Consensus: version.Consensus{
			Block: v.Consensus.Block,
			App:   v.Consensus.App,
		},
		Software: v.Software,
	}
}
type State struct {
	Version Version
	ChainID       string
	InitialHeight int64  
	LastBlockHeight int64
	LastBlockID     types.BlockID
	LastBlockTime   time.Time
	NextValidators              *types.ValidatorSet
	Validators                  *types.ValidatorSet
	LastValidators              *types.ValidatorSet
	LastHeightValidatorsChanged int64
	ConsensusParams                  types.ConsensusParams
	LastHeightConsensusParamsChanged int64
	LastResultsHash []byte
	AppHash []byte
}
func (state State) Copy() State {
	return State{
		Version:       state.Version,
		ChainID:       state.ChainID,
		InitialHeight: state.InitialHeight,
		LastBlockHeight: state.LastBlockHeight,
		LastBlockID:     state.LastBlockID,
		LastBlockTime:   state.LastBlockTime,
		NextValidators:              state.NextValidators.Copy(),
		Validators:                  state.Validators.Copy(),
		LastValidators:              state.LastValidators.Copy(),
		LastHeightValidatorsChanged: state.LastHeightValidatorsChanged,
		ConsensusParams:                  state.ConsensusParams,
		LastHeightConsensusParamsChanged: state.LastHeightConsensusParamsChanged,
		AppHash: state.AppHash,
		LastResultsHash: state.LastResultsHash,
	}
}
func (state State) Equals(state2 State) bool {
	sbz, s2bz := state.Bytes(), state2.Bytes()
	return bytes.Equal(sbz, s2bz)
}
func (state State) Bytes() []byte {
	sm, err := state.ToProto()
	if err != nil {
		panic(err)
	}
	bz, err := proto.Marshal(sm)
	if err != nil {
		panic(err)
	}
	return bz
}
func (state State) IsEmpty() bool {
	return state.Validators == nil  
}