diff --git a/pkg/abi/outputserialization.go b/pkg/abi/outputserialization.go index 579b9169..b97be12c 100644 --- a/pkg/abi/outputserialization.go +++ b/pkg/abi/outputserialization.go @@ -35,6 +35,7 @@ type Serializer struct { is IntSerializer fs FloatSerializer bs ByteSerializer + dn DefaultNameGenerator } // NewSerializer creates a new ABI value tree serializer, with the default @@ -48,6 +49,7 @@ func NewSerializer() *Serializer { is: Base10StringIntSerializer, fs: Base10StringFloatSerializer, bs: HexByteSerializer, + dn: NumericDefaultNameGenerator, } } @@ -70,6 +72,8 @@ var ( minSafeJSONNumberFloat = big.NewFloat(-9007199254740991) ) +type DefaultNameGenerator func(idx int) string + type IntSerializer func(i *big.Int) interface{} type FloatSerializer func(f *big.Float) interface{} @@ -96,6 +100,11 @@ func (s *Serializer) SetByteSerializer(bs ByteSerializer) *Serializer { return s } +func (s *Serializer) SetDefaultNameGenerator(dn DefaultNameGenerator) *Serializer { + s.dn = dn + return s +} + func Base10StringIntSerializer(i *big.Int) interface{} { return i.String() } @@ -133,6 +142,10 @@ func HexByteSerializer0xPrefix(b []byte) interface{} { return "0x" + hex.EncodeToString(b) } +func NumericDefaultNameGenerator(idx int) string { + return strconv.FormatInt(int64(idx), 10) +} + func (s *Serializer) SerializeInterface(cv *ComponentValue) (interface{}, error) { return s.SerializeInterfaceCtx(context.Background(), cv) } @@ -210,7 +223,7 @@ func (s *Serializer) serializeTuple(ctx context.Context, breadcrumbs string, cv if child.Component != nil { name := child.Component.KeyName() if name == "" { - name = strconv.FormatInt(int64(i), 10) + name = s.dn(i) } v, err := s.walkOutput(ctx, fmt.Sprintf("%s[%s]", breadcrumbs, name), child) if err != nil { @@ -239,7 +252,7 @@ func (s *Serializer) serializeTuple(ctx context.Context, breadcrumbs string, cv vm["type"] = child.Component.String() } if vm["name"] == "" { - vm["name"] = strconv.FormatInt(int64(i), 10) + vm["name"] = s.dn(i) } v, err := s.walkOutput(ctx, fmt.Sprintf("%s[%s]", breadcrumbs, vm["name"]), child) if err != nil { diff --git a/pkg/abi/outputserialization_test.go b/pkg/abi/outputserialization_test.go index fd24cb50..c609c4b3 100644 --- a/pkg/abi/outputserialization_test.go +++ b/pkg/abi/outputserialization_test.go @@ -20,6 +20,7 @@ import ( "context" "encoding/base64" "math/big" + "strconv" "testing" "github.com/stretchr/testify/assert" @@ -305,16 +306,23 @@ func TestJSONSerializationFormatsAnonymousTuple(t *testing.T) { j3, err := NewSerializer(). SetFormattingMode(FormatAsSelfDescribingArrays). + SetDefaultNameGenerator(func(idx int) string { + name := "input" + if idx > 0 { + name += strconv.Itoa(idx) + } + return name + }). SerializeJSON(v) assert.NoError(t, err) assert.JSONEq(t, `[ { - "name": "0", + "name": "input", "type": "address", "value": "6c26465984ac94713e83300d1f002296772ebb64" }, { - "name": "1", + "name": "input1", "type": "uint256", "value": "1" }