Skip to content

Commit 8095cee

Browse files
authored
Merge pull request #289 from blinklabs-io/feat/ledger-tx-input-output
feat: generic interface for TX inputs/outputs
2 parents 31eb0d8 + a272c83 commit 8095cee

File tree

6 files changed

+158
-27
lines changed

6 files changed

+158
-27
lines changed

cmd/block-fetch/main.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type blockFetchFlags struct {
2929
*common.GlobalFlags
3030
slot uint64
3131
hash string
32+
all bool
3233
}
3334

3435
func main() {
@@ -38,6 +39,7 @@ func main() {
3839
}
3940
f.Flagset.Uint64Var(&f.slot, "slot", 0, "slot for single block to fetch")
4041
f.Flagset.StringVar(&f.hash, "hash", "", "hash for single block to fetch")
42+
f.Flagset.BoolVar(&f.all, "all", false, "show all available detail for block")
4143
f.Parse()
4244
// Create connection
4345
conn := common.CreateClientConnection(f.GlobalFlags)
@@ -81,4 +83,24 @@ func main() {
8183
case ledger.Block:
8284
fmt.Printf("era = %s, slot = %d, block_no = %d, id = %s\n", v.Era().Name, v.SlotNumber(), v.BlockNumber(), v.Hash())
8385
}
86+
if f.all {
87+
// Display transaction info
88+
fmt.Printf("\nTransactions:\n")
89+
for _, tx := range block.Transactions() {
90+
fmt.Printf(" Hash: %s\n", tx.Hash())
91+
fmt.Printf(" Inputs:\n")
92+
for _, input := range tx.Inputs() {
93+
fmt.Printf(" Id: %s\n", input.Id())
94+
fmt.Printf(" Index: %d\n", input.Index())
95+
fmt.Println("")
96+
}
97+
fmt.Printf(" Outputs:\n")
98+
for _, output := range tx.Outputs() {
99+
fmt.Printf(" Address: %x\n", output.Address())
100+
fmt.Printf(" Amount: %d\n", output.Amount())
101+
fmt.Printf(" Assets: %#v\n", output.Assets())
102+
fmt.Println("")
103+
}
104+
}
105+
}
84106
}

