From 603f3c70db3d83943ccdef4aac63200c26e4daa5 Mon Sep 17 00:00:00 2001 From: Chi Thanh NGUYEN Date: Mon, 25 Jan 2021 14:50:41 +0000 Subject: [PATCH] add method allowing a transaction to add inputs knowing the previous utxos owner --- tx.go | 24 ++++++++++++++++++++++++ tx_test.go | 22 ++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/tx.go b/tx.go index 0e254dca..98936476 100644 --- a/tx.go +++ b/tx.go @@ -1,6 +1,7 @@ package bt import ( + "bytes" "encoding/binary" "encoding/hex" "errors" @@ -132,6 +133,29 @@ func (tx *Tx) AddInput(input *Input) { tx.Inputs = append(tx.Inputs, input) } +// AddInputFromTx take all outputs from previous transaction +// that match a specific public key, add it as input to this new transaction. +func (tx *Tx) AddInputFromTx(pvsTx *Tx, matchPK []byte) error { + matchPKHASH160 := crypto.Hash160(matchPK) + for i, utxo := range pvsTx.Outputs { + utxoPkHASH160, errPK := utxo.LockingScript.GetPublicKeyHash() + if errPK != nil { + return errPK + } + if !bytes.Equal(utxoPkHASH160, matchPKHASH160) { + continue + } + tx.AddInput(&Input{ + PreviousTxID: pvsTx.GetTxID(), + PreviousTxOutIndex: uint32(i), + PreviousTxSatoshis: utxo.Satoshis, + PreviousTxScript: utxo.LockingScript, + SequenceNumber: 0xffffffff, + }) + } + return nil +} + // From adds a new input to the transaction from the specified UTXO fields. func (tx *Tx) From(txID string, vout uint32, prevTxLockingScript string, satoshis uint64) error { pts, err := bscript.NewFromHexString(prevTxLockingScript) diff --git a/tx_test.go b/tx_test.go index f7c86cbd..3809ac47 100644 --- a/tx_test.go +++ b/tx_test.go @@ -113,6 +113,28 @@ func TestNewTxFromBytes(t *testing.T) { }) } +func TestAddInputFromTx(t *testing.T) { + pubkey1 := []byte{1, 2, 3} // utxo test owner + pubkey2 := []byte{1, 2, 4} + + output1, err1 := bt.NewP2PKHOutputFromPubKeyBytes(pubkey1, uint64(100000)) + assert.NoError(t, err1) + output2, err2 := bt.NewP2PKHOutputFromPubKeyBytes(pubkey1, uint64(100000)) + assert.NoError(t, err2) + output3, err3 := bt.NewP2PKHOutputFromPubKeyBytes(pubkey2, uint64(5000000)) + assert.NoError(t, err3) + + prvTx := bt.NewTx() + prvTx.AddOutput(output1) + prvTx.AddOutput(output2) + prvTx.AddOutput(output3) + newTx := bt.NewTx() + err := newTx.AddInputFromTx(prvTx, pubkey1) + assert.NoError(t, err) + assert.Equal(t, newTx.InputCount(), 2) // only 2 utxos has been added + assert.Equal(t, newTx.GetTotalInputSatoshis(), uint64(200000)) +} + func TestTx_GetTxID(t *testing.T) { t.Parallel()