decred.org/dcrdex@v1.0.3/dex/networks/zec/tx.go (about)

     1  // This code is available on the terms of the project LICENSE.md file,
     2  // also available online at https://blueoakcouncil.org
     3  
     4  package zec
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/binary"
     9  	"fmt"
    10  	"io"
    11  
    12  	"github.com/btcsuite/btcd/chaincfg/chainhash"
    13  	"github.com/btcsuite/btcd/txscript"
    14  	"github.com/btcsuite/btcd/wire"
    15  	"github.com/dchest/blake2b"
    16  )
    17  
    18  const (
    19  	VersionPreOverwinter = 2
    20  	VersionOverwinter    = 3
    21  	VersionSapling       = 4
    22  	VersionNU5           = 5
    23  	MaxExpiryHeight      = 499999999 // https://zips.z.cash/zip-0203
    24  
    25  	versionOverwinterGroupID = 0x03C48270
    26  	versionSaplingGroupID    = 0x892f2085
    27  	versionNU5GroupID        = 0x26A7270A
    28  
    29  	overwinterMask = ^uint32(1 << 31)
    30  	pver           = 0
    31  
    32  	overwinterJoinSplitSize = 1802
    33  	saplingJoinSplitSize    = 1698
    34  
    35  	pkTransparentDigest = "ZTxIdTranspaHash"
    36  	pkPrevOutsV5        = "ZTxIdPrevoutHash"
    37  	pkAmounts           = "ZTxTrAmountsHash"
    38  	pkPrevScripts       = "ZTxTrScriptsHash"
    39  	pkSequenceV5        = "ZTxIdSequencHash"
    40  	pkOutputsV5         = "ZTxIdOutputsHash"
    41  	pkTxIn              = "Zcash___TxInHash"
    42  	pkV5TxDigest        = "ZcashTxHash_"
    43  	pkHeader            = "ZTxIdHeadersHash"
    44  	pkPrevOutsV4        = "ZcashPrevoutHash"
    45  	pkSequenceV4        = "ZcashSequencHash"
    46  	pkOutputsV4         = "ZcashOutputsHash"
    47  )
    48  
    49  var (
    50  	// Little-endian encoded CONSENSUS_BRANCH_IDs.
    51  	// https://zcash.readthedocs.io/en/latest/rtd_pages/nu_dev_guide.html#canopy
    52  	ConsensusBranchNU5     = [4]byte{0xB4, 0xD0, 0xD6, 0xC2} // 1687104, testnet: 1842420
    53  	ConsensusBranchSapling = [4]byte{0xBB, 0x09, 0xB8, 0x76}
    54  
    55  	// Zclassic only
    56  	ConsensusBranchButtercup = [4]byte{0x0d, 0x54, 0x0b, 0x93}
    57  
    58  	emptySaplingDigest = [32]byte{0x6f, 0x2f, 0xc8, 0xf9, 0x8f, 0xea, 0xfd, 0x94,
    59  		0xe7, 0x4a, 0x0d, 0xf4, 0xbe, 0xd7, 0x43, 0x91, 0xee, 0x0b, 0x5a, 0x69,
    60  		0x94, 0x5e, 0x4c, 0xed, 0x8c, 0xa8, 0xa0, 0x95, 0x20, 0x6f, 0x00, 0xae}
    61  
    62  	emptyOrchardDigest = [32]byte{0x9f, 0xbe, 0x4e, 0xd1, 0x3b, 0x0c, 0x08, 0xe6,
    63  		0x71, 0xc1, 0x1a, 0x34, 0x07, 0xd8, 0x4e, 0x11, 0x17, 0xcd, 0x45, 0x02,
    64  		0x8a, 0x2e, 0xee, 0x1b, 0x9f, 0xea, 0xe7, 0x8b, 0x48, 0xa6, 0xe2, 0xc1}
    65  )
    66  
    67  // JoinSplit is only the new and old fields of a vJoinSplit.
    68  type JoinSplit struct {
    69  	Old, New uint64
    70  }
    71  
    72  // Tx is a Zcash-adapted MsgTx. Tx will decode any version transaction, but will
    73  // not save most data for shielded transactions.
    74  // Tx can only produce tx hashes for unshielded transactions. Tx can only create
    75  // signature hashes for unshielded version 5 transactions.
    76  type Tx struct {
    77  	*wire.MsgTx
    78  	ExpiryHeight        uint32
    79  	NSpendsSapling      uint64
    80  	NOutputsSapling     uint64
    81  	ValueBalanceSapling int64
    82  	NActionsOrchard     uint64
    83  	SizeProofsOrchard   uint64
    84  	NJoinSplit          uint64
    85  	VJoinSplit          []*JoinSplit
    86  	ValueBalanceOrchard int64
    87  }
    88  
    89  // NewTxFromMsgTx creates a Tx embedding the MsgTx, and adding Zcash-specific
    90  // fields.
    91  func NewTxFromMsgTx(tx *wire.MsgTx, expiryHeight uint32) *Tx {
    92  	zecTx := &Tx{
    93  		MsgTx:        tx,
    94  		ExpiryHeight: expiryHeight,
    95  	}
    96  	return zecTx
    97  }
    98  
    99  // TxHash generates the Hash for the transaction.
   100  func (tx *Tx) TxHash() chainhash.Hash {
   101  	if tx.Version == 5 {
   102  		txHash, _ := tx.txHashV5()
   103  		return txHash
   104  	}
   105  	b, _ := tx.Bytes()
   106  	return chainhash.DoubleHashH(b)
   107  }
   108  
   109  func (tx *Tx) txHashV5() (_ chainhash.Hash, err error) {
   110  	td, err := tx.transparentDigestV5()
   111  	if err != nil {
   112  		return
   113  	}
   114  	return tx.txDigestV5(td)
   115  }
   116  
   117  // SignatureDigest produces a hash of tx data suitable for signing.
   118  // SignatureDigest only works correctly for unshielded version 5 transactions.
   119  func (tx *Tx) SignatureDigest(
   120  	vin int, hashType txscript.SigHashType, script []byte, vals []int64, prevScripts [][]byte,
   121  ) (_ [32]byte, err error) {
   122  
   123  	if tx.Version == 4 {
   124  		return tx.txDigestV4(hashType, vin, vals, script)
   125  	}
   126  	td, err := tx.transparentSigDigestV5(vin, hashType, vals, prevScripts)
   127  	if err != nil {
   128  		return
   129  	}
   130  	return tx.txDigestV5(td)
   131  }
   132  
   133  // txDigestV5 produces hashes of transaction data in accordance with ZIP-244.
   134  func (tx *Tx) txDigestV5(transparentPart [32]byte) (_ chainhash.Hash, err error) {
   135  	hd, err := tx.headerDigestV5()
   136  	if err != nil {
   137  		return
   138  	}
   139  	b := make([]byte, 128)
   140  	copy(b[:32], hd[:])
   141  	copy(b[32:64], transparentPart[:])
   142  	copy(b[64:96], emptySaplingDigest[:])
   143  	copy(b[96:], emptyOrchardDigest[:])
   144  	h, err := blake2bHash(b, append([]byte(pkV5TxDigest), ConsensusBranchNU5[:]...))
   145  	if err != nil {
   146  		return
   147  	}
   148  	var txHash chainhash.Hash
   149  	copy(txHash[:], h[:])
   150  	return txHash, nil
   151  }
   152  
   153  func (tx *Tx) headerDigestV5() ([32]byte, error) {
   154  	b := make([]byte, 20)
   155  	copy(b[:4], uint32Bytes(uint32(tx.Version)|(1<<31)))
   156  	copy(b[4:8], uint32Bytes(versionNU5GroupID))
   157  	copy(b[8:12], ConsensusBranchNU5[:])
   158  	copy(b[12:16], uint32Bytes(tx.LockTime))
   159  	copy(b[16:], uint32Bytes(tx.ExpiryHeight))
   160  	return blake2bHash(b, []byte(pkHeader))
   161  }
   162  
   163  // Zclassic only. Based on ZIP-0243, but uses ConsensusBranchButtercup from
   164  // Zclassic.
   165  // isSimnet is hack for https://github.com/ZclassicCommunity/zclassic/issues/83
   166  func (tx *Tx) txDigestV4(
   167  	hashType txscript.SigHashType, vin int, vals []int64, script []byte,
   168  ) (_ chainhash.Hash, err error) {
   169  
   170  	b, err := tx.sighashPreimageV4(hashType, vin, vals, script)
   171  	if err != nil {
   172  		return
   173  	}
   174  	consensusBranchID := ConsensusBranchButtercup
   175  	h, err := blake2bHash(b, append([]byte("ZcashSigHash"), consensusBranchID[:]...))
   176  	if err != nil {
   177  		return
   178  	}
   179  
   180  	var txHash chainhash.Hash
   181  	copy(txHash[:], h[:])
   182  	return txHash, nil
   183  }
   184  
   185  func (tx *Tx) sighashPreimageV4(hashType txscript.SigHashType, vin int, vals []int64, script []byte) (_ []byte, err error) {
   186  	buf := bytes.NewBuffer(make([]byte, 0, 270+len(script)))
   187  	buf.Write(uint32Bytes(uint32(tx.Version) | (1 << 31))) // 4 bytes
   188  	buf.Write(uint32Bytes(versionSaplingGroupID))          // + 4 = 8
   189  	prevoutsDigest, err := tx.calcHashPrevOuts(pkPrevOutsV4)
   190  	if err != nil {
   191  		return
   192  	}
   193  	buf.Write(prevoutsDigest[:]) // + 32 = 40
   194  
   195  	seqDigest, err := tx.hashSequence(pkSequenceV4)
   196  	if err != nil {
   197  		return
   198  	}
   199  	buf.Write(seqDigest[:]) // + 32 = 72
   200  
   201  	outputsDigest, err := tx.hashOutputs(pkOutputsV4)
   202  	if err != nil {
   203  		return
   204  	}
   205  	buf.Write(outputsDigest[:]) // + 32 = 104
   206  	// The following three fields are all zero hashes for transparent txs.
   207  	// hashJoinSplits, hashShieldedSpends, hashShieldedOutputs [32]byte
   208  	buf.Write(make([]byte, 96))             // + 96 = 200
   209  	buf.Write(uint32Bytes(tx.LockTime))     // + 4 = 204
   210  	buf.Write(uint32Bytes(tx.ExpiryHeight)) // + 4 = 208
   211  	// valueBalance
   212  	buf.Write(uint64Bytes(0))                // + 8 = 216
   213  	buf.Write(uint32Bytes(uint32(hashType))) // + 4 = 220
   214  
   215  	txInsDigest, err := tx.preimageTxInSig(vin, vals[vin], script) // + 50 + len(prevScript) = 270 + len(prevScript)
   216  	if err != nil {
   217  		return
   218  	}
   219  	buf.Write(txInsDigest[:])
   220  	return buf.Bytes(), nil
   221  }
   222  
   223  func (tx *Tx) transparentDigestV5() (h [32]byte, err error) {
   224  	prevoutsDigest, err := tx.calcHashPrevOuts(pkPrevOutsV5)
   225  	if err != nil {
   226  		return
   227  	}
   228  
   229  	seqDigest, err := tx.hashSequence(pkSequenceV5)
   230  	if err != nil {
   231  		return
   232  	}
   233  
   234  	outputsDigest, err := tx.hashOutputs(pkOutputsV5)
   235  	if err != nil {
   236  		return
   237  	}
   238  
   239  	b := make([]byte, 96)
   240  	copy(b[:32], prevoutsDigest[:])
   241  	copy(b[32:64], seqDigest[:])
   242  	copy(b[64:], outputsDigest[:])
   243  	return blake2bHash(b, []byte(pkTransparentDigest))
   244  }
   245  
   246  func (tx *Tx) transparentSigDigestV5(vin int, hashType txscript.SigHashType, vals []int64, prevScripts [][]byte) (h [32]byte, err error) {
   247  	buf := bytes.NewBuffer(make([]byte, 0, 193))
   248  
   249  	buf.Write([]byte{byte(hashType)})
   250  
   251  	anyoneCanPay := hashType&txscript.SigHashAnyOneCanPay > 0
   252  
   253  	prevoutsDigest, err := tx.hashPrevOutsSigV5(anyoneCanPay)
   254  	if err != nil {
   255  		return
   256  	}
   257  	buf.Write(prevoutsDigest[:])
   258  
   259  	amtsDigest, err := tx.hashAmountsSig(anyoneCanPay, vals)
   260  	if err != nil {
   261  		return
   262  	}
   263  	buf.Write(amtsDigest[:])
   264  
   265  	prevScriptsDigest, err := tx.hashPrevScriptsSig(anyoneCanPay, prevScripts)
   266  	if err != nil {
   267  		return
   268  	}
   269  	buf.Write(prevScriptsDigest[:])
   270  
   271  	seqsDigest, err := tx.hashSequenceSigV5(anyoneCanPay)
   272  	if err != nil {
   273  		return
   274  	}
   275  	buf.Write(seqsDigest[:])
   276  
   277  	outputsDigest, err := tx.hashOutputsSigV5(anyoneCanPay)
   278  	if err != nil {
   279  		return
   280  	}
   281  	buf.Write(outputsDigest[:])
   282  
   283  	txInsDigest, err := tx.hashTxInSig(vin, vals[vin], prevScripts[vin])
   284  	if err != nil {
   285  		return
   286  	}
   287  	buf.Write(txInsDigest[:])
   288  
   289  	return blake2bHash(buf.Bytes(), []byte(pkTransparentDigest))
   290  }
   291  
   292  func (tx *Tx) calcHashPrevOuts(pk string) ([32]byte, error) {
   293  	var buf bytes.Buffer
   294  	for _, in := range tx.TxIn {
   295  		buf.Write(in.PreviousOutPoint.Hash[:])
   296  		var b [4]byte
   297  		binary.LittleEndian.PutUint32(b[:], in.PreviousOutPoint.Index)
   298  		buf.Write(b[:])
   299  	}
   300  	return blake2bHash(buf.Bytes(), []byte(pk))
   301  }
   302  
   303  func (tx *Tx) hashPrevOutsSigV5(anyoneCanPay bool) ([32]byte, error) {
   304  	if anyoneCanPay {
   305  		return blake2bHash([]byte{}, []byte(pkPrevOutsV5))
   306  	}
   307  	return tx.calcHashPrevOuts(pkPrevOutsV5)
   308  }
   309  
   310  func (tx *Tx) hashAmountsSig(anyoneCanPay bool, vals []int64) ([32]byte, error) {
   311  	if anyoneCanPay {
   312  		return blake2bHash([]byte{}, []byte(pkAmounts))
   313  	}
   314  	b := make([]byte, 0, 8*len(vals))
   315  	for _, v := range vals {
   316  		b = append(b, int64Bytes(v)...)
   317  	}
   318  	return blake2bHash(b, []byte(pkAmounts))
   319  }
   320  
   321  func (tx *Tx) hashPrevScriptsSig(anyoneCanPay bool, prevScripts [][]byte) (_ [32]byte, err error) {
   322  	if anyoneCanPay {
   323  		return blake2bHash([]byte{}, []byte(pkPrevScripts))
   324  	}
   325  	buf := new(bytes.Buffer)
   326  	for _, s := range prevScripts {
   327  		if err = wire.WriteVarBytes(buf, pver, s); err != nil {
   328  			return
   329  		}
   330  	}
   331  
   332  	return blake2bHash(buf.Bytes(), []byte(pkPrevScripts))
   333  }
   334  
   335  func (tx *Tx) hashSequence(pk string) ([32]byte, error) {
   336  	var b bytes.Buffer
   337  	for _, in := range tx.TxIn {
   338  		var buf [4]byte
   339  		binary.LittleEndian.PutUint32(buf[:], in.Sequence)
   340  		b.Write(buf[:])
   341  	}
   342  	return blake2bHash(b.Bytes(), []byte(pk))
   343  }
   344  
   345  func (tx *Tx) hashSequenceSigV5(anyoneCanPay bool) (h [32]byte, err error) {
   346  	if anyoneCanPay {
   347  		return blake2bHash([]byte{}, []byte(pkSequenceV5))
   348  	}
   349  	return tx.hashSequence(pkSequenceV5)
   350  }
   351  
   352  func (tx *Tx) hashOutputs(pk string) (_ [32]byte, err error) {
   353  	var b bytes.Buffer
   354  	for _, out := range tx.TxOut {
   355  		if err = wire.WriteTxOut(&b, 0, 0, out); err != nil {
   356  			return chainhash.Hash{}, err
   357  		}
   358  	}
   359  	return blake2bHash(b.Bytes(), []byte(pk))
   360  }
   361  
   362  func (tx *Tx) hashOutputsSigV5(anyoneCanPay bool) (_ [32]byte, err error) {
   363  	if anyoneCanPay {
   364  		return blake2bHash([]byte{}, []byte(pkOutputsV5))
   365  	}
   366  	return tx.hashOutputs(pkOutputsV5)
   367  }
   368  
   369  func (tx *Tx) hashTxInSig(idx int, prevVal int64, prevScript []byte) (h [32]byte, err error) {
   370  	b, err := tx.preimageTxInSig(idx, prevVal, prevScript)
   371  	if err != nil {
   372  		return
   373  	}
   374  	return blake2bHash(b, []byte(pkTxIn))
   375  }
   376  
   377  func (tx *Tx) preimageTxInSig(idx int, prevVal int64, script []byte) ([]byte, error) {
   378  	if len(tx.TxIn) <= idx {
   379  		return nil, fmt.Errorf("no input at index %d", idx)
   380  	}
   381  	txIn := tx.TxIn[idx]
   382  
   383  	// prev_hash 32 + prev_index 4 + prev_value 8 + script_pub_key var_int+L (size) + nSequence 4
   384  	b := bytes.NewBuffer(make([]byte, 0, 50+len(script)))
   385  
   386  	b.Write(txIn.PreviousOutPoint.Hash[:])
   387  	b.Write(uint32Bytes(txIn.PreviousOutPoint.Index))
   388  	if tx.Version >= 5 {
   389  		b.Write(int64Bytes(prevVal))
   390  	}
   391  	if err := wire.WriteVarBytes(b, pver, script); err != nil {
   392  		return nil, err
   393  	}
   394  	if tx.Version < 5 {
   395  		b.Write(int64Bytes(prevVal))
   396  	}
   397  	b.Write(uint32Bytes(txIn.Sequence))
   398  
   399  	return b.Bytes(), nil
   400  }
   401  
   402  // Bytes encodes the receiver to w using the bitcoin protocol encoding.
   403  // This is part of the Message interface implementation.
   404  // See Serialize for encoding transactions to be stored to disk, such as in a
   405  // database, as opposed to encoding transactions for the wire.
   406  // msg.Version must be 4 or 5.
   407  func (tx *Tx) Bytes() (_ []byte, err error) {
   408  	w := new(bytes.Buffer)
   409  	header := uint32(tx.Version)
   410  	if tx.Version >= VersionOverwinter {
   411  		header |= 1 << 31
   412  	}
   413  
   414  	if err = putUint32(w, header); err != nil {
   415  		return nil, fmt.Errorf("error writing version: %w", err)
   416  	}
   417  
   418  	if tx.Version >= VersionOverwinter {
   419  		var groupID uint32 = versionOverwinterGroupID
   420  		switch tx.Version {
   421  		case VersionSapling:
   422  			groupID = versionSaplingGroupID
   423  		case VersionNU5:
   424  			groupID = versionNU5GroupID
   425  		}
   426  
   427  		// nVersionGroupId
   428  		if err = putUint32(w, groupID); err != nil {
   429  			return nil, fmt.Errorf("error writing nVersionGroupId: %w", err)
   430  		}
   431  	}
   432  
   433  	if tx.Version == VersionNU5 {
   434  		// nConsensusBranchId
   435  		if _, err = w.Write(ConsensusBranchNU5[:]); err != nil {
   436  			return nil, fmt.Errorf("error writing nConsensusBranchId: %w", err)
   437  		}
   438  
   439  		// lock_time
   440  		if err = putUint32(w, tx.LockTime); err != nil {
   441  			return nil, fmt.Errorf("error writing lock_time: %w", err)
   442  		}
   443  
   444  		// nExpiryHeight
   445  		if err = putUint32(w, tx.ExpiryHeight); err != nil {
   446  			return nil, fmt.Errorf("error writing nExpiryHeight: %w", err)
   447  		}
   448  	}
   449  
   450  	// tx_in_count
   451  	if err = wire.WriteVarInt(w, pver, uint64(len(tx.MsgTx.TxIn))); err != nil {
   452  		return nil, fmt.Errorf("error writing tx_in_count: %w", err)
   453  	}
   454  
   455  	// tx_in
   456  	for vin, ti := range tx.TxIn {
   457  		if err = writeTxIn(w, ti); err != nil {
   458  			return nil, fmt.Errorf("error writing tx_in %d: %w", vin, err)
   459  		}
   460  	}
   461  
   462  	// tx_out_count
   463  	if err = wire.WriteVarInt(w, pver, uint64(len(tx.TxOut))); err != nil {
   464  		return nil, fmt.Errorf("error writing tx_out_count: %w", err)
   465  	}
   466  
   467  	// tx_out
   468  	for vout, to := range tx.TxOut {
   469  		if err = wire.WriteTxOut(w, pver, tx.Version, to); err != nil {
   470  			return nil, fmt.Errorf("error writing tx_out %d: %w", vout, err)
   471  		}
   472  	}
   473  
   474  	if tx.Version <= VersionSapling {
   475  		// lock_time
   476  		if err = putUint32(w, tx.LockTime); err != nil {
   477  			return nil, fmt.Errorf("error writing lock_time: %w", err)
   478  		}
   479  
   480  		if tx.Version >= VersionOverwinter {
   481  			// nExpiryHeight
   482  			if err = putUint32(w, tx.ExpiryHeight); err != nil {
   483  				return nil, fmt.Errorf("error writing nExpiryHeight: %w", err)
   484  			}
   485  		}
   486  	}
   487  
   488  	if tx.Version == VersionSapling {
   489  		// valueBalanceSapling
   490  		if err = putUint64(w, 0); err != nil {
   491  			return nil, fmt.Errorf("error writing valueBalanceSapling: %w", err)
   492  		}
   493  	}
   494  
   495  	if tx.Version >= VersionSapling {
   496  		// nSpendsSapling
   497  		if err = wire.WriteVarInt(w, pver, 0); err != nil {
   498  			return nil, fmt.Errorf("error writing nSpendsSapling: %w", err)
   499  		}
   500  
   501  		// nOutputsSapling
   502  		if err = wire.WriteVarInt(w, pver, 0); err != nil {
   503  			return nil, fmt.Errorf("error writing nOutputsSapling: %w", err)
   504  		}
   505  	}
   506  
   507  	if tx.Version >= VersionPreOverwinter && tx.Version <= VersionSapling {
   508  		// nJoinSplit
   509  		if err = wire.WriteVarInt(w, pver, 0); err != nil {
   510  			return nil, fmt.Errorf("error writing nJoinSplit: %w", err)
   511  		}
   512  		return w.Bytes(), nil
   513  	}
   514  
   515  	// NU 5
   516  
   517  	// no anchorSapling, because nSpendsSapling = 0
   518  	// no bindingSigSapling or valueBalanceSapling, because nSpendsSapling + nOutputsSapling = 0
   519  
   520  	if tx.Version == VersionNU5 {
   521  		// nActionsOrchard
   522  		if err = wire.WriteVarInt(w, pver, 0); err != nil {
   523  			return nil, fmt.Errorf("error writing nActionsOrchard: %w", err)
   524  		}
   525  	}
   526  
   527  	// vActionsOrchard, flagsOrchard, valueBalanceOrchard, anchorOrchard,
   528  	// sizeProofsOrchard, proofsOrchard, vSpendAuthSigsOrchard, and
   529  	// bindingSigOrchard are all empty, because nActionsOrchard = 0.
   530  
   531  	return w.Bytes(), nil
   532  }
   533  
   534  // see https://zips.z.cash/protocol/protocol.pdf section 7.1
   535  func DeserializeTx(b []byte) (*Tx, error) {
   536  	tx := &Tx{MsgTx: new(wire.MsgTx)}
   537  	r := bytes.NewReader(b)
   538  	if err := tx.ZecDecode(r); err != nil {
   539  		return nil, err
   540  	}
   541  
   542  	remains := r.Len()
   543  	if remains > 0 {
   544  		return nil, fmt.Errorf("incomplete deserialization. %d bytes remaining", remains)
   545  	}
   546  
   547  	return tx, nil
   548  }
   549  
   550  // ZecDecode reads the serialized transaction from the reader and populates the
   551  // *Tx's fields.
   552  func (tx *Tx) ZecDecode(r io.Reader) (err error) {
   553  	ver, err := readUint32(r)
   554  	if err != nil {
   555  		return fmt.Errorf("error reading version: %w", err)
   556  	}
   557  
   558  	// overWintered := (ver & (1 << 31)) > 0
   559  	ver &= overwinterMask // Clear the overwinter bit
   560  	tx.Version = int32(ver)
   561  
   562  	if tx.Version > VersionNU5 {
   563  		return fmt.Errorf("unsupported tx version %d > 4", ver)
   564  	}
   565  
   566  	if ver >= VersionOverwinter {
   567  		// nVersionGroupId uint32
   568  		if err = discardBytes(r, 4); err != nil {
   569  			return fmt.Errorf("error reading nVersionGroupId: %w", err)
   570  		}
   571  	}
   572  
   573  	if ver == VersionNU5 {
   574  		// nConsensusBranchId uint32
   575  		if err = discardBytes(r, 4); err != nil {
   576  			return fmt.Errorf("error reading nConsensusBranchId: %w", err)
   577  		}
   578  		// lock_time
   579  		if tx.LockTime, err = readUint32(r); err != nil {
   580  			return fmt.Errorf("error reading lock_time: %w", err)
   581  		}
   582  		// nExpiryHeight
   583  		if tx.ExpiryHeight, err = readUint32(r); err != nil {
   584  			return fmt.Errorf("error reading nExpiryHeight: %w", err)
   585  		}
   586  	}
   587  
   588  	txInCount, err := wire.ReadVarInt(r, pver)
   589  	if err != nil {
   590  		return err
   591  	}
   592  
   593  	tx.TxIn = make([]*wire.TxIn, 0, txInCount)
   594  	for i := 0; i < int(txInCount); i++ {
   595  		ti := new(wire.TxIn)
   596  		if err = readTxIn(r, ti); err != nil {
   597  			return err
   598  		}
   599  		tx.TxIn = append(tx.TxIn, ti)
   600  	}
   601  
   602  	txOutCount, err := wire.ReadVarInt(r, pver)
   603  	if err != nil {
   604  		return err
   605  	}
   606  
   607  	tx.TxOut = make([]*wire.TxOut, 0, txOutCount)
   608  	for i := 0; i < int(txOutCount); i++ {
   609  		to := new(wire.TxOut)
   610  		if err = readTxOut(r, to); err != nil {
   611  			return err
   612  		}
   613  		tx.TxOut = append(tx.TxOut, to)
   614  	}
   615  
   616  	if ver < VersionNU5 {
   617  		// lock_time
   618  		if tx.LockTime, err = readUint32(r); err != nil {
   619  			return fmt.Errorf("error reading lock_time: %w", err)
   620  		}
   621  	}
   622  
   623  	if ver == VersionOverwinter || ver == VersionSapling {
   624  		// nExpiryHeight
   625  		if tx.ExpiryHeight, err = readUint32(r); err != nil {
   626  			return fmt.Errorf("error reading nExpiryHeight: %w", err)
   627  		}
   628  	}
   629  
   630  	// That's it for pre-overwinter.
   631  	if ver < VersionPreOverwinter {
   632  		return nil
   633  	}
   634  
   635  	var bindingSigRequired bool
   636  	if ver == VersionSapling {
   637  		// valueBalanceSapling uint64
   638  		if tx.ValueBalanceSapling, err = readInt64(r); err != nil {
   639  			return fmt.Errorf("error reading valueBalanceSapling: %w", err)
   640  		}
   641  
   642  		if tx.NSpendsSapling, err = wire.ReadVarInt(r, pver); err != nil {
   643  			return fmt.Errorf("error reading nSpendsSapling: %w", err)
   644  		} else if tx.NSpendsSapling > 0 {
   645  			// vSpendsSapling - discard
   646  			bindingSigRequired = true
   647  			if err = discardBytes(r, int64(tx.NSpendsSapling*384)); err != nil {
   648  				return fmt.Errorf("error reading vSpendsSapling: %w", err)
   649  			}
   650  		}
   651  
   652  		if tx.NOutputsSapling, err = wire.ReadVarInt(r, pver); err != nil {
   653  			return fmt.Errorf("error reading nOutputsSapling: %w", err)
   654  		} else if tx.NOutputsSapling > 0 {
   655  			// vOutputsSapling - discard
   656  			bindingSigRequired = true
   657  			if err = discardBytes(r, int64(tx.NOutputsSapling*948)); err != nil {
   658  				return fmt.Errorf("error reading vOutputsSapling: %w", err)
   659  			}
   660  		}
   661  	}
   662  
   663  	if ver <= VersionSapling && ver >= VersionPreOverwinter {
   664  		if tx.NJoinSplit, err = wire.ReadVarInt(r, pver); err != nil {
   665  			return fmt.Errorf("error reading nJoinSplit: %w", err)
   666  		} else if tx.NJoinSplit > 0 {
   667  			// vJoinSplit - discard
   668  			tx.VJoinSplit = make([]*JoinSplit, 0, tx.NJoinSplit)
   669  			for i := uint64(0); i < tx.NJoinSplit; i++ {
   670  				sz := overwinterJoinSplitSize
   671  				if ver == 4 {
   672  					sz = saplingJoinSplitSize
   673  				}
   674  				old, err := readUint64(r)
   675  				if err != nil {
   676  					return fmt.Errorf("error reading joinsplit old: %w", err)
   677  				}
   678  				new, err := readUint64(r)
   679  				if err != nil {
   680  					return fmt.Errorf("error reading joinsplit new: %w", err)
   681  				}
   682  				tx.VJoinSplit = append(tx.VJoinSplit, &JoinSplit{
   683  					Old: old,
   684  					New: new,
   685  				})
   686  				if err = discardBytes(r, int64(sz-16)); err != nil {
   687  					return fmt.Errorf("error reading vJoinSplit: %w", err)
   688  				}
   689  			}
   690  			// joinSplitPubKey
   691  			if err = discardBytes(r, 32); err != nil {
   692  				return fmt.Errorf("error reading joinSplitPubKey: %w", err)
   693  			}
   694  
   695  			// joinSplitSig
   696  			if err = discardBytes(r, 64); err != nil {
   697  				return fmt.Errorf("error reading joinSplitSig: %w", err)
   698  			}
   699  		}
   700  	} else { // NU5
   701  		// nSpendsSapling
   702  		tx.NSpendsSapling, err = wire.ReadVarInt(r, pver)
   703  		if err != nil {
   704  			return fmt.Errorf("error reading nSpendsSapling: %w", err)
   705  		} else if tx.NSpendsSapling > 0 {
   706  			// vSpendsSapling - discard
   707  			bindingSigRequired = true
   708  			if err = discardBytes(r, int64(tx.NSpendsSapling*96)); err != nil {
   709  				return fmt.Errorf("error reading vSpendsSapling: %w", err)
   710  			}
   711  		}
   712  
   713  		// nOutputsSapling
   714  		tx.NOutputsSapling, err = wire.ReadVarInt(r, pver)
   715  		if err != nil {
   716  			return fmt.Errorf("error reading nSpendsSapling: %w", err)
   717  		} else if tx.NOutputsSapling > 0 {
   718  			// vOutputsSapling - discard
   719  			bindingSigRequired = true
   720  			if err = discardBytes(r, int64(tx.NOutputsSapling*756)); err != nil {
   721  				return fmt.Errorf("error reading vOutputsSapling: %w", err)
   722  			}
   723  		}
   724  
   725  		if tx.NOutputsSapling+tx.NSpendsSapling > 0 {
   726  			// valueBalanceSpending uint64
   727  			if err = discardBytes(r, 8); err != nil {
   728  				return fmt.Errorf("error reading valueBalanceSpending: %w", err)
   729  			}
   730  		}
   731  
   732  		if tx.NSpendsSapling > 0 {
   733  			// anchorSapling
   734  			if err = discardBytes(r, 32); err != nil {
   735  				return fmt.Errorf("error reading anchorSapling: %w", err)
   736  			}
   737  			// vSpendProofsSapling
   738  			if err = discardBytes(r, int64(tx.NSpendsSapling*192)); err != nil {
   739  				return fmt.Errorf("error reading vSpendProofsSapling: %w", err)
   740  			}
   741  			// vSpendAuthSigsSapling
   742  			if err = discardBytes(r, int64(tx.NSpendsSapling*64)); err != nil {
   743  				return fmt.Errorf("error reading vSpendAuthSigsSapling: %w", err)
   744  			}
   745  		}
   746  
   747  		if tx.NOutputsSapling > 0 {
   748  			// vOutputProofsSapling
   749  			if err = discardBytes(r, int64(tx.NOutputsSapling*192)); err != nil {
   750  				return fmt.Errorf("error reading vOutputProofsSapling: %w", err)
   751  			}
   752  		}
   753  	}
   754  
   755  	if bindingSigRequired {
   756  		// bindingSigSapling
   757  		if err = discardBytes(r, 64); err != nil {
   758  			return fmt.Errorf("error reading bindingSigSapling: %w", err)
   759  		}
   760  	}
   761  
   762  	// pre-NU5 is done now.
   763  	if ver < VersionNU5 {
   764  		return nil
   765  	}
   766  
   767  	// NU5-only fields below.
   768  
   769  	// nActionsOrchard
   770  	tx.NActionsOrchard, err = wire.ReadVarInt(r, pver)
   771  	if err != nil {
   772  		return fmt.Errorf("error reading bindingSigSapling: %w", err)
   773  	}
   774  
   775  	if tx.NActionsOrchard == 0 {
   776  		return nil
   777  	}
   778  
   779  	// vActionsOrchard
   780  	if err = discardBytes(r, int64(tx.NActionsOrchard*820)); err != nil {
   781  		return fmt.Errorf("error reading vActionsOrchard: %w", err)
   782  	}
   783  
   784  	// flagsOrchard
   785  	if err = discardBytes(r, 1); err != nil {
   786  		return fmt.Errorf("error reading flagsOrchard: %w", err)
   787  	}
   788  
   789  	// valueBalanceOrchard uint64
   790  	if tx.ValueBalanceOrchard, err = readInt64(r); err != nil {
   791  		return fmt.Errorf("error reading valueBalanceOrchard: %w", err)
   792  	}
   793  
   794  	// anchorOrchard
   795  	if err = discardBytes(r, 32); err != nil {
   796  		return fmt.Errorf("error reading anchorOrchard: %w", err)
   797  	}
   798  
   799  	// sizeProofsOrchard
   800  	tx.SizeProofsOrchard, err = wire.ReadVarInt(r, pver)
   801  	if err != nil {
   802  		return fmt.Errorf("error reading sizeProofsOrchard: %w", err)
   803  	}
   804  
   805  	// proofsOrchard
   806  	if err = discardBytes(r, int64(tx.SizeProofsOrchard)); err != nil {
   807  		return fmt.Errorf("error reading proofsOrchard: %w", err)
   808  	}
   809  
   810  	// vSpendAuthSigsOrchard
   811  	if err = discardBytes(r, int64(tx.NActionsOrchard*64)); err != nil {
   812  		return fmt.Errorf("error reading vSpendAuthSigsOrchard: %w", err)
   813  	}
   814  
   815  	// bindingSigOrchard
   816  	if err = discardBytes(r, 64); err != nil {
   817  		return fmt.Errorf("error reading bindingSigOrchard: %w", err)
   818  	}
   819  
   820  	return nil
   821  }
   822  
   823  // SerializeSize is the size of the transaction when serialized.
   824  func (tx *Tx) SerializeSize() uint64 {
   825  	var sz uint64 = 4 // header
   826  	ver := tx.Version
   827  	sz += uint64(wire.VarIntSerializeSize(uint64(len(tx.TxIn)))) // tx_in_count
   828  	for _, txIn := range tx.TxIn {                               // tx_in
   829  		sz += 32 /* prev hash */ + 4 /* prev index */ + 4 /* sequence */
   830  		sz += uint64(wire.VarIntSerializeSize(uint64(len(txIn.SignatureScript))) + len(txIn.SignatureScript))
   831  	}
   832  	sz += uint64(wire.VarIntSerializeSize(uint64(len(tx.TxOut)))) // tx_out_count
   833  	for _, txOut := range tx.TxOut {                              // tx_out
   834  		sz += 8 /* value */
   835  		sz += uint64(wire.VarIntSerializeSize(uint64(len(txOut.PkScript))) + len(txOut.PkScript))
   836  	}
   837  	sz += 4 // lockTime
   838  
   839  	// join-splits are only versions 2 to 4.
   840  	if ver >= VersionPreOverwinter && ver < VersionNU5 {
   841  		sz += uint64(wire.VarIntSerializeSize(tx.NJoinSplit))
   842  		if tx.NJoinSplit > 0 {
   843  			if ver < VersionSapling {
   844  				sz += tx.NJoinSplit * overwinterJoinSplitSize
   845  			} else {
   846  				sz += tx.NJoinSplit * saplingJoinSplitSize
   847  			}
   848  			sz += 32 // joinSplitPubKey
   849  			sz += 64 // joinSplitSig
   850  		}
   851  	}
   852  
   853  	if ver >= VersionOverwinter {
   854  		sz += 4 // nExpiryHeight
   855  		sz += 4 // nVersionGroupId
   856  	}
   857  
   858  	if ver >= VersionSapling {
   859  		sz += 8                                                    // valueBalanceSapling
   860  		sz += uint64(wire.VarIntSerializeSize(tx.NSpendsSapling))  // nSpendsSapling
   861  		sz += 384 * tx.NSpendsSapling                              // vSpendsSapling
   862  		sz += uint64(wire.VarIntSerializeSize(tx.NOutputsSapling)) // nOutputsSapling
   863  		sz += 948 * tx.NOutputsSapling                             // vOutputsSapling
   864  		if tx.NSpendsSapling+tx.NOutputsSapling > 0 {
   865  			sz += 64 // bindingSigSapling
   866  		}
   867  	}
   868  
   869  	if ver == VersionNU5 {
   870  		// With nSpendsSapling = 0 and nOutputsSapling = 0
   871  		sz += 4                                                    // nConsensusBranchId
   872  		sz += uint64(wire.VarIntSerializeSize(tx.NActionsOrchard)) // nActionsOrchard
   873  		if tx.NActionsOrchard > 0 {
   874  			sz += tx.NActionsOrchard * 820                               // vActionsOrchard
   875  			sz++                                                         // flagsOrchard
   876  			sz += 8                                                      // valueBalanceOrchard
   877  			sz += 32                                                     // anchorOrchard
   878  			sz += uint64(wire.VarIntSerializeSize(tx.SizeProofsOrchard)) // sizeProofsOrchard
   879  			sz += tx.SizeProofsOrchard                                   // proofsOrchard
   880  			sz += 64 * tx.NActionsOrchard                                // vSpendAuthSigsOrchard
   881  			sz += 64                                                     // bindingSigOrchard
   882  
   883  		}
   884  	}
   885  	return sz
   886  }
   887  
   888  // RequiredTxFeesZIP317 calculates the minimum tx fees according to ZIP-0317.
   889  func (tx *Tx) RequiredTxFeesZIP317() uint64 {
   890  	txInsSize := uint64(wire.VarIntSerializeSize(uint64(len(tx.TxIn))))
   891  	for _, txIn := range tx.TxIn {
   892  		txInsSize += uint64(txIn.SerializeSize())
   893  	}
   894  
   895  	txOutsSize := uint64(wire.VarIntSerializeSize(uint64(len(tx.TxOut))))
   896  	for _, txOut := range tx.TxOut {
   897  		txOutsSize += uint64(txOut.SerializeSize())
   898  	}
   899  
   900  	return TxFeesZIP317(txInsSize, txOutsSize, tx.NSpendsSapling, tx.NOutputsSapling, tx.NJoinSplit, tx.NActionsOrchard)
   901  }
   902  
   903  // writeTxIn encodes ti to the bitcoin protocol encoding for a transaction
   904  // input (TxIn) to w.
   905  func writeTxIn(w io.Writer, ti *wire.TxIn) error {
   906  	err := writeOutPoint(w, &ti.PreviousOutPoint)
   907  	if err != nil {
   908  		return err
   909  	}
   910  
   911  	err = wire.WriteVarBytes(w, pver, ti.SignatureScript)
   912  	if err != nil {
   913  		return err
   914  	}
   915  
   916  	return putUint32(w, ti.Sequence)
   917  }
   918  
   919  // writeOutPoint encodes op to the bitcoin protocol encoding for an OutPoint
   920  // to w.
   921  func writeOutPoint(w io.Writer, op *wire.OutPoint) error {
   922  	_, err := w.Write(op.Hash[:])
   923  	if err != nil {
   924  		return err
   925  	}
   926  	return putUint32(w, op.Index)
   927  }
   928  
   929  func uint32Bytes(v uint32) []byte {
   930  	b := make([]byte, 4)
   931  	binary.LittleEndian.PutUint32(b, v)
   932  	return b
   933  }
   934  
   935  // putUint32 writes a little-endian encoded uint32 to the Writer.
   936  func putUint32(w io.Writer, v uint32) error {
   937  	_, err := w.Write(uint32Bytes(v))
   938  	return err
   939  }
   940  
   941  func uint64Bytes(v uint64) []byte {
   942  	b := make([]byte, 8)
   943  	binary.LittleEndian.PutUint64(b, v)
   944  	return b
   945  }
   946  
   947  func int64Bytes(v int64) []byte {
   948  	return uint64Bytes(uint64(v))
   949  }
   950  
   951  // putUint64 writes a little-endian encoded uint64 to the Writer.
   952  func putUint64(w io.Writer, v uint64) error {
   953  	_, err := w.Write(uint64Bytes(v))
   954  	return err
   955  }
   956  
   957  // readUint32 reads a little-endian encoded uint32 from the Reader.
   958  func readUint32(r io.Reader) (uint32, error) {
   959  	b := make([]byte, 4)
   960  	if _, err := io.ReadFull(r, b); err != nil {
   961  		return 0, err
   962  	}
   963  	return binary.LittleEndian.Uint32(b), nil
   964  }
   965  
   966  // readUint64 reads a little-endian encoded uint64 from the Reader.
   967  func readUint64(r io.Reader) (uint64, error) {
   968  	b := make([]byte, 8)
   969  	if _, err := io.ReadFull(r, b); err != nil {
   970  		return 0, err
   971  	}
   972  	return binary.LittleEndian.Uint64(b), nil
   973  }
   974  
   975  func readInt64(r io.Reader) (int64, error) {
   976  	u, err := readUint64(r)
   977  	if err != nil {
   978  		return 0, err
   979  	}
   980  	return int64(u), nil
   981  }
   982  
   983  // readTxIn reads the next sequence of bytes from r as a transaction input.
   984  func readTxIn(r io.Reader, ti *wire.TxIn) error {
   985  	err := readOutPoint(r, &ti.PreviousOutPoint)
   986  	if err != nil {
   987  		return err
   988  	}
   989  
   990  	ti.SignatureScript, err = readScript(r)
   991  	if err != nil {
   992  		return err
   993  	}
   994  
   995  	ti.Sequence, err = readUint32(r)
   996  	return err
   997  }
   998  
   999  // readTxOut reads the next sequence of bytes from r as a transaction output.
  1000  func readTxOut(r io.Reader, to *wire.TxOut) error {
  1001  	v, err := readUint64(r)
  1002  	if err != nil {
  1003  		return err
  1004  	}
  1005  	to.Value = int64(v)
  1006  
  1007  	to.PkScript, err = readScript(r)
  1008  	return err
  1009  }
  1010  
  1011  // readOutPoint reads the next sequence of bytes from r as an OutPoint.
  1012  func readOutPoint(r io.Reader, op *wire.OutPoint) error {
  1013  	_, err := io.ReadFull(r, op.Hash[:])
  1014  	if err != nil {
  1015  		return err
  1016  	}
  1017  
  1018  	op.Index, err = readUint32(r)
  1019  	return err
  1020  }
  1021  
  1022  // readScript reads a variable length byte array. Copy of unexported
  1023  // btcd/wire.readScript.
  1024  func readScript(r io.Reader) ([]byte, error) {
  1025  	count, err := wire.ReadVarInt(r, pver)
  1026  	if err != nil {
  1027  		return nil, err
  1028  	}
  1029  	if count > uint64(wire.MaxMessagePayload) {
  1030  		return nil, fmt.Errorf("larger than the max allowed size "+
  1031  			"[count %d, max %d]", count, wire.MaxMessagePayload)
  1032  	}
  1033  	b := make([]byte, count)
  1034  	_, err = io.ReadFull(r, b)
  1035  	if err != nil {
  1036  		return nil, err
  1037  	}
  1038  	return b, nil
  1039  }
  1040  
  1041  func discardBytes(r io.Reader, n int64) error {
  1042  	m, err := io.CopyN(io.Discard, r, n)
  1043  	if err != nil {
  1044  		return err
  1045  	}
  1046  	if m != n {
  1047  		return fmt.Errorf("only discarded %d of %d bytes", m, n)
  1048  	}
  1049  	return nil
  1050  }
  1051  
  1052  // blake2bHash is a BLAKE-2B hash of the data with the specified personalization
  1053  // key.
  1054  func blake2bHash(data, personalizationKey []byte) (_ [32]byte, err error) {
  1055  	bHash, err := blake2b.New(&blake2b.Config{Size: 32, Person: personalizationKey})
  1056  	if err != nil {
  1057  		return
  1058  	}
  1059  
  1060  	if _, err = bHash.Write(data); err != nil {
  1061  		return
  1062  	}
  1063  
  1064  	var h [32]byte
  1065  	copy(h[:], bHash.Sum(nil))
  1066  	return h, err
  1067  }
  1068  
  1069  // CalcTxSize calculates the size of a Zcash transparent transaction. CalcTxSize
  1070  // won't return accurate results for shielded or blended transactions.
  1071  func CalcTxSize(tx *wire.MsgTx) uint64 {
  1072  	return (&Tx{MsgTx: tx}).SerializeSize()
  1073  }