2014-01-09 06:46:05 +01:00
|
|
|
// Copyright (c) 2013-2014 Conformal Systems LLC.
|
2013-10-27 18:17:06 +01:00
|
|
|
// Use of this source code is governed by an ISC
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package btcutil
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2014-06-24 05:01:21 +02:00
|
|
|
"io"
|
2014-07-03 02:29:48 +02:00
|
|
|
|
|
|
|
"github.com/conformal/btcwire"
|
2013-10-27 18:17:06 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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 {
|
2014-06-24 05:01:21 +02:00
|
|
|
msgTx *btcwire.MsgTx // Underlying MsgTx
|
|
|
|
txSha *btcwire.ShaHash // Cached transaction hash
|
|
|
|
txIndex int // Position within a block or TxIndexUnknown
|
2013-10-27 18:17:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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) {
|
2014-06-24 05:01:21 +02:00
|
|
|
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) {
|
2013-10-27 18:17:06 +01:00
|
|
|
// Deserialize the bytes into a MsgTx.
|
|
|
|
var msgTx btcwire.MsgTx
|
2014-06-24 05:01:21 +02:00
|
|
|
err := msgTx.Deserialize(r)
|
2013-10-27 18:17:06 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
t := Tx{
|
2014-06-24 05:01:21 +02:00
|
|
|
msgTx: &msgTx,
|
|
|
|
txIndex: TxIndexUnknown,
|
2013-10-27 18:17:06 +01:00
|
|
|
}
|
|
|
|
return &t, nil
|
|
|
|
}
|