From 08065000c6b43bf1eeac1b10a1704e43e076eb1c Mon Sep 17 00:00:00 2001 From: jiang Date: Fri, 26 May 2023 16:16:13 +0800 Subject: [PATCH 1/3] feat: support parse method input from input data of transaction in abigen --- accounts/abi/bind/template.go | 52 ++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index c22eb4ae8432..5f4c6705f8b5 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -87,9 +87,11 @@ const tmplSourceGo = ` package {{.Package}} import ( + "errors" + "fmt" "math/big" + "reflect" "strings" - "errors" ethereum "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" @@ -378,6 +380,54 @@ var ( } {{end}} + {{$metaType := .Type}} + {{range .Transacts}} + {{if ne (len .Normalized.Inputs) 0}} + + // {{.Normalized.Name}}Params is an auto generated read-only Go binding of transcaction calldata params + type {{.Normalized.Name}}Params struct { + {{range $i, $_ := .Normalized.Inputs}} Param_{{.Name}} {{bindtype .Type $structs}} + {{end}} + } + + // Parse {{.Normalized.Name}} method from calldata of a transaction + // + // Solidity: {{.Original.String}} + func Parse{{.Normalized.Name}}(calldata []byte) (*{{.Normalized.Name}}Params, error) { + if len(calldata) <= 4 { + return nil, fmt.Errorf("invalid calldata input") + } + + _abi, err := {{$metaType}}MetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to get abi of registry metadata:%w", err) + } + + params, err := _abi.Methods["{{.Original.Name}}"].Inputs.Unpack(calldata[4:]) + if err != nil { + return nil, fmt.Errorf("failed to unpack {{.Original.Name}} params data: %w", err) + } + + var paramsResult = new({{.Normalized.Name}}Params) + value := reflect.ValueOf(paramsResult).Elem() + + if value.NumField() != len(params) { + return nil, fmt.Errorf("failed to match calldata with param field number") + } + + for i := range params { + if !value.Field(i).CanSet() { + return nil, fmt.Errorf("failed to set param value in field %v, value %v", value.Field(i), params[i]) + } + value.Field(i).Set(reflect.ValueOf(params[i])) + } + + return paramsResult, nil + } + + {{end}} + {{end}} + {{if .Fallback}} // Fallback is a paid mutator transaction binding the contract fallback function. // From 197a4c8cefcb1fddb1c43db3a9ce9a05be116324 Mon Sep 17 00:00:00 2001 From: jiang Date: Fri, 26 May 2023 22:18:36 +0800 Subject: [PATCH 2/3] fix: fix parse struct by using `abi.ConvertType` --- accounts/abi/bind/template.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index 5f4c6705f8b5..05b6d745e43e 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -403,7 +403,7 @@ var ( return nil, fmt.Errorf("failed to get abi of registry metadata:%w", err) } - params, err := _abi.Methods["{{.Original.Name}}"].Inputs.Unpack(calldata[4:]) + out, err := _abi.Methods["{{.Original.Name}}"].Inputs.Unpack(calldata[4:]) if err != nil { return nil, fmt.Errorf("failed to unpack {{.Original.Name}} params data: %w", err) } @@ -411,18 +411,16 @@ var ( var paramsResult = new({{.Normalized.Name}}Params) value := reflect.ValueOf(paramsResult).Elem() - if value.NumField() != len(params) { + if value.NumField() != len(out) { return nil, fmt.Errorf("failed to match calldata with param field number") } - for i := range params { - if !value.Field(i).CanSet() { - return nil, fmt.Errorf("failed to set param value in field %v, value %v", value.Field(i), params[i]) - } - value.Field(i).Set(reflect.ValueOf(params[i])) - } - - return paramsResult, nil + {{range $i, $t := .Normalized.Inputs}} + out{{$i}} := *abi.ConvertType(out[{{$i}}], new({{bindtype .Type $structs}})).(*{{bindtype .Type $structs}}){{end}} + + return &{{.Normalized.Name}}Params{ + {{range $i, $_ := .Normalized.Inputs}} Param_{{.Name}} : out{{$i}},{{end}} + }, nil } {{end}} From 99c4391da2ea53b54ed26644a22507f69a8f0879 Mon Sep 17 00:00:00 2001 From: jiang Date: Fri, 26 May 2023 22:34:37 +0800 Subject: [PATCH 3/3] style: add space in front of error value --- accounts/abi/bind/template.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go index 05b6d745e43e..4f65971b7033 100644 --- a/accounts/abi/bind/template.go +++ b/accounts/abi/bind/template.go @@ -400,7 +400,7 @@ var ( _abi, err := {{$metaType}}MetaData.GetAbi() if err != nil { - return nil, fmt.Errorf("failed to get abi of registry metadata:%w", err) + return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err) } out, err := _abi.Methods["{{.Original.Name}}"].Inputs.Unpack(calldata[4:])