| 615 | |
| 616 | |
| 617 | class CTransaction: |
| 618 | __slots__ = ("nLockTime", "version", "vin", "vout", "wit") |
| 619 | |
| 620 | def __init__(self, tx=None): |
| 621 | if tx is None: |
| 622 | self.version = 2 |
| 623 | self.vin = [] |
| 624 | self.vout = [] |
| 625 | self.wit = CTxWitness() |
| 626 | self.nLockTime = 0 |
| 627 | else: |
| 628 | self.version = tx.version |
| 629 | self.vin = copy.deepcopy(tx.vin) |
| 630 | self.vout = copy.deepcopy(tx.vout) |
| 631 | self.nLockTime = tx.nLockTime |
| 632 | self.wit = copy.deepcopy(tx.wit) |
| 633 | |
| 634 | def deserialize(self, f): |
| 635 | self.version = int.from_bytes(f.read(4), "little") |
| 636 | self.vin = deser_vector(f, CTxIn) |
| 637 | flags = 0 |
| 638 | if len(self.vin) == 0: |
| 639 | flags = int.from_bytes(f.read(1), "little") |
| 640 | # Not sure why flags can't be zero, but this |
| 641 | # matches the implementation in bitcoind |
| 642 | if (flags != 0): |
| 643 | self.vin = deser_vector(f, CTxIn) |
| 644 | self.vout = deser_vector(f, CTxOut) |
| 645 | else: |
| 646 | self.vout = deser_vector(f, CTxOut) |
| 647 | if flags != 0: |
| 648 | self.wit.vtxinwit = [CTxInWitness() for _ in range(len(self.vin))] |
| 649 | self.wit.deserialize(f) |
| 650 | else: |
| 651 | self.wit = CTxWitness() |
| 652 | self.nLockTime = int.from_bytes(f.read(4), "little") |
| 653 | |
| 654 | def serialize_without_witness(self): |
| 655 | r = b"" |
| 656 | r += self.version.to_bytes(4, "little") |
| 657 | r += ser_vector(self.vin) |
| 658 | r += ser_vector(self.vout) |
| 659 | r += self.nLockTime.to_bytes(4, "little") |
| 660 | return r |
| 661 | |
| 662 | # Only serialize with witness when explicitly called for |
| 663 | def serialize_with_witness(self): |
| 664 | flags = 0 |
| 665 | if not self.wit.is_null(): |
| 666 | flags |= 1 |
| 667 | r = b"" |
| 668 | r += self.version.to_bytes(4, "little") |
| 669 | if flags: |
| 670 | dummy = [] |
| 671 | r += ser_vector(dummy) |
| 672 | r += flags.to_bytes(1, "little") |
| 673 | r += ser_vector(self.vin) |
| 674 | r += ser_vector(self.vout) |
no outgoing calls