lbcutil/tx.go
Josh Rickmar b3e031c1f9 Add NewBlockFromReader and NewTxFromReader.
While here, remove the serializedTx field from Tx.  This field was
originally intended to be used to cache the bytes of the serialized
transaction, but it was never used and can effectively leak memory if
the Tx was created with a call to NewTxFromBytes.

ok @davecgh
2014-06-24 18:46:06 -05:00

95 lines
2.6 KiB
Go

// Copyright (c) 2013-2014 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcutil
import (
"bytes"
"github.com/conformal/btcwire"
"io"
)
// TxIndexUnknown is the value returned for a transaction index that is unknown.
// This is typically because the transaction has not been inserted into a block
// yet.
const TxIndexUnknown = -1
// Tx defines a bitcoin transaction that provides easier and more efficient
// manipulation of raw transactions. It also memoizes the hash for the
// transaction on its first access so subsequent accesses don't have to repeat
// the relatively expensive hashing operations.
type Tx struct {
msgTx *btcwire.MsgTx // Underlying MsgTx
txSha *btcwire.ShaHash // Cached transaction hash
txIndex int // Position within a block or TxIndexUnknown
}
// MsgTx returns the underlying btcwire.MsgTx for the transaction.
func (t *Tx) MsgTx() *btcwire.MsgTx {
// Return the cached transaction.
return t.msgTx
}
// Sha returns the hash of the transaction. This is equivalent to
// calling TxSha on the underlying btcwire.MsgTx, however it caches the
// result so subsequent calls are more efficient.
func (t *Tx) Sha() *btcwire.ShaHash {
// Return the cached hash if it has already been generated.
if t.txSha != nil {
return t.txSha
}
// Generate the transaction hash. Ignore the error since TxSha can't
// currently fail.
sha, _ := t.msgTx.TxSha()
// Cache the hash and return it.
t.txSha = &sha
return &sha
}
// Index returns the saved index of the transaction within a block. This value
// will be TxIndexUnknown if it hasn't already explicitly been set.
func (t *Tx) Index() int {
return t.txIndex
}
// SetIndex sets the index of the transaction in within a block.
func (t *Tx) SetIndex(index int) {
t.txIndex = index
}
// NewTx returns a new instance of a bitcoin transaction given an underlying
// btcwire.MsgTx. See Tx.
func NewTx(msgTx *btcwire.MsgTx) *Tx {
return &Tx{
msgTx: msgTx,
txIndex: TxIndexUnknown,
}
}
// NewTxFromBytes returns a new instance of a bitcoin transaction given the
// serialized bytes. See Tx.
func NewTxFromBytes(serializedTx []byte) (*Tx, error) {
br := bytes.NewReader(serializedTx)
return NewTxFromReader(br)
}
// NewTxFromReader returns a new instance of a bitcoin transaction given a
// Reader to deserialize the transaction. See Tx.
func NewTxFromReader(r io.Reader) (*Tx, error) {
// Deserialize the bytes into a MsgTx.
var msgTx btcwire.MsgTx
err := msgTx.Deserialize(r)
if err != nil {
return nil, err
}
t := Tx{
msgTx: &msgTx,
txIndex: TxIndexUnknown,
}
return &t, nil
}