diff --git a/ledger/allegra.go b/ledger/allegra.go index 40622259..668d092b 100644 --- a/ledger/allegra.go +++ b/ledger/allegra.go @@ -242,8 +242,18 @@ func (t AllegraTransaction) Consumed() []TransactionInput { return t.Inputs() } -func (t AllegraTransaction) Produced() []TransactionOutput { - return t.Outputs() +func (t AllegraTransaction) Produced() []Utxo { + var ret []Utxo + for idx, output := range t.Outputs() { + ret = append( + ret, + Utxo{ + Id: NewShelleyTransactionInput(t.Hash(), idx), + Output: output, + }, + ) + } + return ret } func (t AllegraTransaction) ProtocolParametersUpdate() map[Blake2b224]any { diff --git a/ledger/alonzo.go b/ledger/alonzo.go index b6e842ba..0414d80b 100644 --- a/ledger/alonzo.go +++ b/ledger/alonzo.go @@ -373,12 +373,22 @@ func (t AlonzoTransaction) Consumed() []TransactionInput { } } -func (t AlonzoTransaction) Produced() []TransactionOutput { +func (t AlonzoTransaction) Produced() []Utxo { if t.IsValid() { - return t.Outputs() + var ret []Utxo + for idx, output := range t.Outputs() { + ret = append( + ret, + Utxo{ + Id: NewShelleyTransactionInput(t.Hash(), idx), + Output: output, + }, + ) + } + return ret } else { // No collateral return in Alonzo - return []TransactionOutput{} + return []Utxo{} } } diff --git a/ledger/babbage.go b/ledger/babbage.go index 75f741d9..ff88df4b 100644 --- a/ledger/babbage.go +++ b/ledger/babbage.go @@ -553,14 +553,29 @@ func (t BabbageTransaction) Consumed() []TransactionInput { } } -func (t BabbageTransaction) Produced() []TransactionOutput { +func (t BabbageTransaction) Produced() []Utxo { if t.IsValid() { - return t.Outputs() + var ret []Utxo + for idx, output := range t.Outputs() { + ret = append( + ret, + Utxo{ + Id: NewShelleyTransactionInput(t.Hash(), idx), + Output: output, + }, + ) + } + return ret } else { if t.CollateralReturn() == nil { - return []TransactionOutput{} + return []Utxo{} + } + return []Utxo{ + { + Id: NewShelleyTransactionInput(t.Hash(), len(t.Outputs())), + Output: t.CollateralReturn(), + }, } - return []TransactionOutput{t.CollateralReturn()} } } diff --git a/ledger/byron.go b/ledger/byron.go index 2b3089b6..88d0c8b9 100644 --- a/ledger/byron.go +++ b/ledger/byron.go @@ -15,6 +15,7 @@ package ledger import ( + "encoding/hex" "fmt" utxorpc "github.com/utxorpc/go-codegen/utxorpc/v1alpha/cardano" @@ -257,8 +258,18 @@ func (t *ByronTransaction) Consumed() []TransactionInput { return t.Inputs() } -func (t *ByronTransaction) Produced() []TransactionOutput { - return t.Outputs() +func (t *ByronTransaction) Produced() []Utxo { + var ret []Utxo + for idx, output := range t.Outputs() { + ret = append( + ret, + Utxo{ + Id: NewByronTransactionInput(t.Hash(), idx), + Output: output, + }, + ) + } + return ret } func (t *ByronTransaction) Utxorpc() *utxorpc.Tx { @@ -280,6 +291,17 @@ type ByronTransactionInput struct { OutputIndex uint32 } +func NewByronTransactionInput(hash string, idx int) ByronTransactionInput { + tmpHash, err := hex.DecodeString(hash) + if err != nil { + panic(fmt.Sprintf("failed to decode transaction hash: %s", err)) + } + return ByronTransactionInput{ + TxId: Blake2b256(tmpHash), + OutputIndex: uint32(idx), + } +} + func (i *ByronTransactionInput) UnmarshalCBOR(data []byte) error { id, err := cbor.DecodeIdFromList(data) if err != nil { diff --git a/ledger/conway.go b/ledger/conway.go index badecf0c..cddba314 100644 --- a/ledger/conway.go +++ b/ledger/conway.go @@ -441,14 +441,29 @@ func (t ConwayTransaction) Consumed() []TransactionInput { } } -func (t ConwayTransaction) Produced() []TransactionOutput { +func (t ConwayTransaction) Produced() []Utxo { if t.IsValid() { - return t.Outputs() + var ret []Utxo + for idx, output := range t.Outputs() { + ret = append( + ret, + Utxo{ + Id: NewShelleyTransactionInput(t.Hash(), idx), + Output: output, + }, + ) + } + return ret } else { if t.CollateralReturn() == nil { - return []TransactionOutput{} + return []Utxo{} + } + return []Utxo{ + { + Id: NewShelleyTransactionInput(t.Hash(), len(t.Outputs())), + Output: t.CollateralReturn(), + }, } - return []TransactionOutput{t.CollateralReturn()} } } diff --git a/ledger/mary.go b/ledger/mary.go index 02c8b548..2e845aee 100644 --- a/ledger/mary.go +++ b/ledger/mary.go @@ -259,8 +259,18 @@ func (t MaryTransaction) Consumed() []TransactionInput { return t.Inputs() } -func (t MaryTransaction) Produced() []TransactionOutput { - return t.Outputs() +func (t MaryTransaction) Produced() []Utxo { + var ret []Utxo + for idx, output := range t.Outputs() { + ret = append( + ret, + Utxo{ + Id: NewShelleyTransactionInput(t.Hash(), idx), + Output: output, + }, + ) + } + return ret } func (t *MaryTransaction) Cbor() []byte { diff --git a/ledger/shelley.go b/ledger/shelley.go index 291124b8..fae744b0 100644 --- a/ledger/shelley.go +++ b/ledger/shelley.go @@ -332,6 +332,17 @@ type ShelleyTransactionInput struct { OutputIndex uint32 } +func NewShelleyTransactionInput(hash string, idx int) ShelleyTransactionInput { + tmpHash, err := hex.DecodeString(hash) + if err != nil { + panic(fmt.Sprintf("failed to decode transaction hash: %s", err)) + } + return ShelleyTransactionInput{ + TxId: Blake2b256(tmpHash), + OutputIndex: uint32(idx), + } +} + func (i ShelleyTransactionInput) Id() Blake2b256 { return i.TxId } @@ -502,8 +513,18 @@ func (t ShelleyTransaction) Consumed() []TransactionInput { return t.Inputs() } -func (t ShelleyTransaction) Produced() []TransactionOutput { - return t.Outputs() +func (t ShelleyTransaction) Produced() []Utxo { + var ret []Utxo + for idx, output := range t.Outputs() { + ret = append( + ret, + Utxo{ + Id: NewShelleyTransactionInput(t.Hash(), idx), + Output: output, + }, + ) + } + return ret } func (t ShelleyTransaction) Utxorpc() *utxorpc.Tx { diff --git a/ledger/tx.go b/ledger/tx.go index 8c4eef50..5f48d622 100644 --- a/ledger/tx.go +++ b/ledger/tx.go @@ -29,7 +29,7 @@ type Transaction interface { Metadata() *cbor.LazyValue IsValid() bool Consumed() []TransactionInput - Produced() []TransactionOutput + Produced() []Utxo } type TransactionBody interface { @@ -74,6 +74,11 @@ type TransactionOutput interface { Utxorpc() *utxorpc.TxOutput } +type Utxo struct { + Id TransactionInput + Output TransactionOutput +} + func NewTransactionFromCbor(txType uint, data []byte) (Transaction, error) { switch txType { case TxTypeByron: