github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/btcutil/tx.go (about) 1 // Copyright (c) 2013-2016 The btcsuite developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package btcutil 6 7 import ( 8 "bytes" 9 "io" 10 11 "github.com/mit-dci/lit/btcutil/chaincfg/chainhash" 12 "github.com/mit-dci/lit/wire" 13 ) 14 15 // TxIndexUnknown is the value returned for a transaction index that is unknown. 16 // This is typically because the transaction has not been inserted into a block 17 // yet. 18 const TxIndexUnknown = -1 19 20 // Tx defines a bitcoin transaction that provides easier and more efficient 21 // manipulation of raw transactions. It also memoizes the hash for the 22 // transaction on its first access so subsequent accesses don't have to repeat 23 // the relatively expensive hashing operations. 24 type Tx struct { 25 msgTx *wire.MsgTx // Underlying MsgTx 26 txHash *chainhash.Hash // Cached transaction hash 27 txHashWitness *chainhash.Hash // Cached transaction witness hash 28 txIndex int // Position within a block or TxIndexUnknown 29 } 30 31 // MsgTx returns the underlying wire.MsgTx for the transaction. 32 func (t *Tx) MsgTx() *wire.MsgTx { 33 // Return the cached transaction. 34 return t.msgTx 35 } 36 37 // Hash returns the hash of the transaction. This is equivalent to 38 // calling TxHash on the underlying wire.MsgTx, however it caches the 39 // result so subsequent calls are more efficient. 40 func (t *Tx) Hash() *chainhash.Hash { 41 // Return the cached hash if it has already been generated. 42 if t.txHash != nil { 43 return t.txHash 44 } 45 46 // Cache the hash and return it. 47 hash := t.msgTx.TxHash() 48 t.txHash = &hash 49 return &hash 50 } 51 52 // WitnessHash returns the witness hash (wtxid) of the transaction. This is 53 // equivalent to calling WitnessHash on the underlying wire.MsgTx, however it 54 // caches the result so subsequent calls are more efficient. 55 func (t *Tx) WitnessHash() *chainhash.Hash { 56 // Return the cached hash if it has already been generated. 57 if t.txHashWitness != nil { 58 return t.txHashWitness 59 } 60 61 // Cache the hash and return it. 62 hash := t.msgTx.WitnessHash() 63 t.txHashWitness = &hash 64 return &hash 65 } 66 67 // Index returns the saved index of the transaction within a block. This value 68 // will be TxIndexUnknown if it hasn't already explicitly been set. 69 func (t *Tx) Index() int { 70 return t.txIndex 71 } 72 73 // SetIndex sets the index of the transaction in within a block. 74 func (t *Tx) SetIndex(index int) { 75 t.txIndex = index 76 } 77 78 // NewTx returns a new instance of a bitcoin transaction given an underlying 79 // wire.MsgTx. See Tx. 80 func NewTx(msgTx *wire.MsgTx) *Tx { 81 return &Tx{ 82 msgTx: msgTx, 83 txIndex: TxIndexUnknown, 84 } 85 } 86 87 // NewTxFromBytes returns a new instance of a bitcoin transaction given the 88 // serialized bytes. See Tx. 89 func NewTxFromBytes(serializedTx []byte) (*Tx, error) { 90 br := bytes.NewReader(serializedTx) 91 return NewTxFromReader(br) 92 } 93 94 // NewTxFromReader returns a new instance of a bitcoin transaction given a 95 // Reader to deserialize the transaction. See Tx. 96 func NewTxFromReader(r io.Reader) (*Tx, error) { 97 // Deserialize the bytes into a MsgTx. 98 var msgTx wire.MsgTx 99 err := msgTx.Deserialize(r) 100 if err != nil { 101 return nil, err 102 } 103 104 t := Tx{ 105 msgTx: &msgTx, 106 txIndex: TxIndexUnknown, 107 } 108 return &t, nil 109 }