func putBIP0044AccountInfo(ns walletdb.ReadWriteBucket, account uint32, row *dbBIP0044AccountRow) error {
	if err := putAccountRow(ns, account, &row.dbAccountRow); err != nil {
		return err
	}
	if err := putAccountIDIndex(ns, account, row.name); err != nil {
		return err
	}
	return putAccountNameIndex(ns, account, row.name)
}
putBIP0044AccountInfo stores the provided account information to the database.
package udb
import (
	"crypto/sha256"
	"encoding/binary"
	"time"
	"decred.org/dcrwallet/v2/errors"
	"decred.org/dcrwallet/v2/kdf"
	"decred.org/dcrwallet/v2/wallet/walletdb"
)
var (
	latestMgrVersion uint32 = 6
)
type ObtainUserInputFunc func() ([]byte, error)
type addressType uint8
const (
	adtChain  addressType = iota  
	adtImport                     
	adtScript                     
)
type dbAccount interface {
	accountType() accountType
	rowData() []byte
}
type accountType uint8
const (
	actBIP0044Legacy accountType = iota
	actBIP0044
)
type dbAccountRow struct {
	acctType accountType
	rawData  []byte  
}
type dbBIP0044AccountRow struct {
	dbAccountRow
	pubKeyEncrypted           []byte
	privKeyEncrypted          []byte
	nextExternalIndex         uint32  
	nextInternalIndex         uint32  
	lastUsedExternalIndex     uint32  
	lastUsedInternalIndex     uint32  
	lastReturnedExternalIndex uint32  
	lastReturnedInternalIndex uint32  
	name                      string
	uniqueKey *kdf.Argon2idParams
}
func (r *dbBIP0044AccountRow) accountType() accountType { return actBIP0044Legacy }
func (r *dbBIP0044AccountRow) rowData() []byte          { return r.dbAccountRow.rawData }
type dbBIP0044Account struct {
	dbAccountRow
	pubKeyEncrypted  []byte
	privKeyEncrypted []byte
	lastUsedExternalIndex     uint32
	lastUsedInternalIndex     uint32
	lastReturnedExternalIndex uint32
	lastReturnedInternalIndex uint32
	name                      string
	uniqueKey                 *kdf.Argon2idParams
}
func (a *dbBIP0044Account) accountType() accountType { return actBIP0044 }
func (a *dbBIP0044Account) rowData() []byte          { return a.dbAccountRow.rawData }
func (a *dbBIP0044Account) serializeRow() []byte {
	data := make([]byte, 8+len(a.pubKeyEncrypted)+len(a.privKeyEncrypted))
	binary.LittleEndian.PutUint32(data, uint32(len(a.pubKeyEncrypted)))
	off := 4
	off += copy(data[off:], a.pubKeyEncrypted)
	binary.LittleEndian.PutUint32(data[off:], uint32(len(a.privKeyEncrypted)))
	off += 4
	copy(data[off:], a.privKeyEncrypted)
	a.rawData = data
	return data
}
func (a *dbBIP0044Account) deserializeRow(v []byte) error {
	if len(v) < 8 {
		err := errors.Errorf("BIP0044 account row bad len %d", len(v))
		return errors.E(errors.IO, err)
	}
	encPubLen := binary.LittleEndian.Uint32(v)
	off := uint32(4)
	encPub := append([]byte(nil), v[off:off+encPubLen]...)
	off += encPubLen
	encPrivLen := binary.LittleEndian.Uint32(v[off:])
	off += 4
	encPriv := append([]byte(nil), v[off:off+encPrivLen]...)
	off += encPrivLen
	if int(off) != len(v) {
		return errors.E(errors.IO, "extra bytes in BIP0044 account row")
	}
	a.pubKeyEncrypted = encPub
	a.privKeyEncrypted = encPriv
	a.rawData = v
	return nil
}
type dbAddressRow struct {
	addrType addressType
	account  uint32
	addTime  uint64
	rawData  []byte  
}
type dbChainAddressRow struct {
	dbAddressRow
	branch uint32
	index  uint32
}
type dbImportedAddressRow struct {
	dbAddressRow
	encryptedPubKey  []byte
	encryptedPrivKey []byte
}
type dbScriptAddressRow struct {
	dbAddressRow
	encryptedHash []byte
	script        []byte
}
var (
	nullVal = []byte{0}
	acctBucketName     = []byte("acct")
	acctVarsBucketName = []byte("acctvars")
	addrBucketName     = []byte("addr")
	addrAcctIdxBucketName = []byte("addracctidx")
	acctNameIdxBucketName = []byte("acctnameidx")
	acctIDIdxBucketName = []byte("acctididx")
	metaBucketName = []byte("meta")
	addrPoolMetaKeyLen = 15
	addrPoolKeyPrefixExt = []byte("addrpoolext")
	addrPoolKeyPrefixInt = []byte("addrpoolint")
	lastAccountName = []byte("lastaccount")
	lastImportedAccountName = []byte("lastimportedaccount")
	mainBucketName = []byte("main")
	mgrVersionName    = []byte("mgrver")
	mgrCreateDateName = []byte("mgrcreated")
	seedName                    = []byte("seed")
	masterPrivKeyName           = []byte("mpriv")
	masterPubKeyName            = []byte("mpub")
	cryptoPrivKeyName           = []byte("cpriv")
	cryptoPubKeyName            = []byte("cpub")
	cryptoScriptKeyName         = []byte("cscript")  
	coinTypeLegacyPrivKeyName   = []byte("ctpriv")
	coinTypeLegacyPubKeyName    = []byte("ctpub")
	coinTypeSLIP0044PrivKeyName = []byte("ctpriv-slip0044")
	coinTypeSLIP0044PubKeyName  = []byte("ctpub-slip0044")
	watchingOnlyName            = []byte("watchonly")
	slip0044Account0RowName     = []byte("slip0044acct0")
	usedAddrBucketName = []byte("usedaddrs")
)
func uint32ToBytes(number uint32) []byte {
	buf := make([]byte, 4)
	binary.LittleEndian.PutUint32(buf, number)
	return buf
}
func stringToBytes(s string) []byte {
	size := len(s)
	buf := make([]byte, 4+size)
	copy(buf[0:4], uint32ToBytes(uint32(size)))
	copy(buf[4:4+size], s)
	return buf
}
func fetchManagerVersion(ns walletdb.ReadBucket) (uint32, error) {
	mainBucket := ns.NestedReadBucket(mainBucketName)
	verBytes := mainBucket.Get(mgrVersionName)
	if verBytes == nil {
		return 0, errors.E(errors.IO, "missing address manager version")
	}
	version := binary.LittleEndian.Uint32(verBytes)
	return version, nil
}
func putManagerVersion(ns walletdb.ReadWriteBucket, version uint32) error {
	bucket := ns.NestedReadWriteBucket(mainBucketName)
	verBytes := uint32ToBytes(version)
	err := bucket.Put(mgrVersionName, verBytes)
	if err != nil {
		return errors.E(errors.IO, err)
	}
	return nil
}
func fetchMasterKeyParams(ns walletdb.ReadBucket) ([]byte, []byte, error) {
	bucket := ns.NestedReadBucket(mainBucketName)
	val := bucket.Get(masterPubKeyName)
	if val == nil {
		return nil, nil, errors.E(errors.IO, "missing master pubkey params")
	}
	pubParams := make([]byte, len(val))
	copy(pubParams, val)
	var privParams []byte
	val = bucket.Get(masterPrivKeyName)
	if val != nil {
		privParams = make([]byte, len(val))
		copy(privParams, val)
	}
	return pubParams, privParams, nil
}
func putMasterKeyParams(ns walletdb.ReadWriteBucket, pubParams, privParams []byte) error {
	bucket := ns.NestedReadWriteBucket(mainBucketName)
	if privParams != nil {
		err := bucket.Put(masterPrivKeyName, privParams)
		if err != nil {
			return errors.E(errors.IO, err)
		}
	}
	if pubParams != nil {
		err := bucket.Put(masterPubKeyName, pubParams)
		if err != nil {
			return errors.E(errors.IO, err)
		}
	}
	return nil
}
func fetchCoinTypeKeys(ns walletdb.ReadBucket) ([]byte, []byte, error) {
	bucket := ns.NestedReadBucket(mainBucketName)
	var coinTypeSLIP0044 bool
	coinTypePubKeyEnc := bucket.Get(coinTypeLegacyPubKeyName)
	if coinTypePubKeyEnc == nil {
		coinTypeSLIP0044 = true
		coinTypePubKeyEnc = bucket.Get(coinTypeSLIP0044PubKeyName)
	}
	if coinTypePubKeyEnc == nil {
		return nil, nil, errors.E(errors.IO, "missing encrypted cointype pubkey")
	}
	coinTypePrivKeyName := coinTypeLegacyPrivKeyName
	if coinTypeSLIP0044 {
		coinTypePrivKeyName = coinTypeSLIP0044PrivKeyName
	}
	coinTypePrivKeyEnc := bucket.Get(coinTypePrivKeyName)
	if coinTypePrivKeyEnc == nil {
		return nil, nil, errors.E(errors.IO, "missing encrypted cointype privkey")
	}
	return coinTypePubKeyEnc, coinTypePrivKeyEnc, nil
}
func putCoinTypeLegacyKeys(ns walletdb.ReadWriteBucket, coinTypePubKeyEnc []byte, coinTypePrivKeyEnc []byte) error {
	bucket := ns.NestedReadWriteBucket(mainBucketName)
	if coinTypePubKeyEnc != nil {
		err := bucket.Put(coinTypeLegacyPubKeyName, coinTypePubKeyEnc)
		if err != nil {
			return errors.E(errors.IO, err)
		}
	}
	if coinTypePrivKeyEnc != nil {
		err := bucket.Put(coinTypeLegacyPrivKeyName, coinTypePrivKeyEnc)
		if err != nil {
			return errors.E(errors.IO, err)
		}
	}
	return nil
}
func putCoinTypeSLIP0044Keys(ns walletdb.ReadWriteBucket, coinTypePubKeyEnc []byte, coinTypePrivKeyEnc []byte) error {
	bucket := ns.NestedReadWriteBucket(mainBucketName)
	if coinTypePubKeyEnc != nil {
		err := bucket.Put(coinTypeSLIP0044PubKeyName, coinTypePubKeyEnc)
		if err != nil {
			return errors.E(errors.IO, err)
		}
	}
	if coinTypePrivKeyEnc != nil {
		err := bucket.Put(coinTypeSLIP0044PrivKeyName, coinTypePrivKeyEnc)
		if err != nil {
			return errors.E(errors.IO, err)
		}
	}
	return nil
}
func fetchCryptoKeys(ns walletdb.ReadBucket) ([]byte, []byte, error) {
	bucket := ns.NestedReadBucket(mainBucketName)
	val := bucket.Get(cryptoPubKeyName)
	if val == nil {
		return nil, nil, errors.E(errors.IO, "missing encrypted crypto pubkey")
	}
	pubKey := make([]byte, len(val))
	copy(pubKey, val)
	var privKey []byte
	val = bucket.Get(cryptoPrivKeyName)
	if val != nil {
		privKey = make([]byte, len(val))
		copy(privKey, val)
	}
	return pubKey, privKey, nil
}
func putCryptoKeys(ns walletdb.ReadWriteBucket, pubKeyEncrypted, privKeyEncrypted []byte) error {
	bucket := ns.NestedReadWriteBucket(mainBucketName)
	if pubKeyEncrypted != nil {
		err := bucket.Put(cryptoPubKeyName, pubKeyEncrypted)
		if err != nil {
			return errors.E(errors.IO, err)
		}
	}
	if privKeyEncrypted != nil {
		err := bucket.Put(cryptoPrivKeyName, privKeyEncrypted)
		if err != nil {
			return errors.E(errors.IO, err)
		}
	}
	return nil
}
func fetchWatchingOnly(ns walletdb.ReadBucket) (bool, error) {
	bucket := ns.NestedReadBucket(mainBucketName)
	buf := bucket.Get(watchingOnlyName)
	if len(buf) != 1 {
		return false, errors.E(errors.IO, errors.Errorf("bad watching-only flag len %d", len(buf)))
	}
	return buf[0] != 0, nil
}
func putWatchingOnly(ns walletdb.ReadWriteBucket, watchingOnly bool) error {
	bucket := ns.NestedReadWriteBucket(mainBucketName)
	var encoded byte
	if watchingOnly {
		encoded = 1
	}
	if err := bucket.Put(watchingOnlyName, []byte{encoded}); err != nil {
		return errors.E(errors.IO, err)
	}
	return nil
}
func deserializeAccountRow(accountID []byte, serializedAccount []byte) (*dbAccountRow, error) {
	if len(serializedAccount) < 5 {
		return nil, errors.E(errors.IO, errors.Errorf("bad account len %d", len(serializedAccount)))
	}
	row := dbAccountRow{}
	row.acctType = accountType(serializedAccount[0])
	rdlen := binary.LittleEndian.Uint32(serializedAccount[1:5])
	row.rawData = make([]byte, rdlen)
	copy(row.rawData, serializedAccount[5:5+rdlen])
	return &row, nil
}
func serializeAccountRow(row *dbAccountRow) []byte {
	rdlen := len(row.rawData)
	buf := make([]byte, 5+rdlen)
	buf[0] = byte(row.acctType)
	binary.LittleEndian.PutUint32(buf[1:5], uint32(rdlen))
	copy(buf[5:5+rdlen], row.rawData)
	return buf
}
func deserializeBIP0044AccountRow(accountID []byte, row *dbAccountRow, dbVersion uint32) (*dbBIP0044AccountRow, error) {
	switch {
	case dbVersion < 5 && len(row.rawData) < 20,
		dbVersion >= 5 && len(row.rawData) < 28:
		return nil, errors.E(errors.IO, errors.Errorf("bip0044 account %x bad len %d", accountID, len(row.rawData)))
	}
	retRow := dbBIP0044AccountRow{
		dbAccountRow: *row,
	}
	pubLen := binary.LittleEndian.Uint32(row.rawData[0:4])
	retRow.pubKeyEncrypted = make([]byte, pubLen)
	copy(retRow.pubKeyEncrypted, row.rawData[4:4+pubLen])
	offset := 4 + pubLen
	privLen := binary.LittleEndian.Uint32(row.rawData[offset : offset+4])
	offset += 4
	retRow.privKeyEncrypted = make([]byte, privLen)
	copy(retRow.privKeyEncrypted, row.rawData[offset:offset+privLen])
	offset += privLen
	switch {
	case dbVersion == 1:
		retRow.nextExternalIndex = binary.LittleEndian.Uint32(row.rawData[offset : offset+4])
		offset += 4
		retRow.nextInternalIndex = binary.LittleEndian.Uint32(row.rawData[offset : offset+4])
		offset += 4
	case dbVersion >= 2:
		retRow.lastUsedExternalIndex = binary.LittleEndian.Uint32(row.rawData[offset : offset+4])
		retRow.lastUsedInternalIndex = binary.LittleEndian.Uint32(row.rawData[offset+4 : offset+8])
		offset += 8
	}
	switch {
	case dbVersion >= 5:
		retRow.lastReturnedExternalIndex = binary.LittleEndian.Uint32(row.rawData[offset : offset+4])
		retRow.lastReturnedInternalIndex = binary.LittleEndian.Uint32(row.rawData[offset+4 : offset+8])
		offset += 8
	}
	nameLen := binary.LittleEndian.Uint32(row.rawData[offset : offset+4])
	offset += 4
	retRow.name = string(row.rawData[offset : offset+nameLen])
	return &retRow, nil
}
func serializeBIP0044AccountRow(row *dbBIP0044AccountRow, dbVersion uint32) []byte {
	pubLen := uint32(len(row.pubKeyEncrypted))
	privLen := uint32(len(row.privKeyEncrypted))
	nameLen := uint32(len(row.name))
	rowSize := 28 + pubLen + privLen + nameLen
	switch {
	case dbVersion < 5:
		rowSize -= 8
	}
	rawData := make([]byte, rowSize)
	binary.LittleEndian.PutUint32(rawData[0:4], pubLen)
	copy(rawData[4:4+pubLen], row.pubKeyEncrypted)
	offset := 4 + pubLen
	binary.LittleEndian.PutUint32(rawData[offset:offset+4], privLen)
	offset += 4
	copy(rawData[offset:offset+privLen], row.privKeyEncrypted)
	offset += privLen
	switch {
	case dbVersion == 1:
		binary.LittleEndian.PutUint32(rawData[offset:offset+4], row.nextExternalIndex)
		offset += 4
		binary.LittleEndian.PutUint32(rawData[offset:offset+4], row.nextInternalIndex)
		offset += 4
	case dbVersion >= 2:
		binary.LittleEndian.PutUint32(rawData[offset:offset+4], row.lastUsedExternalIndex)
		binary.LittleEndian.PutUint32(rawData[offset+4:offset+8], row.lastUsedInternalIndex)
		offset += 8
	}
	switch {
	case dbVersion >= 5:
		binary.LittleEndian.PutUint32(rawData[offset:offset+4], row.lastReturnedExternalIndex)
		binary.LittleEndian.PutUint32(rawData[offset+4:offset+8], row.lastReturnedInternalIndex)
		offset += 8
	}
	binary.LittleEndian.PutUint32(rawData[offset:offset+4], nameLen)
	offset += 4
	copy(rawData[offset:offset+nameLen], row.name)
	return rawData
}
func bip0044AccountInfo(pubKeyEnc, privKeyEnc []byte, nextExtIndex, nextIntIndex,
	lastUsedExtIndex, lastUsedIntIndex, lastRetExtIndex, lastRetIntIndex uint32,
	name string, dbVersion uint32) *dbBIP0044AccountRow {
	row := &dbBIP0044AccountRow{
		dbAccountRow: dbAccountRow{
			acctType: actBIP0044Legacy,
			rawData:  nil,
		},
		pubKeyEncrypted:           pubKeyEnc,
		privKeyEncrypted:          privKeyEnc,
		nextExternalIndex:         0,
		nextInternalIndex:         0,
		lastUsedExternalIndex:     0,
		lastUsedInternalIndex:     0,
		lastReturnedExternalIndex: 0,
		lastReturnedInternalIndex: 0,
		name:                      name,
	}
	switch {
	case dbVersion == 1:
		row.nextExternalIndex = nextExtIndex
		row.nextInternalIndex = nextIntIndex
	case dbVersion >= 2:
		row.lastUsedExternalIndex = lastUsedExtIndex
		row.lastUsedInternalIndex = lastUsedIntIndex
	}
	switch {
	case dbVersion >= 5:
		row.lastReturnedExternalIndex = lastRetExtIndex
		row.lastReturnedInternalIndex = lastRetIntIndex
	}
	row.rawData = serializeBIP0044AccountRow(row, dbVersion)
	return row
}
func forEachAccount(ns walletdb.ReadBucket, fn func(account uint32) error) error {
	bucket := ns.NestedReadBucket(acctBucketName)
	return bucket.ForEach(func(k, v []byte) error {
		if v == nil {
			return nil
		}
		return fn(binary.LittleEndian.Uint32(k))
	})
}
func fetchLastAccount(ns walletdb.ReadBucket) (uint32, error) {
	bucket := ns.NestedReadBucket(metaBucketName)
	val := bucket.Get(lastAccountName)
	if len(val) != 4 {
		return 0, errors.E(errors.IO, errors.Errorf("bad last account len %d", len(val)))
	}
	account := binary.LittleEndian.Uint32(val[0:4])
	return account, nil
}
func fetchLastImportedAccount(ns walletdb.ReadBucket) (uint32, error) {
	bucket := ns.NestedReadBucket(metaBucketName)
	val := bucket.Get(lastImportedAccountName)
	if len(val) == 0 {
		return ImportedAddrAccount, nil
	}
	if len(val) != 4 {
		return 0, errors.E(errors.IO, errors.Errorf("bad last imported account len %d", len(val)))
	}
	account := binary.LittleEndian.Uint32(val[0:4])
	if account <= MaxAccountNum {
		return 0, errors.E(errors.IO, errors.Errorf("bad imported xpub account value %d", account))
	}
	return account, nil
}
func fetchAccountName(ns walletdb.ReadBucket, account uint32) (string, error) {
	bucket := ns.NestedReadBucket(acctIDIdxBucketName)
	val := bucket.Get(uint32ToBytes(account))
	if val == nil {
		return "", errors.E(errors.NotExist, errors.Errorf("no account %d", account))
	}
	offset := uint32(0)
	nameLen := binary.LittleEndian.Uint32(val[offset : offset+4])
	offset += 4
	acctName := string(val[offset : offset+nameLen])
	return acctName, nil
}
func fetchAccountByName(ns walletdb.ReadBucket, name string) (uint32, error) {
	bucket := ns.NestedReadBucket(acctNameIdxBucketName)
	val := bucket.Get(stringToBytes(name))
	if val == nil {
		return 0, errors.E(errors.NotExist, errors.Errorf("no account %q", name))
	}
	return binary.LittleEndian.Uint32(val), nil
}
func fetchAccountRow(ns walletdb.ReadBucket, account uint32, dbVersion uint32) (*dbAccountRow, error) {
	bucket := ns.NestedReadBucket(acctBucketName)
	accountID := uint32ToBytes(account)
	serializedRow := bucket.Get(accountID)
	if serializedRow == nil {
		return nil, errors.E(errors.NotExist, errors.Errorf("no account %d", account))
	}
	return deserializeAccountRow(accountID, serializedRow)
}
func fetchAccountInfo(ns walletdb.ReadBucket, account uint32, dbVersion uint32) (*dbBIP0044AccountRow, error) {
	row, err := fetchAccountRow(ns, account, dbVersion)
	if err != nil {
		return nil, err
	}
	accountID := uint32ToBytes(account)
	switch row.acctType {
	case actBIP0044Legacy:
		return deserializeBIP0044AccountRow(accountID, row, dbVersion)
	}
	return nil, errors.E(errors.IO, errors.Errorf("unknown account type %d", row.acctType))
}
func fetchDBAccount(ns walletdb.ReadBucket, account uint32, dbVersion uint32) (dbAccount, error) {
	row, err := fetchAccountRow(ns, account, dbVersion)
	if err != nil {
		return nil, err
	}
	accountID := uint32ToBytes(account)
	switch row.acctType {
	case actBIP0044Legacy:
		if dbVersion >= accountVariablesVersion {
			err := errors.Errorf("legacy BIP0044 account row unsupported "+
				"in db version %v", dbVersion)
			return nil, errors.E(err)
		}
		return deserializeBIP0044AccountRow(accountID, row, dbVersion)
	case actBIP0044:
		bucketKey := uint32ToBytes(account)
		varsBucket := ns.NestedReadBucket(acctVarsBucketName).
			NestedReadBucket(bucketKey)
		var r accountVarReader
		lastUsedExt := r.getAccountUint32Var(varsBucket, acctVarLastUsedExternal)
		lastUsedInt := r.getAccountUint32Var(varsBucket, acctVarLastUsedInternal)
		lastRetExt := r.getAccountUint32Var(varsBucket, acctVarLastReturnedExternal)
		lastRetInt := r.getAccountUint32Var(varsBucket, acctVarLastReturnedInternal)
		name := r.getAccountStringVar(varsBucket, acctVarName)
		kdfParams := r.getAccountKDFVar(varsBucket, acctVarKDF)
		if r.err != nil {
			return nil, errors.E(errors.IO, err)
		}
		a := new(dbBIP0044Account)
		a.dbAccountRow = *row
		err := a.deserializeRow(row.rawData)
		if err != nil {
			return nil, err
		}
		a.lastUsedExternalIndex = lastUsedExt
		a.lastUsedInternalIndex = lastUsedInt
		a.lastReturnedExternalIndex = lastRetExt
		a.lastReturnedInternalIndex = lastRetInt
		a.name = name
		a.uniqueKey = kdfParams
		return a, nil
	}
	return nil, errors.E(errors.IO, errors.Errorf("unknown account type %d", row.acctType))
}
func accountVarsBucket(ns walletdb.ReadWriteBucket, account uint32) walletdb.ReadWriteBucket {
	accountKey := uint32ToBytes(account)
	return ns.NestedReadWriteBucket(acctVarsBucketName).NestedReadWriteBucket(accountKey)
}
func deleteAccountNameIndex(ns walletdb.ReadWriteBucket, name string) error {
	bucket := ns.NestedReadWriteBucket(acctNameIdxBucketName)
	err := bucket.Delete(stringToBytes(name))
	if err != nil {
		return errors.E(errors.IO, err)
	}
	return nil
}
func deleteAccountIDIndex(ns walletdb.ReadWriteBucket, account uint32) error {
	bucket := ns.NestedReadWriteBucket(acctIDIdxBucketName)
	err := bucket.Delete(uint32ToBytes(account))
	if err != nil {
		return errors.E(errors.IO, err)
	}
	return nil
}
func putAccountNameIndex(ns walletdb.ReadWriteBucket, account uint32, name string) error {
	bucket := ns.NestedReadWriteBucket(acctNameIdxBucketName)
	err := bucket.Put(stringToBytes(name), uint32ToBytes(account))
	if err != nil {
		return errors.E(errors.IO, err)
	}
	return nil
}
func putAccountIDIndex(ns walletdb.ReadWriteBucket, account uint32, name string) error {
	bucket := ns.NestedReadWriteBucket(acctIDIdxBucketName)
	err := bucket.Put(uint32ToBytes(account), stringToBytes(name))
	if err != nil {
		return errors.E(errors.IO, err)
	}
	return nil
}
func putAddrAccountIndex(ns walletdb.ReadWriteBucket, account uint32, addrHash []byte) error {
	bucket := ns.NestedReadWriteBucket(addrAcctIdxBucketName)
	err := bucket.Put(addrHash, uint32ToBytes(account))
	if err != nil {
		return errors.E(errors.IO, err)
	}
	bucket, err = bucket.CreateBucketIfNotExists(uint32ToBytes(account))
	if err != nil {
		return errors.E(errors.IO, err)
	}
	err = bucket.Put(addrHash, nullVal)
	if err != nil {
		return errors.E(errors.IO, err)
	}
	return nil
}
func putAccountRow(ns walletdb.ReadWriteBucket, account uint32, row *dbAccountRow) error {
	bucket := ns.NestedReadWriteBucket(acctBucketName)
	err := bucket.Put(uint32ToBytes(account), serializeAccountRow(row))
	if err != nil {
		return errors.E(errors.IO, err)
	}
	return nil
}