func (m *MVCCHelper) SetVersion(hash []byte, version int64) error {
	kvlist, err := m.SetVersionKV(hash, version)
	if err != nil {
		return err
	}
	batch := m.db.NewBatch(true)
	for _, v := range kvlist {
		batch.Set(v.Key, v.Value)
	}
	return batch.Write()
}
SetVersion set stateHash -> version map
package db
import (
	"bytes"
	"fmt"
	"strconv"
	log "github.com/33cn/chain33/common/log/log15"
	"github.com/33cn/chain33/types"
)
var mvccPrefix = []byte(".-mvcc-.")
var mvccMeta = append(mvccPrefix, []byte("m.")...)
var mvccData = append(mvccPrefix, []byte("d.")...)
var mvccLast = append(mvccPrefix, []byte("l.")...)
var mvccMetaVersion = append(mvccMeta, []byte("version.")...)
var mvccMetaVersionKeyList = append(mvccMeta, []byte("versionkl.")...)
type MVCC interface {
	MVCCKV
	SetVersion(hash []byte, version int64) error
	DelVersion(hash []byte) error
	GetVersion(hash []byte) (int64, error)
	GetV(key []byte, version int64) ([]byte, error)
	SetV(key []byte, value []byte, version int64) error
	DelV(key []byte, version int64) error
	AddMVCC(kvs []*types.KeyValue, hash []byte, prevHash []byte, version int64) ([]*types.KeyValue, error)
	DelMVCC(hash []byte, version int64, strict bool) ([]*types.KeyValue, error)
	GetMaxVersion() (int64, error)
	GetVersionHash(version int64) ([]byte, error)
	Trash(version int64) error
}
type MVCCKV interface {
	GetSaveKV(key []byte, value []byte, version int64) (*types.KeyValue, error)
	GetDelKV(key []byte, version int64) (*types.KeyValue, error)
	SetVersionKV(hash []byte, version int64) ([]*types.KeyValue, error)
	DelVersionKV([]byte, int64) ([]*types.KeyValue, error)
}
type MVCCHelper struct {
	*SimpleMVCC
	db DB
}
type SimpleMVCC struct {
	kvdb KVDB
}
var mvcclog = log.New("module", "db.mvcc")
func NewMVCC(db DB) *MVCCHelper {
	return &MVCCHelper{SimpleMVCC: NewSimpleMVCC(NewKVDB(db)), db: db}
}
func (m *MVCCHelper) PrintAll() {
	println("--meta--")
	it := m.db.Iterator(mvccMeta, nil, true)
	defer it.Close()
	for it.Rewind(); it.Valid(); it.Next() {
		if it.Error() != nil {
			mvcclog.Error("PrintAll", "error", it.Error())
			return
		}
		println(string(it.Key()), string(it.Value()))
	}
	println("--data--")
	it = m.db.Iterator(mvccData, nil, true)
	defer it.Close()
	for it.Rewind(); it.Valid(); it.Next() {
		if it.Error() != nil {
			mvcclog.Error("PrintAll", "error", it.Error())
			return
		}
		println(string(it.Key()), string(it.Value()))
	}
	println("--last--")
	it = m.db.Iterator(mvccLast, nil, true)
	defer it.Close()
	for it.Rewind(); it.Valid(); it.Next() {
		if it.Error() != nil {
			mvcclog.Error("PrintAll", "error", it.Error())
			return
		}
		println(string(it.Key()), string(it.Value()))
	}
}
func (m *MVCCHelper) Trash(version int64) error {
	it := m.db.Iterator(mvccData, nil, true)
	defer it.Close()
	perfixkey := []byte("--.xxx.--")
	for it.Rewind(); it.Valid(); it.Next() {
		if it.Error() != nil {
			mvcclog.Error("Trash", "error", it.Error())
			return it.Error()
		}
		if !bytes.HasPrefix(it.Key(), perfixkey) {
			perfixkey = cutVersion(it.Key())
			if perfixkey == nil {
				perfixkey = []byte("--.xxx.--")
			}
			continue
		}
		v, err := getVersion(it.Key())
		if err != nil {
			mvcclog.Error("Trash get verson", "err", err)
			continue
		}
		if v <= version {
			err := m.db.Delete(it.Key())
			if err != nil {
				mvcclog.Error("Trash Delete verson", "err", err)
			}
		}
	}
	return nil
}
func (m *MVCCHelper) DelVersion(hash []byte) error {
	version, err := m.GetVersion(hash)
	if err != nil {
		return err
	}
	kvs, err := m.DelVersionKV(hash, version)
	if err != nil {
		return err
	}
	batch := m.db.NewBatch(true)
	for _, v := range kvs {
		batch.Delete(v.Key)
	}
	return batch.Write()
}