Skip to content

Commit

Permalink
adding changes suggested in PR. Making Inputs and Outputs public rath…
Browse files Browse the repository at this point in the history
…er than private.
  • Loading branch information
theflyingcodr committed Jul 27, 2021
1 parent e430698 commit 25d921a
Show file tree
Hide file tree
Showing 14 changed files with 97 additions and 117 deletions.
6 changes: 1 addition & 5 deletions input.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,7 @@ func (i *Input) PreviousTxIDAddStr(txID string) error {
if err != nil {
return err
}
if !IsValidTxID(bb) {
return ErrInvalidTxID
}
i.previousTxID = bb
return nil
return i.PreviousTxIDAdd(bb)
}

// PreviousTxID will return the PreviousTxID if set.
Expand Down
4 changes: 2 additions & 2 deletions localsigner.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"github.com/libsv/go-bt/sighash"
)

// LocalSigner implements the Signer interface. It is used to sign Tx inputs locally
// using a bkec PrivateKey, any input found that can be signed by the key will be signed.
// LocalSigner implements the Signer interface. It is used to sign Tx Inputs locally
// using a bkec PrivateKey.
type LocalSigner struct {
PrivateKey *bec.PrivateKey
}
Expand Down
8 changes: 4 additions & 4 deletions signaturehash.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ func (tx *Tx) CalcInputPreimage(inputNumber uint32, sigHashFlag sighash.Flag) ([
func (tx *Tx) getPreviousOutHash() []byte {
buf := make([]byte, 0)

for _, in := range tx.Inputs() {
for _, in := range tx.Inputs {
buf = append(buf, ReverseBytes(in.PreviousTxID())...)
oi := make([]byte, 4)
binary.LittleEndian.PutUint32(oi, in.PreviousTxOutIndex)
Expand All @@ -128,7 +128,7 @@ func (tx *Tx) getPreviousOutHash() []byte {
func (tx *Tx) getSequenceHash() []byte {
buf := make([]byte, 0)

for _, in := range tx.Inputs() {
for _, in := range tx.Inputs {
oi := make([]byte, 4)
binary.LittleEndian.PutUint32(oi, in.SequenceNumber)
buf = append(buf, oi...)
Expand All @@ -141,11 +141,11 @@ func (tx *Tx) getOutputsHash(n int32) []byte {
buf := make([]byte, 0)

if n == -1 {
for _, out := range tx.Outputs() {
for _, out := range tx.Outputs {
buf = append(buf, out.BytesForSigHash()...)
}
} else {
buf = append(buf, tx.Outputs()[n].BytesForSigHash()...)
buf = append(buf, tx.Outputs[n].BytesForSigHash()...)
}

return crypto.Sha256d(buf)
Expand Down
4 changes: 2 additions & 2 deletions signaturehash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ func TestTx_CalcInputSignatureHash(t *testing.T) {
assert.NotNil(t, tx)

// Add the UTXO amount and script (PreviousTxScript already in unsiged tx)
tx.Inputs()[test.index].PreviousTxSatoshis = test.previousTxSatoshis
tx.Inputs()[test.index].PreviousTxScript, err = bscript.NewFromHexString(test.previousTxScript)
tx.Inputs[test.index].PreviousTxSatoshis = test.previousTxSatoshis
tx.Inputs[test.index].PreviousTxScript, err = bscript.NewFromHexString(test.previousTxScript)
assert.NoError(t, err)

var actualSigHash []byte
Expand Down
4 changes: 2 additions & 2 deletions signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ type Signer interface {
// canonical in accordance with RFC6979 and BIP0062.
//
// To automatically sign, the PublicKey() method must also be implemented in order to
// use the public key to check which inputs can be signed for before signing.
// use the public key to check which Inputs can be signed for before signing.
type AutoSigner interface {
Signer
PublicKey(ctx context.Context ) (publicKey []byte)
PublicKey(ctx context.Context) (publicKey []byte)
}
64 changes: 24 additions & 40 deletions tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ Version no currently 1
In-counter positive integer VI = VarInt 1 - 9 bytes
list of inputs the first input of the first transaction is also called "coinbase" <in-counter>-many inputs
list of Inputs the first input of the first transaction is also called "coinbase" <in-counter>-many Inputs
(its content was ignored in earlier versions)
Out-counter positive integer VI = VarInt 1 - 9 bytes
list of outputs the outputs of the first transaction spend the mined <out-counter>-many outputs
list of Outputs the Outputs of the first transaction spend the mined <out-counter>-many Outputs
bitcoins for the block
lock_time if non-zero and sequence numbers are < 0xFFFFFFFF: block height or 4 bytes
Expand All @@ -43,8 +43,8 @@ var (
// DO NOT CHANGE ORDER - Optimised memory via malign
//
type Tx struct {
inputs []*Input
outputs []*Output
Inputs []*Input
Outputs []*Output
Version uint32
LockTime uint32
}
Expand All @@ -65,14 +65,14 @@ func (tx *Tx) MarshalJSON() ([]byte, error) {
if tx == nil {
return nil, errors.New("tx is nil so cannot be marshalled")
}
for i, o := range tx.outputs {
for i, o := range tx.Outputs {
o.index = i
}
txj := txJSON{
Version: tx.Version,
LockTime: tx.LockTime,
Inputs: tx.inputs,
Outputs: tx.outputs,
Inputs: tx.Inputs,
Outputs: tx.Outputs,
TxID: tx.TxID(),
Hash: tx.TxID(),
Size: len(tx.Bytes()),
Expand All @@ -96,8 +96,8 @@ func (tx *Tx) UnmarshalJSON(b []byte) error {
*tx = *t
return nil
}
tx.inputs = txj.Inputs
tx.outputs = txj.Outputs
tx.Inputs = txj.Inputs
tx.Outputs = txj.Outputs
tx.LockTime = txj.LockTime
tx.Version = txj.Version
return nil
Expand Down Expand Up @@ -152,7 +152,7 @@ func NewTxFromStream(b []byte) (*Tx, int, error) {
inputCount, size := DecodeVarInt(b[offset:])
offset += size

// create inputs
// create Inputs
var i uint64
var err error
var input *Input
Expand All @@ -165,7 +165,7 @@ func NewTxFromStream(b []byte) (*Tx, int, error) {
t.addInput(input)
}

// create outputs
// create Outputs
var outputCount uint64
var output *Output
outputCount, size = DecodeVarInt(b[offset:])
Expand All @@ -189,19 +189,14 @@ func NewTxFromStream(b []byte) (*Tx, int, error) {
// HasDataOutputs returns true if the transaction has
// at least one data (OP_RETURN) output in it.
func (tx *Tx) HasDataOutputs() bool {
for _, out := range tx.Outputs() {
for _, out := range tx.Outputs {
if out.LockingScript.IsData() {
return true
}
}
return false
}

// Inputs returns the inputs for the transaction.
func (tx *Tx) Inputs() []*Input {
return tx.inputs
}

// InputIdx will return the input at the specified index.
//
// This will consume an overflow error and simply return nil if the input
Expand All @@ -210,12 +205,7 @@ func (tx *Tx) InputIdx(i int) *Input {
if i > tx.InputCount()-1 {
return nil
}
return tx.inputs[i]
}

// Outputs returns the outputs for the transaction.
func (tx *Tx) Outputs() []*Output {
return tx.outputs
return tx.Inputs[i]
}

// OutputIdx will return the output at the specified index.
Expand All @@ -226,23 +216,23 @@ func (tx *Tx) OutputIdx(i int) *Output {
if i > tx.OutputCount()-1 {
return nil
}
return tx.outputs[i]
return tx.Outputs[i]
}

// IsCoinbase determines if this transaction is a coinbase by
// checking if the tx input is a standard coinbase input.
func (tx *Tx) IsCoinbase() bool {
if len(tx.inputs) != 1 {
if len(tx.Inputs) != 1 {
return false
}

cbi := make([]byte, 32)

if !bytes.Equal(tx.inputs[0].PreviousTxID(), cbi) {
if !bytes.Equal(tx.Inputs[0].PreviousTxID(), cbi) {
return false
}

if tx.inputs[0].PreviousTxOutIndex == DefaultSequenceNumber || tx.inputs[0].SequenceNumber == DefaultSequenceNumber {
if tx.Inputs[0].PreviousTxOutIndex == DefaultSequenceNumber || tx.Inputs[0].SequenceNumber == DefaultSequenceNumber {
return true
}

Expand All @@ -268,15 +258,9 @@ func (tx *Tx) String() string {

// IsValidTxID will check that the txid bytes are valid.
//
// A txid should be in hexadecimal and be of 32 bytes length.
// A txid should be of 32 bytes length.
func IsValidTxID(txid []byte) bool {
if len(txid) != 32 {
return false
}
if s := hex.EncodeToString(txid); s == "" {
return false
}
return true
return len(txid) == 32
}

// Bytes encodes the transaction into a byte array.
Expand All @@ -285,7 +269,7 @@ func (tx *Tx) Bytes() []byte {
return tx.toBytesHelper(0, nil)
}

// BytesWithClearedInputs encodes the transaction into a byte array but clears its inputs first.
// BytesWithClearedInputs encodes the transaction into a byte array but clears its Inputs first.
// This is used when signing transactions.
func (tx *Tx) BytesWithClearedInputs(index int, lockingScript []byte) []byte {
return tx.toBytesHelper(index, lockingScript)
Expand All @@ -296,9 +280,9 @@ func (tx *Tx) toBytesHelper(index int, lockingScript []byte) []byte {

h = append(h, LittleEndianBytes(tx.Version, 4)...)

h = append(h, VarInt(uint64(len(tx.inputs)))...)
h = append(h, VarInt(uint64(len(tx.Inputs)))...)

for i, in := range tx.inputs {
for i, in := range tx.Inputs {
s := in.Bytes(lockingScript != nil)
if i == index && lockingScript != nil {
h = append(h, VarInt(uint64(len(lockingScript)))...)
Expand All @@ -308,8 +292,8 @@ func (tx *Tx) toBytesHelper(index int, lockingScript []byte) []byte {
}
}

h = append(h, VarInt(uint64(len(tx.outputs)))...)
for _, out := range tx.outputs {
h = append(h, VarInt(uint64(len(tx.Outputs)))...)
for _, out := range tx.Outputs {
h = append(h, out.Bytes()...)
}

Expand Down
Loading

0 comments on commit 25d921a

Please sign in to comment.