Skip to content

Fix bug in abigen v2 template #10

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
wants to merge 13 commits into
base: abigen2
Choose a base branch
from
60 changes: 38 additions & 22 deletions accounts/abi/bind/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,6 @@ func DeployContract(opts *TransactOpts, abi abi.ABI, bytecode []byte, backend Co
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (c *BoundContract) Call(opts *CallOpts, results *[]interface{}, method string, params ...interface{}) error {
// Don't crash on a lazy user
if opts == nil {
opts = new(CallOpts)
}
if results == nil {
results = new([]interface{})
}
Expand All @@ -161,51 +157,64 @@ func (c *BoundContract) Call(opts *CallOpts, results *[]interface{}, method stri
if err != nil {
return err
}
output, err := c.call(opts, input)
if err != nil {
return err
}

if len(*results) == 0 {
res, err := c.abi.Unpack(method, output)
*results = res
return err
}
res := *results
return c.abi.UnpackIntoInterface(res[0], method, output)
}

func (c *BoundContract) call(opts *CallOpts, input []byte) ([]byte, error) {
// Don't crash on a lazy user
if opts == nil {
opts = new(CallOpts)
}
var (
msg = ethereum.CallMsg{From: opts.From, To: &c.address, Data: input}
ctx = ensureContext(opts.Context)
code []byte
output []byte
err error
)
if opts.Pending {
pb, ok := c.caller.(PendingContractCaller)
if !ok {
return ErrNoPendingState
return nil, ErrNoPendingState
}
output, err = pb.PendingCallContract(ctx, msg)
if err != nil {
return err
return nil, err
}
if len(output) == 0 {
// Make sure we have a contract to operate on, and bail out otherwise.
if code, err = pb.PendingCodeAt(ctx, c.address); err != nil {
return err
return nil, err
} else if len(code) == 0 {
return ErrNoCode
return nil, ErrNoCode
}
}
} else {
output, err = c.caller.CallContract(ctx, msg, opts.BlockNumber)
if err != nil {
return err
return nil, err
}
if len(output) == 0 {
// Make sure we have a contract to operate on, and bail out otherwise.
if code, err = c.caller.CodeAt(ctx, c.address, opts.BlockNumber); err != nil {
return err
return nil, err
} else if len(code) == 0 {
return ErrNoCode
return nil, ErrNoCode
}
}
}

if len(*results) == 0 {
res, err := c.abi.Unpack(method, output)
*results = res
return err
}
res := *results
return c.abi.UnpackIntoInterface(res[0], method, output)
return output, nil
}

// Transact invokes the (paid) contract method with params as input values.
Expand Down Expand Up @@ -409,13 +418,16 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
// FilterLogs filters contract logs for past blocks, returning the necessary
// channels to construct a strongly typed bound iterator on top of them.
func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]interface{}) (chan types.Log, event.Subscription, error) {
return c.filterLogs(opts, c.abi.Events[name].ID, query...)
}

func (c *BoundContract) filterLogs(opts *FilterOpts, eventID common.Hash, query ...[]interface{}) (chan types.Log, event.Subscription, error) {
// Don't crash on a lazy user
if opts == nil {
opts = new(FilterOpts)
}
// Append the event selector to the query parameters and construct the topic set
query = append([][]interface{}{{c.abi.Events[name].ID}}, query...)

query = append([][]interface{}{{eventID}}, query...)
topics, err := abi.MakeTopics(query...)
if err != nil {
return nil, nil, err
Expand Down Expand Up @@ -458,12 +470,16 @@ func (c *BoundContract) FilterLogs(opts *FilterOpts, name string, query ...[]int
// WatchLogs filters subscribes to contract logs for future blocks, returning a
// subscription object that can be used to tear down the watcher.
func (c *BoundContract) WatchLogs(opts *WatchOpts, name string, query ...[]interface{}) (chan types.Log, event.Subscription, error) {
return c.watchLogs(opts, c.abi.Events[name].ID, query...)
}

func (c *BoundContract) watchLogs(opts *WatchOpts, eventID common.Hash, query ...[]interface{}) (chan types.Log, event.Subscription, error) {
// Don't crash on a lazy user
if opts == nil {
opts = new(WatchOpts)
}
// Append the event selector to the query parameters and construct the topic set
query = append([][]interface{}{{c.abi.Events[name].ID}}, query...)
query = append([][]interface{}{{eventID}}, query...)

topics, err := abi.MakeTopics(query...)
if err != nil {
Expand Down
Loading