github.com/fozzysec/SiaPrime@v0.0.0-20190612043147-66c8e8d11fe3/types/encoding.go (about)

     1  package types
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"encoding/hex"
     7  	"encoding/json"
     8  	"fmt"
     9  	"io"
    10  	"math/big"
    11  	"strings"
    12  	"unsafe"
    13  
    14  	"SiaPrime/build"
    15  	"SiaPrime/crypto"
    16  	"SiaPrime/encoding"
    17  )
    18  
    19  // sanityCheckWriter checks that the bytes written to w exactly match the
    20  // bytes in buf.
    21  type sanityCheckWriter struct {
    22  	w   io.Writer
    23  	buf *bytes.Buffer
    24  }
    25  
    26  func (s sanityCheckWriter) Write(p []byte) (int, error) {
    27  	if !bytes.Equal(p, s.buf.Next(len(p))) {
    28  		panic("encoding mismatch")
    29  	}
    30  	return s.w.Write(p)
    31  }
    32  
    33  // An encHelper provides convenience methods and reduces allocations during
    34  // encoding. All of its methods become no-ops after the encHelper encounters a
    35  // Write error.
    36  type encHelper struct {
    37  	w   io.Writer
    38  	buf []byte
    39  	err error
    40  }
    41  
    42  // reset reslices e's internal buffer to have a length of 0.
    43  func (e *encHelper) reset() {
    44  	e.buf = e.buf[:0]
    45  }
    46  
    47  // append appends a byte to e's internal buffer.
    48  func (e *encHelper) append(b byte) {
    49  	if e.err != nil {
    50  		return
    51  	}
    52  	e.buf = append(e.buf, b)
    53  }
    54  
    55  // flush writes e's internal buffer to the underlying io.Writer.
    56  func (e *encHelper) flush() (int, error) {
    57  	if e.err != nil {
    58  		return 0, e.err
    59  	}
    60  	n, err := e.w.Write(e.buf)
    61  	if e.err == nil {
    62  		e.err = err
    63  	}
    64  	return n, e.err
    65  }
    66  
    67  // Write implements the io.Writer interface.
    68  func (e *encHelper) Write(p []byte) (int, error) {
    69  	if e.err != nil {
    70  		return 0, e.err
    71  	}
    72  	e.buf = append(e.buf[:0], p...)
    73  	return e.flush()
    74  }
    75  
    76  // WriteUint64 writes a uint64 value to the underlying io.Writer.
    77  func (e *encHelper) WriteUint64(u uint64) {
    78  	if e.err != nil {
    79  		return
    80  	}
    81  	e.buf = e.buf[:8]
    82  	binary.LittleEndian.PutUint64(e.buf, u)
    83  	e.flush()
    84  }
    85  
    86  // WriteUint64 writes an int value to the underlying io.Writer.
    87  func (e *encHelper) WriteInt(i int) {
    88  	e.WriteUint64(uint64(i))
    89  }
    90  
    91  // WriteUint64 writes p to the underlying io.Writer, prefixed by its length.
    92  func (e *encHelper) WritePrefix(p []byte) {
    93  	e.WriteInt(len(p))
    94  	e.Write(p)
    95  }
    96  
    97  // Err returns the first non-nil error encountered by e.
    98  func (e *encHelper) Err() error {
    99  	return e.err
   100  }
   101  
   102  // encoder converts w to an encHelper. If w's underlying type is already
   103  // *encHelper, it is returned; otherwise, a new encHelper is allocated.
   104  func encoder(w io.Writer) *encHelper {
   105  	if e, ok := w.(*encHelper); ok {
   106  		return e
   107  	}
   108  	return &encHelper{
   109  		w:   w,
   110  		buf: make([]byte, 64), // large enough for everything but ArbitraryData
   111  	}
   112  }
   113  
   114  // A decHelper provides convenience methods and reduces allocations during
   115  // decoding. All of its methods become no-ops after the decHelper encounters a
   116  // Read error.
   117  type decHelper struct {
   118  	r   io.Reader
   119  	buf [8]byte
   120  	err error
   121  	n   int // total number of bytes read
   122  }
   123  
   124  // Read implements the io.Reader interface.
   125  func (d *decHelper) Read(p []byte) (int, error) {
   126  	if d.err != nil {
   127  		return 0, d.err
   128  	}
   129  	n, err := d.r.Read(p)
   130  	if d.err == nil {
   131  		d.err = err
   132  	}
   133  	d.n += n
   134  	if d.n > encoding.MaxObjectSize {
   135  		d.err = encoding.ErrObjectTooLarge(d.n)
   136  	}
   137  	return n, d.err
   138  }
   139  
   140  // ReadFull is shorthand for io.ReadFull(d, p).
   141  func (d *decHelper) ReadFull(p []byte) {
   142  	if d.err != nil {
   143  		return
   144  	}
   145  	io.ReadFull(d, p)
   146  }
   147  
   148  // ReadPrefix reads a length-prefix, allocates a byte slice with that length,
   149  // reads into the byte slice, and returns it. If the length prefix exceeds
   150  // encoding.MaxSliceSize, ReadPrefix returns nil and sets d.Err().
   151  func (d *decHelper) ReadPrefix() []byte {
   152  	n := d.NextPrefix(unsafe.Sizeof(byte(0))) // if too large, n == 0
   153  	b := make([]byte, n)
   154  	d.ReadFull(b)
   155  	if d.err != nil {
   156  		return nil
   157  	}
   158  	return b
   159  }
   160  
   161  // NextUint64 reads the next 8 bytes and returns them as a uint64.
   162  func (d *decHelper) NextUint64() uint64 {
   163  	d.ReadFull(d.buf[:])
   164  	if d.err != nil {
   165  		return 0
   166  	}
   167  	return encoding.DecUint64(d.buf[:])
   168  }
   169  
   170  // NextPrefix is like NextUint64, but performs sanity checks on the prefix.
   171  // Specifically, if the prefix multiplied by elemSize exceeds
   172  // encoding.MaxSliceSize, NextPrefix returns 0 and sets d.Err().
   173  func (d *decHelper) NextPrefix(elemSize uintptr) uint64 {
   174  	n := d.NextUint64()
   175  	if d.err != nil {
   176  		return 0
   177  	}
   178  	if n > 1<<31-1 || n*uint64(elemSize) > encoding.MaxSliceSize {
   179  		d.err = encoding.ErrSliceTooLarge{Len: n, ElemSize: uint64(elemSize)}
   180  		return 0
   181  	}
   182  	return n
   183  }
   184  
   185  // Err returns the first non-nil error encountered by d.
   186  func (d *decHelper) Err() error {
   187  	return d.err
   188  }
   189  
   190  // decoder converts r to a decHelper. If r's underlying type is already
   191  // *decHelper, it is returned; otherwise, a new decHelper is allocated.
   192  func decoder(r io.Reader) *decHelper {
   193  	if d, ok := r.(*decHelper); ok {
   194  		return d
   195  	}
   196  	return &decHelper{r: r}
   197  }
   198  
   199  // MarshalSia implements the encoding.SiaMarshaler interface.
   200  func (b Block) MarshalSia(w io.Writer) error {
   201  	if build.DEBUG {
   202  		// Sanity check: compare against the old encoding
   203  		buf := new(bytes.Buffer)
   204  		encoding.NewEncoder(buf).EncodeAll(
   205  			b.ParentID,
   206  			b.Nonce,
   207  			b.Timestamp,
   208  			b.MinerPayouts,
   209  			b.Transactions,
   210  		)
   211  		w = sanityCheckWriter{w, buf}
   212  	}
   213  
   214  	e := encoder(w)
   215  	e.Write(b.ParentID[:])
   216  	e.Write(b.Nonce[:])
   217  	e.WriteUint64(uint64(b.Timestamp))
   218  	e.WriteInt(len(b.MinerPayouts))
   219  	for i := range b.MinerPayouts {
   220  		b.MinerPayouts[i].MarshalSia(e)
   221  	}
   222  	e.WriteInt(len(b.Transactions))
   223  	for i := range b.Transactions {
   224  		if err := b.Transactions[i].MarshalSia(e); err != nil {
   225  			return err
   226  		}
   227  	}
   228  	return e.Err()
   229  }
   230  
   231  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   232  func (b *Block) UnmarshalSia(r io.Reader) error {
   233  	if build.DEBUG {
   234  		// Sanity check: compare against the old decoding
   235  		buf := new(bytes.Buffer)
   236  		r = io.TeeReader(r, buf)
   237  
   238  		defer func() {
   239  			checkB := new(Block)
   240  			if err := encoding.UnmarshalAll(buf.Bytes(),
   241  				&checkB.ParentID,
   242  				&checkB.Nonce,
   243  				&checkB.Timestamp,
   244  				&checkB.MinerPayouts,
   245  				&checkB.Transactions,
   246  			); err != nil {
   247  				// don't check invalid blocks
   248  				return
   249  			}
   250  			if crypto.HashObject(b) != crypto.HashObject(checkB) {
   251  				panic("decoding differs!")
   252  			}
   253  		}()
   254  	}
   255  
   256  	d := decoder(r)
   257  	d.ReadFull(b.ParentID[:])
   258  	d.ReadFull(b.Nonce[:])
   259  	b.Timestamp = Timestamp(d.NextUint64())
   260  	// MinerPayouts
   261  	b.MinerPayouts = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
   262  	for i := range b.MinerPayouts {
   263  		b.MinerPayouts[i].UnmarshalSia(d)
   264  	}
   265  	// Transactions
   266  	b.Transactions = make([]Transaction, d.NextPrefix(unsafe.Sizeof(Transaction{})))
   267  	for i := range b.Transactions {
   268  		b.Transactions[i].UnmarshalSia(d)
   269  	}
   270  	return d.Err()
   271  }
   272  
   273  // MarshalJSON marshales a block id as a hex string.
   274  func (bid BlockID) MarshalJSON() ([]byte, error) {
   275  	return json.Marshal(bid.String())
   276  }
   277  
   278  // String prints the block id in hex.
   279  func (bid BlockID) String() string {
   280  	return fmt.Sprintf("%x", bid[:])
   281  }
   282  
   283  // LoadString loads a BlockID from a string
   284  func (bid *BlockID) LoadString(str string) error {
   285  	return (*crypto.Hash)(bid).LoadString(str)
   286  }
   287  
   288  // UnmarshalJSON decodes the json hex string of the block id.
   289  func (bid *BlockID) UnmarshalJSON(b []byte) error {
   290  	return (*crypto.Hash)(bid).UnmarshalJSON(b)
   291  }
   292  
   293  // MarshalSia implements the encoding.SiaMarshaler interface.
   294  func (cf CoveredFields) MarshalSia(w io.Writer) error {
   295  	e := encoder(w)
   296  	e.reset()
   297  	if cf.WholeTransaction {
   298  		e.append(1)
   299  	} else {
   300  		e.append(0)
   301  	}
   302  	e.flush()
   303  	fields := [][]uint64{
   304  		cf.SiacoinInputs,
   305  		cf.SiacoinOutputs,
   306  		cf.FileContracts,
   307  		cf.FileContractRevisions,
   308  		cf.StorageProofs,
   309  		cf.SiafundInputs,
   310  		cf.SiafundOutputs,
   311  		cf.MinerFees,
   312  		cf.ArbitraryData,
   313  		cf.TransactionSignatures,
   314  	}
   315  	for _, f := range fields {
   316  		e.WriteInt(len(f))
   317  		for _, u := range f {
   318  			e.WriteUint64(u)
   319  		}
   320  	}
   321  	return e.Err()
   322  }
   323  
   324  // MarshalSiaSize returns the encoded size of cf.
   325  func (cf CoveredFields) MarshalSiaSize() (size int) {
   326  	size++ // WholeTransaction
   327  	size += 8 + len(cf.SiacoinInputs)*8
   328  	size += 8 + len(cf.SiacoinOutputs)*8
   329  	size += 8 + len(cf.FileContracts)*8
   330  	size += 8 + len(cf.FileContractRevisions)*8
   331  	size += 8 + len(cf.StorageProofs)*8
   332  	size += 8 + len(cf.SiafundInputs)*8
   333  	size += 8 + len(cf.SiafundOutputs)*8
   334  	size += 8 + len(cf.MinerFees)*8
   335  	size += 8 + len(cf.ArbitraryData)*8
   336  	size += 8 + len(cf.TransactionSignatures)*8
   337  	return
   338  }
   339  
   340  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   341  func (cf *CoveredFields) UnmarshalSia(r io.Reader) error {
   342  	d := decoder(r)
   343  	buf := make([]byte, 1)
   344  	d.ReadFull(buf)
   345  	cf.WholeTransaction = (buf[0] == 1)
   346  	fields := []*[]uint64{
   347  		&cf.SiacoinInputs,
   348  		&cf.SiacoinOutputs,
   349  		&cf.FileContracts,
   350  		&cf.FileContractRevisions,
   351  		&cf.StorageProofs,
   352  		&cf.SiafundInputs,
   353  		&cf.SiafundOutputs,
   354  		&cf.MinerFees,
   355  		&cf.ArbitraryData,
   356  		&cf.TransactionSignatures,
   357  	}
   358  	for i := range fields {
   359  		f := make([]uint64, d.NextPrefix(unsafe.Sizeof(uint64(0))))
   360  		for i := range f {
   361  			f[i] = d.NextUint64()
   362  		}
   363  		*fields[i] = f
   364  	}
   365  	return d.Err()
   366  }
   367  
   368  // MarshalJSON implements the json.Marshaler interface.
   369  func (c Currency) MarshalJSON() ([]byte, error) {
   370  	// Must enclosed the value in quotes; otherwise JS will convert it to a
   371  	// double and lose precision.
   372  	return []byte(`"` + c.String() + `"`), nil
   373  }
   374  
   375  // UnmarshalJSON implements the json.Unmarshaler interface. An error is
   376  // returned if a negative number is provided.
   377  func (c *Currency) UnmarshalJSON(b []byte) error {
   378  	// UnmarshalJSON does not expect quotes
   379  	b = bytes.Trim(b, `"`)
   380  	err := c.i.UnmarshalJSON(b)
   381  	if err != nil {
   382  		return err
   383  	}
   384  	if c.i.Sign() < 0 {
   385  		c.i = *big.NewInt(0)
   386  		return ErrNegativeCurrency
   387  	}
   388  	return nil
   389  }
   390  
   391  // MarshalSia implements the encoding.SiaMarshaler interface. It writes the
   392  // byte-slice representation of the Currency's internal big.Int to w. Note
   393  // that as the bytes of the big.Int correspond to the absolute value of the
   394  // integer, there is no way to marshal a negative Currency.
   395  func (c Currency) MarshalSia(w io.Writer) error {
   396  	// from math/big/arith.go
   397  	const (
   398  		_m    = ^big.Word(0)
   399  		_logS = _m>>8&1 + _m>>16&1 + _m>>32&1
   400  		_S    = 1 << _logS // number of bytes per big.Word
   401  	)
   402  
   403  	// get raw bits and seek to first zero byte
   404  	bits := c.i.Bits()
   405  	var i int
   406  	for i = len(bits)*_S - 1; i >= 0; i-- {
   407  		if bits[i/_S]>>(uint(i%_S)*8) != 0 {
   408  			break
   409  		}
   410  	}
   411  
   412  	// write length prefix
   413  	e := encoder(w)
   414  	e.WriteInt(i + 1)
   415  
   416  	// write bytes
   417  	e.reset()
   418  	for ; i >= 0; i-- {
   419  		e.append(byte(bits[i/_S] >> (uint(i%_S) * 8)))
   420  	}
   421  	e.flush()
   422  	return e.Err()
   423  }
   424  
   425  // MarshalSiaSize returns the encoded size of c.
   426  func (c Currency) MarshalSiaSize() int {
   427  	// from math/big/arith.go
   428  	const (
   429  		_m    = ^big.Word(0)
   430  		_logS = _m>>8&1 + _m>>16&1 + _m>>32&1
   431  		_S    = 1 << _logS // number of bytes per big.Word
   432  	)
   433  
   434  	// start with the number of Words * number of bytes per Word, then
   435  	// subtract trailing bytes that are 0
   436  	bits := c.i.Bits()
   437  	size := len(bits) * _S
   438  zeros:
   439  	for i := len(bits) - 1; i >= 0; i-- {
   440  		for j := _S - 1; j >= 0; j-- {
   441  			if (bits[i] >> uintptr(j*8)) != 0 {
   442  				break zeros
   443  			}
   444  			size--
   445  		}
   446  	}
   447  	return 8 + size // account for length prefix
   448  }
   449  
   450  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   451  func (c *Currency) UnmarshalSia(r io.Reader) error {
   452  	d := decoder(r)
   453  	var dec Currency
   454  	dec.i.SetBytes(d.ReadPrefix())
   455  	*c = dec
   456  	return d.Err()
   457  }
   458  
   459  // HumanString prints the Currency using human readable units. The unit used
   460  // will be the largest unit that results in a value greater than 1. The value is
   461  // rounded to 4 significant digits.
   462  func (c Currency) HumanString() string {
   463  	pico := SiacoinPrecision.Div64(1e12)
   464  	if c.Cmp(pico) < 0 {
   465  		return c.String() + " H"
   466  	}
   467  
   468  	// iterate until we find a unit greater than c
   469  	mag := pico
   470  	unit := ""
   471  	for _, unit = range []string{"pS", "nS", "uS", "mS", "SC", "KS", "MS", "GS", "TS"} {
   472  		if c.Cmp(mag.Mul64(1e3)) < 0 {
   473  			break
   474  		} else if unit != "TS" {
   475  			// don't want to perform this multiply on the last iter; that
   476  			// would give us 1.235 TS instead of 1235 TS
   477  			mag = mag.Mul64(1e3)
   478  		}
   479  	}
   480  
   481  	num := new(big.Rat).SetInt(c.Big())
   482  	denom := new(big.Rat).SetInt(mag.Big())
   483  	res, _ := new(big.Rat).Mul(num, denom.Inv(denom)).Float64()
   484  
   485  	return fmt.Sprintf("%.4g %s", res, unit)
   486  }
   487  
   488  // String implements the fmt.Stringer interface.
   489  func (c Currency) String() string {
   490  	return c.i.String()
   491  }
   492  
   493  // Scan implements the fmt.Scanner interface, allowing Currency values to be
   494  // scanned from text.
   495  func (c *Currency) Scan(s fmt.ScanState, ch rune) error {
   496  	var dec Currency
   497  	err := dec.i.Scan(s, ch)
   498  	if err != nil {
   499  		return err
   500  	}
   501  	if dec.i.Sign() < 0 {
   502  		return ErrNegativeCurrency
   503  	}
   504  	*c = dec
   505  	return nil
   506  }
   507  
   508  // MarshalSia implements the encoding.SiaMarshaler interface.
   509  func (fc FileContract) MarshalSia(w io.Writer) error {
   510  	e := encoder(w)
   511  	e.WriteUint64(fc.FileSize)
   512  	e.Write(fc.FileMerkleRoot[:])
   513  	e.WriteUint64(uint64(fc.WindowStart))
   514  	e.WriteUint64(uint64(fc.WindowEnd))
   515  	fc.Payout.MarshalSia(e)
   516  	e.WriteInt(len(fc.ValidProofOutputs))
   517  	for _, sco := range fc.ValidProofOutputs {
   518  		sco.MarshalSia(e)
   519  	}
   520  	e.WriteInt(len(fc.MissedProofOutputs))
   521  	for _, sco := range fc.MissedProofOutputs {
   522  		sco.MarshalSia(e)
   523  	}
   524  	e.Write(fc.UnlockHash[:])
   525  	e.WriteUint64(fc.RevisionNumber)
   526  	return e.Err()
   527  }
   528  
   529  // MarshalSiaSize returns the encoded size of fc.
   530  func (fc FileContract) MarshalSiaSize() (size int) {
   531  	size += 8 // FileSize
   532  	size += len(fc.FileMerkleRoot)
   533  	size += 8 + 8 // WindowStart + WindowEnd
   534  	size += fc.Payout.MarshalSiaSize()
   535  	size += 8
   536  	for _, sco := range fc.ValidProofOutputs {
   537  		size += sco.Value.MarshalSiaSize()
   538  		size += len(sco.UnlockHash)
   539  	}
   540  	size += 8
   541  	for _, sco := range fc.MissedProofOutputs {
   542  		size += sco.Value.MarshalSiaSize()
   543  		size += len(sco.UnlockHash)
   544  	}
   545  	size += len(fc.UnlockHash)
   546  	size += 8 // RevisionNumber
   547  	return
   548  }
   549  
   550  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   551  func (fc *FileContract) UnmarshalSia(r io.Reader) error {
   552  	d := decoder(r)
   553  	fc.FileSize = d.NextUint64()
   554  	d.ReadFull(fc.FileMerkleRoot[:])
   555  	fc.WindowStart = BlockHeight(d.NextUint64())
   556  	fc.WindowEnd = BlockHeight(d.NextUint64())
   557  	fc.Payout.UnmarshalSia(d)
   558  	fc.ValidProofOutputs = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
   559  	for i := range fc.ValidProofOutputs {
   560  		fc.ValidProofOutputs[i].UnmarshalSia(d)
   561  	}
   562  	fc.MissedProofOutputs = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
   563  	for i := range fc.MissedProofOutputs {
   564  		fc.MissedProofOutputs[i].UnmarshalSia(d)
   565  	}
   566  	d.ReadFull(fc.UnlockHash[:])
   567  	fc.RevisionNumber = d.NextUint64()
   568  	return d.Err()
   569  }
   570  
   571  // MarshalSia implements the encoding.SiaMarshaler interface.
   572  func (fcr FileContractRevision) MarshalSia(w io.Writer) error {
   573  	e := encoder(w)
   574  	e.Write(fcr.ParentID[:])
   575  	fcr.UnlockConditions.MarshalSia(e)
   576  	e.WriteUint64(fcr.NewRevisionNumber)
   577  	e.WriteUint64(fcr.NewFileSize)
   578  	e.Write(fcr.NewFileMerkleRoot[:])
   579  	e.WriteUint64(uint64(fcr.NewWindowStart))
   580  	e.WriteUint64(uint64(fcr.NewWindowEnd))
   581  	e.WriteInt(len(fcr.NewValidProofOutputs))
   582  	for _, sco := range fcr.NewValidProofOutputs {
   583  		sco.MarshalSia(e)
   584  	}
   585  	e.WriteInt(len(fcr.NewMissedProofOutputs))
   586  	for _, sco := range fcr.NewMissedProofOutputs {
   587  		sco.MarshalSia(e)
   588  	}
   589  	e.Write(fcr.NewUnlockHash[:])
   590  	return e.Err()
   591  }
   592  
   593  // MarshalSiaSize returns the encoded size of fcr.
   594  func (fcr FileContractRevision) MarshalSiaSize() (size int) {
   595  	size += len(fcr.ParentID)
   596  	size += fcr.UnlockConditions.MarshalSiaSize()
   597  	size += 8 // NewRevisionNumber
   598  	size += 8 // NewFileSize
   599  	size += len(fcr.NewFileMerkleRoot)
   600  	size += 8 + 8 // NewWindowStart + NewWindowEnd
   601  	size += 8
   602  	for _, sco := range fcr.NewValidProofOutputs {
   603  		size += sco.Value.MarshalSiaSize()
   604  		size += len(sco.UnlockHash)
   605  	}
   606  	size += 8
   607  	for _, sco := range fcr.NewMissedProofOutputs {
   608  		size += sco.Value.MarshalSiaSize()
   609  		size += len(sco.UnlockHash)
   610  	}
   611  	size += len(fcr.NewUnlockHash)
   612  	return
   613  }
   614  
   615  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   616  func (fcr *FileContractRevision) UnmarshalSia(r io.Reader) error {
   617  	d := decoder(r)
   618  	d.ReadFull(fcr.ParentID[:])
   619  	fcr.UnlockConditions.UnmarshalSia(d)
   620  	fcr.NewRevisionNumber = d.NextUint64()
   621  	fcr.NewFileSize = d.NextUint64()
   622  	d.ReadFull(fcr.NewFileMerkleRoot[:])
   623  	fcr.NewWindowStart = BlockHeight(d.NextUint64())
   624  	fcr.NewWindowEnd = BlockHeight(d.NextUint64())
   625  	fcr.NewValidProofOutputs = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
   626  	for i := range fcr.NewValidProofOutputs {
   627  		fcr.NewValidProofOutputs[i].UnmarshalSia(d)
   628  	}
   629  	fcr.NewMissedProofOutputs = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
   630  	for i := range fcr.NewMissedProofOutputs {
   631  		fcr.NewMissedProofOutputs[i].UnmarshalSia(d)
   632  	}
   633  	d.ReadFull(fcr.NewUnlockHash[:])
   634  	return d.Err()
   635  }
   636  
   637  // LoadString loads a FileContractID from a string
   638  func (fcid *FileContractID) LoadString(str string) error {
   639  	return (*crypto.Hash)(fcid).LoadString(str)
   640  }
   641  
   642  // MarshalJSON marshals an id as a hex string.
   643  func (fcid FileContractID) MarshalJSON() ([]byte, error) {
   644  	return json.Marshal(fcid.String())
   645  }
   646  
   647  // String prints the id in hex.
   648  func (fcid FileContractID) String() string {
   649  	return fmt.Sprintf("%x", fcid[:])
   650  }
   651  
   652  // UnmarshalJSON decodes the json hex string of the id.
   653  func (fcid *FileContractID) UnmarshalJSON(b []byte) error {
   654  	return (*crypto.Hash)(fcid).UnmarshalJSON(b)
   655  }
   656  
   657  // MarshalJSON marshals an id as a hex string.
   658  func (oid OutputID) MarshalJSON() ([]byte, error) {
   659  	return json.Marshal(oid.String())
   660  }
   661  
   662  // String prints the id in hex.
   663  func (oid OutputID) String() string {
   664  	return fmt.Sprintf("%x", oid[:])
   665  }
   666  
   667  // UnmarshalJSON decodes the json hex string of the id.
   668  func (oid *OutputID) UnmarshalJSON(b []byte) error {
   669  	return (*crypto.Hash)(oid).UnmarshalJSON(b)
   670  }
   671  
   672  // MarshalSia implements the encoding.SiaMarshaler interface.
   673  func (sci SiacoinInput) MarshalSia(w io.Writer) error {
   674  	e := encoder(w)
   675  	e.Write(sci.ParentID[:])
   676  	sci.UnlockConditions.MarshalSia(e)
   677  	return e.Err()
   678  }
   679  
   680  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   681  func (sci *SiacoinInput) UnmarshalSia(r io.Reader) error {
   682  	d := decoder(r)
   683  	d.ReadFull(sci.ParentID[:])
   684  	sci.UnlockConditions.UnmarshalSia(d)
   685  	return d.Err()
   686  }
   687  
   688  // MarshalSia implements the encoding.SiaMarshaler interface.
   689  func (sco SiacoinOutput) MarshalSia(w io.Writer) error {
   690  	e := encoder(w)
   691  	sco.Value.MarshalSia(e)
   692  	e.Write(sco.UnlockHash[:])
   693  	return e.Err()
   694  }
   695  
   696  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   697  func (sco *SiacoinOutput) UnmarshalSia(r io.Reader) error {
   698  	d := decoder(r)
   699  	sco.Value.UnmarshalSia(d)
   700  	d.ReadFull(sco.UnlockHash[:])
   701  	return d.Err()
   702  }
   703  
   704  // MarshalJSON marshals an id as a hex string.
   705  func (scoid SiacoinOutputID) MarshalJSON() ([]byte, error) {
   706  	return json.Marshal(scoid.String())
   707  }
   708  
   709  // String prints the id in hex.
   710  func (scoid SiacoinOutputID) String() string {
   711  	return fmt.Sprintf("%x", scoid[:])
   712  }
   713  
   714  // UnmarshalJSON decodes the json hex string of the id.
   715  func (scoid *SiacoinOutputID) UnmarshalJSON(b []byte) error {
   716  	return (*crypto.Hash)(scoid).UnmarshalJSON(b)
   717  }
   718  
   719  // MarshalSia implements the encoding.SiaMarshaler interface.
   720  func (sfi SiafundInput) MarshalSia(w io.Writer) error {
   721  	e := encoder(w)
   722  	e.Write(sfi.ParentID[:])
   723  	sfi.UnlockConditions.MarshalSia(e)
   724  	e.Write(sfi.ClaimUnlockHash[:])
   725  	return e.Err()
   726  }
   727  
   728  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   729  func (sfi *SiafundInput) UnmarshalSia(r io.Reader) error {
   730  	d := decoder(r)
   731  	d.ReadFull(sfi.ParentID[:])
   732  	sfi.UnlockConditions.UnmarshalSia(d)
   733  	d.ReadFull(sfi.ClaimUnlockHash[:])
   734  	return d.Err()
   735  }
   736  
   737  // MarshalSia implements the encoding.SiaMarshaler interface.
   738  func (sfo SiafundOutput) MarshalSia(w io.Writer) error {
   739  	e := encoder(w)
   740  	sfo.Value.MarshalSia(e)
   741  	e.Write(sfo.UnlockHash[:])
   742  	sfo.ClaimStart.MarshalSia(e)
   743  	return e.Err()
   744  }
   745  
   746  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   747  func (sfo *SiafundOutput) UnmarshalSia(r io.Reader) error {
   748  	d := decoder(r)
   749  	sfo.Value.UnmarshalSia(d)
   750  	d.ReadFull(sfo.UnlockHash[:])
   751  	sfo.ClaimStart.UnmarshalSia(d)
   752  	return d.Err()
   753  }
   754  
   755  // MarshalJSON marshals an id as a hex string.
   756  func (sfoid SiafundOutputID) MarshalJSON() ([]byte, error) {
   757  	return json.Marshal(sfoid.String())
   758  }
   759  
   760  // String prints the id in hex.
   761  func (sfoid SiafundOutputID) String() string {
   762  	return fmt.Sprintf("%x", sfoid[:])
   763  }
   764  
   765  // UnmarshalJSON decodes the json hex string of the id.
   766  func (sfoid *SiafundOutputID) UnmarshalJSON(b []byte) error {
   767  	return (*crypto.Hash)(sfoid).UnmarshalJSON(b)
   768  }
   769  
   770  // MarshalSia implements the encoding.SiaMarshaler interface.
   771  func (spk SiaPublicKey) MarshalSia(w io.Writer) error {
   772  	e := encoder(w)
   773  	e.Write(spk.Algorithm[:])
   774  	e.WritePrefix(spk.Key)
   775  	return e.Err()
   776  }
   777  
   778  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   779  func (spk *SiaPublicKey) UnmarshalSia(r io.Reader) error {
   780  	d := decoder(r)
   781  	d.ReadFull(spk.Algorithm[:])
   782  	spk.Key = d.ReadPrefix()
   783  	return d.Err()
   784  }
   785  
   786  // LoadString is the inverse of SiaPublicKey.String().
   787  func (spk *SiaPublicKey) LoadString(s string) {
   788  	parts := strings.Split(s, ":")
   789  	if len(parts) != 2 {
   790  		return
   791  	}
   792  	var err error
   793  	spk.Key, err = hex.DecodeString(parts[1])
   794  	if err != nil {
   795  		spk.Key = nil
   796  		return
   797  	}
   798  	copy(spk.Algorithm[:], []byte(parts[0]))
   799  }
   800  
   801  // String defines how to print a SiaPublicKey - hex is used to keep things
   802  // compact during logging. The key type prefix and lack of a checksum help to
   803  // separate it from a sia address.
   804  func (spk *SiaPublicKey) String() string {
   805  	return spk.Algorithm.String() + ":" + fmt.Sprintf("%x", spk.Key)
   806  }
   807  
   808  // UnmarshalJSON unmarshals a SiaPublicKey as JSON.
   809  func (spk *SiaPublicKey) UnmarshalJSON(b []byte) error {
   810  	spk.LoadString(string(bytes.Trim(b, `"`)))
   811  	if spk.Key == nil {
   812  		// fallback to old (base64) encoding
   813  		var oldSPK struct {
   814  			Algorithm Specifier
   815  			Key       []byte
   816  		}
   817  		if err := json.Unmarshal(b, &oldSPK); err != nil {
   818  			return err
   819  		}
   820  		spk.Algorithm, spk.Key = oldSPK.Algorithm, oldSPK.Key
   821  	}
   822  	return nil
   823  }
   824  
   825  // MarshalJSON marshals a specifier as a string.
   826  func (s Specifier) MarshalJSON() ([]byte, error) {
   827  	return json.Marshal(s.String())
   828  }
   829  
   830  // String returns the specifier as a string, trimming any trailing zeros.
   831  func (s Specifier) String() string {
   832  	var i int
   833  	for i = range s {
   834  		if s[i] == 0 {
   835  			break
   836  		}
   837  	}
   838  	return string(s[:i])
   839  }
   840  
   841  // UnmarshalJSON decodes the json string of the specifier.
   842  func (s *Specifier) UnmarshalJSON(b []byte) error {
   843  	var str string
   844  	if err := json.Unmarshal(b, &str); err != nil {
   845  		return err
   846  	}
   847  	copy(s[:], str)
   848  	return nil
   849  }
   850  
   851  // MarshalSia implements the encoding.SiaMarshaler interface.
   852  func (sp *StorageProof) MarshalSia(w io.Writer) error {
   853  	e := encoder(w)
   854  	e.Write(sp.ParentID[:])
   855  	e.Write(sp.Segment[:])
   856  	e.WriteInt(len(sp.HashSet))
   857  	for i := range sp.HashSet {
   858  		e.Write(sp.HashSet[i][:])
   859  	}
   860  	return e.Err()
   861  }
   862  
   863  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
   864  func (sp *StorageProof) UnmarshalSia(r io.Reader) error {
   865  	d := decoder(r)
   866  	d.ReadFull(sp.ParentID[:])
   867  	d.ReadFull(sp.Segment[:])
   868  	sp.HashSet = make([]crypto.Hash, d.NextPrefix(unsafe.Sizeof(crypto.Hash{})))
   869  	for i := range sp.HashSet {
   870  		d.ReadFull(sp.HashSet[i][:])
   871  	}
   872  	return d.Err()
   873  }
   874  
   875  // MarshalSia implements the encoding.SiaMarshaler interface.
   876  func (t Transaction) MarshalSia(w io.Writer) error {
   877  	if build.DEBUG {
   878  		// Sanity check: compare against the old encoding
   879  		buf := new(bytes.Buffer)
   880  		encoding.NewEncoder(buf).EncodeAll(
   881  			t.SiacoinInputs,
   882  			t.SiacoinOutputs,
   883  			t.FileContracts,
   884  			t.FileContractRevisions,
   885  			t.StorageProofs,
   886  			t.SiafundInputs,
   887  			t.SiafundOutputs,
   888  			t.MinerFees,
   889  			t.ArbitraryData,
   890  			t.TransactionSignatures,
   891  		)
   892  		w = sanityCheckWriter{w, buf}
   893  	}
   894  
   895  	e := encoder(w)
   896  	t.MarshalSiaNoSignatures(e)
   897  	e.WriteInt(len((t.TransactionSignatures)))
   898  	for i := range t.TransactionSignatures {
   899  		t.TransactionSignatures[i].MarshalSia(e)
   900  	}
   901  	return e.Err()
   902  }
   903  
   904  // MarshalSiaNoSignatures is a helper function for calculating certain hashes
   905  // that do not include the transaction's signatures.
   906  func (t Transaction) MarshalSiaNoSignatures(w io.Writer) {
   907  	e := encoder(w)
   908  	e.WriteInt(len((t.SiacoinInputs)))
   909  	for i := range t.SiacoinInputs {
   910  		t.SiacoinInputs[i].MarshalSia(e)
   911  	}
   912  	e.WriteInt(len((t.SiacoinOutputs)))
   913  	for i := range t.SiacoinOutputs {
   914  		t.SiacoinOutputs[i].MarshalSia(e)
   915  	}
   916  	e.WriteInt(len((t.FileContracts)))
   917  	for i := range t.FileContracts {
   918  		t.FileContracts[i].MarshalSia(e)
   919  	}
   920  	e.WriteInt(len((t.FileContractRevisions)))
   921  	for i := range t.FileContractRevisions {
   922  		t.FileContractRevisions[i].MarshalSia(e)
   923  	}
   924  	e.WriteInt(len((t.StorageProofs)))
   925  	for i := range t.StorageProofs {
   926  		t.StorageProofs[i].MarshalSia(e)
   927  	}
   928  	e.WriteInt(len((t.SiafundInputs)))
   929  	for i := range t.SiafundInputs {
   930  		t.SiafundInputs[i].MarshalSia(e)
   931  	}
   932  	e.WriteInt(len((t.SiafundOutputs)))
   933  	for i := range t.SiafundOutputs {
   934  		t.SiafundOutputs[i].MarshalSia(e)
   935  	}
   936  	e.WriteInt(len((t.MinerFees)))
   937  	for i := range t.MinerFees {
   938  		t.MinerFees[i].MarshalSia(e)
   939  	}
   940  	e.WriteInt(len((t.ArbitraryData)))
   941  	for i := range t.ArbitraryData {
   942  		e.WritePrefix(t.ArbitraryData[i])
   943  	}
   944  }
   945  
   946  // MarshalSiaSize returns the encoded size of t.
   947  func (t Transaction) MarshalSiaSize() (size int) {
   948  	size += 8
   949  	for _, sci := range t.SiacoinInputs {
   950  		size += len(sci.ParentID)
   951  		size += sci.UnlockConditions.MarshalSiaSize()
   952  	}
   953  	size += 8
   954  	for _, sco := range t.SiacoinOutputs {
   955  		size += sco.Value.MarshalSiaSize()
   956  		size += len(sco.UnlockHash)
   957  	}
   958  	size += 8
   959  	for i := range t.FileContracts {
   960  		size += t.FileContracts[i].MarshalSiaSize()
   961  	}
   962  	size += 8
   963  	for i := range t.FileContractRevisions {
   964  		size += t.FileContractRevisions[i].MarshalSiaSize()
   965  	}
   966  	size += 8
   967  	for _, sp := range t.StorageProofs {
   968  		size += len(sp.ParentID)
   969  		size += len(sp.Segment)
   970  		size += 8 + len(sp.HashSet)*crypto.HashSize
   971  	}
   972  	size += 8
   973  	for _, sfi := range t.SiafundInputs {
   974  		size += len(sfi.ParentID)
   975  		size += len(sfi.ClaimUnlockHash)
   976  		size += sfi.UnlockConditions.MarshalSiaSize()
   977  	}
   978  	size += 8
   979  	for _, sfo := range t.SiafundOutputs {
   980  		size += sfo.Value.MarshalSiaSize()
   981  		size += len(sfo.UnlockHash)
   982  		size += sfo.ClaimStart.MarshalSiaSize()
   983  	}
   984  	size += 8
   985  	for i := range t.MinerFees {
   986  		size += t.MinerFees[i].MarshalSiaSize()
   987  	}
   988  	size += 8
   989  	for i := range t.ArbitraryData {
   990  		size += 8 + len(t.ArbitraryData[i])
   991  	}
   992  	size += 8
   993  	for _, ts := range t.TransactionSignatures {
   994  		size += len(ts.ParentID)
   995  		size += 8 // ts.PublicKeyIndex
   996  		size += 8 // ts.Timelock
   997  		size += ts.CoveredFields.MarshalSiaSize()
   998  		size += 8 + len(ts.Signature)
   999  	}
  1000  
  1001  	// Sanity check against the slower method.
  1002  	if build.DEBUG {
  1003  		expectedSize := len(encoding.Marshal(t))
  1004  		if expectedSize != size {
  1005  			panic("Transaction size different from expected size.")
  1006  		}
  1007  	}
  1008  	return
  1009  }
  1010  
  1011  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
  1012  func (t *Transaction) UnmarshalSia(r io.Reader) error {
  1013  	d := decoder(r)
  1014  	t.SiacoinInputs = make([]SiacoinInput, d.NextPrefix(unsafe.Sizeof(SiacoinInput{})))
  1015  	for i := range t.SiacoinInputs {
  1016  		t.SiacoinInputs[i].UnmarshalSia(d)
  1017  	}
  1018  	t.SiacoinOutputs = make([]SiacoinOutput, d.NextPrefix(unsafe.Sizeof(SiacoinOutput{})))
  1019  	for i := range t.SiacoinOutputs {
  1020  		t.SiacoinOutputs[i].UnmarshalSia(d)
  1021  	}
  1022  	t.FileContracts = make([]FileContract, d.NextPrefix(unsafe.Sizeof(FileContract{})))
  1023  	for i := range t.FileContracts {
  1024  		t.FileContracts[i].UnmarshalSia(d)
  1025  	}
  1026  	t.FileContractRevisions = make([]FileContractRevision, d.NextPrefix(unsafe.Sizeof(FileContractRevision{})))
  1027  	for i := range t.FileContractRevisions {
  1028  		t.FileContractRevisions[i].UnmarshalSia(d)
  1029  	}
  1030  	t.StorageProofs = make([]StorageProof, d.NextPrefix(unsafe.Sizeof(StorageProof{})))
  1031  	for i := range t.StorageProofs {
  1032  		t.StorageProofs[i].UnmarshalSia(d)
  1033  	}
  1034  	t.SiafundInputs = make([]SiafundInput, d.NextPrefix(unsafe.Sizeof(SiafundInput{})))
  1035  	for i := range t.SiafundInputs {
  1036  		t.SiafundInputs[i].UnmarshalSia(d)
  1037  	}
  1038  	t.SiafundOutputs = make([]SiafundOutput, d.NextPrefix(unsafe.Sizeof(SiafundOutput{})))
  1039  	for i := range t.SiafundOutputs {
  1040  		t.SiafundOutputs[i].UnmarshalSia(d)
  1041  	}
  1042  	t.MinerFees = make([]Currency, d.NextPrefix(unsafe.Sizeof(Currency{})))
  1043  	for i := range t.MinerFees {
  1044  		t.MinerFees[i].UnmarshalSia(d)
  1045  	}
  1046  	t.ArbitraryData = make([][]byte, d.NextPrefix(unsafe.Sizeof([]byte{})))
  1047  	for i := range t.ArbitraryData {
  1048  		t.ArbitraryData[i] = d.ReadPrefix()
  1049  	}
  1050  	t.TransactionSignatures = make([]TransactionSignature, d.NextPrefix(unsafe.Sizeof(TransactionSignature{})))
  1051  	for i := range t.TransactionSignatures {
  1052  		t.TransactionSignatures[i].UnmarshalSia(d)
  1053  	}
  1054  	return d.Err()
  1055  }
  1056  
  1057  // MarshalJSON marshals an id as a hex string.
  1058  func (tid TransactionID) MarshalJSON() ([]byte, error) {
  1059  	return json.Marshal(tid.String())
  1060  }
  1061  
  1062  // String prints the id in hex.
  1063  func (tid TransactionID) String() string {
  1064  	return fmt.Sprintf("%x", tid[:])
  1065  }
  1066  
  1067  // UnmarshalJSON decodes the json hex string of the id.
  1068  func (tid *TransactionID) UnmarshalJSON(b []byte) error {
  1069  	return (*crypto.Hash)(tid).UnmarshalJSON(b)
  1070  }
  1071  
  1072  // MarshalSia implements the encoding.SiaMarshaler interface.
  1073  func (ts TransactionSignature) MarshalSia(w io.Writer) error {
  1074  	e := encoder(w)
  1075  	e.Write(ts.ParentID[:])
  1076  	e.WriteUint64(ts.PublicKeyIndex)
  1077  	e.WriteUint64(uint64(ts.Timelock))
  1078  	ts.CoveredFields.MarshalSia(e)
  1079  	e.WritePrefix(ts.Signature)
  1080  	return e.Err()
  1081  }
  1082  
  1083  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
  1084  func (ts *TransactionSignature) UnmarshalSia(r io.Reader) error {
  1085  	d := decoder(r)
  1086  	d.ReadFull(ts.ParentID[:])
  1087  	ts.PublicKeyIndex = d.NextUint64()
  1088  	ts.Timelock = BlockHeight(d.NextUint64())
  1089  	ts.CoveredFields.UnmarshalSia(d)
  1090  	ts.Signature = d.ReadPrefix()
  1091  	return d.Err()
  1092  }
  1093  
  1094  // MarshalSia implements the encoding.SiaMarshaler interface.
  1095  func (uc UnlockConditions) MarshalSia(w io.Writer) error {
  1096  	e := encoder(w)
  1097  	e.WriteUint64(uint64(uc.Timelock))
  1098  	e.WriteInt(len(uc.PublicKeys))
  1099  	for _, spk := range uc.PublicKeys {
  1100  		spk.MarshalSia(e)
  1101  	}
  1102  	e.WriteUint64(uc.SignaturesRequired)
  1103  	return e.Err()
  1104  }
  1105  
  1106  // MarshalSiaSize returns the encoded size of uc.
  1107  func (uc UnlockConditions) MarshalSiaSize() (size int) {
  1108  	size += 8 // Timelock
  1109  	size += 8 // length prefix for PublicKeys
  1110  	for _, spk := range uc.PublicKeys {
  1111  		size += len(spk.Algorithm)
  1112  		size += 8 + len(spk.Key)
  1113  	}
  1114  	size += 8 // SignaturesRequired
  1115  	return
  1116  }
  1117  
  1118  // UnmarshalSia implements the encoding.SiaUnmarshaler interface.
  1119  func (uc *UnlockConditions) UnmarshalSia(r io.Reader) error {
  1120  	d := decoder(r)
  1121  	uc.Timelock = BlockHeight(d.NextUint64())
  1122  	uc.PublicKeys = make([]SiaPublicKey, d.NextPrefix(unsafe.Sizeof(SiaPublicKey{})))
  1123  	for i := range uc.PublicKeys {
  1124  		uc.PublicKeys[i].UnmarshalSia(d)
  1125  	}
  1126  	uc.SignaturesRequired = d.NextUint64()
  1127  	return d.Err()
  1128  }
  1129  
  1130  // MarshalJSON is implemented on the unlock hash to always produce a hex string
  1131  // upon marshalling.
  1132  func (uh UnlockHash) MarshalJSON() ([]byte, error) {
  1133  	return json.Marshal(uh.String())
  1134  }
  1135  
  1136  // UnmarshalJSON is implemented on the unlock hash to recover an unlock hash
  1137  // that has been encoded to a hex string.
  1138  func (uh *UnlockHash) UnmarshalJSON(b []byte) error {
  1139  	// Check the length of b.
  1140  	if len(b) != crypto.HashSize*2+UnlockHashChecksumSize*2+2 && len(b) != crypto.HashSize*2+2 {
  1141  		return ErrUnlockHashWrongLen
  1142  	}
  1143  	return uh.LoadString(string(b[1 : len(b)-1]))
  1144  }
  1145  
  1146  // String returns the hex representation of the unlock hash as a string - this
  1147  // includes a checksum.
  1148  func (uh UnlockHash) String() string {
  1149  	uhChecksum := crypto.HashObject(uh)
  1150  	return fmt.Sprintf("%x%x", uh[:], uhChecksum[:UnlockHashChecksumSize])
  1151  }
  1152  
  1153  // LoadString loads a hex representation (including checksum) of an unlock hash
  1154  // into an unlock hash object. An error is returned if the string is invalid or
  1155  // fails the checksum.
  1156  func (uh *UnlockHash) LoadString(strUH string) error {
  1157  	// Check the length of strUH.
  1158  	if len(strUH) != crypto.HashSize*2+UnlockHashChecksumSize*2 {
  1159  		return ErrUnlockHashWrongLen
  1160  	}
  1161  
  1162  	// Decode the unlock hash.
  1163  	var byteUnlockHash []byte
  1164  	var checksum []byte
  1165  	_, err := fmt.Sscanf(strUH[:crypto.HashSize*2], "%x", &byteUnlockHash)
  1166  	if err != nil {
  1167  		return err
  1168  	}
  1169  
  1170  	// Decode and verify the checksum.
  1171  	_, err = fmt.Sscanf(strUH[crypto.HashSize*2:], "%x", &checksum)
  1172  	if err != nil {
  1173  		return err
  1174  	}
  1175  	expectedChecksum := crypto.HashBytes(byteUnlockHash)
  1176  	if !bytes.Equal(expectedChecksum[:UnlockHashChecksumSize], checksum) {
  1177  		return ErrInvalidUnlockHashChecksum
  1178  	}
  1179  
  1180  	copy(uh[:], byteUnlockHash[:])
  1181  	return nil
  1182  }
  1183  
  1184  // Scan implements the fmt.Scanner interface, allowing UnlockHash values to be
  1185  // scanned from text.
  1186  func (uh *UnlockHash) Scan(s fmt.ScanState, ch rune) error {
  1187  	s.SkipSpace()
  1188  	tok, err := s.Token(false, nil)
  1189  	if err != nil {
  1190  		return err
  1191  	}
  1192  	return uh.LoadString(string(tok))
  1193  }