From 8d9141ed9a3dec321ffd184a039d1959c3257ddd Mon Sep 17 00:00:00 2001 From: Felix Lange Date: Fri, 5 Aug 2016 13:25:52 +0200 Subject: [PATCH] ethereum: add new Go API interfaces --- interfaces.go | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 interfaces.go diff --git a/interfaces.go b/interfaces.go new file mode 100644 index 0000000000..921d026164 --- /dev/null +++ b/interfaces.go @@ -0,0 +1,168 @@ +// Copyright 2016 The go-ethereum Authors +// 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 . + +// Package ethereum defines interfaces for interacting with Ethereum. +package ethereum + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "golang.org/x/net/context" +) + +// TODO: move subscription to package event + +// Subscription represents an event subscription where events are +// delivered on a data channel. +type Subscription interface { + // Unsubscribe cancels the sending of events to the data channel + // and closes the error channel. + Unsubscribe() + // Err returns the subscription error channel. The error channel receives + // a value if there is an issue with the subscription (e.g. the network connection + // delivering the events has been closed). Only one value will ever be sent. + // The error channel is closed by Unsubscribe. + Err() <-chan error +} + +// ChainReader provides access to the blockchain. The methods in this interface access raw +// data from either the canonical chain (when requesting by block number) or any +// blockchain fork that was previously downloaded and processed by the node. The block +// number argument can be nil to select the latest canonical block. Reading block headers +// should be preferred over full blocks whenever possible. +type ChainReader interface { + BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) + BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) + HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) + HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) + TransactionCount(ctx context.Context, blockHash common.Hash) (uint, error) + TransactionInBlock(ctx context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) + TransactionByHash(ctx context.Context, txHash common.Hash) (*types.Transaction, error) + TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) +} + +// ChainStateReader wraps access to the state trie of the canonical blockchain. Note that +// implementations of the interface may be unable to return state values for old blocks. +// In many cases, using CallContract can be preferable to reading raw contract storage. +type ChainStateReader interface { + BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) + StorageAt(ctx context.Context, account common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) + CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) + NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) +} + +// A ChainHeadEventer returns notifications whenever the canonical head block is updated. +type ChainHeadEventer interface { + SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (Subscription, error) +} + +// CallMsg contains parameters for contract calls. +type CallMsg struct { + From common.Address // the sender of the 'transaction' + To *common.Address // the destination contract (nil for contract creation) + Gas *big.Int // if nil, the call executes with near-infinite gas + GasPrice *big.Int // wei <-> gas exchange ratio + Value *big.Int // amount of wei sent along with the call + Data []byte // input data, usually an ABI-encoded contract method invocation +} + +// A ContractCaller provides contract calls, essentially transactions that are executed by +// the EVM but not mined into the blockchain. ContractCall is a low-level method to +// execute such calls. For applications which are structured around specific contracts, +// the abigen tool provides a nicer, properly typed way to perform calls. +type ContractCaller interface { + CallContract(ctx context.Context, call CallMsg, blockNumber *big.Int) ([]byte, error) +} + +// FilterQuery contains options for contact log filtering. +type FilterQuery struct { + FromBlock *big.Int // beginning of the queried range, nil means genesis block + ToBlock *big.Int // end of the range, nil means latest block + Addresses []common.Address // restricts matches to events created by specific contracts + + // The Topic list restricts matches to particular event topics. Each event has a list + // of topics. Topics matches a prefix of that list. An empty element slice matches any + // topic. Non-empty elements represent an alternative that matches any of the + // contained topics. + // + // Examples: + // {} or nil matches any topic list + // {{A}} matches topic A in first position + // {{}, {B}} matches any topic in first position, B in second position + // {{A}}, {B}} matches topic A in first position, B in second position + // {{A, B}}, {C, D}} matches topic (A OR B) in first position, (C OR D) in second position + Topics [][]common.Hash +} + +// LogFilterer provides access to contract log events using a one-off query or continuous +// event subscription. +type LogFilterer interface { + FilterLogs(ctx context.Context, q FilterQuery) ([]vm.Log, error) + SubscribeFilterLogs(ctx context.Context, q FilterQuery, ch chan<- vm.Log) (Subscription, error) +} + +// TransactionSender wraps transaction sending. The SendTransaction method injects a +// signed transaction into the pending transaction pool for execution. If the transaction +// was a contract creation, the TransactionReceipt method can be used to retrieve the +// contract address after the transaction has been mined. +// +// The transaction must be signed and have a valid nonce to be included. Consumers of the +// API can use package accounts to maintain local private keys and need can retrieve the +// next available nonce using PendingNonceAt. +type TransactionSender interface { + SendTransaction(ctx context.Context, tx *types.Transaction) error +} + +// GasPricer wraps the gas price oracle, which monitors the blockchain to determine the +// optimal gas price given current fee market conditions. +type GasPricer interface { + SuggestGasPrice(ctx context.Context) (*big.Int, error) +} + +// A PendingStateReader provides access to the pending state, which is the result of all +// known executable transactions which have not yet been included in the blockchain. It is +// commonly used to display the result of ’unconfirmed’ actions (e.g. wallet value +// transfers) initiated by the user. The PendingNonceAt operation is a good way to +// retrieve the next available transaction nonce for a specific account. +type PendingStateReader interface { + PendingBalanceAt(ctx context.Context, account common.Address) (*big.Int, error) + PendingStorageAt(ctx context.Context, account common.Address, key common.Hash) ([]byte, error) + PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) + PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) + PendingTransactionCount(ctx context.Context) (uint, error) +} + +// PendingContractCaller can be used to perform calls against the pending state. +type PendingContractCaller interface { + PendingCallContract(ctx context.Context, call CallMsg) ([]byte, error) +} + +// GasEstimator wraps EstimateGas, which tries to estimate the gas needed to execute a +// specific transaction based on the pending state. 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. +type GasEstimator interface { + EstimateGas(ctx context.Context, call CallMsg) (usedGas *big.Int, err error) +} + +// A PendingStateEventer provides access to real time notifications about changes to the +// pending state. +type PendingStateEventer interface { + SubscribePendingTransactions(ctx context.Context, ch chan<- *types.Transaction) (Subscription, error) +}