| 
									
										
										
										
											2016-11-09 02:01:56 +01:00
										 |  |  | // Copyright 2015 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | // 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 eth | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2017-03-22 18:20:33 +01:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | 	"math/big" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-22 14:01:28 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum" | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2016-12-17 15:39:55 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common/hexutil" | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core/types" | 
					
						
							| 
									
										
										
										
											2015-12-16 04:26:23 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/internal/ethapi" | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | 	"github.com/ethereum/go-ethereum/rlp" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/rpc" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // ContractBackend implements bind.ContractBackend with direct calls to Ethereum | 
					
						
							|  |  |  | // internals to support operating on contracts within subprotocols like eth and | 
					
						
							|  |  |  | // swarm. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // Internally this backend uses the already exposed API endpoints of the Ethereum | 
					
						
							|  |  |  | // object. These should be rewritten to internal Go method calls when the Go API | 
					
						
							|  |  |  | // is refactored to support a clean library use. | 
					
						
							|  |  |  | type ContractBackend struct { | 
					
						
							| 
									
										
										
										
											2015-12-16 04:26:23 +01:00
										 |  |  | 	eapi  *ethapi.PublicEthereumAPI        // Wrapper around the Ethereum object to access metadata | 
					
						
							|  |  |  | 	bcapi *ethapi.PublicBlockChainAPI      // Wrapper around the blockchain to access chain data | 
					
						
							|  |  |  | 	txapi *ethapi.PublicTransactionPoolAPI // Wrapper around the transaction pool to access transaction data | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // NewContractBackend creates a new native contract backend using an existing | 
					
						
							|  |  |  | // Etheruem object. | 
					
						
							| 
									
										
										
										
											2016-01-13 19:35:48 +01:00
										 |  |  | func NewContractBackend(apiBackend ethapi.Backend) *ContractBackend { | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | 	return &ContractBackend{ | 
					
						
							| 
									
										
										
										
											2016-01-13 19:35:48 +01:00
										 |  |  | 		eapi:  ethapi.NewPublicEthereumAPI(apiBackend), | 
					
						
							|  |  |  | 		bcapi: ethapi.NewPublicBlockChainAPI(apiBackend), | 
					
						
							| 
									
										
										
										
											2017-05-25 17:08:13 +02:00
										 |  |  | 		txapi: ethapi.NewPublicTransactionPoolAPI(apiBackend, new(ethapi.AddrLocker)), | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-22 14:01:28 +02:00
										 |  |  | // CodeAt retrieves any code associated with the contract from the local API. | 
					
						
							|  |  |  | func (b *ContractBackend) CodeAt(ctx context.Context, contract common.Address, blockNum *big.Int) ([]byte, error) { | 
					
						
							| 
									
										
										
										
											2017-06-27 15:57:06 +02:00
										 |  |  | 	return b.bcapi.GetCode(ctx, contract, toBlockNumber(blockNum)) | 
					
						
							| 
									
										
										
										
											2016-08-22 14:01:28 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // CodeAt retrieves any code associated with the contract from the local API. | 
					
						
							|  |  |  | func (b *ContractBackend) PendingCodeAt(ctx context.Context, contract common.Address) ([]byte, error) { | 
					
						
							| 
									
										
										
										
											2017-06-27 15:57:06 +02:00
										 |  |  | 	return b.bcapi.GetCode(ctx, contract, rpc.PendingBlockNumber) | 
					
						
							| 
									
										
										
										
											2016-05-20 12:29:28 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | // ContractCall implements bind.ContractCaller executing an Ethereum contract | 
					
						
							|  |  |  | // call with the specified data as the input. The pending flag requests execution | 
					
						
							|  |  |  | // against the pending block, not the stable head of the chain. | 
					
						
							| 
									
										
										
										
											2016-08-22 14:01:28 +02:00
										 |  |  | func (b *ContractBackend) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNum *big.Int) ([]byte, error) { | 
					
						
							|  |  |  | 	out, err := b.bcapi.Call(ctx, toCallArgs(msg), toBlockNumber(blockNum)) | 
					
						
							| 
									
										
										
										
											2017-01-04 20:17:24 +01:00
										 |  |  | 	return out, err | 
					
						
							| 
									
										
										
										
											2016-08-22 14:01:28 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // ContractCall implements bind.ContractCaller executing an Ethereum contract | 
					
						
							|  |  |  | // call with the specified data as the input. The pending flag requests execution | 
					
						
							|  |  |  | // against the pending block, not the stable head of the chain. | 
					
						
							|  |  |  | func (b *ContractBackend) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) { | 
					
						
							|  |  |  | 	out, err := b.bcapi.Call(ctx, toCallArgs(msg), rpc.PendingBlockNumber) | 
					
						
							| 
									
										
										
										
											2017-01-04 20:17:24 +01:00
										 |  |  | 	return out, err | 
					
						
							| 
									
										
										
										
											2016-08-22 14:01:28 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func toCallArgs(msg ethereum.CallMsg) ethapi.CallArgs { | 
					
						
							| 
									
										
										
										
											2015-12-16 04:26:23 +01:00
										 |  |  | 	args := ethapi.CallArgs{ | 
					
						
							| 
									
										
										
										
											2016-08-22 14:01:28 +02:00
										 |  |  | 		To:   msg.To, | 
					
						
							|  |  |  | 		From: msg.From, | 
					
						
							| 
									
										
										
										
											2016-12-20 14:31:10 +01:00
										 |  |  | 		Data: msg.Data, | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-08-22 14:01:28 +02:00
										 |  |  | 	if msg.Gas != nil { | 
					
						
							| 
									
										
										
										
											2016-12-17 15:39:55 +01:00
										 |  |  | 		args.Gas = hexutil.Big(*msg.Gas) | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-08-22 14:01:28 +02:00
										 |  |  | 	if msg.GasPrice != nil { | 
					
						
							| 
									
										
										
										
											2016-12-17 15:39:55 +01:00
										 |  |  | 		args.GasPrice = hexutil.Big(*msg.GasPrice) | 
					
						
							| 
									
										
										
										
											2016-08-22 14:01:28 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if msg.Value != nil { | 
					
						
							| 
									
										
										
										
											2016-12-17 15:39:55 +01:00
										 |  |  | 		args.Value = hexutil.Big(*msg.Value) | 
					
						
							| 
									
										
										
										
											2016-08-22 14:01:28 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return args | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func toBlockNumber(num *big.Int) rpc.BlockNumber { | 
					
						
							|  |  |  | 	if num == nil { | 
					
						
							|  |  |  | 		return rpc.LatestBlockNumber | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return rpc.BlockNumber(num.Int64()) | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // PendingAccountNonce implements bind.ContractTransactor retrieving the current | 
					
						
							|  |  |  | // pending nonce associated with an account. | 
					
						
							| 
									
										
										
										
											2016-12-17 15:39:55 +01:00
										 |  |  | func (b *ContractBackend) PendingNonceAt(ctx context.Context, account common.Address) (nonce uint64, err error) { | 
					
						
							| 
									
										
										
										
											2015-12-16 04:26:23 +01:00
										 |  |  | 	out, err := b.txapi.GetTransactionCount(ctx, account, rpc.PendingBlockNumber) | 
					
						
							| 
									
										
										
										
											2016-12-17 15:39:55 +01:00
										 |  |  | 	if out != nil { | 
					
						
							|  |  |  | 		nonce = uint64(*out) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nonce, err | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // SuggestGasPrice implements bind.ContractTransactor retrieving the currently | 
					
						
							|  |  |  | // suggested gas price to allow a timely execution of a transaction. | 
					
						
							| 
									
										
										
										
											2015-12-16 04:26:23 +01:00
										 |  |  | func (b *ContractBackend) SuggestGasPrice(ctx context.Context) (*big.Int, error) { | 
					
						
							|  |  |  | 	return b.eapi.GasPrice(ctx) | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // EstimateGasLimit implements bind.ContractTransactor triing 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. | 
					
						
							| 
									
										
										
										
											2016-08-22 14:01:28 +02:00
										 |  |  | func (b *ContractBackend) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (*big.Int, error) { | 
					
						
							|  |  |  | 	out, err := b.bcapi.EstimateGas(ctx, toCallArgs(msg)) | 
					
						
							| 
									
										
										
										
											2016-12-17 15:39:55 +01:00
										 |  |  | 	return out.ToInt(), err | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // SendTransaction implements bind.ContractTransactor injects the transaction | 
					
						
							|  |  |  | // into the pending pool for execution. | 
					
						
							| 
									
										
										
										
											2015-12-16 04:26:23 +01:00
										 |  |  | func (b *ContractBackend) SendTransaction(ctx context.Context, tx *types.Transaction) error { | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | 	raw, _ := rlp.EncodeToBytes(tx) | 
					
						
							| 
									
										
										
										
											2016-12-20 14:31:10 +01:00
										 |  |  | 	_, err := b.txapi.SendRawTransaction(ctx, raw) | 
					
						
							| 
									
										
										
										
											2016-04-28 12:00:11 +03:00
										 |  |  | 	return err | 
					
						
							|  |  |  | } |