aboutsummaryrefslogtreecommitdiff
path: root/accounts
diff options
context:
space:
mode:
authorDeterminant <[email protected]>2020-09-15 23:55:34 -0400
committerDeterminant <[email protected]>2020-09-15 23:55:34 -0400
commit78745551c077bf54151202138c2629f288769561 (patch)
tree2b628e99fd110617089778fa91235ecd2888f4ef /accounts
parent7d1388c743b4ec8f4a86bea95bfada785dee83f7 (diff)
WIP: geth-tavum
Diffstat (limited to 'accounts')
-rw-r--r--accounts/abi/abi.go192
-rw-r--r--accounts/abi/argument.go365
-rw-r--r--accounts/abi/bind/auth.go96
-rw-r--r--accounts/abi/bind/backend.go112
-rw-r--r--accounts/abi/bind/backends/simulated.go523
-rw-r--r--accounts/abi/bind/base.go366
-rw-r--r--accounts/abi/bind/bind.go558
-rw-r--r--accounts/abi/bind/template.go616
-rw-r--r--accounts/abi/bind/topics.go241
-rw-r--r--accounts/abi/bind/util.go76
-rw-r--r--accounts/abi/doc.go26
-rw-r--r--accounts/abi/error.go84
-rw-r--r--accounts/abi/event.go77
-rw-r--r--accounts/abi/method.go90
-rw-r--r--accounts/abi/numbers.go44
-rw-r--r--accounts/abi/pack.go81
-rw-r--r--accounts/abi/reflect.go226
-rw-r--r--accounts/abi/type.go348
-rw-r--r--accounts/abi/unpack.go295
-rw-r--r--accounts/accounts.go5
-rw-r--r--accounts/external/backend.go30
-rw-r--r--accounts/keystore/keystore.go23
-rw-r--r--accounts/keystore/passphrase.go11
-rw-r--r--accounts/manager.go7
-rw-r--r--accounts/scwallet/hub.go2
-rw-r--r--accounts/scwallet/securechannel.go24
-rw-r--r--accounts/scwallet/wallet.go23
27 files changed, 85 insertions, 4456 deletions
diff --git a/accounts/abi/abi.go b/accounts/abi/abi.go
deleted file mode 100644
index 7af6685..0000000
--- a/accounts/abi/abi.go
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package abi
-
-import (
- "bytes"
- "encoding/json"
- "fmt"
- "io"
-
- "github.com/ava-labs/go-ethereum/common"
-)
-
-// The ABI holds information about a contract's context and available
-// invokable methods. It will allow you to type check function calls and
-// packs data accordingly.
-type ABI struct {
- Constructor Method
- Methods map[string]Method
- Events map[string]Event
-}
-
-// JSON returns a parsed ABI interface and error if it failed.
-func JSON(reader io.Reader) (ABI, error) {
- dec := json.NewDecoder(reader)
-
- var abi ABI
- if err := dec.Decode(&abi); err != nil {
- return ABI{}, err
- }
-
- return abi, nil
-}
-
-// Pack the given method name to conform the ABI. Method call's data
-// will consist of method_id, args0, arg1, ... argN. Method id consists
-// of 4 bytes and arguments are all 32 bytes.
-// Method ids are created from the first 4 bytes of the hash of the
-// methods string signature. (signature = baz(uint32,string32))
-func (abi ABI) Pack(name string, args ...interface{}) ([]byte, error) {
- // Fetch the ABI of the requested method
- if name == "" {
- // constructor
- arguments, err := abi.Constructor.Inputs.Pack(args...)
- if err != nil {
- return nil, err
- }
- return arguments, nil
- }
- method, exist := abi.Methods[name]
- if !exist {
- return nil, fmt.Errorf("method '%s' not found", name)
- }
- arguments, err := method.Inputs.Pack(args...)
- if err != nil {
- return nil, err
- }
- // Pack up the method ID too if not a constructor and return
- return append(method.ID(), arguments...), nil
-}
-
-// Unpack output in v according to the abi specification
-func (abi ABI) Unpack(v interface{}, name string, data []byte) (err error) {
- if len(data) == 0 {
- return fmt.Errorf("abi: unmarshalling empty output")
- }
- // since there can't be naming collisions with contracts and events,
- // we need to decide whether we're calling a method or an event
- if method, ok := abi.Methods[name]; ok {
- if len(data)%32 != 0 {
- return fmt.Errorf("abi: improperly formatted output: %s - Bytes: [%+v]", string(data), data)
- }
- return method.Outputs.Unpack(v, data)
- }
- if event, ok := abi.Events[name]; ok {
- return event.Inputs.Unpack(v, data)
- }
- return fmt.Errorf("abi: could not locate named method or event")
-}
-
-// UnpackIntoMap unpacks a log into the provided map[string]interface{}
-func (abi ABI) UnpackIntoMap(v map[string]interface{}, name string, data []byte) (err error) {
- if len(data) == 0 {
- return fmt.Errorf("abi: unmarshalling empty output")
- }
- // since there can't be naming collisions with contracts and events,
- // we need to decide whether we're calling a method or an event
- if method, ok := abi.Methods[name]; ok {
- if len(data)%32 != 0 {
- return fmt.Errorf("abi: improperly formatted output")
- }
- return method.Outputs.UnpackIntoMap(v, data)
- }
- if event, ok := abi.Events[name]; ok {
- return event.Inputs.UnpackIntoMap(v, data)
- }
- return fmt.Errorf("abi: could not locate named method or event")
-}
-
-// UnmarshalJSON implements json.Unmarshaler interface
-func (abi *ABI) UnmarshalJSON(data []byte) error {
- var fields []struct {
- Type string
- Name string
- Constant bool
- Anonymous bool
- Inputs []Argument
- Outputs []Argument
- }
- if err := json.Unmarshal(data, &fields); err != nil {
- return err
- }
- abi.Methods = make(map[string]Method)
- abi.Events = make(map[string]Event)
- for _, field := range fields {
- switch field.Type {
- case "constructor":
- abi.Constructor = Method{
- Inputs: field.Inputs,
- }
- // empty defaults to function according to the abi spec
- case "function", "":
- name := field.Name
- _, ok := abi.Methods[name]
- for idx := 0; ok; idx++ {
- name = fmt.Sprintf("%s%d", field.Name, idx)
- _, ok = abi.Methods[name]
- }
- abi.Methods[name] = Method{
- Name: name,
- RawName: field.Name,
- Const: field.Constant,
- Inputs: field.Inputs,
- Outputs: field.Outputs,
- }
- case "event":
- name := field.Name
- _, ok := abi.Events[name]
- for idx := 0; ok; idx++ {
- name = fmt.Sprintf("%s%d", field.Name, idx)
- _, ok = abi.Events[name]
- }
- abi.Events[name] = Event{
- Name: name,
- RawName: field.Name,
- Anonymous: field.Anonymous,
- Inputs: field.Inputs,
- }
- }
- }
-
- return nil
-}
-
-// MethodById looks up a method by the 4-byte id
-// returns nil if none found
-func (abi *ABI) MethodById(sigdata []byte) (*Method, error) {
- if len(sigdata) < 4 {
- return nil, fmt.Errorf("data too short (%d bytes) for abi method lookup", len(sigdata))
- }
- for _, method := range abi.Methods {
- if bytes.Equal(method.ID(), sigdata[:4]) {
- return &method, nil
- }
- }
- return nil, fmt.Errorf("no method with id: %#x", sigdata[:4])
-}
-
-// EventByID looks an event up by its topic hash in the
-// ABI and returns nil if none found.
-func (abi *ABI) EventByID(topic common.Hash) (*Event, error) {
- for _, event := range abi.Events {
- if bytes.Equal(event.ID().Bytes(), topic.Bytes()) {
- return &event, nil
- }
- }
- return nil, fmt.Errorf("no event with id: %#x", topic.Hex())
-}
diff --git a/accounts/abi/argument.go b/accounts/abi/argument.go
deleted file mode 100644
index 4dae586..0000000
--- a/accounts/abi/argument.go
+++ /dev/null
@@ -1,365 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package abi
-
-import (
- "encoding/json"
- "fmt"
- "reflect"
- "strings"
-)
-
-// Argument holds the name of the argument and the corresponding type.
-// Types are used when packing and testing arguments.
-type Argument struct {
- Name string
- Type Type
- Indexed bool // indexed is only used by events
-}
-
-type Arguments []Argument
-
-type ArgumentMarshaling struct {
- Name string
- Type string
- Components []ArgumentMarshaling
- Indexed bool
-}
-
-// UnmarshalJSON implements json.Unmarshaler interface
-func (argument *Argument) UnmarshalJSON(data []byte) error {
- var arg ArgumentMarshaling
- err := json.Unmarshal(data, &arg)
- if err != nil {
- return fmt.Errorf("argument json err: %v", err)
- }
-
- argument.Type, err = NewType(arg.Type, arg.Components)
- if err != nil {
- return err
- }
- argument.Name = arg.Name
- argument.Indexed = arg.Indexed
-
- return nil
-}
-
-// LengthNonIndexed returns the number of arguments when not counting 'indexed' ones. Only events
-// can ever have 'indexed' arguments, it should always be false on arguments for method input/output
-func (arguments Arguments) LengthNonIndexed() int {
- out := 0
- for _, arg := range arguments {
- if !arg.Indexed {
- out++
- }
- }
- return out
-}
-
-// NonIndexed returns the arguments with indexed arguments filtered out
-func (arguments Arguments) NonIndexed() Arguments {
- var ret []Argument
- for _, arg := range arguments {
- if !arg.Indexed {
- ret = append(ret, arg)
- }
- }
- return ret
-}
-
-// isTuple returns true for non-atomic constructs, like (uint,uint) or uint[]
-func (arguments Arguments) isTuple() bool {
- return len(arguments) > 1
-}
-
-// Unpack performs the operation hexdata -> Go format
-func (arguments Arguments) Unpack(v interface{}, data []byte) error {
- // make sure the passed value is arguments pointer
- if reflect.Ptr != reflect.ValueOf(v).Kind() {
- return fmt.Errorf("abi: Unpack(non-pointer %T)", v)
- }
- marshalledValues, err := arguments.UnpackValues(data)
- if err != nil {
- return err
- }
- if arguments.isTuple() {
- return arguments.unpackTuple(v, marshalledValues)
- }
- return arguments.unpackAtomic(v, marshalledValues[0])
-}
-
-// UnpackIntoMap performs the operation hexdata -> mapping of argument name to argument value
-func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) error {
- marshalledValues, err := arguments.UnpackValues(data)
- if err != nil {
- return err
- }
-
- return arguments.unpackIntoMap(v, marshalledValues)
-}
-
-// unpack sets the unmarshalled value to go format.
-// Note the dst here must be settable.
-func unpack(t *Type, dst interface{}, src interface{}) error {
- var (
- dstVal = reflect.ValueOf(dst).Elem()
- srcVal = reflect.ValueOf(src)
- )
- tuple, typ := false, t
- for {
- if typ.T == SliceTy || typ.T == ArrayTy {
- typ = typ.Elem
- continue
- }
- tuple = typ.T == TupleTy
- break
- }
- if !tuple {
- return set(dstVal, srcVal)
- }
-
- // Dereferences interface or pointer wrapper
- dstVal = indirectInterfaceOrPtr(dstVal)
-
- switch t.T {
- case TupleTy:
- if dstVal.Kind() != reflect.Struct {
- return fmt.Errorf("abi: invalid dst value for unpack, want struct, got %s", dstVal.Kind())
- }
- fieldmap, err := mapArgNamesToStructFields(t.TupleRawNames, dstVal)
- if err != nil {
- return err
- }
- for i, elem := range t.TupleElems {
- fname := fieldmap[t.TupleRawNames[i]]
- field := dstVal.FieldByName(fname)
- if !field.IsValid() {
- return fmt.Errorf("abi: field %s can't found in the given value", t.TupleRawNames[i])
- }
- if err := unpack(elem, field.Addr().Interface(), srcVal.Field(i).Interface()); err != nil {
- return err
- }
- }
- return nil
- case SliceTy:
- if dstVal.Kind() != reflect.Slice {
- return fmt.Errorf("abi: invalid dst value for unpack, want slice, got %s", dstVal.Kind())
- }
- slice := reflect.MakeSlice(dstVal.Type(), srcVal.Len(), srcVal.Len())
- for i := 0; i < slice.Len(); i++ {
- if err := unpack(t.Elem, slice.Index(i).Addr().Interface(), srcVal.Index(i).Interface()); err != nil {
- return err
- }
- }
- dstVal.Set(slice)
- case ArrayTy:
- if dstVal.Kind() != reflect.Array {
- return fmt.Errorf("abi: invalid dst value for unpack, want array, got %s", dstVal.Kind())
- }
- array := reflect.New(dstVal.Type()).Elem()
- for i := 0; i < array.Len(); i++ {
- if err := unpack(t.Elem, array.Index(i).Addr().Interface(), srcVal.Index(i).Interface()); err != nil {
- return err
- }
- }
- dstVal.Set(array)
- }
- return nil
-}
-
-// unpackIntoMap unpacks marshalledValues into the provided map[string]interface{}
-func (arguments Arguments) unpackIntoMap(v map[string]interface{}, marshalledValues []interface{}) error {
- // Make sure map is not nil
- if v == nil {
- return fmt.Errorf("abi: cannot unpack into a nil map")
- }
-
- for i, arg := range arguments.NonIndexed() {
- v[arg.Name] = marshalledValues[i]
- }
- return nil
-}
-
-// unpackAtomic unpacks ( hexdata -> go ) a single value
-func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues interface{}) error {
- if arguments.LengthNonIndexed() == 0 {
- return nil
- }
- argument := arguments.NonIndexed()[0]
- elem := reflect.ValueOf(v).Elem()
-
- if elem.Kind() == reflect.Struct && argument.Type.T != TupleTy {
- fieldmap, err := mapArgNamesToStructFields([]string{argument.Name}, elem)
- if err != nil {
- return err
- }
- field := elem.FieldByName(fieldmap[argument.Name])
- if !field.IsValid() {
- return fmt.Errorf("abi: field %s can't be found in the given value", argument.Name)
- }
- return unpack(&argument.Type, field.Addr().Interface(), marshalledValues)
- }
- return unpack(&argument.Type, elem.Addr().Interface(), marshalledValues)
-}
-
-// unpackTuple unpacks ( hexdata -> go ) a batch of values.
-func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interface{}) error {
- var (
- value = reflect.ValueOf(v).Elem()
- typ = value.Type()
- kind = value.Kind()
- )
- if err := requireUnpackKind(value, typ, kind, arguments); err != nil {
- return err
- }
-
- // If the interface is a struct, get of abi->struct_field mapping
- var abi2struct map[string]string
- if kind == reflect.Struct {
- var (
- argNames []string
- err error
- )
- for _, arg := range arguments.NonIndexed() {
- argNames = append(argNames, arg.Name)
- }
- abi2struct, err = mapArgNamesToStructFields(argNames, value)
- if err != nil {
- return err
- }
- }
- for i, arg := range arguments.NonIndexed() {
- switch kind {
- case reflect.Struct:
- field := value.FieldByName(abi2struct[arg.Name])
- if !field.IsValid() {
- return fmt.Errorf("abi: field %s can't be found in the given value", arg.Name)
- }
- if err := unpack(&arg.Type, field.Addr().Interface(), marshalledValues[i]); err != nil {
- return err
- }
- case reflect.Slice, reflect.Array:
- if value.Len() < i {
- return fmt.Errorf("abi: insufficient number of arguments for unpack, want %d, got %d", len(arguments), value.Len())
- }
- v := value.Index(i)
- if err := requireAssignable(v, reflect.ValueOf(marshalledValues[i])); err != nil {
- return err
- }
- if err := unpack(&arg.Type, v.Addr().Interface(), marshalledValues[i]); err != nil {
- return err
- }
- default:
- return fmt.Errorf("abi:[2] cannot unmarshal tuple in to %v", typ)
- }
- }
- return nil
-
-}
-
-// UnpackValues can be used to unpack ABI-encoded hexdata according to the ABI-specification,
-// without supplying a struct to unpack into. Instead, this method returns a list containing the
-// values. An atomic argument will be a list with one element.
-func (arguments Arguments) UnpackValues(data []byte) ([]interface{}, error) {
- retval := make([]interface{}, 0, arguments.LengthNonIndexed())
- virtualArgs := 0
- for index, arg := range arguments.NonIndexed() {
- marshalledValue, err := toGoType((index+virtualArgs)*32, arg.Type, data)
- if arg.Type.T == ArrayTy && !isDynamicType(arg.Type) {
- // If we have a static array, like [3]uint256, these are coded as
- // just like uint256,uint256,uint256.
- // This means that we need to add two 'virtual' arguments when
- // we count the index from now on.
- //
- // Array values nested multiple levels deep are also encoded inline:
- // [2][3]uint256: uint256,uint256,uint256,uint256,uint256,uint256
- //
- // Calculate the full array size to get the correct offset for the next argument.
- // Decrement it by 1, as the normal index increment is still applied.
- virtualArgs += getTypeSize(arg.Type)/32 - 1
- } else if arg.Type.T == TupleTy && !isDynamicType(arg.Type) {
- // If we have a static tuple, like (uint256, bool, uint256), these are
- // coded as just like uint256,bool,uint256
- virtualArgs += getTypeSize(arg.Type)/32 - 1
- }
- if err != nil {
- return nil, err
- }
- retval = append(retval, marshalledValue)
- }
- return retval, nil
-}
-
-// PackValues performs the operation Go format -> Hexdata
-// It is the semantic opposite of UnpackValues
-func (arguments Arguments) PackValues(args []interface{}) ([]byte, error) {
- return arguments.Pack(args...)
-}
-
-// Pack performs the operation Go format -> Hexdata
-func (arguments Arguments) Pack(args ...interface{}) ([]byte, error) {
- // Make sure arguments match up and pack them
- abiArgs := arguments
- if len(args) != len(abiArgs) {
- return nil, fmt.Errorf("argument count mismatch: %d for %d", len(args), len(abiArgs))
- }
- // variable input is the output appended at the end of packed
- // output. This is used for strings and bytes types input.
- var variableInput []byte
-
- // input offset is the bytes offset for packed output
- inputOffset := 0
- for _, abiArg := range abiArgs {
- inputOffset += getTypeSize(abiArg.Type)
- }
- var ret []byte
- for i, a := range args {
- input := abiArgs[i]
- // pack the input
- packed, err := input.Type.pack(reflect.ValueOf(a))
- if err != nil {
- return nil, err
- }
- // check for dynamic types
- if isDynamicType(input.Type) {
- // set the offset
- ret = append(ret, packNum(reflect.ValueOf(inputOffset))...)
- // calculate next offset
- inputOffset += len(packed)
- // append to variable input
- variableInput = append(variableInput, packed...)
- } else {
- // append the packed value to the input
- ret = append(ret, packed...)
- }
- }
- // append the variable input at the end of the packed input
- ret = append(ret, variableInput...)
-
- return ret, nil
-}
-
-// ToCamelCase converts an under-score string to a camel-case string
-func ToCamelCase(input string) string {
- parts := strings.Split(input, "_")
- for i, s := range parts {
- if len(s) > 0 {
- parts[i] = strings.ToUpper(s[:1]) + s[1:]
- }
- }
- return strings.Join(parts, "")
-}
diff --git a/accounts/abi/bind/auth.go b/accounts/abi/bind/auth.go
deleted file mode 100644
index c916cc4..0000000
--- a/accounts/abi/bind/auth.go
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package bind
-
-import (
- "crypto/ecdsa"
- "errors"
- "io"
- "io/ioutil"
-
- "github.com/ava-labs/coreth/accounts"
- "github.com/ava-labs/coreth/accounts/external"
- "github.com/ava-labs/coreth/accounts/keystore"
- "github.com/ava-labs/coreth/core/types"
- "github.com/ava-labs/go-ethereum/common"
- "github.com/ava-labs/go-ethereum/crypto"
-)
-
-// NewTransactor is a utility method to easily create a transaction signer from
-// an encrypted json key stream and the associated passphrase.
-func NewTransactor(keyin io.Reader, passphrase string) (*TransactOpts, error) {
- json, err := ioutil.ReadAll(keyin)
- if err != nil {
- return nil, err
- }
- key, err := keystore.DecryptKey(json, passphrase)
- if err != nil {
- return nil, err
- }
- return NewKeyedTransactor(key.PrivateKey), nil
-}
-
-// NewKeyStoreTransactor is a utility method to easily create a transaction signer from
-// an decrypted key from a keystore
-func NewKeyStoreTransactor(keystore *keystore.KeyStore, account accounts.Account) (*TransactOpts, error) {
- return &TransactOpts{
- From: account.Address,
- Signer: func(signer types.Signer, address common.Address, tx *types.Transaction) (*types.Transaction, error) {
- if address != account.Address {
- return nil, errors.New("not authorized to sign this account")
- }
- signature, err := keystore.SignHash(account, signer.Hash(tx).Bytes())
- if err != nil {
- return nil, err
- }
- return tx.WithSignature(signer, signature)
- },
- }, nil
-}
-
-// NewKeyedTransactor is a utility method to easily create a transaction signer
-// from a single private key.
-func NewKeyedTransactor(key *ecdsa.PrivateKey) *TransactOpts {
- keyAddr := crypto.PubkeyToAddress(key.PublicKey)
- return &TransactOpts{
- From: keyAddr,
- Signer: func(signer types.Signer, address common.Address, tx *types.Transaction) (*types.Transaction, error) {
- if address != keyAddr {
- return nil, errors.New("not authorized to sign this account")
- }
- signature, err := crypto.Sign(signer.Hash(tx).Bytes(), key)
- if err != nil {
- return nil, err
- }
- return tx.WithSignature(signer, signature)
- },
- }
-}
-
-// NewClefTransactor is a utility method to easily create a transaction signer
-// with a clef backend.
-func NewClefTransactor(clef *external.ExternalSigner, account accounts.Account) *TransactOpts {
- return &TransactOpts{
- From: account.Address,
- Signer: func(signer types.Signer, address common.Address, transaction *types.Transaction) (*types.Transaction, error) {
- if address != account.Address {
- return nil, errors.New("not authorized to sign this account")
- }
- return clef.SignTx(account, transaction, nil) // Clef enforces its own chain id
- },
- }
-}
diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go
deleted file mode 100644
index 556394f..0000000
--- a/accounts/abi/bind/backend.go
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package bind
-
-import (
- "context"
- "errors"
- "math/big"
-
- "github.com/ava-labs/coreth/core/types"
- "github.com/ava-labs/go-ethereum"
- "github.com/ava-labs/go-ethereum/common"
-)
-
-var (
- // ErrNoCode is returned by call and transact operations for which the requested
- // recipient contract to operate on does not exist in the state db or does not
- // have any code associated with it (i.e. suicided).
- ErrNoCode = errors.New("no contract code at given address")
-
- // This error is raised when attempting to perform a pending state action
- // on a backend that doesn't implement PendingContractCaller.
- ErrNoPendingState = errors.New("backend does not support pending state")
-
- // This error is returned by WaitDeployed if contract creation leaves an
- // empty contract behind.
- ErrNoCodeAfterDeploy = errors.New("no contract code after deployment")
-)
-
-// ContractCaller defines the methods needed to allow operating with contract on a read
-// only basis.
-type ContractCaller interface {
- // CodeAt returns the code of the given account. This is needed to differentiate
- // between contract internal errors and the local chain being out of sync.
- CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error)
- // ContractCall executes an Ethereum contract call with the specified data as the
- // input.
- CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
-}
-
-// PendingContractCaller defines methods to perform contract calls on the pending state.
-// Call will try to discover this interface when access to the pending state is requested.
-// If the backend does not support the pending state, Call returns ErrNoPendingState.
-type PendingContractCaller interface {
- // PendingCodeAt returns the code of the given account in the pending state.
- PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error)
- // PendingCallContract executes an Ethereum contract call against the pending state.
- PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error)
-}
-
-// ContractTransactor defines the methods needed to allow operating with contract
-// on a write only basis. Beside the transacting method, the remainder are helpers
-// used when the user does not provide some needed values, but rather leaves it up
-// to the transactor to decide.
-type ContractTransactor interface {
- // PendingCodeAt returns the code of the given account in the pending state.
- PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error)
- // PendingNonceAt retrieves the current pending nonce associated with an account.
- PendingNonceAt(ctx context.Context, account common.Address) (uint64, error)
- // SuggestGasPrice retrieves the currently suggested gas price to allow a timely
- // execution of a transaction.
- SuggestGasPrice(ctx context.Context) (*big.Int, error)
- // EstimateGas tries to estimate the gas needed to execute a specific
- // transaction based on the current pending state of the backend blockchain.
- // There is no guarantee that this is the true gas limit requirement as other
- // transactions may be added or removed by miners, but it should provide a basis
- // for setting a reasonable default.
- EstimateGas(ctx context.Context, call ethereum.CallMsg) (gas uint64, err error)
- // SendTransaction injects the transaction into the pending pool for execution.
- SendTransaction(ctx context.Context, tx *types.Transaction) error
-}
-
-// ContractFilterer defines the methods needed to access log events using one-off
-// queries or continuous event subscriptions.
-type ContractFilterer interface {
- // FilterLogs executes a log filter operation, blocking during execution and
- // returning all the results in one batch.
- //
- // TODO(karalabe): Deprecate when the subscription one can return past data too.
- FilterLogs(ctx context.Context, query ethereum.FilterQuery) ([]types.Log, error)
-
- // SubscribeFilterLogs creates a background log filtering operation, returning
- // a subscription immediately, which can be used to stream the found events.
- SubscribeFilterLogs(ctx context.Context, query ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error)
-}
-
-// DeployBackend wraps the operations needed by WaitMined and WaitDeployed.
-type DeployBackend interface {
- TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
- CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error)
-}
-
-// ContractBackend defines the methods needed to work with contracts on a read-write basis.
-type ContractBackend interface {
- ContractCaller
- ContractTransactor
- ContractFilterer
-}
diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go
deleted file mode 100644
index 88610a4..0000000
--- a/accounts/abi/bind/backends/simulated.go
+++ /dev/null
@@ -1,523 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package backends
-
-import (
- "context"
- "errors"
- "fmt"
- "math/big"
- "sync"
- "time"
-
- "github.com/ava-labs/coreth/accounts/abi/bind"
- "github.com/ava-labs/coreth/consensus/ethash"
- "github.com/ava-labs/coreth/core"
- "github.com/ava-labs/coreth/core/bloombits"
- "github.com/ava-labs/coreth/core/rawdb"
- "github.com/ava-labs/coreth/core/state"
- "github.com/ava-labs/coreth/core/types"
- "github.com/ava-labs/coreth/core/vm"
- "github.com/ava-labs/coreth/params"
- "github.com/ava-labs/coreth/rpc"
- "github.com/ava-labs/go-ethereum"
- "github.com/ava-labs/go-ethereum/common"
- "github.com/ava-labs/go-ethereum/common/math"
- "github.com/ava-labs/go-ethereum/eth/filters"
- "github.com/ava-labs/go-ethereum/ethdb"
- "github.com/ava-labs/go-ethereum/event"
-)
-
-// This nil assignment ensures compile time that SimulatedBackend implements bind.ContractBackend.
-var _ bind.ContractBackend = (*SimulatedBackend)(nil)
-
-var (
- errBlockNumberUnsupported = errors.New("simulatedBackend cannot access blocks other than the latest block")
- errGasEstimationFailed = errors.New("gas required exceeds allowance or always failing transaction")
-)
-
-// SimulatedBackend implements bind.ContractBackend, simulating a blockchain in
-// the background. Its main purpose is to allow easily testing contract bindings.
-type SimulatedBackend struct {
- database ethdb.Database // In memory database to store our testing data
- blockchain *core.BlockChain // Ethereum blockchain to handle the consensus
-
- mu sync.Mutex
- pendingBlock *types.Block // Currently pending block that will be imported on request
- pendingState *state.StateDB // Currently pending state that will be the active on on request
-
- events *filters.EventSystem // Event system for filtering log events live
-
- config *params.ChainConfig
-}
-
-// NewSimulatedBackendWithDatabase creates a new binding backend based on the given database
-// and uses a simulated blockchain for testing purposes.
-func NewSimulatedBackendWithDatabase(database ethdb.Database, alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend {
- genesis := core.Genesis{Config: params.AllEthashProtocolChanges, GasLimit: gasLimit, Alloc: alloc}
- genesis.MustCommit(database)
- blockchain, _ := core.NewBlockChain(database, nil, genesis.Config, ethash.NewFaker(), vm.Config{}, nil)
-
- backend := &SimulatedBackend{
- database: database,
- blockchain: blockchain,
- config: genesis.Config,
- events: filters.NewEventSystem(new(event.TypeMux), &filterBackend{database, blockchain}, false),
- }
- backend.rollback()
- return backend
-}
-
-// NewSimulatedBackend creates a new binding backend using a simulated blockchain
-// for testing purposes.
-func NewSimulatedBackend(alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend {
- return NewSimulatedBackendWithDatabase(rawdb.NewMemoryDatabase(), alloc, gasLimit)
-}
-
-// Close terminates the underlying blockchain's update loop.
-func (b *SimulatedBackend) Close() error {
- b.blockchain.Stop()
- return nil
-}
-
-// Commit imports all the pending transactions as a single block and starts a
-// fresh new state.
-func (b *SimulatedBackend) Commit() {
- b.mu.Lock()
- defer b.mu.Unlock()
-
- if _, err := b.blockchain.InsertChain([]*types.Block{b.pendingBlock}); err != nil {
- panic(err) // This cannot happen unless the simulator is wrong, fail in that case
- }
- b.rollback()
-}
-
-// Rollback aborts all pending transactions, reverting to the last committed state.
-func (b *SimulatedBackend) Rollback() {
- b.mu.Lock()
- defer b.mu.Unlock()
-
- b.rollback()
-}
-
-func (b *SimulatedBackend) rollback() {
- blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(int, *core.BlockGen) {})
- statedb, _ := b.blockchain.State()
-
- b.pendingBlock = blocks[0]
- b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database())
-}
-
-// CodeAt returns the code associated with a certain account in the blockchain.
-func (b *SimulatedBackend) CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error) {
- b.mu.Lock()
- defer b.mu.Unlock()
-
- if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 {
- return nil, errBlockNumberUnsupported
- }
- statedb, _ := b.blockchain.State()
- return statedb.GetCode(contract), nil
-}
-
-// BalanceAt returns the wei balance of a certain account in the blockchain.
-func (b *SimulatedBackend) BalanceAt(ctx context.Context, contract common.Address, blockNumber *big.Int) (*big.Int, error) {
- b.mu.Lock()
- defer b.mu.Unlock()
-
- if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 {
- return nil, errBlockNumberUnsupported
- }
- statedb, _ := b.blockchain.State()
- return statedb.GetBalance(contract), nil
-}
-
-// NonceAt returns the nonce of a certain account in the blockchain.
-func (b *SimulatedBackend) NonceAt(ctx context.Context, contract common.Address, blockNumber *big.Int) (uint64, error) {
- b.mu.Lock()
- defer b.mu.Unlock()
-
- if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 {
- return 0, errBlockNumberUnsupported
- }
- statedb, _ := b.blockchain.State()
- return statedb.GetNonce(contract), nil
-}
-
-// StorageAt returns the value of key in the storage of an account in the blockchain.
-func (b *SimulatedBackend) StorageAt(ctx context.Context, contract common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) {
- b.mu.Lock()
- defer b.mu.Unlock()
-
- if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 {
- return nil, errBlockNumberUnsupported
- }
- statedb, _ := b.blockchain.State()
- val := statedb.GetState(contract, key)
- return val[:], nil
-}
-
-// TransactionReceipt returns the receipt of a transaction.
-func (b *SimulatedBackend) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) {
- receipt, _, _, _ := rawdb.ReadReceipt(b.database, txHash, b.config)
- return receipt, nil
-}
-
-// TransactionByHash checks the pool of pending transactions in addition to the
-// blockchain. The isPending return value indicates whether the transaction has been
-// mined yet. Note that the transaction may not be part of the canonical chain even if
-// it's not pending.
-func (b *SimulatedBackend) TransactionByHash(ctx context.Context, txHash common.Hash) (*types.Transaction, bool, error) {
- b.mu.Lock()
- defer b.mu.Unlock()
-
- tx := b.pendingBlock.Transaction(txHash)
- if tx != nil {
- return tx, true, nil
- }
- tx, _, _, _ = rawdb.ReadTransaction(b.database, txHash)
- if tx != nil {
- return tx, false, nil
- }
- return nil, false, ethereum.NotFound
-}
-
-// PendingCodeAt returns the code associated with an account in the pending state.
-func (b *SimulatedBackend) PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) {
- b.mu.Lock()
- defer b.mu.Unlock()
-
- return b.pendingState.GetCode(contract), nil
-}
-
-// CallContract executes a contract call.
-func (b *SimulatedBackend) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) {
- b.mu.Lock()
- defer b.mu.Unlock()
-
- if blockNumber != nil && blockNumber.Cmp(b.blockchain.CurrentBlock().Number()) != 0 {
- return nil, errBlockNumberUnsupported
- }
- state, err := b.blockchain.State()
- if err != nil {
- return nil, err
- }
- rval, _, _, err := b.callContract(ctx, call, b.blockchain.CurrentBlock(), state)
- return rval, err
-}
-
-// PendingCallContract executes a contract call on the pending state.
-func (b *SimulatedBackend) PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) {
- b.mu.Lock()
- defer b.mu.Unlock()
- defer b.pendingState.RevertToSnapshot(b.pendingState.Snapshot())
-
- rval, _, _, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState)
- return rval, err
-}
-
-// PendingNonceAt implements PendingStateReader.PendingNonceAt, retrieving
-// the nonce currently pending for the account.
-func (b *SimulatedBackend) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) {
- b.mu.Lock()
- defer b.mu.Unlock()
-
- return b.pendingState.GetOrNewStateObject(account).Nonce(), nil
-}
-
-// SuggestGasPrice implements ContractTransactor.SuggestGasPrice. Since the simulated
-// chain doesn't have miners, we just return a gas price of 1 for any call.
-func (b *SimulatedBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error) {
- return big.NewInt(1), nil
-}
-
-// EstimateGas executes the requested code against the currently pending block/state and
-// returns the used amount of gas.
-func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error) {
- b.mu.Lock()
- defer b.mu.Unlock()
-
- // Determine the lowest and highest possible gas limits to binary search in between
- var (
- lo uint64 = params.TxGas - 1
- hi uint64
- cap uint64
- )
- if call.Gas >= params.TxGas {
- hi = call.Gas
- } else {
- hi = b.pendingBlock.GasLimit()
- }
- cap = hi
-
- // Create a helper to check if a gas allowance results in an executable transaction
- executable := func(gas uint64) bool {
- call.Gas = gas
-
- snapshot := b.pendingState.Snapshot()
- _, _, failed, err := b.callContract(ctx, call, b.pendingBlock, b.pendingState)
- b.pendingState.RevertToSnapshot(snapshot)
-
- if err != nil || failed {
- return false
- }
- return true
- }
- // Execute the binary search and hone in on an executable gas limit
- for lo+1 < hi {
- mid := (hi + lo) / 2
- if !executable(mid) {
- lo = mid
- } else {
- hi = mid
- }
- }
- // Reject the transaction as invalid if it still fails at the highest allowance
- if hi == cap {
- if !executable(hi) {
- return 0, errGasEstimationFailed
- }
- }
- return hi, nil
-}
-
-// callContract implements common code between normal and pending contract calls.
-// state is modified during execution, make sure to copy it if necessary.
-func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallMsg, block *types.Block, statedb *state.StateDB) ([]byte, uint64, bool, error) {
- // Ensure message is initialized properly.
- if call.GasPrice == nil {
- call.GasPrice = big.NewInt(1)
- }
- if call.Gas == 0 {
- call.Gas = 50000000
- }
- if call.Value == nil {
- call.Value = new(big.Int)
- }
- // Set infinite balance to the fake caller account.
- from := statedb.GetOrNewStateObject(call.From)
- from.SetBalance(math.MaxBig256)
- // Execute the call.
- msg := callmsg{call}
-
- evmContext := core.NewEVMContext(msg, block.Header(), b.blockchain, nil)
- // Create a new environment which holds all relevant information
- // about the transaction and calling mechanisms.
- vmenv := vm.NewEVM(evmContext, statedb, b.config, vm.Config{})
- gaspool := new(core.GasPool).AddGas(math.MaxUint64)
-
- return core.NewStateTransition(vmenv, msg, gaspool).TransitionDb()
-}
-
-// SendTransaction updates the pending block to include the given transaction.
-// It panics if the transaction is invalid.
-func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx *types.Transaction) error {
- b.mu.Lock()
- defer b.mu.Unlock()
-
- sender, err := types.Sender(types.NewEIP155Signer(b.config.ChainID), tx)
- if err != nil {
- panic(fmt.Errorf("invalid transaction: %v", err))
- }
- nonce := b.pendingState.GetNonce(sender)
- if tx.Nonce() != nonce {
- panic(fmt.Errorf("invalid transaction nonce: got %d, want %d", tx.Nonce(), nonce))
- }
-
- blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(number int, block *core.BlockGen) {
- for _, tx := range b.pendingBlock.Transactions() {
- block.AddTxWithChain(b.blockchain, tx)
- }
- block.AddTxWithChain(b.blockchain, tx)
- })
- statedb, _ := b.blockchain.State()
-
- b.pendingBlock = blocks[0]
- b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database())
- return nil
-}
-
-// FilterLogs executes a log filter operation, blocking during execution and
-// returning all the results in one batch.
-//
-// TODO(karalabe): Deprecate when the subscription one can return past data too.
-func (b *SimulatedBackend) FilterLogs(ctx context.Context, query ethereum.FilterQuery) ([]types.Log, error) {
- var filter *filters.Filter
- if query.BlockHash != nil {
- // Block filter requested, construct a single-shot filter
- filter = filters.NewBlockFilter(&filterBackend{b.database, b.blockchain}, *query.BlockHash, query.Addresses, query.Topics)
- } else {
- // Initialize unset filter boundaried to run from genesis to chain head
- from := int64(0)
- if query.FromBlock != nil {
- from = query.FromBlock.Int64()
- }
- to := int64(-1)
- if query.ToBlock != nil {
- to = query.ToBlock.Int64()
- }
- // Construct the range filter
- filter = filters.NewRangeFilter(&filterBackend{b.database, b.blockchain}, from, to, query.Addresses, query.Topics)
- }
- // Run the filter and return all the logs
- logs, err := filter.Logs(ctx)
- if err != nil {
- return nil, err
- }
- res := make([]types.Log, len(logs))
- for i, log := range logs {
- res[i] = *log
- }
- return res, nil
-}
-
-// SubscribeFilterLogs creates a background log filtering operation, returning a
-// subscription immediately, which can be used to stream the found events.
-func (b *SimulatedBackend) SubscribeFilterLogs(ctx context.Context, query ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error) {
- // Subscribe to contract events
- sink := make(chan []*types.Log)
-
- sub, err := b.events.SubscribeLogs(query, sink)
- if err != nil {
- return nil, err
- }
- // Since we're getting logs in batches, we need to flatten them into a plain stream
- return event.NewSubscription(func(quit <-chan struct{}) error {
- defer sub.Unsubscribe()
- for {
- select {
- case logs := <-sink:
- for _, log := range logs {
- select {
- case ch <- *log:
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- }
- case err := <-sub.Err():
- return err
- case <-quit:
- return nil
- }
- }
- }), nil
-}
-
-// AdjustTime adds a time shift to the simulated clock.
-func (b *SimulatedBackend) AdjustTime(adjustment time.Duration) error {
- b.mu.Lock()
- defer b.mu.Unlock()
- blocks, _ := core.GenerateChain(b.config, b.blockchain.CurrentBlock(), ethash.NewFaker(), b.database, 1, func(number int, block *core.BlockGen) {
- for _, tx := range b.pendingBlock.Transactions() {
- block.AddTx(tx)
- }
- block.OffsetTime(int64(adjustment.Seconds()))
- })
- statedb, _ := b.blockchain.State()
-
- b.pendingBlock = blocks[0]
- b.pendingState, _ = state.New(b.pendingBlock.Root(), statedb.Database())
-
- return nil
-}
-
-// Blockchain returns the underlying blockchain.
-func (b *SimulatedBackend) Blockchain() *core.BlockChain {
- return b.blockchain
-}
-
-// callmsg implements core.Message to allow passing it as a transaction simulator.
-type callmsg struct {
- ethereum.CallMsg
-}
-
-func (m callmsg) From() common.Address { return m.CallMsg.From }
-func (m callmsg) Nonce() uint64 { return 0 }
-func (m callmsg) CheckNonce() bool { return false }
-func (m callmsg) To() *common.Address { return m.CallMsg.To }
-func (m callmsg) GasPrice() *big.Int { return m.CallMsg.GasPrice }
-func (m callmsg) Gas() uint64 { return m.CallMsg.Gas }
-func (m callmsg) Value() *big.Int { return m.CallMsg.Value }
-func (m callmsg) Data() []byte { return m.CallMsg.Data }
-
-// filterBackend implements filters.Backend to support filtering for logs without
-// taking bloom-bits acceleration structures into account.
-type filterBackend struct {
- db ethdb.Database
- bc *core.BlockChain
-}
-
-func (fb *filterBackend) ChainDb() ethdb.Database { return fb.db }
-func (fb *filterBackend) EventMux() *event.TypeMux { panic("not supported") }
-
-func (fb *filterBackend) HeaderByNumber(ctx context.Context, block rpc.BlockNumber) (*types.Header, error) {
- if block == rpc.LatestBlockNumber {
- return fb.bc.CurrentHeader(), nil
- }
- return fb.bc.GetHeaderByNumber(uint64(block.Int64())), nil
-}
-
-func (fb *filterBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
- return fb.bc.GetHeaderByHash(hash), nil
-}
-
-func (fb *filterBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) {
- number := rawdb.ReadHeaderNumber(fb.db, hash)
- if number == nil {
- return nil, nil
- }
- return rawdb.ReadReceipts(fb.db, hash, *number, fb.bc.Config()), nil
-}
-
-func (fb *filterBackend) GetLogs(ctx context.Context, hash common.Hash) ([][]*types.Log, error) {
- number := rawdb.ReadHeaderNumber(fb.db, hash)
- if number == nil {
- return nil, nil
- }
- receipts := rawdb.ReadReceipts(fb.db, hash, *number, fb.bc.Config())
- if receipts == nil {
- return nil, nil
- }
- logs := make([][]*types.Log, len(receipts))
- for i, receipt := range receipts {
- logs[i] = receipt.Logs
- }
- return logs, nil
-}
-
-func (fb *filterBackend) SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription {
- return event.NewSubscription(func(quit <-chan struct{}) error {
- <-quit
- return nil
- })
-}
-func (fb *filterBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription {
- return fb.bc.SubscribeChainEvent(ch)
-}
-func (fb *filterBackend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription {
- return fb.bc.SubscribeRemovedLogsEvent(ch)
-}
-func (fb *filterBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription {
- return fb.bc.SubscribeLogsEvent(ch)
-}
-
-func (fb *filterBackend) BloomStatus() (uint64, uint64) { return 4096, 0 }
-func (fb *filterBackend) ServiceFilter(ctx context.Context, ms *bloombits.MatcherSession) {
- panic("not supported")
-}
diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go
deleted file mode 100644
index 3d64f85..0000000
--- a/accounts/abi/bind/base.go
+++ /dev/null
@@ -1,366 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package bind
-
-import (
- "context"
- "errors"
- "fmt"
- "math/big"
-
- "github.com/ava-labs/coreth/accounts/abi"
- "github.com/ava-labs/coreth/core/types"
- "github.com/ava-labs/go-ethereum"
- "github.com/ava-labs/go-ethereum/common"
- "github.com/ava-labs/go-ethereum/crypto"
- "github.com/ava-labs/go-ethereum/event"
-)
-
-// SignerFn is a signer function callback when a contract requires a method to
-// sign the transaction before submission.
-type SignerFn func(types.Signer, common.Address, *types.Transaction) (*types.Transaction, error)
-
-// CallOpts is the collection of options to fine tune a contract call request.
-type CallOpts struct {
- Pending bool // Whether to operate on the pending state or the last known one
- From common.Address // Optional the sender address, otherwise the first account is used
- BlockNumber *big.Int // Optional the block number on which the call should be performed
- Context context.Context // Network context to support cancellation and timeouts (nil = no timeout)
-}
-
-// TransactOpts is the collection of authorization data required to create a
-// valid Ethereum transaction.
-type TransactOpts struct {
- From common.Address // Ethereum account to send the transaction from
- Nonce *big.Int // Nonce to use for the transaction execution (nil = use pending state)
- Signer SignerFn // Method to use for signing the transaction (mandatory)
-
- Value *big.Int // Funds to transfer along along the transaction (nil = 0 = no funds)
- GasPrice *big.Int // Gas price to use for the transaction execution (nil = gas price oracle)
- GasLimit uint64 // Gas limit to set for the transaction execution (0 = estimate)
-
- Context context.Context // Network context to support cancellation and timeouts (nil = no timeout)
-}
-
-// FilterOpts is the collection of options to fine tune filtering for events
-// within a bound contract.
-type FilterOpts struct {
- Start uint64 // Start of the queried range
- End *uint64 // End of the range (nil = latest)
-
- Context context.Context // Network context to support cancellation and timeouts (nil = no timeout)
-}
-
-// WatchOpts is the collection of options to fine tune subscribing for events
-// within a bound contract.
-type WatchOpts struct {
- Start *uint64 // Start of the queried range (nil = latest)
- Context context.Context // Network context to support cancellation and timeouts (nil = no timeout)
-}
-
-// BoundContract is the base wrapper object that reflects a contract on the
-// Ethereum network. It contains a collection of methods that are used by the
-// higher level contract bindings to operate.
-type BoundContract struct {
- address common.Address // Deployment address of the contract on the Ethereum blockchain
- abi abi.ABI // Reflect based ABI to access the correct Ethereum methods
- caller ContractCaller // Read interface to interact with the blockchain
- transactor ContractTransactor // Write interface to interact with the blockchain
- filterer ContractFilterer // Event filtering to interact with the blockchain
-}
-
-// NewBoundContract creates a low level contract interface through which calls
-// and transactions may be made through.
-func NewBoundContract(address common.Address, abi abi.ABI, caller ContractCaller, transactor ContractTransactor, filterer ContractFilterer) *BoundContract {
- return &BoundContract{
- address: address,
- abi: abi,
- caller: caller,
- transactor: transactor,
- filterer: filterer,
- }
-}
-
-// DeployContract deploys a contract onto the Ethereum blockchain and binds the
-// deployment address with a Go wrapper.
-func DeployContract(opts *TransactOpts, abi abi.ABI, bytecode []byte, backend ContractBackend, params ...interface{}) (common.Address, *types.Transaction, *BoundContract, error) {
- // Otherwise try to deploy the contract
- c := NewBoundContract(common.Address{}, abi, backend, backend, backend)
-
- input, err := c.abi.Pack("", params...)
- if err != nil {
- return common.Address{}, nil, nil, err
- }
- tx, err := c.transact(opts, nil, append(bytecode, input...))
- if err != nil {
- return common.Address{}, nil, nil, err
- }
- c.address = crypto.CreateAddress(opts.From, tx.Nonce())
- return c.address, tx, c, 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 (c *BoundContract) Call(opts *CallOpts, result interface{}, method string, params ...interface{}) error {
- // Don't crash on a lazy user
- if opts == nil {
- opts = new(CallOpts)
- }
- // Pack the input, call and unpack the results
- input, err := c.abi.Pack(method, params...)
- if err != nil {
- return err
- }
- var (
- msg = ethereum.CallMsg{From: opts.From, To: &c.address, Data: input}
- ctx = ensureContext(opts.Context)
- code []byte
- output []byte
- )
- if opts.Pending {
- pb, ok := c.caller.(PendingContractCaller)
- if !ok {
- return ErrNoPendingState
- }
- output, err = pb.PendingCallContract(ctx, msg)
- if err == nil && 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
- } else if len(code) == 0 {
- return ErrNoCode
- }
- }
- } else {
- output, err = c.caller.CallContract(ctx, msg, opts.BlockNumber)
- if err == nil && 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
- } else if len(code) == 0 {
- return ErrNoCode
- }
- }
- }
- if err != nil {
- return err
- }
- return c.abi.Unpack(result, method, output)
-}
-
-// Transact invokes the (paid) contract method with params as input values.
-func (c *BoundContract) Transact(opts *TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- // Otherwise pack up the parameters and invoke the contract
- input, err := c.abi.Pack(method, params...)
- if err != nil {
- return nil, err
- }
- return c.transact(opts, &c.address, input)
-}
-
-// Transfer initiates a plain transaction to move funds to the contract, calling
-// its default method if one is available.
-func (c *BoundContract) Transfer(opts *TransactOpts) (*types.Transaction, error) {
- return c.transact(opts, &c.address, nil)
-}
-
-// transact executes an actual transaction invocation, first deriving any missing
-// authorization fields, and then scheduling the transaction for execution.
-func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, input []byte) (*types.Transaction, error) {
- var err error
-
- // Ensure a valid value field and resolve the account nonce
- value := opts.Value
- if value == nil {
- value = new(big.Int)
- }
- var nonce uint64
- if opts.Nonce == nil {
- nonce, err = c.transactor.PendingNonceAt(ensureContext(opts.Context), opts.From)
- if err != nil {
- return nil, fmt.Errorf("failed to retrieve account nonce: %v", err)
- }
- } else {
- nonce = opts.Nonce.Uint64()
- }
- // Figure out the gas allowance and gas price values
- gasPrice := opts.GasPrice
- if gasPrice == nil {
- gasPrice, err = c.transactor.SuggestGasPrice(ensureContext(opts.Context))
- if err != nil {
- return nil, fmt.Errorf("failed to suggest gas price: %v", err)
- }
- }
- gasLimit := opts.GasLimit
- if gasLimit == 0 {
- // Gas estimation cannot succeed without code for method invocations
- if contract != nil {
- if code, err := c.transactor.PendingCodeAt(ensureContext(opts.Context), c.address); err != nil {
- return nil, err
- } else if len(code) == 0 {
- return nil, ErrNoCode
- }
- }
- // If the contract surely has code (or code is not needed), estimate the transaction
- msg := ethereum.CallMsg{From: opts.From, To: contract, Value: value, Data: input}
- gasLimit, err = c.transactor.EstimateGas(ensureContext(opts.Context), msg)
- if err != nil {
- return nil, fmt.Errorf("failed to estimate gas needed: %v", err)
- }
- }
- // Create the transaction, sign it and schedule it for execution
- var rawTx *types.Transaction
- if contract == nil {
- rawTx = types.NewContractCreation(nonce, value, gasLimit, gasPrice, input)
- } else {
- rawTx = types.NewTransaction(nonce, c.address, value, gasLimit, gasPrice, input)
- }
- if opts.Signer == nil {
- return nil, errors.New("no signer to authorize the transaction with")
- }
- signedTx, err := opts.Signer(types.HomesteadSigner{}, opts.From, rawTx)
- if err != nil {
- return nil, err
- }
- if err := c.transactor.SendTransaction(ensureContext(opts.Context), signedTx); err != nil {
- return nil, err
- }
- return signedTx, nil
-}
-
-// 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) {
- // 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...)
-
- topics, err := makeTopics(query...)
- if err != nil {
- return nil, nil, err
- }
- // Start the background filtering
- logs := make(chan types.Log, 128)
-
- config := ethereum.FilterQuery{
- Addresses: []common.Address{c.address},
- Topics: topics,
- FromBlock: new(big.Int).SetUint64(opts.Start),
- }
- if opts.End != nil {
- config.ToBlock = new(big.Int).SetUint64(*opts.End)
- }
- /* TODO(karalabe): Replace the rest of the method below with this when supported
- sub, err := c.filterer.SubscribeFilterLogs(ensureContext(opts.Context), config, logs)
- */
- buff, err := c.filterer.FilterLogs(ensureContext(opts.Context), config)
- if err != nil {
- return nil, nil, err
- }
- sub, err := event.NewSubscription(func(quit <-chan struct{}) error {
- for _, log := range buff {
- select {
- case logs <- log:
- case <-quit:
- return nil
- }
- }
- return nil
- }), nil
-
- if err != nil {
- return nil, nil, err
- }
- return logs, sub, nil
-}
-
-// 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) {
- // 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...)
-
- topics, err := makeTopics(query...)
- if err != nil {
- return nil, nil, err
- }
- // Start the background filtering
- logs := make(chan types.Log, 128)
-
- config := ethereum.FilterQuery{
- Addresses: []common.Address{c.address},
- Topics: topics,
- }
- if opts.Start != nil {
- config.FromBlock = new(big.Int).SetUint64(*opts.Start)
- }
- sub, err := c.filterer.SubscribeFilterLogs(ensureContext(opts.Context), config, logs)
- if err != nil {
- return nil, nil, err
- }
- return logs, sub, nil
-}
-
-// UnpackLog unpacks a retrieved log into the provided output structure.
-func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log) error {
- if len(log.Data) > 0 {
- if err := c.abi.Unpack(out, event, log.Data); err != nil {
- return err
- }
- }
- var indexed abi.Arguments
- for _, arg := range c.abi.Events[event].Inputs {
- if arg.Indexed {
- indexed = append(indexed, arg)
- }
- }
- return parseTopics(out, indexed, log.Topics[1:])
-}
-
-// UnpackLogIntoMap unpacks a retrieved log into the provided map.
-func (c *BoundContract) UnpackLogIntoMap(out map[string]interface{}, event string, log types.Log) error {
- if len(log.Data) > 0 {
- if err := c.abi.UnpackIntoMap(out, event, log.Data); err != nil {
- return err
- }
- }
- var indexed abi.Arguments
- for _, arg := range c.abi.Events[event].Inputs {
- if arg.Indexed {
- indexed = append(indexed, arg)
- }
- }
- return parseTopicsIntoMap(out, indexed, log.Topics[1:])
-}
-
-// ensureContext is a helper method to ensure a context is not nil, even if the
-// user specified it as such.
-func ensureContext(ctx context.Context) context.Context {
- if ctx == nil {
- return context.TODO()
- }
- return ctx
-}
diff --git a/accounts/abi/bind/bind.go b/accounts/abi/bind/bind.go
deleted file mode 100644
index e869eef..0000000
--- a/accounts/abi/bind/bind.go
+++ /dev/null
@@ -1,558 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-// Package bind generates Ethereum contract Go bindings.
-//
-// Detailed usage document and tutorial available on the go-ethereum Wiki page:
-// https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts
-package bind
-
-import (
- "bytes"
- "errors"
- "fmt"
- "go/format"
- "regexp"
- "strings"
- "text/template"
- "unicode"
-
- "github.com/ava-labs/coreth/accounts/abi"
- "github.com/ava-labs/go-ethereum/log"
-)
-
-// Lang is a target programming language selector to generate bindings for.
-type Lang int
-
-const (
- LangGo Lang = iota
- LangJava
- LangObjC
-)
-
-// Bind generates a Go wrapper around a contract ABI. This wrapper isn't meant
-// to be used as is in client code, but rather as an intermediate struct which
-// enforces compile time type safety and naming convention opposed to having to
-// 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) (string, error) {
- // Process each individual contract requested binding
- contracts := make(map[string]*tmplContract)
-
- // Map used to flag each encountered library as such
- isLib := make(map[string]struct{})
-
- for i := 0; i < len(types); i++ {
- // Parse the actual ABI to generate the binding for
- evmABI, err := abi.JSON(strings.NewReader(abis[i]))
- if err != nil {
- return "", err
- }
- // Strip any whitespace from the JSON ABI
- strippedABI := strings.Map(func(r rune) rune {
- if unicode.IsSpace(r) {
- return -1
- }
- return r
- }, abis[i])
-
- // Extract the call and transact methods; events, struct definitions; and sort them alphabetically
- var (
- calls = make(map[string]*tmplMethod)
- transacts = make(map[string]*tmplMethod)
- events = make(map[string]*tmplEvent)
- structs = make(map[string]*tmplStruct)
- )
- for _, original := range evmABI.Methods {
- // Normalize the method for capital cases and non-anonymous inputs/outputs
- normalized := original
- normalized.Name = methodNormalizer[lang](original.Name)
-
- normalized.Inputs = make([]abi.Argument, len(original.Inputs))
- copy(normalized.Inputs, original.Inputs)
- for j, input := range normalized.Inputs {
- if input.Name == "" {
- normalized.Inputs[j].Name = fmt.Sprintf("arg%d", j)
- }
- if _, exist := structs[input.Type.String()]; input.Type.T == abi.TupleTy && !exist {
- bindStructType[lang](input.Type, structs)
- }
- }
- normalized.Outputs = make([]abi.Argument, len(original.Outputs))
- copy(normalized.Outputs, original.Outputs)
- for j, output := range normalized.Outputs {
- if output.Name != "" {
- normalized.Outputs[j].Name = capitalise(output.Name)
- }
- if _, exist := structs[output.Type.String()]; output.Type.T == abi.TupleTy && !exist {
- bindStructType[lang](output.Type, structs)
- }
- }
- // Append the methods to the call or transact lists
- if original.Const {
- calls[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original.Outputs)}
- } else {
- transacts[original.Name] = &tmplMethod{Original: original, Normalized: normalized, Structured: structured(original.Outputs)}
- }
- }
- for _, original := range evmABI.Events {
- // Skip anonymous events as they don't support explicit filtering
- if original.Anonymous {
- continue
- }
- // Normalize the event for capital cases and non-anonymous outputs
- normalized := original
- normalized.Name = methodNormalizer[lang](original.Name)
-
- normalized.Inputs = make([]abi.Argument, len(original.Inputs))
- copy(normalized.Inputs, original.Inputs)
- for j, input := range normalized.Inputs {
- // Indexed fields are input, non-indexed ones are outputs
- if input.Indexed {
- if input.Name == "" {
- normalized.Inputs[j].Name = fmt.Sprintf("arg%d", j)
- }
- if _, exist := structs[input.Type.String()]; input.Type.T == abi.TupleTy && !exist {
- bindStructType[lang](input.Type, structs)
- }
- }
- }
- // Append the event to the accumulator list
- events[original.Name] = &tmplEvent{Original: original, Normalized: normalized}
- }
-
- // There is no easy way to pass arbitrary java objects to the Go side.
- if len(structs) > 0 && lang == LangJava {
- return "", errors.New("java binding for tuple arguments is not supported yet")
- }
-
- contracts[types[i]] = &tmplContract{
- Type: capitalise(types[i]),
- InputABI: strings.Replace(strippedABI, "\"", "\\\"", -1),
- InputBin: strings.TrimPrefix(strings.TrimSpace(bytecodes[i]), "0x"),
- Constructor: evmABI.Constructor,
- Calls: calls,
- Transacts: transacts,
- Events: events,
- Libraries: make(map[string]string),
- Structs: structs,
- }
- // Function 4-byte signatures are stored in the same sequence
- // as types, if available.
- if len(fsigs) > i {
- contracts[types[i]].FuncSigs = fsigs[i]
- }
- // Parse library references.
- for pattern, name := range libs {
- matched, err := regexp.Match("__\\$"+pattern+"\\$__", []byte(contracts[types[i]].InputBin))
- if err != nil {
- log.Error("Could not search for pattern", "pattern", pattern, "contract", contracts[types[i]], "err", err)
- }
- if matched {
- contracts[types[i]].Libraries[pattern] = name
- // keep track that this type is a library
- if _, ok := isLib[name]; !ok {
- isLib[name] = struct{}{}
- }
- }
- }
- }
- // Check if that type has already been identified as a library
- for i := 0; i < len(types); i++ {
- _, ok := isLib[types[i]]
- contracts[types[i]].Library = ok
- }
- // Generate the contract template data content and render it
- data := &tmplData{
- Package: pkg,
- Contracts: contracts,
- Libraries: libs,
- }
- buffer := new(bytes.Buffer)
-
- funcs := map[string]interface{}{
- "bindtype": bindType[lang],
- "bindtopictype": bindTopicType[lang],
- "namedtype": namedType[lang],
- "formatmethod": formatMethod,
- "formatevent": formatEvent,
- "capitalise": capitalise,
- "decapitalise": decapitalise,
- }
- tmpl := template.Must(template.New("").Funcs(funcs).Parse(tmplSource[lang]))
- if err := tmpl.Execute(buffer, data); err != nil {
- return "", err
- }
- // For Go bindings pass the code through gofmt to clean it up
- if lang == LangGo {
- code, err := format.Source(buffer.Bytes())
- if err != nil {
- return "", fmt.Errorf("%v\n%s", err, buffer)
- }
- return string(code), nil
- }
- // For all others just return as is for now
- return buffer.String(), nil
-}
-
-// bindType is a set of type binders that convert Solidity types to some supported
-// programming language types.
-var bindType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) string{
- LangGo: bindTypeGo,
- LangJava: bindTypeJava,
-}
-
-// bindBasicTypeGo converts basic solidity types(except array, slice and tuple) to Go one.
-func bindBasicTypeGo(kind abi.Type) string {
- switch kind.T {
- case abi.AddressTy:
- return "common.Address"
- case abi.IntTy, abi.UintTy:
- parts := regexp.MustCompile(`(u)?int([0-9]*)`).FindStringSubmatch(kind.String())
- switch parts[2] {
- case "8", "16", "32", "64":
- return fmt.Sprintf("%sint%s", parts[1], parts[2])
- }
- return "*big.Int"
- case abi.FixedBytesTy:
- return fmt.Sprintf("[%d]byte", kind.Size)
- case abi.BytesTy:
- return "[]byte"
- case abi.FunctionTy:
- return "[24]byte"
- default:
- // string, bool types
- return kind.String()
- }
-}
-
-// bindTypeGo converts solidity types to Go ones. Since there is no clear mapping
-// from all Solidity types to Go ones (e.g. uint17), those that cannot be exactly
-// mapped will use an upscaled type (e.g. BigDecimal).
-func bindTypeGo(kind abi.Type, structs map[string]*tmplStruct) string {
- switch kind.T {
- case abi.TupleTy:
- return structs[kind.String()].Name
- case abi.ArrayTy:
- return fmt.Sprintf("[%d]", kind.Size) + bindTypeGo(*kind.Elem, structs)
- case abi.SliceTy:
- return "[]" + bindTypeGo(*kind.Elem, structs)
- default:
- return bindBasicTypeGo(kind)
- }
-}
-
-// bindBasicTypeJava converts basic solidity types(except array, slice and tuple) to Java one.
-func bindBasicTypeJava(kind abi.Type) string {
- switch kind.T {
- case abi.AddressTy:
- return "Address"
- case abi.IntTy, abi.UintTy:
- // Note that uint and int (without digits) are also matched,
- // these are size 256, and will translate to BigInt (the default).
- parts := regexp.MustCompile(`(u)?int([0-9]*)`).FindStringSubmatch(kind.String())
- if len(parts) != 3 {
- return kind.String()
- }
- // All unsigned integers should be translated to BigInt since gomobile doesn't
- // support them.
- if parts[1] == "u" {
- return "BigInt"
- }
-
- namedSize := map[string]string{
- "8": "byte",
- "16": "short",
- "32": "int",
- "64": "long",
- }[parts[2]]
-
- // default to BigInt
- if namedSize == "" {
- namedSize = "BigInt"
- }
- return namedSize
- case abi.FixedBytesTy, abi.BytesTy:
- return "byte[]"
- case abi.BoolTy:
- return "boolean"
- case abi.StringTy:
- return "String"
- case abi.FunctionTy:
- return "byte[24]"
- default:
- return kind.String()
- }
-}
-
-// pluralizeJavaType explicitly converts multidimensional types to predefined
-// type in go side.
-func pluralizeJavaType(typ string) string {
- switch typ {
- case "boolean":
- return "Bools"
- case "String":
- return "Strings"
- case "Address":
- return "Addresses"
- case "byte[]":
- return "Binaries"
- case "BigInt":
- return "BigInts"
- }
- return typ + "[]"
-}
-
-// bindTypeJava converts a Solidity type to a Java one. Since there is no clear mapping
-// from all Solidity types to Java ones (e.g. uint17), those that cannot be exactly
-// mapped will use an upscaled type (e.g. BigDecimal).
-func bindTypeJava(kind abi.Type, structs map[string]*tmplStruct) string {
- switch kind.T {
- case abi.TupleTy:
- return structs[kind.String()].Name
- case abi.ArrayTy, abi.SliceTy:
- return pluralizeJavaType(bindTypeJava(*kind.Elem, structs))
- default:
- return bindBasicTypeJava(kind)
- }
-}
-
-// bindTopicType is a set of type binders that convert Solidity types to some
-// supported programming language topic types.
-var bindTopicType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) string{
- LangGo: bindTopicTypeGo,
- LangJava: bindTopicTypeJava,
-}
-
-// bindTopicTypeGo converts a Solidity topic type to a Go one. It is almost the same
-// funcionality as for simple types, but dynamic types get converted to hashes.
-func bindTopicTypeGo(kind abi.Type, structs map[string]*tmplStruct) string {
- bound := bindTypeGo(kind, structs)
- if bound == "string" || bound == "[]byte" {
- bound = "common.Hash"
- }
- return bound
-}
-
-// bindTopicTypeJava converts a Solidity topic type to a Java one. It is almost the same
-// funcionality as for simple types, but dynamic types get converted to hashes.
-func bindTopicTypeJava(kind abi.Type, structs map[string]*tmplStruct) string {
- bound := bindTypeJava(kind, structs)
- if bound == "String" || bound == "byte[]" {
- bound = "Hash"
- }
- return bound
-}
-
-// bindStructType is a set of type binders that convert Solidity tuple types to some supported
-// programming language struct definition.
-var bindStructType = map[Lang]func(kind abi.Type, structs map[string]*tmplStruct) string{
- LangGo: bindStructTypeGo,
- LangJava: bindStructTypeJava,
-}
-
-// bindStructTypeGo converts a Solidity tuple type to a Go one and records the mapping
-// in the given map.
-// Notably, this function will resolve and record nested struct recursively.
-func bindStructTypeGo(kind abi.Type, structs map[string]*tmplStruct) string {
- switch kind.T {
- case abi.TupleTy:
- if s, exist := structs[kind.String()]; exist {
- return s.Name
- }
- var fields []*tmplField
- for i, elem := range kind.TupleElems {
- field := bindStructTypeGo(*elem, structs)
- fields = append(fields, &tmplField{Type: field, Name: capitalise(kind.TupleRawNames[i]), SolKind: *elem})
- }
- name := fmt.Sprintf("Struct%d", len(structs))
- structs[kind.String()] = &tmplStruct{
- Name: name,
- Fields: fields,
- }
- return name
- case abi.ArrayTy:
- return fmt.Sprintf("[%d]", kind.Size) + bindStructTypeGo(*kind.Elem, structs)
- case abi.SliceTy:
- return "[]" + bindStructTypeGo(*kind.Elem, structs)
- default:
- return bindBasicTypeGo(kind)
- }
-}
-
-// bindStructTypeJava converts a Solidity tuple type to a Java one and records the mapping
-// in the given map.
-// Notably, this function will resolve and record nested struct recursively.
-func bindStructTypeJava(kind abi.Type, structs map[string]*tmplStruct) string {
- switch kind.T {
- case abi.TupleTy:
- if s, exist := structs[kind.String()]; exist {
- return s.Name
- }
- var fields []*tmplField
- for i, elem := range kind.TupleElems {
- field := bindStructTypeJava(*elem, structs)
- fields = append(fields, &tmplField{Type: field, Name: decapitalise(kind.TupleRawNames[i]), SolKind: *elem})
- }
- name := fmt.Sprintf("Class%d", len(structs))
- structs[kind.String()] = &tmplStruct{
- Name: name,
- Fields: fields,
- }
- return name
- case abi.ArrayTy, abi.SliceTy:
- return pluralizeJavaType(bindStructTypeJava(*kind.Elem, structs))
- default:
- return bindBasicTypeJava(kind)
- }
-}
-
-// namedType is a set of functions that transform language specific types to
-// named versions that my be used inside method names.
-var namedType = map[Lang]func(string, abi.Type) string{
- LangGo: func(string, abi.Type) string { panic("this shouldn't be needed") },
- LangJava: namedTypeJava,
-}
-
-// namedTypeJava converts some primitive data types to named variants that can
-// be used as parts of method names.
-func namedTypeJava(javaKind string, solKind abi.Type) string {
- switch javaKind {
- case "byte[]":
- return "Binary"
- case "boolean":
- return "Bool"
- default:
- parts := regexp.MustCompile(`(u)?int([0-9]*)(\[[0-9]*\])?`).FindStringSubmatch(solKind.String())
- if len(parts) != 4 {
- return javaKind
- }
- switch parts[2] {
- case "8", "16", "32", "64":
- if parts[3] == "" {
- return capitalise(fmt.Sprintf("%sint%s", parts[1], parts[2]))
- }
- return capitalise(fmt.Sprintf("%sint%ss", parts[1], parts[2]))
-
- default:
- return javaKind
- }
- }
-}
-
-// methodNormalizer is a name transformer that modifies Solidity method names to
-// conform to target language naming concentions.
-var methodNormalizer = map[Lang]func(string) string{
- LangGo: abi.ToCamelCase,
- LangJava: decapitalise,
-}
-
-// capitalise makes a camel-case string which starts with an upper case character.
-func capitalise(input string) string {
- return abi.ToCamelCase(input)
-}
-
-// decapitalise makes a camel-case string which starts with a lower case character.
-func decapitalise(input string) string {
- if len(input) == 0 {
- return input
- }
-
- goForm := abi.ToCamelCase(input)
- return strings.ToLower(goForm[:1]) + goForm[1:]
-}
-
-// structured checks whether a list of ABI data types has enough information to
-// operate through a proper Go struct or if flat returns are needed.
-func structured(args abi.Arguments) bool {
- if len(args) < 2 {
- return false
- }
- exists := make(map[string]bool)
- for _, out := range args {
- // If the name is anonymous, we can't organize into a struct
- if out.Name == "" {
- return false
- }
- // If the field name is empty when normalized or collides (var, Var, _var, _Var),
- // we can't organize into a struct
- field := capitalise(out.Name)
- if field == "" || exists[field] {
- return false
- }
- exists[field] = true
- }
- return true
-}
-
-// resolveArgName converts a raw argument representation into a user friendly format.
-func resolveArgName(arg abi.Argument, structs map[string]*tmplStruct) string {
- var (
- prefix string
- embedded string
- typ = &arg.Type
- )
-loop:
- for {
- switch typ.T {
- case abi.SliceTy:
- prefix += "[]"
- case abi.ArrayTy:
- prefix += fmt.Sprintf("[%d]", typ.Size)
- default:
- embedded = typ.String()
- break loop
- }
- typ = typ.Elem
- }
- if s, exist := structs[embedded]; exist {
- return prefix + s.Name
- } else {
- return arg.Type.String()
- }
-}
-
-// formatMethod transforms raw method representation into a user friendly one.
-func formatMethod(method abi.Method, structs map[string]*tmplStruct) string {
- inputs := make([]string, len(method.Inputs))
- for i, input := range method.Inputs {
- inputs[i] = fmt.Sprintf("%v %v", resolveArgName(input, structs), input.Name)
- }
- outputs := make([]string, len(method.Outputs))
- for i, output := range method.Outputs {
- outputs[i] = resolveArgName(output, structs)
- if len(output.Name) > 0 {
- outputs[i] += fmt.Sprintf(" %v", output.Name)
- }
- }
- constant := ""
- if method.Const {
- constant = "constant "
- }
- return fmt.Sprintf("function %v(%v) %sreturns(%v)", method.RawName, strings.Join(inputs, ", "), constant, strings.Join(outputs, ", "))
-}
-
-// formatEvent transforms raw event representation into a user friendly one.
-func formatEvent(event abi.Event, structs map[string]*tmplStruct) string {
- inputs := make([]string, len(event.Inputs))
- for i, input := range event.Inputs {
- if input.Indexed {
- inputs[i] = fmt.Sprintf("%v indexed %v", resolveArgName(input, structs), input.Name)
- } else {
- inputs[i] = fmt.Sprintf("%v %v", resolveArgName(input, structs), input.Name)
- }
- }
- return fmt.Sprintf("event %v(%v)", event.RawName, strings.Join(inputs, ", "))
-}
diff --git a/accounts/abi/bind/template.go b/accounts/abi/bind/template.go
deleted file mode 100644
index e90d02e..0000000
--- a/accounts/abi/bind/template.go
+++ /dev/null
@@ -1,616 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package bind
-
-import "github.com/ava-labs/coreth/accounts/abi"
-
-// tmplData is the data structure required to fill the binding template.
-type tmplData struct {
- Package string // Name of the package to place the generated file in
- 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
-}
-
-// tmplContract contains the data needed to generate an individual contract binding.
-type tmplContract struct {
- Type string // Type name of the main contract binding
- InputABI string // JSON ABI used as the input to generate the binding from
- InputBin string // Optional EVM bytecode used to denetare deploy code from
- FuncSigs map[string]string // Optional map: string signature -> 4-byte signature
- Constructor abi.Method // Contract constructor for deploy parametrization
- Calls map[string]*tmplMethod // Contract calls that only read state data
- Transacts map[string]*tmplMethod // Contract calls that write state data
- Events map[string]*tmplEvent // Contract events accessors
- 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
-}
-
-// tmplMethod is a wrapper around an abi.Method that contains a few preprocessed
-// and cached data fields.
-type tmplMethod struct {
- Original abi.Method // Original method as parsed by the abi package
- Normalized abi.Method // Normalized version of the parsed method (capitalized names, non-anonymous args/returns)
- Structured bool // Whether the returns should be accumulated into a struct
-}
-
-// tmplEvent is a wrapper around an a
-type tmplEvent struct {
- Original abi.Event // Original event as parsed by the abi package
- Normalized abi.Event // Normalized version of the parsed fields
-}
-
-// tmplField is a wrapper around a struct field with binding language
-// struct type definition and relative filed name.
-type tmplField struct {
- Type string // Field type representation depends on target binding language
- Name string // Field name converted from the raw user-defined field name
- SolKind abi.Type // Raw abi type information
-}
-
-// tmplStruct is a wrapper around an abi.tuple contains a auto-generated
-// struct name.
-type tmplStruct struct {
- Name string // Auto-generated struct name(We can't obtain the raw struct name through abi)
- Fields []*tmplField // Struct fields definition depends on the binding language.
-}
-
-// tmplSource is language to template mapping containing all the supported
-// programming languages the package can generate to.
-var tmplSource = map[Lang]string{
- LangGo: tmplSourceGo,
- LangJava: tmplSourceJava,
-}
-
-// tmplSourceGo is the Go source template use to generate the contract binding
-// based on.
-const tmplSourceGo = `
-// Code generated - DO NOT EDIT.
-// This file is a generated binding and any manual changes will be lost.
-
-package {{.Package}}
-
-import (
- "math/big"
- "strings"
-
- ethereum "github.com/ava-labs/go-ethereum"
- "github.com/ava-labs/coreth/accounts/abi"
- "github.com/ava-labs/coreth/accounts/abi/bind"
- "github.com/ava-labs/go-ethereum/common"
- "github.com/ava-labs/coreth/core/types"
- "github.com/ava-labs/go-ethereum/event"
-)
-
-// Reference imports to suppress errors if they are not otherwise used.
-var (
- _ = big.NewInt
- _ = strings.NewReader
- _ = ethereum.NotFound
- _ = abi.U256
- _ = bind.Bind
- _ = common.Big1
- _ = types.BloomLookup
- _ = event.NewSubscription
-)
-
-{{range $contract := .Contracts}}
- {{$structs := $contract.Structs}}
- // {{.Type}}ABI is the input ABI used to generate the binding from.
- const {{.Type}}ABI = "{{.InputABI}}"
-
- {{if $contract.FuncSigs}}
- // {{.Type}}FuncSigs maps the 4-byte function signature to its string representation.
- var {{.Type}}FuncSigs = map[string]string{
- {{range $strsig, $binsig := .FuncSigs}}"{{$binsig}}": "{{$strsig}}",
- {{end}}
- }
- {{end}}
-
- {{if .InputBin}}
- // {{.Type}}Bin is the compiled bytecode used for deploying new contracts.
- var {{.Type}}Bin = "0x{{.InputBin}}"
-
- // Deploy{{.Type}} deploys a new Ethereum contract, binding an instance of {{.Type}} to it.
- func Deploy{{.Type}}(auth *bind.TransactOpts, backend bind.ContractBackend {{range .Constructor.Inputs}}, {{.Name}} {{bindtype .Type $structs}}{{end}}) (common.Address, *types.Transaction, *{{.Type}}, error) {
- parsed, err := abi.JSON(strings.NewReader({{.Type}}ABI))
- if err != nil {
- return common.Address{}, nil, nil, err
- }
- {{range $pattern, $name := .Libraries}}
- {{decapitalise $name}}Addr, _, _, _ := Deploy{{capitalise $name}}(auth, backend)
- {{$contract.Type}}Bin = strings.Replace({{$contract.Type}}Bin, "__${{$pattern}}$__", {{decapitalise $name}}Addr.String()[2:], -1)
- {{end}}
- address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex({{.Type}}Bin), backend {{range .Constructor.Inputs}}, {{.Name}}{{end}})
- if err != nil {
- return common.Address{}, nil, nil, err
- }
- return address, tx, &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil
- }
- {{end}}
-
- // {{.Type}} is an auto generated Go binding around an Ethereum contract.
- type {{.Type}} struct {
- {{.Type}}Caller // Read-only binding to the contract
- {{.Type}}Transactor // Write-only binding to the contract
- {{.Type}}Filterer // Log filterer for contract events
- }
-
- // {{.Type}}Caller is an auto generated read-only Go binding around an Ethereum contract.
- type {{.Type}}Caller struct {
- contract *bind.BoundContract // Generic contract wrapper for the low level calls
- }
-
- // {{.Type}}Transactor is an auto generated write-only Go binding around an Ethereum contract.
- type {{.Type}}Transactor struct {
- contract *bind.BoundContract // Generic contract wrapper for the low level calls
- }
-
- // {{.Type}}Filterer is an auto generated log filtering Go binding around an Ethereum contract events.
- type {{.Type}}Filterer struct {
- contract *bind.BoundContract // Generic contract wrapper for the low level calls
- }
-
- // {{.Type}}Session is an auto generated Go binding around an Ethereum contract,
- // with pre-set call and transact options.
- type {{.Type}}Session struct {
- Contract *{{.Type}} // 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
- }
-
- // {{.Type}}CallerSession is an auto generated read-only Go binding around an Ethereum contract,
- // with pre-set call options.
- type {{.Type}}CallerSession struct {
- Contract *{{.Type}}Caller // Generic contract caller binding to set the session for
- CallOpts bind.CallOpts // Call options to use throughout this session
- }
-
- // {{.Type}}TransactorSession is an auto generated write-only Go binding around an Ethereum contract,
- // with pre-set transact options.
- type {{.Type}}TransactorSession struct {
- Contract *{{.Type}}Transactor // Generic contract transactor binding to set the session for
- TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
- }
-
- // {{.Type}}Raw is an auto generated low-level Go binding around an Ethereum contract.
- type {{.Type}}Raw struct {
- Contract *{{.Type}} // Generic contract binding to access the raw methods on
- }
-
- // {{.Type}}CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
- type {{.Type}}CallerRaw struct {
- Contract *{{.Type}}Caller // Generic read-only contract binding to access the raw methods on
- }
-
- // {{.Type}}TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
- type {{.Type}}TransactorRaw struct {
- Contract *{{.Type}}Transactor // Generic write-only contract binding to access the raw methods on
- }
-
- // New{{.Type}} creates a new instance of {{.Type}}, bound to a specific deployed contract.
- func New{{.Type}}(address common.Address, backend bind.ContractBackend) (*{{.Type}}, error) {
- contract, err := bind{{.Type}}(address, backend, backend, backend)
- if err != nil {
- return nil, err
- }
- return &{{.Type}}{ {{.Type}}Caller: {{.Type}}Caller{contract: contract}, {{.Type}}Transactor: {{.Type}}Transactor{contract: contract}, {{.Type}}Filterer: {{.Type}}Filterer{contract: contract} }, nil
- }
-
- // New{{.Type}}Caller creates a new read-only instance of {{.Type}}, bound to a specific deployed contract.
- func New{{.Type}}Caller(address common.Address, caller bind.ContractCaller) (*{{.Type}}Caller, error) {
- contract, err := bind{{.Type}}(address, caller, nil, nil)
- if err != nil {
- return nil, err
- }
- return &{{.Type}}Caller{contract: contract}, nil
- }
-
- // New{{.Type}}Transactor creates a new write-only instance of {{.Type}}, bound to a specific deployed contract.
- func New{{.Type}}Transactor(address common.Address, transactor bind.ContractTransactor) (*{{.Type}}Transactor, error) {
- contract, err := bind{{.Type}}(address, nil, transactor, nil)
- if err != nil {
- return nil, err
- }
- return &{{.Type}}Transactor{contract: contract}, nil
- }
-
- // New{{.Type}}Filterer creates a new log filterer instance of {{.Type}}, bound to a specific deployed contract.
- func New{{.Type}}Filterer(address common.Address, filterer bind.ContractFilterer) (*{{.Type}}Filterer, error) {
- contract, err := bind{{.Type}}(address, nil, nil, filterer)
- if err != nil {
- return nil, err
- }
- return &{{.Type}}Filterer{contract: contract}, nil
- }
-
- // bind{{.Type}} binds a generic wrapper to an already deployed contract.
- func bind{{.Type}}(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
- parsed, err := abi.JSON(strings.NewReader({{.Type}}ABI))
- 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 (_{{$contract.Type}} *{{$contract.Type}}Raw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
- return _{{$contract.Type}}.Contract.{{$contract.Type}}Caller.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 (_{{$contract.Type}} *{{$contract.Type}}Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.contract.Transfer(opts)
- }
-
- // Transact invokes the (paid) contract method with params as input values.
- func (_{{$contract.Type}} *{{$contract.Type}}Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- return _{{$contract.Type}}.Contract.{{$contract.Type}}Transactor.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 (_{{$contract.Type}} *{{$contract.Type}}CallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
- return _{{$contract.Type}}.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 (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
- return _{{$contract.Type}}.Contract.contract.Transfer(opts)
- }
-
- // Transact invokes the (paid) contract method with params as input values.
- func (_{{$contract.Type}} *{{$contract.Type}}TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
- 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}}
- // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
- //
- // Solidity: {{formatmethod .Original $structs}}
- func (_{{$contract.Type}} *{{$contract.Type}}Caller) {{.Normalized.Name}}(opts *bind.CallOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} },{{else}}{{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}}{{end}} error) {
- {{if .Structured}}ret := new(struct{
- {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}}
- {{end}}
- }){{else}}var (
- {{range $i, $_ := .Normalized.Outputs}}ret{{$i}} = new({{bindtype .Type $structs}})
- {{end}}
- ){{end}}
- out := {{if .Structured}}ret{{else}}{{if eq (len .Normalized.Outputs) 1}}ret0{{else}}&[]interface{}{
- {{range $i, $_ := .Normalized.Outputs}}ret{{$i}},
- {{end}}
- }{{end}}{{end}}
- err := _{{$contract.Type}}.contract.Call(opts, out, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}})
- return {{if .Structured}}*ret,{{else}}{{range $i, $_ := .Normalized.Outputs}}*ret{{$i}},{{end}}{{end}} err
- }
-
- // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
- //
- // Solidity: {{formatmethod .Original $structs}}
- func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) {
- return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}})
- }
-
- // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
- //
- // Solidity: {{formatmethod .Original $structs}}
- func (_{{$contract.Type}} *{{$contract.Type}}CallerSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) ({{if .Structured}}struct{ {{range .Normalized.Outputs}}{{.Name}} {{bindtype .Type $structs}};{{end}} }, {{else}} {{range .Normalized.Outputs}}{{bindtype .Type $structs}},{{end}} {{end}} error) {
- return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.CallOpts {{range .Normalized.Inputs}}, {{.Name}}{{end}})
- }
- {{end}}
-
- {{range .Transacts}}
- // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}.
- //
- // Solidity: {{formatmethod .Original $structs}}
- func (_{{$contract.Type}} *{{$contract.Type}}Transactor) {{.Normalized.Name}}(opts *bind.TransactOpts {{range .Normalized.Inputs}}, {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) {
- return _{{$contract.Type}}.contract.Transact(opts, "{{.Original.Name}}" {{range .Normalized.Inputs}}, {{.Name}}{{end}})
- }
-
- // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}.
- //
- // Solidity: {{formatmethod .Original $structs}}
- func (_{{$contract.Type}} *{{$contract.Type}}Session) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) {
- return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}})
- }
-
- // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}.
- //
- // Solidity: {{formatmethod .Original $structs}}
- func (_{{$contract.Type}} *{{$contract.Type}}TransactorSession) {{.Normalized.Name}}({{range $i, $_ := .Normalized.Inputs}}{{if ne $i 0}},{{end}} {{.Name}} {{bindtype .Type $structs}} {{end}}) (*types.Transaction, error) {
- return _{{$contract.Type}}.Contract.{{.Normalized.Name}}(&_{{$contract.Type}}.TransactOpts {{range $i, $_ := .Normalized.Inputs}}, {{.Name}}{{end}})
- }
- {{end}}
-
- {{range .Events}}
- // {{$contract.Type}}{{.Normalized.Name}}Iterator is returned from Filter{{.Normalized.Name}} and is used to iterate over the raw logs and unpacked data for {{.Normalized.Name}} events raised by the {{$contract.Type}} contract.
- type {{$contract.Type}}{{.Normalized.Name}}Iterator struct {
- Event *{{$contract.Type}}{{.Normalized.Name}} // 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 *{{$contract.Type}}{{.Normalized.Name}}Iterator) 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({{$contract.Type}}{{.Normalized.Name}})
- 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({{$contract.Type}}{{.Normalized.Name}})
- 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 *{{$contract.Type}}{{.Normalized.Name}}Iterator) Error() error {
- return it.fail
- }
- // Close terminates the iteration process, releasing any pending underlying
- // resources.
- func (it *{{$contract.Type}}{{.Normalized.Name}}Iterator) Close() error {
- it.sub.Unsubscribe()
- return nil
- }
-
- // {{$contract.Type}}{{.Normalized.Name}} represents a {{.Normalized.Name}} event raised by the {{$contract.Type}} contract.
- type {{$contract.Type}}{{.Normalized.Name}} struct { {{range .Normalized.Inputs}}
- {{capitalise .Name}} {{if .Indexed}}{{bindtopictype .Type $structs}}{{else}}{{bindtype .Type $structs}}{{end}}; {{end}}
- Raw types.Log // Blockchain specific contextual infos
- }
-
- // Filter{{.Normalized.Name}} is a free log retrieval operation binding the contract event 0x{{printf "%x" .Original.ID}}.
- //
- // Solidity: {{formatevent .Original $structs}}
- func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Filter{{.Normalized.Name}}(opts *bind.FilterOpts{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (*{{$contract.Type}}{{.Normalized.Name}}Iterator, error) {
- {{range .Normalized.Inputs}}
- {{if .Indexed}}var {{.Name}}Rule []interface{}
- for _, {{.Name}}Item := range {{.Name}} {
- {{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item)
- }{{end}}{{end}}
-
- logs, sub, err := _{{$contract.Type}}.contract.FilterLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}})
- if err != nil {
- return nil, err
- }
- return &{{$contract.Type}}{{.Normalized.Name}}Iterator{contract: _{{$contract.Type}}.contract, event: "{{.Original.Name}}", logs: logs, sub: sub}, nil
- }
-
- // Watch{{.Normalized.Name}} is a free log subscription operation binding the contract event 0x{{printf "%x" .Original.ID}}.
- //
- // Solidity: {{formatevent .Original $structs}}
- func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Watch{{.Normalized.Name}}(opts *bind.WatchOpts, sink chan<- *{{$contract.Type}}{{.Normalized.Name}}{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}} []{{bindtype .Type $structs}}{{end}}{{end}}) (event.Subscription, error) {
- {{range .Normalized.Inputs}}
- {{if .Indexed}}var {{.Name}}Rule []interface{}
- for _, {{.Name}}Item := range {{.Name}} {
- {{.Name}}Rule = append({{.Name}}Rule, {{.Name}}Item)
- }{{end}}{{end}}
-
- logs, sub, err := _{{$contract.Type}}.contract.WatchLogs(opts, "{{.Original.Name}}"{{range .Normalized.Inputs}}{{if .Indexed}}, {{.Name}}Rule{{end}}{{end}})
- 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({{$contract.Type}}{{.Normalized.Name}})
- if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", 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
- }
-
- // Parse{{.Normalized.Name}} is a log parse operation binding the contract event 0x{{printf "%x" .Original.ID}}.
- //
- // Solidity: {{.Original.String}}
- func (_{{$contract.Type}} *{{$contract.Type}}Filterer) Parse{{.Normalized.Name}}(log types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) {
- event := new({{$contract.Type}}{{.Normalized.Name}})
- if err := _{{$contract.Type}}.contract.UnpackLog(event, "{{.Original.Name}}", log); err != nil {
- return nil, err
- }
- return event, nil
- }
-
- {{end}}
-{{end}}
-`
-
-// tmplSourceJava is the Java source template use to generate the contract binding
-// based on.
-const tmplSourceJava = `
-// This file is an automatically generated Java binding. Do not modify as any
-// change will likely be lost upon the next re-generation!
-
-package {{.Package}};
-
-import org.ethereum.geth.*;
-import java.util.*;
-
-{{range $contract := .Contracts}}
-{{$structs := $contract.Structs}}
-{{if not .Library}}public {{end}}class {{.Type}} {
- // ABI is the input ABI used to generate the binding from.
- public final static String ABI = "{{.InputABI}}";
- {{if $contract.FuncSigs}}
- // {{.Type}}FuncSigs maps the 4-byte function signature to its string representation.
- public final static Map<String, String> {{.Type}}FuncSigs;
- static {
- Hashtable<String, String> temp = new Hashtable<String, String>();
- {{range $strsig, $binsig := .FuncSigs}}temp.put("{{$binsig}}", "{{$strsig}}");
- {{end}}
- {{.Type}}FuncSigs = Collections.unmodifiableMap(temp);
- }
- {{end}}
- {{if .InputBin}}
- // BYTECODE is the compiled bytecode used for deploying new contracts.
- public final static String BYTECODE = "0x{{.InputBin}}";
-
- // deploy deploys a new Ethereum contract, binding an instance of {{.Type}} to it.
- public static {{.Type}} deploy(TransactOpts auth, EthereumClient client{{range .Constructor.Inputs}}, {{bindtype .Type $structs}} {{.Name}}{{end}}) throws Exception {
- Interfaces args = Geth.newInterfaces({{(len .Constructor.Inputs)}});
- String bytecode = BYTECODE;
- {{if .Libraries}}
-
- // "link" contract to dependent libraries by deploying them first.
- {{range $pattern, $name := .Libraries}}
- {{capitalise $name}} {{decapitalise $name}}Inst = {{capitalise $name}}.deploy(auth, client);
- bytecode = bytecode.replace("__${{$pattern}}$__", {{decapitalise $name}}Inst.Address.getHex().substring(2));
- {{end}}
- {{end}}
- {{range $index, $element := .Constructor.Inputs}}Interface arg{{$index}} = Geth.newInterface();arg{{$index}}.set{{namedtype (bindtype .Type $structs) .Type}}({{.Name}});args.set({{$index}},arg{{$index}});
- {{end}}
- return new {{.Type}}(Geth.deployContract(auth, ABI, Geth.decodeFromHex(bytecode), client, args));
- }
-
- // Internal constructor used by contract deployment.
- private {{.Type}}(BoundContract deployment) {
- this.Address = deployment.getAddress();
- this.Deployer = deployment.getDeployer();
- this.Contract = deployment;
- }
- {{end}}
-
- // Ethereum address where this contract is located at.
- public final Address Address;
-
- // Ethereum transaction in which this contract was deployed (if known!).
- public final Transaction Deployer;
-
- // Contract instance bound to a blockchain address.
- private final BoundContract Contract;
-
- // Creates a new instance of {{.Type}}, bound to a specific deployed contract.
- public {{.Type}}(Address address, EthereumClient client) throws Exception {
- this(Geth.bindContract(address, ABI, client));
- }
-
- {{range .Calls}}
- {{if gt (len .Normalized.Outputs) 1}}
- // {{capitalise .Normalized.Name}}Results is the output of a call to {{.Normalized.Name}}.
- public class {{capitalise .Normalized.Name}}Results {
- {{range $index, $item := .Normalized.Outputs}}public {{bindtype .Type $structs}} {{if ne .Name ""}}{{.Name}}{{else}}Return{{$index}}{{end}};
- {{end}}
- }
- {{end}}
-
- // {{.Normalized.Name}} is a free data retrieval call binding the contract method 0x{{printf "%x" .Original.ID}}.
- //
- // Solidity: {{.Original.String}}
- public {{if gt (len .Normalized.Outputs) 1}}{{capitalise .Normalized.Name}}Results{{else}}{{range .Normalized.Outputs}}{{bindtype .Type $structs}}{{end}}{{end}} {{.Normalized.Name}}(CallOpts opts{{range .Normalized.Inputs}}, {{bindtype .Type $structs}} {{.Name}}{{end}}) throws Exception {
- Interfaces args = Geth.newInterfaces({{(len .Normalized.Inputs)}});
- {{range $index, $item := .Normalized.Inputs}}Interface arg{{$index}} = Geth.newInterface();arg{{$index}}.set{{namedtype (bindtype .Type $structs) .Type}}({{.Name}});args.set({{$index}},arg{{$index}});
- {{end}}
-
- Interfaces results = Geth.newInterfaces({{(len .Normalized.Outputs)}});
- {{range $index, $item := .Normalized.Outputs}}Interface result{{$index}} = Geth.newInterface(); result{{$index}}.setDefault{{namedtype (bindtype .Type $structs) .Type}}(); results.set({{$index}}, result{{$index}});
- {{end}}
-
- if (opts == null) {
- opts = Geth.newCallOpts();
- }
- this.Contract.call(opts, results, "{{.Original.Name}}", args);
- {{if gt (len .Normalized.Outputs) 1}}
- {{capitalise .Normalized.Name}}Results result = new {{capitalise .Normalized.Name}}Results();
- {{range $index, $item := .Normalized.Outputs}}result.{{if ne .Name ""}}{{.Name}}{{else}}Return{{$index}}{{end}} = results.get({{$index}}).get{{namedtype (bindtype .Type $structs) .Type}}();
- {{end}}
- return result;
- {{else}}{{range .Normalized.Outputs}}return results.get(0).get{{namedtype (bindtype .Type $structs) .Type}}();{{end}}
- {{end}}
- }
- {{end}}
-
- {{range .Transacts}}
- // {{.Normalized.Name}} is a paid mutator transaction binding the contract method 0x{{printf "%x" .Original.ID}}.
- //
- // Solidity: {{.Original.String}}
- public Transaction {{.Normalized.Name}}(TransactOpts opts{{range .Normalized.Inputs}}, {{bindtype .Type $structs}} {{.Name}}{{end}}) throws Exception {
- Interfaces args = Geth.newInterfaces({{(len .Normalized.Inputs)}});
- {{range $index, $item := .Normalized.Inputs}}Interface arg{{$index}} = Geth.newInterface();arg{{$index}}.set{{namedtype (bindtype .Type $structs) .Type}}({{.Name}});args.set({{$index}},arg{{$index}});
- {{end}}
- return this.Contract.transact(opts, "{{.Original.Name}}" , args);
- }
- {{end}}
-}
-{{end}}
-`
diff --git a/accounts/abi/bind/topics.go b/accounts/abi/bind/topics.go
deleted file mode 100644
index 58e4ff3..0000000
--- a/accounts/abi/bind/topics.go
+++ /dev/null
@@ -1,241 +0,0 @@
-// Copyright 2018 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package bind
-
-import (
- "encoding/binary"
- "errors"
- "fmt"
- "math/big"
- "reflect"
-
- "github.com/ava-labs/coreth/accounts/abi"
- "github.com/ava-labs/go-ethereum/common"
- "github.com/ava-labs/go-ethereum/crypto"
-)
-
-// makeTopics converts a filter query argument list into a filter topic set.
-func makeTopics(query ...[]interface{}) ([][]common.Hash, error) {
- topics := make([][]common.Hash, len(query))
- for i, filter := range query {
- for _, rule := range filter {
- var topic common.Hash
-
- // Try to generate the topic based on simple types
- switch rule := rule.(type) {
- case common.Hash:
- copy(topic[:], rule[:])
- case common.Address:
- copy(topic[common.HashLength-common.AddressLength:], rule[:])
- case *big.Int:
- blob := rule.Bytes()
- copy(topic[common.HashLength-len(blob):], blob)
- case bool:
- if rule {
- topic[common.HashLength-1] = 1
- }
- case int8:
- blob := big.NewInt(int64(rule)).Bytes()
- copy(topic[common.HashLength-len(blob):], blob)
- case int16:
- blob := big.NewInt(int64(rule)).Bytes()
- copy(topic[common.HashLength-len(blob):], blob)
- case int32:
- blob := big.NewInt(int64(rule)).Bytes()
- copy(topic[common.HashLength-len(blob):], blob)
- case int64:
- blob := big.NewInt(rule).Bytes()
- copy(topic[common.HashLength-len(blob):], blob)
- case uint8:
- blob := new(big.Int).SetUint64(uint64(rule)).Bytes()
- copy(topic[common.HashLength-len(blob):], blob)
- case uint16:
- blob := new(big.Int).SetUint64(uint64(rule)).Bytes()
- copy(topic[common.HashLength-len(blob):], blob)
- case uint32:
- blob := new(big.Int).SetUint64(uint64(rule)).Bytes()
- copy(topic[common.HashLength-len(blob):], blob)
- case uint64:
- blob := new(big.Int).SetUint64(rule).Bytes()
- copy(topic[common.HashLength-len(blob):], blob)
- case string:
- hash := crypto.Keccak256Hash([]byte(rule))
- copy(topic[:], hash[:])
- case []byte:
- hash := crypto.Keccak256Hash(rule)
- copy(topic[:], hash[:])
-
- default:
- // Attempt to generate the topic from funky types
- val := reflect.ValueOf(rule)
-
- switch {
-
- // static byte array
- case val.Kind() == reflect.Array && reflect.TypeOf(rule).Elem().Kind() == reflect.Uint8:
- reflect.Copy(reflect.ValueOf(topic[:val.Len()]), val)
-
- default:
- return nil, fmt.Errorf("unsupported indexed type: %T", rule)
- }
- }
- topics[i] = append(topics[i], topic)
- }
- }
- return topics, nil
-}
-
-// Big batch of reflect types for topic reconstruction.
-var (
- reflectHash = reflect.TypeOf(common.Hash{})
- reflectAddress = reflect.TypeOf(common.Address{})
- reflectBigInt = reflect.TypeOf(new(big.Int))
-)
-
-// parseTopics converts the indexed topic fields into actual log field values.
-//
-// Note, dynamic types cannot be reconstructed since they get mapped to Keccak256
-// hashes as the topic value!
-func parseTopics(out interface{}, fields abi.Arguments, topics []common.Hash) error {
- // Sanity check that the fields and topics match up
- if len(fields) != len(topics) {
- return errors.New("topic/field count mismatch")
- }
- // Iterate over all the fields and reconstruct them from topics
- for _, arg := range fields {
- if !arg.Indexed {
- return errors.New("non-indexed field in topic reconstruction")
- }
- field := reflect.ValueOf(out).Elem().FieldByName(capitalise(arg.Name))
-
- // Try to parse the topic back into the fields based on primitive types
- switch field.Kind() {
- case reflect.Bool:
- if topics[0][common.HashLength-1] == 1 {
- field.Set(reflect.ValueOf(true))
- }
- case reflect.Int8:
- num := new(big.Int).SetBytes(topics[0][:])
- field.Set(reflect.ValueOf(int8(num.Int64())))
-
- case reflect.Int16:
- num := new(big.Int).SetBytes(topics[0][:])
- field.Set(reflect.ValueOf(int16(num.Int64())))
-
- case reflect.Int32:
- num := new(big.Int).SetBytes(topics[0][:])
- field.Set(reflect.ValueOf(int32(num.Int64())))
-
- case reflect.Int64:
- num := new(big.Int).SetBytes(topics[0][:])
- field.Set(reflect.ValueOf(num.Int64()))
-
- case reflect.Uint8:
- num := new(big.Int).SetBytes(topics[0][:])
- field.Set(reflect.ValueOf(uint8(num.Uint64())))
-
- case reflect.Uint16:
- num := new(big.Int).SetBytes(topics[0][:])
- field.Set(reflect.ValueOf(uint16(num.Uint64())))
-
- case reflect.Uint32:
- num := new(big.Int).SetBytes(topics[0][:])
- field.Set(reflect.ValueOf(uint32(num.Uint64())))
-
- case reflect.Uint64:
- num := new(big.Int).SetBytes(topics[0][:])
- field.Set(reflect.ValueOf(num.Uint64()))
-
- default:
- // Ran out of plain primitive types, try custom types
- switch field.Type() {
- case reflectHash: // Also covers all dynamic types
- field.Set(reflect.ValueOf(topics[0]))
-
- case reflectAddress:
- var addr common.Address
- copy(addr[:], topics[0][common.HashLength-common.AddressLength:])
- field.Set(reflect.ValueOf(addr))
-
- case reflectBigInt:
- num := new(big.Int).SetBytes(topics[0][:])
- field.Set(reflect.ValueOf(num))
-
- default:
- // Ran out of custom types, try the crazies
- switch {
-
- // static byte array
- case arg.Type.T == abi.FixedBytesTy:
- reflect.Copy(field, reflect.ValueOf(topics[0][:arg.Type.Size]))
-
- default:
- return fmt.Errorf("unsupported indexed type: %v", arg.Type)
- }
- }
- }
- topics = topics[1:]
- }
- return nil
-}
-
-// parseTopicsIntoMap converts the indexed topic field-value pairs into map key-value pairs
-func parseTopicsIntoMap(out map[string]interface{}, fields abi.Arguments, topics []common.Hash) error {
- // Sanity check that the fields and topics match up
- if len(fields) != len(topics) {
- return errors.New("topic/field count mismatch")
- }
- // Iterate over all the fields and reconstruct them from topics
- for _, arg := range fields {
- if !arg.Indexed {
- return errors.New("non-indexed field in topic reconstruction")
- }
-
- switch arg.Type.T {
- case abi.BoolTy:
- out[arg.Name] = topics[0][common.HashLength-1] == 1
- case abi.IntTy, abi.UintTy:
- num := new(big.Int).SetBytes(topics[0][:])
- out[arg.Name] = num
- case abi.AddressTy:
- var addr common.Address
- copy(addr[:], topics[0][common.HashLength-common.AddressLength:])
- out[arg.Name] = addr
- case abi.HashTy:
- out[arg.Name] = topics[0]
- case abi.FixedBytesTy:
- out[arg.Name] = topics[0][:]
- case abi.StringTy, abi.BytesTy, abi.SliceTy, abi.ArrayTy:
- // Array types (including strings and bytes) have their keccak256 hashes stored in the topic- not a hash
- // whose bytes can be decoded to the actual value- so the best we can do is retrieve that hash
- out[arg.Name] = topics[0]
- case abi.FunctionTy:
- if garbage := binary.BigEndian.Uint64(topics[0][0:8]); garbage != 0 {
- return fmt.Errorf("bind: got improperly encoded function type, got %v", topics[0].Bytes())
- }
- var tmp [24]byte
- copy(tmp[:], topics[0][8:32])
- out[arg.Name] = tmp
- default: // Not handling tuples
- return fmt.Errorf("unsupported indexed type: %v", arg.Type)
- }
-
- topics = topics[1:]
- }
-
- return nil
-}
diff --git a/accounts/abi/bind/util.go b/accounts/abi/bind/util.go
deleted file mode 100644
index b3ec22c..0000000
--- a/accounts/abi/bind/util.go
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package bind
-
-import (
- "context"
- "fmt"
- "time"
-
- "github.com/ava-labs/coreth/core/types"
- "github.com/ava-labs/go-ethereum/common"
- "github.com/ava-labs/go-ethereum/log"
-)
-
-// WaitMined waits for tx to be mined on the blockchain.
-// It stops waiting when the context is canceled.
-func WaitMined(ctx context.Context, b DeployBackend, tx *types.Transaction) (*types.Receipt, error) {
- queryTicker := time.NewTicker(time.Second)
- defer queryTicker.Stop()
-
- logger := log.New("hash", tx.Hash())
- for {
- receipt, err := b.TransactionReceipt(ctx, tx.Hash())
- if receipt != nil {
- return receipt, nil
- }
- if err != nil {
- logger.Trace("Receipt retrieval failed", "err", err)
- } else {
- logger.Trace("Transaction not yet mined")
- }
- // Wait for the next round.
- select {
- case <-ctx.Done():
- return nil, ctx.Err()
- case <-queryTicker.C:
- }
- }
-}
-
-// WaitDeployed waits for a contract deployment transaction and returns the on-chain
-// contract address when it is mined. It stops waiting when ctx is canceled.
-func WaitDeployed(ctx context.Context, b DeployBackend, tx *types.Transaction) (common.Address, error) {
- if tx.To() != nil {
- return common.Address{}, fmt.Errorf("tx is not contract creation")
- }
- receipt, err := WaitMined(ctx, b, tx)
- if err != nil {
- return common.Address{}, err
- }
- if receipt.ContractAddress == (common.Address{}) {
- return common.Address{}, fmt.Errorf("zero address")
- }
- // Check that code has indeed been deployed at the address.
- // This matters on pre-Homestead chains: OOG in the constructor
- // could leave an empty account behind.
- code, err := b.CodeAt(ctx, receipt.ContractAddress, nil)
- if err == nil && len(code) == 0 {
- err = ErrNoCodeAfterDeploy
- }
- return receipt.ContractAddress, err
-}
diff --git a/accounts/abi/doc.go b/accounts/abi/doc.go
deleted file mode 100644
index 8242068..0000000
--- a/accounts/abi/doc.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-// Package abi implements the Ethereum ABI (Application Binary
-// Interface).
-//
-// The Ethereum ABI is strongly typed, known at compile time
-// and static. This ABI will handle basic type casting; unsigned
-// to signed and visa versa. It does not handle slice casting such
-// as unsigned slice to signed slice. Bit size type casting is also
-// handled. ints with a bit size of 32 will be properly cast to int256,
-// etc.
-package abi
diff --git a/accounts/abi/error.go b/accounts/abi/error.go
deleted file mode 100644
index 9d8674a..0000000
--- a/accounts/abi/error.go
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package abi
-
-import (
- "errors"
- "fmt"
- "reflect"
-)
-
-var (
- errBadBool = errors.New("abi: improperly encoded boolean value")
-)
-
-// formatSliceString formats the reflection kind with the given slice size
-// and returns a formatted string representation.
-func formatSliceString(kind reflect.Kind, sliceSize int) string {
- if sliceSize == -1 {
- return fmt.Sprintf("[]%v", kind)
- }
- return fmt.Sprintf("[%d]%v", sliceSize, kind)
-}
-
-// sliceTypeCheck checks that the given slice can by assigned to the reflection
-// type in t.
-func sliceTypeCheck(t Type, val reflect.Value) error {
- if val.Kind() != reflect.Slice && val.Kind() != reflect.Array {
- return typeErr(formatSliceString(t.Kind, t.Size), val.Type())
- }
-
- if t.T == ArrayTy && val.Len() != t.Size {
- return typeErr(formatSliceString(t.Elem.Kind, t.Size), formatSliceString(val.Type().Elem().Kind(), val.Len()))
- }
-
- if t.Elem.T == SliceTy {
- if val.Len() > 0 {
- return sliceTypeCheck(*t.Elem, val.Index(0))
- }
- } else if t.Elem.T == ArrayTy {
- return sliceTypeCheck(*t.Elem, val.Index(0))
- }
-
- if elemKind := val.Type().Elem().Kind(); elemKind != t.Elem.Kind {
- return typeErr(formatSliceString(t.Elem.Kind, t.Size), val.Type())
- }
- return nil
-}
-
-// typeCheck checks that the given reflection value can be assigned to the reflection
-// type in t.
-func typeCheck(t Type, value reflect.Value) error {
- if t.T == SliceTy || t.T == ArrayTy {
- return sliceTypeCheck(t, value)
- }
-
- // Check base type validity. Element types will be checked later on.
- if t.Kind != value.Kind() {
- return typeErr(t.Kind, value.Kind())
- } else if t.T == FixedBytesTy && t.Size != value.Len() {
- return typeErr(t.Type, value.Type())
- } else {
- return nil
- }
-
-}
-
-// typeErr returns a formatted type casting error.
-func typeErr(expected, got interface{}) error {
- return fmt.Errorf("abi: cannot use %v as type %v as argument", got, expected)
-}
diff --git a/accounts/abi/event.go b/accounts/abi/event.go
deleted file mode 100644
index 7a41baa..0000000
--- a/accounts/abi/event.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package abi
-
-import (
- "fmt"
- "strings"
-
- "github.com/ava-labs/go-ethereum/common"
- "github.com/ava-labs/go-ethereum/crypto"
-)
-
-// Event is an event potentially triggered by the EVM's LOG mechanism. The Event
-// holds type information (inputs) about the yielded output. Anonymous events
-// don't get the signature canonical representation as the first LOG topic.
-type Event struct {
- // Name is the event name used for internal representation. It's derived from
- // the raw name and a suffix will be added in the case of a event overload.
- //
- // e.g.
- // There are two events have same name:
- // * foo(int,int)
- // * foo(uint,uint)
- // The event name of the first one wll be resolved as foo while the second one
- // will be resolved as foo0.
- Name string
- // RawName is the raw event name parsed from ABI.
- RawName string
- Anonymous bool
- Inputs Arguments
-}
-
-func (e Event) String() string {
- inputs := make([]string, len(e.Inputs))
- for i, input := range e.Inputs {
- inputs[i] = fmt.Sprintf("%v %v", input.Type, input.Name)
- if input.Indexed {
- inputs[i] = fmt.Sprintf("%v indexed %v", input.Type, input.Name)
- }
- }
- return fmt.Sprintf("event %v(%v)", e.RawName, strings.Join(inputs, ", "))
-}
-
-// Sig returns the event string signature according to the ABI spec.
-//
-// Example
-//
-// event foo(uint32 a, int b) = "foo(uint32,int256)"
-//
-// Please note that "int" is substitute for its canonical representation "int256"
-func (e Event) Sig() string {
- types := make([]string, len(e.Inputs))
- for i, input := range e.Inputs {
- types[i] = input.Type.String()
- }
- return fmt.Sprintf("%v(%v)", e.RawName, strings.Join(types, ","))
-}
-
-// ID returns the canonical representation of the event's signature used by the
-// abi definition to identify event names and types.
-func (e Event) ID() common.Hash {
- return common.BytesToHash(crypto.Keccak256([]byte(e.Sig())))
-}
diff --git a/accounts/abi/method.go b/accounts/abi/method.go
deleted file mode 100644
index 9cceaba..0000000
--- a/accounts/abi/method.go
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package abi
-
-import (
- "fmt"
- "strings"
-
- "github.com/ava-labs/go-ethereum/crypto"
-)
-
-// Method represents a callable given a `Name` and whether the method is a constant.
-// If the method is `Const` no transaction needs to be created for this
-// particular Method call. It can easily be simulated using a local VM.
-// For example a `Balance()` method only needs to retrieve something
-// from the storage and therefore requires no Tx to be send to the
-// network. A method such as `Transact` does require a Tx and thus will
-// be flagged `false`.
-// Input specifies the required input parameters for this gives method.
-type Method struct {
- // Name is the method name used for internal representation. It's derived from
- // the raw name and a suffix will be added in the case of a function overload.
- //
- // e.g.
- // There are two functions have same name:
- // * foo(int,int)
- // * foo(uint,uint)
- // The method name of the first one will be resolved as foo while the second one
- // will be resolved as foo0.
- Name string
- // RawName is the raw method name parsed from ABI.
- RawName string
- Const bool
- Inputs Arguments
- Outputs Arguments
-}
-
-// Sig returns the methods string signature according to the ABI spec.
-//
-// Example
-//
-// function foo(uint32 a, int b) = "foo(uint32,int256)"
-//
-// Please note that "int" is substitute for its canonical representation "int256"
-func (method Method) Sig() string {
- types := make([]string, len(method.Inputs))
- for i, input := range method.Inputs {
- types[i] = input.Type.String()
- }
- return fmt.Sprintf("%v(%v)", method.RawName, strings.Join(types, ","))
-}
-
-func (method Method) String() string {
- inputs := make([]string, len(method.Inputs))
- for i, input := range method.Inputs {
- inputs[i] = fmt.Sprintf("%v %v", input.Type, input.Name)
- }
- outputs := make([]string, len(method.Outputs))
- for i, output := range method.Outputs {
- outputs[i] = output.Type.String()
- if len(output.Name) > 0 {
- outputs[i] += fmt.Sprintf(" %v", output.Name)
- }
- }
- constant := ""
- if method.Const {
- constant = "constant "
- }
- return fmt.Sprintf("function %v(%v) %sreturns(%v)", method.RawName, strings.Join(inputs, ", "), constant, strings.Join(outputs, ", "))
-}
-
-// ID returns the canonical representation of the method's signature used by the
-// abi definition to identify method names and types.
-func (method Method) ID() []byte {
- return crypto.Keccak256([]byte(method.Sig()))[:4]
-}
diff --git a/accounts/abi/numbers.go b/accounts/abi/numbers.go
deleted file mode 100644
index c2e844c..0000000
--- a/accounts/abi/numbers.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package abi
-
-import (
- "math/big"
- "reflect"
-
- "github.com/ava-labs/go-ethereum/common"
- "github.com/ava-labs/go-ethereum/common/math"
-)
-
-var (
- bigT = reflect.TypeOf(&big.Int{})
- derefbigT = reflect.TypeOf(big.Int{})
- uint8T = reflect.TypeOf(uint8(0))
- uint16T = reflect.TypeOf(uint16(0))
- uint32T = reflect.TypeOf(uint32(0))
- uint64T = reflect.TypeOf(uint64(0))
- int8T = reflect.TypeOf(int8(0))
- int16T = reflect.TypeOf(int16(0))
- int32T = reflect.TypeOf(int32(0))
- int64T = reflect.TypeOf(int64(0))
- addressT = reflect.TypeOf(common.Address{})
-)
-
-// U256 converts a big Int into a 256bit EVM number.
-func U256(n *big.Int) []byte {
- return math.PaddedBigBytes(math.U256(n), 32)
-}
diff --git a/accounts/abi/pack.go b/accounts/abi/pack.go
deleted file mode 100644
index d88dde8..0000000
--- a/accounts/abi/pack.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package abi
-
-import (
- "math/big"
- "reflect"
-
- "github.com/ava-labs/go-ethereum/common"
- "github.com/ava-labs/go-ethereum/common/math"
-)
-
-// packBytesSlice packs the given bytes as [L, V] as the canonical representation
-// bytes slice
-func packBytesSlice(bytes []byte, l int) []byte {
- len := packNum(reflect.ValueOf(l))
- return append(len, common.RightPadBytes(bytes, (l+31)/32*32)...)
-}
-
-// packElement packs the given reflect value according to the abi specification in
-// t.
-func packElement(t Type, reflectValue reflect.Value) []byte {
- switch t.T {
- case IntTy, UintTy:
- return packNum(reflectValue)
- case StringTy:
- return packBytesSlice([]byte(reflectValue.String()), reflectValue.Len())
- case AddressTy:
- if reflectValue.Kind() == reflect.Array {
- reflectValue = mustArrayToByteSlice(reflectValue)
- }
-
- return common.LeftPadBytes(reflectValue.Bytes(), 32)
- case BoolTy:
- if reflectValue.Bool() {
- return math.PaddedBigBytes(common.Big1, 32)
- }
- return math.PaddedBigBytes(common.Big0, 32)
- case BytesTy:
- if reflectValue.Kind() == reflect.Array {
- reflectValue = mustArrayToByteSlice(reflectValue)
- }
- return packBytesSlice(reflectValue.Bytes(), reflectValue.Len())
- case FixedBytesTy, FunctionTy:
- if reflectValue.Kind() == reflect.Array {
- reflectValue = mustArrayToByteSlice(reflectValue)
- }
- return common.RightPadBytes(reflectValue.Bytes(), 32)
- default:
- panic("abi: fatal error")
- }
-}
-
-// packNum packs the given number (using the reflect value) and will cast it to appropriate number representation
-func packNum(value reflect.Value) []byte {
- switch kind := value.Kind(); kind {
- case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
- return U256(new(big.Int).SetUint64(value.Uint()))
- case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- return U256(big.NewInt(value.Int()))
- case reflect.Ptr:
- return U256(value.Interface().(*big.Int))
- default:
- panic("abi: fatal error")
- }
-
-}
diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go
deleted file mode 100644
index 73ca8fa..0000000
--- a/accounts/abi/reflect.go
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package abi
-
-import (
- "fmt"
- "reflect"
- "strings"
-)
-
-// indirect recursively dereferences the value until it either gets the value
-// or finds a big.Int
-func indirect(v reflect.Value) reflect.Value {
- if v.Kind() == reflect.Ptr && v.Elem().Type() != derefbigT {
- return indirect(v.Elem())
- }
- return v
-}
-
-// indirectInterfaceOrPtr recursively dereferences the value until value is not interface.
-func indirectInterfaceOrPtr(v reflect.Value) reflect.Value {
- if (v.Kind() == reflect.Interface || v.Kind() == reflect.Ptr) && v.Elem().IsValid() {
- return indirect(v.Elem())
- }
- return v
-}
-
-// reflectIntKind returns the reflect using the given size and
-// unsignedness.
-func reflectIntKindAndType(unsigned bool, size int) (reflect.Kind, reflect.Type) {
- switch size {
- case 8:
- if unsigned {
- return reflect.Uint8, uint8T
- }
- return reflect.Int8, int8T
- case 16:
- if unsigned {
- return reflect.Uint16, uint16T
- }
- return reflect.Int16, int16T
- case 32:
- if unsigned {
- return reflect.Uint32, uint32T
- }
- return reflect.Int32, int32T
- case 64:
- if unsigned {
- return reflect.Uint64, uint64T
- }
- return reflect.Int64, int64T
- }
- return reflect.Ptr, bigT
-}
-
-// mustArrayToBytesSlice creates a new byte slice with the exact same size as value
-// and copies the bytes in value to the new slice.
-func mustArrayToByteSlice(value reflect.Value) reflect.Value {
- slice := reflect.MakeSlice(reflect.TypeOf([]byte{}), value.Len(), value.Len())
- reflect.Copy(slice, value)
- return slice
-}
-
-// set attempts to assign src to dst by either setting, copying or otherwise.
-//
-// set is a bit more lenient when it comes to assignment and doesn't force an as
-// strict ruleset as bare `reflect` does.
-func set(dst, src reflect.Value) error {
- dstType, srcType := dst.Type(), src.Type()
- switch {
- case dstType.Kind() == reflect.Interface && dst.Elem().IsValid():
- return set(dst.Elem(), src)
- case dstType.Kind() == reflect.Ptr && dstType.Elem() != derefbigT:
- return set(dst.Elem(), src)
- case srcType.AssignableTo(dstType) && dst.CanSet():
- dst.Set(src)
- case dstType.Kind() == reflect.Slice && srcType.Kind() == reflect.Slice:
- return setSlice(dst, src)
- default:
- return fmt.Errorf("abi: cannot unmarshal %v in to %v", src.Type(), dst.Type())
- }
- return nil
-}
-
-// setSlice attempts to assign src to dst when slices are not assignable by default
-// e.g. src: [][]byte -> dst: [][15]byte
-func setSlice(dst, src reflect.Value) error {
- slice := reflect.MakeSlice(dst.Type(), src.Len(), src.Len())
- for i := 0; i < src.Len(); i++ {
- v := src.Index(i)
- reflect.Copy(slice.Index(i), v)
- }
-
- dst.Set(slice)
- return nil
-}
-
-// requireAssignable assures that `dest` is a pointer and it's not an interface.
-func requireAssignable(dst, src reflect.Value) error {
- if dst.Kind() != reflect.Ptr && dst.Kind() != reflect.Interface {
- return fmt.Errorf("abi: cannot unmarshal %v into %v", src.Type(), dst.Type())
- }
- return nil
-}
-
-// requireUnpackKind verifies preconditions for unpacking `args` into `kind`
-func requireUnpackKind(v reflect.Value, t reflect.Type, k reflect.Kind,
- args Arguments) error {
-
- switch k {
- case reflect.Struct:
- case reflect.Slice, reflect.Array:
- if minLen := args.LengthNonIndexed(); v.Len() < minLen {
- return fmt.Errorf("abi: insufficient number of elements in the list/array for unpack, want %d, got %d",
- minLen, v.Len())
- }
- default:
- return fmt.Errorf("abi: cannot unmarshal tuple into %v", t)
- }
- return nil
-}
-
-// mapArgNamesToStructFields maps a slice of argument names to struct fields.
-// first round: for each Exportable field that contains a `abi:""` tag
-// and this field name exists in the given argument name list, pair them together.
-// second round: for each argument name that has not been already linked,
-// find what variable is expected to be mapped into, if it exists and has not been
-// used, pair them.
-// Note this function assumes the given value is a struct value.
-func mapArgNamesToStructFields(argNames []string, value reflect.Value) (map[string]string, error) {
- typ := value.Type()
-
- abi2struct := make(map[string]string)
- struct2abi := make(map[string]string)
-
- // first round ~~~
- for i := 0; i < typ.NumField(); i++ {
- structFieldName := typ.Field(i).Name
-
- // skip private struct fields.
- if structFieldName[:1] != strings.ToUpper(structFieldName[:1]) {
- continue
- }
- // skip fields that have no abi:"" tag.
- var ok bool
- var tagName string
- if tagName, ok = typ.Field(i).Tag.Lookup("abi"); !ok {
- continue
- }
- // check if tag is empty.
- if tagName == "" {
- return nil, fmt.Errorf("struct: abi tag in '%s' is empty", structFieldName)
- }
- // check which argument field matches with the abi tag.
- found := false
- for _, arg := range argNames {
- if arg == tagName {
- if abi2struct[arg] != "" {
- return nil, fmt.Errorf("struct: abi tag in '%s' already mapped", structFieldName)
- }
- // pair them
- abi2struct[arg] = structFieldName
- struct2abi[structFieldName] = arg
- found = true
- }
- }
- // check if this tag has been mapped.
- if !found {
- return nil, fmt.Errorf("struct: abi tag '%s' defined but not found in abi", tagName)
- }
- }
-
- // second round ~~~
- for _, argName := range argNames {
-
- structFieldName := ToCamelCase(argName)
-
- if structFieldName == "" {
- return nil, fmt.Errorf("abi: purely underscored output cannot unpack to struct")
- }
-
- // this abi has already been paired, skip it... unless there exists another, yet unassigned
- // struct field with the same field name. If so, raise an error:
- // abi: [ { "name": "value" } ]
- // struct { Value *big.Int , Value1 *big.Int `abi:"value"`}
- if abi2struct[argName] != "" {
- if abi2struct[argName] != structFieldName &&
- struct2abi[structFieldName] == "" &&
- value.FieldByName(structFieldName).IsValid() {
- return nil, fmt.Errorf("abi: multiple variables maps to the same abi field '%s'", argName)
- }
- continue
- }
-
- // return an error if this struct field has already been paired.
- if struct2abi[structFieldName] != "" {
- return nil, fmt.Errorf("abi: multiple outputs mapping to the same struct field '%s'", structFieldName)
- }
-
- if value.FieldByName(structFieldName).IsValid() {
- // pair them
- abi2struct[argName] = structFieldName
- struct2abi[structFieldName] = argName
- } else {
- // not paired, but annotate as used, to detect cases like
- // abi : [ { "name": "value" }, { "name": "_value" } ]
- // struct { Value *big.Int }
- struct2abi[structFieldName] = argName
- }
- }
- return abi2struct, nil
-}
diff --git a/accounts/abi/type.go b/accounts/abi/type.go
deleted file mode 100644
index 597d314..0000000
--- a/accounts/abi/type.go
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright 2015 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package abi
-
-import (
- "errors"
- "fmt"
- "reflect"
- "regexp"
- "strconv"
- "strings"
-)
-
-// Type enumerator
-const (
- IntTy byte = iota
- UintTy
- BoolTy
- StringTy
- SliceTy
- ArrayTy
- TupleTy
- AddressTy
- FixedBytesTy
- BytesTy
- HashTy
- FixedPointTy
- FunctionTy
-)
-
-// Type is the reflection of the supported argument type
-type Type struct {
- Elem *Type
- Kind reflect.Kind
- Type reflect.Type
- Size int
- T byte // Our own type checking
-
- stringKind string // holds the unparsed string for deriving signatures
-
- // Tuple relative fields
- TupleElems []*Type // Type information of all tuple fields
- TupleRawNames []string // Raw field name of all tuple fields
-}
-
-var (
- // typeRegex parses the abi sub types
- typeRegex = regexp.MustCompile("([a-zA-Z]+)(([0-9]+)(x([0-9]+))?)?")
-)
-
-// NewType creates a new reflection type of abi type given in t.
-func NewType(t string, components []ArgumentMarshaling) (typ Type, err error) {
- // check that array brackets are equal if they exist
- if strings.Count(t, "[") != strings.Count(t, "]") {
- return Type{}, fmt.Errorf("invalid arg type in abi")
- }
- typ.stringKind = t
-
- // if there are brackets, get ready to go into slice/array mode and
- // recursively create the type
- if strings.Count(t, "[") != 0 {
- i := strings.LastIndex(t, "[")
- // recursively embed the type
- embeddedType, err := NewType(t[:i], components)
- if err != nil {
- return Type{}, err
- }
- // grab the last cell and create a type from there
- sliced := t[i:]
- // grab the slice size with regexp
- re := regexp.MustCompile("[0-9]+")
- intz := re.FindAllString(sliced, -1)
-
- if len(intz) == 0 {
- // is a slice
- typ.T = SliceTy
- typ.Kind = reflect.Slice
- typ.Elem = &embeddedType
- typ.Type = reflect.SliceOf(embeddedType.Type)
- typ.stringKind = embeddedType.stringKind + sliced
- } else if len(intz) == 1 {
- // is a array
- typ.T = ArrayTy
- typ.Kind = reflect.Array
- typ.Elem = &embeddedType
- typ.Size, err = strconv.Atoi(intz[0])
- if err != nil {
- return Type{}, fmt.Errorf("abi: error parsing variable size: %v", err)
- }
- typ.Type = reflect.ArrayOf(typ.Size, embeddedType.Type)
- typ.stringKind = embeddedType.stringKind + sliced
- } else {
- return Type{}, fmt.Errorf("invalid formatting of array type")
- }
- return typ, err
- }
- // parse the type and size of the abi-type.
- matches := typeRegex.FindAllStringSubmatch(t, -1)
- if len(matches) == 0 {
- return Type{}, fmt.Errorf("invalid type '%v'", t)
- }
- parsedType := matches[0]
-
- // varSize is the size of the variable
- var varSize int
- if len(parsedType[3]) > 0 {
- var err error
- varSize, err = strconv.Atoi(parsedType[2])
- if err != nil {
- return Type{}, fmt.Errorf("abi: error parsing variable size: %v", err)
- }
- } else {
- if parsedType[0] == "uint" || parsedType[0] == "int" {
- // this should fail because it means that there's something wrong with
- // the abi type (the compiler should always format it to the size...always)
- return Type{}, fmt.Errorf("unsupported arg type: %s", t)
- }
- }
- // varType is the parsed abi type
- switch varType := parsedType[1]; varType {
- case "int":
- typ.Kind, typ.Type = reflectIntKindAndType(false, varSize)
- typ.Size = varSize
- typ.T = IntTy
- case "uint":
- typ.Kind, typ.Type = reflectIntKindAndType(true, varSize)
- typ.Size = varSize
- typ.T = UintTy
- case "bool":
- typ.Kind = reflect.Bool
- typ.T = BoolTy
- typ.Type = reflect.TypeOf(bool(false))
- case "address":
- typ.Kind = reflect.Array
- typ.Type = addressT
- typ.Size = 20
- typ.T = AddressTy
- case "string":
- typ.Kind = reflect.String
- typ.Type = reflect.TypeOf("")
- typ.T = StringTy
- case "bytes":
- if varSize == 0 {
- typ.T = BytesTy
- typ.Kind = reflect.Slice
- typ.Type = reflect.SliceOf(reflect.TypeOf(byte(0)))
- } else {
- typ.T = FixedBytesTy
- typ.Kind = reflect.Array
- typ.Size = varSize
- typ.Type = reflect.ArrayOf(varSize, reflect.TypeOf(byte(0)))
- }
- case "tuple":
- var (
- fields []reflect.StructField
- elems []*Type
- names []string
- expression string // canonical parameter expression
- )
- expression += "("
- for idx, c := range components {
- cType, err := NewType(c.Type, c.Components)
- if err != nil {
- return Type{}, err
- }
- if ToCamelCase(c.Name) == "" {
- return Type{}, errors.New("abi: purely anonymous or underscored field is not supported")
- }
- fields = append(fields, reflect.StructField{
- Name: ToCamelCase(c.Name), // reflect.StructOf will panic for any exported field.
- Type: cType.Type,
- Tag: reflect.StructTag("json:\"" + c.Name + "\""),
- })
- elems = append(elems, &cType)
- names = append(names, c.Name)
- expression += cType.stringKind
- if idx != len(components)-1 {
- expression += ","
- }
- }
- expression += ")"
- typ.Kind = reflect.Struct
- typ.Type = reflect.StructOf(fields)
- typ.TupleElems = elems
- typ.TupleRawNames = names
- typ.T = TupleTy
- typ.stringKind = expression
- case "function":
- typ.Kind = reflect.Array
- typ.T = FunctionTy
- typ.Size = 24
- typ.Type = reflect.ArrayOf(24, reflect.TypeOf(byte(0)))
- default:
- return Type{}, fmt.Errorf("unsupported arg type: %s", t)
- }
-
- return
-}
-
-// String implements Stringer
-func (t Type) String() (out string) {
- return t.stringKind
-}
-
-func (t Type) pack(v reflect.Value) ([]byte, error) {
- // dereference pointer first if it's a pointer
- v = indirect(v)
- if err := typeCheck(t, v); err != nil {
- return nil, err
- }
-
- switch t.T {
- case SliceTy, ArrayTy:
- var ret []byte
-
- if t.requiresLengthPrefix() {
- // append length
- ret = append(ret, packNum(reflect.ValueOf(v.Len()))...)
- }
-
- // calculate offset if any
- offset := 0
- offsetReq := isDynamicType(*t.Elem)
- if offsetReq {
- offset = getTypeSize(*t.Elem) * v.Len()
- }
- var tail []byte
- for i := 0; i < v.Len(); i++ {
- val, err := t.Elem.pack(v.Index(i))
- if err != nil {
- return nil, err
- }
- if !offsetReq {
- ret = append(ret, val...)
- continue
- }
- ret = append(ret, packNum(reflect.ValueOf(offset))...)
- offset += len(val)
- tail = append(tail, val...)
- }
- return append(ret, tail...), nil
- case TupleTy:
- // (T1,...,Tk) for k >= 0 and any types T1, …, Tk
- // enc(X) = head(X(1)) ... head(X(k)) tail(X(1)) ... tail(X(k))
- // where X = (X(1), ..., X(k)) and head and tail are defined for Ti being a static
- // type as
- // head(X(i)) = enc(X(i)) and tail(X(i)) = "" (the empty string)
- // and as
- // head(X(i)) = enc(len(head(X(1)) ... head(X(k)) tail(X(1)) ... tail(X(i-1))))
- // tail(X(i)) = enc(X(i))
- // otherwise, i.e. if Ti is a dynamic type.
- fieldmap, err := mapArgNamesToStructFields(t.TupleRawNames, v)
- if err != nil {
- return nil, err
- }
- // Calculate prefix occupied size.
- offset := 0
- for _, elem := range t.TupleElems {
- offset += getTypeSize(*elem)
- }
- var ret, tail []byte
- for i, elem := range t.TupleElems {
- field := v.FieldByName(fieldmap[t.TupleRawNames[i]])
- if !field.IsValid() {
- return nil, fmt.Errorf("field %s for tuple not found in the given struct", t.TupleRawNames[i])
- }
- val, err := elem.pack(field)
- if err != nil {
- return nil, err
- }
- if isDynamicType(*elem) {
- ret = append(ret, packNum(reflect.ValueOf(offset))...)
- tail = append(tail, val...)
- offset += len(val)
- } else {
- ret = append(ret, val...)
- }
- }
- return append(ret, tail...), nil
-
- default:
- return packElement(t, v), nil
- }
-}
-
-// requireLengthPrefix returns whether the type requires any sort of length
-// prefixing.
-func (t Type) requiresLengthPrefix() bool {
- return t.T == StringTy || t.T == BytesTy || t.T == SliceTy
-}
-
-// isDynamicType returns true if the type is dynamic.
-// The following types are called “dynamic”:
-// * bytes
-// * string
-// * T[] for any T
-// * T[k] for any dynamic T and any k >= 0
-// * (T1,...,Tk) if Ti is dynamic for some 1 <= i <= k
-func isDynamicType(t Type) bool {
- if t.T == TupleTy {
- for _, elem := range t.TupleElems {
- if isDynamicType(*elem) {
- return true
- }
- }
- return false
- }
- return t.T == StringTy || t.T == BytesTy || t.T == SliceTy || (t.T == ArrayTy && isDynamicType(*t.Elem))
-}
-
-// getTypeSize returns the size that this type needs to occupy.
-// We distinguish static and dynamic types. Static types are encoded in-place
-// and dynamic types are encoded at a separately allocated location after the
-// current block.
-// So for a static variable, the size returned represents the size that the
-// variable actually occupies.
-// For a dynamic variable, the returned size is fixed 32 bytes, which is used
-// to store the location reference for actual value storage.
-func getTypeSize(t Type) int {
- if t.T == ArrayTy && !isDynamicType(*t.Elem) {
- // Recursively calculate type size if it is a nested array
- if t.Elem.T == ArrayTy {
- return t.Size * getTypeSize(*t.Elem)
- }
- return t.Size * 32
- } else if t.T == TupleTy && !isDynamicType(t) {
- total := 0
- for _, elem := range t.TupleElems {
- total += getTypeSize(*elem)
- }
- return total
- }
- return 32
-}
diff --git a/accounts/abi/unpack.go b/accounts/abi/unpack.go
deleted file mode 100644
index d3cd310..0000000
--- a/accounts/abi/unpack.go
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright 2017 The go-ethereum Authors
-// This file is part of the go-ethereum library.
-//
-// The go-ethereum library is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Lesser General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// The go-ethereum library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
-
-package abi
-
-import (
- "encoding/binary"
- "fmt"
- "math/big"
- "reflect"
-
- "github.com/ava-labs/go-ethereum/common"
-)
-
-var (
- maxUint256 = big.NewInt(0).Add(
- big.NewInt(0).Exp(big.NewInt(2), big.NewInt(256), nil),
- big.NewInt(-1))
- maxInt256 = big.NewInt(0).Add(
- big.NewInt(0).Exp(big.NewInt(2), big.NewInt(255), nil),
- big.NewInt(-1))
-)
-
-// reads the integer based on its kind
-func readInteger(typ byte, kind reflect.Kind, b []byte) interface{} {
- switch kind {
- case reflect.Uint8:
- return b[len(b)-1]
- case reflect.Uint16:
- return binary.BigEndian.Uint16(b[len(b)-2:])
- case reflect.Uint32:
- return binary.BigEndian.Uint32(b[len(b)-4:])
- case reflect.Uint64:
- return binary.BigEndian.Uint64(b[len(b)-8:])
- case reflect.Int8:
- return int8(b[len(b)-1])
- case reflect.Int16:
- return int16(binary.BigEndian.Uint16(b[len(b)-2:]))
- case reflect.Int32:
- return int32(binary.BigEndian.Uint32(b[len(b)-4:]))
- case reflect.Int64:
- return int64(binary.BigEndian.Uint64(b[len(b)-8:]))
- default:
- // the only case lefts for integer is int256/uint256.
- // big.SetBytes can't tell if a number is negative, positive on itself.
- // On EVM, if the returned number > max int256, it is negative.
- ret := new(big.Int).SetBytes(b)
- if typ == UintTy {
- return ret
- }
-
- if ret.Cmp(maxInt256) > 0 {
- ret.Add(maxUint256, big.NewInt(0).Neg(ret))
- ret.Add(ret, big.NewInt(1))
- ret.Neg(ret)
- }
- return ret
- }
-}
-
-// reads a bool
-func readBool(word []byte) (bool, error) {
- for _, b := range word[:31] {
- if b != 0 {
- return false, errBadBool
- }
- }
- switch word[31] {
- case 0:
- return false, nil
- case 1:
- return true, nil
- default:
- return false, errBadBool
- }
-}
-
-// A function type is simply the address with the function selection signature at the end.
-// This enforces that standard by always presenting it as a 24-array (address + sig = 24 bytes)
-func readFunctionType(t Type, word []byte) (funcTy [24]byte, err error) {
- if t.T != FunctionTy {
- return [24]byte{}, fmt.Errorf("abi: invalid type in call to make function type byte array")
- }
- if garbage := binary.BigEndian.Uint64(word[24:32]); garbage != 0 {
- err = fmt.Errorf("abi: got improperly encoded function type, got %v", word)
- } else {
- copy(funcTy[:], word[0:24])
- }
- return
-}
-
-// through reflection, creates a fixed array to be read from
-func readFixedBytes(t Type, word []byte) (interface{}, error) {
- if t.T != FixedBytesTy {
- return nil, fmt.Errorf("abi: invalid type in call to make fixed byte array")
- }
- // convert
- array := reflect.New(t.Type).Elem()
-
- reflect.Copy(array, reflect.ValueOf(word[0:t.Size]))
- return array.Interface(), nil
-
-}
-
-// iteratively unpack elements
-func forEachUnpack(t Type, output []byte, start, size int) (interface{}, error) {
- if size < 0 {
- return nil, fmt.Errorf("cannot marshal input to array, size is negative (%d)", size)
- }
- if start+32*size > len(output) {
- return nil, fmt.Errorf("abi: cannot marshal in to go array: offset %d would go over slice boundary (len=%d)", len(output), start+32*size)
- }
-
- // this value will become our slice or our array, depending on the type
- var refSlice reflect.Value
-
- if t.T == SliceTy {
- // declare our slice
- refSlice = reflect.MakeSlice(t.Type, size, size)
- } else if t.T == ArrayTy {
- // declare our array
- refSlice = reflect.New(t.Type).Elem()
- } else {
- return nil, fmt.Errorf("abi: invalid type in array/slice unpacking stage")
- }
-
- // Arrays have packed elements, resulting in longer unpack steps.
- // Slices have just 32 bytes per element (pointing to the contents).
- elemSize := getTypeSize(*t.Elem)
-
- for i, j := start, 0; j < size; i, j = i+elemSize, j+1 {
- inter, err := toGoType(i, *t.Elem, output)
- if err != nil {
- return nil, err
- }
-
- // append the item to our reflect slice
- refSlice.Index(j).Set(reflect.ValueOf(inter))
- }
-
- // return the interface
- return refSlice.Interface(), nil
-}
-
-func forTupleUnpack(t Type, output []byte) (interface{}, error) {
- retval := reflect.New(t.Type).Elem()
- virtualArgs := 0
- for index, elem := range t.TupleElems {
- marshalledValue, err := toGoType((index+virtualArgs)*32, *elem, output)
- if elem.T == ArrayTy && !isDynamicType(*elem) {
- // If we have a static array, like [3]uint256, these are coded as
- // just like uint256,uint256,uint256.
- // This means that we need to add two 'virtual' arguments when
- // we count the index from now on.
- //
- // Array values nested multiple levels deep are also encoded inline:
- // [2][3]uint256: uint256,uint256,uint256,uint256,uint256,uint256
- //
- // Calculate the full array size to get the correct offset for the next argument.
- // Decrement it by 1, as the normal index increment is still applied.
- virtualArgs += getTypeSize(*elem)/32 - 1
- } else if elem.T == TupleTy && !isDynamicType(*elem) {
- // If we have a static tuple, like (uint256, bool, uint256), these are
- // coded as just like uint256,bool,uint256
- virtualArgs += getTypeSize(*elem)/32 - 1
- }
- if err != nil {
- return nil, err
- }
- retval.Field(index).Set(reflect.ValueOf(marshalledValue))
- }
- return retval.Interface(), nil
-}
-
-// toGoType parses the output bytes and recursively assigns the value of these bytes
-// into a go type with accordance with the ABI spec.
-func toGoType(index int, t Type, output []byte) (interface{}, error) {
- if index+32 > len(output) {
- return nil, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %d require %d", len(output), index+32)
- }
-
- var (
- returnOutput []byte
- begin, length int
- err error
- )
-
- // if we require a length prefix, find the beginning word and size returned.
- if t.requiresLengthPrefix() {
- begin, length, err = lengthPrefixPointsTo(index, output)
- if err != nil {
- return nil, err
- }
- } else {
- returnOutput = output[index : index+32]
- }
-
- switch t.T {
- case TupleTy:
- if isDynamicType(t) {
- begin, err := tuplePointsTo(index, output)
- if err != nil {
- return nil, err
- }
- return forTupleUnpack(t, output[begin:])
- } else {
- return forTupleUnpack(t, output[index:])
- }
- case SliceTy:
- return forEachUnpack(t, output[begin:], 0, length)
- case ArrayTy:
- if isDynamicType(*t.Elem) {
- offset := int64(binary.BigEndian.Uint64(returnOutput[len(returnOutput)-8:]))
- return forEachUnpack(t, output[offset:], 0, t.Size)
- }
- return forEachUnpack(t, output[index:], 0, t.Size)
- case StringTy: // variable arrays are written at the end of the return bytes
- return string(output[begin : begin+length]), nil
- case IntTy, UintTy:
- return readInteger(t.T, t.Kind, returnOutput), nil
- case BoolTy:
- return readBool(returnOutput)
- case AddressTy:
- return common.BytesToAddress(returnOutput), nil
- case HashTy:
- return common.BytesToHash(returnOutput), nil
- case BytesTy:
- return output[begin : begin+length], nil
- case FixedBytesTy:
- return readFixedBytes(t, returnOutput)
- case FunctionTy:
- return readFunctionType(t, returnOutput)
- default:
- return nil, fmt.Errorf("abi: unknown type %v", t.T)
- }
-}
-
-// interprets a 32 byte slice as an offset and then determines which indice to look to decode the type.
-func lengthPrefixPointsTo(index int, output []byte) (start int, length int, err error) {
- bigOffsetEnd := big.NewInt(0).SetBytes(output[index : index+32])
- bigOffsetEnd.Add(bigOffsetEnd, common.Big32)
- outputLength := big.NewInt(int64(len(output)))
-
- if bigOffsetEnd.Cmp(outputLength) > 0 {
- return 0, 0, fmt.Errorf("abi: cannot marshal in to go slice: offset %v would go over slice boundary (len=%v)", bigOffsetEnd, outputLength)
- }
-
- if bigOffsetEnd.BitLen() > 63 {
- return 0, 0, fmt.Errorf("abi offset larger than int64: %v", bigOffsetEnd)
- }
-
- offsetEnd := int(bigOffsetEnd.Uint64())
- lengthBig := big.NewInt(0).SetBytes(output[offsetEnd-32 : offsetEnd])
-
- totalSize := big.NewInt(0)
- totalSize.Add(totalSize, bigOffsetEnd)
- totalSize.Add(totalSize, lengthBig)
- if totalSize.BitLen() > 63 {
- return 0, 0, fmt.Errorf("abi: length larger than int64: %v", totalSize)
- }
-
- if totalSize.Cmp(outputLength) > 0 {
- return 0, 0, fmt.Errorf("abi: cannot marshal in to go type: length insufficient %v require %v", outputLength, totalSize)
- }
- start = int(bigOffsetEnd.Uint64())
- length = int(lengthBig.Uint64())
- return
-}
-
-// tuplePointsTo resolves the location reference for dynamic tuple.
-func tuplePointsTo(index int, output []byte) (start int, err error) {
- offset := big.NewInt(0).SetBytes(output[index : index+32])
- outputLen := big.NewInt(int64(len(output)))
-
- if offset.Cmp(big.NewInt(int64(len(output)))) > 0 {
- return 0, fmt.Errorf("abi: cannot marshal in to go slice: offset %v would go over slice boundary (len=%v)", offset, outputLen)
- }
- if offset.BitLen() > 63 {
- return 0, fmt.Errorf("abi offset larger than int64: %v", offset)
- }
- return int(offset.Uint64()), nil
-}
diff --git a/accounts/accounts.go b/accounts/accounts.go
index bca3223..2f39684 100644
--- a/accounts/accounts.go
+++ b/accounts/accounts.go
@@ -23,6 +23,7 @@ import (
"github.com/ava-labs/coreth/core/types"
ethereum "github.com/ava-labs/go-ethereum"
+ gethaccounts "github.com/ava-labs/go-ethereum/accounts"
"github.com/ava-labs/go-ethereum/common"
"github.com/ava-labs/go-ethereum/event"
"golang.org/x/crypto/sha3"
@@ -129,6 +130,8 @@ type Wallet interface {
// about which fields or actions are needed. The user may retry by providing
// the needed details via SignHashWithPassphrase, or by other means (e.g. unlock
// the account in a keystore).
+ //
+ // This method should return the signature in 'canonical' format, with v 0 or 1
SignText(account Account, text []byte) ([]byte, error)
// SignTextWithPassphrase is identical to Signtext, but also takes a password
@@ -199,7 +202,7 @@ func TextAndHash(data []byte) ([]byte, string) {
// WalletEventType represents the different event types that can be fired by
// the wallet subscription subsystem.
-type WalletEventType int
+type WalletEventType = gethaccounts.WalletEventType
const (
// WalletArrived is fired when a new wallet is detected either via USB or via
diff --git a/accounts/external/backend.go b/accounts/external/backend.go
index 16e201d..41329d3 100644
--- a/accounts/external/backend.go
+++ b/accounts/external/backend.go
@@ -23,13 +23,12 @@ import (
"github.com/ava-labs/coreth/accounts"
"github.com/ava-labs/coreth/core/types"
- "github.com/ava-labs/coreth/internal/ethapi"
- "github.com/ava-labs/coreth/rpc"
"github.com/ava-labs/go-ethereum"
"github.com/ava-labs/go-ethereum/common"
"github.com/ava-labs/go-ethereum/common/hexutil"
"github.com/ava-labs/go-ethereum/event"
"github.com/ava-labs/go-ethereum/log"
+ "github.com/ava-labs/go-ethereum/rpc"
"github.com/ava-labs/go-ethereum/signer/core"
)
@@ -131,6 +130,12 @@ func (api *ExternalSigner) Accounts() []accounts.Account {
func (api *ExternalSigner) Contains(account accounts.Account) bool {
api.cacheMu.RLock()
defer api.cacheMu.RUnlock()
+ if api.cache == nil {
+ // If we haven't already fetched the accounts, it's time to do so now
+ api.cacheMu.RUnlock()
+ api.Accounts()
+ api.cacheMu.RLock()
+ }
for _, a := range api.cache {
if a.Address == account.Address && (account.URL == (accounts.URL{}) || account.URL == api.URL()) {
return true
@@ -161,7 +166,7 @@ func (api *ExternalSigner) SignData(account accounts.Account, mimeType string, d
hexutil.Encode(data)); err != nil {
return nil, err
}
- // If V is on 27/28-form, convert to to 0/1 for Clique
+ // If V is on 27/28-form, convert to 0/1 for Clique
if mimeType == accounts.MimetypeClique && (res[64] == 27 || res[64] == 28) {
res[64] -= 27 // Transform V from 27/28 to 0/1 for Clique use
}
@@ -169,19 +174,29 @@ func (api *ExternalSigner) SignData(account accounts.Account, mimeType string, d
}
func (api *ExternalSigner) SignText(account accounts.Account, text []byte) ([]byte, error) {
- var res hexutil.Bytes
+ var signature hexutil.Bytes
var signAddress = common.NewMixedcaseAddress(account.Address)
- if err := api.client.Call(&res, "account_signData",
+ if err := api.client.Call(&signature, "account_signData",
accounts.MimetypeTextPlain,
&signAddress, // Need to use the pointer here, because of how MarshalJSON is defined
hexutil.Encode(text)); err != nil {
return nil, err
}
- return res, nil
+ if signature[64] == 27 || signature[64] == 28 {
+ // If clef is used as a backend, it may already have transformed
+ // the signature to ethereum-type signature.
+ signature[64] -= 27 // Transform V from Ethereum-legacy to 0/1
+ }
+ return signature, nil
+}
+
+// signTransactionResult represents the signinig result returned by clef.
+type signTransactionResult struct {
+ Raw hexutil.Bytes `json:"raw"`
+ Tx *types.Transaction `json:"tx"`
}
func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
- res := ethapi.SignTransactionResult{}
data := hexutil.Bytes(tx.Data())
var to *common.MixedcaseAddress
if tx.To() != nil {
@@ -197,6 +212,7 @@ func (api *ExternalSigner) SignTx(account accounts.Account, tx *types.Transactio
To: to,
From: common.NewMixedcaseAddress(account.Address),
}
+ var res signTransactionResult
if err := api.client.Call(&res, "account_signTransaction", args); err != nil {
return nil, err
}
diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go
index a3ce33f..1bcaf13 100644
--- a/accounts/keystore/keystore.go
+++ b/accounts/keystore/keystore.go
@@ -24,7 +24,6 @@ import (
"crypto/ecdsa"
crand "crypto/rand"
"errors"
- "fmt"
"math/big"
"os"
"path/filepath"
@@ -44,6 +43,10 @@ var (
ErrLocked = accounts.NewAuthNeededError("password or unlock")
ErrNoMatch = errors.New("no key for given address or file")
ErrDecrypt = errors.New("could not decrypt key with given password")
+
+ // ErrAccountAlreadyExists is returned if an account attempted to import is
+ // already present in the keystore.
+ ErrAccountAlreadyExists = errors.New("account already exists")
)
// KeyStoreType is the reflect type of a keystore backend.
@@ -67,7 +70,8 @@ type KeyStore struct {
updateScope event.SubscriptionScope // Subscription scope tracking current live listeners
updating bool // Whether the event notification loop is running
- mu sync.RWMutex
+ mu sync.RWMutex
+ importMu sync.Mutex // Import Mutex locks the import to prevent two insertions from racing
}
type unlocked struct {
@@ -443,14 +447,27 @@ func (ks *KeyStore) Import(keyJSON []byte, passphrase, newPassphrase string) (ac
if err != nil {
return accounts.Account{}, err
}
+ ks.importMu.Lock()
+ defer ks.importMu.Unlock()
+
+ if ks.cache.hasAddress(key.Address) {
+ return accounts.Account{
+ Address: key.Address,
+ }, ErrAccountAlreadyExists
+ }
return ks.importKey(key, newPassphrase)
}
// ImportECDSA stores the given key into the key directory, encrypting it with the passphrase.
func (ks *KeyStore) ImportECDSA(priv *ecdsa.PrivateKey, passphrase string) (accounts.Account, error) {
+ ks.importMu.Lock()
+ defer ks.importMu.Unlock()
+
key := newKeyFromECDSA(priv)
if ks.cache.hasAddress(key.Address) {
- return accounts.Account{}, fmt.Errorf("account already exists")
+ return accounts.Account{
+ Address: key.Address,
+ }, ErrAccountAlreadyExists
}
return ks.importKey(key, passphrase)
}
diff --git a/accounts/keystore/passphrase.go b/accounts/keystore/passphrase.go
index fa5a09d..04f31ff 100644
--- a/accounts/keystore/passphrase.go
+++ b/accounts/keystore/passphrase.go
@@ -121,8 +121,9 @@ func (ks keyStorePassphrase) StoreKey(filename string, key *Key, auth string) er
"This indicates that the keystore is corrupted. \n" +
"The corrupted file is stored at \n%v\n" +
"Please file a ticket at:\n\n" +
- "https://github.com/ethereum/go-ethereum/issues." +
+ "https://github.com/ava-labs/go-ethereum/issues." +
"The error was : %s"
+ //lint:ignore ST1005 This is a message for the user
return fmt.Errorf(msg, tmpName, err)
}
}
@@ -237,7 +238,7 @@ func DecryptKey(keyjson []byte, auth string) (*Key, error) {
func DecryptDataV3(cryptoJson CryptoJSON, auth string) ([]byte, error) {
if cryptoJson.Cipher != "aes-128-ctr" {
- return nil, fmt.Errorf("Cipher not supported: %v", cryptoJson.Cipher)
+ return nil, fmt.Errorf("cipher not supported: %v", cryptoJson.Cipher)
}
mac, err := hex.DecodeString(cryptoJson.MAC)
if err != nil {
@@ -273,7 +274,7 @@ func DecryptDataV3(cryptoJson CryptoJSON, auth string) ([]byte, error) {
func decryptKeyV3(keyProtected *encryptedKeyJSONV3, auth string) (keyBytes []byte, keyId []byte, err error) {
if keyProtected.Version != version {
- return nil, nil, fmt.Errorf("Version not supported: %v", keyProtected.Version)
+ return nil, nil, fmt.Errorf("version not supported: %v", keyProtected.Version)
}
keyId = uuid.Parse(keyProtected.Id)
plainText, err := DecryptDataV3(keyProtected.Crypto, auth)
@@ -335,13 +336,13 @@ func getKDFKey(cryptoJSON CryptoJSON, auth string) ([]byte, error) {
c := ensureInt(cryptoJSON.KDFParams["c"])
prf := cryptoJSON.KDFParams["prf"].(string)
if prf != "hmac-sha256" {
- return nil, fmt.Errorf("Unsupported PBKDF2 PRF: %s", prf)
+ return nil, fmt.Errorf("unsupported PBKDF2 PRF: %s", prf)
}
key := pbkdf2.Key(authArray, salt, c, dkLen, sha256.New)
return key, nil
}
- return nil, fmt.Errorf("Unsupported KDF: %s", cryptoJSON.KDF)
+ return nil, fmt.Errorf("unsupported KDF: %s", cryptoJSON.KDF)
}
// TODO: can we do without this when unmarshalling dynamic JSON?
diff --git a/accounts/manager.go b/accounts/manager.go
index 39211da..87d3df8 100644
--- a/accounts/manager.go
+++ b/accounts/manager.go
@@ -141,6 +141,11 @@ func (am *Manager) Wallets() []Wallet {
am.lock.RLock()
defer am.lock.RUnlock()
+ return am.walletsNoLock()
+}
+
+// walletsNoLock returns all registered wallets. Callers must hold am.lock.
+func (am *Manager) walletsNoLock() []Wallet {
cpy := make([]Wallet, len(am.wallets))
copy(cpy, am.wallets)
return cpy
@@ -155,7 +160,7 @@ func (am *Manager) Wallet(url string) (Wallet, error) {
if err != nil {
return nil, err
}
- for _, wallet := range am.Wallets() {
+ for _, wallet := range am.walletsNoLock() {
if wallet.URL() == parsed {
return wallet, nil
}
diff --git a/accounts/scwallet/hub.go b/accounts/scwallet/hub.go
index ceb422c..67483b8 100644
--- a/accounts/scwallet/hub.go
+++ b/accounts/scwallet/hub.go
@@ -220,7 +220,7 @@ func (hub *Hub) refreshWallets() {
// Mark the reader as present
seen[reader] = struct{}{}
- // If we alreay know about this card, skip to the next reader, otherwise clean up
+ // If we already know about this card, skip to the next reader, otherwise clean up
if wallet, ok := hub.wallets[reader]; ok {
if err := wallet.ping(); err == nil {
continue
diff --git a/accounts/scwallet/securechannel.go b/accounts/scwallet/securechannel.go
index c1b7cff..a5666c9 100644
--- a/accounts/scwallet/securechannel.go
+++ b/accounts/scwallet/securechannel.go
@@ -71,7 +71,7 @@ func NewSecureChannelSession(card *pcsc.Card, keyData []byte) (*SecureChannelSes
cardPublic, ok := gen.Unmarshal(keyData)
if !ok {
- return nil, fmt.Errorf("Could not unmarshal public key from card")
+ return nil, fmt.Errorf("could not unmarshal public key from card")
}
secret, err := gen.GenerateSharedSecret(private, cardPublic)
@@ -109,7 +109,7 @@ func (s *SecureChannelSession) Pair(pairingPassword []byte) error {
cardChallenge := response.Data[32:64]
if !bytes.Equal(expectedCryptogram, cardCryptogram) {
- return fmt.Errorf("Invalid card cryptogram %v != %v", expectedCryptogram, cardCryptogram)
+ return fmt.Errorf("invalid card cryptogram %v != %v", expectedCryptogram, cardCryptogram)
}
md.Reset()
@@ -132,7 +132,7 @@ func (s *SecureChannelSession) Pair(pairingPassword []byte) error {
// Unpair disestablishes an existing pairing.
func (s *SecureChannelSession) Unpair() error {
if s.PairingKey == nil {
- return fmt.Errorf("Cannot unpair: not paired")
+ return fmt.Errorf("cannot unpair: not paired")
}
_, err := s.transmitEncrypted(claSCWallet, insUnpair, s.PairingIndex, 0, []byte{})
@@ -148,7 +148,7 @@ func (s *SecureChannelSession) Unpair() error {
// Open initializes the secure channel.
func (s *SecureChannelSession) Open() error {
if s.iv != nil {
- return fmt.Errorf("Session already opened")
+ return fmt.Errorf("session already opened")
}
response, err := s.open()
@@ -185,11 +185,11 @@ func (s *SecureChannelSession) mutuallyAuthenticate() error {
return err
}
if response.Sw1 != 0x90 || response.Sw2 != 0x00 {
- return fmt.Errorf("Got unexpected response from MUTUALLY_AUTHENTICATE: 0x%x%x", response.Sw1, response.Sw2)
+ return fmt.Errorf("got unexpected response from MUTUALLY_AUTHENTICATE: 0x%x%x", response.Sw1, response.Sw2)
}
if len(response.Data) != scSecretLength {
- return fmt.Errorf("Response from MUTUALLY_AUTHENTICATE was %d bytes, expected %d", len(response.Data), scSecretLength)
+ return fmt.Errorf("response from MUTUALLY_AUTHENTICATE was %d bytes, expected %d", len(response.Data), scSecretLength)
}
return nil
@@ -222,7 +222,7 @@ func (s *SecureChannelSession) pair(p1 uint8, data []byte) (*responseAPDU, error
// transmitEncrypted sends an encrypted message, and decrypts and returns the response.
func (s *SecureChannelSession) transmitEncrypted(cla, ins, p1, p2 byte, data []byte) (*responseAPDU, error) {
if s.iv == nil {
- return nil, fmt.Errorf("Channel not open")
+ return nil, fmt.Errorf("channel not open")
}
data, err := s.encryptAPDU(data)
@@ -261,14 +261,14 @@ func (s *SecureChannelSession) transmitEncrypted(cla, ins, p1, p2 byte, data []b
return nil, err
}
if !bytes.Equal(s.iv, rmac) {
- return nil, fmt.Errorf("Invalid MAC in response")
+ return nil, fmt.Errorf("invalid MAC in response")
}
rapdu := &responseAPDU{}
rapdu.deserialize(plainData)
if rapdu.Sw1 != sw1Ok {
- return nil, fmt.Errorf("Unexpected response status Cla=0x%x, Ins=0x%x, Sw=0x%x%x", cla, ins, rapdu.Sw1, rapdu.Sw2)
+ return nil, fmt.Errorf("unexpected response status Cla=0x%x, Ins=0x%x, Sw=0x%x%x", cla, ins, rapdu.Sw1, rapdu.Sw2)
}
return rapdu, nil
@@ -277,7 +277,7 @@ func (s *SecureChannelSession) transmitEncrypted(cla, ins, p1, p2 byte, data []b
// encryptAPDU is an internal method that serializes and encrypts an APDU.
func (s *SecureChannelSession) encryptAPDU(data []byte) ([]byte, error) {
if len(data) > maxPayloadSize {
- return nil, fmt.Errorf("Payload of %d bytes exceeds maximum of %d", len(data), maxPayloadSize)
+ return nil, fmt.Errorf("payload of %d bytes exceeds maximum of %d", len(data), maxPayloadSize)
}
data = pad(data, 0x80)
@@ -323,10 +323,10 @@ func unpad(data []byte, terminator byte) ([]byte, error) {
case terminator:
return data[:len(data)-i], nil
default:
- return nil, fmt.Errorf("Expected end of padding, got %d", data[len(data)-i])
+ return nil, fmt.Errorf("expected end of padding, got %d", data[len(data)-i])
}
}
- return nil, fmt.Errorf("Expected end of padding, got 0")
+ return nil, fmt.Errorf("expected end of padding, got 0")
}
// updateIV is an internal method that updates the initialization vector after
diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go
index f72e685..5d2aff8 100644
--- a/accounts/scwallet/wallet.go
+++ b/accounts/scwallet/wallet.go
@@ -167,7 +167,7 @@ func transmit(card *pcsc.Card, command *commandAPDU) (*responseAPDU, error) {
}
if response.Sw1 != sw1Ok {
- return nil, fmt.Errorf("Unexpected insecure response status Cla=0x%x, Ins=0x%x, Sw=0x%x%x", command.Cla, command.Ins, response.Sw1, response.Sw2)
+ return nil, fmt.Errorf("unexpected insecure response status Cla=0x%x, Ins=0x%x, Sw=0x%x%x", command.Cla, command.Ins, response.Sw1, response.Sw2)
}
return response, nil
@@ -252,7 +252,7 @@ func (w *Wallet) release() error {
// with the wallet.
func (w *Wallet) pair(puk []byte) error {
if w.session.paired() {
- return fmt.Errorf("Wallet already paired")
+ return fmt.Errorf("wallet already paired")
}
pairing, err := w.session.pair(puk)
if err != nil {
@@ -312,15 +312,15 @@ func (w *Wallet) Status() (string, error) {
}
switch {
case !w.session.verified && status.PinRetryCount == 0 && status.PukRetryCount == 0:
- return fmt.Sprintf("Bricked, waiting for full wipe"), nil
+ return "Bricked, waiting for full wipe", nil
case !w.session.verified && status.PinRetryCount == 0:
return fmt.Sprintf("Blocked, waiting for PUK (%d attempts left) and new PIN", status.PukRetryCount), nil
case !w.session.verified:
return fmt.Sprintf("Locked, waiting for PIN (%d attempts left)", status.PinRetryCount), nil
case !status.Initialized:
- return fmt.Sprintf("Empty, waiting for initialization"), nil
+ return "Empty, waiting for initialization", nil
default:
- return fmt.Sprintf("Online"), nil
+ return "Online", nil
}
}
@@ -362,7 +362,7 @@ func (w *Wallet) Open(passphrase string) error {
return err
}
// Pairing succeeded, fall through to PIN checks. This will of course fail,
- // but we can't return ErrPINNeeded directly here becase we don't know whether
+ // but we can't return ErrPINNeeded directly here because we don't know whether
// a PIN check or a PIN reset is needed.
passphrase = ""
}
@@ -773,12 +773,12 @@ func (w *Wallet) findAccountPath(account accounts.Account) (accounts.DerivationP
// Look for the path in the URL
if account.URL.Scheme != w.Hub.scheme {
- return nil, fmt.Errorf("Scheme %s does not match wallet scheme %s", account.URL.Scheme, w.Hub.scheme)
+ return nil, fmt.Errorf("scheme %s does not match wallet scheme %s", account.URL.Scheme, w.Hub.scheme)
}
parts := strings.SplitN(account.URL.Path, "/", 2)
if len(parts) != 2 {
- return nil, fmt.Errorf("Invalid URL format: %s", account.URL)
+ return nil, fmt.Errorf("invalid URL format: %s", account.URL)
}
if parts[0] != fmt.Sprintf("%x", w.PublicKey[1:3]) {
@@ -813,7 +813,7 @@ func (s *Session) pair(secret []byte) (smartcardPairing, error) {
// unpair deletes an existing pairing.
func (s *Session) unpair() error {
if !s.verified {
- return fmt.Errorf("Unpair requires that the PIN be verified")
+ return fmt.Errorf("unpair requires that the PIN be verified")
}
return s.Channel.Unpair()
}
@@ -850,7 +850,7 @@ func (s *Session) paired() bool {
// authenticate uses an existing pairing to establish a secure channel.
func (s *Session) authenticate(pairing smartcardPairing) error {
if !bytes.Equal(s.Wallet.PublicKey, pairing.PublicKey) {
- return fmt.Errorf("Cannot pair using another wallet's pairing; %x != %x", s.Wallet.PublicKey, pairing.PublicKey)
+ return fmt.Errorf("cannot pair using another wallet's pairing; %x != %x", s.Wallet.PublicKey, pairing.PublicKey)
}
s.Channel.PairingKey = pairing.PairingKey
s.Channel.PairingIndex = pairing.PairingIndex
@@ -879,6 +879,7 @@ func (s *Session) walletStatus() (*walletStatus, error) {
}
// derivationPath fetches the wallet's current derivation path from the card.
+//lint:ignore U1000 needs to be added to the console interface
func (s *Session) derivationPath() (accounts.DerivationPath, error) {
response, err := s.Channel.transmitEncrypted(claSCWallet, insStatus, statusP1Path, 0, nil)
if err != nil {
@@ -993,12 +994,14 @@ func (s *Session) derive(path accounts.DerivationPath) (accounts.Account, error)
}
// keyExport contains information on an exported keypair.
+//lint:ignore U1000 needs to be added to the console interface
type keyExport struct {
PublicKey []byte `asn1:"tag:0"`
PrivateKey []byte `asn1:"tag:1,optional"`
}
// publicKey returns the public key for the current derivation path.
+//lint:ignore U1000 needs to be added to the console interface
func (s *Session) publicKey() ([]byte, error) {
response, err := s.Channel.transmitEncrypted(claSCWallet, insExportKey, exportP1Any, exportP2Pubkey, nil)
if err != nil {