gitlab.com/SiaPrime/SiaPrime@v1.4.1/types/encoding.go (about)

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