aboutsummaryrefslogtreecommitdiff
path: root/accounts
diff options
context:
space:
mode:
authorDeterminant <tederminant@gmail.com>2020-09-15 23:55:34 -0400
committerDeterminant <tederminant@gmail.com>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 {
='#n8461'>8461 8462 8463 8464 8465 8466 8467 8468 8469 8470 8471 8472 8473 8474 8475 8476 8477 8478 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488 8489 8490 8491 8492 8493 8494 8495 8496 8497 8498 8499 8500 8501 8502 8503 8504 8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 8532 8533 8534 8535 8536 8537 8538 8539 8540 8541 8542 8543 8544 8545 8546 8547 8548 8549 8550 8551 8552 8553 8554 8555 8556 8557 8558 8559 8560 8561 8562 8563 8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 8575 8576 8577 8578 8579 8580 8581 8582 8583 8584 8585 8586 8587 8588 8589 8590 8591 8592 8593 8594 8595 8596 8597 8598 8599 8600 8601 8602 8603 8604 8605 8606 8607 8608 8609 8610 8611 8612 8613 8614 8615 8616 8617 8618 8619 8620 8621 8622 8623 8624 8625 8626 8627 8628 8629 8630 8631 8632 8633 8634 8635 8636 8637 8638 8639 8640 8641 8642 8643 8644 8645 8646 8647 8648 8649 8650 8651 8652 8653 8654 8655 8656 8657 8658 8659 8660 8661 8662 8663 8664 8665 8666 8667 8668 8669 8670 8671 8672 8673 8674 8675 8676 8677 8678 8679 8680 8681 8682 8683 8684 8685 8686 8687 8688 8689 8690 8691 8692 8693 8694 8695 8696 8697 8698 8699 8700 8701 8702 8703 8704 8705 8706 8707 8708 8709 8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733 8734 8735 8736 8737 8738 8739 8740 8741 8742 8743 8744 8745 8746 8747 8748 8749 8750 8751 8752 8753 8754 8755 8756 8757 8758 8759 8760 8761 8762 8763 8764 8765 8766 8767 8768 8769 8770 8771 8772 8773 8774 8775 8776 8777 8778 8779 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 8815 8816 8817 8818 8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 8847 8848 8849 8850 8851 8852 8853 8854 8855 8856 8857 8858 8859 8860 8861 8862 8863 8864 8865 8866 8867 8868 8869 8870 8871 8872 8873 8874 8875 8876 8877 8878 8879 8880 8881 8882 8883 8884 8885 8886 8887 8888 8889 8890 8891 8892 8893 8894 8895 8896 8897 8898 8899 8900 8901 8902 8903 8904 8905 8906 8907 8908 8909 8910 8911 8912 8913 8914 8915 8916 8917 8918 8919 8920 8921 8922 8923 8924 8925 8926 8927 8928 8929 8930 8931 8932 8933 8934 8935 8936 8937 8938 8939 8940 8941 8942 8943 8944 8945 8946 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 8970 8971 8972 8973 8974 8975 8976 8977 8978 8979 8980 8981 8982 8983 8984 8985 8986 8987 8988 8989 8990 8991 8992 8993 8994 8995 8996 8997 8998 8999 9000 9001 9002 9003 9004 9005 9006 9007 9008 9009 9010 9011 9012 9013 9014 9015 9016 9017 9018 9019 9020 9021 9022 9023 9024 9025 9026 9027 9028 9029 9030 9031 9032 9033 9034 9035 9036 9037 9038 9039 9040 9041 9042 9043 9044 9045 9046 9047 9048 9049 9050 9051 9052 9053 9054 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065 9066 9067 9068 9069 9070 9071 9072 9073 9074 9075 9076 9077 9078 9079 9080 9081 9082 9083 9084 9085 9086 9087 9088 9089 9090 9091 9092 9093 9094 9095 9096 9097 9098 9099 9100 9101 9102 9103 9104 9105 9106 9107 9108 9109 9110 9111 9112 9113 9114 9115 9116 9117 9118 9119 9120 9121 9122 9123 9124 9125 9126 9127 9128 9129 9130 9131 9132 9133 9134 9135 9136 9137 9138 9139 9140 9141 9142 9143 9144 9145 9146 9147 9148 9149 9150 9151 9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 9162 9163 9164 9165 9166 9167 9168 9169 9170 9171 9172 9173 9174 9175 9176 9177 9178 9179 9180 9181 9182 9183 9184 9185 9186 9187 9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221 9222 9223 9224 9225 9226 9227 9228 9229 9230 9231 9232 9233 9234 9235 9236 9237 9238 9239 9240 9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 9270 9271 9272 9273 9274 9275 9276 9277 9278 9279 9280 9281 9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296 9297 9298 9299 9300 9301 9302 9303 9304 9305 9306 9307 9308 9309 9310 9311 9312 9313 9314 9315 9316 9317 9318 9319 9320 9321 9322 9323 9324 9325 9326 9327 9328 9329 9330 9331 9332 9333 9334 9335 9336 9337 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 9358 9359 9360 9361 9362 9363 9364 9365 9366 9367 9368 9369 9370 9371 9372 9373 9374 9375 9376 9377 9378 9379 9380 9381 9382 9383 9384 9385 9386 9387 9388 9389 9390 9391 9392 9393 9394 9395 9396 9397 9398 9399 9400 9401 9402 9403 9404 9405 9406 9407 9408 9409 9410 9411 9412 9413 9414 9415 9416 9417 9418 9419 9420 9421 9422 9423 9424 9425 9426 9427 9428 9429 9430 9431 9432 9433 9434 9435 9436 9437 9438 9439 9440 9441 9442 9443 9444 9445 9446 9447 9448 9449 9450 9451 9452 9453 9454 9455 9456 9457 9458 9459 9460 9461 9462 9463 9464 9465 9466 9467 9468 9469 9470 9471 9472 9473 9474 9475 9476 9477 9478 9479 9480 9481 9482 9483 9484 9485 9486 9487 9488 9489 9490 9491 9492 9493 9494 9495 9496 9497 9498 9499 9500 9501 9502 9503 9504 9505 9506 9507 9508 9509 9510 9511 9512 9513 9514 9515 9516 9517 9518 9519 9520 9521 9522 9523 9524 9525 9526 9527 9528 9529 9530 9531 9532 9533 9534 9535 9536 9537 9538 9539 9540 9541 9542 9543 9544 9545 9546 9547 9548 9549 9550 9551 9552 9553 9554 9555 9556 9557 9558 9559 9560 9561 9562 9563 9564 9565 9566 9567 9568 9569 9570 9571 9572 9573 9574 9575 9576 9577 9578 9579 9580 9581 9582 9583 9584 9585 9586 9587 9588 9589 9590 9591 9592 9593 9594 9595 9596 9597 9598 9599 9600 9601 9602 9603 9604 9605 9606 9607 9608 9609 9610 9611 9612 9613 9614 9615 9616 9617 9618 9619 9620 9621 9622 9623 9624 9625 9626 9627 9628 9629 9630 9631 9632 9633 9634 9635 9636 9637 9638 9639 9640 9641 9642 9643 9644 9645 9646 9647 9648 9649 9650 9651 9652 9653 9654 9655 9656 9657 9658 9659 9660 9661 9662 9663 9664 9665 9666 9667 9668 9669 9670 9671 9672 9673 9674 9675 9676 9677 9678 9679 9680 9681 9682 9683 9684 9685 9686 9687 9688 9689 9690 9691 9692 9693 9694 9695 9696 9697 9698 9699 9700 9701 9702 9703 9704 9705 9706 9707 9708 9709 9710 9711 9712 9713 9714 9715 9716 9717 9718 9719 9720 9721 9722 9723 9724 9725 9726 9727 9728 9729 9730 9731 9732 9733 9734 9735 9736 9737 9738 9739 9740 9741 9742 9743 9744 9745 9746 9747 9748 9749 9750 9751 9752 9753 9754 9755 9756 9757 9758 9759 9760 9761 9762 9763 9764 9765 9766 9767 9768 9769 9770 9771 9772 9773 9774 9775 9776 9777 9778 9779 9780 9781 9782 9783 9784 9785 9786 9787 9788 9789 9790 9791 9792 9793 9794 9795 9796 9797 9798 9799 9800 9801 9802 9803 9804 9805 9806 9807 9808 9809 9810 9811 9812 9813 9814 9815 9816 9817 9818 9819 9820 9821 9822 9823 9824 9825 9826 9827 9828 9829 9830 9831 9832 9833 9834 9835 9836 9837 9838 9839 9840 9841 9842 9843 9844 9845 9846 9847 9848 9849 9850 9851 9852 9853 9854 9855 9856 9857 9858 9859 9860 9861 9862 9863 9864 9865 9866 9867 9868 9869 9870 9871 9872 9873 9874 9875 9876 9877 9878 9879 9880 9881 9882 9883 9884 9885 9886 9887 9888 9889 9890 9891 9892 9893 9894 9895 9896 9897 9898 9899 9900 9901 9902 9903 9904 9905 9906 9907 9908 9909 9910 9911 9912 9913 9914 9915 9916 9917 9918 9919 9920 9921 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9954 9955 9956 9957 9958 9959 9960 9961 9962 9963 9964 9965 9966 9967 9968 9969 9970 9971 9972 9973 9974 9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990 9991 9992 9993 9994 9995 9996 9997 9998 9999 10000