func deserializeSStxTicketHash160(serializedSStxRecord []byte, dbVersion uint32) (hash160 []byte, p2sh bool, err error) {
	var pkscriptLocOffset int
	var txOffset int
	switch {
	case dbVersion < 3:
		pkscriptLocOffset = 8  
		txOffset = 8 + 4 + 1 + stake.MaxSingleBytePushLength
	case dbVersion >= 3:
		pkscriptLocOffset = 0
		txOffset = 4
	}
	pkscriptLoc := int(binary.LittleEndian.Uint32(serializedSStxRecord[pkscriptLocOffset:])) + txOffset
	prefixBytes := serializedSStxRecord[pkscriptLoc : pkscriptLoc+3]
	scriptHash := make([]byte, 20)
	p2sh = false
	switch {
	case bytes.Equal(prefixBytes, sstxTicket2PKHPrefix):
		scrHashLoc := pkscriptLoc + 4
		if scrHashLoc+20 >= len(serializedSStxRecord) {
			return nil, false, stakeStoreError(apperrors.ErrDatabase,
				"bad serialized sstx record size for pubkey hash", nil)
		}
		copy(scriptHash, serializedSStxRecord[scrHashLoc:scrHashLoc+20])
	case bytes.Equal(prefixBytes, sstxTicket2SHPrefix):
		scrHashLoc := pkscriptLoc + 3
		if scrHashLoc+20 >= len(serializedSStxRecord) {
			return nil, false, stakeStoreError(apperrors.ErrDatabase,
				"bad serialized sstx record size for script hash", nil)
		}
		copy(scriptHash, serializedSStxRecord[scrHashLoc:scrHashLoc+20])
		p2sh = true
	}
	return scriptHash, p2sh, nil
}
deserializeSStxTicketHash160 deserializes and returns a 20 byte script
hash for a ticket's 0th output.
package udb
import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
	"time"
	"github.com/HcashOrg/hcashd/blockchain/stake"
	"github.com/HcashOrg/hcashd/chaincfg/chainhash"
	"github.com/HcashOrg/hcashd/wire"
	"github.com/HcashOrg/hcashutil"
	"github.com/HcashOrg/hcashwallet/apperrors"
	"github.com/HcashOrg/hcashwallet/walletdb"
)
const (
	int8Size  = 1
	int16Size = 2
	int32Size = 4
	int64Size = 8
	hashSize  = 32
	ssgenRecordSize = 32 + 4 + 32 + 2 + 8
	ssrtxRecordSize = 32 + 4 + 32 + 8
	stakePoolUserTicketSize = 32 + 4 + 1 + 4 + 32
	stakePoolTicketsPrefixSize = 5
	stakePoolInvalidPrefixSize = 5
	scriptHashSize = 20
)
var (
	sstxTicket2PKHPrefix = []byte{0xba, 0x76, 0xa9}
	sstxTicket2SHPrefix = []byte{0xba, 0xa9, 0x14}
	stakePoolTicketsPrefix = []byte("tickt")
	stakePoolInvalidPrefix = []byte("invld")
)
var (
	sstxRecordsBucketName  = []byte("sstxrecords")
	ssgenRecordsBucketName = []byte("ssgenrecords")
	ssrtxRecordsBucketName = []byte("ssrtxrecords")
	stakeStoreCreateDateName = []byte("stakestorecreated")
)
func deserializeSStxRecord(serializedSStxRecord []byte, dbVersion uint32) (*sstxRecord, error) {
	switch {
	case dbVersion < 3:
		record := new(sstxRecord)
		curPos := 0
		msgTxLen := int(binary.LittleEndian.Uint64(
			serializedSStxRecord[curPos : curPos+int64Size]))
		curPos += int64Size
		curPos += int32Size
		record.voteBitsSet = false
		voteBitsLen := int(serializedSStxRecord[curPos])
		if voteBitsLen != 0 {
			record.voteBitsSet = true
		}
		curPos += int8Size
		record.voteBits = binary.LittleEndian.Uint16(
			serializedSStxRecord[curPos : curPos+int16Size])
		curPos += int16Size
		if voteBitsLen != 0 {
			record.voteBitsExt = make([]byte, voteBitsLen-int16Size)
			copy(record.voteBitsExt, serializedSStxRecord[curPos:curPos+voteBitsLen-int16Size])
		}
		curPos += stake.MaxSingleBytePushLength - int16Size
		buf := bytes.NewBuffer(serializedSStxRecord[curPos : curPos+msgTxLen])
		curPos += msgTxLen
		msgTx := new(wire.MsgTx)
		err := msgTx.Deserialize(buf)
		if err != nil {
			if err == io.EOF {
				err = io.ErrUnexpectedEOF
			}
			return nil, err
		}
		tx := hcashutil.NewTx(msgTx)
		tx.SetIndex(hcashutil.TxIndexUnknown)
		tx.SetTree(wire.TxTreeStake)
		record.tx = tx
		received := int64(binary.LittleEndian.Uint64(
			serializedSStxRecord[curPos : curPos+int64Size]))
		record.ts = time.Unix(received, 0)
		return record, nil
	case dbVersion >= 3:
		serializedSStxRecord = serializedSStxRecord[4:]
		var tx wire.MsgTx
		err := tx.Deserialize(bytes.NewReader(serializedSStxRecord))
		if err != nil {
			return nil, err
		}
		unixTime := int64(binary.LittleEndian.Uint64(serializedSStxRecord[tx.SerializeSize():]))
		return &sstxRecord{tx: hcashutil.NewTx(&tx), ts: time.Unix(unixTime, 0)}, nil
	default:
		panic("unreachable")
	}
}