ledger/alonzo.go

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func (h *AlonzoBlockHeader) Era() Era {
8080

8181
type AlonzoTransactionBody struct {
8282
MaryTransactionBody
83-
Outputs []AlonzoTransactionOutput `cbor:"1,keyasint,omitempty"`
83+
TxOutputs []AlonzoTransactionOutput `cbor:"1,keyasint,omitempty"`
8484
ScriptDataHash Blake2b256 `cbor:"11,keyasint,omitempty"`
8585
Collateral []ShelleyTransactionInput `cbor:"13,keyasint,omitempty"`
8686
RequiredSigners []Blake2b224 `cbor:"14,keyasint,omitempty"`
@@ -91,27 +91,47 @@ func (b *AlonzoTransactionBody) UnmarshalCBOR(cborData []byte) error {
9191
return b.UnmarshalCbor(cborData, b)
9292
}
9393

94+
func (b *AlonzoTransactionBody) Outputs() []TransactionOutput {
95+
ret := []TransactionOutput{}
96+
for _, output := range b.TxOutputs {
97+
ret = append(ret, output)
98+
}
99+
return ret
100+
}
101+
94102
type AlonzoTransactionOutput struct {
95103
cbor.StructAsArray
96104
cbor.DecodeStoreCbor
97-
Address Blake2b256
98-
Amount MaryTransactionOutputValue
99-
DatumHash Blake2b256
105+
OutputAddress []byte
106+
OutputAmount MaryTransactionOutputValue
107+
DatumHash Blake2b256
100108
}
101109

102110
func (o *AlonzoTransactionOutput) UnmarshalCBOR(cborData []byte) error {
103111
// Try to parse as Mary output first
104112
var tmpOutput MaryTransactionOutput
105113
if _, err := cbor.Decode(cborData, &tmpOutput); err == nil {
106114
// Copy from temp Shelley output to Alonzo format
107-
o.Address = tmpOutput.Address
108-
o.Amount = tmpOutput.Amount
115+
o.OutputAddress = tmpOutput.OutputAddress
116+
o.OutputAmount = tmpOutput.OutputAmount
109117
} else {
110118
return o.UnmarshalCbor(cborData, o)
111119
}
112120
return nil
113121
}
114122

123+
func (o AlonzoTransactionOutput) Address() []byte {
124+
return o.OutputAddress
125+
}
126+
127+
func (o AlonzoTransactionOutput) Amount() uint64 {
128+
return o.OutputAmount.Amount
129+
}
130+
131+
func (o AlonzoTransactionOutput) Assets() interface{} {
132+
return o.OutputAmount.Assets
133+
}
134+
115135
type AlonzoTransactionWitnessSet struct {
116136
ShelleyTransactionWitnessSet
117137
PlutusScripts []cbor.RawMessage `cbor:"3,keyasint,omitempty"`

ledger/babbage.go

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func (h *BabbageBlockHeader) Era() Era {
125125

126126
type BabbageTransactionBody struct {
127127
AlonzoTransactionBody
128-
Outputs []BabbageTransactionOutput `cbor:"1,keyasint,omitempty"`
128+
TxOutputs []BabbageTransactionOutput `cbor:"1,keyasint,omitempty"`
129129
CollateralReturn BabbageTransactionOutput `cbor:"16,keyasint,omitempty"`
130130
TotalCollateral uint64 `cbor:"17,keyasint,omitempty"`
131131
ReferenceInputs []ShelleyTransactionInput `cbor:"18,keyasint,omitempty"`
@@ -135,28 +135,48 @@ func (b *BabbageTransactionBody) UnmarshalCBOR(cborData []byte) error {
135135
return b.UnmarshalCbor(cborData, b)
136136
}
137137

138+
func (b *BabbageTransactionBody) Outputs() []TransactionOutput {
139+
ret := []TransactionOutput{}
140+
for _, output := range b.TxOutputs {
141+
ret = append(ret, output)
142+
}
143+
return ret
144+
}
145+
138146
type BabbageTransactionOutput struct {
139-
Address Blake2b256 `cbor:"0,keyasint,omitempty"`
140-
Amount MaryTransactionOutputValue `cbor:"1,keyasint,omitempty"`
141-
DatumOption []cbor.RawMessage `cbor:"2,keyasint,omitempty"`
142-
ScriptRef cbor.Tag `cbor:"3,keyasint,omitempty"`
143-
legacyOutput bool
147+
OutputAddress []byte `cbor:"0,keyasint,omitempty"`
148+
OutputAmount MaryTransactionOutputValue `cbor:"1,keyasint,omitempty"`
149+
DatumOption []cbor.RawMessage `cbor:"2,keyasint,omitempty"`
150+
ScriptRef cbor.Tag `cbor:"3,keyasint,omitempty"`
151+
legacyOutput bool
144152
}
145153

146154
func (o *BabbageTransactionOutput) UnmarshalCBOR(cborData []byte) error {
147155
// Try to parse as legacy output first
148156
var tmpOutput AlonzoTransactionOutput
149157
if _, err := cbor.Decode(cborData, &tmpOutput); err == nil {
150158
// Copy from temp legacy object to Babbage format
151-
o.Address = tmpOutput.Address
152-
o.Amount = tmpOutput.Amount
159+
o.OutputAddress = tmpOutput.OutputAddress
160+
o.OutputAmount = tmpOutput.OutputAmount
153161
o.legacyOutput = true
154162
} else {
155163
return cbor.DecodeGeneric(cborData, o)
156164
}
157165
return nil
158166
}
159167

168+
func (o BabbageTransactionOutput) Address() []byte {
169+
return o.OutputAddress
170+
}
171+
172+
func (o BabbageTransactionOutput) Amount() uint64 {
173+
return o.OutputAmount.Amount
174+
}
175+
176+
func (o BabbageTransactionOutput) Assets() interface{} {
177+
return o.OutputAmount.Assets
178+
}
179+
160180
type BabbageTransactionWitnessSet struct {
161181
AlonzoTransactionWitnessSet
162182
PlutusV2Scripts []cbor.RawMessage `cbor:"6,keyasint,omitempty"`

ledger/mary.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func (h *MaryBlockHeader) Era() Era {
7979

8080
type MaryTransactionBody struct {
8181
AllegraTransactionBody
82-
Outputs []MaryTransactionOutput `cbor:"1,keyasint,omitempty"`
82+
TxOutputs []MaryTransactionOutput `cbor:"1,keyasint,omitempty"`
8383
// TODO: further parsing of this field
8484
Mint cbor.Value `cbor:"9,keyasint,omitempty"`
8585
}
@@ -88,6 +88,14 @@ func (b *MaryTransactionBody) UnmarshalCBOR(cborData []byte) error {
8888
return b.UnmarshalCbor(cborData, b)
8989
}
9090

91+
func (b *MaryTransactionBody) Outputs() []TransactionOutput {
92+
ret := []TransactionOutput{}
93+
for _, output := range b.TxOutputs {
94+
ret = append(ret, output)
95+
}
96+
return ret
97+
}
98+
9199
type MaryTransaction struct {
92100
cbor.StructAsArray
93101
Body MaryTransactionBody
@@ -97,8 +105,20 @@ type MaryTransaction struct {
97105

98106
type MaryTransactionOutput struct {
99107
cbor.StructAsArray
100-
Address Blake2b256
101-
Amount MaryTransactionOutputValue
108+
OutputAddress []byte
109+
OutputAmount MaryTransactionOutputValue
110+
}
111+
112+
func (o MaryTransactionOutput) Address() []byte {
113+
return o.OutputAddress
114+
}
115+
116+
func (o MaryTransactionOutput) Amount() uint64 {
117+
return o.OutputAmount.Amount
118+
}
119+
120+
func (o MaryTransactionOutput) Assets() interface{} {
121+
return o.OutputAmount.Assets
102122
}
103123

104124
type MaryTransactionOutputValue struct {

ledger/shelley.go

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,11 @@ func (h *ShelleyBlockHeader) Era() Era {
119119

120120
type ShelleyTransactionBody struct {
121121
cbor.DecodeStoreCbor
122-
hash string
123-
Inputs []ShelleyTransactionInput `cbor:"0,keyasint,omitempty"`
124-
Outputs []ShelleyTransactionOutput `cbor:"1,keyasint,omitempty"`
125-
Fee uint64 `cbor:"2,keyasint,omitempty"`
126-
Ttl uint64 `cbor:"3,keyasint,omitempty"`
122+
hash string
123+
TxInputs []ShelleyTransactionInput `cbor:"0,keyasint,omitempty"`
124+
TxOutputs []ShelleyTransactionOutput `cbor:"1,keyasint,omitempty"`
125+
Fee uint64 `cbor:"2,keyasint,omitempty"`
126+
Ttl uint64 `cbor:"3,keyasint,omitempty"`
127127
// TODO: figure out how to parse properly
128128
Certificates cbor.RawMessage `cbor:"4,keyasint,omitempty"`
129129
// TODO: figure out how to parse this correctly
@@ -149,16 +149,52 @@ func (b *ShelleyTransactionBody) Hash() string {
149149
return b.hash
150150
}
151151

152+
func (b *ShelleyTransactionBody) Inputs() []TransactionInput {
153+
ret := []TransactionInput{}
154+
for _, input := range b.TxInputs {
155+
ret = append(ret, input)
156+
}
157+
return ret
158+
}
159+
160+
func (b *ShelleyTransactionBody) Outputs() []TransactionOutput {
161+
ret := []TransactionOutput{}
162+
for _, output := range b.TxOutputs {
163+
ret = append(ret, output)
164+
}
165+
return ret
166+
}
167+
152168
type ShelleyTransactionInput struct {
153169
cbor.StructAsArray
154-
Id Blake2b256
155-
Index uint32
170+
TxId Blake2b256
171+
OutputIndex uint32
172+
}
173+
174+
func (i ShelleyTransactionInput) Id() Blake2b256 {
175+
return i.TxId
176+
}
177+
178+
func (i ShelleyTransactionInput) Index() uint32 {
179+
return i.OutputIndex
156180
}
157181

158182
type ShelleyTransactionOutput struct {
159183
cbor.StructAsArray
160-
Address Blake2b256
161-
Amount uint64
184+
OutputAddress []byte
185+
OutputAmount uint64
186+
}
187+
188+
func (o ShelleyTransactionOutput) Address() []byte {
189+
return o.OutputAddress
190+
}
191+
192+
func (o ShelleyTransactionOutput) Amount() uint64 {
193+
return o.OutputAmount
194+
}
195+
196+
func (o ShelleyTransactionOutput) Assets() interface{} {
197+
return nil
162198
}
163199

164200
type ShelleyTransactionWitnessSet struct {

ledger/tx.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,20 @@ import (
2424
type TransactionBody interface {
2525
Hash() string
2626
Cbor() []byte
27-
// TODO: add additional functions for things like inputs, outputs, etc.
27+
Inputs() []TransactionInput
28+
Outputs() []TransactionOutput
29+
}
30+
31+
type TransactionInput interface {
32+
Id() Blake2b256
33+
Index() uint32
34+
}
35+
36+
type TransactionOutput interface {
37+
Address() []byte
38+
Amount() uint64
39+
// TODO: create more specific type/interface for assets
40+
Assets() interface{}
2841
}
2942

3043
func NewTransactionFromCbor(txType uint, data []byte) (interface{}, error) {

0 commit comments

Comments
 (0)