Skip to content

Instantly share code, notes, and snippets.

@dt665m
Created February 27, 2018 11:31
Show Gist options
  • Save dt665m/dc3ab4347aa5340905ac84810ce52201 to your computer and use it in GitHub Desktop.
Save dt665m/dc3ab4347aa5340905ac84810ce52201 to your computer and use it in GitHub Desktop.
[BUG](go-ethereum) abigen gocode events with single parameter unmarshal error
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package bindtest
import (
"strings"
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
)
// EventerSingleABI is the input ABI used to generate the binding from.
const EventerSingleABI = "[{\"constant\":false,\"inputs\":[{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"raiseSimpleEvent\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"Addr\",\"type\":\"address\"}],\"name\":\"SimpleEvent\",\"type\":\"event\"}]"
// EventerSingleBin is the compiled bytecode used for deploying new contracts.
const EventerSingleBin = `0x6060604052341561000f57600080fd5b61010c8061001e6000396000f300606060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063fec21c12146044575b600080fd5b3415604e57600080fd5b6078600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050607a565b005b7f3c9ae378d7e6b85e4a3d0a05ddf9a30e8153c6fdc4c1e2610b93a03c3261ea3b81604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a1505600a165627a7a723058204eb66c2dc149b98809aa998b8ca9e5ec366345c002975817a451b80d1b02b85a0029`
// DeployEventerSingle deploys a new Ethereum contract, binding an instance of EventerSingle to it.
func DeployEventerSingle(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *EventerSingle, error) {
parsed, err := abi.JSON(strings.NewReader(EventerSingleABI))
if err != nil {
return common.Address{}, nil, nil, err
}
address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(EventerSingleBin), backend)
if err != nil {
return common.Address{}, nil, nil, err
}
return address, tx, &EventerSingle{EventerSingleCaller: EventerSingleCaller{contract: contract}, EventerSingleTransactor: EventerSingleTransactor{contract: contract}, EventerSingleFilterer: EventerSingleFilterer{contract: contract}}, nil
}
// EventerSingle is an auto generated Go binding around an Ethereum contract.
type EventerSingle struct {
EventerSingleCaller // Read-only binding to the contract
EventerSingleTransactor // Write-only binding to the contract
EventerSingleFilterer // Log filterer for contract events
}
// EventerSingleCaller is an auto generated read-only Go binding around an Ethereum contract.
type EventerSingleCaller struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// EventerSingleTransactor is an auto generated write-only Go binding around an Ethereum contract.
type EventerSingleTransactor struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// EventerSingleFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
type EventerSingleFilterer struct {
contract *bind.BoundContract // Generic contract wrapper for the low level calls
}
// EventerSingleSession is an auto generated Go binding around an Ethereum contract,
// with pre-set call and transact options.
type EventerSingleSession struct {
Contract *EventerSingle // Generic contract binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// EventerSingleCallerSession is an auto generated read-only Go binding around an Ethereum contract,
// with pre-set call options.
type EventerSingleCallerSession struct {
Contract *EventerSingleCaller // Generic contract caller binding to set the session for
CallOpts bind.CallOpts // Call options to use throughout this session
}
// EventerSingleTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
// with pre-set transact options.
type EventerSingleTransactorSession struct {
Contract *EventerSingleTransactor // Generic contract transactor binding to set the session for
TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}
// EventerSingleRaw is an auto generated low-level Go binding around an Ethereum contract.
type EventerSingleRaw struct {
Contract *EventerSingle // Generic contract binding to access the raw methods on
}
// EventerSingleCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
type EventerSingleCallerRaw struct {
Contract *EventerSingleCaller // Generic read-only contract binding to access the raw methods on
}
// EventerSingleTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
type EventerSingleTransactorRaw struct {
Contract *EventerSingleTransactor // Generic write-only contract binding to access the raw methods on
}
// NewEventerSingle creates a new instance of EventerSingle, bound to a specific deployed contract.
func NewEventerSingle(address common.Address, backend bind.ContractBackend) (*EventerSingle, error) {
contract, err := bindEventerSingle(address, backend, backend, backend)
if err != nil {
return nil, err
}
return &EventerSingle{EventerSingleCaller: EventerSingleCaller{contract: contract}, EventerSingleTransactor: EventerSingleTransactor{contract: contract}, EventerSingleFilterer: EventerSingleFilterer{contract: contract}}, nil
}
// NewEventerSingleCaller creates a new read-only instance of EventerSingle, bound to a specific deployed contract.
func NewEventerSingleCaller(address common.Address, caller bind.ContractCaller) (*EventerSingleCaller, error) {
contract, err := bindEventerSingle(address, caller, nil, nil)
if err != nil {
return nil, err
}
return &EventerSingleCaller{contract: contract}, nil
}
// NewEventerSingleTransactor creates a new write-only instance of EventerSingle, bound to a specific deployed contract.
func NewEventerSingleTransactor(address common.Address, transactor bind.ContractTransactor) (*EventerSingleTransactor, error) {
contract, err := bindEventerSingle(address, nil, transactor, nil)
if err != nil {
return nil, err
}
return &EventerSingleTransactor{contract: contract}, nil
}
// NewEventerSingleFilterer creates a new log filterer instance of EventerSingle, bound to a specific deployed contract.
func NewEventerSingleFilterer(address common.Address, filterer bind.ContractFilterer) (*EventerSingleFilterer, error) {
contract, err := bindEventerSingle(address, nil, nil, filterer)
if err != nil {
return nil, err
}
return &EventerSingleFilterer{contract: contract}, nil
}
// bindEventerSingle binds a generic wrapper to an already deployed contract.
func bindEventerSingle(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
parsed, err := abi.JSON(strings.NewReader(EventerSingleABI))
if err != nil {
return nil, err
}
return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_EventerSingle *EventerSingleRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
return _EventerSingle.Contract.EventerSingleCaller.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_EventerSingle *EventerSingleRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _EventerSingle.Contract.EventerSingleTransactor.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_EventerSingle *EventerSingleRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _EventerSingle.Contract.EventerSingleTransactor.contract.Transact(opts, method, params...)
}
// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_EventerSingle *EventerSingleCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
return _EventerSingle.Contract.contract.Call(opts, result, method, params...)
}
// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_EventerSingle *EventerSingleTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _EventerSingle.Contract.contract.Transfer(opts)
}
// Transact invokes the (paid) contract method with params as input values.
func (_EventerSingle *EventerSingleTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
return _EventerSingle.Contract.contract.Transact(opts, method, params...)
}
// RaiseSimpleEvent is a paid mutator transaction binding the contract method 0xfec21c12.
//
// Solidity: function raiseSimpleEvent(addr address) returns()
func (_EventerSingle *EventerSingleTransactor) RaiseSimpleEvent(opts *bind.TransactOpts, addr common.Address) (*types.Transaction, error) {
return _EventerSingle.contract.Transact(opts, "raiseSimpleEvent", addr)
}
// RaiseSimpleEvent is a paid mutator transaction binding the contract method 0xfec21c12.
//
// Solidity: function raiseSimpleEvent(addr address) returns()
func (_EventerSingle *EventerSingleSession) RaiseSimpleEvent(addr common.Address) (*types.Transaction, error) {
return _EventerSingle.Contract.RaiseSimpleEvent(&_EventerSingle.TransactOpts, addr)
}
// RaiseSimpleEvent is a paid mutator transaction binding the contract method 0xfec21c12.
//
// Solidity: function raiseSimpleEvent(addr address) returns()
func (_EventerSingle *EventerSingleTransactorSession) RaiseSimpleEvent(addr common.Address) (*types.Transaction, error) {
return _EventerSingle.Contract.RaiseSimpleEvent(&_EventerSingle.TransactOpts, addr)
}
// EventerSingleSimpleEventIterator is returned from FilterSimpleEvent and is used to iterate over the raw logs and unpacked data for SimpleEvent events raised by the EventerSingle contract.
type EventerSingleSimpleEventIterator struct {
Event *EventerSingleSimpleEvent // Event containing the contract specifics and raw log
contract *bind.BoundContract // Generic contract to use for unpacking event data
event string // Event name to use for unpacking event data
logs chan types.Log // Log channel receiving the found contract events
sub ethereum.Subscription // Subscription for errors, completion and termination
done bool // Whether the subscription completed delivering logs
fail error // Occurred error to stop iteration
}
// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *EventerSingleSimpleEventIterator) Next() bool {
// If the iterator failed, stop iterating
if it.fail != nil {
return false
}
// If the iterator completed, deliver directly whatever's available
if it.done {
select {
case log := <-it.logs:
it.Event = new(EventerSingleSimpleEvent)
//if err := it.contract.UnpackLog(&it.Event.Addr, it.event, log); err != nil {
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
default:
return false
}
}
// Iterator still in progress, wait for either a data or an error event
select {
case log := <-it.logs:
it.Event = new(EventerSingleSimpleEvent)
// if err := it.contract.UnpackLog(&it.Event.Addr, it.event, log); err != nil {
if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil {
it.fail = err
return false
}
it.Event.Raw = log
return true
case err := <-it.sub.Err():
it.done = true
it.fail = err
return it.Next()
}
}
// Error returns any retrieval or parsing error occurred during filtering.
func (it *EventerSingleSimpleEventIterator) Error() error {
return it.fail
}
// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *EventerSingleSimpleEventIterator) Close() error {
it.sub.Unsubscribe()
return nil
}
// EventerSingleSimpleEvent represents a SimpleEvent event raised by the EventerSingle contract.
type EventerSingleSimpleEvent struct {
Addr common.Address
Raw types.Log // Blockchain specific contextual infos
}
// FilterSimpleEvent is a free log retrieval operation binding the contract event 0x3c9ae378d7e6b85e4a3d0a05ddf9a30e8153c6fdc4c1e2610b93a03c3261ea3b.
//
// Solidity: event SimpleEvent(Addr address)
func (_EventerSingle *EventerSingleFilterer) FilterSimpleEvent(opts *bind.FilterOpts) (*EventerSingleSimpleEventIterator, error) {
logs, sub, err := _EventerSingle.contract.FilterLogs(opts, "SimpleEvent")
if err != nil {
return nil, err
}
return &EventerSingleSimpleEventIterator{contract: _EventerSingle.contract, event: "SimpleEvent", logs: logs, sub: sub}, nil
}
// WatchSimpleEvent is a free log subscription operation binding the contract event 0x3c9ae378d7e6b85e4a3d0a05ddf9a30e8153c6fdc4c1e2610b93a03c3261ea3b.
//
// Solidity: event SimpleEvent(Addr address)
func (_EventerSingle *EventerSingleFilterer) WatchSimpleEvent(opts *bind.WatchOpts, sink chan<- *EventerSingleSimpleEvent) (event.Subscription, error) {
logs, sub, err := _EventerSingle.contract.WatchLogs(opts, "SimpleEvent")
if err != nil {
return nil, err
}
return event.NewSubscription(func(quit <-chan struct{}) error {
defer sub.Unsubscribe()
for {
select {
case log := <-logs:
// New log arrived, parse the event and forward to the user
event := new(EventerSingleSimpleEvent)
if err := _EventerSingle.contract.UnpackLog(event, "SimpleEvent", log); err != nil {
return err
}
event.Raw = log
select {
case sink <- event:
case err := <-sub.Err():
return err
case <-quit:
return nil
}
case err := <-sub.Err():
return err
case <-quit:
return nil
}
}
}), nil
}
pragma solidity ^0.4.18;
contract EventerSingle {
event SimpleEvent (address Addr);
function raiseSimpleEvent(address addr) {
SimpleEvent(addr);
}
}
package bindtest
import (
"fmt"
"math/big"
"testing"
"time"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/crypto"
)
func TestEventerSingle(t *testing.T) {
// Generate a new random account and a funded simulator
key, _ := crypto.GenerateKey()
auth := bind.NewKeyedTransactor(key)
sim := backends.NewSimulatedBackend(core.GenesisAlloc{auth.From: {Balance: big.NewInt(10000000000)}})
// Deploy an eventer contract
_, _, eventer, err := DeployEventerSingle(auth, sim)
if err != nil {
t.Fatalf("Failed to deploy eventer contract: %v", err)
}
sim.Commit()
// Inject a few events into Contract
for i := 1; i <= 3; i++ {
for j := 1; j <= i; j++ {
if _, err := eventer.RaiseSimpleEvent(auth, common.Address{byte(j)}); err != nil {
t.Fatalf("block %d, event %d: raise failed: %v", i, j, err)
}
}
sim.Commit()
}
// Test filtering for certain events and ensure they can be found
sit, err := eventer.FilterSimpleEvent(nil)
if err != nil {
t.Fatalf("failed to filter for simple events: %v", err)
}
defer sit.Close()
sit.Next()
if sit.Event.Addr.String() != (common.Address{byte(1)}).String() {
t.Errorf("simple log content mismatch: have %v, want %v", sit.Event.Addr.String(), (common.Address{byte(1)}).String())
}
sit.Next()
if sit.Event.Addr.String() != (common.Address{byte(1)}).String() {
t.Errorf("simple log content mismatch: have %v, want %v", sit.Event.Addr.String(), (common.Address{byte(1)}).String())
}
sit.Next()
if sit.Event.Addr.String() != (common.Address{byte(2)}).String() {
t.Errorf("simple log content mismatch: have %v, want %v", sit.Event.Addr.String(), (common.Address{byte(2)}).String())
}
sit.Next()
if sit.Event.Addr.String() != (common.Address{byte(1)}).String() {
t.Errorf("simple log content mismatch: have %v, want %v", sit.Event.Addr.String(), (common.Address{byte(1)}).String())
}
sit.Next()
if sit.Event.Addr.String() != (common.Address{byte(2)}).String() {
t.Errorf("simple log content mismatch: have %v, want %v", sit.Event.Addr.String(), (common.Address{byte(2)}).String())
}
sit.Next()
if sit.Event.Addr.String() != (common.Address{byte(3)}).String() {
t.Errorf("simple log content mismatch: have %v, want %v", sit.Event.Addr.String(), (common.Address{byte(3)}).String())
}
if sit.Next() {
t.Errorf("unexpected simple event found: %+v", sit.Event)
}
if err = sit.Error(); err != nil {
t.Fatalf("simple event iteration failed: %v", err)
}
// Test subscribing to an event and raising it afterwards
ch := make(chan *EventerSingleSimpleEvent, 16)
sub, err := eventer.WatchSimpleEvent(nil, ch)
if err != nil {
t.Fatalf("failed to subscribe to simple events: %v", err)
}
if _, err := eventer.RaiseSimpleEvent(auth, common.Address{255}); err != nil {
t.Fatalf("failed to raise subscribed simple event: %v", err)
}
sim.Commit()
select {
case event := <-ch:
if event.Addr.String() == (common.Address{255}).String() {
t.Errorf("simple log content mismatch: have %v, want 255", event)
}
case <-time.After(250 * time.Millisecond):
t.Fatalf("subscribed simple event didn't arrive")
}
// Unsubscribe from the event and make sure we're not delivered more
sub.Unsubscribe()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment