func (txn Transaction) MarshalSia(w io.Writer) error {
	stamp := txn.Timestamp.Unix()
	return encoding.NewEncoder(w).EncodeAll(txn.Transaction, txn.BlockID, txn.BlockHeight, stamp, txn.FeePerByte, txn.InputValues)
}
MarshalSia implements encoding.SiaMarshaler.
package wallet
import (
	"encoding/binary"
	"fmt"
	"io"
	"strconv"
	"strings"
	"time"
	"go.sia.tech/siad/crypto"
	"go.sia.tech/siad/modules"
	"go.sia.tech/siad/types"
	"gitlab.com/NebulousLabs/encoding"
	"golang.org/x/crypto/blake2b"
)
type AddressOwner interface {
	OwnsAddress(addr types.UnlockHash) bool
}
type ChainStore interface {
	ApplyConsensusChange(reverted, applied ProcessedConsensusChange, id modules.ConsensusChangeID)
}
type Store interface {
	AddressOwner
	Addresses() []types.UnlockHash
	AddAddress(info SeedAddressInfo)
	AddressInfo(addr types.UnlockHash) (SeedAddressInfo, bool)
	RemoveAddress(addr types.UnlockHash)
	BlockRewards(n int) []BlockReward
	ConsensusChangeID() modules.ConsensusChangeID
	ChainHeight() types.BlockHeight
	FileContracts(n int) []FileContract
	FileContractHistory(id types.FileContractID) []FileContract
	LimboTransactions() []LimboTransaction
	AddToLimbo(txn types.Transaction)
	RemoveFromLimbo(id types.TransactionID)
	Memo(txid types.TransactionID) []byte
	SetMemo(txid types.TransactionID, memo []byte)
	SeedIndex() uint64
	SetSeedIndex(index uint64)
	Transaction(id types.TransactionID) (Transaction, bool)
	Transactions(n int) []types.TransactionID
	TransactionsByAddress(addr types.UnlockHash, n int) []types.TransactionID
	UnspentOutputs() []UnspentOutput
}
type ProcessedConsensusChange struct {
	Outputs             []UnspentOutput
	Transactions        []Transaction
	AddressTransactions map[types.UnlockHash][]types.TransactionID
	BlockRewards        []BlockReward
	FileContracts       []FileContract
	BlockCount          int
}
func StandardUnlockConditions(pk types.SiaPublicKey) types.UnlockConditions {
	return types.UnlockConditions{
		PublicKeys:         []types.SiaPublicKey{pk},
		SignaturesRequired: 1,
	}
}
func StandardAddress(pk types.SiaPublicKey) types.UnlockHash {
	buf := make([]byte, 65)
	buf[0] = 0x00  
	copy(buf[1:], pk.Algorithm[:])
	binary.LittleEndian.PutUint64(buf[17:], uint64(len(pk.Key)))
	buf = append(buf[:25], pk.Key...)  
	pubkeyHash := blake2b.Sum256(buf)
	timelockHash := []byte{
		0x51, 0x87, 0xb7, 0xa8, 0x02, 0x1b, 0xf4, 0xf2,
		0xc0, 0x04, 0xea, 0x3a, 0x54, 0xcf, 0xec, 0xe1,
		0x75, 0x4f, 0x11, 0xc7, 0x62, 0x4d, 0x23, 0x63,
		0xc7, 0xf4, 0xcf, 0x4f, 0xdd, 0xd1, 0x44, 0x1e,
	}
	sigsrequiredHash := []byte{
		0xb3, 0x60, 0x10, 0xeb, 0x28, 0x5c, 0x15, 0x4a,
		0x8c, 0xd6, 0x30, 0x84, 0xac, 0xbe, 0x7e, 0xac,
		0x0c, 0x4d, 0x62, 0x5a, 0xb4, 0xe1, 0xa7, 0x6e,
		0x62, 0x4a, 0x87, 0x98, 0xcb, 0x63, 0x49, 0x7b,
	}
	buf = buf[:65]
	buf[0] = 0x01  
	copy(buf[1:], timelockHash)
	copy(buf[33:], pubkeyHash[:])
	tlpkHash := blake2b.Sum256(buf)
	copy(buf[1:], tlpkHash[:])
	copy(buf[33:], sigsrequiredHash)
	return blake2b.Sum256(buf)
}
func CalculateUnlockHash(uc types.UnlockConditions) types.UnlockHash {
	if uc.Timelock == 0 && len(uc.PublicKeys) == 1 && uc.SignaturesRequired == 1 {
		return StandardAddress(uc.PublicKeys[0])
	}
	return uc.UnlockHash()
}
func StandardTransactionSignature(id crypto.Hash) types.TransactionSignature {
	return types.TransactionSignature{
		ParentID:       id,
		CoveredFields:  types.FullCoveredFields,
		PublicKeyIndex: 0,
	}
}
type UnspentOutput struct {
	types.SiacoinOutput
	ID types.SiacoinOutputID
}
func (o UnspentOutput) MarshalSia(w io.Writer) error {
	return encoding.NewEncoder(w).EncodeAll(o.SiacoinOutput, o.ID)
}
func (o *UnspentOutput) UnmarshalSia(r io.Reader) error {
	return encoding.NewDecoder(r, encoding.DefaultAllocLimit).DecodeAll(&o.SiacoinOutput, &o.ID)
}
type ValuedInput struct {
	types.SiacoinInput
	Value types.Currency
}
func (i ValuedInput) MarshalSia(w io.Writer) error {
	return encoding.NewEncoder(w).EncodeAll(i.SiacoinInput, i.Value)
}
func (i *ValuedInput) UnmarshalSia(r io.Reader) error {
	return encoding.NewDecoder(r, encoding.DefaultAllocLimit).DecodeAll(&i.SiacoinInput, &i.Value)
}
type BlockReward struct {
	UnspentOutput
	Timelock types.BlockHeight
}
func (br BlockReward) MarshalSia(w io.Writer) error {
	return encoding.NewEncoder(w).EncodeAll(br.UnspentOutput, br.Timelock)
}
func (br *BlockReward) UnmarshalSia(r io.Reader) error {
	return encoding.NewDecoder(r, encoding.DefaultAllocLimit).DecodeAll(&br.UnspentOutput, &br.Timelock)
}
type FileContract struct {
	types.FileContract
	UnlockConditions types.UnlockConditions
	ID               types.FileContractID
}
func (fc FileContract) MarshalSia(w io.Writer) error {
	return encoding.NewEncoder(w).EncodeAll(fc.FileContract, fc.UnlockConditions, fc.ID)
}
func (fc *FileContract) UnmarshalSia(r io.Reader) error {
	return encoding.NewDecoder(r, encoding.DefaultAllocLimit).DecodeAll(&fc.FileContract, &fc.UnlockConditions, &fc.ID)
}
type Transaction struct {
	types.Transaction
	BlockID     types.BlockID
	BlockHeight types.BlockHeight
	Timestamp   time.Time
	FeePerByte  types.Currency
	InputValues []types.Currency
}