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 }