diff --git a/pkg/bitcoin/transaction_builder.go b/pkg/bitcoin/transaction_builder.go index e446f07517..2b8c1f1041 100644 --- a/pkg/bitcoin/transaction_builder.go +++ b/pkg/bitcoin/transaction_builder.go @@ -148,6 +148,14 @@ func (tb *TransactionBuilder) getScript( ) } + if uint64(utxo.Outpoint.OutputIndex) >= uint64(len(transaction.Outputs)) { + return nil, fmt.Errorf( + "transaction with hash [%s] does not have output index [%v]", + hash.Hex(InternalByteOrder), + utxo.Outpoint.OutputIndex, + ) + } + return transaction.Outputs[utxo.Outpoint.OutputIndex].PublicKeyScript, nil } diff --git a/pkg/bitcoin/transaction_builder_test.go b/pkg/bitcoin/transaction_builder_test.go index 246e70cd51..638711f924 100644 --- a/pkg/bitcoin/transaction_builder_test.go +++ b/pkg/bitcoin/transaction_builder_test.go @@ -202,6 +202,34 @@ func TestTransactionBuilder_AddScriptHashInput(t *testing.T) { } } +func TestTransactionBuilder_AddPublicKeyHashInput_OutOfRangeOutputIndex(t *testing.T) { + localChain := newLocalChain() + builder := NewTransactionBuilder(localChain) + + inputTransaction := &Transaction{ + Version: 1, + Outputs: []*TransactionOutput{}, + } + + err := localChain.addTransaction(inputTransaction) + if err != nil { + t.Fatal(err) + } + + inputTransactionUtxo := &UnspentTransactionOutput{ + Outpoint: &TransactionOutpoint{ + TransactionHash: inputTransaction.Hash(), + OutputIndex: 0, + }, + Value: 1, + } + + err = builder.AddPublicKeyHashInput(inputTransactionUtxo) + if err == nil { + t.Fatal("expected error for out-of-range output index") + } +} + func TestTransactionBuilder_AddOutput(t *testing.T) { builder := NewTransactionBuilder(nil) // chain is not relevant here