forked from cerc-io/plugeth
accounts/abi/bind: avoid reclaring structs (#20381)
This commit is contained in:
parent
44b41641f8
commit
b26eedf9e9
@ -48,12 +48,16 @@ const (
|
|||||||
// enforces compile time type safety and naming convention opposed to having to
|
// enforces compile time type safety and naming convention opposed to having to
|
||||||
// manually maintain hard coded strings that break on runtime.
|
// manually maintain hard coded strings that break on runtime.
|
||||||
func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang, libs map[string]string, aliases map[string]string) (string, error) {
|
func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang, libs map[string]string, aliases map[string]string) (string, error) {
|
||||||
// Process each individual contract requested binding
|
var (
|
||||||
contracts := make(map[string]*tmplContract)
|
// contracts is the map of each individual contract requested binding
|
||||||
|
contracts = make(map[string]*tmplContract)
|
||||||
|
|
||||||
// Map used to flag each encountered library as such
|
// structs is the map of all reclared structs shared by passed contracts.
|
||||||
isLib := make(map[string]struct{})
|
structs = make(map[string]*tmplStruct)
|
||||||
|
|
||||||
|
// isLib is the map used to flag each encountered library as such
|
||||||
|
isLib = make(map[string]struct{})
|
||||||
|
)
|
||||||
for i := 0; i < len(types); i++ {
|
for i := 0; i < len(types); i++ {
|
||||||
// Parse the actual ABI to generate the binding for
|
// Parse the actual ABI to generate the binding for
|
||||||
evmABI, err := abi.JSON(strings.NewReader(abis[i]))
|
evmABI, err := abi.JSON(strings.NewReader(abis[i]))
|
||||||
@ -73,7 +77,6 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
|
|||||||
calls = make(map[string]*tmplMethod)
|
calls = make(map[string]*tmplMethod)
|
||||||
transacts = make(map[string]*tmplMethod)
|
transacts = make(map[string]*tmplMethod)
|
||||||
events = make(map[string]*tmplEvent)
|
events = make(map[string]*tmplEvent)
|
||||||
structs = make(map[string]*tmplStruct)
|
|
||||||
|
|
||||||
// identifiers are used to detect duplicated identifier of function
|
// identifiers are used to detect duplicated identifier of function
|
||||||
// and event. For all calls, transacts and events, abigen will generate
|
// and event. For all calls, transacts and events, abigen will generate
|
||||||
@ -168,7 +171,6 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
|
|||||||
Transacts: transacts,
|
Transacts: transacts,
|
||||||
Events: events,
|
Events: events,
|
||||||
Libraries: make(map[string]string),
|
Libraries: make(map[string]string),
|
||||||
Structs: structs,
|
|
||||||
}
|
}
|
||||||
// Function 4-byte signatures are stored in the same sequence
|
// Function 4-byte signatures are stored in the same sequence
|
||||||
// as types, if available.
|
// as types, if available.
|
||||||
@ -200,6 +202,7 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
|
|||||||
Package: pkg,
|
Package: pkg,
|
||||||
Contracts: contracts,
|
Contracts: contracts,
|
||||||
Libraries: libs,
|
Libraries: libs,
|
||||||
|
Structs: structs,
|
||||||
}
|
}
|
||||||
buffer := new(bytes.Buffer)
|
buffer := new(bytes.Buffer)
|
||||||
|
|
||||||
|
@ -1448,6 +1448,88 @@ var bindTests = []struct {
|
|||||||
map[string]string{"_myVar": "pubVar"}, // alias MyVar to PubVar
|
map[string]string{"_myVar": "pubVar"}, // alias MyVar to PubVar
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"MultiContracts",
|
||||||
|
`
|
||||||
|
pragma solidity ^0.5.11;
|
||||||
|
pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
|
library ExternalLib {
|
||||||
|
struct SharedStruct{
|
||||||
|
uint256 f1;
|
||||||
|
bytes32 f2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract ContractOne {
|
||||||
|
function foo(ExternalLib.SharedStruct memory s) pure public {
|
||||||
|
// Do stuff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract ContractTwo {
|
||||||
|
function bar(ExternalLib.SharedStruct memory s) pure public {
|
||||||
|
// Do stuff
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
[]string{
|
||||||
|
`60806040523480156100115760006000fd5b50610017565b6101b5806100266000396000f3fe60806040523480156100115760006000fd5b50600436106100305760003560e01c80639d8a8ba81461003657610030565b60006000fd5b610050600480360361004b91908101906100d1565b610052565b005b5b5056610171565b6000813590506100698161013d565b92915050565b6000604082840312156100825760006000fd5b61008c60406100fb565b9050600061009c848285016100bc565b60008301525060206100b08482850161005a565b60208301525092915050565b6000813590506100cb81610157565b92915050565b6000604082840312156100e45760006000fd5b60006100f28482850161006f565b91505092915050565b6000604051905081810181811067ffffffffffffffff8211171561011f5760006000fd5b8060405250919050565b6000819050919050565b6000819050919050565b61014681610129565b811415156101545760006000fd5b50565b61016081610133565b8114151561016e5760006000fd5b50565bfea365627a7a72315820749274eb7f6c01010d5322af4e1668b0a154409eb7968bd6cae5524c7ed669bb6c6578706572696d656e74616cf564736f6c634300050c0040`,
|
||||||
|
`60806040523480156100115760006000fd5b50610017565b6101b5806100266000396000f3fe60806040523480156100115760006000fd5b50600436106100305760003560e01c8063db8ba08c1461003657610030565b60006000fd5b610050600480360361004b91908101906100d1565b610052565b005b5b5056610171565b6000813590506100698161013d565b92915050565b6000604082840312156100825760006000fd5b61008c60406100fb565b9050600061009c848285016100bc565b60008301525060206100b08482850161005a565b60208301525092915050565b6000813590506100cb81610157565b92915050565b6000604082840312156100e45760006000fd5b60006100f28482850161006f565b91505092915050565b6000604051905081810181811067ffffffffffffffff8211171561011f5760006000fd5b8060405250919050565b6000819050919050565b6000819050919050565b61014681610129565b811415156101545760006000fd5b50565b61016081610133565b8114151561016e5760006000fd5b50565bfea365627a7a723158209bc28ee7ea97c131a13330d77ec73b4493b5c59c648352da81dd288b021192596c6578706572696d656e74616cf564736f6c634300050c0040`,
|
||||||
|
`606c6026600b82828239805160001a6073141515601857fe5b30600052607381538281f350fe73000000000000000000000000000000000000000030146080604052600436106023575b60006000fdfea365627a7a72315820518f0110144f5b3de95697d05e456a064656890d08e6f9cff47f3be710cc46a36c6578706572696d656e74616cf564736f6c634300050c0040`,
|
||||||
|
},
|
||||||
|
[]string{
|
||||||
|
`[{"constant":true,"inputs":[{"components":[{"internalType":"uint256","name":"f1","type":"uint256"},{"internalType":"bytes32","name":"f2","type":"bytes32"}],"internalType":"struct ExternalLib.SharedStruct","name":"s","type":"tuple"}],"name":"foo","outputs":[],"payable":false,"stateMutability":"pure","type":"function"}]`,
|
||||||
|
`[{"constant":true,"inputs":[{"components":[{"internalType":"uint256","name":"f1","type":"uint256"},{"internalType":"bytes32","name":"f2","type":"bytes32"}],"internalType":"struct ExternalLib.SharedStruct","name":"s","type":"tuple"}],"name":"bar","outputs":[],"payable":false,"stateMutability":"pure","type":"function"}]`,
|
||||||
|
`[]`,
|
||||||
|
},
|
||||||
|
`
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
|
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
"github.com/ethereum/go-ethereum/core"
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
key, _ := crypto.GenerateKey()
|
||||||
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
|
|
||||||
|
// Deploy registrar contract
|
||||||
|
sim := backends.NewSimulatedBackend(core.GenesisAlloc{addr: {Balance: big.NewInt(1000000000)}}, 10000000)
|
||||||
|
defer sim.Close()
|
||||||
|
|
||||||
|
transactOpts := bind.NewKeyedTransactor(key)
|
||||||
|
_, _, c1, err := DeployContractOne(transactOpts, sim)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Failed to deploy contract")
|
||||||
|
}
|
||||||
|
sim.Commit()
|
||||||
|
err = c1.Foo(nil, ExternalLibSharedStruct{
|
||||||
|
F1: big.NewInt(100),
|
||||||
|
F2: [32]byte{0x01, 0x02, 0x03},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Failed to invoke function")
|
||||||
|
}
|
||||||
|
_, _, c2, err := DeployContractTwo(transactOpts, sim)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Failed to deploy contract")
|
||||||
|
}
|
||||||
|
sim.Commit()
|
||||||
|
err = c2.Bar(nil, ExternalLibSharedStruct{
|
||||||
|
F1: big.NewInt(100),
|
||||||
|
F2: [32]byte{0x01, 0x02, 0x03},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("Failed to invoke function")
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
[]string{"ContractOne", "ContractTwo", "ExternalLib"},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests that packages generated by the binder can be successfully compiled and
|
// Tests that packages generated by the binder can be successfully compiled and
|
||||||
|
@ -23,6 +23,7 @@ type tmplData struct {
|
|||||||
Package string // Name of the package to place the generated file in
|
Package string // Name of the package to place the generated file in
|
||||||
Contracts map[string]*tmplContract // List of contracts to generate into this file
|
Contracts map[string]*tmplContract // List of contracts to generate into this file
|
||||||
Libraries map[string]string // Map the bytecode's link pattern to the library name
|
Libraries map[string]string // Map the bytecode's link pattern to the library name
|
||||||
|
Structs map[string]*tmplStruct // Contract struct type definitions
|
||||||
}
|
}
|
||||||
|
|
||||||
// tmplContract contains the data needed to generate an individual contract binding.
|
// tmplContract contains the data needed to generate an individual contract binding.
|
||||||
@ -36,8 +37,7 @@ type tmplContract struct {
|
|||||||
Transacts map[string]*tmplMethod // Contract calls that write state data
|
Transacts map[string]*tmplMethod // Contract calls that write state data
|
||||||
Events map[string]*tmplEvent // Contract events accessors
|
Events map[string]*tmplEvent // Contract events accessors
|
||||||
Libraries map[string]string // Same as tmplData, but filtered to only keep what the contract needs
|
Libraries map[string]string // Same as tmplData, but filtered to only keep what the contract needs
|
||||||
Structs map[string]*tmplStruct // Contract struct type definitions
|
Library bool // Indicator whether the contract is a library
|
||||||
Library bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// tmplMethod is a wrapper around an abi.Method that contains a few preprocessed
|
// tmplMethod is a wrapper around an abi.Method that contains a few preprocessed
|
||||||
@ -108,8 +108,16 @@ var (
|
|||||||
_ = event.NewSubscription
|
_ = event.NewSubscription
|
||||||
)
|
)
|
||||||
|
|
||||||
|
{{$structs := .Structs}}
|
||||||
|
{{range $structs}}
|
||||||
|
// {{.Name}} is an auto generated low-level Go binding around an user-defined struct.
|
||||||
|
type {{.Name}} struct {
|
||||||
|
{{range $field := .Fields}}
|
||||||
|
{{$field.Name}} {{$field.Type}}{{end}}
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
{{range $contract := .Contracts}}
|
{{range $contract := .Contracts}}
|
||||||
{{$structs := $contract.Structs}}
|
|
||||||
// {{.Type}}ABI is the input ABI used to generate the binding from.
|
// {{.Type}}ABI is the input ABI used to generate the binding from.
|
||||||
const {{.Type}}ABI = "{{.InputABI}}"
|
const {{.Type}}ABI = "{{.InputABI}}"
|
||||||
|
|
||||||
@ -285,14 +293,6 @@ var (
|
|||||||
return _{{$contract.Type}}.Contract.contract.Transact(opts, method, params...)
|
return _{{$contract.Type}}.Contract.contract.Transact(opts, method, params...)
|
||||||
}
|
}
|
||||||
|
|
||||||
{{range .Structs}}
|
|
||||||
// {{.Name}} is an auto generated low-level Go binding around an user-defined struct.
|
|
||||||
type {{.Name}} struct {
|
|
||||||
{{range $field := .Fields}}
|
|
||||||
{{$field.Name}} {{$field.Type}}{{end}}
|
|
||||||
}
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{range .Calls}}
|
{{range .Calls}}
|
||||||
// {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
|
// {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
|
||||||
//
|
//
|
||||||
@ -507,8 +507,8 @@ package {{.Package}};
|
|||||||
import org.ethereum.geth.*;
|
import org.ethereum.geth.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
{{$structs := .Structs}}
|
||||||
{{range $contract := .Contracts}}
|
{{range $contract := .Contracts}}
|
||||||
{{$structs := $contract.Structs}}
|
|
||||||
{{if not .Library}}public {{end}}class {{.Type}} {
|
{{if not .Library}}public {{end}}class {{.Type}} {
|
||||||
// ABI is the input ABI used to generate the binding from.
|
// ABI is the input ABI used to generate the binding from.
|
||||||
public final static String ABI = "{{.InputABI}}";
|
public final static String ABI = "{{.InputABI}}";
|
||||||
|
Loading…
Reference in New Issue
Block a user