github.com/chainopen/ethchaincode@v0.0.0-20190924072703-d975acdaa1c6/graphql/graphql.go (about) 1 // Copyright 2019 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 graphql provides a GraphQL interface to Ethereum node data. 18 package graphql 19 20 import ( 21 "context" 22 "errors" 23 "time" 24 25 "github.com/ethereum/go-ethereum" 26 "github.com/ethereum/go-ethereum/common" 27 "github.com/ethereum/go-ethereum/common/hexutil" 28 "github.com/ethereum/go-ethereum/core/rawdb" 29 "github.com/ethereum/go-ethereum/core/state" 30 "github.com/ethereum/go-ethereum/core/types" 31 "github.com/ethereum/go-ethereum/core/vm" 32 "github.com/ethereum/go-ethereum/eth/filters" 33 "github.com/ethereum/go-ethereum/internal/ethapi" 34 "github.com/ethereum/go-ethereum/rlp" 35 "github.com/ethereum/go-ethereum/rpc" 36 ) 37 38 var ( 39 errOnlyOnMainChain = errors.New("this operation is only available for blocks on the canonical chain") 40 errBlockInvariant = errors.New("block objects must be instantiated with at least one of num or hash") 41 ) 42 43 // Account represents an Ethereum account at a particular block. 44 type Account struct { 45 backend ethapi.Backend 46 address common.Address 47 blockNumber rpc.BlockNumber 48 } 49 50 // getState fetches the StateDB object for an account. 51 func (a *Account) getState(ctx context.Context) (*state.StateDB, error) { 52 state, _, err := a.backend.StateAndHeaderByNumber(ctx, a.blockNumber) 53 return state, err 54 } 55 56 func (a *Account) Address(ctx context.Context) (common.Address, error) { 57 return a.address, nil 58 } 59 60 func (a *Account) Balance(ctx context.Context) (hexutil.Big, error) { 61 state, err := a.getState(ctx) 62 if err != nil { 63 return hexutil.Big{}, err 64 } 65 return hexutil.Big(*state.GetBalance(a.address)), nil 66 } 67 68 func (a *Account) TransactionCount(ctx context.Context) (hexutil.Uint64, error) { 69 state, err := a.getState(ctx) 70 if err != nil { 71 return 0, err 72 } 73 return hexutil.Uint64(state.GetNonce(a.address)), nil 74 } 75 76 func (a *Account) Code(ctx context.Context) (hexutil.Bytes, error) { 77 state, err := a.getState(ctx) 78 if err != nil { 79 return hexutil.Bytes{}, err 80 } 81 return hexutil.Bytes(state.GetCode(a.address)), nil 82 } 83 84 func (a *Account) Storage(ctx context.Context, args struct{ Slot common.Hash }) (common.Hash, error) { 85 state, err := a.getState(ctx) 86 if err != nil { 87 return common.Hash{}, err 88 } 89 return state.GetState(a.address, args.Slot), nil 90 } 91 92 // Log represents an individual log message. All arguments are mandatory. 93 type Log struct { 94 backend ethapi.Backend 95 transaction *Transaction 96 log *types.Log 97 } 98 99 func (l *Log) Transaction(ctx context.Context) *Transaction { 100 return l.transaction 101 } 102 103 func (l *Log) Account(ctx context.Context, args BlockNumberArgs) *Account { 104 return &Account{ 105 backend: l.backend, 106 address: l.log.Address, 107 blockNumber: args.Number(), 108 } 109 } 110 111 func (l *Log) Index(ctx context.Context) int32 { 112 return int32(l.log.Index) 113 } 114 115 func (l *Log) Topics(ctx context.Context) []common.Hash { 116 return l.log.Topics 117 } 118 119 func (l *Log) Data(ctx context.Context) hexutil.Bytes { 120 return hexutil.Bytes(l.log.Data) 121 } 122 123 // Transaction represents an Ethereum transaction. 124 // backend and hash are mandatory; all others will be fetched when required. 125 type Transaction struct { 126 backend ethapi.Backend 127 hash common.Hash 128 tx *types.Transaction 129 block *Block 130 index uint64 131 } 132 133 // resolve returns the internal transaction object, fetching it if needed. 134 func (t *Transaction) resolve(ctx context.Context) (*types.Transaction, error) { 135 if t.tx == nil { 136 tx, blockHash, _, index := rawdb.ReadTransaction(t.backend.ChainDb(), t.hash) 137 if tx != nil { 138 t.tx = tx 139 t.block = &Block{ 140 backend: t.backend, 141 hash: blockHash, 142 canonical: unknown, 143 } 144 t.index = index 145 } else { 146 t.tx = t.backend.GetPoolTransaction(t.hash) 147 } 148 } 149 return t.tx, nil 150 } 151 152 func (t *Transaction) Hash(ctx context.Context) common.Hash { 153 return t.hash 154 } 155 156 func (t *Transaction) InputData(ctx context.Context) (hexutil.Bytes, error) { 157 tx, err := t.resolve(ctx) 158 if err != nil || tx == nil { 159 return hexutil.Bytes{}, err 160 } 161 return hexutil.Bytes(tx.Data()), nil 162 } 163 164 func (t *Transaction) Gas(ctx context.Context) (hexutil.Uint64, error) { 165 tx, err := t.resolve(ctx) 166 if err != nil || tx == nil { 167 return 0, err 168 } 169 return hexutil.Uint64(tx.Gas()), nil 170 } 171 172 func (t *Transaction) GasPrice(ctx context.Context) (hexutil.Big, error) { 173 tx, err := t.resolve(ctx) 174 if err != nil || tx == nil { 175 return hexutil.Big{}, err 176 } 177 return hexutil.Big(*tx.GasPrice()), nil 178 } 179 180 func (t *Transaction) Value(ctx context.Context) (hexutil.Big, error) { 181 tx, err := t.resolve(ctx) 182 if err != nil || tx == nil { 183 return hexutil.Big{}, err 184 } 185 return hexutil.Big(*tx.Value()), nil 186 } 187 188 func (t *Transaction) Nonce(ctx context.Context) (hexutil.Uint64, error) { 189 tx, err := t.resolve(ctx) 190 if err != nil || tx == nil { 191 return 0, err 192 } 193 return hexutil.Uint64(tx.Nonce()), nil 194 } 195 196 func (t *Transaction) To(ctx context.Context, args BlockNumberArgs) (*Account, error) { 197 tx, err := t.resolve(ctx) 198 if err != nil || tx == nil { 199 return nil, err 200 } 201 to := tx.To() 202 if to == nil { 203 return nil, nil 204 } 205 return &Account{ 206 backend: t.backend, 207 address: *to, 208 blockNumber: args.Number(), 209 }, nil 210 } 211 212 func (t *Transaction) From(ctx context.Context, args BlockNumberArgs) (*Account, error) { 213 tx, err := t.resolve(ctx) 214 if err != nil || tx == nil { 215 return nil, err 216 } 217 var signer types.Signer = types.HomesteadSigner{} 218 if tx.Protected() { 219 signer = types.NewEIP155Signer(tx.ChainId()) 220 } 221 from, _ := types.Sender(signer, tx) 222 223 return &Account{ 224 backend: t.backend, 225 address: from, 226 blockNumber: args.Number(), 227 }, nil 228 } 229 230 func (t *Transaction) Block(ctx context.Context) (*Block, error) { 231 if _, err := t.resolve(ctx); err != nil { 232 return nil, err 233 } 234 return t.block, nil 235 } 236 237 func (t *Transaction) Index(ctx context.Context) (*int32, error) { 238 if _, err := t.resolve(ctx); err != nil { 239 return nil, err 240 } 241 if t.block == nil { 242 return nil, nil 243 } 244 index := int32(t.index) 245 return &index, nil 246 } 247 248 // getReceipt returns the receipt associated with this transaction, if any. 249 func (t *Transaction) getReceipt(ctx context.Context) (*types.Receipt, error) { 250 if _, err := t.resolve(ctx); err != nil { 251 return nil, err 252 } 253 if t.block == nil { 254 return nil, nil 255 } 256 receipts, err := t.block.resolveReceipts(ctx) 257 if err != nil { 258 return nil, err 259 } 260 return receipts[t.index], nil 261 } 262 263 func (t *Transaction) Status(ctx context.Context) (*hexutil.Uint64, error) { 264 receipt, err := t.getReceipt(ctx) 265 if err != nil || receipt == nil { 266 return nil, err 267 } 268 ret := hexutil.Uint64(receipt.Status) 269 return &ret, nil 270 } 271 272 func (t *Transaction) GasUsed(ctx context.Context) (*hexutil.Uint64, error) { 273 receipt, err := t.getReceipt(ctx) 274 if err != nil || receipt == nil { 275 return nil, err 276 } 277 ret := hexutil.Uint64(receipt.GasUsed) 278 return &ret, nil 279 } 280 281 func (t *Transaction) CumulativeGasUsed(ctx context.Context) (*hexutil.Uint64, error) { 282 receipt, err := t.getReceipt(ctx) 283 if err != nil || receipt == nil { 284 return nil, err 285 } 286 ret := hexutil.Uint64(receipt.CumulativeGasUsed) 287 return &ret, nil 288 } 289 290 func (t *Transaction) CreatedContract(ctx context.Context, args BlockNumberArgs) (*Account, error) { 291 receipt, err := t.getReceipt(ctx) 292 if err != nil || receipt == nil || receipt.ContractAddress == (common.Address{}) { 293 return nil, err 294 } 295 return &Account{ 296 backend: t.backend, 297 address: receipt.ContractAddress, 298 blockNumber: args.Number(), 299 }, nil 300 } 301 302 func (t *Transaction) Logs(ctx context.Context) (*[]*Log, error) { 303 receipt, err := t.getReceipt(ctx) 304 if err != nil || receipt == nil { 305 return nil, err 306 } 307 ret := make([]*Log, 0, len(receipt.Logs)) 308 for _, log := range receipt.Logs { 309 ret = append(ret, &Log{ 310 backend: t.backend, 311 transaction: t, 312 log: log, 313 }) 314 } 315 return &ret, nil 316 } 317 318 type BlockType int 319 320 const ( 321 unknown BlockType = iota 322 isCanonical 323 notCanonical 324 ) 325 326 // Block represents an Ethereum block. 327 // backend, and either num or hash are mandatory. All other fields are lazily fetched 328 // when required. 329 type Block struct { 330 backend ethapi.Backend 331 num *rpc.BlockNumber 332 hash common.Hash 333 header *types.Header 334 block *types.Block 335 receipts []*types.Receipt 336 canonical BlockType // Indicates if this block is on the main chain or not. 337 } 338 339 func (b *Block) onMainChain(ctx context.Context) error { 340 if b.canonical == unknown { 341 header, err := b.resolveHeader(ctx) 342 if err != nil { 343 return err 344 } 345 canonHeader, err := b.backend.HeaderByNumber(ctx, rpc.BlockNumber(header.Number.Uint64())) 346 if err != nil { 347 return err 348 } 349 if header.Hash() == canonHeader.Hash() { 350 b.canonical = isCanonical 351 } else { 352 b.canonical = notCanonical 353 } 354 } 355 if b.canonical != isCanonical { 356 return errOnlyOnMainChain 357 } 358 return nil 359 } 360 361 // resolve returns the internal Block object representing this block, fetching 362 // it if necessary. 363 func (b *Block) resolve(ctx context.Context) (*types.Block, error) { 364 if b.block != nil { 365 return b.block, nil 366 } 367 var err error 368 if b.hash != (common.Hash{}) { 369 b.block, err = b.backend.BlockByHash(ctx, b.hash) 370 } else { 371 b.block, err = b.backend.BlockByNumber(ctx, *b.num) 372 } 373 if b.block != nil && b.header == nil { 374 b.header = b.block.Header() 375 } 376 return b.block, err 377 } 378 379 // resolveHeader returns the internal Header object for this block, fetching it 380 // if necessary. Call this function instead of `resolve` unless you need the 381 // additional data (transactions and uncles). 382 func (b *Block) resolveHeader(ctx context.Context) (*types.Header, error) { 383 if b.num == nil && b.hash == (common.Hash{}) { 384 return nil, errBlockInvariant 385 } 386 var err error 387 if b.header == nil { 388 if b.hash != (common.Hash{}) { 389 b.header, err = b.backend.HeaderByHash(ctx, b.hash) 390 } else { 391 b.header, err = b.backend.HeaderByNumber(ctx, *b.num) 392 } 393 } 394 return b.header, err 395 } 396 397 // resolveReceipts returns the list of receipts for this block, fetching them 398 // if necessary. 399 func (b *Block) resolveReceipts(ctx context.Context) ([]*types.Receipt, error) { 400 if b.receipts == nil { 401 hash := b.hash 402 if hash == (common.Hash{}) { 403 header, err := b.resolveHeader(ctx) 404 if err != nil { 405 return nil, err 406 } 407 hash = header.Hash() 408 } 409 receipts, err := b.backend.GetReceipts(ctx, hash) 410 if err != nil { 411 return nil, err 412 } 413 b.receipts = []*types.Receipt(receipts) 414 } 415 return b.receipts, nil 416 } 417 418 func (b *Block) Number(ctx context.Context) (hexutil.Uint64, error) { 419 if b.num == nil || *b.num == rpc.LatestBlockNumber { 420 header, err := b.resolveHeader(ctx) 421 if err != nil { 422 return 0, err 423 } 424 num := rpc.BlockNumber(header.Number.Uint64()) 425 b.num = &num 426 } 427 return hexutil.Uint64(*b.num), nil 428 } 429 430 func (b *Block) Hash(ctx context.Context) (common.Hash, error) { 431 if b.hash == (common.Hash{}) { 432 header, err := b.resolveHeader(ctx) 433 if err != nil { 434 return common.Hash{}, err 435 } 436 b.hash = header.Hash() 437 } 438 return b.hash, nil 439 } 440 441 func (b *Block) GasLimit(ctx context.Context) (hexutil.Uint64, error) { 442 header, err := b.resolveHeader(ctx) 443 if err != nil { 444 return 0, err 445 } 446 return hexutil.Uint64(header.GasLimit), nil 447 } 448 449 func (b *Block) GasUsed(ctx context.Context) (hexutil.Uint64, error) { 450 header, err := b.resolveHeader(ctx) 451 if err != nil { 452 return 0, err 453 } 454 return hexutil.Uint64(header.GasUsed), nil 455 } 456 457 func (b *Block) Parent(ctx context.Context) (*Block, error) { 458 // If the block header hasn't been fetched, and we'll need it, fetch it. 459 if b.num == nil && b.hash != (common.Hash{}) && b.header == nil { 460 if _, err := b.resolveHeader(ctx); err != nil { 461 return nil, err 462 } 463 } 464 if b.header != nil && b.header.Number.Uint64() > 0 { 465 num := rpc.BlockNumber(b.header.Number.Uint64() - 1) 466 return &Block{ 467 backend: b.backend, 468 num: &num, 469 hash: b.header.ParentHash, 470 canonical: unknown, 471 }, nil 472 } 473 if b.num != nil && *b.num != 0 { 474 num := *b.num - 1 475 return &Block{ 476 backend: b.backend, 477 num: &num, 478 canonical: isCanonical, 479 }, nil 480 } 481 return nil, nil 482 } 483 484 func (b *Block) Difficulty(ctx context.Context) (hexutil.Big, error) { 485 header, err := b.resolveHeader(ctx) 486 if err != nil { 487 return hexutil.Big{}, err 488 } 489 return hexutil.Big(*header.Difficulty), nil 490 } 491 492 func (b *Block) Timestamp(ctx context.Context) (hexutil.Uint64, error) { 493 header, err := b.resolveHeader(ctx) 494 if err != nil { 495 return 0, err 496 } 497 return hexutil.Uint64(header.Time), nil 498 } 499 500 func (b *Block) Nonce(ctx context.Context) (hexutil.Bytes, error) { 501 header, err := b.resolveHeader(ctx) 502 if err != nil { 503 return hexutil.Bytes{}, err 504 } 505 return hexutil.Bytes(header.Nonce[:]), nil 506 } 507 508 func (b *Block) MixHash(ctx context.Context) (common.Hash, error) { 509 header, err := b.resolveHeader(ctx) 510 if err != nil { 511 return common.Hash{}, err 512 } 513 return header.MixDigest, nil 514 } 515 516 func (b *Block) TransactionsRoot(ctx context.Context) (common.Hash, error) { 517 header, err := b.resolveHeader(ctx) 518 if err != nil { 519 return common.Hash{}, err 520 } 521 return header.TxHash, nil 522 } 523 524 func (b *Block) StateRoot(ctx context.Context) (common.Hash, error) { 525 header, err := b.resolveHeader(ctx) 526 if err != nil { 527 return common.Hash{}, err 528 } 529 return header.Root, nil 530 } 531 532 func (b *Block) ReceiptsRoot(ctx context.Context) (common.Hash, error) { 533 header, err := b.resolveHeader(ctx) 534 if err != nil { 535 return common.Hash{}, err 536 } 537 return header.ReceiptHash, nil 538 } 539 540 func (b *Block) OmmerHash(ctx context.Context) (common.Hash, error) { 541 header, err := b.resolveHeader(ctx) 542 if err != nil { 543 return common.Hash{}, err 544 } 545 return header.UncleHash, nil 546 } 547 548 func (b *Block) OmmerCount(ctx context.Context) (*int32, error) { 549 block, err := b.resolve(ctx) 550 if err != nil || block == nil { 551 return nil, err 552 } 553 count := int32(len(block.Uncles())) 554 return &count, err 555 } 556 557 func (b *Block) Ommers(ctx context.Context) (*[]*Block, error) { 558 block, err := b.resolve(ctx) 559 if err != nil || block == nil { 560 return nil, err 561 } 562 ret := make([]*Block, 0, len(block.Uncles())) 563 for _, uncle := range block.Uncles() { 564 blockNumber := rpc.BlockNumber(uncle.Number.Uint64()) 565 ret = append(ret, &Block{ 566 backend: b.backend, 567 num: &blockNumber, 568 hash: uncle.Hash(), 569 header: uncle, 570 canonical: notCanonical, 571 }) 572 } 573 return &ret, nil 574 } 575 576 func (b *Block) ExtraData(ctx context.Context) (hexutil.Bytes, error) { 577 header, err := b.resolveHeader(ctx) 578 if err != nil { 579 return hexutil.Bytes{}, err 580 } 581 return hexutil.Bytes(header.Extra), nil 582 } 583 584 func (b *Block) LogsBloom(ctx context.Context) (hexutil.Bytes, error) { 585 header, err := b.resolveHeader(ctx) 586 if err != nil { 587 return hexutil.Bytes{}, err 588 } 589 return hexutil.Bytes(header.Bloom.Bytes()), nil 590 } 591 592 func (b *Block) TotalDifficulty(ctx context.Context) (hexutil.Big, error) { 593 h := b.hash 594 if h == (common.Hash{}) { 595 header, err := b.resolveHeader(ctx) 596 if err != nil { 597 return hexutil.Big{}, err 598 } 599 h = header.Hash() 600 } 601 return hexutil.Big(*b.backend.GetTd(h)), nil 602 } 603 604 // BlockNumberArgs encapsulates arguments to accessors that specify a block number. 605 type BlockNumberArgs struct { 606 Block *hexutil.Uint64 607 } 608 609 // Number returns the provided block number, or rpc.LatestBlockNumber if none 610 // was provided. 611 func (a BlockNumberArgs) Number() rpc.BlockNumber { 612 if a.Block != nil { 613 return rpc.BlockNumber(*a.Block) 614 } 615 return rpc.LatestBlockNumber 616 } 617 618 func (b *Block) Miner(ctx context.Context, args BlockNumberArgs) (*Account, error) { 619 header, err := b.resolveHeader(ctx) 620 if err != nil { 621 return nil, err 622 } 623 return &Account{ 624 backend: b.backend, 625 address: header.Coinbase, 626 blockNumber: args.Number(), 627 }, nil 628 } 629 630 func (b *Block) TransactionCount(ctx context.Context) (*int32, error) { 631 block, err := b.resolve(ctx) 632 if err != nil || block == nil { 633 return nil, err 634 } 635 count := int32(len(block.Transactions())) 636 return &count, err 637 } 638 639 func (b *Block) Transactions(ctx context.Context) (*[]*Transaction, error) { 640 block, err := b.resolve(ctx) 641 if err != nil || block == nil { 642 return nil, err 643 } 644 ret := make([]*Transaction, 0, len(block.Transactions())) 645 for i, tx := range block.Transactions() { 646 ret = append(ret, &Transaction{ 647 backend: b.backend, 648 hash: tx.Hash(), 649 tx: tx, 650 block: b, 651 index: uint64(i), 652 }) 653 } 654 return &ret, nil 655 } 656 657 func (b *Block) TransactionAt(ctx context.Context, args struct{ Index int32 }) (*Transaction, error) { 658 block, err := b.resolve(ctx) 659 if err != nil || block == nil { 660 return nil, err 661 } 662 txs := block.Transactions() 663 if args.Index < 0 || int(args.Index) >= len(txs) { 664 return nil, nil 665 } 666 tx := txs[args.Index] 667 return &Transaction{ 668 backend: b.backend, 669 hash: tx.Hash(), 670 tx: tx, 671 block: b, 672 index: uint64(args.Index), 673 }, nil 674 } 675 676 func (b *Block) OmmerAt(ctx context.Context, args struct{ Index int32 }) (*Block, error) { 677 block, err := b.resolve(ctx) 678 if err != nil || block == nil { 679 return nil, err 680 } 681 uncles := block.Uncles() 682 if args.Index < 0 || int(args.Index) >= len(uncles) { 683 return nil, nil 684 } 685 uncle := uncles[args.Index] 686 blockNumber := rpc.BlockNumber(uncle.Number.Uint64()) 687 return &Block{ 688 backend: b.backend, 689 num: &blockNumber, 690 hash: uncle.Hash(), 691 header: uncle, 692 canonical: notCanonical, 693 }, nil 694 } 695 696 // BlockFilterCriteria encapsulates criteria passed to a `logs` accessor inside 697 // a block. 698 type BlockFilterCriteria struct { 699 Addresses *[]common.Address // restricts matches to events created by specific contracts 700 701 // The Topic list restricts matches to particular event topics. Each event has a list 702 // of topics. Topics matches a prefix of that list. An empty element slice matches any 703 // topic. Non-empty elements represent an alternative that matches any of the 704 // contained topics. 705 // 706 // Examples: 707 // {} or nil matches any topic list 708 // {{A}} matches topic A in first position 709 // {{}, {B}} matches any topic in first position, B in second position 710 // {{A}, {B}} matches topic A in first position, B in second position 711 // {{A, B}}, {C, D}} matches topic (A OR B) in first position, (C OR D) in second position 712 Topics *[][]common.Hash 713 } 714 715 // runFilter accepts a filter and executes it, returning all its results as 716 // `Log` objects. 717 func runFilter(ctx context.Context, be ethapi.Backend, filter *filters.Filter) ([]*Log, error) { 718 logs, err := filter.Logs(ctx) 719 if err != nil || logs == nil { 720 return nil, err 721 } 722 ret := make([]*Log, 0, len(logs)) 723 for _, log := range logs { 724 ret = append(ret, &Log{ 725 backend: be, 726 transaction: &Transaction{backend: be, hash: log.TxHash}, 727 log: log, 728 }) 729 } 730 return ret, nil 731 } 732 733 func (b *Block) Logs(ctx context.Context, args struct{ Filter BlockFilterCriteria }) ([]*Log, error) { 734 var addresses []common.Address 735 if args.Filter.Addresses != nil { 736 addresses = *args.Filter.Addresses 737 } 738 var topics [][]common.Hash 739 if args.Filter.Topics != nil { 740 topics = *args.Filter.Topics 741 } 742 hash := b.hash 743 if hash == (common.Hash{}) { 744 header, err := b.resolveHeader(ctx) 745 if err != nil { 746 return nil, err 747 } 748 hash = header.Hash() 749 } 750 // Construct the range filter 751 filter := filters.NewBlockFilter(b.backend, hash, addresses, topics) 752 753 // Run the filter and return all the logs 754 return runFilter(ctx, b.backend, filter) 755 } 756 757 func (b *Block) Account(ctx context.Context, args struct { 758 Address common.Address 759 }) (*Account, error) { 760 err := b.onMainChain(ctx) 761 if err != nil { 762 return nil, err 763 } 764 if b.num == nil { 765 _, err := b.resolveHeader(ctx) 766 if err != nil { 767 return nil, err 768 } 769 } 770 return &Account{ 771 backend: b.backend, 772 address: args.Address, 773 blockNumber: *b.num, 774 }, nil 775 } 776 777 // CallData encapsulates arguments to `call` or `estimateGas`. 778 // All arguments are optional. 779 type CallData struct { 780 From *common.Address // The Ethereum address the call is from. 781 To *common.Address // The Ethereum address the call is to. 782 Gas *hexutil.Uint64 // The amount of gas provided for the call. 783 GasPrice *hexutil.Big // The price of each unit of gas, in wei. 784 Value *hexutil.Big // The value sent along with the call. 785 Data *hexutil.Bytes // Any data sent with the call. 786 } 787 788 // CallResult encapsulates the result of an invocation of the `call` accessor. 789 type CallResult struct { 790 data hexutil.Bytes // The return data from the call 791 gasUsed hexutil.Uint64 // The amount of gas used 792 status hexutil.Uint64 // The return status of the call - 0 for failure or 1 for success. 793 } 794 795 func (c *CallResult) Data() hexutil.Bytes { 796 return c.data 797 } 798 799 func (c *CallResult) GasUsed() hexutil.Uint64 { 800 return c.gasUsed 801 } 802 803 func (c *CallResult) Status() hexutil.Uint64 { 804 return c.status 805 } 806 807 func (b *Block) Call(ctx context.Context, args struct { 808 Data ethapi.CallArgs 809 }) (*CallResult, error) { 810 err := b.onMainChain(ctx) 811 if err != nil { 812 return nil, err 813 } 814 if b.num == nil { 815 _, err := b.resolveHeader(ctx) 816 if err != nil { 817 return nil, err 818 } 819 } 820 result, gas, failed, err := ethapi.DoCall(ctx, b.backend, args.Data, *b.num, nil, vm.Config{}, 5*time.Second, b.backend.RPCGasCap()) 821 status := hexutil.Uint64(1) 822 if failed { 823 status = 0 824 } 825 return &CallResult{ 826 data: hexutil.Bytes(result), 827 gasUsed: hexutil.Uint64(gas), 828 status: status, 829 }, err 830 } 831 832 func (b *Block) EstimateGas(ctx context.Context, args struct { 833 Data ethapi.CallArgs 834 }) (hexutil.Uint64, error) { 835 err := b.onMainChain(ctx) 836 if err != nil { 837 return hexutil.Uint64(0), err 838 } 839 if b.num == nil { 840 _, err := b.resolveHeader(ctx) 841 if err != nil { 842 return hexutil.Uint64(0), err 843 } 844 } 845 gas, err := ethapi.DoEstimateGas(ctx, b.backend, args.Data, *b.num, b.backend.RPCGasCap()) 846 return gas, err 847 } 848 849 type Pending struct { 850 backend ethapi.Backend 851 } 852 853 func (p *Pending) TransactionCount(ctx context.Context) (int32, error) { 854 txs, err := p.backend.GetPoolTransactions() 855 return int32(len(txs)), err 856 } 857 858 func (p *Pending) Transactions(ctx context.Context) (*[]*Transaction, error) { 859 txs, err := p.backend.GetPoolTransactions() 860 if err != nil { 861 return nil, err 862 } 863 ret := make([]*Transaction, 0, len(txs)) 864 for i, tx := range txs { 865 ret = append(ret, &Transaction{ 866 backend: p.backend, 867 hash: tx.Hash(), 868 tx: tx, 869 index: uint64(i), 870 }) 871 } 872 return &ret, nil 873 } 874 875 func (p *Pending) Account(ctx context.Context, args struct { 876 Address common.Address 877 }) *Account { 878 return &Account{ 879 backend: p.backend, 880 address: args.Address, 881 blockNumber: rpc.PendingBlockNumber, 882 } 883 } 884 885 func (p *Pending) Call(ctx context.Context, args struct { 886 Data ethapi.CallArgs 887 }) (*CallResult, error) { 888 result, gas, failed, err := ethapi.DoCall(ctx, p.backend, args.Data, rpc.PendingBlockNumber, nil, vm.Config{}, 5*time.Second, p.backend.RPCGasCap()) 889 status := hexutil.Uint64(1) 890 if failed { 891 status = 0 892 } 893 return &CallResult{ 894 data: hexutil.Bytes(result), 895 gasUsed: hexutil.Uint64(gas), 896 status: status, 897 }, err 898 } 899 900 func (p *Pending) EstimateGas(ctx context.Context, args struct { 901 Data ethapi.CallArgs 902 }) (hexutil.Uint64, error) { 903 return ethapi.DoEstimateGas(ctx, p.backend, args.Data, rpc.PendingBlockNumber, p.backend.RPCGasCap()) 904 } 905 906 // Resolver is the top-level object in the GraphQL hierarchy. 907 type Resolver struct { 908 backend ethapi.Backend 909 } 910 911 func (r *Resolver) Block(ctx context.Context, args struct { 912 Number *hexutil.Uint64 913 Hash *common.Hash 914 }) (*Block, error) { 915 var block *Block 916 if args.Number != nil { 917 num := rpc.BlockNumber(uint64(*args.Number)) 918 block = &Block{ 919 backend: r.backend, 920 num: &num, 921 canonical: isCanonical, 922 } 923 } else if args.Hash != nil { 924 block = &Block{ 925 backend: r.backend, 926 hash: *args.Hash, 927 canonical: unknown, 928 } 929 } else { 930 num := rpc.LatestBlockNumber 931 block = &Block{ 932 backend: r.backend, 933 num: &num, 934 canonical: isCanonical, 935 } 936 } 937 // Resolve the header, return nil if it doesn't exist. 938 // Note we don't resolve block directly here since it will require an 939 // additional network request for light client. 940 h, err := block.resolveHeader(ctx) 941 if err != nil { 942 return nil, err 943 } else if h == nil { 944 return nil, nil 945 } 946 return block, nil 947 } 948 949 func (r *Resolver) Blocks(ctx context.Context, args struct { 950 From hexutil.Uint64 951 To *hexutil.Uint64 952 }) ([]*Block, error) { 953 from := rpc.BlockNumber(args.From) 954 955 var to rpc.BlockNumber 956 if args.To != nil { 957 to = rpc.BlockNumber(*args.To) 958 } else { 959 to = rpc.BlockNumber(r.backend.CurrentBlock().Number().Int64()) 960 } 961 if to < from { 962 return []*Block{}, nil 963 } 964 ret := make([]*Block, 0, to-from+1) 965 for i := from; i <= to; i++ { 966 num := i 967 ret = append(ret, &Block{ 968 backend: r.backend, 969 num: &num, 970 canonical: isCanonical, 971 }) 972 } 973 return ret, nil 974 } 975 976 func (r *Resolver) Pending(ctx context.Context) *Pending { 977 return &Pending{r.backend} 978 } 979 980 func (r *Resolver) Transaction(ctx context.Context, args struct{ Hash common.Hash }) (*Transaction, error) { 981 tx := &Transaction{ 982 backend: r.backend, 983 hash: args.Hash, 984 } 985 // Resolve the transaction; if it doesn't exist, return nil. 986 t, err := tx.resolve(ctx) 987 if err != nil { 988 return nil, err 989 } else if t == nil { 990 return nil, nil 991 } 992 return tx, nil 993 } 994 995 func (r *Resolver) SendRawTransaction(ctx context.Context, args struct{ Data hexutil.Bytes }) (common.Hash, error) { 996 tx := new(types.Transaction) 997 if err := rlp.DecodeBytes(args.Data, tx); err != nil { 998 return common.Hash{}, err 999 } 1000 hash, err := ethapi.SubmitTransaction(ctx, r.backend, tx) 1001 return hash, err 1002 } 1003 1004 // FilterCriteria encapsulates the arguments to `logs` on the root resolver object. 1005 type FilterCriteria struct { 1006 FromBlock *hexutil.Uint64 // beginning of the queried range, nil means genesis block 1007 ToBlock *hexutil.Uint64 // end of the range, nil means latest block 1008 Addresses *[]common.Address // restricts matches to events created by specific contracts 1009 1010 // The Topic list restricts matches to particular event topics. Each event has a list 1011 // of topics. Topics matches a prefix of that list. An empty element slice matches any 1012 // topic. Non-empty elements represent an alternative that matches any of the 1013 // contained topics. 1014 // 1015 // Examples: 1016 // {} or nil matches any topic list 1017 // {{A}} matches topic A in first position 1018 // {{}, {B}} matches any topic in first position, B in second position 1019 // {{A}, {B}} matches topic A in first position, B in second position 1020 // {{A, B}}, {C, D}} matches topic (A OR B) in first position, (C OR D) in second position 1021 Topics *[][]common.Hash 1022 } 1023 1024 func (r *Resolver) Logs(ctx context.Context, args struct{ Filter FilterCriteria }) ([]*Log, error) { 1025 // Convert the RPC block numbers into internal representations 1026 begin := rpc.LatestBlockNumber.Int64() 1027 if args.Filter.FromBlock != nil { 1028 begin = int64(*args.Filter.FromBlock) 1029 } 1030 end := rpc.LatestBlockNumber.Int64() 1031 if args.Filter.ToBlock != nil { 1032 end = int64(*args.Filter.ToBlock) 1033 } 1034 var addresses []common.Address 1035 if args.Filter.Addresses != nil { 1036 addresses = *args.Filter.Addresses 1037 } 1038 var topics [][]common.Hash 1039 if args.Filter.Topics != nil { 1040 topics = *args.Filter.Topics 1041 } 1042 // Construct the range filter 1043 filter := filters.NewRangeFilter(filters.Backend(r.backend), begin, end, addresses, topics) 1044 return runFilter(ctx, r.backend, filter) 1045 } 1046 1047 func (r *Resolver) GasPrice(ctx context.Context) (hexutil.Big, error) { 1048 price, err := r.backend.SuggestPrice(ctx) 1049 return hexutil.Big(*price), err 1050 } 1051 1052 func (r *Resolver) ProtocolVersion(ctx context.Context) (int32, error) { 1053 return int32(r.backend.ProtocolVersion()), nil 1054 } 1055 1056 // SyncState represents the synchronisation status returned from the `syncing` accessor. 1057 type SyncState struct { 1058 progress ethereum.SyncProgress 1059 } 1060 1061 func (s *SyncState) StartingBlock() hexutil.Uint64 { 1062 return hexutil.Uint64(s.progress.StartingBlock) 1063 } 1064 1065 func (s *SyncState) CurrentBlock() hexutil.Uint64 { 1066 return hexutil.Uint64(s.progress.CurrentBlock) 1067 } 1068 1069 func (s *SyncState) HighestBlock() hexutil.Uint64 { 1070 return hexutil.Uint64(s.progress.HighestBlock) 1071 } 1072 1073 func (s *SyncState) PulledStates() *hexutil.Uint64 { 1074 ret := hexutil.Uint64(s.progress.PulledStates) 1075 return &ret 1076 } 1077 1078 func (s *SyncState) KnownStates() *hexutil.Uint64 { 1079 ret := hexutil.Uint64(s.progress.KnownStates) 1080 return &ret 1081 } 1082 1083 // Syncing returns false in case the node is currently not syncing with the network. It can be up to date or has not 1084 // yet received the latest block headers from its pears. In case it is synchronizing: 1085 // - startingBlock: block number this node started to synchronise from 1086 // - currentBlock: block number this node is currently importing 1087 // - highestBlock: block number of the highest block header this node has received from peers 1088 // - pulledStates: number of state entries processed until now 1089 // - knownStates: number of known state entries that still need to be pulled 1090 func (r *Resolver) Syncing() (*SyncState, error) { 1091 progress := r.backend.Downloader().Progress() 1092 1093 // Return not syncing if the synchronisation already completed 1094 if progress.CurrentBlock >= progress.HighestBlock { 1095 return nil, nil 1096 } 1097 // Otherwise gather the block sync stats 1098 return &SyncState{progress}, nil 1099 }