github.com/ethereumproject/go-ethereum@v5.5.2+incompatible/eth/bind.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package eth 18 19 import ( 20 "math/big" 21 22 "github.com/ethereumproject/go-ethereum/common" 23 "github.com/ethereumproject/go-ethereum/core/types" 24 "github.com/ethereumproject/go-ethereum/rlp" 25 "github.com/ethereumproject/go-ethereum/rpc" 26 ) 27 28 // ContractBackend implements bind.ContractBackend with direct calls to Ethereum 29 // internals to support operating on contracts within subprotocols like eth and 30 // swarm. 31 // 32 // Internally this backend uses the already exposed API endpoints of the Ethereum 33 // object. These should be rewritten to internal Go method calls when the Go API 34 // is refactored to support a clean library use. 35 type ContractBackend struct { 36 eapi *PublicEthereumAPI // Wrapper around the Ethereum object to access metadata 37 bcapi *PublicBlockChainAPI // Wrapper around the blockchain to access chain data 38 txapi *PublicTransactionPoolAPI // Wrapper around the transaction pool to access transaction data 39 } 40 41 // NewContractBackend creates a new native contract backend using an existing 42 // Etheruem object. 43 func NewContractBackend(eth *Ethereum) *ContractBackend { 44 return &ContractBackend{ 45 eapi: NewPublicEthereumAPI(eth), 46 bcapi: NewPublicBlockChainAPI(eth.chainConfig, eth.blockchain, eth.miner, eth.chainDb, eth.gpo, eth.eventMux, eth.accountManager), 47 txapi: NewPublicTransactionPoolAPI(eth), 48 } 49 } 50 51 // HasCode implements bind.ContractVerifier.HasCode by retrieving any code associated 52 // with the contract from the local API, and checking its size. 53 func (b *ContractBackend) HasCode(contract common.Address, pending bool) (bool, error) { 54 block := rpc.LatestBlockNumber 55 if pending { 56 block = rpc.PendingBlockNumber 57 } 58 out, err := b.bcapi.GetCode(contract, block) 59 return len(common.FromHex(out)) > 0, err 60 } 61 62 // ContractCall implements bind.ContractCaller executing an Ethereum contract 63 // call with the specified data as the input. The pending flag requests execution 64 // against the pending block, not the stable head of the chain. 65 func (b *ContractBackend) ContractCall(contract common.Address, data []byte, pending bool) ([]byte, error) { 66 // Convert the input args to the API spec 67 args := CallArgs{ 68 To: &contract, 69 Data: common.ToHex(data), 70 } 71 block := rpc.LatestBlockNumber 72 if pending { 73 block = rpc.PendingBlockNumber 74 } 75 // Execute the call and convert the output back to Go types 76 out, err := b.bcapi.Call(args, block) 77 return common.FromHex(out), err 78 } 79 80 // PendingAccountNonce implements bind.ContractTransactor retrieving the current 81 // pending nonce associated with an account. 82 func (b *ContractBackend) PendingAccountNonce(account common.Address) (uint64, error) { 83 out, err := b.txapi.GetTransactionCount(account, rpc.PendingBlockNumber) 84 return out.Uint64(), err 85 } 86 87 // SuggestGasPrice implements bind.ContractTransactor retrieving the currently 88 // suggested gas price to allow a timely execution of a transaction. 89 func (b *ContractBackend) SuggestGasPrice() (*big.Int, error) { 90 return b.eapi.GasPrice(), nil 91 } 92 93 // EstimateGasLimit implements bind.ContractTransactor triing to estimate the gas 94 // needed to execute a specific transaction based on the current pending state of 95 // the backend blockchain. There is no guarantee that this is the true gas limit 96 // requirement as other transactions may be added or removed by miners, but it 97 // should provide a basis for setting a reasonable default. 98 func (b *ContractBackend) EstimateGasLimit(sender common.Address, contract *common.Address, value *big.Int, data []byte) (*big.Int, error) { 99 out, err := b.bcapi.EstimateGas(CallArgs{ 100 From: sender, 101 To: contract, 102 Value: *rpc.NewHexNumber(value), 103 Data: common.ToHex(data), 104 }) 105 return out.BigInt(), err 106 } 107 108 // SendTransaction implements bind.ContractTransactor injects the transaction 109 // into the pending pool for execution. 110 func (b *ContractBackend) SendTransaction(tx *types.Transaction) error { 111 raw, _ := rlp.EncodeToBytes(tx) 112 _, err := b.txapi.SendRawTransaction(common.ToHex(raw)) 113 return err 114 }