aboutsummaryrefslogtreecommitdiff
path: root/accounts/abi/bind
diff options
context:
space:
mode:
authorTed Yin <[email protected]>2020-09-18 13:14:29 -0400
committerGitHub <[email protected]>2020-09-18 13:14:29 -0400
commitd048937c48753d9eaef771bf71820cf95d79df26 (patch)
tree1a7f65fcd72e77092525ab01625b8b9d365e3e40 /accounts/abi/bind
parent7d1388c743b4ec8f4a86bea95bfada785dee83f7 (diff)
parent7d8c85cf8895b0f998d8eafb02f99d5b689fcd59 (diff)
Merge pull request #34 from ava-labs/devv0.3.0-rc.5
Dev
Diffstat (limited to 'accounts/abi/bind')
-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
8 files changed, 0 insertions, 2588 deletions
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
-}