aboutsummaryrefslogtreecommitdiffstats
path: root/accounts/abi/bind/backend.go
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2016-03-18 01:27:37 +0800
committerPéter Szilágyi <peterke@gmail.com>2016-03-24 20:15:32 +0800
commit86cfc22c79594bd0d9625650dcbfb60c3e6ba9fe (patch)
treef080840b4ac808304862846125bf8b4d47a4ef37 /accounts/abi/bind/backend.go
parent72826bb5adddedf0fd4fb9903e883d4c64fa18a6 (diff)
downloaddexon-86cfc22c79594bd0d9625650dcbfb60c3e6ba9fe.tar
dexon-86cfc22c79594bd0d9625650dcbfb60c3e6ba9fe.tar.gz
dexon-86cfc22c79594bd0d9625650dcbfb60c3e6ba9fe.tar.bz2
dexon-86cfc22c79594bd0d9625650dcbfb60c3e6ba9fe.tar.lz
dexon-86cfc22c79594bd0d9625650dcbfb60c3e6ba9fe.tar.xz
dexon-86cfc22c79594bd0d9625650dcbfb60c3e6ba9fe.tar.zst
dexon-86cfc22c79594bd0d9625650dcbfb60c3e6ba9fe.zip
accounts/abi/bind: constructor, auth utils and various backends
Diffstat (limited to 'accounts/abi/bind/backend.go')
-rw-r--r--accounts/abi/bind/backend.go196
1 files changed, 4 insertions, 192 deletions
diff --git a/accounts/abi/bind/backend.go b/accounts/abi/bind/backend.go
index fcd1c4d0a..596e97f1d 100644
--- a/accounts/abi/bind/backend.go
+++ b/accounts/abi/bind/backend.go
@@ -17,24 +17,19 @@
package bind
import (
- "encoding/json"
- "fmt"
"math/big"
- "sync"
- "sync/atomic"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/rlp"
- "github.com/ethereum/go-ethereum/rpc"
)
// ContractCaller defines the methods needed to allow operating with contract on a read
// only basis.
type ContractCaller interface {
// ContractCall executes an Ethereum contract call with the specified data as
- // the input.
- ContractCall(contract common.Address, data []byte) ([]byte, error)
+ // the input. The pending flag requests execution against the pending block, not
+ // the stable head of the chain.
+ ContractCall(contract common.Address, data []byte, pending bool) ([]byte, error)
}
// ContractTransactor defines the methods needed to allow operating with contract
@@ -50,7 +45,7 @@ type ContractTransactor interface {
GasPrice() (*big.Int, error)
// GasLimit tries to estimate the gas needed to execute a specific transaction.
- GasLimit(sender, contract common.Address, value *big.Int, data []byte) (*big.Int, error)
+ GasLimit(sender common.Address, contract *common.Address, value *big.Int, data []byte) (*big.Int, error)
// SendTransaction injects the transaction into the pending pool for execution.
SendTransaction(*types.Transaction) error
@@ -62,186 +57,3 @@ type ContractBackend interface {
ContractCaller
ContractTransactor
}
-
-// nilBackend implements bind.ContractBackend, but panics on any method call.
-// Its sole purpose is to support the binding tests to construct the generated
-// wrappers without calling any methods on them.
-type nilBackend struct{}
-
-func (*nilBackend) ContractCall(common.Address, []byte) ([]byte, error) { panic("not implemented") }
-func (*nilBackend) SendTransaction(*types.Transaction) error { panic("not implemented") }
-func (*nilBackend) AccountNonce(common.Address) (uint64, error) { panic("not implemented") }
-func (*nilBackend) GasPrice() (*big.Int, error) { panic("not implemented") }
-func (*nilBackend) GasLimit(common.Address, common.Address, *big.Int, []byte) (*big.Int, error) {
- panic("not implemented")
-}
-
-// Helper backend for internal tests. Will panic on any invocation!
-var NilBackend = new(nilBackend)
-
-// rpcBackend implements bind.ContractBackend, and acts as the data provider to
-// Ethereum contracts bound to Go structs. It uses an RPC connection to delegate
-// all its functionality.
-//
-// Note: The current implementation is a blocking one. This should be replaced
-// by a proper async version when a real RPC client is created.
-type rpcBackend struct {
- client rpc.Client // RPC client connection to interact with an API server
- autoid uint32 // ID number to use for the next API request
- lock sync.Mutex // Singleton access until we get to request multiplexing
-}
-
-// NewRPCBackend creates a new binding backend to an RPC provider that can be
-// used to interact with remote contracts.
-func NewRPCBackend(client rpc.Client) ContractBackend {
- return &rpcBackend{
- client: client,
- }
-}
-
-// request is a JSON RPC request package assembled internally from the client
-// method calls.
-type request struct {
- JsonRpc string `json:"jsonrpc"` // Version of the JSON RPC protocol, always set to 2.0
- Id int `json:"id"` // Auto incrementing ID number for this request
- Method string `json:"method"` // Remote procedure name to invoke on the server
- Params []interface{} `json:"params"` // List of parameters to pass through (keep types simple)
-}
-
-// response is a JSON RPC response package sent back from the API server.
-type response struct {
- JsonRpc string `json:"jsonrpc"` // Version of the JSON RPC protocol, always set to 2.0
- Id int `json:"id"` // Auto incrementing ID number for this request
- Error json.RawMessage `json:"error"` // Any error returned by the remote side
- Result json.RawMessage `json:"result"` // Whatever the remote side sends us in reply
-}
-
-// request forwards an API request to the RPC server, and parses the response.
-//
-// This is currently painfully non-concurrent, but it will have to do until we
-// find the time for niceties like this :P
-func (backend *rpcBackend) request(method string, params []interface{}) (json.RawMessage, error) {
- backend.lock.Lock()
- defer backend.lock.Unlock()
-
- // Ugly hack to serialize an empty list properly
- if params == nil {
- params = []interface{}{}
- }
- // Assemble the request object
- req := &request{
- JsonRpc: "2.0",
- Id: int(atomic.AddUint32(&backend.autoid, 1)),
- Method: method,
- Params: params,
- }
- if err := backend.client.Send(req); err != nil {
- return nil, err
- }
- res := new(response)
- if err := backend.client.Recv(res); err != nil {
- return nil, err
- }
- if len(res.Error) > 0 {
- return nil, fmt.Errorf("remote error: %s", string(res.Error))
- }
- return res.Result, nil
-}
-
-// ContractCall implements ContractCaller.ContractCall, delegating the execution of
-// a contract call to the remote node, returning the reply to for local processing.
-func (b *rpcBackend) ContractCall(contract common.Address, data []byte) ([]byte, error) {
- // Pack up the request into an RPC argument
- args := struct {
- To common.Address `json:"to"`
- Data string `json:"data"`
- }{
- To: contract,
- Data: common.ToHex(data),
- }
- // Execute the RPC call and retrieve the response
- res, err := b.request("eth_call", []interface{}{args, "pending"})
- if err != nil {
- return nil, err
- }
- var hex string
- if err := json.Unmarshal(res, &hex); err != nil {
- return nil, err
- }
- // Convert the response back to a Go byte slice and return
- return common.FromHex(hex), nil
-}
-
-// AccountNonce implements ContractTransactor.AccountNonce, delegating the
-// current account nonce retrieval to the remote node.
-func (b *rpcBackend) AccountNonce(account common.Address) (uint64, error) {
- res, err := b.request("eth_getTransactionCount", []interface{}{account.Hex(), "pending"})
- if err != nil {
- return 0, err
- }
- var hex string
- if err := json.Unmarshal(res, &hex); err != nil {
- return 0, err
- }
- return new(big.Int).SetBytes(common.FromHex(hex)).Uint64(), nil
-}
-
-// GasPrice implements ContractTransactor.GasPrice, delegating the gas price
-// oracle request to the remote node.
-func (b *rpcBackend) GasPrice() (*big.Int, error) {
- res, err := b.request("eth_gasPrice", nil)
- if err != nil {
- return nil, err
- }
- var hex string
- if err := json.Unmarshal(res, &hex); err != nil {
- return nil, err
- }
- return new(big.Int).SetBytes(common.FromHex(hex)), nil
-}
-
-// GasLimit implements ContractTransactor.GasLimit, delegating the gas estimation
-// to the remote node.
-func (b *rpcBackend) GasLimit(sender, contract common.Address, value *big.Int, data []byte) (*big.Int, error) {
- // Pack up the request into an RPC argument
- args := struct {
- From common.Address `json:"from"`
- To common.Address `json:"to"`
- Value *rpc.HexNumber `json:"value"`
- Data string `json:"data"`
- }{
- From: sender,
- To: contract,
- Data: common.ToHex(data),
- Value: rpc.NewHexNumber(value),
- }
- // Execute the RPC call and retrieve the response
- res, err := b.request("eth_estimateGas", []interface{}{args})
- if err != nil {
- return nil, err
- }
- var hex string
- if err := json.Unmarshal(res, &hex); err != nil {
- return nil, err
- }
- // Convert the response back to a Go byte slice and return
- return new(big.Int).SetBytes(common.FromHex(hex)), nil
-}
-
-// Transact implements ContractTransactor.SendTransaction, delegating the raw
-// transaction injection to the remote node.
-func (b *rpcBackend) SendTransaction(tx *types.Transaction) error {
- data, err := rlp.EncodeToBytes(tx)
- if err != nil {
- return err
- }
- res, err := b.request("eth_sendRawTransaction", []interface{}{common.ToHex(data)})
- if err != nil {
- return err
- }
- var hex string
- if err := json.Unmarshal(res, &hex); err != nil {
- return err
- }
- return nil
-}