restructured eth rpc API
This commit is contained in:
		
				
					committed by
					
						
						Bas van Kervel
					
				
			
			
				
	
			
			
			
						parent
						
							6609d45ef4
						
					
				
				
					commit
					2f55a1d798
				
			
							
								
								
									
										12
									
								
								rpc/api/api.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								rpc/api/api.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					package api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "github.com/ethereum/go-ethereum/rpc/shared"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Ethereum RPC API interface
 | 
				
			||||||
 | 
					type EthereumApi interface {
 | 
				
			||||||
 | 
						// Execute the given request and returns the response or an error
 | 
				
			||||||
 | 
						Execute(*shared.Request) (interface{}, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// List of supported RCP methods this API provides
 | 
				
			||||||
 | 
						Methods() []string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										42
									
								
								rpc/api/api_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								rpc/api/api_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					package api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/rpc/codec"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestParseApiString(t *testing.T) {
 | 
				
			||||||
 | 
						apis, err := ParseApiString("", codec.JSON, nil, nil)
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							t.Errorf("Expected an err from parsing empty API string but got nil")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(apis) != 0 {
 | 
				
			||||||
 | 
							t.Errorf("Expected 0 apis from empty API string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						apis, err = ParseApiString("eth", codec.JSON, nil, nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Errorf("Expected nil err from parsing empty API string but got %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(apis) != 1 {
 | 
				
			||||||
 | 
							t.Errorf("Expected 1 apis but got %d - %v", apis, apis)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						apis, err = ParseApiString("eth,eth", codec.JSON, nil, nil)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Errorf("Expected nil err from parsing empty API string but got \"%v\"", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(apis) != 2 {
 | 
				
			||||||
 | 
							t.Errorf("Expected 2 apis but got %d - %v", apis, apis)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						apis, err = ParseApiString("eth,invalid", codec.JSON, nil, nil)
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							t.Errorf("Expected an err but got no err")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										523
									
								
								rpc/api/eth.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										523
									
								
								rpc/api/eth.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,523 @@
 | 
				
			|||||||
 | 
					package api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"math/big"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/common"
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/rpc/codec"
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/rpc/shared"
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/xeth"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// eth api provider
 | 
				
			||||||
 | 
					// See https://github.com/ethereum/wiki/wiki/JSON-RPC
 | 
				
			||||||
 | 
					type EthApi struct {
 | 
				
			||||||
 | 
						xeth    *xeth.XEth
 | 
				
			||||||
 | 
						methods map[string]ethhandler
 | 
				
			||||||
 | 
						codec   codec.ApiCoder
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// eth callback handler
 | 
				
			||||||
 | 
					type ethhandler func(*EthApi, *shared.Request) (interface{}, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						ethMapping = map[string]ethhandler{
 | 
				
			||||||
 | 
							"eth_accounts":                          (*EthApi).Accounts,
 | 
				
			||||||
 | 
							"eth_blockNumber":                       (*EthApi).BlockNumber,
 | 
				
			||||||
 | 
							"eth_getBalance":                        (*EthApi).GetBalance,
 | 
				
			||||||
 | 
							"eth_protocolVersion":                   (*EthApi).ProtocolVersion,
 | 
				
			||||||
 | 
							"eth_coinbase":                          (*EthApi).Coinbase,
 | 
				
			||||||
 | 
							"eth_mining":                            (*EthApi).IsMining,
 | 
				
			||||||
 | 
							"eth_gasPrice":                          (*EthApi).GasPrice,
 | 
				
			||||||
 | 
							"eth_getStorage":                        (*EthApi).GetStorage,
 | 
				
			||||||
 | 
							"eth_storageAt":                         (*EthApi).GetStorage,
 | 
				
			||||||
 | 
							"eth_getStorageAt":                      (*EthApi).GetStorageAt,
 | 
				
			||||||
 | 
							"eth_getTransactionCount":               (*EthApi).GetTransactionCount,
 | 
				
			||||||
 | 
							"eth_getBlockTransactionCountByHash":    (*EthApi).GetBlockTransactionCountByHash,
 | 
				
			||||||
 | 
							"eth_getBlockTransactionCountByNumber":  (*EthApi).GetBlockTransactionCountByNumber,
 | 
				
			||||||
 | 
							"eth_getUncleCountByBlockHash":          (*EthApi).GetUncleCountByBlockHash,
 | 
				
			||||||
 | 
							"eth_getUncleCountByBlockNumber":        (*EthApi).GetUncleCountByBlockNumber,
 | 
				
			||||||
 | 
							"eth_getData":                           (*EthApi).GetData,
 | 
				
			||||||
 | 
							"eth_getCode":                           (*EthApi).GetData,
 | 
				
			||||||
 | 
							"eth_sign":                              (*EthApi).Sign,
 | 
				
			||||||
 | 
							"eth_sendTransaction":                   (*EthApi).SendTransaction,
 | 
				
			||||||
 | 
							"eth_transact":                          (*EthApi).SendTransaction,
 | 
				
			||||||
 | 
							"eth_estimateGas":                       (*EthApi).EstimateGas,
 | 
				
			||||||
 | 
							"eth_call":                              (*EthApi).Call,
 | 
				
			||||||
 | 
							"eth_flush":                             (*EthApi).Flush,
 | 
				
			||||||
 | 
							"eth_getBlockByHash":                    (*EthApi).GetBlockByHash,
 | 
				
			||||||
 | 
							"eth_getBlockByNumber":                  (*EthApi).GetBlockByNumber,
 | 
				
			||||||
 | 
							"eth_getTransactionByHash":              (*EthApi).GetTransactionByHash,
 | 
				
			||||||
 | 
							"eth_getTransactionByBlockHashAndIndex": (*EthApi).GetTransactionByBlockHashAndIndex,
 | 
				
			||||||
 | 
							"eth_getUncleByBlockHashAndIndex":       (*EthApi).GetUncleByBlockHashAndIndex,
 | 
				
			||||||
 | 
							"eth_getUncleByBlockNumberAndIndex":     (*EthApi).GetUncleByBlockNumberAndIndex,
 | 
				
			||||||
 | 
							"eth_getCompilers":                      (*EthApi).GetCompilers,
 | 
				
			||||||
 | 
							"eth_compileSolidity":                   (*EthApi).CompileSolidity,
 | 
				
			||||||
 | 
							"eth_newFilter":                         (*EthApi).NewFilter,
 | 
				
			||||||
 | 
							"eth_newBlockFilter":                    (*EthApi).NewBlockFilter,
 | 
				
			||||||
 | 
							"eth_newPendingTransactionFilter":       (*EthApi).NewPendingTransactionFilter,
 | 
				
			||||||
 | 
							"eth_uninstallFilter":                   (*EthApi).UninstallFilter,
 | 
				
			||||||
 | 
							"eth_getFilterChanges":                  (*EthApi).GetFilterChanges,
 | 
				
			||||||
 | 
							"eth_getFilterLogs":                     (*EthApi).GetFilterLogs,
 | 
				
			||||||
 | 
							"eth_getLogs":                           (*EthApi).GetLogs,
 | 
				
			||||||
 | 
							"eth_hashrate":                          (*EthApi).Hashrate,
 | 
				
			||||||
 | 
							"eth_getWork":                           (*EthApi).GetWork,
 | 
				
			||||||
 | 
							"eth_submitWork":                        (*EthApi).SubmitWork,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// create new EthApi instance
 | 
				
			||||||
 | 
					func NewEthApi(xeth *xeth.XEth, codec codec.Codec) *EthApi {
 | 
				
			||||||
 | 
						return &EthApi{xeth, ethMapping, codec.New(nil)}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// collection with supported methods
 | 
				
			||||||
 | 
					func (self *EthApi) Methods() []string {
 | 
				
			||||||
 | 
						methods := make([]string, len(self.methods))
 | 
				
			||||||
 | 
						i := 0
 | 
				
			||||||
 | 
						for k := range self.methods {
 | 
				
			||||||
 | 
							methods[i] = k
 | 
				
			||||||
 | 
							i++
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return methods
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Execute given request
 | 
				
			||||||
 | 
					func (self *EthApi) Execute(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						if callback, ok := self.methods[req.Method]; ok {
 | 
				
			||||||
 | 
							return callback(self, req)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil, shared.NewNotImplementedError(req.Method)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) Accounts(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						return self.xeth.Accounts(), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) Hashrate(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						return newHexNum(self.xeth.HashRate()), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) BlockNumber(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						return self.xeth.CurrentBlock().Number(), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetBalance(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(GetBalanceArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return self.xeth.AtStateNum(args.BlockNumber).BalanceAt(args.Address), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) ProtocolVersion(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						return self.xeth.EthVersion(), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) Coinbase(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						return newHexData(self.xeth.Coinbase()), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) IsMining(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						return self.xeth.IsMining(), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GasPrice(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						return newHexNum(xeth.DefaultGasPrice().Bytes()), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetStorage(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(GetStorageArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return self.xeth.AtStateNum(args.BlockNumber).State().SafeGet(args.Address).Storage(), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetStorageAt(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(GetStorageAtArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return self.xeth.AtStateNum(args.BlockNumber).StorageAt(args.Address, args.Key), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetTransactionCount(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(GetTxCountArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						count := self.xeth.AtStateNum(args.BlockNumber).TxCountAt(args.Address)
 | 
				
			||||||
 | 
						return newHexNum(big.NewInt(int64(count)).Bytes()), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetBlockTransactionCountByHash(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(HashArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						block := NewBlockRes(self.xeth.EthBlockByHash(args.Hash), false)
 | 
				
			||||||
 | 
						if block == nil {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return newHexNum(big.NewInt(int64(len(block.Transactions))).Bytes()), nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetBlockTransactionCountByNumber(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(BlockNumArg)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						block := NewBlockRes(self.xeth.EthBlockByNumber(args.BlockNumber), false)
 | 
				
			||||||
 | 
						if block == nil {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return newHexNum(big.NewInt(int64(len(block.Transactions))).Bytes()), nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetUncleCountByBlockHash(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(HashArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						block := self.xeth.EthBlockByHash(args.Hash)
 | 
				
			||||||
 | 
						br := NewBlockRes(block, false)
 | 
				
			||||||
 | 
						if br == nil {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return newHexNum(big.NewInt(int64(len(br.Uncles))).Bytes()), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetUncleCountByBlockNumber(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(BlockNumArg)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						block := self.xeth.EthBlockByNumber(args.BlockNumber)
 | 
				
			||||||
 | 
						br := NewBlockRes(block, false)
 | 
				
			||||||
 | 
						if br == nil {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return newHexNum(big.NewInt(int64(len(br.Uncles))).Bytes()), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetData(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(GetDataArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						v := self.xeth.AtStateNum(args.BlockNumber).CodeAtBytes(args.Address)
 | 
				
			||||||
 | 
						return newHexData(v), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) Sign(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(NewSignArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						v, err := self.xeth.Sign(args.From, args.Data, false)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return v, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) SendTransaction(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(NewTxArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// nonce may be nil ("guess" mode)
 | 
				
			||||||
 | 
						var nonce string
 | 
				
			||||||
 | 
						if args.Nonce != nil {
 | 
				
			||||||
 | 
							nonce = args.Nonce.String()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						v, err := self.xeth.Transact(args.From, args.To, nonce, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return v, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) EstimateGas(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						_, gas, err := self.doCall(req.Params)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO unwrap the parent method's ToHex call
 | 
				
			||||||
 | 
						if len(gas) == 0 {
 | 
				
			||||||
 | 
							return newHexNum(0), nil
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return newHexNum(gas), nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) Call(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						v, _, err := self.doCall(req.Params)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO unwrap the parent method's ToHex call
 | 
				
			||||||
 | 
						if v == "0x0" {
 | 
				
			||||||
 | 
							return newHexData([]byte{}), nil
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return newHexData(common.FromHex(v)), nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) Flush(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						return nil, shared.NewNotImplementedError(req.Method)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) doCall(params json.RawMessage) (string, string, error) {
 | 
				
			||||||
 | 
						args := new(CallArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(params, &args); err != nil {
 | 
				
			||||||
 | 
							return "", "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return self.xeth.AtStateNum(args.BlockNumber).Call(args.From, args.To, args.Value.String(), args.Gas.String(), args.GasPrice.String(), args.Data)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetBlockByHash(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(GetBlockByHashArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						block := self.xeth.EthBlockByHash(args.BlockHash)
 | 
				
			||||||
 | 
						return NewBlockRes(block, args.IncludeTxs), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetBlockByNumber(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(GetBlockByNumberArgs)
 | 
				
			||||||
 | 
						if err := json.Unmarshal(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						block := self.xeth.EthBlockByNumber(args.BlockNumber)
 | 
				
			||||||
 | 
						br := NewBlockRes(block, args.IncludeTxs)
 | 
				
			||||||
 | 
						// If request was for "pending", nil nonsensical fields
 | 
				
			||||||
 | 
						if args.BlockNumber == -2 {
 | 
				
			||||||
 | 
							br.BlockHash = nil
 | 
				
			||||||
 | 
							br.BlockNumber = nil
 | 
				
			||||||
 | 
							br.Miner = nil
 | 
				
			||||||
 | 
							br.Nonce = nil
 | 
				
			||||||
 | 
							br.LogsBloom = nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return br, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetTransactionByHash(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(HashArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tx, bhash, bnum, txi := self.xeth.EthTransactionByHash(args.Hash)
 | 
				
			||||||
 | 
						if tx != nil {
 | 
				
			||||||
 | 
							v := NewTransactionRes(tx)
 | 
				
			||||||
 | 
							// if the blockhash is 0, assume this is a pending transaction
 | 
				
			||||||
 | 
							if bytes.Compare(bhash.Bytes(), bytes.Repeat([]byte{0}, 32)) != 0 {
 | 
				
			||||||
 | 
								v.BlockHash = newHexData(bhash)
 | 
				
			||||||
 | 
								v.BlockNumber = newHexNum(bnum)
 | 
				
			||||||
 | 
								v.TxIndex = newHexNum(txi)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return v, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetTransactionByBlockHashAndIndex(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(HashIndexArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						block := self.xeth.EthBlockByHash(args.Hash)
 | 
				
			||||||
 | 
						br := NewBlockRes(block, true)
 | 
				
			||||||
 | 
						if br == nil {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if args.Index >= int64(len(br.Transactions)) || args.Index < 0 {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return br.Transactions[args.Index], nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetTransactionByBlockNumberAndIndex(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(BlockNumIndexArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						block := self.xeth.EthBlockByNumber(args.BlockNumber)
 | 
				
			||||||
 | 
						v := NewBlockRes(block, true)
 | 
				
			||||||
 | 
						if v == nil {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if args.Index >= int64(len(v.Transactions)) || args.Index < 0 {
 | 
				
			||||||
 | 
							// return NewValidationError("Index", "does not exist")
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return v.Transactions[args.Index], nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetUncleByBlockHashAndIndex(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(HashIndexArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						br := NewBlockRes(self.xeth.EthBlockByHash(args.Hash), false)
 | 
				
			||||||
 | 
						if br == nil {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if args.Index >= int64(len(br.Uncles)) || args.Index < 0 {
 | 
				
			||||||
 | 
							// return NewValidationError("Index", "does not exist")
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return br.Uncles[args.Index], nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetUncleByBlockNumberAndIndex(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(BlockNumIndexArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						block := self.xeth.EthBlockByNumber(args.BlockNumber)
 | 
				
			||||||
 | 
						v := NewBlockRes(block, true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if v == nil {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if args.Index >= int64(len(v.Uncles)) || args.Index < 0 {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							return v.Uncles[args.Index], nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetCompilers(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						var lang string
 | 
				
			||||||
 | 
						if solc, _ := self.xeth.Solc(); solc != nil {
 | 
				
			||||||
 | 
							lang = "Solidity"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						c := []string{lang}
 | 
				
			||||||
 | 
						return c, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) CompileSolidity(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						solc, _ := self.xeth.Solc()
 | 
				
			||||||
 | 
						if solc == nil {
 | 
				
			||||||
 | 
							return nil, shared.NewNotAvailableError(req.Method, "solc (solidity compiler) not found")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args := new(SourceArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						contracts, err := solc.Compile(args.Source)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return contracts, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) NewFilter(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(BlockFilterArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						id := self.xeth.NewLogFilter(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics)
 | 
				
			||||||
 | 
						return newHexNum(big.NewInt(int64(id)).Bytes()), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) NewBlockFilter(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						return newHexNum(self.xeth.NewBlockFilter()), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) NewPendingTransactionFilter(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						return newHexNum(self.xeth.NewTransactionFilter()), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) UninstallFilter(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(FilterIdArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return self.xeth.UninstallFilter(args.Id), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetFilterChanges(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(FilterIdArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch self.xeth.GetFilterType(args.Id) {
 | 
				
			||||||
 | 
						case xeth.BlockFilterTy:
 | 
				
			||||||
 | 
							return NewHashesRes(self.xeth.BlockFilterChanged(args.Id)), nil
 | 
				
			||||||
 | 
						case xeth.TransactionFilterTy:
 | 
				
			||||||
 | 
							return NewHashesRes(self.xeth.TransactionFilterChanged(args.Id)), nil
 | 
				
			||||||
 | 
						case xeth.LogFilterTy:
 | 
				
			||||||
 | 
							return NewLogsRes(self.xeth.LogFilterChanged(args.Id)), nil
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return []string{}, nil // reply empty string slice
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetFilterLogs(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(FilterIdArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return NewLogsRes(self.xeth.Logs(args.Id)), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetLogs(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(BlockFilterArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return NewLogsRes(self.xeth.AllLogs(args.Earliest, args.Latest, args.Skip, args.Max, args.Address, args.Topics)), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) GetWork(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						self.xeth.SetMining(true, 0)
 | 
				
			||||||
 | 
						return self.xeth.RemoteMining().GetWork(), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *EthApi) SubmitWork(req *shared.Request) (interface{}, error) {
 | 
				
			||||||
 | 
						args := new(SubmitWorkArgs)
 | 
				
			||||||
 | 
						if err := self.codec.Decode(req.Params, &args); err != nil {
 | 
				
			||||||
 | 
							return nil, shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return self.xeth.RemoteMining().SubmitWork(args.Nonce, common.HexToHash(args.Digest), common.HexToHash(args.Header)), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										835
									
								
								rpc/api/eth_args.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										835
									
								
								rpc/api/eth_args.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,835 @@
 | 
				
			|||||||
 | 
					package api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"math/big"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/common"
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/core/state"
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/rpc/shared"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						defaultLogLimit  = 100
 | 
				
			||||||
 | 
						defaultLogOffset = 0
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GetBalanceArgs struct {
 | 
				
			||||||
 | 
						Address     string
 | 
				
			||||||
 | 
						BlockNumber int64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []interface{}
 | 
				
			||||||
 | 
						if err := json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) < 1 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						addstr, ok := obj[0].(string)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return shared.NewInvalidTypeError("address", "not a string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Address = addstr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) > 1 {
 | 
				
			||||||
 | 
							if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							args.BlockNumber = -1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GetStorageArgs struct {
 | 
				
			||||||
 | 
						Address     string
 | 
				
			||||||
 | 
						BlockNumber int64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []interface{}
 | 
				
			||||||
 | 
						if err := json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) < 1 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						addstr, ok := obj[0].(string)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return shared.NewInvalidTypeError("address", "not a string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Address = addstr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) > 1 {
 | 
				
			||||||
 | 
							if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							args.BlockNumber = -1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GetStorageAtArgs struct {
 | 
				
			||||||
 | 
						Address     string
 | 
				
			||||||
 | 
						BlockNumber int64
 | 
				
			||||||
 | 
						Key         string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []interface{}
 | 
				
			||||||
 | 
						if err := json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) < 2 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 2)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						addstr, ok := obj[0].(string)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return shared.NewInvalidTypeError("address", "not a string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Address = addstr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						keystr, ok := obj[1].(string)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return shared.NewInvalidTypeError("key", "not a string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Key = keystr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) > 2 {
 | 
				
			||||||
 | 
							if err := blockHeight(obj[2], &args.BlockNumber); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							args.BlockNumber = -1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GetTxCountArgs struct {
 | 
				
			||||||
 | 
						Address     string
 | 
				
			||||||
 | 
						BlockNumber int64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []interface{}
 | 
				
			||||||
 | 
						if err := json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) < 1 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						addstr, ok := obj[0].(string)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return shared.NewInvalidTypeError("address", "not a string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Address = addstr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) > 1 {
 | 
				
			||||||
 | 
							if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							args.BlockNumber = -1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type HashArgs struct {
 | 
				
			||||||
 | 
						Hash string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *HashArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []interface{}
 | 
				
			||||||
 | 
						if err := json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) < 1 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						arg0, ok := obj[0].(string)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return shared.NewInvalidTypeError("hash", "not a string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Hash = arg0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type BlockNumArg struct {
 | 
				
			||||||
 | 
						BlockNumber int64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *BlockNumArg) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []interface{}
 | 
				
			||||||
 | 
						if err := json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) < 1 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := blockHeight(obj[0], &args.BlockNumber); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GetDataArgs struct {
 | 
				
			||||||
 | 
						Address     string
 | 
				
			||||||
 | 
						BlockNumber int64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []interface{}
 | 
				
			||||||
 | 
						if err := json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) < 1 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						addstr, ok := obj[0].(string)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return shared.NewInvalidTypeError("address", "not a string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Address = addstr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) > 1 {
 | 
				
			||||||
 | 
							if err := blockHeight(obj[1], &args.BlockNumber); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							args.BlockNumber = -1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type NewSignArgs struct {
 | 
				
			||||||
 | 
						From string
 | 
				
			||||||
 | 
						Data string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *NewSignArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []json.RawMessage
 | 
				
			||||||
 | 
						var ext struct {
 | 
				
			||||||
 | 
							From string
 | 
				
			||||||
 | 
							Data string
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Decode byte slice to array of RawMessages
 | 
				
			||||||
 | 
						if err := json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check for sufficient params
 | 
				
			||||||
 | 
						if len(obj) < 1 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Decode 0th RawMessage to temporary struct
 | 
				
			||||||
 | 
						if err := json.Unmarshal(obj[0], &ext); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(ext.From) == 0 {
 | 
				
			||||||
 | 
							return shared.NewValidationError("from", "is required")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(ext.Data) == 0 {
 | 
				
			||||||
 | 
							return shared.NewValidationError("data", "is required")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args.From = ext.From
 | 
				
			||||||
 | 
						args.Data = ext.Data
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type NewTxArgs struct {
 | 
				
			||||||
 | 
						From     string
 | 
				
			||||||
 | 
						To       string
 | 
				
			||||||
 | 
						Nonce    *big.Int
 | 
				
			||||||
 | 
						Value    *big.Int
 | 
				
			||||||
 | 
						Gas      *big.Int
 | 
				
			||||||
 | 
						GasPrice *big.Int
 | 
				
			||||||
 | 
						Data     string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BlockNumber int64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []json.RawMessage
 | 
				
			||||||
 | 
						var ext struct {
 | 
				
			||||||
 | 
							From     string
 | 
				
			||||||
 | 
							To       string
 | 
				
			||||||
 | 
							Nonce    interface{}
 | 
				
			||||||
 | 
							Value    interface{}
 | 
				
			||||||
 | 
							Gas      interface{}
 | 
				
			||||||
 | 
							GasPrice interface{}
 | 
				
			||||||
 | 
							Data     string
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Decode byte slice to array of RawMessages
 | 
				
			||||||
 | 
						if err := json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check for sufficient params
 | 
				
			||||||
 | 
						if len(obj) < 1 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Decode 0th RawMessage to temporary struct
 | 
				
			||||||
 | 
						if err := json.Unmarshal(obj[0], &ext); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(ext.From) == 0 {
 | 
				
			||||||
 | 
							return shared.NewValidationError("from", "is required")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args.From = ext.From
 | 
				
			||||||
 | 
						args.To = ext.To
 | 
				
			||||||
 | 
						args.Data = ext.Data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var num *big.Int
 | 
				
			||||||
 | 
						if ext.Nonce != nil {
 | 
				
			||||||
 | 
							num, err = numString(ext.Nonce)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Nonce = num
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ext.Value == nil {
 | 
				
			||||||
 | 
							num = big.NewInt(0)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							num, err = numString(ext.Value)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Value = num
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						num = nil
 | 
				
			||||||
 | 
						if ext.Gas == nil {
 | 
				
			||||||
 | 
							num = big.NewInt(0)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if num, err = numString(ext.Gas); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Gas = num
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						num = nil
 | 
				
			||||||
 | 
						if ext.GasPrice == nil {
 | 
				
			||||||
 | 
							num = big.NewInt(0)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if num, err = numString(ext.GasPrice); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.GasPrice = num
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check for optional BlockNumber param
 | 
				
			||||||
 | 
						if len(obj) > 1 {
 | 
				
			||||||
 | 
							if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							args.BlockNumber = -1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SourceArgs struct {
 | 
				
			||||||
 | 
						Source string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *SourceArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []interface{}
 | 
				
			||||||
 | 
						if err := json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) < 1 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						arg0, ok := obj[0].(string)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return shared.NewInvalidTypeError("source code", "not a string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Source = arg0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CallArgs struct {
 | 
				
			||||||
 | 
						From     string
 | 
				
			||||||
 | 
						To       string
 | 
				
			||||||
 | 
						Value    *big.Int
 | 
				
			||||||
 | 
						Gas      *big.Int
 | 
				
			||||||
 | 
						GasPrice *big.Int
 | 
				
			||||||
 | 
						Data     string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BlockNumber int64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *CallArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []json.RawMessage
 | 
				
			||||||
 | 
						var ext struct {
 | 
				
			||||||
 | 
							From     string
 | 
				
			||||||
 | 
							To       string
 | 
				
			||||||
 | 
							Value    interface{}
 | 
				
			||||||
 | 
							Gas      interface{}
 | 
				
			||||||
 | 
							GasPrice interface{}
 | 
				
			||||||
 | 
							Data     string
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Decode byte slice to array of RawMessages
 | 
				
			||||||
 | 
						if err := json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check for sufficient params
 | 
				
			||||||
 | 
						if len(obj) < 1 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Decode 0th RawMessage to temporary struct
 | 
				
			||||||
 | 
						if err := json.Unmarshal(obj[0], &ext); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args.From = ext.From
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(ext.To) == 0 {
 | 
				
			||||||
 | 
							return shared.NewValidationError("to", "is required")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.To = ext.To
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var num *big.Int
 | 
				
			||||||
 | 
						if ext.Value == nil {
 | 
				
			||||||
 | 
							num = big.NewInt(0)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if num, err = numString(ext.Value); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Value = num
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ext.Gas == nil {
 | 
				
			||||||
 | 
							num = big.NewInt(0)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if num, err = numString(ext.Gas); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Gas = num
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ext.GasPrice == nil {
 | 
				
			||||||
 | 
							num = big.NewInt(0)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if num, err = numString(ext.GasPrice); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.GasPrice = num
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args.Data = ext.Data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Check for optional BlockNumber param
 | 
				
			||||||
 | 
						if len(obj) > 1 {
 | 
				
			||||||
 | 
							if err := blockHeightFromJson(obj[1], &args.BlockNumber); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							args.BlockNumber = -1
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type HashIndexArgs struct {
 | 
				
			||||||
 | 
						Hash  string
 | 
				
			||||||
 | 
						Index int64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *HashIndexArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []interface{}
 | 
				
			||||||
 | 
						if err := json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) < 2 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 2)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						arg0, ok := obj[0].(string)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return shared.NewInvalidTypeError("hash", "not a string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Hash = arg0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						arg1, ok := obj[1].(string)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return shared.NewInvalidTypeError("index", "not a string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Index = common.Big(arg1).Int64()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type BlockNumIndexArgs struct {
 | 
				
			||||||
 | 
						BlockNumber int64
 | 
				
			||||||
 | 
						Index       int64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *BlockNumIndexArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []interface{}
 | 
				
			||||||
 | 
						if err := json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) < 2 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 2)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := blockHeight(obj[0], &args.BlockNumber); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var arg1 *big.Int
 | 
				
			||||||
 | 
						if arg1, err = numString(obj[1]); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Index = arg1.Int64()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GetBlockByHashArgs struct {
 | 
				
			||||||
 | 
						BlockHash  string
 | 
				
			||||||
 | 
						IncludeTxs bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []interface{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) < 2 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 2)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						argstr, ok := obj[0].(string)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return shared.NewInvalidTypeError("blockHash", "not a string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.BlockHash = argstr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args.IncludeTxs = obj[1].(bool)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GetBlockByNumberArgs struct {
 | 
				
			||||||
 | 
						BlockNumber int64
 | 
				
			||||||
 | 
						IncludeTxs  bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []interface{}
 | 
				
			||||||
 | 
						if err := json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) < 2 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 2)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := blockHeight(obj[0], &args.BlockNumber); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args.IncludeTxs = obj[1].(bool)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type BlockFilterArgs struct {
 | 
				
			||||||
 | 
						Earliest int64
 | 
				
			||||||
 | 
						Latest   int64
 | 
				
			||||||
 | 
						Address  []string
 | 
				
			||||||
 | 
						Topics   [][]string
 | 
				
			||||||
 | 
						Skip     int
 | 
				
			||||||
 | 
						Max      int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *BlockFilterArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []struct {
 | 
				
			||||||
 | 
							FromBlock interface{} `json:"fromBlock"`
 | 
				
			||||||
 | 
							ToBlock   interface{} `json:"toBlock"`
 | 
				
			||||||
 | 
							Limit     interface{} `json:"limit"`
 | 
				
			||||||
 | 
							Offset    interface{} `json:"offset"`
 | 
				
			||||||
 | 
							Address   interface{} `json:"address"`
 | 
				
			||||||
 | 
							Topics    interface{} `json:"topics"`
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err = json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) < 1 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// args.Earliest, err = toNumber(obj[0].ToBlock)
 | 
				
			||||||
 | 
						// if err != nil {
 | 
				
			||||||
 | 
						// 	return shared.NewDecodeParamError(fmt.Sprintf("FromBlock %v", err))
 | 
				
			||||||
 | 
						// }
 | 
				
			||||||
 | 
						// args.Latest, err = toNumber(obj[0].FromBlock)
 | 
				
			||||||
 | 
						// if err != nil {
 | 
				
			||||||
 | 
						// 	return shared.NewDecodeParamError(fmt.Sprintf("ToBlock %v", err))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var num int64
 | 
				
			||||||
 | 
						var numBig *big.Int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// if blank then latest
 | 
				
			||||||
 | 
						if obj[0].FromBlock == nil {
 | 
				
			||||||
 | 
							num = -1
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if err := blockHeight(obj[0].FromBlock, &num); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// if -2 or other "silly" number, use latest
 | 
				
			||||||
 | 
						if num < 0 {
 | 
				
			||||||
 | 
							args.Earliest = -1 //latest block
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							args.Earliest = num
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// if blank than latest
 | 
				
			||||||
 | 
						if obj[0].ToBlock == nil {
 | 
				
			||||||
 | 
							num = -1
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if err := blockHeight(obj[0].ToBlock, &num); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Latest = num
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if obj[0].Limit == nil {
 | 
				
			||||||
 | 
							numBig = big.NewInt(defaultLogLimit)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if numBig, err = numString(obj[0].Limit); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Max = int(numBig.Int64())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if obj[0].Offset == nil {
 | 
				
			||||||
 | 
							numBig = big.NewInt(defaultLogOffset)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							if numBig, err = numString(obj[0].Offset); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Skip = int(numBig.Int64())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if obj[0].Address != nil {
 | 
				
			||||||
 | 
							marg, ok := obj[0].Address.([]interface{})
 | 
				
			||||||
 | 
							if ok {
 | 
				
			||||||
 | 
								v := make([]string, len(marg))
 | 
				
			||||||
 | 
								for i, arg := range marg {
 | 
				
			||||||
 | 
									argstr, ok := arg.(string)
 | 
				
			||||||
 | 
									if !ok {
 | 
				
			||||||
 | 
										return shared.NewInvalidTypeError(fmt.Sprintf("address[%d]", i), "is not a string")
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									v[i] = argstr
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								args.Address = v
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								argstr, ok := obj[0].Address.(string)
 | 
				
			||||||
 | 
								if ok {
 | 
				
			||||||
 | 
									v := make([]string, 1)
 | 
				
			||||||
 | 
									v[0] = argstr
 | 
				
			||||||
 | 
									args.Address = v
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									return shared.NewInvalidTypeError("address", "is not a string or array")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if obj[0].Topics != nil {
 | 
				
			||||||
 | 
							other, ok := obj[0].Topics.([]interface{})
 | 
				
			||||||
 | 
							if ok {
 | 
				
			||||||
 | 
								topicdbl := make([][]string, len(other))
 | 
				
			||||||
 | 
								for i, iv := range other {
 | 
				
			||||||
 | 
									if argstr, ok := iv.(string); ok {
 | 
				
			||||||
 | 
										// Found a string, push into first element of array
 | 
				
			||||||
 | 
										topicsgl := make([]string, 1)
 | 
				
			||||||
 | 
										topicsgl[0] = argstr
 | 
				
			||||||
 | 
										topicdbl[i] = topicsgl
 | 
				
			||||||
 | 
									} else if argarray, ok := iv.([]interface{}); ok {
 | 
				
			||||||
 | 
										// Found an array of other
 | 
				
			||||||
 | 
										topicdbl[i] = make([]string, len(argarray))
 | 
				
			||||||
 | 
										for j, jv := range argarray {
 | 
				
			||||||
 | 
											if v, ok := jv.(string); ok {
 | 
				
			||||||
 | 
												topicdbl[i][j] = v
 | 
				
			||||||
 | 
											} else if jv == nil {
 | 
				
			||||||
 | 
												topicdbl[i][j] = ""
 | 
				
			||||||
 | 
											} else {
 | 
				
			||||||
 | 
												return shared.NewInvalidTypeError(fmt.Sprintf("topic[%d][%d]", i, j), "is not a string")
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									} else if iv == nil {
 | 
				
			||||||
 | 
										topicdbl[i] = []string{""}
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										return shared.NewInvalidTypeError(fmt.Sprintf("topic[%d]", i), "not a string or array")
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								args.Topics = topicdbl
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return shared.NewInvalidTypeError("topic", "is not a string or array")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type FilterIdArgs struct {
 | 
				
			||||||
 | 
						Id int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *FilterIdArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []interface{}
 | 
				
			||||||
 | 
						if err := json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) < 1 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var num *big.Int
 | 
				
			||||||
 | 
						if num, err = numString(obj[0]); err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						args.Id = int(num.Int64())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type LogRes struct {
 | 
				
			||||||
 | 
						Address          *hexdata   `json:"address"`
 | 
				
			||||||
 | 
						Topics           []*hexdata `json:"topics"`
 | 
				
			||||||
 | 
						Data             *hexdata   `json:"data"`
 | 
				
			||||||
 | 
						BlockNumber      *hexnum    `json:"blockNumber"`
 | 
				
			||||||
 | 
						LogIndex         *hexnum    `json:"logIndex"`
 | 
				
			||||||
 | 
						BlockHash        *hexdata   `json:"blockHash"`
 | 
				
			||||||
 | 
						TransactionHash  *hexdata   `json:"transactionHash"`
 | 
				
			||||||
 | 
						TransactionIndex *hexnum    `json:"transactionIndex"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewLogRes(log *state.Log) LogRes {
 | 
				
			||||||
 | 
						var l LogRes
 | 
				
			||||||
 | 
						l.Topics = make([]*hexdata, len(log.Topics))
 | 
				
			||||||
 | 
						for j, topic := range log.Topics {
 | 
				
			||||||
 | 
							l.Topics[j] = newHexData(topic)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						l.Address = newHexData(log.Address)
 | 
				
			||||||
 | 
						l.Data = newHexData(log.Data)
 | 
				
			||||||
 | 
						l.BlockNumber = newHexNum(log.Number)
 | 
				
			||||||
 | 
						l.LogIndex = newHexNum(log.Index)
 | 
				
			||||||
 | 
						l.TransactionHash = newHexData(log.TxHash)
 | 
				
			||||||
 | 
						l.TransactionIndex = newHexNum(log.TxIndex)
 | 
				
			||||||
 | 
						l.BlockHash = newHexData(log.BlockHash)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return l
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewLogsRes(logs state.Logs) (ls []LogRes) {
 | 
				
			||||||
 | 
						ls = make([]LogRes, len(logs))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i, log := range logs {
 | 
				
			||||||
 | 
							ls[i] = NewLogRes(log)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewHashesRes(hs []common.Hash) []string {
 | 
				
			||||||
 | 
						hashes := make([]string, len(hs))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i, hash := range hs {
 | 
				
			||||||
 | 
							hashes[i] = hash.Hex()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return hashes
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SubmitWorkArgs struct {
 | 
				
			||||||
 | 
						Nonce  uint64
 | 
				
			||||||
 | 
						Header string
 | 
				
			||||||
 | 
						Digest string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (args *SubmitWorkArgs) UnmarshalJSON(b []byte) (err error) {
 | 
				
			||||||
 | 
						var obj []interface{}
 | 
				
			||||||
 | 
						if err = json.Unmarshal(b, &obj); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(obj) < 3 {
 | 
				
			||||||
 | 
							return shared.NewInsufficientParamsError(len(obj), 3)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var objstr string
 | 
				
			||||||
 | 
						var ok bool
 | 
				
			||||||
 | 
						if objstr, ok = obj[0].(string); !ok {
 | 
				
			||||||
 | 
							return shared.NewInvalidTypeError("nonce", "not a string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args.Nonce = common.String2Big(objstr).Uint64()
 | 
				
			||||||
 | 
						if objstr, ok = obj[1].(string); !ok {
 | 
				
			||||||
 | 
							return shared.NewInvalidTypeError("header", "not a string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args.Header = objstr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if objstr, ok = obj[2].(string); !ok {
 | 
				
			||||||
 | 
							return shared.NewInvalidTypeError("digest", "not a string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						args.Digest = objstr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										3
									
								
								rpc/api/eth_js.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								rpc/api/eth_js.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					package api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// JS api provided by web3.js
 | 
				
			||||||
							
								
								
									
										460
									
								
								rpc/api/parsing.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										460
									
								
								rpc/api/parsing.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,460 @@
 | 
				
			|||||||
 | 
					package api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/binary"
 | 
				
			||||||
 | 
						"encoding/hex"
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"math/big"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/common"
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/core/types"
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/rpc/shared"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type hexdata struct {
 | 
				
			||||||
 | 
						data  []byte
 | 
				
			||||||
 | 
						isNil bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d *hexdata) String() string {
 | 
				
			||||||
 | 
						return "0x" + common.Bytes2Hex(d.data)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d *hexdata) MarshalJSON() ([]byte, error) {
 | 
				
			||||||
 | 
						if d.isNil {
 | 
				
			||||||
 | 
							return json.Marshal(nil)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return json.Marshal(d.String())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newHexData(input interface{}) *hexdata {
 | 
				
			||||||
 | 
						d := new(hexdata)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if input == nil {
 | 
				
			||||||
 | 
							d.isNil = true
 | 
				
			||||||
 | 
							return d
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						switch input := input.(type) {
 | 
				
			||||||
 | 
						case []byte:
 | 
				
			||||||
 | 
							d.data = input
 | 
				
			||||||
 | 
						case common.Hash:
 | 
				
			||||||
 | 
							d.data = input.Bytes()
 | 
				
			||||||
 | 
						case *common.Hash:
 | 
				
			||||||
 | 
							if input == nil {
 | 
				
			||||||
 | 
								d.isNil = true
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								d.data = input.Bytes()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case common.Address:
 | 
				
			||||||
 | 
							d.data = input.Bytes()
 | 
				
			||||||
 | 
						case *common.Address:
 | 
				
			||||||
 | 
							if input == nil {
 | 
				
			||||||
 | 
								d.isNil = true
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								d.data = input.Bytes()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case types.Bloom:
 | 
				
			||||||
 | 
							d.data = input.Bytes()
 | 
				
			||||||
 | 
						case *types.Bloom:
 | 
				
			||||||
 | 
							if input == nil {
 | 
				
			||||||
 | 
								d.isNil = true
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								d.data = input.Bytes()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case *big.Int:
 | 
				
			||||||
 | 
							if input == nil {
 | 
				
			||||||
 | 
								d.isNil = true
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								d.data = input.Bytes()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						case int64:
 | 
				
			||||||
 | 
							d.data = big.NewInt(input).Bytes()
 | 
				
			||||||
 | 
						case uint64:
 | 
				
			||||||
 | 
							buff := make([]byte, 8)
 | 
				
			||||||
 | 
							binary.BigEndian.PutUint64(buff, input)
 | 
				
			||||||
 | 
							d.data = buff
 | 
				
			||||||
 | 
						case int:
 | 
				
			||||||
 | 
							d.data = big.NewInt(int64(input)).Bytes()
 | 
				
			||||||
 | 
						case uint:
 | 
				
			||||||
 | 
							d.data = big.NewInt(int64(input)).Bytes()
 | 
				
			||||||
 | 
						case int8:
 | 
				
			||||||
 | 
							d.data = big.NewInt(int64(input)).Bytes()
 | 
				
			||||||
 | 
						case uint8:
 | 
				
			||||||
 | 
							d.data = big.NewInt(int64(input)).Bytes()
 | 
				
			||||||
 | 
						case int16:
 | 
				
			||||||
 | 
							d.data = big.NewInt(int64(input)).Bytes()
 | 
				
			||||||
 | 
						case uint16:
 | 
				
			||||||
 | 
							buff := make([]byte, 2)
 | 
				
			||||||
 | 
							binary.BigEndian.PutUint16(buff, input)
 | 
				
			||||||
 | 
							d.data = buff
 | 
				
			||||||
 | 
						case int32:
 | 
				
			||||||
 | 
							d.data = big.NewInt(int64(input)).Bytes()
 | 
				
			||||||
 | 
						case uint32:
 | 
				
			||||||
 | 
							buff := make([]byte, 4)
 | 
				
			||||||
 | 
							binary.BigEndian.PutUint32(buff, input)
 | 
				
			||||||
 | 
							d.data = buff
 | 
				
			||||||
 | 
						case string: // hexstring
 | 
				
			||||||
 | 
							// aaargh ffs TODO: avoid back-and-forth hex encodings where unneeded
 | 
				
			||||||
 | 
							bytes, err := hex.DecodeString(strings.TrimPrefix(input, "0x"))
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								d.isNil = true
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								d.data = bytes
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							d.isNil = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return d
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type hexnum struct {
 | 
				
			||||||
 | 
						data  []byte
 | 
				
			||||||
 | 
						isNil bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d *hexnum) String() string {
 | 
				
			||||||
 | 
						// Get hex string from bytes
 | 
				
			||||||
 | 
						out := common.Bytes2Hex(d.data)
 | 
				
			||||||
 | 
						// Trim leading 0s
 | 
				
			||||||
 | 
						out = strings.TrimLeft(out, "0")
 | 
				
			||||||
 | 
						// Output "0x0" when value is 0
 | 
				
			||||||
 | 
						if len(out) == 0 {
 | 
				
			||||||
 | 
							out = "0"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return "0x" + out
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (d *hexnum) MarshalJSON() ([]byte, error) {
 | 
				
			||||||
 | 
						if d.isNil {
 | 
				
			||||||
 | 
							return json.Marshal(nil)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return json.Marshal(d.String())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newHexNum(input interface{}) *hexnum {
 | 
				
			||||||
 | 
						d := new(hexnum)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						d.data = newHexData(input).data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return d
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type BlockRes struct {
 | 
				
			||||||
 | 
						fullTx bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BlockNumber     *hexnum           `json:"number"`
 | 
				
			||||||
 | 
						BlockHash       *hexdata          `json:"hash"`
 | 
				
			||||||
 | 
						ParentHash      *hexdata          `json:"parentHash"`
 | 
				
			||||||
 | 
						Nonce           *hexdata          `json:"nonce"`
 | 
				
			||||||
 | 
						Sha3Uncles      *hexdata          `json:"sha3Uncles"`
 | 
				
			||||||
 | 
						LogsBloom       *hexdata          `json:"logsBloom"`
 | 
				
			||||||
 | 
						TransactionRoot *hexdata          `json:"transactionsRoot"`
 | 
				
			||||||
 | 
						StateRoot       *hexdata          `json:"stateRoot"`
 | 
				
			||||||
 | 
						Miner           *hexdata          `json:"miner"`
 | 
				
			||||||
 | 
						Difficulty      *hexnum           `json:"difficulty"`
 | 
				
			||||||
 | 
						TotalDifficulty *hexnum           `json:"totalDifficulty"`
 | 
				
			||||||
 | 
						Size            *hexnum           `json:"size"`
 | 
				
			||||||
 | 
						ExtraData       *hexdata          `json:"extraData"`
 | 
				
			||||||
 | 
						GasLimit        *hexnum           `json:"gasLimit"`
 | 
				
			||||||
 | 
						GasUsed         *hexnum           `json:"gasUsed"`
 | 
				
			||||||
 | 
						UnixTimestamp   *hexnum           `json:"timestamp"`
 | 
				
			||||||
 | 
						Transactions    []*TransactionRes `json:"transactions"`
 | 
				
			||||||
 | 
						Uncles          []*UncleRes       `json:"uncles"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (b *BlockRes) MarshalJSON() ([]byte, error) {
 | 
				
			||||||
 | 
						if b.fullTx {
 | 
				
			||||||
 | 
							var ext struct {
 | 
				
			||||||
 | 
								BlockNumber     *hexnum           `json:"number"`
 | 
				
			||||||
 | 
								BlockHash       *hexdata          `json:"hash"`
 | 
				
			||||||
 | 
								ParentHash      *hexdata          `json:"parentHash"`
 | 
				
			||||||
 | 
								Nonce           *hexdata          `json:"nonce"`
 | 
				
			||||||
 | 
								Sha3Uncles      *hexdata          `json:"sha3Uncles"`
 | 
				
			||||||
 | 
								LogsBloom       *hexdata          `json:"logsBloom"`
 | 
				
			||||||
 | 
								TransactionRoot *hexdata          `json:"transactionsRoot"`
 | 
				
			||||||
 | 
								StateRoot       *hexdata          `json:"stateRoot"`
 | 
				
			||||||
 | 
								Miner           *hexdata          `json:"miner"`
 | 
				
			||||||
 | 
								Difficulty      *hexnum           `json:"difficulty"`
 | 
				
			||||||
 | 
								TotalDifficulty *hexnum           `json:"totalDifficulty"`
 | 
				
			||||||
 | 
								Size            *hexnum           `json:"size"`
 | 
				
			||||||
 | 
								ExtraData       *hexdata          `json:"extraData"`
 | 
				
			||||||
 | 
								GasLimit        *hexnum           `json:"gasLimit"`
 | 
				
			||||||
 | 
								GasUsed         *hexnum           `json:"gasUsed"`
 | 
				
			||||||
 | 
								UnixTimestamp   *hexnum           `json:"timestamp"`
 | 
				
			||||||
 | 
								Transactions    []*TransactionRes `json:"transactions"`
 | 
				
			||||||
 | 
								Uncles          []*hexdata        `json:"uncles"`
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ext.BlockNumber = b.BlockNumber
 | 
				
			||||||
 | 
							ext.BlockHash = b.BlockHash
 | 
				
			||||||
 | 
							ext.ParentHash = b.ParentHash
 | 
				
			||||||
 | 
							ext.Nonce = b.Nonce
 | 
				
			||||||
 | 
							ext.Sha3Uncles = b.Sha3Uncles
 | 
				
			||||||
 | 
							ext.LogsBloom = b.LogsBloom
 | 
				
			||||||
 | 
							ext.TransactionRoot = b.TransactionRoot
 | 
				
			||||||
 | 
							ext.StateRoot = b.StateRoot
 | 
				
			||||||
 | 
							ext.Miner = b.Miner
 | 
				
			||||||
 | 
							ext.Difficulty = b.Difficulty
 | 
				
			||||||
 | 
							ext.TotalDifficulty = b.TotalDifficulty
 | 
				
			||||||
 | 
							ext.Size = b.Size
 | 
				
			||||||
 | 
							ext.ExtraData = b.ExtraData
 | 
				
			||||||
 | 
							ext.GasLimit = b.GasLimit
 | 
				
			||||||
 | 
							ext.GasUsed = b.GasUsed
 | 
				
			||||||
 | 
							ext.UnixTimestamp = b.UnixTimestamp
 | 
				
			||||||
 | 
							ext.Transactions = b.Transactions
 | 
				
			||||||
 | 
							ext.Uncles = make([]*hexdata, len(b.Uncles))
 | 
				
			||||||
 | 
							for i, u := range b.Uncles {
 | 
				
			||||||
 | 
								ext.Uncles[i] = u.BlockHash
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return json.Marshal(ext)
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							var ext struct {
 | 
				
			||||||
 | 
								BlockNumber     *hexnum    `json:"number"`
 | 
				
			||||||
 | 
								BlockHash       *hexdata   `json:"hash"`
 | 
				
			||||||
 | 
								ParentHash      *hexdata   `json:"parentHash"`
 | 
				
			||||||
 | 
								Nonce           *hexdata   `json:"nonce"`
 | 
				
			||||||
 | 
								Sha3Uncles      *hexdata   `json:"sha3Uncles"`
 | 
				
			||||||
 | 
								LogsBloom       *hexdata   `json:"logsBloom"`
 | 
				
			||||||
 | 
								TransactionRoot *hexdata   `json:"transactionsRoot"`
 | 
				
			||||||
 | 
								StateRoot       *hexdata   `json:"stateRoot"`
 | 
				
			||||||
 | 
								Miner           *hexdata   `json:"miner"`
 | 
				
			||||||
 | 
								Difficulty      *hexnum    `json:"difficulty"`
 | 
				
			||||||
 | 
								TotalDifficulty *hexnum    `json:"totalDifficulty"`
 | 
				
			||||||
 | 
								Size            *hexnum    `json:"size"`
 | 
				
			||||||
 | 
								ExtraData       *hexdata   `json:"extraData"`
 | 
				
			||||||
 | 
								GasLimit        *hexnum    `json:"gasLimit"`
 | 
				
			||||||
 | 
								GasUsed         *hexnum    `json:"gasUsed"`
 | 
				
			||||||
 | 
								UnixTimestamp   *hexnum    `json:"timestamp"`
 | 
				
			||||||
 | 
								Transactions    []*hexdata `json:"transactions"`
 | 
				
			||||||
 | 
								Uncles          []*hexdata `json:"uncles"`
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ext.BlockNumber = b.BlockNumber
 | 
				
			||||||
 | 
							ext.BlockHash = b.BlockHash
 | 
				
			||||||
 | 
							ext.ParentHash = b.ParentHash
 | 
				
			||||||
 | 
							ext.Nonce = b.Nonce
 | 
				
			||||||
 | 
							ext.Sha3Uncles = b.Sha3Uncles
 | 
				
			||||||
 | 
							ext.LogsBloom = b.LogsBloom
 | 
				
			||||||
 | 
							ext.TransactionRoot = b.TransactionRoot
 | 
				
			||||||
 | 
							ext.StateRoot = b.StateRoot
 | 
				
			||||||
 | 
							ext.Miner = b.Miner
 | 
				
			||||||
 | 
							ext.Difficulty = b.Difficulty
 | 
				
			||||||
 | 
							ext.TotalDifficulty = b.TotalDifficulty
 | 
				
			||||||
 | 
							ext.Size = b.Size
 | 
				
			||||||
 | 
							ext.ExtraData = b.ExtraData
 | 
				
			||||||
 | 
							ext.GasLimit = b.GasLimit
 | 
				
			||||||
 | 
							ext.GasUsed = b.GasUsed
 | 
				
			||||||
 | 
							ext.UnixTimestamp = b.UnixTimestamp
 | 
				
			||||||
 | 
							ext.Transactions = make([]*hexdata, len(b.Transactions))
 | 
				
			||||||
 | 
							for i, tx := range b.Transactions {
 | 
				
			||||||
 | 
								ext.Transactions[i] = tx.Hash
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							ext.Uncles = make([]*hexdata, len(b.Uncles))
 | 
				
			||||||
 | 
							for i, u := range b.Uncles {
 | 
				
			||||||
 | 
								ext.Uncles[i] = u.BlockHash
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return json.Marshal(ext)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewBlockRes(block *types.Block, fullTx bool) *BlockRes {
 | 
				
			||||||
 | 
						if block == nil {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res := new(BlockRes)
 | 
				
			||||||
 | 
						res.fullTx = fullTx
 | 
				
			||||||
 | 
						res.BlockNumber = newHexNum(block.Number())
 | 
				
			||||||
 | 
						res.BlockHash = newHexData(block.Hash())
 | 
				
			||||||
 | 
						res.ParentHash = newHexData(block.ParentHash())
 | 
				
			||||||
 | 
						res.Nonce = newHexData(block.Nonce())
 | 
				
			||||||
 | 
						res.Sha3Uncles = newHexData(block.Header().UncleHash)
 | 
				
			||||||
 | 
						res.LogsBloom = newHexData(block.Bloom())
 | 
				
			||||||
 | 
						res.TransactionRoot = newHexData(block.Header().TxHash)
 | 
				
			||||||
 | 
						res.StateRoot = newHexData(block.Root())
 | 
				
			||||||
 | 
						res.Miner = newHexData(block.Header().Coinbase)
 | 
				
			||||||
 | 
						res.Difficulty = newHexNum(block.Difficulty())
 | 
				
			||||||
 | 
						res.TotalDifficulty = newHexNum(block.Td)
 | 
				
			||||||
 | 
						res.Size = newHexNum(block.Size().Int64())
 | 
				
			||||||
 | 
						res.ExtraData = newHexData(block.Header().Extra)
 | 
				
			||||||
 | 
						res.GasLimit = newHexNum(block.GasLimit())
 | 
				
			||||||
 | 
						res.GasUsed = newHexNum(block.GasUsed())
 | 
				
			||||||
 | 
						res.UnixTimestamp = newHexNum(block.Time())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.Transactions = make([]*TransactionRes, len(block.Transactions()))
 | 
				
			||||||
 | 
						for i, tx := range block.Transactions() {
 | 
				
			||||||
 | 
							res.Transactions[i] = NewTransactionRes(tx)
 | 
				
			||||||
 | 
							res.Transactions[i].BlockHash = res.BlockHash
 | 
				
			||||||
 | 
							res.Transactions[i].BlockNumber = res.BlockNumber
 | 
				
			||||||
 | 
							res.Transactions[i].TxIndex = newHexNum(i)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						res.Uncles = make([]*UncleRes, len(block.Uncles()))
 | 
				
			||||||
 | 
						for i, uncle := range block.Uncles() {
 | 
				
			||||||
 | 
							res.Uncles[i] = NewUncleRes(uncle)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return res
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TransactionRes struct {
 | 
				
			||||||
 | 
						Hash        *hexdata `json:"hash"`
 | 
				
			||||||
 | 
						Nonce       *hexnum  `json:"nonce"`
 | 
				
			||||||
 | 
						BlockHash   *hexdata `json:"blockHash"`
 | 
				
			||||||
 | 
						BlockNumber *hexnum  `json:"blockNumber"`
 | 
				
			||||||
 | 
						TxIndex     *hexnum  `json:"transactionIndex"`
 | 
				
			||||||
 | 
						From        *hexdata `json:"from"`
 | 
				
			||||||
 | 
						To          *hexdata `json:"to"`
 | 
				
			||||||
 | 
						Value       *hexnum  `json:"value"`
 | 
				
			||||||
 | 
						Gas         *hexnum  `json:"gas"`
 | 
				
			||||||
 | 
						GasPrice    *hexnum  `json:"gasPrice"`
 | 
				
			||||||
 | 
						Input       *hexdata `json:"input"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewTransactionRes(tx *types.Transaction) *TransactionRes {
 | 
				
			||||||
 | 
						if tx == nil {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var v = new(TransactionRes)
 | 
				
			||||||
 | 
						v.Hash = newHexData(tx.Hash())
 | 
				
			||||||
 | 
						v.Nonce = newHexNum(tx.Nonce())
 | 
				
			||||||
 | 
						// v.BlockHash =
 | 
				
			||||||
 | 
						// v.BlockNumber =
 | 
				
			||||||
 | 
						// v.TxIndex =
 | 
				
			||||||
 | 
						from, _ := tx.From()
 | 
				
			||||||
 | 
						v.From = newHexData(from)
 | 
				
			||||||
 | 
						v.To = newHexData(tx.To())
 | 
				
			||||||
 | 
						v.Value = newHexNum(tx.Value())
 | 
				
			||||||
 | 
						v.Gas = newHexNum(tx.Gas())
 | 
				
			||||||
 | 
						v.GasPrice = newHexNum(tx.GasPrice())
 | 
				
			||||||
 | 
						v.Input = newHexData(tx.Data())
 | 
				
			||||||
 | 
						return v
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UncleRes struct {
 | 
				
			||||||
 | 
						BlockNumber     *hexnum  `json:"number"`
 | 
				
			||||||
 | 
						BlockHash       *hexdata `json:"hash"`
 | 
				
			||||||
 | 
						ParentHash      *hexdata `json:"parentHash"`
 | 
				
			||||||
 | 
						Nonce           *hexdata `json:"nonce"`
 | 
				
			||||||
 | 
						Sha3Uncles      *hexdata `json:"sha3Uncles"`
 | 
				
			||||||
 | 
						ReceiptHash     *hexdata `json:"receiptHash"`
 | 
				
			||||||
 | 
						LogsBloom       *hexdata `json:"logsBloom"`
 | 
				
			||||||
 | 
						TransactionRoot *hexdata `json:"transactionsRoot"`
 | 
				
			||||||
 | 
						StateRoot       *hexdata `json:"stateRoot"`
 | 
				
			||||||
 | 
						Miner           *hexdata `json:"miner"`
 | 
				
			||||||
 | 
						Difficulty      *hexnum  `json:"difficulty"`
 | 
				
			||||||
 | 
						ExtraData       *hexdata `json:"extraData"`
 | 
				
			||||||
 | 
						GasLimit        *hexnum  `json:"gasLimit"`
 | 
				
			||||||
 | 
						GasUsed         *hexnum  `json:"gasUsed"`
 | 
				
			||||||
 | 
						UnixTimestamp   *hexnum  `json:"timestamp"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewUncleRes(h *types.Header) *UncleRes {
 | 
				
			||||||
 | 
						if h == nil {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var v = new(UncleRes)
 | 
				
			||||||
 | 
						v.BlockNumber = newHexNum(h.Number)
 | 
				
			||||||
 | 
						v.BlockHash = newHexData(h.Hash())
 | 
				
			||||||
 | 
						v.ParentHash = newHexData(h.ParentHash)
 | 
				
			||||||
 | 
						v.Sha3Uncles = newHexData(h.UncleHash)
 | 
				
			||||||
 | 
						v.Nonce = newHexData(h.Nonce[:])
 | 
				
			||||||
 | 
						v.LogsBloom = newHexData(h.Bloom)
 | 
				
			||||||
 | 
						v.TransactionRoot = newHexData(h.TxHash)
 | 
				
			||||||
 | 
						v.StateRoot = newHexData(h.Root)
 | 
				
			||||||
 | 
						v.Miner = newHexData(h.Coinbase)
 | 
				
			||||||
 | 
						v.Difficulty = newHexNum(h.Difficulty)
 | 
				
			||||||
 | 
						v.ExtraData = newHexData(h.Extra)
 | 
				
			||||||
 | 
						v.GasLimit = newHexNum(h.GasLimit)
 | 
				
			||||||
 | 
						v.GasUsed = newHexNum(h.GasUsed)
 | 
				
			||||||
 | 
						v.UnixTimestamp = newHexNum(h.Time)
 | 
				
			||||||
 | 
						v.ReceiptHash = newHexData(h.ReceiptHash)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return v
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// type FilterLogRes struct {
 | 
				
			||||||
 | 
					// 	Hash             string `json:"hash"`
 | 
				
			||||||
 | 
					// 	Address          string `json:"address"`
 | 
				
			||||||
 | 
					// 	Data             string `json:"data"`
 | 
				
			||||||
 | 
					// 	BlockNumber      string `json:"blockNumber"`
 | 
				
			||||||
 | 
					// 	TransactionHash  string `json:"transactionHash"`
 | 
				
			||||||
 | 
					// 	BlockHash        string `json:"blockHash"`
 | 
				
			||||||
 | 
					// 	TransactionIndex string `json:"transactionIndex"`
 | 
				
			||||||
 | 
					// 	LogIndex         string `json:"logIndex"`
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// type FilterWhisperRes struct {
 | 
				
			||||||
 | 
					// 	Hash       string `json:"hash"`
 | 
				
			||||||
 | 
					// 	From       string `json:"from"`
 | 
				
			||||||
 | 
					// 	To         string `json:"to"`
 | 
				
			||||||
 | 
					// 	Expiry     string `json:"expiry"`
 | 
				
			||||||
 | 
					// 	Sent       string `json:"sent"`
 | 
				
			||||||
 | 
					// 	Ttl        string `json:"ttl"`
 | 
				
			||||||
 | 
					// 	Topics     string `json:"topics"`
 | 
				
			||||||
 | 
					// 	Payload    string `json:"payload"`
 | 
				
			||||||
 | 
					// 	WorkProved string `json:"workProved"`
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func numString(raw interface{}) (*big.Int, error) {
 | 
				
			||||||
 | 
						var number *big.Int
 | 
				
			||||||
 | 
						// Parse as integer
 | 
				
			||||||
 | 
						num, ok := raw.(float64)
 | 
				
			||||||
 | 
						if ok {
 | 
				
			||||||
 | 
							number = big.NewInt(int64(num))
 | 
				
			||||||
 | 
							return number, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Parse as string/hexstring
 | 
				
			||||||
 | 
						str, ok := raw.(string)
 | 
				
			||||||
 | 
						if ok {
 | 
				
			||||||
 | 
							number = common.String2Big(str)
 | 
				
			||||||
 | 
							return number, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil, shared.NewInvalidTypeError("", "not a number or string")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func blockHeight(raw interface{}, number *int64) error {
 | 
				
			||||||
 | 
						// Parse as integer
 | 
				
			||||||
 | 
						num, ok := raw.(float64)
 | 
				
			||||||
 | 
						if ok {
 | 
				
			||||||
 | 
							*number = int64(num)
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Parse as string/hexstring
 | 
				
			||||||
 | 
						str, ok := raw.(string)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return shared.NewInvalidTypeError("", "not a number or string")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch str {
 | 
				
			||||||
 | 
						case "earliest":
 | 
				
			||||||
 | 
							*number = 0
 | 
				
			||||||
 | 
						case "latest":
 | 
				
			||||||
 | 
							*number = -1
 | 
				
			||||||
 | 
						case "pending":
 | 
				
			||||||
 | 
							*number = -2
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							if common.HasHexPrefix(str) {
 | 
				
			||||||
 | 
								*number = common.String2Big(str).Int64()
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return shared.NewInvalidTypeError("blockNumber", "is not a valid string")
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func blockHeightFromJson(msg json.RawMessage, number *int64) error {
 | 
				
			||||||
 | 
						var raw interface{}
 | 
				
			||||||
 | 
						if err := json.Unmarshal(msg, &raw); err != nil {
 | 
				
			||||||
 | 
							return shared.NewDecodeParamError(err.Error())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return blockHeight(raw, number)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										36
									
								
								rpc/api/utils.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								rpc/api/utils.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					package api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/eth"
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/rpc/codec"
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/xeth"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						EthApiName = "eth"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parse a comma separated API string to individual api's
 | 
				
			||||||
 | 
					func ParseApiString(apistr string, codec codec.Codec, xeth *xeth.XEth, eth *eth.Ethereum) ([]EthereumApi, error) {
 | 
				
			||||||
 | 
						if len(strings.TrimSpace(apistr)) == 0 {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("Empty apistr provided")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						names := strings.Split(apistr, ",")
 | 
				
			||||||
 | 
						apis := make([]EthereumApi, len(names))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i, name := range names {
 | 
				
			||||||
 | 
							switch strings.ToLower(strings.TrimSpace(name)) {
 | 
				
			||||||
 | 
							case EthApiName:
 | 
				
			||||||
 | 
								apis[i] = NewEthApi(xeth, codec)
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								return nil, fmt.Errorf("Unknown API '%s'", name)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return apis, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										47
									
								
								rpc/codec/codec.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								rpc/codec/codec.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					package codec
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/rpc/shared"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Codec int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// (de)serialization support for rpc interface
 | 
				
			||||||
 | 
					type ApiCoder interface {
 | 
				
			||||||
 | 
						// Parse message to request from underlying stream
 | 
				
			||||||
 | 
						ReadRequest() (*shared.Request, error)
 | 
				
			||||||
 | 
						// Parse response message from underlying stream
 | 
				
			||||||
 | 
						ReadResponse() (interface{}, error)
 | 
				
			||||||
 | 
						// Encode response to encoded form in underlying stream
 | 
				
			||||||
 | 
						WriteResponse(interface{}) error
 | 
				
			||||||
 | 
						// Decode single message from data
 | 
				
			||||||
 | 
						Decode([]byte, interface{}) error
 | 
				
			||||||
 | 
						// Encode msg to encoded form
 | 
				
			||||||
 | 
						Encode(msg interface{}) ([]byte, error)
 | 
				
			||||||
 | 
						// close the underlying stream
 | 
				
			||||||
 | 
						Close()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// supported codecs
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						JSON Codec = iota
 | 
				
			||||||
 | 
						nCodecs
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						// collection with supported coders
 | 
				
			||||||
 | 
						coders = make([]func(net.Conn) ApiCoder, nCodecs)
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// create a new coder instance
 | 
				
			||||||
 | 
					func (c Codec) New(conn net.Conn) ApiCoder {
 | 
				
			||||||
 | 
						switch c {
 | 
				
			||||||
 | 
						case JSON:
 | 
				
			||||||
 | 
							return NewJsonCoder(conn)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						panic("codec: request for codec #" + strconv.Itoa(int(c)) + " is unavailable")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										75
									
								
								rpc/codec/json.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								rpc/codec/json.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
				
			|||||||
 | 
					package codec
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"net"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/ethereum/go-ethereum/rpc/shared"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						MAX_RESPONSE_SIZE = 64 * 1024
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Json serialization support
 | 
				
			||||||
 | 
					type JsonCodec struct {
 | 
				
			||||||
 | 
						c net.Conn
 | 
				
			||||||
 | 
						d *json.Decoder
 | 
				
			||||||
 | 
						e *json.Encoder
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create new JSON coder instance
 | 
				
			||||||
 | 
					func NewJsonCoder(conn net.Conn) ApiCoder {
 | 
				
			||||||
 | 
						return &JsonCodec{
 | 
				
			||||||
 | 
							c: conn,
 | 
				
			||||||
 | 
							d: json.NewDecoder(conn),
 | 
				
			||||||
 | 
							e: json.NewEncoder(conn),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Serialize obj to JSON and write it to conn
 | 
				
			||||||
 | 
					func (self *JsonCodec) ReadRequest() (*shared.Request, error) {
 | 
				
			||||||
 | 
						req := shared.Request{}
 | 
				
			||||||
 | 
						err := self.d.Decode(&req)
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							return &req, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *JsonCodec) ReadResponse() (interface{}, error) {
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						buf := make([]byte, MAX_RESPONSE_SIZE)
 | 
				
			||||||
 | 
						n, _ := self.c.Read(buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var failure shared.ErrorResponse
 | 
				
			||||||
 | 
						if err = json.Unmarshal(buf[:n], &failure); err == nil && failure.Error != nil {
 | 
				
			||||||
 | 
							return failure, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var success shared.SuccessResponse
 | 
				
			||||||
 | 
						if err = json.Unmarshal(buf[:n], &success); err == nil {
 | 
				
			||||||
 | 
							return success, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil, err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encode response to encoded form in underlying stream
 | 
				
			||||||
 | 
					func (self *JsonCodec) Decode(data []byte, msg interface{}) error {
 | 
				
			||||||
 | 
						return json.Unmarshal(data, msg)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (self *JsonCodec) Encode(msg interface{}) ([]byte, error) {
 | 
				
			||||||
 | 
						return json.Marshal(msg)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Parse JSON data from conn to obj
 | 
				
			||||||
 | 
					func (self *JsonCodec) WriteResponse(res interface{}) error {
 | 
				
			||||||
 | 
						return self.e.Encode(&res)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Close decoder and encoder
 | 
				
			||||||
 | 
					func (self *JsonCodec) Close() {
 | 
				
			||||||
 | 
						self.c.Close()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										96
									
								
								rpc/shared/errors.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								rpc/shared/errors.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
				
			|||||||
 | 
					package shared
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type InvalidTypeError struct {
 | 
				
			||||||
 | 
						method string
 | 
				
			||||||
 | 
						msg    string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *InvalidTypeError) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("invalid type on field %s: %s", e.method, e.msg)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewInvalidTypeError(method, msg string) *InvalidTypeError {
 | 
				
			||||||
 | 
						return &InvalidTypeError{
 | 
				
			||||||
 | 
							method: method,
 | 
				
			||||||
 | 
							msg:    msg,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type InsufficientParamsError struct {
 | 
				
			||||||
 | 
						have int
 | 
				
			||||||
 | 
						want int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *InsufficientParamsError) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("insufficient params, want %d have %d", e.want, e.have)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewInsufficientParamsError(have int, want int) *InsufficientParamsError {
 | 
				
			||||||
 | 
						return &InsufficientParamsError{
 | 
				
			||||||
 | 
							have: have,
 | 
				
			||||||
 | 
							want: want,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type NotImplementedError struct {
 | 
				
			||||||
 | 
						Method string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *NotImplementedError) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("%s method not implemented", e.Method)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewNotImplementedError(method string) *NotImplementedError {
 | 
				
			||||||
 | 
						return &NotImplementedError{
 | 
				
			||||||
 | 
							Method: method,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type DecodeParamError struct {
 | 
				
			||||||
 | 
						err string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *DecodeParamError) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("could not decode, %s", e.err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewDecodeParamError(errstr string) error {
 | 
				
			||||||
 | 
						return &DecodeParamError{
 | 
				
			||||||
 | 
							err: errstr,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ValidationError struct {
 | 
				
			||||||
 | 
						ParamName string
 | 
				
			||||||
 | 
						msg       string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *ValidationError) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("%s not valid, %s", e.ParamName, e.msg)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewValidationError(param string, msg string) error {
 | 
				
			||||||
 | 
						return &ValidationError{
 | 
				
			||||||
 | 
							ParamName: param,
 | 
				
			||||||
 | 
							msg:       msg,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type NotAvailableError struct {
 | 
				
			||||||
 | 
						Method string
 | 
				
			||||||
 | 
						Reason string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e *NotAvailableError) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("%s method not available: %s", e.Method, e.Reason)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewNotAvailableError(method string, reason string) *NotAvailableError {
 | 
				
			||||||
 | 
						return &NotAvailableError{
 | 
				
			||||||
 | 
							Method: method,
 | 
				
			||||||
 | 
							Reason: reason,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								rpc/shared/types.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								rpc/shared/types.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					package shared
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "encoding/json"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RPC request
 | 
				
			||||||
 | 
					type Request struct {
 | 
				
			||||||
 | 
						Id      interface{}     `json:"id"`
 | 
				
			||||||
 | 
						Jsonrpc string          `json:"jsonrpc"`
 | 
				
			||||||
 | 
						Method  string          `json:"method"`
 | 
				
			||||||
 | 
						Params  json.RawMessage `json:"params"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RPC response
 | 
				
			||||||
 | 
					type Response struct {
 | 
				
			||||||
 | 
						Id      interface{} `json:"id"`
 | 
				
			||||||
 | 
						Jsonrpc string      `json:"jsonrpc"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RPC success response
 | 
				
			||||||
 | 
					type SuccessResponse struct {
 | 
				
			||||||
 | 
						Id      interface{} `json:"id"`
 | 
				
			||||||
 | 
						Jsonrpc string      `json:"jsonrpc"`
 | 
				
			||||||
 | 
						Result  interface{} `json:"result"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RPC error response
 | 
				
			||||||
 | 
					type ErrorResponse struct {
 | 
				
			||||||
 | 
						Id      interface{}  `json:"id"`
 | 
				
			||||||
 | 
						Jsonrpc string       `json:"jsonrpc"`
 | 
				
			||||||
 | 
						Error   *ErrorObject `json:"error"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// RPC error response details
 | 
				
			||||||
 | 
					type ErrorObject struct {
 | 
				
			||||||
 | 
						Code    int    `json:"code"`
 | 
				
			||||||
 | 
						Message string `json:"message"`
 | 
				
			||||||
 | 
						// Data    interface{} `json:"data"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user