Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
G
Geth-Modification
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
张蕾
Geth-Modification
Commits
73308dbe
Commit
73308dbe
authored
Mar 21, 2016
by
Péter Szilágyi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
accounts/abi/bind, cmd/abigen: port to templates, bind to solidity
parent
86cfc22c
Changes
10
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
594 additions
and
448 deletions
+594
-448
auth.go
accounts/abi/bind/auth.go
+10
-4
backend.go
accounts/abi/bind/backend.go
+12
-8
nil.go
accounts/abi/bind/backends/nil.go
+7
-4
remote.go
accounts/abi/bind/backends/remote.go
+40
-26
simulated.go
accounts/abi/bind/backends/simulated.go
+18
-15
base.go
accounts/abi/bind/base.go
+9
-17
bind.go
accounts/abi/bind/bind.go
+87
-334
bind_test.go
accounts/abi/bind/bind_test.go
+135
-20
template.go
accounts/abi/bind/template.go
+212
-0
main.go
cmd/abigen/main.go
+64
-20
No files found.
accounts/abi/bind/auth.go
View file @
73308dbe
...
...
@@ -18,6 +18,8 @@ package bind
import
(
"errors"
"io"
"io/ioutil"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
...
...
@@ -25,9 +27,13 @@ import (
)
// NewTransactor is a utility method to easily create a transaction signer from
// an encrypted json key file and the associated passphrase.
func
NewTransactor
(
keyjson
string
,
passphrase
string
)
(
*
TransactOpts
,
error
)
{
key
,
err
:=
crypto
.
DecryptKey
([]
byte
(
keyjson
),
passphrase
)
// 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
:=
crypto
.
DecryptKey
(
json
,
passphrase
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -38,7 +44,7 @@ func NewTransactor(keyjson string, passphrase string) (*TransactOpts, error) {
// from a plain go-ethereum crypto key.
func
NewKeyedTransactor
(
key
*
crypto
.
Key
)
*
TransactOpts
{
return
&
TransactOpts
{
Account
:
key
.
Address
,
From
:
key
.
Address
,
Signer
:
func
(
address
common
.
Address
,
tx
*
types
.
Transaction
)
(
*
types
.
Transaction
,
error
)
{
if
address
!=
key
.
Address
{
return
nil
,
errors
.
New
(
"not authorized to sign this account"
)
...
...
accounts/abi/bind/backend.go
View file @
73308dbe
...
...
@@ -38,14 +38,18 @@ type ContractCaller interface {
// to the transactor to decide.
type
ContractTransactor
interface
{
// Nonce retrieves the current pending nonce associated with an account.
AccountNonce
(
account
common
.
Address
)
(
uint64
,
error
)
// GasPrice retrieves the currently suggested gas price to allow a timely execution
// of a transaction.
GasPrice
()
(
*
big
.
Int
,
error
)
// GasLimit tries to estimate the gas needed to execute a specific transaction.
GasLimit
(
sender
common
.
Address
,
contract
*
common
.
Address
,
value
*
big
.
Int
,
data
[]
byte
)
(
*
big
.
Int
,
error
)
PendingAccountNonce
(
account
common
.
Address
)
(
uint64
,
error
)
// SuggestGasPrice retrieves the currently suggested gas price to allow a timely
// execution of a transaction.
SuggestGasPrice
()
(
*
big
.
Int
,
error
)
// EstimateGasLimit 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.
EstimateGasLimit
(
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
...
...
accounts/abi/bind/backends/nil.go
View file @
73308dbe
...
...
@@ -24,6 +24,9 @@ import (
"github.com/ethereum/go-ethereum/core/types"
)
// This nil assignment ensures compile time that nilBackend implements bind.ContractBackend.
var
_
bind
.
ContractBackend
=
(
*
nilBackend
)(
nil
)
// 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.
...
...
@@ -32,11 +35,11 @@ type nilBackend struct{}
func
(
*
nilBackend
)
ContractCall
(
common
.
Address
,
[]
byte
,
bool
)
([]
byte
,
error
)
{
panic
(
"not implemented"
)
}
func
(
*
nilBackend
)
GasLimit
(
common
.
Address
,
*
common
.
Address
,
*
big
.
Int
,
[]
byte
)
(
*
big
.
Int
,
error
)
{
func
(
*
nilBackend
)
Estimate
GasLimit
(
common
.
Address
,
*
common
.
Address
,
*
big
.
Int
,
[]
byte
)
(
*
big
.
Int
,
error
)
{
panic
(
"not implemented"
)
}
func
(
*
nilBackend
)
GasPrice
()
(
*
big
.
Int
,
error
)
{
panic
(
"not implemented"
)
}
func
(
*
nilBackend
)
AccountNonce
(
common
.
Address
)
(
uint64
,
error
)
{
panic
(
"not implemented"
)
}
func
(
*
nilBackend
)
Suggest
GasPrice
()
(
*
big
.
Int
,
error
)
{
panic
(
"not implemented"
)
}
func
(
*
nilBackend
)
Pending
AccountNonce
(
common
.
Address
)
(
uint64
,
error
)
{
panic
(
"not implemented"
)
}
func
(
*
nilBackend
)
SendTransaction
(
*
types
.
Transaction
)
error
{
panic
(
"not implemented"
)
}
// NewNilBackend creates a new binding backend that can be used for instantiation
...
...
accounts/abi/bind/backends/remote.go
View file @
73308dbe
...
...
@@ -30,6 +30,9 @@ import (
"github.com/ethereum/go-ethereum/rpc"
)
// This nil assignment ensures compile time that rpcBackend implements bind.ContractBackend.
var
_
bind
.
ContractBackend
=
(
*
rpcBackend
)(
nil
)
// 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.
...
...
@@ -53,16 +56,16 @@ func NewRPCBackend(client rpc.Client) bind.ContractBackend {
// request is a JSON RPC request package assembled internally from the client
// method calls.
type
request
struct
{
J
sonRpc
string
`json:"jsonrpc"`
// Version of the JSON RPC protocol, always set to 2.0
I
d
int
`json:"id"`
// Auto incrementing ID number for this request
J
SONRPC
string
`json:"jsonrpc"`
// Version of the JSON RPC protocol, always set to 2.0
I
D
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
{
J
sonRpc
string
`json:"jsonrpc"`
// Version of the JSON RPC protocol, always set to 2.0
I
d
int
`json:"id"`
// Auto incrementing ID number for this request
J
SONRPC
string
`json:"jsonrpc"`
// Version of the JSON RPC protocol, always set to 2.0
I
D
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
}
...
...
@@ -71,9 +74,9 @@ type response struct {
//
// This is currently painfully non-concurrent, but it will have to do until we
// find the time for niceties like this :P
func
(
b
ackend
*
rpcBackend
)
request
(
method
string
,
params
[]
interface
{})
(
json
.
RawMessage
,
error
)
{
b
ackend
.
lock
.
Lock
()
defer
b
ackend
.
lock
.
Unlock
()
func
(
b
*
rpcBackend
)
request
(
method
string
,
params
[]
interface
{})
(
json
.
RawMessage
,
error
)
{
b
.
lock
.
Lock
()
defer
b
.
lock
.
Unlock
()
// Ugly hack to serialize an empty list properly
if
params
==
nil
{
...
...
@@ -81,16 +84,16 @@ func (backend *rpcBackend) request(method string, params []interface{}) (json.Ra
}
// Assemble the request object
req
:=
&
request
{
J
sonRpc
:
"2.0"
,
I
d
:
int
(
atomic
.
AddUint32
(
&
backend
.
autoid
,
1
)),
J
SONRPC
:
"2.0"
,
I
D
:
int
(
atomic
.
AddUint32
(
&
b
.
autoid
,
1
)),
Method
:
method
,
Params
:
params
,
}
if
err
:=
b
ackend
.
client
.
Send
(
req
);
err
!=
nil
{
if
err
:=
b
.
client
.
Send
(
req
);
err
!=
nil
{
return
nil
,
err
}
res
:=
new
(
response
)
if
err
:=
b
ackend
.
client
.
Recv
(
res
);
err
!=
nil
{
if
err
:=
b
.
client
.
Recv
(
res
);
err
!=
nil
{
return
nil
,
err
}
if
len
(
res
.
Error
)
>
0
{
...
...
@@ -127,9 +130,9 @@ func (b *rpcBackend) ContractCall(contract common.Address, data []byte, pending
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
)
{
//
PendingAccountNonce implements ContractTransactor.PendingAccountNonce, delegating
//
the
current account nonce retrieval to the remote node.
func
(
b
*
rpcBackend
)
Pending
AccountNonce
(
account
common
.
Address
)
(
uint64
,
error
)
{
res
,
err
:=
b
.
request
(
"eth_getTransactionCount"
,
[]
interface
{}{
account
.
Hex
(),
"pending"
})
if
err
!=
nil
{
return
0
,
err
...
...
@@ -138,12 +141,16 @@ func (b *rpcBackend) AccountNonce(account common.Address) (uint64, error) {
if
err
:=
json
.
Unmarshal
(
res
,
&
hex
);
err
!=
nil
{
return
0
,
err
}
return
new
(
big
.
Int
)
.
SetBytes
(
common
.
FromHex
(
hex
))
.
Uint64
(),
nil
nonce
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
hex
,
0
)
if
!
ok
{
return
0
,
fmt
.
Errorf
(
"invalid nonce hex: %s"
,
hex
)
}
return
nonce
.
Uint64
(),
nil
}
//
GasPrice implements ContractTransactor.GasPrice, delegating the gas pric
e
// oracle request to the remote node.
func
(
b
*
rpcBackend
)
GasPrice
()
(
*
big
.
Int
,
error
)
{
//
SuggestGasPrice implements ContractTransactor.SuggestGasPrice, delegating th
e
//
gas price
oracle request to the remote node.
func
(
b
*
rpcBackend
)
Suggest
GasPrice
()
(
*
big
.
Int
,
error
)
{
res
,
err
:=
b
.
request
(
"eth_gasPrice"
,
nil
)
if
err
!=
nil
{
return
nil
,
err
...
...
@@ -152,12 +159,16 @@ func (b *rpcBackend) GasPrice() (*big.Int, error) {
if
err
:=
json
.
Unmarshal
(
res
,
&
hex
);
err
!=
nil
{
return
nil
,
err
}
return
new
(
big
.
Int
)
.
SetBytes
(
common
.
FromHex
(
hex
)),
nil
price
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
hex
,
0
)
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"invalid price hex: %s"
,
hex
)
}
return
price
,
nil
}
//
GasLimit implements ContractTransactor.GasLimit, delegating the gas estimation
// to the remote node.
func
(
b
*
rpcBackend
)
GasLimit
(
sender
common
.
Address
,
contract
*
common
.
Address
,
value
*
big
.
Int
,
data
[]
byte
)
(
*
big
.
Int
,
error
)
{
//
EstimateGasLimit implements ContractTransactor.EstimateGasLimit, delegating
// t
he gas estimation t
o the remote node.
func
(
b
*
rpcBackend
)
Estimate
GasLimit
(
sender
common
.
Address
,
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"`
...
...
@@ -179,12 +190,15 @@ func (b *rpcBackend) GasLimit(sender common.Address, contract *common.Address, v
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
estimate
,
ok
:=
new
(
big
.
Int
)
.
SetString
(
hex
,
0
)
if
!
ok
{
return
nil
,
fmt
.
Errorf
(
"invalid estimate hex: %s"
,
hex
)
}
return
estimate
,
nil
}
//
Transact implements ContractTransactor.SendTransaction, delegating the raw
// transaction injection to the remote node.
//
SendTransaction 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
{
...
...
accounts/abi/bind/backends/simulated.go
View file @
73308dbe
...
...
@@ -19,6 +19,7 @@ package backends
import
(
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/state"
...
...
@@ -27,6 +28,9 @@ import (
"github.com/ethereum/go-ethereum/event"
)
// This nil assignment ensures compile time that SimulatedBackend implements bind.ContractBackend.
var
_
bind
.
ContractBackend
=
(
*
SimulatedBackend
)(
nil
)
// SimulatedBackend implements bind.ContractBackend, simulating a blockchain in
// the background. Its main purpose is to allow easily testing contract bindings.
type
SimulatedBackend
struct
{
...
...
@@ -79,13 +83,11 @@ func (b *SimulatedBackend) ContractCall(contract common.Address, data []byte, pe
statedb
*
state
.
StateDB
)
if
pending
{
block
,
statedb
=
b
.
pendingBlock
,
b
.
pendingState
block
,
statedb
=
b
.
pendingBlock
,
b
.
pendingState
.
Copy
()
}
else
{
block
=
b
.
blockchain
.
CurrentBlock
()
statedb
,
_
=
b
.
blockchain
.
State
()
}
statedb
=
statedb
.
Copy
()
// Set infinite balance to the a fake caller account
from
:=
statedb
.
GetOrNewStateObject
(
common
.
Address
{})
from
.
SetBalance
(
common
.
MaxBig
)
...
...
@@ -100,28 +102,29 @@ func (b *SimulatedBackend) ContractCall(contract common.Address, data []byte, pe
data
:
data
,
}
// Execute the call and return
vmenv
:=
core
.
NewEnv
(
statedb
,
b
.
blockchain
,
msg
,
block
.
Header
())
vmenv
:=
core
.
NewEnv
(
statedb
,
b
.
blockchain
,
msg
,
block
.
Header
()
,
nil
)
gaspool
:=
new
(
core
.
GasPool
)
.
AddGas
(
common
.
MaxBig
)
out
,
_
,
err
:=
core
.
ApplyMessage
(
vmenv
,
msg
,
gaspool
)
return
out
,
err
}
//
AccountNonce implements ContractTransactor.AccountNonce, retrieving the nonce
// currently pending for the account.
func
(
b
*
SimulatedBackend
)
AccountNonce
(
account
common
.
Address
)
(
uint64
,
error
)
{
//
PendingAccountNonce implements ContractTransactor.PendingAccountNonce, retrieving
//
the nonce
currently pending for the account.
func
(
b
*
SimulatedBackend
)
Pending
AccountNonce
(
account
common
.
Address
)
(
uint64
,
error
)
{
return
b
.
pendingState
.
GetOrNewStateObject
(
account
)
.
Nonce
(),
nil
}
//
GasPrice implements ContractTransactor.GasPrice. Since the simulated chain
// doens't have miners, we just return a gas price of 1 for any call.
func
(
b
*
SimulatedBackend
)
GasPrice
()
(
*
big
.
Int
,
error
)
{
//
SuggestGasPrice implements ContractTransactor.SuggestGasPrice. Since the simulated
//
chain
doens't have miners, we just return a gas price of 1 for any call.
func
(
b
*
SimulatedBackend
)
Suggest
GasPrice
()
(
*
big
.
Int
,
error
)
{
return
big
.
NewInt
(
1
),
nil
}
// GasLimit implements ContractTransactor.GasLimit, executing the requested code
// against the currently pending block/state and returning the used gas.
func
(
b
*
SimulatedBackend
)
GasLimit
(
sender
common
.
Address
,
contract
*
common
.
Address
,
value
*
big
.
Int
,
data
[]
byte
)
(
*
big
.
Int
,
error
)
{
// EstimateGasLimit implements ContractTransactor.EstimateGasLimit, executing the
// requested code against the currently pending block/state and returning the used
// gas.
func
(
b
*
SimulatedBackend
)
EstimateGasLimit
(
sender
common
.
Address
,
contract
*
common
.
Address
,
value
*
big
.
Int
,
data
[]
byte
)
(
*
big
.
Int
,
error
)
{
// Create a copy of the currently pending state db to screw around with
var
(
block
=
b
.
pendingBlock
...
...
@@ -142,14 +145,14 @@ func (b *SimulatedBackend) GasLimit(sender common.Address, contract *common.Addr
data
:
data
,
}
// Execute the call and return
vmenv
:=
core
.
NewEnv
(
statedb
,
b
.
blockchain
,
msg
,
block
.
Header
())
vmenv
:=
core
.
NewEnv
(
statedb
,
b
.
blockchain
,
msg
,
block
.
Header
()
,
nil
)
gaspool
:=
new
(
core
.
GasPool
)
.
AddGas
(
common
.
MaxBig
)
_
,
gas
,
err
:=
core
.
ApplyMessage
(
vmenv
,
msg
,
gaspool
)
return
gas
,
err
}
//
Transact
implements ContractTransactor.SendTransaction, delegating the raw
//
SendTransaction
implements ContractTransactor.SendTransaction, delegating the raw
// transaction injection to the remote node.
func
(
b
*
SimulatedBackend
)
SendTransaction
(
tx
*
types
.
Transaction
)
error
{
blocks
,
_
:=
core
.
GenerateChain
(
b
.
blockchain
.
CurrentBlock
(),
b
.
database
,
1
,
func
(
number
int
,
block
*
core
.
BlockGen
)
{
...
...
accounts/abi/bind/base.go
View file @
73308dbe
...
...
@@ -39,7 +39,7 @@ type CallOpts struct {
// 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
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)
...
...
@@ -72,12 +72,8 @@ 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
)
)
c
:=
NewBoundContract
(
common
.
Address
{},
abi
,
backend
,
backend
)
input
,
err
:=
c
.
abi
.
Pack
(
""
,
params
...
)
if
err
!=
nil
{
...
...
@@ -87,7 +83,7 @@ func DeployContract(opts *TransactOpts, abi abi.ABI, bytecode []byte, backend Co
if
err
!=
nil
{
return
common
.
Address
{},
nil
,
nil
,
err
}
c
.
address
=
crypto
.
CreateAddress
(
opts
.
Account
,
tx
.
Nonce
())
c
.
address
=
crypto
.
CreateAddress
(
opts
.
From
,
tx
.
Nonce
())
return
c
.
address
,
tx
,
c
,
nil
}
...
...
@@ -115,10 +111,6 @@ func (c *BoundContract) Call(opts *CallOpts, result interface{}, method string,
// 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
*
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
{
...
...
@@ -139,7 +131,7 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
}
nonce
:=
uint64
(
0
)
if
opts
.
Nonce
==
nil
{
nonce
,
err
=
c
.
transactor
.
AccountNonce
(
opts
.
Account
)
nonce
,
err
=
c
.
transactor
.
PendingAccountNonce
(
opts
.
From
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to retrieve account nonce: %v"
,
err
)
}
...
...
@@ -149,14 +141,14 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
// Figure out the gas allowance and gas price values
gasPrice
:=
opts
.
GasPrice
if
gasPrice
==
nil
{
gasPrice
,
err
=
c
.
transactor
.
GasPrice
()
gasPrice
,
err
=
c
.
transactor
.
Suggest
GasPrice
()
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to suggest gas price: %v"
,
err
)
}
}
gasLimit
:=
opts
.
GasLimit
if
gasLimit
==
nil
{
gasLimit
,
err
=
c
.
transactor
.
GasLimit
(
opts
.
Account
,
contract
,
value
,
input
)
gasLimit
,
err
=
c
.
transactor
.
EstimateGasLimit
(
opts
.
From
,
contract
,
value
,
input
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to exstimate gas needed: %v"
,
err
)
}
...
...
@@ -171,7 +163,7 @@ func (c *BoundContract) transact(opts *TransactOpts, contract *common.Address, i
if
opts
.
Signer
==
nil
{
return
nil
,
errors
.
New
(
"no signer to authorize the transaction with"
)
}
signedTx
,
err
:=
opts
.
Signer
(
opts
.
Account
,
rawTx
)
signedTx
,
err
:=
opts
.
Signer
(
opts
.
From
,
rawTx
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
accounts/abi/bind/bind.go
View file @
73308dbe
This diff is collapsed.
Click to expand it.
accounts/abi/bind/bind_test.go
View file @
73308dbe
This diff is collapsed.
Click to expand it.
accounts/abi/bind/template.go
0 → 100644
View file @
73308dbe
This diff is collapsed.
Click to expand it.
cmd/abigen/main.go
View file @
73308dbe
...
...
@@ -17,40 +17,80 @@
package
main
import
(
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"os"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common/compiler"
)
var
(
abiFlag
=
flag
.
String
(
"abi"
,
""
,
"Path to the Ethereum contract ABI json to bind"
)
binFlag
=
flag
.
String
(
"bin"
,
""
,
"Path to the Ethereum contract bytecode (generate deploy method)"
)
pkgFlag
=
flag
.
String
(
"pkg"
,
""
,
"Go package name to generate the binding into"
)
typFlag
=
flag
.
String
(
"type"
,
""
,
"Go struct name for the binding (default = package name)"
)
outFlag
=
flag
.
String
(
"out"
,
""
,
"Output path for the generated binding (default = stdout)"
)
solFlag
=
flag
.
String
(
"sol"
,
""
,
"Path to the Ethereum contract Solidity source to build and bind"
)
solcFlag
=
flag
.
String
(
"solc"
,
"solc"
,
"Solidity compiler to use if source builds are requested"
)
pkgFlag
=
flag
.
String
(
"pkg"
,
""
,
"Go package name to generate the binding into"
)
outFlag
=
flag
.
String
(
"out"
,
""
,
"Output file for the generated binding (default = stdout)"
)
)
func
main
()
{
// Parse and
validate the command line flags
// Parse and
ensure all needed inputs are specified
flag
.
Parse
()
if
*
abiFlag
==
""
{
fmt
.
Printf
(
"No contract ABI path specified (--abi)
\n
"
)
if
*
abiFlag
==
""
&&
*
solFlag
==
""
{
fmt
.
Printf
(
"No contract ABI (--abi) or Solidity source (--sol) specified
\n
"
)
os
.
Exit
(
-
1
)
}
else
if
(
*
abiFlag
!=
""
||
*
binFlag
!=
""
||
*
typFlag
!=
""
)
&&
*
solFlag
!=
""
{
fmt
.
Printf
(
"Contract ABI (--abi), bytecode (--bin) and type (--type) flags are mutually exclusive with the Solidity source (--sol) flag
\n
"
)
os
.
Exit
(
-
1
)
}
if
*
pkgFlag
==
""
{
fmt
.
Printf
(
"No destination Go package specified (--pkg)
\n
"
)
os
.
Exit
(
-
1
)
}
// Read the ABI json from disk and optionally the contract bytecode too
// If the entire solidity code was specified, build and bind based on that
var
(
abis
[]
string
bins
[]
string
types
[]
string
)
if
*
solFlag
!=
""
{
solc
,
err
:=
compiler
.
New
(
*
solcFlag
)
if
err
!=
nil
{
fmt
.
Printf
(
"Failed to locate Solidity compiler: %v
\n
"
,
err
)
os
.
Exit
(
-
1
)
}
source
,
err
:=
ioutil
.
ReadFile
(
*
solFlag
)
if
err
!=
nil
{
fmt
.
Printf
(
"Failed to read Soldity source code: %v
\n
"
,
err
)
os
.
Exit
(
-
1
)
}
contracts
,
err
:=
solc
.
Compile
(
string
(
source
))
if
err
!=
nil
{
fmt
.
Printf
(
"Failed to build Solidity contract: %v
\n
"
,
err
)
os
.
Exit
(
-
1
)
}
for
name
,
contract
:=
range
contracts
{
abi
,
_
:=
json
.
Marshal
(
contract
.
Info
.
AbiDefinition
)
// Flatten the compiler parse
abis
=
append
(
abis
,
string
(
abi
))
bins
=
append
(
bins
,
contract
.
Code
)
types
=
append
(
types
,
name
)
}
}
else
{
// Otherwise load up the ABI, optional bytecode and type name from the parameters
abi
,
err
:=
ioutil
.
ReadFile
(
*
abiFlag
)
if
err
!=
nil
{
fmt
.
Printf
(
"Failed to read input ABI: %v
\n
"
,
err
)
os
.
Exit
(
-
1
)
}
abis
=
append
(
abis
,
string
(
abi
))
bin
:=
[]
byte
{}
if
*
binFlag
!=
""
{
if
bin
,
err
=
ioutil
.
ReadFile
(
*
binFlag
);
err
!=
nil
{
...
...
@@ -58,12 +98,16 @@ func main() {
os
.
Exit
(
-
1
)
}
}
// Generate the contract binding
bins
=
append
(
bins
,
string
(
bin
))
kind
:=
*
typFlag
if
kind
==
""
{
kind
=
*
pkgFlag
}
code
,
err
:=
bind
.
Bind
(
string
(
abi
),
string
(
bin
),
*
pkgFlag
,
kind
)
types
=
append
(
types
,
kind
)
}
// Generate the contract binding
code
,
err
:=
bind
.
Bind
(
types
,
abis
,
bins
,
*
pkgFlag
)
if
err
!=
nil
{
fmt
.
Printf
(
"Failed to generate ABI binding: %v
\n
"
,
err
)
os
.
Exit
(
-
1
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment