func unspendRawCredit(ns walletdb.ReadWriteBucket, k []byte) (hcashutil.Amount, error) {
	b := ns.NestedReadWriteBucket(bucketCredits)
	v := b.Get(k)
	if v == nil {
		return 0, nil
	}
	newv := make([]byte, creditValueSize)
	copy(newv, v)
	newv[8] &^= 1 << 0
	err := b.Put(k, newv)
	if err != nil {
		str := "failed to put credit"
		return 0, storeError(apperrors.ErrDatabase, str, err)
	}
	return hcashutil.Amount(byteOrder.Uint64(v[0:8])), nil
}
unspendRawCredit rewrites the credit for the given key as unspent.  The
output amount of the credit is returned.  It returns without error if no
credit exists for the key.
package udb
import (
	"bytes"
	"encoding/binary"
	"fmt"
	"time"
	"github.com/HcashOrg/hcashd/blockchain/stake"
	"github.com/HcashOrg/hcashd/chaincfg"
	"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"
	"golang.org/x/crypto/ripemd160"
)
const (
	accountExistsMask = uint8(0x80)
)
type scriptType uint8
const (
	scriptTypeNonexisting = iota
	scriptTypeUnspecified
	scriptTypeP2PKH
	scriptTypeP2PK
	scriptTypeP2PKHAlt
	scriptTypeP2PKAlt
	scriptTypeP2SH
	scriptTypeSP2PKH
	scriptTypeSP2SH
)
const (
	scriptLocNotStored = 0
)
var byteOrder = binary.BigEndian
var _ [32]byte = chainhash.Hash{}
var (
	bucketBlocks                  = []byte("b")
	bucketHeaders                 = []byte("h")
	bucketTxRecords               = []byte("t")
	bucketCredits                 = []byte("c")
	bucketUnspent                 = []byte("u")
	bucketDebits                  = []byte("d")
	bucketUnmined                 = []byte("m")
	bucketUnminedCredits          = []byte("mc")
	bucketUnminedInputs           = []byte("mi")
	bucketTickets                 = []byte("tix")
	bucketScripts                 = []byte("sc")
	bucketMultisig                = []byte("ms")
	bucketMultisigUsp             = []byte("mu")
	bucketStakeInvalidatedCredits = []byte("ic")
	bucketStakeInvalidatedDebits  = []byte("id")
)
var (
	rootCreateDate   = []byte("date")
	rootVersion      = []byte("vers")
	rootMinedBalance = []byte("bal")
	rootTipBlock     = []byte("tip")
)
func fetchMinedBalance(ns walletdb.ReadBucket) (hcashutil.Amount, error) {
	v := ns.Get(rootMinedBalance)
	if len(v) != 8 {
		str := fmt.Sprintf("mined balance: short read (expected 8 bytes, "+
			"read %v)", len(v))
		return 0, storeError(apperrors.ErrData, str, nil)
	}
	return hcashutil.Amount(byteOrder.Uint64(v)), nil
}
func putMinedBalance(ns walletdb.ReadWriteBucket, amt hcashutil.Amount) error {
	v := make([]byte, 8)
	byteOrder.PutUint64(v, uint64(amt))
	err := ns.Put(rootMinedBalance, v)
	if err != nil {
		str := "failed to put balance"
		return storeError(apperrors.ErrDatabase, str, err)
	}
	return nil
}
func canonicalOutPoint(txHash *chainhash.Hash, index uint32) []byte {
	k := make([]byte, 36)
	copy(k, txHash[:])
	byteOrder.PutUint32(k[32:36], index)
	return k
}
func readCanonicalOutPoint(k []byte, op *wire.OutPoint) error {
	if len(k) < 36 {
		str := "short canonical outpoint"
		return storeError(apperrors.ErrData, str, nil)
	}
	copy(op.Hash[:], k)
	op.Index = byteOrder.Uint32(k[32:36])
	return nil
}
func keyBlockRecord(height int32) []byte {
	k := make([]byte, 4)
	byteOrder.PutUint32(k, uint32(height))
	return k
}
func valueBlockRecordEmptyFromHeader(blockHash *chainhash.Hash, header *RawBlockHeader) []byte {
	v := make([]byte, 51)
	copy(v, blockHash[:])
	byteOrder.PutUint32(v[32:36], uint32(extractBlockHeaderKeyHeight(header[:])))
	byteOrder.PutUint64(v[36:44], uint64(extractBlockHeaderUnixTime(header[:])))
	byteOrder.PutUint16(v[44:46], extractBlockHeaderVoteBits(header[:]))
	byteOrder.PutUint32(v[47:51], 0)
	return v
}
func valueBlockRecordStakeValidated(v []byte) []byte {
	newv := make([]byte, len(v))
	copy(newv, v[:46])
	copy(newv[47:], v[47:])
	return newv
}
func valueBlockRecordStakeInvalidated(v []byte) []byte {
	newv := make([]byte, len(v))
	copy(newv, v[:46])
	newv[46] = 1
	copy(newv[47:], v[47:])
	return newv
}
func appendRawBlockRecord(v []byte, txHash *chainhash.Hash) ([]byte, error) {
	if len(v) < 51 {
		str := fmt.Sprintf("%s: appendRawBlockRecord short read "+
			"(expected %d bytes, read %d)", bucketBlocks, 51, len(v))
		return nil, storeError(apperrors.ErrData, str, nil)
	}
	newv := append(v[:len(v):len(v)], txHash[:]...)
	n := byteOrder.Uint32(newv[47:51])
	byteOrder.PutUint32(newv[47:51], n+1)
	return newv, nil
}
func putRawBlockRecord(ns walletdb.ReadWriteBucket, k, v []byte) error {
	err := ns.NestedReadWriteBucket(bucketBlocks).Put(k, v)
	if err != nil {
		str := "failed to store block"
		return storeError(apperrors.ErrDatabase, str, err)
	}
	return nil
}
func fetchBlockTime(ns walletdb.ReadBucket, height int32) (time.Time, error) {
	k := keyBlockRecord(height)
	v := ns.NestedReadBucket(bucketBlocks).Get(k)
	if len(v) < 51 {
		str := fmt.Sprintf("%s: short read for fetchBlockTime (expected "+
			"%d bytes, read %d)", bucketBlocks, 51, len(v))
		return time.Time{}, storeError(apperrors.ErrData, str, nil)
	}
	return time.Unix(int64(byteOrder.Uint64(v[36:44])), 0), nil
}
func fetchBlockRecord(ns walletdb.ReadBucket, height int32) (*blockRecord, error) {
	br := &blockRecord{}
	k := keyBlockRecord(height)
	v := ns.NestedReadBucket(bucketBlocks).Get(k)
	err := readRawBlockRecord(k, v, br)
	return br, err
}
func existsBlockRecord(ns walletdb.ReadBucket, height int32) (k, v []byte) {
	k = keyBlockRecord(height)
	v = ns.NestedReadBucket(bucketBlocks).Get(k)
	return
}
func readRawBlockRecord(k, v []byte, block *blockRecord) error {
	if len(k) < 4 {
		str := fmt.Sprintf("%s: short key for readRawBlockRecord (expected "+
			"%d bytes, read %d)", bucketBlocks, 4, len(k))
		return storeError(apperrors.ErrData, str, nil)
	}
	if len(v) < 51 {
		str := fmt.Sprintf("%s: short value read for readRawBlockRecord "+
			"(expected %d bytes, read %d)", bucketBlocks, 51, len(v))
		return storeError(apperrors.ErrData, str, nil)
	}
	numTransactions := int(byteOrder.Uint32(v[47:51]))
	expectedLen := 51 + chainhash.HashSize*numTransactions
	if len(v) < expectedLen {
		str := fmt.Sprintf("%s: short read readRawBlockRecord for hashes "+
			"(expected %d bytes, read %d)", bucketBlocks, expectedLen, len(v))
		return storeError(apperrors.ErrData, str, nil)
	}
	block.Height = int32(byteOrder.Uint32(k))
	copy(block.Hash[:], v)
	block.KeyHeight = int32(byteOrder.Uint32(v[32:36]))
	block.Time = time.Unix(int64(byteOrder.Uint64(v[36:44])), 0)
	block.VoteBits = byteOrder.Uint16(v[44:46])
	block.transactions = make([]chainhash.Hash, numTransactions)
	off := 51
	for i := range block.transactions {
		copy(block.transactions[i][:], v[off:])
		off += chainhash.HashSize
	}
	return nil
}
func extractRawBlockRecordHash(v []byte) []byte {
	return v[:32]
}
func extractRawBlockRecordStakeInvalid(v []byte) bool {
	return v[46] != 0
}
type blockIterator struct {
	c    walletdb.ReadWriteCursor
	seek []byte
	ck   []byte
	cv   []byte
	elem blockRecord
	err  error
}
func makeReadBlockIterator(ns walletdb.ReadBucket, height int32) blockIterator {
	seek := make([]byte, 4)
	byteOrder.PutUint32(seek, uint32(height))
	c := ns.NestedReadBucket(bucketBlocks).ReadCursor()
	return blockIterator{c: readCursor{c}, seek: seek}
}
func makeReverseBlockIterator(ns walletdb.ReadWriteBucket) blockIterator {
	seek := make([]byte, 4)
	byteOrder.PutUint32(seek, ^uint32(0))
	c := ns.NestedReadWriteBucket(bucketBlocks).ReadWriteCursor()
	return blockIterator{c: c, seek: seek}
}
func (it *blockIterator) next() bool {
	if it.c == nil {
		return false
	}
	if it.ck == nil {
		it.ck, it.cv = it.c.Seek(it.seek)
	} else {
		it.ck, it.cv = it.c.Next()
	}
	if it.ck == nil {
		it.c = nil
		return false
	}
	err := readRawBlockRecord(it.ck, it.cv, &it.elem)
	if err != nil {
		it.c = nil
		it.err = err
		return false
	}
	return true
}
func (it *blockIterator) prev() bool {
	if it.c == nil {
		return false
	}
	if it.ck == nil {
		it.ck, it.cv = it.c.Seek(it.seek)
		if !bytes.HasPrefix(it.ck, it.seek) {
			it.ck, it.cv = it.c.Prev()
		}
	} else {
		it.ck, it.cv = it.c.Prev()
	}
	if it.ck == nil {
		it.c = nil
		return false
	}
	err := readRawBlockRecord(it.ck, it.cv, &it.elem)
	if err != nil {
		it.c = nil
		it.err = err
		return false
	}
	return true
}
func (it *blockIterator) reposition(height int32) {
	it.c.Seek(keyBlockRecord(height))
}
func deleteBlockRecord(ns walletdb.ReadWriteBucket, height int32) error {
	k := keyBlockRecord(height)
	return ns.NestedReadWriteBucket(bucketBlocks).Delete(k)
}
func keyBlockHeader(blockHash *chainhash.Hash) []byte { return blockHash[:] }
func putRawBlockHeader(ns walletdb.ReadWriteBucket, k, v []byte) error {
	err := ns.NestedReadWriteBucket(bucketHeaders).Put(k, v)
	if err != nil {
		str := "failed to store block header"
		return storeError(apperrors.ErrDatabase, str, err)
	}
	return nil
}
func fetchRawBlockHeader(ns walletdb.ReadBucket, k []byte) ([]byte, error) {
	v := ns.NestedReadBucket(bucketHeaders).Get(k)
	if v == nil {
		str := "block header not found"
		return nil, storeError(apperrors.ErrValueNoExists, str, nil)
	}
	vcopy := make([]byte, len(v))
	copy(vcopy, v)
	return vcopy, nil
}
func existsBlockHeader(ns walletdb.ReadBucket, k []byte) []byte {
	return ns.NestedReadBucket(bucketHeaders).Get(k)
}
func keyTxRecord(txHash *chainhash.Hash, block *Block) []byte {
	k := make([]byte, 72)
	copy(k, txHash[:])
	byteOrder.PutUint32(k[32:36], uint32(block.Height))
	byteOrder.PutUint32(k[36:40], uint32(block.KeyHeight))
	copy(k[40:72], block.Hash[:])
	return k
}
func valueTxRecord(rec *TxRecord) ([]byte, error) {
	var v []byte
	if rec.SerializedTx == nil {
		txSize := rec.MsgTx.SerializeSize()
		v = make([]byte, 8, 8+txSize)
		err := rec.MsgTx.Serialize(bytes.NewBuffer(v[8:]))
		if err != nil {
			str := fmt.Sprintf("unable to serialize transaction %v", rec.Hash)
			return nil, storeError(apperrors.ErrInput, str, err)
		}
		v = v[:cap(v)]
	} else {
		v = make([]byte, 8+len(rec.SerializedTx))
		copy(v[8:], rec.SerializedTx)
	}
	byteOrder.PutUint64(v, uint64(rec.Received.Unix()))
	return v, nil
}
func putTxRecord(ns walletdb.ReadWriteBucket, rec *TxRecord, block *Block) error {
	k := keyTxRecord(&rec.Hash, block)
	v, err := valueTxRecord(rec)
	if err != nil {
		return err
	}
	err = ns.NestedReadWriteBucket(bucketTxRecords).Put(k, v)
	if err != nil {
		str := fmt.Sprintf("%s: put failed for %v", bucketTxRecords, rec.Hash)
		return storeError(apperrors.ErrDatabase, str, err)
	}
	return nil
}
func putRawTxRecord(ns walletdb.ReadWriteBucket, k, v []byte) error {
	err := ns.NestedReadWriteBucket(bucketTxRecords).Put(k, v)
	if err != nil {
		str := fmt.Sprintf("%s: put failed", bucketTxRecords)
		return storeError(apperrors.ErrDatabase, str, err)
	}
	return nil
}
func readRawTxRecordMsgTx(txHash *chainhash.Hash, v []byte, msgTx *wire.MsgTx) error {
	if len(v) < 8 {
		str := fmt.Sprintf("%s: short read for raw tx record msg tx(expected %d "+
			"bytes, read %d, txHash %v)", bucketTxRecords, 8, len(v), txHash)
		return apperrors.New(apperrors.ErrData, str)
	}
	err := msgTx.Deserialize(bytes.NewReader(v[8:]))
	if err != nil {
		str := fmt.Sprintf("%s: failed to deserialize transaction %v",
			bucketTxRecords, txHash)
		return storeError(apperrors.ErrData, str, err)
	}
	return nil
}
func readRawTxRecord(txHash *chainhash.Hash, v []byte, rec *TxRecord) error {
	if len(v) < 8 {
		str := fmt.Sprintf("%s: short read for raw tx record (expected %d "+
			"bytes, read %d, txHash %v)", bucketTxRecords, 8, len(v), txHash)
		return storeError(apperrors.ErrData, str, nil)
	}
	rec.Hash = *txHash
	rec.Received = time.Unix(int64(byteOrder.Uint64(v)), 0)
	err := rec.MsgTx.Deserialize(bytes.NewReader(v[8:]))
	if err != nil {
		str := fmt.Sprintf("%s: failed to deserialize transaction %v",
			bucketTxRecords, txHash)
		return storeError(apperrors.ErrData, str, err)
	}
	rec.TxType = stake.DetermineTxType(&rec.MsgTx)
	return nil
}
func readRawTxRecordHash(k []byte, hash *chainhash.Hash) error {
	if len(k) < 72 {
		str := fmt.Sprintf("%s: short key (expected %d bytes, read %d)",
			bucketTxRecords, 72, len(k))
		return storeError(apperrors.ErrData, str, nil)
	}
	copy(hash[:], k[:32])
	return nil
}
func readRawTxRecordBlockHeight(k []byte, height *int32) error {
	if len(k) < 72 {
		str := fmt.Sprintf("%s: short key (expected %d bytes, read %d)",
			bucketTxRecords, 72, len(k))
		return storeError(apperrors.ErrData, str, nil)
	}
	*height = int32(byteOrder.Uint32(k[32:36]))
	return nil
}
func readRawTxRecordBlockKeyHeight(k []byte, keyHeight *int32) error {
	if len(k) < 72 {
		str := fmt.Sprintf("%s: short key (expected %d bytes, read %d)",
			bucketTxRecords, 72, len(k))
		return storeError(apperrors.ErrData, str, nil)
	}
	*keyHeight = int32(byteOrder.Uint32(k[36:40]))
	return nil
}
func readRawTxRecordBlock(k []byte, block *Block) error {
	if len(k) < 72 {
		str := fmt.Sprintf("%s: short key (expected %d bytes, read %d)",
			bucketTxRecords, 72, len(k))
		return storeError(apperrors.ErrData, str, nil)
	}
	block.Height = int32(byteOrder.Uint32(k[32:36]))
	block.KeyHeight = int32(byteOrder.Uint32(k[36:40]))
	copy(block.Hash[:], k[40:72])
	return nil
}
func fetchRawTxRecordPkScript(k, v []byte, index uint32, scrLoc uint32,
	scrLen uint32) ([]byte, error) {
	if k == nil {
		str := fmt.Sprintf("nil key in pkscript fetch call")
		return nil, storeError(apperrors.ErrData, str, nil)
	}
	if v == nil {
		str := fmt.Sprintf("nil val in pkscript fetch call")
		return nil, storeError(apperrors.ErrData, str, nil)
	}
	var pkScript []byte
	if scrLoc == scriptLocNotStored {
		var rec TxRecord
		copy(rec.Hash[:], k)  
		err := readRawTxRecord(&rec.Hash, v, &rec)
		if err != nil {
			return nil, err
		}
		if int(index) >= len(rec.MsgTx.TxOut) {
			str := "missing transaction output for credit index"
			return nil, storeError(apperrors.ErrData, str, nil)
		}
		pkScript = rec.MsgTx.TxOut[index].PkScript
	} else {
		scrLocInt := int(scrLoc) + 8
		scrLenInt := int(scrLen)
		if scrLocInt > len(v)-1 || scrLocInt+scrLenInt > len(v) {
			str := fmt.Sprintf("bad pkscript location in serialized "+
				"transaction; v[%v:%v] requested but v is only "+
				"len %v", scrLocInt, scrLocInt+scrLenInt, len(v))
			return nil, storeError(apperrors.ErrData, str, nil)
		}
		pkScript = make([]byte, scrLenInt)
		copy(pkScript, v[scrLocInt:scrLocInt+scrLenInt])
	}
	return pkScript, nil
}
func fetchRawTxRecordReceived(v []byte) time.Time {
	return time.Unix(int64(byteOrder.Uint64(v)), 0)
}
func existsTxRecord(ns walletdb.ReadBucket, txHash *chainhash.Hash, block *Block) (k, v []byte) {
	k = keyTxRecord(txHash, block)
	v = ns.NestedReadBucket(bucketTxRecords).Get(k)
	return
}
func existsRawTxRecord(ns walletdb.ReadBucket, k []byte) (v []byte) {
	return ns.NestedReadBucket(bucketTxRecords).Get(k)
}
func deleteTxRecord(ns walletdb.ReadWriteBucket, txHash *chainhash.Hash, block *Block) error {
	k := keyTxRecord(txHash, block)
	return ns.NestedReadWriteBucket(bucketTxRecords).Delete(k)
}
func latestTxRecord(ns walletdb.ReadBucket, txHash []byte) (k, v []byte) {
	c := ns.NestedReadBucket(bucketTxRecords).ReadCursor()
	ck, cv := c.Seek(txHash)
	var lastKey, lastVal []byte
	for bytes.HasPrefix(ck, txHash) {
		lastKey, lastVal = ck, cv
		ck, cv = c.Next()
	}
	return lastKey, lastVal
}
const (
	creditKeySize = 76
	creditValueSize = 94
)
func keyCredit(txHash *chainhash.Hash, index uint32, block *Block) []byte {
	k := make([]byte, creditKeySize)
	copy(k, txHash[:])
	byteOrder.PutUint32(k[32:36], uint32(block.Height))
	byteOrder.PutUint32(k[36:40], uint32(block.KeyHeight))
	copy(k[40:72], block.Hash[:])
	byteOrder.PutUint32(k[72:76], index)
	return k
}
func condenseOpCode(opCode uint8) byte {
	return (opCode - 0xb9) << 2
}
func valueUnspentCredit(cred *credit, scrType scriptType, scrLoc uint32,
	scrLen uint32, account uint32) []byte {
	v := make([]byte, creditValueSize)
	byteOrder.PutUint64(v, uint64(cred.amount))
	v[8] = condenseOpCode(cred.opCode)
	if cred.change {
		v[8] |= 1 << 1
	}
	if cred.isCoinbase {
		v[8] |= 1 << 5
	}
	v[81] = byte(scrType)
	v[81] |= accountExistsMask
	byteOrder.PutUint32(v[82:86], scrLoc)
	byteOrder.PutUint32(v[86:90], scrLen)
	byteOrder.PutUint32(v[90:94], account)
	return v
}
func putRawCredit(ns walletdb.ReadWriteBucket, k, v []byte) error {
	err := ns.NestedReadWriteBucket(bucketCredits).Put(k, v)
	if err != nil {
		str := "failed to put credit"
		return storeError(apperrors.ErrDatabase, str, err)
	}
	return nil
}
func putUnspentCredit(ns walletdb.ReadWriteBucket, cred *credit, scrType scriptType,
	scrLoc uint32, scrLen uint32, account uint32) error {
	k := keyCredit(&cred.outPoint.Hash, cred.outPoint.Index, &cred.block)
	v := valueUnspentCredit(cred, scrType, scrLoc, scrLen, account)
	return putRawCredit(ns, k, v)
}
func extractRawCreditTxHash(k []byte) chainhash.Hash {
	hash, _ := chainhash.NewHash(k[0:32])
	return *hash
}
func extractRawCreditTxRecordKey(k []byte) []byte {
	return k[0:72]
}
func extractRawCreditHeight(k []byte) int32 {
	return int32(byteOrder.Uint32(k[32:36]))
}
func extractRawCreditKeyHeight(k []byte) int32 {
	return int32(byteOrder.Uint32(k[36:40]))
}
func extractRawCreditIndex(k []byte) uint32 {
	return byteOrder.Uint32(k[72:76])
}
func extractRawUnminedCreditTxHash(k []byte) []byte {
	return k[:32]
}
func extractRawCreditIsSpent(k []byte) bool {
	return k[8]&1<<0 != 0
}
func extractRawCreditSpenderDebitKey(v []byte) []byte {
	return v[9:81]
}
func fetchRawCreditAmount(v []byte) (hcashutil.Amount, error) {
	if len(v) < 9 {
		str := fmt.Sprintf("%s: short read for raw credit amount (expected %d "+
			"bytes, read %d)", bucketCredits, 9, len(v))
		return 0, storeError(apperrors.ErrData, str, nil)
	}
	return hcashutil.Amount(byteOrder.Uint64(v)), nil
}
func fetchRawCreditAmountSpent(v []byte) (hcashutil.Amount, bool, error) {
	if len(v) < 9 {
		str := fmt.Sprintf("%s: short read for raw credit amount spent "+
			"(expected %d bytes, read %d)", bucketCredits, 9, len(v))
		return 0, false, storeError(apperrors.ErrData, str, nil)
	}
	return hcashutil.Amount(byteOrder.Uint64(v)), v[8]&(1<<0) != 0, nil
}
func fetchRawCreditAmountChange(v []byte) (hcashutil.Amount, bool, error) {
	if len(v) < 9 {
		str := fmt.Sprintf("%s: short read for raw credit amount change "+
			"(expected %d bytes, read %d)", bucketCredits, 9, len(v))
		return 0, false, storeError(apperrors.ErrData, str, nil)
	}
	return hcashutil.Amount(byteOrder.Uint64(v)), v[8]&(1<<1) != 0, nil
}
func fetchRawCreditUnspentValue(k []byte) ([]byte, error) {
	if len(k) < 76 {
		str := fmt.Sprintf("%s: short key (expected %d bytes, read %d)",
			bucketCredits, 76, len(k))
		return nil, storeError(apperrors.ErrData, str, nil)
	}
	return k[32:72], nil
}
func fetchRawCreditTagOpCode(v []byte) uint8 {
	return (((v[8] >> 2) & 0x07) + 0xb9)
}
func fetchRawCreditIsCoinbase(v []byte) bool {
	return v[8]&(1<<5) != 0
}
func fetchRawCreditScriptOffset(v []byte) uint32 {
	if len(v) < creditValueSize {
		return 0
	}
	return byteOrder.Uint32(v[82:86])
}
func fetchRawCreditScriptLength(v []byte) uint32 {
	if len(v) < creditValueSize {
		return 0
	}
	return byteOrder.Uint32(v[86:90])
}
func fetchRawCreditAccount(v []byte) (uint32, error) {
	if len(v) < creditValueSize {
		str := "short credit value"
		return 0, storeError(apperrors.ErrData, str, nil)
	}
	if v[81]&accountExistsMask != accountExistsMask {
		str := "account value unset"
		return 0, storeError(apperrors.ErrValueNoExists, str, nil)
	}
	return byteOrder.Uint32(v[90:94]), nil
}
func spendCredit(ns walletdb.ReadWriteBucket, k []byte, spender *indexedIncidence) (hcashutil.Amount, error) {
	v := ns.NestedReadWriteBucket(bucketCredits).Get(k)
	newv := make([]byte, creditValueSize)
	copy(newv, v)
	v = newv
	v[8] |= 1 << 0
	copy(v[9:41], spender.txHash[:])
	byteOrder.PutUint32(v[41:45], uint32(spender.block.Height))
	copy(v[45:77], spender.block.Hash[:])
	byteOrder.PutUint32(v[77:81], spender.index)
	return hcashutil.Amount(byteOrder.Uint64(v[0:8])), putRawCredit(ns, k, v)
}