aboutsummaryrefslogtreecommitdiffstats
path: root/accounts/abi/bind/base.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/base.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/base.go')
-rw-r--r--accounts/abi/bind/base.go66
1 files changed, 59 insertions, 7 deletions
diff --git a/accounts/abi/bind/base.go b/accounts/abi/bind/base.go
index 75e3c1d2d..e9e35fbcb 100644
--- a/accounts/abi/bind/base.go
+++ b/accounts/abi/bind/base.go
@@ -24,14 +24,21 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/crypto"
)
// SignerFn is a signer function callback when a contract requires a method to
// sign the transaction before submission.
type SignerFn func(common.Address, *types.Transaction) (*types.Transaction, error)
-// AuthOpts is the authorization data required to create a valid Ethereum transaction.
-type AuthOpts struct {
+// 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
+}
+
+// TransactOpts is the collection of authorization data required to create a
+// valid Ethereum transaction.
+type TransactOpts struct {
Account 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)
@@ -62,16 +69,43 @@ func NewBoundContract(address common.Address, abi abi.ABI, caller ContractCaller
}
}
+// 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) {
+ // Sanity check the authorization options
+ if opts == nil {
+ return common.Address{}, nil, nil, errors.New("transaction options missing")
+ }
+ // Otherwise try to deploy the contract
+ c := NewBoundContract(common.Address{}, abi, backend.(ContractCaller), backend.(ContractTransactor))
+
+ 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.Account, 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(result interface{}, method string, params ...interface{}) error {
+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
}
- output, err := c.caller.ContractCall(c.address, input)
+ output, err := c.caller.ContractCall(c.address, input, opts.Pending)
if err != nil {
return err
}
@@ -80,11 +114,24 @@ func (c *BoundContract) Call(result interface{}, method string, params ...interf
// Transact invokes the (paid) contract method with params as input values and
// value as the fund transfer to the contract.
-func (c *BoundContract) Transact(opts *AuthOpts, method string, params ...interface{}) (*types.Transaction, error) {
+func (c *BoundContract) Transact(opts *TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
+ // Sanity check the authorization options
+ if opts == nil {
+ return nil, errors.New("transaction options missing")
+ }
+ // 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)
+}
+
+// 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 {
@@ -109,13 +156,18 @@ func (c *BoundContract) Transact(opts *AuthOpts, method string, params ...interf
}
gasLimit := opts.GasLimit
if gasLimit == nil {
- gasLimit, err = c.transactor.GasLimit(opts.Account, c.address, value, input)
+ gasLimit, err = c.transactor.GasLimit(opts.Account, contract, value, input)
if err != nil {
return nil, fmt.Errorf("failed to exstimate gas needed: %v", err)
}
}
// Create the transaction, sign it and schedule it for execution
- rawTx := types.NewTransaction(nonce, c.address, value, gasLimit, gasPrice, input)
+ 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")
}