Skip to content

Commit 5bc9ccf

Browse files
authored
accounts/abi/bind: link dependent libs in deploy (#19718)
* accounts, abigen: link dependent libs in deploy * abigen: add java generation * bind: Fix unit tests * abigen: add unit test * Fix CI * Post-rebase fixes * Fix rebase issue * accounts/abi: Gary's review feedback * accounts/abi: More Gary feedback * accounts/abi: minor fixes
1 parent f2eb3b1 commit 5bc9ccf

File tree

4 files changed

+224
-61
lines changed

4 files changed

+224
-61
lines changed

accounts/abi/bind/bind.go

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"unicode"
3232

3333
"github.com/ethereum/go-ethereum/accounts/abi"
34+
"github.com/ethereum/go-ethereum/log"
3435
)
3536

3637
// Lang is a target programming language selector to generate bindings for.
@@ -46,10 +47,13 @@ const (
4647
// to be used as is in client code, but rather as an intermediate struct which
4748
// enforces compile time type safety and naming convention opposed to having to
4849
// manually maintain hard coded strings that break on runtime.
49-
func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang) (string, error) {
50+
func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]string, pkg string, lang Lang, libs map[string]string) (string, error) {
5051
// Process each individual contract requested binding
5152
contracts := make(map[string]*tmplContract)
5253

54+
// Map used to flag each encountered library as such
55+
isLib := make(map[string]struct{})
56+
5357
for i := 0; i < len(types); i++ {
5458
// Parse the actual ABI to generate the binding for
5559
evmABI, err := abi.JSON(strings.NewReader(abis[i]))
@@ -137,21 +141,44 @@ func Bind(types []string, abis []string, bytecodes []string, fsigs []map[string]
137141
contracts[types[i]] = &tmplContract{
138142
Type: capitalise(types[i]),
139143
InputABI: strings.Replace(strippedABI, "\"", "\\\"", -1),
140-
InputBin: strings.TrimSpace(bytecodes[i]),
144+
InputBin: strings.TrimPrefix(strings.TrimSpace(bytecodes[i]), "0x"),
141145
Constructor: evmABI.Constructor,
142146
Calls: calls,
143147
Transacts: transacts,
144148
Events: events,
149+
Libraries: make(map[string]string),
145150
Structs: structs,
146151
}
152+
// Function 4-byte signatures are stored in the same sequence
153+
// as types, if available.
147154
if len(fsigs) > i {
148155
contracts[types[i]].FuncSigs = fsigs[i]
149156
}
157+
// Parse library references.
158+
for pattern, name := range libs {
159+
matched, err := regexp.Match("__\\$"+pattern+"\\$__", []byte(contracts[types[i]].InputBin))
160+
if err != nil {
161+
log.Error("Could not search for pattern", "pattern", pattern, "contract", contracts[types[i]], "err", err)
162+
}
163+
if matched {
164+
contracts[types[i]].Libraries[pattern] = name
165+
// keep track that this type is a library
166+
if _, ok := isLib[name]; !ok {
167+
isLib[name] = struct{}{}
168+
}
169+
}
170+
}
171+
}
172+
// Check if that type has already been identified as a library
173+
for i := 0; i < len(types); i++ {
174+
_, ok := isLib[types[i]]
175+
contracts[types[i]].Library = ok
150176
}
151177
// Generate the contract template data content and render it
152178
data := &tmplData{
153179
Package: pkg,
154180
Contracts: contracts,
181+
Libraries: libs,
155182
}
156183
buffer := new(bytes.Buffer)
157184

0 commit comments

Comments
 (0)