forked from cerc-io/plugeth
graphql: Updates to graphql support to match EIP1767 (#19238)
Updates to match EIP1767
This commit is contained in:
parent
6e401792ce
commit
acebccc3bf
@ -19,6 +19,7 @@ package graphql
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -43,6 +44,9 @@ import (
|
|||||||
"github.com/graph-gophers/graphql-go/relay"
|
"github.com/graph-gophers/graphql-go/relay"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var OnlyOnMainChainError = errors.New("This operation is only available for blocks on the canonical chain.")
|
||||||
|
var BlockInvariantError = errors.New("Block objects must be instantiated with at least one of num or hash.")
|
||||||
|
|
||||||
// Account represents an Ethereum account at a particular block.
|
// Account represents an Ethereum account at a particular block.
|
||||||
type Account struct {
|
type Account struct {
|
||||||
backend *eth.EthAPIBackend
|
backend *eth.EthAPIBackend
|
||||||
@ -144,8 +148,9 @@ func (t *Transaction) resolve(ctx context.Context) (*types.Transaction, error) {
|
|||||||
if tx != nil {
|
if tx != nil {
|
||||||
t.tx = tx
|
t.tx = tx
|
||||||
t.block = &Block{
|
t.block = &Block{
|
||||||
backend: t.backend,
|
backend: t.backend,
|
||||||
hash: blockHash,
|
hash: blockHash,
|
||||||
|
canonical: unknown,
|
||||||
}
|
}
|
||||||
t.index = index
|
t.index = index
|
||||||
} else {
|
} else {
|
||||||
@ -332,16 +337,47 @@ func (t *Transaction) Logs(ctx context.Context) (*[]*Log, error) {
|
|||||||
return &ret, nil
|
return &ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block represennts an Ethereum block.
|
type BlockType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
unknown BlockType = iota
|
||||||
|
isCanonical
|
||||||
|
notCanonical
|
||||||
|
)
|
||||||
|
|
||||||
|
// Block represents an Ethereum block.
|
||||||
// backend, and either num or hash are mandatory. All other fields are lazily fetched
|
// backend, and either num or hash are mandatory. All other fields are lazily fetched
|
||||||
// when required.
|
// when required.
|
||||||
type Block struct {
|
type Block struct {
|
||||||
backend *eth.EthAPIBackend
|
backend *eth.EthAPIBackend
|
||||||
num *rpc.BlockNumber
|
num *rpc.BlockNumber
|
||||||
hash common.Hash
|
hash common.Hash
|
||||||
header *types.Header
|
header *types.Header
|
||||||
block *types.Block
|
block *types.Block
|
||||||
receipts []*types.Receipt
|
receipts []*types.Receipt
|
||||||
|
canonical BlockType // Indicates if this block is on the main chain or not.
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Block) onMainChain(ctx context.Context) error {
|
||||||
|
if b.canonical == unknown {
|
||||||
|
header, err := b.resolveHeader(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
canonHeader, err := b.backend.HeaderByNumber(ctx, rpc.BlockNumber(header.Number.Uint64()))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if header.Hash() == canonHeader.Hash() {
|
||||||
|
b.canonical = isCanonical
|
||||||
|
} else {
|
||||||
|
b.canonical = notCanonical
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if b.canonical != isCanonical {
|
||||||
|
return OnlyOnMainChainError
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve returns the internal Block object representing this block, fetching
|
// resolve returns the internal Block object representing this block, fetching
|
||||||
@ -367,6 +403,10 @@ func (b *Block) resolve(ctx context.Context) (*types.Block, error) {
|
|||||||
// if necessary. Call this function instead of `resolve` unless you need the
|
// if necessary. Call this function instead of `resolve` unless you need the
|
||||||
// additional data (transactions and uncles).
|
// additional data (transactions and uncles).
|
||||||
func (b *Block) resolveHeader(ctx context.Context) (*types.Header, error) {
|
func (b *Block) resolveHeader(ctx context.Context) (*types.Header, error) {
|
||||||
|
if b.num == nil && b.hash == (common.Hash{}) {
|
||||||
|
return nil, BlockInvariantError
|
||||||
|
}
|
||||||
|
|
||||||
if b.header == nil {
|
if b.header == nil {
|
||||||
if _, err := b.resolve(ctx); err != nil {
|
if _, err := b.resolve(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -447,15 +487,18 @@ func (b *Block) Parent(ctx context.Context) (*Block, error) {
|
|||||||
if b.header != nil && b.block.NumberU64() > 0 {
|
if b.header != nil && b.block.NumberU64() > 0 {
|
||||||
num := rpc.BlockNumber(b.header.Number.Uint64() - 1)
|
num := rpc.BlockNumber(b.header.Number.Uint64() - 1)
|
||||||
return &Block{
|
return &Block{
|
||||||
backend: b.backend,
|
backend: b.backend,
|
||||||
num: &num,
|
num: &num,
|
||||||
hash: b.header.ParentHash,
|
hash: b.header.ParentHash,
|
||||||
|
canonical: unknown,
|
||||||
}, nil
|
}, nil
|
||||||
} else if b.num != nil && *b.num != 0 {
|
}
|
||||||
|
if b.num != nil && *b.num != 0 {
|
||||||
num := *b.num - 1
|
num := *b.num - 1
|
||||||
return &Block{
|
return &Block{
|
||||||
backend: b.backend,
|
backend: b.backend,
|
||||||
num: &num,
|
num: &num,
|
||||||
|
canonical: isCanonical,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -544,10 +587,11 @@ func (b *Block) Ommers(ctx context.Context) (*[]*Block, error) {
|
|||||||
for _, uncle := range block.Uncles() {
|
for _, uncle := range block.Uncles() {
|
||||||
blockNumber := rpc.BlockNumber(uncle.Number.Uint64())
|
blockNumber := rpc.BlockNumber(uncle.Number.Uint64())
|
||||||
ret = append(ret, &Block{
|
ret = append(ret, &Block{
|
||||||
backend: b.backend,
|
backend: b.backend,
|
||||||
num: &blockNumber,
|
num: &blockNumber,
|
||||||
hash: uncle.Hash(),
|
hash: uncle.Hash(),
|
||||||
header: uncle,
|
header: uncle,
|
||||||
|
canonical: notCanonical,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return &ret, nil
|
return &ret, nil
|
||||||
@ -672,10 +716,11 @@ func (b *Block) OmmerAt(ctx context.Context, args struct{ Index int32 }) (*Block
|
|||||||
uncle := uncles[args.Index]
|
uncle := uncles[args.Index]
|
||||||
blockNumber := rpc.BlockNumber(uncle.Number.Uint64())
|
blockNumber := rpc.BlockNumber(uncle.Number.Uint64())
|
||||||
return &Block{
|
return &Block{
|
||||||
backend: b.backend,
|
backend: b.backend,
|
||||||
num: &blockNumber,
|
num: &blockNumber,
|
||||||
hash: uncle.Hash(),
|
hash: uncle.Hash(),
|
||||||
header: uncle,
|
header: uncle,
|
||||||
|
canonical: notCanonical,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -744,6 +789,162 @@ func (b *Block) Logs(ctx context.Context, args struct{ Filter BlockFilterCriteri
|
|||||||
return runFilter(ctx, b.backend, filter)
|
return runFilter(ctx, b.backend, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Block) Account(ctx context.Context, args struct {
|
||||||
|
Address common.Address
|
||||||
|
}) (*Account, error) {
|
||||||
|
err := b.onMainChain(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.num == nil {
|
||||||
|
_, err := b.resolveHeader(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Account{
|
||||||
|
backend: b.backend,
|
||||||
|
address: args.Address,
|
||||||
|
blockNumber: *b.num,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CallData encapsulates arguments to `call` or `estimateGas`.
|
||||||
|
// All arguments are optional.
|
||||||
|
type CallData struct {
|
||||||
|
From *common.Address // The Ethereum address the call is from.
|
||||||
|
To *common.Address // The Ethereum address the call is to.
|
||||||
|
Gas *hexutil.Uint64 // The amount of gas provided for the call.
|
||||||
|
GasPrice *hexutil.Big // The price of each unit of gas, in wei.
|
||||||
|
Value *hexutil.Big // The value sent along with the call.
|
||||||
|
Data *hexutil.Bytes // Any data sent with the call.
|
||||||
|
}
|
||||||
|
|
||||||
|
// CallResult encapsulates the result of an invocation of the `call` accessor.
|
||||||
|
type CallResult struct {
|
||||||
|
data hexutil.Bytes // The return data from the call
|
||||||
|
gasUsed hexutil.Uint64 // The amount of gas used
|
||||||
|
status hexutil.Uint64 // The return status of the call - 0 for failure or 1 for success.
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CallResult) Data() hexutil.Bytes {
|
||||||
|
return c.data
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CallResult) GasUsed() hexutil.Uint64 {
|
||||||
|
return c.gasUsed
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *CallResult) Status() hexutil.Uint64 {
|
||||||
|
return c.status
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Block) Call(ctx context.Context, args struct {
|
||||||
|
Data ethapi.CallArgs
|
||||||
|
}) (*CallResult, error) {
|
||||||
|
err := b.onMainChain(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.num == nil {
|
||||||
|
_, err := b.resolveHeader(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result, gas, failed, err := ethapi.DoCall(ctx, b.backend, args.Data, *b.num, vm.Config{}, 5*time.Second)
|
||||||
|
status := hexutil.Uint64(1)
|
||||||
|
if failed {
|
||||||
|
status = 0
|
||||||
|
}
|
||||||
|
return &CallResult{
|
||||||
|
data: hexutil.Bytes(result),
|
||||||
|
gasUsed: hexutil.Uint64(gas),
|
||||||
|
status: status,
|
||||||
|
}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Block) EstimateGas(ctx context.Context, args struct {
|
||||||
|
Data ethapi.CallArgs
|
||||||
|
}) (hexutil.Uint64, error) {
|
||||||
|
err := b.onMainChain(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return hexutil.Uint64(0), err
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.num == nil {
|
||||||
|
_, err := b.resolveHeader(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return hexutil.Uint64(0), err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gas, err := ethapi.DoEstimateGas(ctx, b.backend, args.Data, *b.num)
|
||||||
|
return gas, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type Pending struct {
|
||||||
|
backend *eth.EthAPIBackend
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pending) TransactionCount(ctx context.Context) (int32, error) {
|
||||||
|
txs, err := p.backend.GetPoolTransactions()
|
||||||
|
return int32(len(txs)), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pending) Transactions(ctx context.Context) (*[]*Transaction, error) {
|
||||||
|
txs, err := p.backend.GetPoolTransactions()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := make([]*Transaction, 0, len(txs))
|
||||||
|
for i, tx := range txs {
|
||||||
|
ret = append(ret, &Transaction{
|
||||||
|
backend: p.backend,
|
||||||
|
hash: tx.Hash(),
|
||||||
|
tx: tx,
|
||||||
|
index: uint64(i),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return &ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pending) Account(ctx context.Context, args struct {
|
||||||
|
Address common.Address
|
||||||
|
}) *Account {
|
||||||
|
return &Account{
|
||||||
|
backend: p.backend,
|
||||||
|
address: args.Address,
|
||||||
|
blockNumber: rpc.PendingBlockNumber,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pending) Call(ctx context.Context, args struct {
|
||||||
|
Data ethapi.CallArgs
|
||||||
|
}) (*CallResult, error) {
|
||||||
|
result, gas, failed, err := ethapi.DoCall(ctx, p.backend, args.Data, rpc.PendingBlockNumber, vm.Config{}, 5*time.Second)
|
||||||
|
status := hexutil.Uint64(1)
|
||||||
|
if failed {
|
||||||
|
status = 0
|
||||||
|
}
|
||||||
|
return &CallResult{
|
||||||
|
data: hexutil.Bytes(result),
|
||||||
|
gasUsed: hexutil.Uint64(gas),
|
||||||
|
status: status,
|
||||||
|
}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Pending) EstimateGas(ctx context.Context, args struct {
|
||||||
|
Data ethapi.CallArgs
|
||||||
|
}) (hexutil.Uint64, error) {
|
||||||
|
return ethapi.DoEstimateGas(ctx, p.backend, args.Data, rpc.PendingBlockNumber)
|
||||||
|
}
|
||||||
|
|
||||||
// Resolver is the top-level object in the GraphQL hierarchy.
|
// Resolver is the top-level object in the GraphQL hierarchy.
|
||||||
type Resolver struct {
|
type Resolver struct {
|
||||||
backend *eth.EthAPIBackend
|
backend *eth.EthAPIBackend
|
||||||
@ -757,19 +958,22 @@ func (r *Resolver) Block(ctx context.Context, args struct {
|
|||||||
if args.Number != nil {
|
if args.Number != nil {
|
||||||
num := rpc.BlockNumber(uint64(*args.Number))
|
num := rpc.BlockNumber(uint64(*args.Number))
|
||||||
block = &Block{
|
block = &Block{
|
||||||
backend: r.backend,
|
backend: r.backend,
|
||||||
num: &num,
|
num: &num,
|
||||||
|
canonical: isCanonical,
|
||||||
}
|
}
|
||||||
} else if args.Hash != nil {
|
} else if args.Hash != nil {
|
||||||
block = &Block{
|
block = &Block{
|
||||||
backend: r.backend,
|
backend: r.backend,
|
||||||
hash: *args.Hash,
|
hash: *args.Hash,
|
||||||
|
canonical: unknown,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
num := rpc.LatestBlockNumber
|
num := rpc.LatestBlockNumber
|
||||||
block = &Block{
|
block = &Block{
|
||||||
backend: r.backend,
|
backend: r.backend,
|
||||||
num: &num,
|
num: &num,
|
||||||
|
canonical: isCanonical,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -804,27 +1008,16 @@ func (r *Resolver) Blocks(ctx context.Context, args struct {
|
|||||||
for i := from; i <= to; i++ {
|
for i := from; i <= to; i++ {
|
||||||
num := i
|
num := i
|
||||||
ret = append(ret, &Block{
|
ret = append(ret, &Block{
|
||||||
backend: r.backend,
|
backend: r.backend,
|
||||||
num: &num,
|
num: &num,
|
||||||
|
canonical: isCanonical,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) Account(ctx context.Context, args struct {
|
func (r *Resolver) Pending(ctx context.Context) *Pending {
|
||||||
Address common.Address
|
return &Pending{r.backend}
|
||||||
BlockNumber *hexutil.Uint64
|
|
||||||
}) *Account {
|
|
||||||
blockNumber := rpc.LatestBlockNumber
|
|
||||||
if args.BlockNumber != nil {
|
|
||||||
blockNumber = rpc.BlockNumber(*args.BlockNumber)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Account{
|
|
||||||
backend: r.backend,
|
|
||||||
address: args.Address,
|
|
||||||
blockNumber: blockNumber,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) Transaction(ctx context.Context, args struct{ Hash common.Hash }) (*Transaction, error) {
|
func (r *Resolver) Transaction(ctx context.Context, args struct{ Hash common.Hash }) (*Transaction, error) {
|
||||||
@ -852,70 +1045,6 @@ func (r *Resolver) SendRawTransaction(ctx context.Context, args struct{ Data hex
|
|||||||
return hash, err
|
return hash, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// CallData encapsulates arguments to `call` or `estimateGas`.
|
|
||||||
// All arguments are optional.
|
|
||||||
type CallData struct {
|
|
||||||
From *common.Address // The Ethereum address the call is from.
|
|
||||||
To *common.Address // The Ethereum address the call is to.
|
|
||||||
Gas *hexutil.Uint64 // The amount of gas provided for the call.
|
|
||||||
GasPrice *hexutil.Big // The price of each unit of gas, in wei.
|
|
||||||
Value *hexutil.Big // The value sent along with the call.
|
|
||||||
Data *hexutil.Bytes // Any data sent with the call.
|
|
||||||
}
|
|
||||||
|
|
||||||
// CallResult encapsulates the result of an invocation of the `call` accessor.
|
|
||||||
type CallResult struct {
|
|
||||||
data hexutil.Bytes // The return data from the call
|
|
||||||
gasUsed hexutil.Uint64 // The amount of gas used
|
|
||||||
status hexutil.Uint64 // The return status of the call - 0 for failure or 1 for success.
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CallResult) Data() hexutil.Bytes {
|
|
||||||
return c.data
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CallResult) GasUsed() hexutil.Uint64 {
|
|
||||||
return c.gasUsed
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CallResult) Status() hexutil.Uint64 {
|
|
||||||
return c.status
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Resolver) Call(ctx context.Context, args struct {
|
|
||||||
Data ethapi.CallArgs
|
|
||||||
BlockNumber *hexutil.Uint64
|
|
||||||
}) (*CallResult, error) {
|
|
||||||
blockNumber := rpc.LatestBlockNumber
|
|
||||||
if args.BlockNumber != nil {
|
|
||||||
blockNumber = rpc.BlockNumber(*args.BlockNumber)
|
|
||||||
}
|
|
||||||
|
|
||||||
result, gas, failed, err := ethapi.DoCall(ctx, r.backend, args.Data, blockNumber, vm.Config{}, 5*time.Second)
|
|
||||||
status := hexutil.Uint64(1)
|
|
||||||
if failed {
|
|
||||||
status = 0
|
|
||||||
}
|
|
||||||
return &CallResult{
|
|
||||||
data: hexutil.Bytes(result),
|
|
||||||
gasUsed: hexutil.Uint64(gas),
|
|
||||||
status: status,
|
|
||||||
}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Resolver) EstimateGas(ctx context.Context, args struct {
|
|
||||||
Data ethapi.CallArgs
|
|
||||||
BlockNumber *hexutil.Uint64
|
|
||||||
}) (hexutil.Uint64, error) {
|
|
||||||
blockNumber := rpc.LatestBlockNumber
|
|
||||||
if args.BlockNumber != nil {
|
|
||||||
blockNumber = rpc.BlockNumber(*args.BlockNumber)
|
|
||||||
}
|
|
||||||
|
|
||||||
gas, err := ethapi.DoEstimateGas(ctx, r.backend, args.Data, blockNumber)
|
|
||||||
return gas, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// FilterCriteria encapsulates the arguments to `logs` on the root resolver object.
|
// FilterCriteria encapsulates the arguments to `logs` on the root resolver object.
|
||||||
type FilterCriteria struct {
|
type FilterCriteria struct {
|
||||||
FromBlock *hexutil.Uint64 // beginning of the queried range, nil means genesis block
|
FromBlock *hexutil.Uint64 // beginning of the queried range, nil means genesis block
|
||||||
|
@ -22,6 +22,7 @@ const schema string = `
|
|||||||
# Address is a 20 byte Ethereum address, represented as 0x-prefixed hexadecimal.
|
# Address is a 20 byte Ethereum address, represented as 0x-prefixed hexadecimal.
|
||||||
scalar Address
|
scalar Address
|
||||||
# Bytes is an arbitrary length binary string, represented as 0x-prefixed hexadecimal.
|
# Bytes is an arbitrary length binary string, represented as 0x-prefixed hexadecimal.
|
||||||
|
# An empty byte string is represented as '0x'. Byte strings must have an even number of hexadecimal nybbles.
|
||||||
scalar Bytes
|
scalar Bytes
|
||||||
# BigInt is a large integer. Input is accepted as either a JSON number or as a string.
|
# BigInt is a large integer. Input is accepted as either a JSON number or as a string.
|
||||||
# Strings may be either decimal or 0x-prefixed hexadecimal. Output values are all
|
# Strings may be either decimal or 0x-prefixed hexadecimal. Output values are all
|
||||||
@ -75,7 +76,7 @@ const schema string = `
|
|||||||
# Nonce is the nonce of the account this transaction was generated with.
|
# Nonce is the nonce of the account this transaction was generated with.
|
||||||
nonce: Long!
|
nonce: Long!
|
||||||
# Index is the index of this transaction in the parent block. This will
|
# Index is the index of this transaction in the parent block. This will
|
||||||
# be null if the transaction has not yet beenn mined.
|
# be null if the transaction has not yet been mined.
|
||||||
index: Int
|
index: Int
|
||||||
# From is the account that sent this transaction - this will always be
|
# From is the account that sent this transaction - this will always be
|
||||||
# an externally owned account.
|
# an externally owned account.
|
||||||
@ -123,16 +124,16 @@ const schema string = `
|
|||||||
# empty, results will not be filtered by address.
|
# empty, results will not be filtered by address.
|
||||||
addresses: [Address!]
|
addresses: [Address!]
|
||||||
# Topics list restricts matches to particular event topics. Each event has a list
|
# Topics list restricts matches to particular event topics. Each event has a list
|
||||||
# of topics. Topics matches a prefix of that list. An empty element array matches any
|
# of topics. Topics matches a prefix of that list. An empty element array matches any
|
||||||
# topic. Non-empty elements represent an alternative that matches any of the
|
# topic. Non-empty elements represent an alternative that matches any of the
|
||||||
# contained topics.
|
# contained topics.
|
||||||
#
|
#
|
||||||
# Examples:
|
# Examples:
|
||||||
# - [] or nil matches any topic list
|
# - [] or nil matches any topic list
|
||||||
# - [[A]] matches topic A in first position
|
# - [[A]] matches topic A in first position
|
||||||
# - [[], [B]] matches any topic in first position, B in second 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]] 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
|
# - [[A, B]], [C, D]] matches topic (A OR B) in first position, (C OR D) in second position
|
||||||
topics: [[Bytes32!]!]
|
topics: [[Bytes32!]!]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,6 +199,13 @@ const schema string = `
|
|||||||
transactionAt(index: Int!): Transaction
|
transactionAt(index: Int!): Transaction
|
||||||
# Logs returns a filtered set of logs from this block.
|
# Logs returns a filtered set of logs from this block.
|
||||||
logs(filter: BlockFilterCriteria!): [Log!]!
|
logs(filter: BlockFilterCriteria!): [Log!]!
|
||||||
|
# Account fetches an Ethereum account at the current block's state.
|
||||||
|
account(address: Address!): Account!
|
||||||
|
# Call executes a local call operation at the current block's state.
|
||||||
|
call(data: CallData!): CallResult
|
||||||
|
# EstimateGas estimates the amount of gas that will be required for
|
||||||
|
# successful execution of a transaction at the current block's state.
|
||||||
|
estimateGas(data: CallData!): Long!
|
||||||
}
|
}
|
||||||
|
|
||||||
# CallData represents the data associated with a local contract call.
|
# CallData represents the data associated with a local contract call.
|
||||||
@ -217,7 +225,7 @@ const schema string = `
|
|||||||
data: Bytes
|
data: Bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
# CallResult is the result of a local call operationn.
|
# CallResult is the result of a local call operation.
|
||||||
type CallResult {
|
type CallResult {
|
||||||
# Data is the return data of the called contract.
|
# Data is the return data of the called contract.
|
||||||
data: Bytes!
|
data: Bytes!
|
||||||
@ -239,16 +247,16 @@ const schema string = `
|
|||||||
# empty, results will not be filtered by address.
|
# empty, results will not be filtered by address.
|
||||||
addresses: [Address!]
|
addresses: [Address!]
|
||||||
# Topics list restricts matches to particular event topics. Each event has a list
|
# Topics list restricts matches to particular event topics. Each event has a list
|
||||||
# of topics. Topics matches a prefix of that list. An empty element array matches any
|
# of topics. Topics matches a prefix of that list. An empty element array matches any
|
||||||
# topic. Non-empty elements represent an alternative that matches any of the
|
# topic. Non-empty elements represent an alternative that matches any of the
|
||||||
# contained topics.
|
# contained topics.
|
||||||
#
|
#
|
||||||
# Examples:
|
# Examples:
|
||||||
# - [] or nil matches any topic list
|
# - [] or nil matches any topic list
|
||||||
# - [[A]] matches topic A in first position
|
# - [[A]] matches topic A in first position
|
||||||
# - [[], [B]] matches any topic in first position, B in second 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]] 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
|
# - [[A, B]], [C, D]] matches topic (A OR B) in first position, (C OR D) in second position
|
||||||
topics: [[Bytes32!]!]
|
topics: [[Bytes32!]!]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,25 +276,32 @@ const schema string = `
|
|||||||
knownStates: Long
|
knownStates: Long
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Pending represents the current pending state.
|
||||||
|
type Pending {
|
||||||
|
# TransactionCount is the number of transactions in the pending state.
|
||||||
|
transactionCount: Int!
|
||||||
|
# Transactions is a list of transactions in the current pending state.
|
||||||
|
transactions: [Transaction!]
|
||||||
|
# Account fetches an Ethereum account for the pending state.
|
||||||
|
account(address: Address!): Account!
|
||||||
|
# Call executes a local call operation for the pending state.
|
||||||
|
call(data: CallData!): CallResult
|
||||||
|
# EstimateGas estimates the amount of gas that will be required for
|
||||||
|
# successful execution of a transaction for the pending state.
|
||||||
|
estimateGas(data: CallData!): Long!
|
||||||
|
}
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
# Account fetches an Ethereum account at the specified block number.
|
|
||||||
# If blockNumber is not provided, it defaults to the most recent block.
|
|
||||||
account(address: Address!, blockNumber: Long): Account!
|
|
||||||
# Block fetches an Ethereum block by number or by hash. If neither is
|
# Block fetches an Ethereum block by number or by hash. If neither is
|
||||||
# supplied, the most recent known block is returned.
|
# supplied, the most recent known block is returned.
|
||||||
block(number: Long, hash: Bytes32): Block
|
block(number: Long, hash: Bytes32): Block
|
||||||
# Blocks returns all the blocks between two numbers, inclusive. If
|
# Blocks returns all the blocks between two numbers, inclusive. If
|
||||||
# to is not supplied, it defaults to the most recent known block.
|
# to is not supplied, it defaults to the most recent known block.
|
||||||
blocks(from: Long!, to: Long): [Block!]!
|
blocks(from: Long!, to: Long): [Block!]!
|
||||||
|
# Pending returns the current pending state.
|
||||||
|
pending: Pending!
|
||||||
# Transaction returns a transaction specified by its hash.
|
# Transaction returns a transaction specified by its hash.
|
||||||
transaction(hash: Bytes32!): Transaction
|
transaction(hash: Bytes32!): Transaction
|
||||||
# Call executes a local call operation. If blockNumber is not specified,
|
|
||||||
# it defaults to the most recent known block.
|
|
||||||
call(data: CallData!, blockNumber: Long): CallResult
|
|
||||||
# EstimateGas estimates the amount of gas that will be required for
|
|
||||||
# successful execution of a transaction. If blockNumber is not specified,
|
|
||||||
# it defaults ot the most recent known block.
|
|
||||||
estimateGas(data: CallData!, blockNumber: Long): Long!
|
|
||||||
# Logs returns log entries matching the provided filter.
|
# Logs returns log entries matching the provided filter.
|
||||||
logs(filter: FilterCriteria!): [Log!]!
|
logs(filter: FilterCriteria!): [Log!]!
|
||||||
# GasPrice returns the node's estimate of a gas price sufficient to
|
# GasPrice returns the node's estimate of a gas price sufficient to
|
||||||
|
Loading…
Reference in New Issue
Block a user