func (spk *SiaPublicKey) LoadString(s string) {
	parts := strings.Split(s, ":")
	if len(parts) != 2 {
		return
	}
	var err error
	spk.Key, err = hex.DecodeString(parts[1])
	if err != nil {
		spk.Key = nil
		return
	}
	copy(spk.Algorithm[:], []byte(parts[0]))
}
LoadString is the inverse of SiaPublicKey.String().
package types
import (
	"bytes"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io"
	"math/big"
	"strings"
	"unsafe"
	"github.com/NebulousLabs/Sia/build"
	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/encoding"
)
type sanityCheckWriter struct {
	w   io.Writer
	buf *bytes.Buffer
}
func (s sanityCheckWriter) Write(p []byte) (int, error) {
	if !bytes.Equal(p, s.buf.Next(len(p))) {
		panic("encoding mismatch")
	}
	return s.w.Write(p)
}
func (b Block) MarshalSia(w io.Writer) error {
	if build.DEBUG {
		buf := new(bytes.Buffer)
		encoding.NewEncoder(buf).EncodeAll(
			b.ParentID,
			b.Nonce,
			b.Timestamp,
			b.MinerPayouts,
			b.Transactions,
		)
		w = sanityCheckWriter{w, buf}
	}
	e := encoding.NewEncoder(w)
	e.Write(b.ParentID[:])
	e.Write(b.Nonce[:])
	e.WriteUint64(uint64(b.Timestamp))
	e.WriteInt(len(b.MinerPayouts))
	for i := range b.MinerPayouts {
		b.MinerPayouts[i].MarshalSia(e)
	}
	e.WriteInt(len(b.Transactions))
	for i := range b.Transactions {
		if err := b.Transactions[i].MarshalSia(e); err != nil {
			return err
		}
	}
	return e.Err()
}
func (b *Block) UnmarshalSia(r io.Reader) error {
	if build.DEBUG {
		buf := new(bytes.Buffer)
		r = io.TeeReader(r, buf)
		defer func() {
			checkB := new(Block)
			if err := encoding.UnmarshalAll(buf.Bytes(),
				&checkB.ParentID,
				&checkB.Nonce,
				&checkB.Timestamp,
				&checkB.MinerPayouts,
				&checkB.Transactions,
			); err != nil {
				return
			}
			if crypto.HashObject(b) != crypto.HashObject(checkB) {
				panic("decoding differs!")
			}
		}()
	}
	d := encoding.NewDecoder(r)
	d.ReadFull(b.ParentID[:])
	d.ReadFull(b.Nonce[:])
	b.Timestamp = Timestamp(d.NextUint64())
	b.MinerPayouts = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
	for i := range b.MinerPayouts {
		b.MinerPayouts[i].UnmarshalSia(d)
	}
	b.Transactions = make([]Transaction, d.NextPrefix(unsafe.Sizeof(Transaction{})))
	for i := range b.Transactions {
		b.Transactions[i].UnmarshalSia(d)
	}
	return d.Err()
}
func (bid BlockID) MarshalJSON() ([]byte, error) {
	return json.Marshal(bid.String())
}
func (bid BlockID) String() string {
	return fmt.Sprintf("%x", bid[:])
}
func (bid *BlockID) LoadString(str string) error {
	return (*crypto.Hash)(bid).LoadString(str)
}
func (bid *BlockID) UnmarshalJSON(b []byte) error {
	return (*crypto.Hash)(bid).UnmarshalJSON(b)
}
func (cf CoveredFields) MarshalSia(w io.Writer) error {
	e := encoding.NewEncoder(w)
	e.WriteBool(cf.WholeTransaction)
	fields := [][]uint64{
		cf.SiacoinInputs,
		cf.SiacoinOutputs,
		cf.FileContracts,
		cf.FileContractRevisions,
		cf.StorageProofs,
		cf.SiafundInputs,
		cf.SiafundOutputs,
		cf.MinerFees,
		cf.ArbitraryData,
		cf.TransactionSignatures,
	}
	for _, f := range fields {
		e.WriteInt(len(f))
		for _, u := range f {
			e.WriteUint64(u)
		}
	}
	return e.Err()
}
func (cf CoveredFields) MarshalSiaSize() (size int) {
	size++  
	size += 8 + len(cf.SiacoinInputs)*8
	size += 8 + len(cf.SiacoinOutputs)*8
	size += 8 + len(cf.FileContracts)*8
	size += 8 + len(cf.FileContractRevisions)*8
	size += 8 + len(cf.StorageProofs)*8
	size += 8 + len(cf.SiafundInputs)*8
	size += 8 + len(cf.SiafundOutputs)*8
	size += 8 + len(cf.MinerFees)*8
	size += 8 + len(cf.ArbitraryData)*8
	size += 8 + len(cf.TransactionSignatures)*8
	return
}
func (cf *CoveredFields) UnmarshalSia(r io.Reader) error {
	d := encoding.NewDecoder(r)
	buf := make([]byte, 1)
	d.ReadFull(buf)
	cf.WholeTransaction = (buf[0] == 1)
	fields := []*[]uint64{
		&cf.SiacoinInputs,
		&cf.SiacoinOutputs,
		&cf.FileContracts,
		&cf.FileContractRevisions,
		&cf.StorageProofs,
		&cf.SiafundInputs,
		&cf.SiafundOutputs,
		&cf.MinerFees,
		&cf.ArbitraryData,
		&cf.TransactionSignatures,
	}
	for i := range fields {
		f := make([]uint64, d.NextPrefix(unsafe.Sizeof(uint64(0))))
		for i := range f {
			f[i] = d.NextUint64()
		}
		*fields[i] = f
	}
	return d.Err()
}
func (c Currency) MarshalJSON() ([]byte, error) {
	return []byte(`"` + c.String() + `"`), nil
}
func (c *Currency) UnmarshalJSON(b []byte) error {
	b = bytes.Trim(b, `"`)
	err := c.i.UnmarshalJSON(b)
	if err != nil {
		return err
	}
	if c.i.Sign() < 0 {
		c.i = *big.NewInt(0)
		return ErrNegativeCurrency
	}
	return nil
}
// MarshalSia implements the encoding.SiaMarshaler interface. It writes the
// byte-slice representation of the Currency's internal big.Int to w. Note
// that as the bytes of the big.Int correspond to the absolute value of the
// integer, there is no way to marshal a negative Currency.
func (c Currency) MarshalSia(w io.Writer) error {
	// from math/big/arith.go
	const (
		_m    = ^big.Word(0)
		_logS = _m>>8&1 + _m>>16&1 + _m>>32&1
		_S    = 1 << _logS // number of bytes per big.Word
	)
	// get raw bits and seek to first zero byte
	bits := c.i.Bits()
	var i int
	for i = len(bits)*_S - 1; i >= 0; i-- {
		if bits[i/_S]>>(uint(i%_S)*8) != 0 {
			break
		}
	}
	// write length prefix
	e := encoding.NewEncoder(w)
	e.WriteInt(i + 1)
	// write bytes
	for ; i >= 0; i-- {
		e.WriteByte(byte(bits[i/_S] >> (uint(i%_S) * 8)))
	}
	return e.Err()
}
// MarshalSiaSize returns the encoded size of c.
func (c Currency) MarshalSiaSize() int {
	// from math/big/arith.go
	const (
		_m    = ^big.Word(0)
		_logS = _m>>8&1 + _m>>16&1 + _m>>32&1
		_S    = 1 << _logS // number of bytes per big.Word
	)
	// start with the number of Words * number of bytes per Word, then
	// subtract trailing bytes that are 0
	bits := c.i.Bits()
	size := len(bits) * _S
zeros:
	for i := len(bits) - 1; i >= 0; i-- {
		for j := _S - 1; j >= 0; j-- {
			if (bits[i] >> uintptr(j*8)) != 0 {
				break zeros
			}
			size--
		}
	}
	return 8 + size // account for length prefix
}
// UnmarshalSia implements the encoding.SiaUnmarshaler interface.
func (c *Currency) UnmarshalSia(r io.Reader) error {
	d := encoding.NewDecoder(r)
	var dec Currency
	dec.i.SetBytes(d.ReadPrefixedBytes())
	*c = dec
	return d.Err()
}
// HumanString prints the Currency using human readable units. The unit used
// will be the largest unit that results in a value greater than 1. The value is
// rounded to 4 significant digits.
func (c Currency) HumanString() string {
	pico := SiacoinPrecision.Div64(1e12)
	if c.Cmp(pico) < 0 {
		return c.String() + " H"
	}
	// iterate until we find a unit greater than c
	mag := pico
	unit := ""
	for _, unit = range []string{"pS", "nS", "uS", "mS", "SC", "KS", "MS", "GS", "TS"} {
		if c.Cmp(mag.Mul64(1e3)) < 0 {
			break
		} else if unit != "TS" {
			// don't want to perform this multiply on the last iter; that
			// would give us 1.235 TS instead of 1235 TS
			mag = mag.Mul64(1e3)
		}
	}
	num := new(big.Rat).SetInt(c.Big())
	denom := new(big.Rat).SetInt(mag.Big())
	res, _ := new(big.Rat).Mul(num, denom.Inv(denom)).Float64()
	return fmt.Sprintf("%.4g %s", res, unit)
}
// String implements the fmt.Stringer interface.
func (c Currency) String() string {
	return c.i.String()
}
// Scan implements the fmt.Scanner interface, allowing Currency values to be
// scanned from text.
func (c *Currency) Scan(s fmt.ScanState, ch rune) error {
	var dec Currency
	err := dec.i.Scan(s, ch)
	if err != nil {
		return err
	}
	if dec.i.Sign() < 0 {
		return ErrNegativeCurrency
	}
	*c = dec
	return nil
}
// MarshalSia implements the encoding.SiaMarshaler interface.
func (fc FileContract) MarshalSia(w io.Writer) error {
	e := encoding.NewEncoder(w)
	e.WriteUint64(fc.FileSize)
	e.Write(fc.FileMerkleRoot[:])
	e.WriteUint64(uint64(fc.WindowStart))
	e.WriteUint64(uint64(fc.WindowEnd))
	fc.Payout.MarshalSia(e)
	e.WriteInt(len(fc.ValidProofOutputs))
	for _, sco := range fc.ValidProofOutputs {
		sco.MarshalSia(e)
	}
	e.WriteInt(len(fc.MissedProofOutputs))
	for _, sco := range fc.MissedProofOutputs {
		sco.MarshalSia(e)
	}
	e.Write(fc.UnlockHash[:])
	e.WriteUint64(fc.RevisionNumber)
	return e.Err()
}
// MarshalSiaSize returns the encoded size of fc.
func (fc FileContract) MarshalSiaSize() (size int) {
	size += 8 // FileSize
	size += len(fc.FileMerkleRoot)
	size += 8 + 8 // WindowStart + WindowEnd
	size += fc.Payout.MarshalSiaSize()
	size += 8
	for _, sco := range fc.ValidProofOutputs {
		size += sco.Value.MarshalSiaSize()
		size += len(sco.UnlockHash)
	}
	size += 8
	for _, sco := range fc.MissedProofOutputs {
		size += sco.Value.MarshalSiaSize()
		size += len(sco.UnlockHash)
	}
	size += len(fc.UnlockHash)
	size += 8 // RevisionNumber
	return
}
// UnmarshalSia implements the encoding.SiaUnmarshaler interface.
func (fc *FileContract) UnmarshalSia(r io.Reader) error {
	d := encoding.NewDecoder(r)
	fc.FileSize = d.NextUint64()
	d.ReadFull(fc.FileMerkleRoot[:])
	fc.WindowStart = BlockHeight(d.NextUint64())
	fc.WindowEnd = BlockHeight(d.NextUint64())
	fc.Payout.UnmarshalSia(d)
	fc.ValidProofOutputs = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
	for i := range fc.ValidProofOutputs {
		fc.ValidProofOutputs[i].UnmarshalSia(d)
	}
	fc.MissedProofOutputs = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
	for i := range fc.MissedProofOutputs {
		fc.MissedProofOutputs[i].UnmarshalSia(d)
	}
	d.ReadFull(fc.UnlockHash[:])
	fc.RevisionNumber = d.NextUint64()
	return d.Err()
}
// MarshalSia implements the encoding.SiaMarshaler interface.
func (fcr FileContractRevision) MarshalSia(w io.Writer) error {
	e := encoding.NewEncoder(w)
	e.Write(fcr.ParentID[:])
	fcr.UnlockConditions.MarshalSia(e)
	e.WriteUint64(fcr.NewRevisionNumber)
	e.WriteUint64(fcr.NewFileSize)
	e.Write(fcr.NewFileMerkleRoot[:])
	e.WriteUint64(uint64(fcr.NewWindowStart))
	e.WriteUint64(uint64(fcr.NewWindowEnd))
	e.WriteInt(len(fcr.NewValidProofOutputs))
	for _, sco := range fcr.NewValidProofOutputs {
		sco.MarshalSia(e)
	}
	e.WriteInt(len(fcr.NewMissedProofOutputs))
	for _, sco := range fcr.NewMissedProofOutputs {
		sco.MarshalSia(e)
	}
	e.Write(fcr.NewUnlockHash[:])
	return e.Err()
}
// MarshalSiaSize returns the encoded size of fcr.
func (fcr FileContractRevision) MarshalSiaSize() (size int) {
	size += len(fcr.ParentID)
	size += fcr.UnlockConditions.MarshalSiaSize()
	size += 8 // NewRevisionNumber
	size += 8 // NewFileSize
	size += len(fcr.NewFileMerkleRoot)
	size += 8 + 8 // NewWindowStart + NewWindowEnd
	size += 8
	for _, sco := range fcr.NewValidProofOutputs {
		size += sco.Value.MarshalSiaSize()
		size += len(sco.UnlockHash)
	}
	size += 8
	for _, sco := range fcr.NewMissedProofOutputs {
		size += sco.Value.MarshalSiaSize()
		size += len(sco.UnlockHash)
	}
	size += len(fcr.NewUnlockHash)
	return
}
// UnmarshalSia implements the encoding.SiaUnmarshaler interface.
func (fcr *FileContractRevision) UnmarshalSia(r io.Reader) error {
	d := encoding.NewDecoder(r)
	d.ReadFull(fcr.ParentID[:])
	fcr.UnlockConditions.UnmarshalSia(d)
	fcr.NewRevisionNumber = d.NextUint64()
	fcr.NewFileSize = d.NextUint64()
	d.ReadFull(fcr.NewFileMerkleRoot[:])
	fcr.NewWindowStart = BlockHeight(d.NextUint64())
	fcr.NewWindowEnd = BlockHeight(d.NextUint64())
	fcr.NewValidProofOutputs = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
	for i := range fcr.NewValidProofOutputs {
		fcr.NewValidProofOutputs[i].UnmarshalSia(d)
	}
	fcr.NewMissedProofOutputs = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
	for i := range fcr.NewMissedProofOutputs {
		fcr.NewMissedProofOutputs[i].UnmarshalSia(d)
	}
	d.ReadFull(fcr.NewUnlockHash[:])
	return d.Err()
}
// MarshalJSON marshals an id as a hex string.
func (fcid FileContractID) MarshalJSON() ([]byte, error) {
	return json.Marshal(fcid.String())
}
// String prints the id in hex.
func (fcid FileContractID) String() string {
	return fmt.Sprintf("%x", fcid[:])
}
// UnmarshalJSON decodes the json hex string of the id.
func (fcid *FileContractID) UnmarshalJSON(b []byte) error {
	return (*crypto.Hash)(fcid).UnmarshalJSON(b)
}
// MarshalJSON marshals an id as a hex string.
func (oid OutputID) MarshalJSON() ([]byte, error) {
	return json.Marshal(oid.String())
}
// String prints the id in hex.
func (oid OutputID) String() string {
	return fmt.Sprintf("%x", oid[:])
}
// UnmarshalJSON decodes the json hex string of the id.
func (oid *OutputID) UnmarshalJSON(b []byte) error {
	return (*crypto.Hash)(oid).UnmarshalJSON(b)
}
// MarshalSia implements the encoding.SiaMarshaler interface.
func (sci SiacoinInput) MarshalSia(w io.Writer) error {
	e := encoding.NewEncoder(w)
	e.Write(sci.ParentID[:])
	sci.UnlockConditions.MarshalSia(e)
	return e.Err()
}
// UnmarshalSia implements the encoding.SiaUnmarshaler interface.
func (sci *SiacoinInput) UnmarshalSia(r io.Reader) error {
	d := encoding.NewDecoder(r)
	d.ReadFull(sci.ParentID[:])
	sci.UnlockConditions.UnmarshalSia(d)
	return d.Err()
}
// MarshalSia implements the encoding.SiaMarshaler interface.
func (sco SiacoinOutput) MarshalSia(w io.Writer) error {
	e := encoding.NewEncoder(w)
	sco.Value.MarshalSia(e)
	e.Write(sco.UnlockHash[:])
	return e.Err()
}
// UnmarshalSia implements the encoding.SiaUnmarshaler interface.
func (sco *SiacoinOutput) UnmarshalSia(r io.Reader) error {
	d := encoding.NewDecoder(r)
	sco.Value.UnmarshalSia(d)
	d.ReadFull(sco.UnlockHash[:])
	return d.Err()
}
// MarshalJSON marshals an id as a hex string.
func (scoid SiacoinOutputID) MarshalJSON() ([]byte, error) {
	return json.Marshal(scoid.String())
}
// String prints the id in hex.
func (scoid SiacoinOutputID) String() string {
	return fmt.Sprintf("%x", scoid[:])
}
// UnmarshalJSON decodes the json hex string of the id.
func (scoid *SiacoinOutputID) UnmarshalJSON(b []byte) error {
	return (*crypto.Hash)(scoid).UnmarshalJSON(b)
}
// MarshalSia implements the encoding.SiaMarshaler interface.
func (sfi SiafundInput) MarshalSia(w io.Writer) error {
	e := encoding.NewEncoder(w)
	e.Write(sfi.ParentID[:])
	sfi.UnlockConditions.MarshalSia(e)
	e.Write(sfi.ClaimUnlockHash[:])
	return e.Err()
}
// UnmarshalSia implements the encoding.SiaUnmarshaler interface.
func (sfi *SiafundInput) UnmarshalSia(r io.Reader) error {
	d := encoding.NewDecoder(r)
	d.ReadFull(sfi.ParentID[:])
	sfi.UnlockConditions.UnmarshalSia(d)
	d.ReadFull(sfi.ClaimUnlockHash[:])
	return d.Err()
}
// MarshalSia implements the encoding.SiaMarshaler interface.
func (sfo SiafundOutput) MarshalSia(w io.Writer) error {
	e := encoding.NewEncoder(w)
	sfo.Value.MarshalSia(e)
	e.Write(sfo.UnlockHash[:])
	sfo.ClaimStart.MarshalSia(e)
	return e.Err()
}
// UnmarshalSia implements the encoding.SiaUnmarshaler interface.
func (sfo *SiafundOutput) UnmarshalSia(r io.Reader) error {
	d := encoding.NewDecoder(r)
	sfo.Value.UnmarshalSia(d)
	d.ReadFull(sfo.UnlockHash[:])
	sfo.ClaimStart.UnmarshalSia(d)
	return d.Err()
}
// MarshalJSON marshals an id as a hex string.
func (sfoid SiafundOutputID) MarshalJSON() ([]byte, error) {
	return json.Marshal(sfoid.String())
}
// String prints the id in hex.
func (sfoid SiafundOutputID) String() string {
	return fmt.Sprintf("%x", sfoid[:])
}
func (sfoid *SiafundOutputID) UnmarshalJSON(b []byte) error {
	return (*crypto.Hash)(sfoid).UnmarshalJSON(b)
}
func (spk SiaPublicKey) MarshalSia(w io.Writer) error {
	e := encoding.NewEncoder(w)
	e.Write(spk.Algorithm[:])
	e.WritePrefixedBytes(spk.Key)
	return e.Err()
}
func (spk *SiaPublicKey) UnmarshalSia(r io.Reader) error {
	d := encoding.NewDecoder(r)
	d.ReadFull(spk.Algorithm[:])
	spk.Key = d.ReadPrefixedBytes()
	return d.Err()
}