├── .github └── workflows │ └── go.yml ├── .gitignore ├── README.md ├── client.go ├── client ├── base.go ├── client_debug.go ├── client_eth.go ├── client_eth_test.go ├── client_filter.go ├── client_parity.go ├── client_trace.go └── utils.go ├── client_abigen.go ├── client_abigen_test.go ├── client_option.go ├── client_test.go ├── go.mod ├── go.sum ├── integration_test ├── client_debug_test_.go ├── client_eth_test.go ├── client_filter_test.go └── client_pubsub_test.go ├── interfaces └── signer.go ├── providers └── provider_sign.go ├── signers ├── keystore.go ├── keystore_test.go ├── privatekey_signer.go ├── privatekey_signer_test.go ├── signer_manager.go └── signer_manager_test.go └── types ├── account_pending_transactions.go ├── account_pending_transactions_test.go ├── action.go ├── action_result.go ├── call_request_json.go ├── enums ├── geth_debug_builtin_trace.go ├── geth_trace.go ├── pending_reason.go └── transaction_status.go ├── filter_changes.go ├── filter_query.go ├── filter_transaction.go ├── gas_fee_data.go ├── gen_account_pending_transactions_json.go ├── gen_block_json.go ├── gen_call_json.go ├── gen_call_result_json.go ├── gen_create_json.go ├── gen_create_result_json.go ├── gen_eth_protocol_info_json.go ├── gen_fee_history_json.go ├── gen_histogram_json.go ├── gen_log_json.go ├── gen_memory_diff_json.go ├── gen_plain_transaction_json.go ├── gen_receipt_json.go ├── gen_reward_json.go ├── gen_storage_diff_json.go ├── gen_suicide_json.go ├── gen_trace_results_json.go ├── gen_trace_results_with_transaction_hash_json.go ├── gen_value_filter_argument_json.go ├── gen_vm_executed_operation_json.go ├── gen_vm_trace_json.go ├── geth_trace.go ├── geth_trace_option.go ├── geth_trace_result.go ├── geth_trace_result_test.go ├── header.go ├── header_test.go ├── parity.go ├── sync_status.go ├── trace.go ├── transaction_args.go ├── transaction_args_test.go ├── tx_or_hash_list.go ├── types.go ├── types_test.go └── util.go /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | 16 | - name: Set up Go 17 | uses: actions/setup-go@v3 18 | with: 19 | go-version: 1.21 20 | 21 | - name: Build 22 | run: go build -v ./... 23 | 24 | - name: Test 25 | run: go test -v ./... 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | tmp 2 | .rust_commit.md 3 | __debug_bin 4 | keys 5 | .DS_Store 6 | .licence.txt -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # web3go 2 | The web3go's goal is to build a golang SDK for supporting all Ethereum RPC 3 | 4 | ## Struct Fields Type Rule 5 | For developer convenience, the web3go use standard type instead of hex types in RPC response, for example, `*hexutil.Big` will be `*big.Int` in client interface. As well as the struct fields, but `marshal/unmarshal` result still be hex format. 6 | 1. The types of struct fields according to geth and parity and use the minimal type, such geth is `hexutil.Uint64` and parity is `*hexutil.Big`, then the field type will be `uint64` 7 | 2. The slice item always be a pointer if the item is struct to avoid value copy when iteration 8 | 9 | ## Client 10 | 11 | ### NewClient 12 | 13 | The `NewClient` creates a client with default timeout options. 14 | 15 | - the default timeout is 30 seconds 16 | 17 | ```golang 18 | NewClient("http://localhost:8545") 19 | ``` 20 | ### NewClientWithOption 21 | Use `NewClientWithOption` to specify retry, timeout and signer manager options, the signer manager option is used for signing transactions automatically when call `SendTransaction` or `SendTransactionByArgs` 22 | 23 | ```golang 24 | NewClientWithOption("http://localhost:8545", providers.Option{...}) 25 | ``` 26 | 27 | The provider of both clients created by `NewClient` and `NewClientWithOption` are [middlewarable providers](https://github.com/openweb3/go-rpc-provider). 28 | 29 | Middlewarable providers could hook CallContext/BatchCallContext/Subscribe, such as log RPC request and response or cache environment variable in the context. 30 | 31 | For custom pre/post Call/Batchcall behaviors, you can use HookCallContext of Middlewarable, such as log requests and so on, see more from [go-rpc-provider](https://github.com/openweb3/go-rpc-provider) 32 | ```golang 33 | p, e := providers.NewBaseProvider(context.Background(), "http://localhost:8545") 34 | if e != nil { 35 | return e 36 | } 37 | p.HookCallContext(callContextLogMiddleware) 38 | NewClientWithProvider(p) 39 | ``` 40 | 41 | the callLogMiddleware is like 42 | ```golang 43 | func callContextLogMiddleware(f providers.CallFunc) providers.CallFunc { 44 | return func(ctx context.Context, resultPtr interface{}, method string, args ...interface{}) error { 45 | fmt.Printf("request %v %v\n", method, args) 46 | err := f(ctx, resultPtr, method, args...) 47 | j, _ := json.Marshal(resultPtr) 48 | fmt.Printf("response %s\n", j) 49 | return err 50 | } 51 | } 52 | ``` 53 | ### NewClientWithProvider 54 | 55 | You also could set your customer provider by `NewClientWithProvider` 56 | 57 | ## Sign 58 | 59 | ### Signer 60 | There is an interface `signer` for signing transactions and messages. 61 | 62 | - `SignTransaction` to sign a transaction 63 | - `SignMessage` to sign a message 64 | 65 | We provide kinds of functions to create a private key signer, which means it will convert anything input to the private key. 66 | 67 | *create by private key* 68 | - `NewPrivateKeySigner` 69 | 70 | *create by private key string* 71 | - `NewPrivateKeySignerByString` 72 | - `MustNewPrivateKeySignerByString` 73 | 74 | *create a random private key* 75 | - `NewRandomPrivateKeySigner` 76 | - `MustNewRandomPrivateKeySigner` 77 | 78 | *create by mnemonic* 79 | - `NewPrivateKeySignerByMnemonic` 80 | - `MustNewPrivateKeySignerByMnemonic` 81 | 82 | *create by Keystore* 83 | - `NewPrivateKeySignerByKeystoreFile` 84 | - `MustNewPrivateKeySignerByKeystoreFile` 85 | - `NewPrivateKeySignerByKeystore` 86 | - `MustNewPrivateKeySignerByKeystore` 87 | 88 | ### Signer Manager 89 | 90 | Signer Manager is for manager signers conveniently, support get/add/remove/list signer. 91 | 92 | And convenient functions to create signer managers, such as create by private key strings and mnemonic 93 | 94 | - `NewSignerManager` 95 | - `NewSignerManagerByPrivateKeyStrings` 96 | - `MustNewSignerManagerByPrivateKeyStrings` 97 | - `NewSignerManagerByMnemonic` 98 | - `MustNewSignerManagerByMnemonic` 99 | 100 | ### Auto Sign 101 | 102 | There are two ways to create a client that can be automatically signed when sending transactions. 103 | 104 | - Firstly and the simple way is to create a client by `NewClientWithOption` and set the field `SignerManager` of `Option` 105 | 106 | ```go 107 | mnemonic := "crisp shove million stem shiver side hospital split play lottery join vintage" 108 | sm := signers.MustNewSignerManagerByMnemonic(mnemonic, 10, nil) 109 | option := new(ClientOption).WithLooger(os.Stdout).WithSignerManager(sm) 110 | c, err := NewClientWithOption("https://evm.confluxrpc.com", *option) 111 | 112 | from := sm.List()[0].Address() 113 | to := sm.List()[1].Address() 114 | hash, err := c.Eth.SendTransactionByArgs(types.TransactionArgs{ 115 | From: &from, 116 | To: &to, 117 | }) 118 | ``` 119 | 120 | - Another way is to create a `MiddlewareableProvider` by [`NewSignableProvider`](https://github.com/openweb3/web3go/blob/main/providers/provider_sign.go) 121 | 122 | ```go 123 | mnemonic := "crisp shove million stem shiver side hospital split play lottery join vintage" 124 | sm := signers.MustNewSignerManagerByMnemonic(mnemonic, 10, nil) 125 | p := pproviders.MustNewBaseProvider(context.Background(), "https://evm.confluxrpc.com") 126 | p = providers.NewSignableProvider(p, sm) 127 | c := NewClientWithProvider(p) 128 | ``` 129 | 130 | #### Send Transaction 131 | 132 | There are two ways to send transactions and auto-sign, `SendTransaction` and `SendTransactionByArgs` 133 | 134 | - `SendTransaction` send by [transaction type of `go-ethereum`](https://github.com/openweb3/web3go/blob/08c2cb1790acbc92277f28b3d98e8b7347450cc5/types/types.go#L246) and needs to specify the sender 135 | ```golang 136 | mnemonic := "crisp shove million stem shiver side hospital split play lottery join vintage" 137 | sm := signers.MustNewSignerManagerByMnemonic(mnemonic, 10, nil) 138 | c := MustNewClientWithOption("https://ropsten.infura.io/v3/cb2c1b76cb894b699f20a602f35731f1", *(new(ClientOption).WithLoger(os.Stdout).WithSignerManager(sm))) 139 | 140 | // send legacy tx 141 | tx := ethrpctypes.NewTransaction(nonce.Uint64(), from, big.NewInt(1000000), 1000000, big.NewInt(1), nil) 142 | txhash, err := c.SendTransaction(from, *tx) 143 | if err != nil { 144 | panic(err) 145 | } 146 | fmt.Printf("send legacy tx, hash: %s\n", txhash) 147 | 148 | // send dynamic fee tx 149 | dtx := ðrpctypes.DynamicFeeTx{ 150 | To: &from, 151 | Value: big.NewInt(1), 152 | } 153 | txhash, err = c.SendTransaction(from, *ethrpctypes.NewTx(dtx)) 154 | if err != nil { 155 | panic(err) 156 | } 157 | fmt.Printf("send dynamic fee tx, hash: %s\n", txhash) 158 | 159 | ``` 160 | - `SendTransactionByArgs` send by transaction type of `TransactionArgs` which contains all fields a transaction needs 161 | ```golang 162 | mnemonic := "crisp shove million stem shiver side hospital split play lottery join vintage" 163 | sm := signers.MustNewSignerManagerByMnemonic(mnemonic, 10, nil) 164 | c := MustNewClientWithOption("https://ropsten.infura.io/v3/cb2c1b76cb894b699f20a602f35731f1", *(new(ClientOption).WithLoger(os.Stdout).WithSignerManager(sm))) 165 | 166 | from := sm.List()[0].Address() 167 | to := sm.List()[1].Address() 168 | hash, err := c.Eth.SendTransactionByArgs(types.TransactionArgs{ 169 | From: &from, 170 | To: &to, 171 | }) 172 | if err != nil { 173 | panic(err) 174 | } 175 | fmt.Printf("hash: %s\n", hash) 176 | ``` 177 | If the provider of client contains the signer of the transaction's `From`, both of them will populate transaction fields, sign the transaction and call `eth_sendRawTransaction` to send RLP-Encoded transaction. Otherwise will call `eth_sendTransaction`. 178 | 179 | ## Contract 180 | 181 | Invoke with contract please use [abigen](https://geth.ethereum.org/docs/dapp/native-bindings), we provide the methods `ToClientForContract` for generating `bind.ContractBackend` and `bind.SignerFn` for conveniently use in abi-binding struct which is generated by abigen 182 | 183 | Please see the example from [example_abigen](https://github.com/openweb3/web3go-example/blob/master/example_abigen) 184 | -------------------------------------------------------------------------------- /client.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 OpenWeb3. All rights reserved. 2 | // Conflux is free software and distributed under GNU General Public License. 3 | // See http://www.gnu.org/licenses/ 4 | 5 | package web3go 6 | 7 | import ( 8 | "context" 9 | "errors" 10 | "math/big" 11 | 12 | "github.com/ethereum/go-ethereum/accounts/abi/bind" 13 | "github.com/ethereum/go-ethereum/common" 14 | "github.com/openweb3/go-rpc-provider/interfaces" 15 | pproviders "github.com/openweb3/go-rpc-provider/provider_wrapper" 16 | client "github.com/openweb3/web3go/client" 17 | "github.com/openweb3/web3go/providers" 18 | "github.com/openweb3/web3go/signers" 19 | "github.com/openweb3/web3go/types" 20 | ) 21 | 22 | // Client defines typed wrappers for the Ethereum RPC API. 23 | type Client struct { 24 | *pproviders.MiddlewarableProvider 25 | context context.Context 26 | option *ClientOption 27 | Eth *client.RpcEthClient 28 | Trace *client.RpcTraceClient 29 | Parity *client.RpcParityClient 30 | Filter *client.RpcFilterClient 31 | Debug *client.RpcDebugClient 32 | } 33 | 34 | var ( 35 | ErrNotFound = errors.New("not found") 36 | ) 37 | 38 | func NewClient(rawurl string) (*Client, error) { 39 | return NewClientWithOption(rawurl, ClientOption{}) 40 | } 41 | 42 | func MustNewClient(rawurl string) *Client { 43 | c, err := NewClient(rawurl) 44 | if err != nil { 45 | panic(err) 46 | } 47 | return c 48 | } 49 | 50 | func NewClientWithOption(rawurl string, option ClientOption) (*Client, error) { 51 | 52 | option.setDefault() 53 | 54 | p, err := pproviders.NewProviderWithOption(rawurl, option.Option) 55 | if err != nil { 56 | return nil, err 57 | } 58 | 59 | if option.SignerManager != nil { 60 | p = providers.NewSignableProvider(p, option.SignerManager) 61 | } 62 | 63 | ec := NewClientWithProvider(p) 64 | ec.option = &option 65 | 66 | return ec, nil 67 | } 68 | 69 | func MustNewClientWithOption(rawurl string, option ClientOption) *Client { 70 | c, err := NewClientWithOption(rawurl, option) 71 | if err != nil { 72 | panic(err) 73 | } 74 | return c 75 | } 76 | 77 | func NewClientWithProvider(p interfaces.Provider) *Client { 78 | c := &Client{} 79 | c.SetProvider(p) 80 | return c 81 | } 82 | 83 | // WithContext creates a new Client with specified context 84 | func (client *Client) WithContext(ctx context.Context) *Client { 85 | _client := client.copy() 86 | _client.context = ctx 87 | _client.Eth.SetContext(ctx) 88 | _client.Filter.SetContext(ctx) 89 | _client.Parity.SetContext(ctx) 90 | _client.Trace.SetContext(ctx) 91 | _client.Debug.SetContext(ctx) 92 | return _client 93 | } 94 | 95 | func (client *Client) copy() *Client { 96 | _client := *client 97 | eth := *client.Eth 98 | filter := *client.Filter 99 | parity := *client.Parity 100 | trace := *client.Trace 101 | debug := *client.Debug 102 | 103 | _client.Eth = ð 104 | _client.Filter = &filter 105 | _client.Parity = &parity 106 | _client.Trace = &trace 107 | _client.Debug = &debug 108 | 109 | return &_client 110 | } 111 | 112 | func (c *Client) SetProvider(p interfaces.Provider) { 113 | if _, ok := p.(*pproviders.MiddlewarableProvider); !ok { 114 | p = pproviders.NewMiddlewarableProvider(p) 115 | } 116 | 117 | c.MiddlewarableProvider = p.(*pproviders.MiddlewarableProvider) 118 | c.Eth = client.NewRpcEthClient(p) 119 | c.Trace = client.NewRpcTraceClient(p) 120 | c.Parity = client.NewRpcParityClient(p) 121 | c.Filter = client.NewRpcFilterClient(p) 122 | c.Debug = client.NewRpcDebugClient(p) 123 | } 124 | 125 | func (c *Client) Provider() *pproviders.MiddlewarableProvider { 126 | return c.MiddlewarableProvider 127 | } 128 | 129 | // GetSignerManager returns signer manager if exist in option, otherwise return error 130 | func (c *Client) GetSignerManager() (*signers.SignerManager, error) { 131 | if c.option.SignerManager != nil { 132 | return c.option.SignerManager, nil 133 | } 134 | return nil, ErrNotFound 135 | } 136 | 137 | // ToClientForContract returns ClientForContract and SignerFn for use by abi-binding struct generated by abigen. 138 | // abigen is a source code generator to convert Ethereum contract definitions into easy to use, compile-time type-safe Go packages. 139 | // Please see https://geth.ethereum.org/docs/dapp/native-bindings page for details 140 | func (c *Client) ToClientForContract() (*ClientForContract, bind.SignerFn) { 141 | sm, err := c.GetSignerManager() 142 | if err != nil { 143 | return NewClientForContract(c), nil 144 | } 145 | 146 | signFunc := func(addr common.Address, t *types.Transaction) (*types.Transaction, error) { 147 | chainId, err := c.Eth.ChainId() 148 | if err != nil { 149 | return nil, err 150 | } 151 | s, err := sm.Get(addr) 152 | if err != nil { 153 | return nil, err 154 | } 155 | return s.SignTransaction(t, new(big.Int).SetUint64(*chainId)) 156 | } 157 | 158 | return NewClientForContract(c), signFunc 159 | } 160 | -------------------------------------------------------------------------------- /client/base.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | 6 | providers "github.com/openweb3/go-rpc-provider/provider_wrapper" 7 | ) 8 | 9 | type BaseClient struct { 10 | *providers.MiddlewarableProvider 11 | context context.Context 12 | } 13 | 14 | // WithContext creates a new Client with specified context 15 | func (client *BaseClient) SetContext(ctx context.Context) { 16 | client.context = ctx 17 | } 18 | 19 | func (client *BaseClient) getContext() context.Context { 20 | if client.context == nil { 21 | return context.Background() 22 | } 23 | return client.context 24 | } 25 | -------------------------------------------------------------------------------- /client/client_debug.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | "github.com/openweb3/go-rpc-provider/interfaces" 8 | providers "github.com/openweb3/go-rpc-provider/provider_wrapper" 9 | "github.com/openweb3/web3go/types" 10 | "github.com/openweb3/web3go/types/enums" 11 | ) 12 | 13 | type RpcDebugClient struct { 14 | BaseClient 15 | } 16 | 17 | func NewRpcDebugClient(provider interfaces.Provider) *RpcDebugClient { 18 | _client := &RpcDebugClient{} 19 | _client.MiddlewarableProvider = providers.NewMiddlewarableProvider(provider) 20 | return _client 21 | } 22 | 23 | func (c *RpcDebugClient) TraceTransaction(tx_hash common.Hash, opts ...*types.GethDebugTracingOptions) (val *types.GethTrace, err error) { 24 | opt := get1stOpt(opts) 25 | val = &types.GethTrace{Type: getGethTraceTypeByOpt(opt)} 26 | err = c.CallContext(c.getContext(), &val, "debug_traceTransaction", tx_hash, opt) 27 | return 28 | } 29 | 30 | func (c *RpcDebugClient) TraceBlockByHash(block_hash common.Hash, opts ...*types.GethDebugTracingOptions) (val []*types.GethTraceResult, err error) { 31 | opt := get1stOpt(opts) 32 | 33 | var tmpVal []any 34 | err = c.CallContext(c.getContext(), &tmpVal, "debug_traceBlockByHash", block_hash, opt) 35 | if err != nil { 36 | return nil, err 37 | } 38 | 39 | val = make([]*types.GethTraceResult, len(tmpVal)) 40 | tracerType := getGethTraceTypeByOpt(opt) 41 | for i, v := range tmpVal { 42 | val[i] = &types.GethTraceResult{TracerType: tracerType} 43 | 44 | b, _ := json.Marshal(v) 45 | if err := val[i].UnmarshalJSON(b); err != nil { 46 | return nil, err 47 | } 48 | } 49 | 50 | return val, err 51 | } 52 | 53 | func (c *RpcDebugClient) TraceBlockByNumber(blockNumber types.BlockNumber, opts ...*types.GethDebugTracingOptions) (val []*types.GethTraceResult, err error) { 54 | opt := get1stOpt(opts) 55 | 56 | var tmpVal []any 57 | err = c.CallContext(c.getContext(), &tmpVal, "debug_traceBlockByNumber", blockNumber, opt) 58 | if err != nil { 59 | return nil, err 60 | } 61 | 62 | val = make([]*types.GethTraceResult, len(tmpVal)) 63 | tracerType := getGethTraceTypeByOpt(opt) 64 | for i, v := range tmpVal { 65 | val[i] = &types.GethTraceResult{TracerType: tracerType} 66 | 67 | b, _ := json.Marshal(v) 68 | if err := val[i].UnmarshalJSON(b); err != nil { 69 | return nil, err 70 | } 71 | } 72 | 73 | return val, err 74 | } 75 | 76 | func (c *RpcDebugClient) TraceCall(request types.CallRequest, block_number *types.BlockNumber, opts ...*types.GethDebugTracingOptions) (val *types.GethTrace, err error) { 77 | opt := get1stOpt(opts) 78 | val = &types.GethTrace{Type: getGethTraceTypeByOpt(opt)} 79 | err = c.CallContext(c.getContext(), &val, "debug_traceCall", request, block_number, opt) 80 | return 81 | } 82 | 83 | func getGethTraceTypeByOpt(opts *types.GethDebugTracingOptions) enums.GethTraceType { 84 | t := enums.GETH_TRACE_DEFAULT 85 | if opts != nil { 86 | t = enums.ParseGethTraceType(opts.Tracer) 87 | } 88 | return t 89 | } 90 | 91 | func get1stOpt(opts []*types.GethDebugTracingOptions) *types.GethDebugTracingOptions { 92 | if len(opts) == 0 { 93 | return nil 94 | } 95 | return opts[0] 96 | } 97 | -------------------------------------------------------------------------------- /client/client_eth_test.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "math/big" 7 | "os" 8 | "testing" 9 | 10 | "github.com/ethereum/go-ethereum/common" 11 | "github.com/ethereum/go-ethereum/common/hexutil" 12 | 13 | rpc "github.com/openweb3/go-rpc-provider" 14 | 15 | ethrpctypes "github.com/ethereum/go-ethereum/core/types" 16 | pproviders "github.com/openweb3/go-rpc-provider/provider_wrapper" 17 | "github.com/openweb3/web3go/providers" 18 | "github.com/openweb3/web3go/signers" 19 | "github.com/openweb3/web3go/types" 20 | "github.com/stretchr/testify/assert" 21 | ) 22 | 23 | func TestSendTransaction(t *testing.T) { 24 | ast := assert.New(t) 25 | sm, err := signers.NewSignerManagerByPrivateKeyStrings([]string{"9ec393923a14eeb557600010ea05d635c667a6995418f8a8f4bdecc63dfe0bb9"}) 26 | ast.NoError(err) 27 | 28 | provider := pproviders.MustNewBaseProvider(context.Background(), "https://sepolia.infura.io/v3/d91582da330a4812be53d698a34741aa") 29 | provider = pproviders.NewLoggerProvider(provider, os.Stdout) 30 | provider = providers.NewSignableProvider(provider, sm) 31 | provider = pproviders.NewLoggerProvider(provider, os.Stdout) 32 | 33 | c := NewRpcEthClient(provider) 34 | 35 | from := common.HexToAddress("0xe6D148D8398c4cb456196C776D2d9093Dd62C9B0") 36 | pendingBlock := types.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) 37 | nonce, err := c.TransactionCount(from, &pendingBlock) 38 | ast.NoError(err) 39 | 40 | // legacy tx 41 | tx := ethrpctypes.NewTransaction(nonce.Uint64(), from, big.NewInt(1000000), 1000000, big.NewInt(1), nil) 42 | txhash, err := c.SendTransaction(from, *tx) 43 | ast.NoError(err) 44 | fmt.Printf("txhash: %s\n", txhash) 45 | 46 | // dynamic fee tx 47 | dtx := ðrpctypes.DynamicFeeTx{ 48 | To: &from, 49 | Value: big.NewInt(1), 50 | } 51 | txhash, err = c.SendTransaction(from, *ethrpctypes.NewTx(dtx)) 52 | ast.NoError(err) 53 | fmt.Printf("txhash: %s\n", txhash) 54 | } 55 | 56 | func TestBatchCall(t *testing.T) { 57 | provider := pproviders.MustNewBaseProvider(context.Background(), "https://sepolia.infura.io/v3/d91582da330a4812be53d698a34741aa") 58 | provider = pproviders.NewLoggerProvider(provider, os.Stdout) 59 | 60 | var batchElems []rpc.BatchElem 61 | batchElems = append(batchElems, rpc.BatchElem{ 62 | Method: "eth_blockNumber", 63 | Args: nil, 64 | Result: new(hexutil.Big), 65 | }, rpc.BatchElem{ 66 | Method: "eth_getBlockByNumber", 67 | Args: []interface{}{types.LatestBlockNumber, false}, 68 | Result: new(types.Block), 69 | }, 70 | ) 71 | err := provider.BatchCallContext(context.Background(), batchElems) 72 | assert.NoError(t, err) 73 | assert.NotEqual(t, 0, *batchElems[0].Result.(*hexutil.Big)) 74 | assert.NotEqual(t, types.Block{}, *batchElems[1].Result.(*types.Block)) 75 | } 76 | 77 | func TestAccountPendingTransactions(t *testing.T) { 78 | // node := "https://sepolia.infura.io/v3/d91582da330a4812be53d698a34741aa" 79 | node := "https://evmtestnet-internal.confluxrpc.com" 80 | provider := pproviders.MustNewBaseProvider(context.Background(), node) 81 | provider = pproviders.NewLoggerProvider(provider, os.Stdout) 82 | 83 | c := NewRpcEthClient(provider) 84 | 85 | addr := common.HexToAddress("0xBeD38c825459994002257DFBB88371E243204B6c") 86 | pendingTxs, err := c.AccountPendingTransactions(addr, nil, nil) 87 | assert.NoError(t, err) 88 | fmt.Printf("pending: %+v\n", pendingTxs) 89 | } 90 | -------------------------------------------------------------------------------- /client/client_filter.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "github.com/openweb3/go-rpc-provider" 5 | "github.com/openweb3/go-rpc-provider/interfaces" 6 | providers "github.com/openweb3/go-rpc-provider/provider_wrapper" 7 | "github.com/openweb3/web3go/types" 8 | ) 9 | 10 | type RpcFilterClient struct { 11 | BaseClient 12 | } 13 | 14 | func NewRpcFilterClient(provider interfaces.Provider) *RpcFilterClient { 15 | _client := &RpcFilterClient{} 16 | _client.MiddlewarableProvider = providers.NewMiddlewarableProvider(provider) 17 | return _client 18 | } 19 | 20 | // Returns id of new filter. 21 | func (c *RpcFilterClient) NewLogFilter(filter *types.FilterQuery) (val *rpc.ID, err error) { 22 | err = c.CallContext(c.getContext(), &val, "eth_newFilter", filter) 23 | return 24 | } 25 | 26 | // Returns id of new block filter. 27 | func (c *RpcFilterClient) NewBlockFilter() (val *rpc.ID, err error) { 28 | err = c.CallContext(c.getContext(), &val, "eth_newBlockFilter") 29 | return 30 | } 31 | 32 | // Returns id of new block filter. 33 | func (c *RpcFilterClient) NewPendingTransactionFilter() (val *rpc.ID, err error) { 34 | err = c.CallContext(c.getContext(), &val, "eth_newPendingTransactionFilter") 35 | return 36 | } 37 | 38 | // Returns filter changes since last poll. 39 | func (c *RpcFilterClient) GetFilterChanges(filterID rpc.ID) (val *types.FilterChanges, err error) { 40 | err = c.CallContext(c.getContext(), &val, "eth_getFilterChanges", filterID) 41 | return 42 | } 43 | 44 | // Returns all logs matching given filter (in a range 'from' - 'to'). 45 | func (c *RpcFilterClient) GetFilterLogs(filterID rpc.ID) (val []types.Log, err error) { 46 | err = c.CallContext(c.getContext(), &val, "eth_getFilterLogs", filterID) 47 | return 48 | } 49 | 50 | // Uninstalls filter. 51 | func (c *RpcFilterClient) UninstallFilter(filterID rpc.ID) (val bool, err error) { 52 | err = c.CallContext(c.getContext(), &val, "eth_uninstallFilter", filterID) 53 | return 54 | } 55 | -------------------------------------------------------------------------------- /client/client_parity.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "math/big" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | "github.com/ethereum/go-ethereum/common/hexutil" 8 | "github.com/openweb3/go-rpc-provider/interfaces" 9 | providers "github.com/openweb3/go-rpc-provider/provider_wrapper" 10 | "github.com/openweb3/web3go/types" 11 | ) 12 | 13 | type RpcParityClient struct { 14 | BaseClient 15 | } 16 | 17 | func NewRpcParityClient(provider interfaces.Provider) *RpcParityClient { 18 | _client := &RpcParityClient{} 19 | _client.MiddlewarableProvider = providers.NewMiddlewarableProvider(provider) 20 | return _client 21 | } 22 | 23 | // Returns current transactions limit. 24 | func (c *RpcParityClient) TransactionsLimit() (val uint, err error) { 25 | err = c.CallContext(c.getContext(), &val, "parity_transactionsLimit") 26 | return 27 | } 28 | 29 | // Returns mining extra data. 30 | func (c *RpcParityClient) ExtraData() (val []byte, err error) { 31 | var _val hexutil.Bytes 32 | err = c.CallContext(c.getContext(), &_val, "parity_extraData") 33 | val = ([]byte)(_val) 34 | return 35 | } 36 | 37 | // Returns mining gas floor target. 38 | func (c *RpcParityClient) GasFloorTarget() (val *big.Int, err error) { 39 | var _val *hexutil.Big 40 | err = c.CallContext(c.getContext(), &_val, "parity_gasFloorTarget") 41 | val = (*big.Int)(_val) 42 | return 43 | } 44 | 45 | // Returns mining gas floor cap. 46 | func (c *RpcParityClient) GasCeilTarget() (val *big.Int, err error) { 47 | var _val *hexutil.Big 48 | err = c.CallContext(c.getContext(), &_val, "parity_gasCeilTarget") 49 | val = (*big.Int)(_val) 50 | return 51 | } 52 | 53 | // Returns minimal gas price for transaction to be included in queue. 54 | func (c *RpcParityClient) MinGasPrice() (val *big.Int, err error) { 55 | var _val *hexutil.Big 56 | err = c.CallContext(c.getContext(), &_val, "parity_minGasPrice") 57 | val = (*big.Int)(_val) 58 | return 59 | } 60 | 61 | // Returns latest logs 62 | func (c *RpcParityClient) DevLogs() (val []string, err error) { 63 | err = c.CallContext(c.getContext(), &val, "parity_devLogs") 64 | return 65 | } 66 | 67 | // Returns logs levels 68 | func (c *RpcParityClient) DevLogsLevels() (val string, err error) { 69 | err = c.CallContext(c.getContext(), &val, "parity_devLogsLevels") 70 | return 71 | } 72 | 73 | // Returns chain name - DEPRECATED. Use `parity_chainName` instead. 74 | func (c *RpcParityClient) NetChain() (val string, err error) { 75 | err = c.CallContext(c.getContext(), &val, "parity_netChain") 76 | return 77 | } 78 | 79 | // Returns peers details 80 | func (c *RpcParityClient) NetPeers() (val types.Peers, err error) { 81 | err = c.CallContext(c.getContext(), &val, "parity_netPeers") 82 | return 83 | } 84 | 85 | // Returns network port 86 | func (c *RpcParityClient) NetPort() (val uint16, err error) { 87 | err = c.CallContext(c.getContext(), &val, "parity_netPort") 88 | return 89 | } 90 | 91 | // Returns rpc settings 92 | func (c *RpcParityClient) RpcSettings() (val types.RpcSettings, err error) { 93 | err = c.CallContext(c.getContext(), &val, "parity_rpcSettings") 94 | return 95 | } 96 | 97 | // Returns node name 98 | func (c *RpcParityClient) NodeName() (val string, err error) { 99 | err = c.CallContext(c.getContext(), &val, "parity_nodeName") 100 | return 101 | } 102 | 103 | // Returns default extra data 104 | func (c *RpcParityClient) DefaultExtraData() (val []byte, err error) { 105 | var _val hexutil.Bytes 106 | err = c.CallContext(c.getContext(), &_val, "parity_defaultExtraData") 107 | val = ([]byte)(_val) 108 | return 109 | } 110 | 111 | // Returns distribution of gas price in latest blocks. 112 | func (c *RpcParityClient) GasPriceHistogram() (val types.Histogram, err error) { 113 | err = c.CallContext(c.getContext(), &val, "parity_gasPriceHistogram") 114 | return 115 | } 116 | 117 | // Returns number of unsigned transactions waiting in the signer queue (if signer enabled) 118 | // Returns error when signer is disabled 119 | func (c *RpcParityClient) UnsignedTransactionsCount() (val uint, err error) { 120 | err = c.CallContext(c.getContext(), &val, "parity_unsignedTransactionsCount") 121 | return 122 | } 123 | 124 | // Returns a cryptographically random phrase sufficient for securely seeding a secret key. 125 | func (c *RpcParityClient) GenerateSecretPhrase() (val string, err error) { 126 | err = c.CallContext(c.getContext(), &val, "parity_generateSecretPhrase") 127 | return 128 | } 129 | 130 | // Returns whatever address would be derived from the given phrase if it were to seed a brainwallet. 131 | func (c *RpcParityClient) PhraseToAddress(phrase string) (val common.Address, err error) { 132 | err = c.CallContext(c.getContext(), &val, "parity_phraseToAddress", phrase) 133 | return 134 | } 135 | 136 | // Returns the value of the registrar for this network. 137 | func (c *RpcParityClient) RegistryAddress() (val *common.Address, err error) { 138 | err = c.CallContext(c.getContext(), &val, "parity_registryAddress") 139 | return 140 | } 141 | 142 | // Returns all addresses if Fat DB is enabled (`--fat-db`), or null if not. 143 | func (c *RpcParityClient) ListAccounts(count uint64, after *common.Address, blockNumber *types.BlockNumberOrHash) (val []common.Address, err error) { 144 | err = c.CallContext(c.getContext(), &val, "parity_listAccounts", count, after, getRealBlockNumberOrHash(blockNumber)) 145 | return 146 | } 147 | 148 | // Returns all storage keys of the given address (first parameter) if Fat DB is enabled (`--fat-db`), 149 | // or null if not. 150 | func (c *RpcParityClient) ListStorageKeys(address common.Address, count uint64, after *common.Hash, blockNumber *types.BlockNumberOrHash) (val []common.Hash, err error) { 151 | err = c.CallContext(c.getContext(), &val, "parity_listStorageKeys", address, count, after, getRealBlockNumberOrHash(blockNumber)) 152 | return 153 | } 154 | 155 | // Encrypt some data with a public key under ECIES. 156 | // First parameter is the 512-byte destination public key, second is the message. 157 | // FIXME: key should be H512 public key 158 | func (c *RpcParityClient) EncryptMessage(key string, phrase []byte) (val []byte, err error) { 159 | _phrase := (hexutil.Bytes)(phrase) 160 | var _val hexutil.Bytes 161 | err = c.CallContext(c.getContext(), &_val, "parity_encryptMessage", key, _phrase) 162 | val = ([]byte)(_val) 163 | return 164 | } 165 | 166 | // Returns all pending transactions from transaction queue. 167 | func (c *RpcParityClient) PendingTransactions(limit *uint, filter *types.TransactionFilter) (val []types.TransactionDetail, err error) { 168 | err = c.CallContext(c.getContext(), &val, "parity_pendingTransactions", limit, filter) 169 | return 170 | } 171 | 172 | // Returns all transactions from transaction queue. 173 | // 174 | // Some of them might not be ready to be included in a block yet. 175 | func (c *RpcParityClient) AllTransactions() (val []types.TransactionDetail, err error) { 176 | err = c.CallContext(c.getContext(), &val, "parity_allTransactions") 177 | return 178 | } 179 | 180 | // Same as parity_allTransactions, but return only transactions hashes. 181 | func (c *RpcParityClient) AllTransactionHashes() (val []common.Hash, err error) { 182 | err = c.CallContext(c.getContext(), &val, "parity_allTransactionHashes") 183 | return 184 | } 185 | 186 | // Returns all future transactions from transaction queue (deprecated) 187 | func (c *RpcParityClient) FutureTransactions() (val []types.TransactionDetail, err error) { 188 | err = c.CallContext(c.getContext(), &val, "parity_futureTransactions") 189 | return 190 | } 191 | 192 | // Returns propagation statistics on transactions pending in the queue. 193 | func (c *RpcParityClient) PendingTransactionsStats() (val map[common.Hash](types.TransactionStats), err error) { 194 | err = c.CallContext(c.getContext(), &val, "parity_pendingTransactionsStats") 195 | return 196 | } 197 | 198 | // Returns a list of current and past local transactions with status details. 199 | func (c *RpcParityClient) LocalTransactions() (val map[common.Hash]types.LocalTransactionStatus, err error) { 200 | err = c.CallContext(c.getContext(), &val, "parity_localTransactions") 201 | return 202 | } 203 | 204 | // Returns current WS Server interface and port or an error if ws server is disabled. 205 | func (c *RpcParityClient) WsUrl() (val string, err error) { 206 | err = c.CallContext(c.getContext(), &val, "parity_wsUrl") 207 | return 208 | } 209 | 210 | // Returns next nonce for particular sender. Should include all transactions in the queue. 211 | func (c *RpcParityClient) NextNonce(address common.Address) (val *big.Int, err error) { 212 | var _val *hexutil.Big 213 | err = c.CallContext(c.getContext(), &_val, "parity_nextNonce", address) 214 | val = (*big.Int)(_val) 215 | return 216 | } 217 | 218 | // Get the mode. Returns one of: "active", "passive", "dark", "offline". 219 | func (c *RpcParityClient) Mode() (val string, err error) { 220 | err = c.CallContext(c.getContext(), &val, "parity_mode") 221 | return 222 | } 223 | 224 | // Get the chain name. Returns one of the pre-configured chain names or a filename. 225 | func (c *RpcParityClient) Chain() (val string, err error) { 226 | err = c.CallContext(c.getContext(), &val, "parity_chain") 227 | return 228 | } 229 | 230 | // Get the enode of this node. 231 | func (c *RpcParityClient) Enode() (val string, err error) { 232 | err = c.CallContext(c.getContext(), &val, "parity_enode") 233 | return 234 | } 235 | 236 | // Get the current chain status. 237 | func (c *RpcParityClient) ChainStatus() (val types.ChainStatus, err error) { 238 | err = c.CallContext(c.getContext(), &val, "parity_chainStatus") 239 | return 240 | } 241 | 242 | // Get node kind info. 243 | func (c *RpcParityClient) NodeKind() (val types.NodeKind, err error) { 244 | err = c.CallContext(c.getContext(), &val, "parity_nodeKind") 245 | return 246 | } 247 | 248 | // Get block header. 249 | // Same as `eth_getBlockByNumber` but without uncles and transactions. 250 | func (c *RpcParityClient) BlockHeader(blockNum *types.BlockNumberOrHash) (val types.RichHeader, err error) { 251 | err = c.CallContext(c.getContext(), &val, "parity_getBlockHeaderByNumber", getRealBlockNumberOrHash(blockNum)) 252 | return 253 | } 254 | 255 | // Get block receipts. 256 | // Allows you to fetch receipts from the entire block at once. 257 | // If no parameter is provided defaults to `latest`. 258 | func (c *RpcParityClient) BlockReceipts(blockNum *types.BlockNumberOrHash) (val []types.Receipt, err error) { 259 | err = c.CallContext(c.getContext(), &val, "parity_getBlockReceipts", getRealBlockNumberOrHash(blockNum)) 260 | return 261 | } 262 | 263 | // Call contract, returning the output data. 264 | func (c *RpcParityClient) Call(requests []types.CallRequest, blockNum *types.BlockNumberOrHash) (val [][]byte, err error) { 265 | var _val []hexutil.Bytes 266 | err = c.CallContext(c.getContext(), &_val, "parity_call", requests, getRealBlockNumberOrHash(blockNum)) 267 | 268 | for _, _valItem := range _val { 269 | val = append(val, []byte(_valItem)) 270 | } 271 | return 272 | } 273 | 274 | // Used for submitting a proof-of-work solution (similar to `eth_submitWork`, 275 | // but returns block hash on success, and returns an explicit error message on failure). 276 | // FIXME: nonce should be H64 hash 277 | func (c *RpcParityClient) SubmitWorkDetail(nonce string, powHash common.Hash, mixHash common.Hash) (val common.Hash, err error) { 278 | err = c.CallContext(c.getContext(), &val, "parity_submitWorkDetail", nonce, powHash, mixHash) 279 | return 280 | } 281 | 282 | // Returns the status of the node. Used as the health endpoint. 283 | // 284 | // The RPC returns successful response if: 285 | // - The node have a peer (unless running a dev chain) 286 | // - The node is not syncing. 287 | // 288 | // Otherwise the RPC returns error. 289 | func (c *RpcParityClient) Status() (err error) { 290 | err = c.CallContext(c.getContext(), &[]interface{}{}, "parity_nodeStatus") 291 | return 292 | } 293 | 294 | // Extracts Address and public key from signature using the r, s and v params. Equivalent to Solidity erecover 295 | // as well as checks the signature for chain replay protection 296 | func (c *RpcParityClient) VerifySignature(isPrefixed bool, message []byte, r common.Hash, s common.Hash, v uint64) (val types.RecoveredAccount, err error) { 297 | _message := (hexutil.Bytes)(message) 298 | _v := (hexutil.Uint64)(v) 299 | err = c.CallContext(c.getContext(), &val, "parity_verifySignature", isPrefixed, _message, r, s, _v) 300 | return 301 | } 302 | -------------------------------------------------------------------------------- /client/client_trace.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "github.com/ethereum/go-ethereum/common" 5 | "github.com/ethereum/go-ethereum/common/hexutil" 6 | 7 | "github.com/openweb3/go-rpc-provider/interfaces" 8 | providers "github.com/openweb3/go-rpc-provider/provider_wrapper" 9 | "github.com/openweb3/web3go/types" 10 | ) 11 | 12 | type RpcTraceClient struct { 13 | BaseClient 14 | } 15 | 16 | func NewRpcTraceClient(provider interfaces.Provider) *RpcTraceClient { 17 | _client := &RpcTraceClient{} 18 | _client.MiddlewarableProvider = providers.NewMiddlewarableProvider(provider) 19 | return _client 20 | } 21 | 22 | // Returns traces matching given filter. 23 | func (c *RpcTraceClient) Filter(traceFilter types.TraceFilter) (val []types.LocalizedTrace, err error) { 24 | err = c.CallContext(c.getContext(), &val, "trace_filter", traceFilter) 25 | return 26 | } 27 | 28 | // Returns transaction trace at given index. 29 | func (c *RpcTraceClient) Trace(transactionHash common.Hash, indexes []uint) (val *types.LocalizedTrace, err error) { 30 | err = c.CallContext(c.getContext(), &val, "trace_get", transactionHash, indexes) 31 | return 32 | } 33 | 34 | // Returns all traces of given transaction. 35 | func (c *RpcTraceClient) Transactions(transactionHash common.Hash) (val []types.LocalizedTrace, err error) { 36 | err = c.CallContext(c.getContext(), &val, "trace_transaction", transactionHash) 37 | return 38 | } 39 | 40 | // Returns all traces produced at given block. 41 | func (c *RpcTraceClient) Blocks(blockNumber types.BlockNumberOrHash) (val []types.LocalizedTrace, err error) { 42 | err = c.CallContext(c.getContext(), &val, "trace_block", blockNumber) 43 | return 44 | } 45 | 46 | // Executes the given call and returns a number of possible traces for it. 47 | func (c *RpcTraceClient) Call(request types.CallRequest, options types.TraceOptions, blockNumber *types.BlockNumberOrHash) (val types.TraceResults, err error) { 48 | err = c.CallContext(c.getContext(), &val, "trace_call", request, options, getRealBlockNumberOrHash(blockNumber)) 49 | return 50 | } 51 | 52 | // Executes the given raw transaction and returns a number of possible traces for it. 53 | func (c *RpcTraceClient) RawTransaction(rawTransaction []byte, options types.TraceOptions, blockNumber *types.BlockNumberOrHash) (val types.TraceResults, err error) { 54 | _rawTransaction := (hexutil.Bytes)(rawTransaction) 55 | err = c.CallContext(c.getContext(), &val, "trace_rawTransaction", _rawTransaction, options, getRealBlockNumberOrHash(blockNumber)) 56 | return 57 | } 58 | 59 | // Executes the transaction with the given hash and returns a number of possible traces for it. 60 | func (c *RpcTraceClient) ReplayTransaction(transactionHash common.Hash, options types.TraceOptions) (val types.TraceResults, err error) { 61 | err = c.CallContext(c.getContext(), &val, "trace_replayTransaction", transactionHash, options) 62 | return 63 | } 64 | 65 | // Executes all the transactions at the given block and returns a number of possible traces for each transaction. 66 | func (c *RpcTraceClient) ReplayBlockTransactions(blockNumber types.BlockNumberOrHash, options types.TraceOptions) (val []types.TraceResultsWithTransactionHash, err error) { 67 | err = c.CallContext(c.getContext(), &val, "trace_replayBlockTransactions", blockNumber, options) 68 | return 69 | } 70 | -------------------------------------------------------------------------------- /client/utils.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | rpc "github.com/openweb3/go-rpc-provider" 5 | "github.com/openweb3/web3go/types" 6 | ) 7 | 8 | func getRealBlockNumberOrHash(input *types.BlockNumberOrHash) *types.BlockNumberOrHash { 9 | if input == nil { 10 | tmp := types.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) 11 | return &tmp 12 | } 13 | return input 14 | } 15 | -------------------------------------------------------------------------------- /client_abigen.go: -------------------------------------------------------------------------------- 1 | package web3go 2 | 3 | import ( 4 | "context" 5 | "errors" 6 | "math/big" 7 | 8 | "github.com/ethereum/go-ethereum" 9 | "github.com/ethereum/go-ethereum/common" 10 | ethtypes "github.com/ethereum/go-ethereum/core/types" 11 | "github.com/openweb3/web3go/types" 12 | ) 13 | 14 | // ClientForContract is used for abi-binding struct generated by abigen. 15 | // abigen is a source code generator to convert Ethereum contract definitions into easy to use, compile-time type-safe Go packages. 16 | // Please see https://geth.ethereum.org/docs/dapp/native-bindings page for details 17 | type ClientForContract struct { 18 | raw *Client 19 | } 20 | 21 | func NewClientForContract(raw *Client) *ClientForContract { 22 | return &ClientForContract{ 23 | raw: raw, 24 | } 25 | } 26 | 27 | func (c *ClientForContract) TransactionReceipt(ctx context.Context, txHash common.Hash) (*ethtypes.Receipt, error) { 28 | r, err := c.raw.Eth.TransactionReceipt(txHash) 29 | if err != nil { 30 | return nil, err 31 | } 32 | ethReceipt := toEthReceipt(*r) 33 | return ðReceipt, nil 34 | } 35 | 36 | func (c *ClientForContract) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) { 37 | bnOrHash := types.BlockNumberOrHashWithNumber(getBlockNumberIfy(blockNumber)) 38 | return c.raw.Eth.CodeAt(account, &bnOrHash) 39 | } 40 | 41 | func (c *ClientForContract) CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) { 42 | cr := convertCallMsg2CallRequest(call) 43 | bn := types.BlockNumberOrHashWithNumber(getBlockNumberIfy(blockNumber)) 44 | return c.raw.Eth.Call(cr, &bn) 45 | } 46 | 47 | // PendingCallContract executes an Ethereum contract call against the pending state. 48 | func (c *ClientForContract) PendingCallContract(ctx context.Context, call ethereum.CallMsg) ([]byte, error) { 49 | cr := convertCallMsg2CallRequest(call) 50 | pending := types.BlockNumberOrHashWithNumber(types.PendingBlockNumber) 51 | return c.raw.Eth.Call(cr, &pending) 52 | } 53 | 54 | // HeaderByNumber returns a block header from the current canonical chain. If 55 | // number is nil, the latest known header is returned. 56 | func (c *ClientForContract) HeaderByNumber(ctx context.Context, number *big.Int) (*ethtypes.Header, error) { 57 | b, err := c.raw.Eth.BlockByNumber(getBlockNumberIfy(number), false) 58 | if err != nil { 59 | return nil, err 60 | } 61 | h, err := b.Header() 62 | if err != nil { 63 | return nil, err 64 | } 65 | return &h.Header, nil 66 | } 67 | 68 | // PendingCodeAt returns the code of the given account in the pending state. 69 | func (c *ClientForContract) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) { 70 | pending := types.BlockNumberOrHashWithNumber(types.PendingBlockNumber) 71 | return c.raw.Eth.CodeAt(account, &pending) 72 | } 73 | 74 | // PendingNonceAt retrieves the current pending nonce associated with an account. 75 | func (c *ClientForContract) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) { 76 | pending := types.BlockNumberOrHashWithNumber(types.PendingBlockNumber) 77 | nonce, err := c.raw.Eth.TransactionCount(account, &pending) 78 | if err != nil { 79 | return 0, err 80 | } 81 | return nonce.Uint64(), nil 82 | } 83 | 84 | // SuggestGasPrice retrieves the currently suggested gas price to allow a timely 85 | // execution of a transaction. 86 | func (c *ClientForContract) SuggestGasPrice(ctx context.Context) (*big.Int, error) { 87 | return c.raw.Eth.GasPrice() 88 | } 89 | 90 | // SuggestGasTipCap retrieves the currently suggested 1559 priority fee to allow 91 | // a timely execution of a transaction. 92 | func (c *ClientForContract) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { 93 | return c.raw.Eth.MaxPriorityFeePerGas() 94 | } 95 | 96 | // EstimateGas tries to estimate the gas needed to execute a specific 97 | // transaction based on the current pending state of the backend blockchain. 98 | // There is no guarantee that this is the true gas limit requirement as other 99 | // transactions may be added or removed by miners, but it should provide a basis 100 | // for setting a reasonable default. 101 | func (c *ClientForContract) EstimateGas(ctx context.Context, call ethereum.CallMsg) (gas uint64, err error) { 102 | cr := convertCallMsg2CallRequest(call) 103 | 104 | pending := types.BlockNumberOrHashWithNumber(types.PendingBlockNumber) 105 | val, err := c.raw.Eth.EstimateGas(cr, &pending) 106 | if err != nil { 107 | return 0, err 108 | } 109 | return val.Uint64(), nil 110 | } 111 | 112 | // SendTransaction injects the transaction into the pending pool for execution. 113 | func (c *ClientForContract) SendTransaction(ctx context.Context, tx *types.Transaction) error { 114 | // if not signed, sign it by first account 115 | if v, _, _ := tx.RawSignatureValues(); v == nil { 116 | sm, err := c.raw.GetSignerManager() 117 | if err != nil { 118 | return err 119 | } 120 | 121 | if len(sm.List()) == 0 { 122 | return errors.New("no signer available") 123 | } 124 | 125 | account := sm.List()[0].Address() 126 | _, err = c.raw.Eth.SendTransaction(account, *tx) 127 | return err 128 | } 129 | 130 | // otherwise, send raw transaction 131 | rawTx, err := tx.MarshalBinary() 132 | if err != nil { 133 | return err 134 | } 135 | 136 | _, err = c.raw.Eth.SendRawTransaction(rawTx) 137 | return err 138 | } 139 | 140 | // FilterLogs executes a log filter operation, blocking during execution and 141 | // returning all the results in one batch. 142 | // 143 | // TODO(karalabe): Deprecate when the subscription one can return past data too. 144 | func (c *ClientForContract) FilterLogs(ctx context.Context, query ethereum.FilterQuery) ([]ethtypes.Log, error) { 145 | q := convertFilterQuery(query) 146 | logs, err := c.raw.Eth.Logs(q) 147 | if err != nil { 148 | return nil, err 149 | } 150 | return toEthLogs(logs), nil 151 | } 152 | 153 | // SubscribeFilterLogs creates a background log filtering operation, returning 154 | // a subscription immediately, which can be used to stream the found events. 155 | func (c *ClientForContract) SubscribeFilterLogs(ctx context.Context, query ethereum.FilterQuery, ch chan<- ethtypes.Log) (ethereum.Subscription, error) { 156 | q := convertFilterQuery(query) 157 | return c.raw.Subscribe(context.Background(), "eth", ch, "logs", q) 158 | } 159 | 160 | // getBlockNumberIfy returns latest block number if input nil 161 | func getBlockNumberIfy(blockNumber *big.Int) types.BlockNumber { 162 | result := types.LatestBlockNumber 163 | if blockNumber != nil { 164 | result = types.NewBlockNumber(blockNumber.Int64()) 165 | } 166 | return result 167 | } 168 | 169 | func convertFilterQuery(query ethereum.FilterQuery) types.FilterQuery { 170 | fromBlock := types.NewBlockNumber(query.FromBlock.Int64()) 171 | toBlock := types.NewBlockNumber(query.ToBlock.Int64()) 172 | return types.FilterQuery{ 173 | BlockHash: query.BlockHash, 174 | FromBlock: &fromBlock, 175 | ToBlock: &toBlock, 176 | Addresses: query.Addresses, 177 | Topics: query.Topics, 178 | } 179 | } 180 | 181 | func convertCallMsg2CallRequest(call ethereum.CallMsg) types.CallRequest { 182 | cr := types.CallRequest{ 183 | To: call.To, 184 | GasPrice: call.GasPrice, 185 | MaxFeePerGas: call.GasFeeCap, 186 | MaxPriorityFeePerGas: call.GasTipCap, 187 | Value: call.Value, 188 | Data: call.Data, 189 | } 190 | 191 | if call.From != (common.Address{}) { 192 | cr.From = &call.From 193 | } 194 | 195 | if call.Gas != 0 { 196 | cr.Gas = &call.Gas 197 | } 198 | 199 | if call.AccessList != nil { 200 | cr.AccessList = &call.AccessList 201 | } 202 | 203 | return cr 204 | } 205 | 206 | func toEthReceipt(r types.Receipt) ethtypes.Receipt { 207 | eReceipt := ethtypes.Receipt{ 208 | PostState: r.Root, 209 | CumulativeGasUsed: r.CumulativeGasUsed, 210 | Bloom: r.LogsBloom, 211 | Logs: toEthLogPtrs(r.Logs), 212 | TxHash: r.TransactionHash, 213 | GasUsed: r.GasUsed, 214 | BlockHash: r.BlockHash, 215 | BlockNumber: new(big.Int).SetUint64(r.BlockNumber), 216 | TransactionIndex: uint(r.TransactionIndex), 217 | } 218 | if r.Type != nil { 219 | eReceipt.Type = uint8(*r.Type) 220 | } 221 | 222 | if r.Status != nil { 223 | eReceipt.Status = *r.Status 224 | } 225 | 226 | if r.ContractAddress != nil { 227 | eReceipt.ContractAddress = *r.ContractAddress 228 | } 229 | return eReceipt 230 | } 231 | 232 | func toEthLogs(logs []types.Log) []ethtypes.Log { 233 | eLogs := make([]ethtypes.Log, len(logs)) 234 | for i, l := range logs { 235 | eLogs[i] = *l.ToEthLog() 236 | } 237 | return eLogs 238 | } 239 | 240 | func toEthLogPtrs(logs []*types.Log) []*ethtypes.Log { 241 | eLogs := make([]*ethtypes.Log, len(logs)) 242 | for i, l := range logs { 243 | if l == nil { 244 | eLogs[i] = nil 245 | continue 246 | } 247 | eLogs[i] = l.ToEthLog() 248 | } 249 | return eLogs 250 | } 251 | -------------------------------------------------------------------------------- /client_abigen_test.go: -------------------------------------------------------------------------------- 1 | package web3go 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/ethereum/go-ethereum/accounts/abi/bind" 7 | ) 8 | 9 | func TestClientForContractImplementInterfaces(t *testing.T) { 10 | var _ bind.ContractBackend = &ClientForContract{} 11 | var _ bind.DeployBackend = &ClientForContract{} 12 | } 13 | -------------------------------------------------------------------------------- /client_option.go: -------------------------------------------------------------------------------- 1 | package web3go 2 | 3 | import ( 4 | "io" 5 | "time" 6 | 7 | "github.com/mcuadros/go-defaults" 8 | providers "github.com/openweb3/go-rpc-provider/provider_wrapper" 9 | "github.com/openweb3/web3go/signers" 10 | ) 11 | 12 | type ClientOption struct { 13 | providers.Option 14 | SignerManager *signers.SignerManager 15 | } 16 | 17 | func (c *ClientOption) setDefault() *ClientOption { 18 | defaults.SetDefaults(&c.Option) 19 | return c 20 | } 21 | 22 | func (c *ClientOption) WithRetry(retryCount int, retryInterval time.Duration) *ClientOption { 23 | c.Option.WithRetry(retryCount, retryInterval) 24 | return c 25 | } 26 | 27 | func (c *ClientOption) WithTimout(requestTimeout time.Duration) *ClientOption { 28 | c.Option.WithTimout(requestTimeout) 29 | return c 30 | } 31 | 32 | func (c *ClientOption) WithMaxConnectionPerHost(maxConnectionPerHost int) *ClientOption { 33 | c.Option.WithMaxConnectionPerHost(maxConnectionPerHost) 34 | return c 35 | } 36 | 37 | func (c *ClientOption) WithLooger(w io.Writer) *ClientOption { 38 | c.Option.WithLooger(w) 39 | return c 40 | } 41 | 42 | func (c *ClientOption) WithSignerManager(signerManager *signers.SignerManager) *ClientOption { 43 | c.SignerManager = signerManager 44 | return c 45 | } 46 | -------------------------------------------------------------------------------- /client_test.go: -------------------------------------------------------------------------------- 1 | package web3go 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "fmt" 7 | "os" 8 | "testing" 9 | 10 | pproviders "github.com/openweb3/go-rpc-provider/provider_wrapper" 11 | "github.com/openweb3/web3go/signers" 12 | "github.com/openweb3/web3go/types" 13 | "github.com/stretchr/testify/assert" 14 | ) 15 | 16 | func TestClient(t *testing.T) { 17 | client, err := NewClient("https://sepolia.infura.io/v3/d91582da330a4812be53d698a34741aa") 18 | if err != nil { 19 | t.Fatal(err) 20 | } 21 | 22 | p := client.Provider() 23 | mp := pproviders.NewMiddlewarableProvider(p) 24 | mp.HookCallContext(callcontextLogMiddleware) 25 | client.SetProvider(mp) 26 | 27 | _, err = client.Eth.ClientVersion() 28 | if err != nil { 29 | t.Fatal(err) 30 | } 31 | } 32 | 33 | func callcontextLogMiddleware(f pproviders.CallContextFunc) pproviders.CallContextFunc { 34 | return func(ctx context.Context, resultPtr interface{}, method string, args ...interface{}) error { 35 | fmt.Printf("request %v %v\n", method, args) 36 | err := f(ctx, resultPtr, method, args...) 37 | j, _ := json.Marshal(resultPtr) 38 | fmt.Printf("response %s\n", j) 39 | return err 40 | } 41 | } 42 | 43 | func TestSendTxByArgsUseClientWithOption(t *testing.T) { 44 | mnemonic := "crisp shove million stem shiver side hospital split play lottery join vintage" 45 | sm := signers.MustNewSignerManagerByMnemonic(mnemonic, 10, nil) 46 | c, err := NewClientWithOption("https://sepolia.infura.io/v3/d91582da330a4812be53d698a34741aa", *(new(ClientOption).WithLooger(os.Stdout).WithSignerManager(sm))) 47 | assert.NoError(t, err) 48 | 49 | from := sm.List()[0].Address() 50 | to := sm.List()[1].Address() 51 | hash, err := c.Eth.SendTransactionByArgs(types.TransactionArgs{ 52 | From: &from, 53 | To: &to, 54 | }) 55 | assert.NoError(t, err) 56 | fmt.Printf("hash: %s\n", hash) 57 | } 58 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/openweb3/web3go 2 | 3 | go 1.23.0 4 | 5 | toolchain go1.23.10 6 | 7 | require ( 8 | github.com/ethereum/go-ethereum v1.15.11 9 | github.com/holiman/uint256 v1.3.2 10 | github.com/mcuadros/go-defaults v1.2.0 11 | github.com/openweb3/go-rpc-provider v0.3.5 12 | github.com/openweb3/go-sdk-common v0.0.0-20240627072707-f78f0155ab34 13 | github.com/pkg/errors v0.9.1 14 | github.com/stretchr/testify v1.10.0 15 | ) 16 | 17 | require ( 18 | github.com/Microsoft/go-winio v0.6.2 // indirect 19 | github.com/StackExchange/wmi v1.2.1 // indirect 20 | github.com/VictoriaMetrics/fastcache v1.12.2 // indirect 21 | github.com/andybalholm/brotli v1.0.5 // indirect 22 | github.com/bits-and-blooms/bitset v1.20.0 // indirect 23 | github.com/btcsuite/btcd v0.24.0 // indirect 24 | github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect 25 | github.com/btcsuite/btcd/btcutil v1.1.5 // indirect 26 | github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect 27 | github.com/cespare/xxhash/v2 v2.3.0 // indirect 28 | github.com/consensys/bavard v0.1.27 // indirect 29 | github.com/consensys/gnark-crypto v0.16.0 // indirect 30 | github.com/crate-crypto/go-eth-kzg v1.3.0 // indirect 31 | github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a // indirect 32 | github.com/davecgh/go-spew v1.1.1 // indirect 33 | github.com/deckarep/golang-set v1.8.0 // indirect 34 | github.com/deckarep/golang-set/v2 v2.6.0 // indirect 35 | github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect 36 | github.com/ethereum/c-kzg-4844/v2 v2.1.0 // indirect 37 | github.com/ethereum/go-verkle v0.2.2 // indirect 38 | github.com/fatih/color v1.16.0 // indirect 39 | github.com/fsnotify/fsnotify v1.6.0 // indirect 40 | github.com/go-ole/go-ole v1.3.0 // indirect 41 | github.com/gofrs/flock v0.8.1 // indirect 42 | github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect 43 | github.com/google/go-cmp v0.5.9 // indirect 44 | github.com/google/uuid v1.3.0 // indirect 45 | github.com/gorilla/websocket v1.5.0 // indirect 46 | github.com/holiman/bloomfilter/v2 v2.0.3 // indirect 47 | github.com/huin/goupnp v1.3.0 // indirect 48 | github.com/jackpal/go-nat-pmp v1.0.2 // indirect 49 | github.com/klauspost/compress v1.16.0 // indirect 50 | github.com/mattn/go-colorable v0.1.13 // indirect 51 | github.com/mattn/go-isatty v0.0.20 // indirect 52 | github.com/mattn/go-runewidth v0.0.13 // indirect 53 | github.com/mmcloughlin/addchain v0.4.0 // indirect 54 | github.com/olekukonko/tablewriter v0.0.5 // indirect 55 | github.com/onsi/ginkgo v1.16.5 // indirect 56 | github.com/onsi/gomega v1.18.1 // indirect 57 | github.com/openweb3/go-ethereum-hdwallet v0.1.0 // indirect 58 | github.com/pion/dtls/v2 v2.2.7 // indirect 59 | github.com/pion/logging v0.2.2 // indirect 60 | github.com/pion/stun/v2 v2.0.0 // indirect 61 | github.com/pion/transport/v2 v2.2.1 // indirect 62 | github.com/pion/transport/v3 v3.0.1 // indirect 63 | github.com/pmezard/go-difflib v1.0.0 // indirect 64 | github.com/rivo/uniseg v0.2.0 // indirect 65 | github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect 66 | github.com/supranational/blst v0.3.14 // indirect 67 | github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect 68 | github.com/tklauser/go-sysconf v0.3.12 // indirect 69 | github.com/tklauser/numcpus v0.6.1 // indirect 70 | github.com/tyler-smith/go-bip39 v1.1.0 // indirect 71 | github.com/valyala/bytebufferpool v1.0.0 // indirect 72 | github.com/valyala/fasthttp v1.40.0 // indirect 73 | golang.org/x/crypto v0.35.0 // indirect 74 | golang.org/x/sync v0.11.0 // indirect 75 | golang.org/x/sys v0.30.0 // indirect 76 | gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect 77 | gopkg.in/yaml.v3 v3.0.1 // indirect 78 | gotest.tools v2.2.0+incompatible // indirect 79 | rsc.io/tmplfunc v0.0.3 // indirect 80 | ) 81 | 82 | // replace github.com/openweb3/go-sdk-common => ../go-sdk-common 83 | // replace github.com/openweb3/go-rpc-provider v0.2.2 => ../go-rpc-provider 84 | // replace github.com/openweb3/go-sdk-common v0.0.0 => ../go-sdk-common 85 | -------------------------------------------------------------------------------- /integration_test/client_debug_test_.go: -------------------------------------------------------------------------------- 1 | package integrationtest 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "fmt" 7 | "os" 8 | "testing" 9 | 10 | "github.com/ethereum/go-ethereum/common" 11 | pproviders "github.com/openweb3/go-rpc-provider/provider_wrapper" 12 | "github.com/openweb3/web3go/client" 13 | "github.com/openweb3/web3go/types" 14 | "github.com/stretchr/testify/assert" 15 | ) 16 | 17 | func TestTraceTransaction(t *testing.T) { 18 | provider := pproviders.MustNewBaseProvider(context.Background(), "https://evmtestnet-internal.confluxrpc.com") 19 | provider = pproviders.NewLoggerProvider(provider, os.Stdout) 20 | 21 | c := client.NewRpcDebugClient(provider) 22 | val, err := c.TraceTransaction(common.HexToHash("0x6b9a69106704eec878731c00b251c3a67e1fbb561bda279e92ee3f6071da6500")) 23 | assert.NoError(t, err) 24 | 25 | fmt.Printf("val %v\n", val) 26 | 27 | for _, tracer := range []string{ 28 | "4byteTracer", 29 | "callTracer", 30 | "prestateTracer", 31 | "noopTracer", 32 | "muxTracer", 33 | } { 34 | 35 | onlyTopCall := true 36 | val, err := c.TraceTransaction(common.HexToHash("0x6b9a69106704eec878731c00b251c3a67e1fbb561bda279e92ee3f6071da6500"), &types.GethDebugTracingOptions{ 37 | Tracer: tracer, 38 | TracerConfig: &types.GethDebugTracerConfig{CallConfig: &types.CallConfig{OnlyTopCall: &onlyTopCall}}, 39 | }) 40 | assert.NoError(t, err) 41 | 42 | j, _ := json.Marshal(val) 43 | fmt.Printf("val %s\n", j) 44 | } 45 | } 46 | 47 | func TestTraceBlockByHash(t *testing.T) { 48 | provider := pproviders.MustNewBaseProvider(context.Background(), "https://evmtestnet-internal.confluxrpc.com") 49 | provider = pproviders.NewLoggerProvider(provider, os.Stdout) 50 | 51 | c := client.NewRpcDebugClient(provider) 52 | 53 | val, err := c.TraceBlockByHash(common.HexToHash("0x92346af4d942871946186ef86c7136ffa45abf1424a605df2723a9ed5694d1f8")) 54 | assert.NoError(t, err) 55 | 56 | j, err := json.Marshal(val) 57 | assert.NoError(t, err) 58 | fmt.Printf("val %s\n", j) 59 | } 60 | 61 | func TestTraceBlockByNumber(t *testing.T) { 62 | provider := pproviders.MustNewBaseProvider(context.Background(), "https://evmtestnet-internal.confluxrpc.com") 63 | provider = pproviders.NewLoggerProvider(provider, os.Stdout) 64 | 65 | c := client.NewRpcDebugClient(provider) 66 | 67 | val, err := c.TraceBlockByNumber(types.NewBlockNumber(179904465)) 68 | assert.NoError(t, err) 69 | 70 | j, err := json.Marshal(val) 71 | assert.NoError(t, err) 72 | fmt.Printf("val %s\n", j) 73 | } 74 | 75 | func TestTraceCall(t *testing.T) { 76 | provider := pproviders.MustNewBaseProvider(context.Background(), "https://evmtestnet-internal.confluxrpc.com") 77 | provider = pproviders.NewLoggerProvider(provider, os.Stdout) 78 | 79 | c := client.NewRpcDebugClient(provider) 80 | 81 | blkNum := types.NewBlockNumber(179904465) 82 | to := common.HexToAddress("0x807da62384be660ded0319d613d8b37cf3892d20") 83 | val, err := c.TraceCall(types.CallRequest{ 84 | To: &to, 85 | }, &blkNum) 86 | assert.NoError(t, err) 87 | 88 | j, err := json.Marshal(val) 89 | assert.NoError(t, err) 90 | fmt.Printf("val %s\n", j) 91 | } 92 | -------------------------------------------------------------------------------- /integration_test/client_eth_test.go: -------------------------------------------------------------------------------- 1 | package integrationtest 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "fmt" 7 | "math/big" 8 | "testing" 9 | 10 | "github.com/ethereum/go-ethereum/common/hexutil" 11 | ethrpctypes "github.com/ethereum/go-ethereum/rpc" 12 | providers "github.com/openweb3/go-rpc-provider/provider_wrapper" 13 | "github.com/openweb3/go-sdk-common/rpctest" 14 | "github.com/openweb3/web3go/client" 15 | ) 16 | 17 | func int2Hexbig(val interface{}) (converted interface{}) { 18 | return (*hexutil.Big)(val.(*big.Int)) 19 | } 20 | 21 | func hexBig2Int(val interface{}) (converted interface{}) { 22 | return (*big.Int)(val.(*hexutil.Big)) 23 | } 24 | 25 | func u64ToHexU64(val interface{}) (converted interface{}) { 26 | return (*hexutil.Uint64)(val.(*uint64)) 27 | } 28 | 29 | func bytes2HexBytes(val interface{}) (converted interface{}) { 30 | return (hexutil.Bytes)(val.([]byte)) 31 | } 32 | 33 | func getEthTestConfig() rpctest.RpcTestConfig { 34 | 35 | var rpc2Func map[string]string = map[string]string{ 36 | "web3_clientVersion": "ClientVersion", 37 | "net_version": "NetVersion", 38 | "eth_protocolVersion": "ProtocolVersion", 39 | "eth_syncing": "Syncing", 40 | "eth_hashrate": "Hashrate", 41 | "eth_coinbase": "Author", 42 | "eth_mining": "IsMining", 43 | "eth_chainId": "ChainId", 44 | "eth_gasPrice": "GasPrice", 45 | "eth_maxPriorityFeePerGas": "MaxPriorityFeePerGas", 46 | "eth_feeHistory": "FeeHistory", 47 | "eth_accounts": "Accounts", 48 | "eth_blockNumber": "BlockNumber", 49 | "eth_getBalance": "Balance", 50 | "eth_getStorageAt": "StorageAt", 51 | "eth_getBlockByHash": "BlockByHash", 52 | "eth_getBlockByNumber": "BlockByNumber", 53 | "eth_getTransactionCount": "TransactionCount", 54 | "eth_getBlockTransactionCountByHash": "BlockTransactionCountByHash", 55 | "eth_getBlockTransactionCountByNumber": "BlockTransactionCountByNumber", 56 | "eth_getUncleCountByBlockHash": "BlockUnclesCountByHash", 57 | "eth_getUncleCountByBlockNumber": "BlockUnclesCountByNumber", 58 | "eth_getCode": "CodeAt", 59 | "eth_sendRawTransaction": "SendRawTransaction", 60 | "eth_submitTransaction": "SubmitTransaction", 61 | "eth_call": "Call", 62 | "eth_estimateGas": "EstimateGas", 63 | "eth_getTransactionByHash": "TransactionByHash", 64 | "eth_getTransactionByBlockHashAndIndex": "TransactionByBlockHashAndIndex", 65 | "eth_getTransactionByBlockNumberAndIndex": "TransactionByBlockNumberAndIndex", 66 | "eth_getTransactionReceipt": "TransactionReceipt", 67 | "eth_getUncleByBlockHashAndIndex": "UncleByBlockHashAndIndex", 68 | "eth_getUncleByBlockNumberAndIndex": "UncleByBlockNumberAndIndex", 69 | "eth_getLogs": "Logs", 70 | "eth_submitHashrate": "SubmitHashrate", 71 | } 72 | 73 | rpc2FuncSelector := map[string]func(params []interface{}) (realFuncName string, realParams []interface{}){ 74 | "eth_getBalance": func(params []interface{}) (realFuncName string, realParams []interface{}) { 75 | if len(params) == 1 { 76 | return "Balance", append(params, ethrpctypes.LatestBlockNumber) 77 | } 78 | return "Balance", params 79 | }, 80 | "eth_getStorageAt": func(params []interface{}) (realFuncName string, realParams []interface{}) { 81 | params[1] = hexutil.MustDecodeBig(params[1].(string)) 82 | if len(params) == 2 { 83 | return "StorageAt", append(params, ethrpctypes.LatestBlockNumber) 84 | } 85 | return "StorageAt", params 86 | }, 87 | "eth_getTransactionCount": func(params []interface{}) (realFuncName string, realParams []interface{}) { 88 | if len(params) == 1 { 89 | return "TransactionCount", append(params, ethrpctypes.LatestBlockNumber) 90 | } 91 | return "TransactionCount", params 92 | }, 93 | "eth_getCode": func(params []interface{}) (realFuncName string, realParams []interface{}) { 94 | if len(params) == 1 { 95 | return "CodeAt", append(params, ethrpctypes.LatestBlockNumber) 96 | } 97 | return "CodeAt", params 98 | }, 99 | "eth_call": func(params []interface{}) (realFuncName string, realParams []interface{}) { 100 | if len(params) == 1 { 101 | return "Call", append(params, ethrpctypes.LatestBlockNumber) 102 | } 103 | return "Call", params 104 | }, 105 | "eth_estimateGas": func(params []interface{}) (realFuncName string, realParams []interface{}) { 106 | if len(params) == 1 { 107 | return "EstimateGas", append(params, ethrpctypes.LatestBlockNumber) 108 | } 109 | return "EstimateGas", params 110 | }, 111 | "eth_feeHistory": func(params []interface{}) (realFuncName string, realParams []interface{}) { 112 | params[0], _ = hexutil.DecodeUint64(params[0].(string)) 113 | return "FeeHistory", params 114 | }, 115 | } 116 | 117 | rpc2FuncResultHandler := map[string]func(result interface{}) (handlerdResult interface{}){ 118 | "eth_hashrate": int2Hexbig, 119 | "eth_chainId": u64ToHexU64, 120 | "eth_gasPrice": int2Hexbig, 121 | "eth_maxPriorityFeePerGas": int2Hexbig, 122 | "eth_blockNumber": int2Hexbig, 123 | "eth_getBalance": int2Hexbig, 124 | "eth_getTransactionCount": int2Hexbig, 125 | "eth_getBlockTransactionCountByHash": int2Hexbig, 126 | "eth_getBlockTransactionCountByNumber": int2Hexbig, 127 | "eth_getUncleCountByBlockHash": int2Hexbig, 128 | "eth_getUncleCountByBlockNumber": int2Hexbig, 129 | "eth_getCode": bytes2HexBytes, 130 | "eth_call": bytes2HexBytes, 131 | "eth_estimateGas": int2Hexbig, 132 | } 133 | 134 | ignoreRpc := map[string]bool{} 135 | onlyTestRpc := map[string]bool{} 136 | ignoreExamples := map[string]bool{ 137 | "eth_getCode-0x1e6309dc46a2a4936abda54b69c91d7a3c75a39e": true, 138 | "eth_getStorageAt-0x1e6309dc46a2a4936abda54b69c91d7a3c75a39e,0x100": true, 139 | "eth_getLogs-1649755528773": true, 140 | } 141 | onlyExamples := map[string]bool{} 142 | 143 | provider, _ := providers.NewBaseProvider(context.Background(), "http://39.100.93.109/eth/") 144 | middled := providers.NewMiddlewarableProvider(provider) 145 | middled.HookCallContext(callcontextFuncLogMiddle) 146 | provider = middled 147 | 148 | return rpctest.RpcTestConfig{ 149 | ExamplesUrl: "https://raw.githubusercontent.com/Conflux-Chain/jsonrpc-spec/main/src/eth/examples.json", 150 | Client: client.NewRpcEthClient(provider), 151 | 152 | Rpc2Func: rpc2Func, 153 | Rpc2FuncSelector: rpc2FuncSelector, 154 | Rpc2FuncResultHandler: rpc2FuncResultHandler, 155 | IgnoreRpcs: ignoreRpc, 156 | IgnoreExamples: ignoreExamples, 157 | OnlyTestRpcs: onlyTestRpc, 158 | OnlyExamples: onlyExamples, 159 | } 160 | 161 | } 162 | 163 | func callcontextFuncLogMiddle(f providers.CallContextFunc) providers.CallContextFunc { 164 | return func(ctx context.Context, resultPtr interface{}, method string, args ...interface{}) error { 165 | jArgs, _ := json.Marshal(args) 166 | fmt.Printf("\n-- rpc call %v %s--\n", method, jArgs) 167 | err := f(ctx, resultPtr, method, args...) 168 | j, _ := json.Marshal(resultPtr) 169 | fmt.Printf("\trpc response %s\n", j) 170 | fmt.Printf("\trpc error %v\n", err) 171 | return err 172 | } 173 | } 174 | 175 | func TestClientEth(t *testing.T) { 176 | config := getEthTestConfig() 177 | rpctest.DoClientTest(t, config) 178 | } 179 | -------------------------------------------------------------------------------- /integration_test/client_filter_test.go: -------------------------------------------------------------------------------- 1 | package integrationtest 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "testing" 7 | "time" 8 | 9 | "github.com/ethereum/go-ethereum/common" 10 | providers "github.com/openweb3/go-rpc-provider/provider_wrapper" 11 | "github.com/openweb3/web3go" 12 | "github.com/openweb3/web3go/types" 13 | "github.com/stretchr/testify/assert" 14 | ) 15 | 16 | func _TestFilters(t *testing.T) { 17 | client, err := web3go.NewClientWithOption("https://evmtestnet-internal.confluxrpc.com", web3go.ClientOption{ 18 | Option: providers.Option{ 19 | Logger: os.Stdout, 20 | }, 21 | }) 22 | if err != nil { 23 | t.Fatal(err) 24 | } 25 | 26 | logId, err := client.Filter.NewLogFilter(&types.FilterQuery{ 27 | Topics: [][]common.Hash{{common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef")}}, 28 | }) 29 | assert.NoError(t, err) 30 | fmt.Printf("new log filter: %v\n", *logId) 31 | 32 | blockId, err := client.Filter.NewBlockFilter() 33 | assert.NoError(t, err) 34 | fmt.Printf("new block filter: %v\n", *blockId) 35 | 36 | pendingTxId, err := client.Filter.NewPendingTransactionFilter() 37 | assert.NoError(t, err) 38 | fmt.Printf("new pending tx filter: %v\n", *pendingTxId) 39 | 40 | for i := 0; i < 10; i++ { 41 | logChanges, err := client.Filter.GetFilterLogs(*logId) 42 | assert.NoError(t, err) 43 | fmt.Printf("filtered logs: %v\n", logChanges) 44 | 45 | blockChanges, err := client.Filter.GetFilterChanges(*blockId) 46 | assert.NoError(t, err) 47 | fmt.Printf("block changes: %v\n", blockChanges) 48 | 49 | pendingTxChanges, err := client.Filter.GetFilterChanges(*pendingTxId) 50 | assert.NoError(t, err) 51 | fmt.Printf("pending tx changes: %v\n", pendingTxChanges) 52 | time.Sleep(time.Second * 2) 53 | } 54 | 55 | ok, err := client.Filter.UninstallFilter(*logId) 56 | assert.NoError(t, err) 57 | fmt.Printf("uninstall filter result: %v\n", ok) 58 | } 59 | -------------------------------------------------------------------------------- /integration_test/client_pubsub_test.go: -------------------------------------------------------------------------------- 1 | package integrationtest 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "os" 7 | "testing" 8 | 9 | providers "github.com/openweb3/go-rpc-provider/provider_wrapper" 10 | "github.com/openweb3/web3go" 11 | "github.com/openweb3/web3go/types" 12 | "github.com/stretchr/testify/assert" 13 | ) 14 | 15 | func _TestSubHeader(t *testing.T) { 16 | client, err := web3go.NewClientWithOption("wss://evmtestnet-internal.confluxrpc.com/ws ", web3go.ClientOption{ 17 | Option: providers.Option{ 18 | Logger: os.Stdout, 19 | }, 20 | }) 21 | if err != nil { 22 | t.Fatal(err) 23 | } 24 | 25 | head := make(chan *types.Header, 100) 26 | sub, err := client.Eth.SubscribeNewHead(head) 27 | assert.NoError(t, err) 28 | defer sub.Unsubscribe() 29 | 30 | for h := range head { 31 | j, _ := json.Marshal(h) 32 | fmt.Printf("%s\n", j) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /interfaces/signer.go: -------------------------------------------------------------------------------- 1 | package interfaces 2 | 3 | import ( 4 | "math/big" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | "github.com/openweb3/web3go/types" 8 | ) 9 | 10 | type Signer interface { 11 | Address() common.Address 12 | SignTransaction(tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) 13 | SignMessage(text []byte) ([]byte, error) 14 | } 15 | -------------------------------------------------------------------------------- /providers/provider_sign.go: -------------------------------------------------------------------------------- 1 | package providers 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "errors" 7 | 8 | "github.com/ethereum/go-ethereum/common/hexutil" 9 | "github.com/openweb3/go-rpc-provider" 10 | pinterfaces "github.com/openweb3/go-rpc-provider/interfaces" 11 | "github.com/openweb3/web3go/interfaces" 12 | signers "github.com/openweb3/web3go/signers" 13 | "github.com/openweb3/web3go/types" 14 | 15 | pproviders "github.com/openweb3/go-rpc-provider/provider_wrapper" 16 | ) 17 | 18 | type SignableMiddleware struct { 19 | manager signers.SignerManager 20 | provider pinterfaces.Provider 21 | } 22 | 23 | var ( 24 | ErrNoSigner error = errors.New("signer not found") 25 | ErrChainNotReady error = errors.New("chain is not ready") 26 | ErrNoTxArgs error = errors.New("no transaction args") 27 | ) 28 | 29 | const ( 30 | METHOD_SEND_TRANSACTION = "eth_sendTransaction" 31 | METHOD_SEND_RAW_TRANSACTION = "eth_sendRawTransaction" 32 | METHOD_CHAIN_ID = "eth_chainId" 33 | ) 34 | 35 | func NewSignableProvider(p pinterfaces.Provider, signManager *signers.SignerManager) *pproviders.MiddlewarableProvider { 36 | mp := pproviders.NewMiddlewarableProvider(p) 37 | 38 | mid := &SignableMiddleware{ 39 | manager: *signManager, 40 | provider: p, 41 | } 42 | mp.HookCallContext(mid.CallContextMiddleware) 43 | mp.HookBatchCallContext(mid.BatchCallContextMiddleware) 44 | 45 | return mp 46 | } 47 | 48 | func (s *SignableMiddleware) CallContextMiddleware(call pproviders.CallContextFunc) pproviders.CallContextFunc { 49 | return func(ctx context.Context, resultPtr interface{}, method string, args ...interface{}) error { 50 | if method == METHOD_SEND_TRANSACTION { 51 | rawTx, err := s.signTxAndEncode(args[0]) 52 | if err != nil && err != ErrNoSigner { 53 | return err 54 | } 55 | args[0] = rawTx 56 | method = METHOD_SEND_RAW_TRANSACTION 57 | } 58 | return call(ctx, resultPtr, method, args...) 59 | } 60 | } 61 | 62 | func (s *SignableMiddleware) BatchCallContextMiddleware(batchCall pproviders.BatchCallContextFunc) pproviders.BatchCallContextFunc { 63 | return func(ctx context.Context, b []rpc.BatchElem) error { 64 | for i := range b { 65 | if b[i].Method == METHOD_SEND_TRANSACTION { 66 | 67 | if len(b[i].Args) == 0 { 68 | return ErrNoTxArgs 69 | } 70 | 71 | rawTx, err := s.signTxAndEncode(b[i].Args[0]) 72 | if err != nil && err != ErrNoSigner { 73 | return err 74 | } 75 | b[i].Args[0] = rawTx 76 | } 77 | } 78 | return batchCall(ctx, b) 79 | } 80 | } 81 | 82 | func (s *SignableMiddleware) signTxAndEncode(tx interface{}) (hexutil.Bytes, error) { 83 | 84 | var txArgs types.TransactionArgs 85 | 86 | switch tx.(type) { 87 | case map[string]interface{}: 88 | j, err := json.Marshal(tx) 89 | if err != nil { 90 | return nil, err 91 | } 92 | 93 | if err = json.Unmarshal(j, &txArgs); err != nil { 94 | return nil, err 95 | } 96 | case types.TransactionArgs: 97 | txArgs = tx.(types.TransactionArgs) 98 | case *types.TransactionArgs: 99 | txArgs = *tx.(*types.TransactionArgs) 100 | } 101 | 102 | var signer interfaces.Signer 103 | if txArgs.From == nil { 104 | signers := s.manager.List() 105 | if len(signers) == 0 { 106 | return nil, ErrNoSigner 107 | } 108 | signer = signers[0] 109 | } else { 110 | var err error 111 | signer, err = s.manager.Get(*txArgs.From) 112 | if err != nil { 113 | return nil, err 114 | } 115 | } 116 | 117 | if signer == nil { 118 | return nil, ErrNoSigner 119 | } 120 | 121 | // get chainId from chain 122 | var chainId *hexutil.Big 123 | if err := s.provider.CallContext(context.Background(), &chainId, METHOD_CHAIN_ID); err != nil { 124 | return nil, err 125 | } 126 | 127 | if chainId == nil { 128 | return nil, ErrChainNotReady 129 | } 130 | 131 | tx2, err := txArgs.ToTransaction() 132 | if err != nil { 133 | return nil, err 134 | } 135 | 136 | tx2, err = signer.SignTransaction(tx2, chainId.ToInt()) 137 | if err != nil { 138 | return nil, err 139 | } 140 | 141 | rawTx, err := tx2.MarshalBinary() 142 | if err != nil { 143 | return nil, err 144 | } 145 | 146 | return rawTx, nil 147 | } 148 | -------------------------------------------------------------------------------- /signers/keystore.go: -------------------------------------------------------------------------------- 1 | package signers 2 | 3 | import ( 4 | "github.com/openweb3/go-sdk-common/privatekeyhelper" 5 | ) 6 | 7 | func NewPrivateKeySignerByKeystoreFile(filePath string, auth string) (*PrivateKeySigner, error) { 8 | key, err := privatekeyhelper.NewFromKeystoreFile(filePath, auth) 9 | if err != nil { 10 | return nil, err 11 | } 12 | return NewPrivateKeySigner(key), nil 13 | } 14 | 15 | func NewPrivateKeySignerByKeystore(keyjson []byte, auth string) (*PrivateKeySigner, error) { 16 | key, err := privatekeyhelper.NewFromKeystore(keyjson, auth) 17 | if err != nil { 18 | return nil, err 19 | } 20 | return NewPrivateKeySigner(key), nil 21 | } 22 | 23 | func MustNewPrivateKeySignerByKeystoreFile(filePath string, auth string) *PrivateKeySigner { 24 | signer, err := NewPrivateKeySignerByKeystoreFile(filePath, auth) 25 | if err != nil { 26 | panic(err) 27 | } 28 | return signer 29 | } 30 | 31 | func MustNewPrivateKeySignerByKeystore(keyjson []byte, auth string) *PrivateKeySigner { 32 | signer, err := NewPrivateKeySignerByKeystore(keyjson, auth) 33 | if err != nil { 34 | panic(err) 35 | } 36 | return signer 37 | } 38 | 39 | func (p *PrivateKeySigner) ToKeystore(auth string) ([]byte, error) { 40 | return privatekeyhelper.ToKeystore(p.privateKey, auth) 41 | } 42 | 43 | func (p *PrivateKeySigner) SaveKeystore(dirPath string, auth string) error { 44 | return privatekeyhelper.SaveAsKeystore(p.privateKey, dirPath, auth) 45 | } 46 | -------------------------------------------------------------------------------- /signers/keystore_test.go: -------------------------------------------------------------------------------- 1 | package signers 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | 7 | "github.com/ethereum/go-ethereum/common" 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestNewPrivateKeySignerByKeystore(t *testing.T) { 12 | keyjson := []byte(`{"address":"c41899f4588e58f76bbfb07ccca4e4fafccbe1ae","crypto":{"cipher":"aes-128-ctr","ciphertext":"99e29c806b220e98c74516ecfc590a1b46bb7e1a0b3538d53b72eed15434f5c1","cipherparams":{"iv":"63d7fc36514c80f3ae7d57a02133dc24"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"62c112c1c1f853a2ad413e103fc2acc9a2be261b24441893951a0d1db19b6267"},"mac":"27dd38452370d8413c68dde25ba0af17e788f7b2e62f4196146352fdf9f3c66f"},"id":"6cd87026-3b85-46d2-a229-e25164c75d21","version":3}`) 13 | signer, err := NewPrivateKeySignerByKeystore(keyjson, "foo") 14 | assert.NoError(t, err) 15 | 16 | assert.Equal(t, common.HexToAddress("0xc41899f4588e58f76bbfb07ccca4e4fafccbe1ae"), signer.Address()) 17 | } 18 | 19 | func TestToKeystore(t *testing.T) { 20 | signer := MustNewPrivateKeySignerByString("0x0d501c86786789f8cb068c3ed04c0c010db2e526d864bedf2f5a68419daa8e90") 21 | keyjson, err := signer.ToKeystore("foo") 22 | assert.NoError(t, err) 23 | 24 | signer2, err := NewPrivateKeySignerByKeystore(keyjson, "foo") 25 | assert.NoError(t, err) 26 | 27 | assert.Equal(t, signer.Address(), signer2.Address()) 28 | } 29 | 30 | func TestStoreToKeystore(t *testing.T) { 31 | err := os.RemoveAll("keys") 32 | assert.NoError(t, err) 33 | keyjson := []byte(`{"address":"c41899f4588e58f76bbfb07ccca4e4fafccbe1ae","crypto":{"cipher":"aes-128-ctr","ciphertext":"99e29c806b220e98c74516ecfc590a1b46bb7e1a0b3538d53b72eed15434f5c1","cipherparams":{"iv":"63d7fc36514c80f3ae7d57a02133dc24"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"62c112c1c1f853a2ad413e103fc2acc9a2be261b24441893951a0d1db19b6267"},"mac":"27dd38452370d8413c68dde25ba0af17e788f7b2e62f4196146352fdf9f3c66f"},"id":"6cd87026-3b85-46d2-a229-e25164c75d21","version":3}`) 34 | err = MustNewPrivateKeySignerByKeystore(keyjson, "foo").SaveKeystore("keys", "foo") 35 | assert.NoError(t, err) 36 | err = MustNewPrivateKeySignerByKeystore(keyjson, "foo").SaveKeystore("keys", "foo") 37 | assert.Error(t, err) 38 | 39 | err = MustNewRandomPrivateKeySigner().SaveKeystore("keys", "foo") 40 | assert.NoError(t, err) 41 | } 42 | -------------------------------------------------------------------------------- /signers/privatekey_signer.go: -------------------------------------------------------------------------------- 1 | package signers 2 | 3 | import ( 4 | "crypto/ecdsa" 5 | "fmt" 6 | "math/big" 7 | 8 | "github.com/ethereum/go-ethereum/accounts" 9 | "github.com/ethereum/go-ethereum/common" 10 | "github.com/ethereum/go-ethereum/common/hexutil" 11 | "github.com/ethereum/go-ethereum/core/types" 12 | "github.com/ethereum/go-ethereum/crypto" 13 | "github.com/openweb3/go-sdk-common/privatekeyhelper" 14 | "github.com/pkg/errors" 15 | ) 16 | 17 | var ( 18 | ErrInvalidMnemonic error = errors.New("invalid mnemonic") 19 | ) 20 | 21 | type PrivateKeySigner struct { 22 | address common.Address 23 | privateKey *ecdsa.PrivateKey 24 | pubKey *ecdsa.PublicKey 25 | } 26 | 27 | func NewPrivateKeySigner(privateKey *ecdsa.PrivateKey) *PrivateKeySigner { 28 | p := &PrivateKeySigner{ 29 | privateKey: privateKey, 30 | pubKey: &privateKey.PublicKey, 31 | address: crypto.PubkeyToAddress(privateKey.PublicKey), 32 | } 33 | 34 | return p 35 | } 36 | 37 | func NewPrivateKeySignerByString(keyString string) (*PrivateKeySigner, error) { 38 | key, err := privatekeyhelper.NewFromKeyString(keyString) 39 | if err != nil { 40 | return nil, err 41 | } 42 | return NewPrivateKeySigner(key), nil 43 | } 44 | 45 | func NewRandomPrivateKeySigner() (*PrivateKeySigner, error) { 46 | key, err := privatekeyhelper.NewRandom() 47 | if err != nil { 48 | return nil, err 49 | } 50 | return NewPrivateKeySigner(key), nil 51 | } 52 | 53 | func NewPrivateKeySignerByMnemonic(mnemonic string, addressIndex int, option *privatekeyhelper.MnemonicOption) (*PrivateKeySigner, error) { 54 | key, err := privatekeyhelper.NewFromMnemonic(mnemonic, addressIndex, option) 55 | if err != nil { 56 | return nil, err 57 | } 58 | return NewPrivateKeySigner(key), nil 59 | } 60 | 61 | func MustNewPrivateKeySignerByString(keyString string) *PrivateKeySigner { 62 | signer, err := NewPrivateKeySignerByString(keyString) 63 | if err != nil { 64 | panic(err) 65 | } 66 | return signer 67 | } 68 | 69 | func MustNewRandomPrivateKeySigner() *PrivateKeySigner { 70 | signer, err := NewRandomPrivateKeySigner() 71 | if err != nil { 72 | panic(err) 73 | } 74 | return signer 75 | } 76 | 77 | func MustNewPrivateKeySignerByMnemonic(mnemonic string, addressIndex int, option *privatekeyhelper.MnemonicOption) *PrivateKeySigner { 78 | signer, err := NewPrivateKeySignerByMnemonic(mnemonic, addressIndex, option) 79 | if err != nil { 80 | panic(err) 81 | } 82 | return signer 83 | } 84 | 85 | func (p *PrivateKeySigner) Address() common.Address { 86 | return p.address 87 | } 88 | 89 | func (p *PrivateKeySigner) PrivateKey() *ecdsa.PrivateKey { 90 | return p.privateKey 91 | } 92 | 93 | func (p *PrivateKeySigner) PrivateKeyString() string { 94 | privKeyBytes := (crypto.FromECDSA(p.privateKey)) 95 | privKeyStr := hexutil.Encode(privKeyBytes) 96 | return privKeyStr 97 | } 98 | 99 | func (p *PrivateKeySigner) PublicKey() *ecdsa.PublicKey { 100 | return p.pubKey 101 | } 102 | 103 | func (p *PrivateKeySigner) PublicKeyString() string { 104 | pubKeyBytes := crypto.FromECDSAPub(p.pubKey) 105 | pubKeyStr := hexutil.Encode(pubKeyBytes[1:]) 106 | return pubKeyStr 107 | } 108 | 109 | func (p *PrivateKeySigner) SignTransaction(tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { 110 | signer := types.LatestSignerForChainID(chainID) 111 | return types.SignTx(tx, signer, p.privateKey) 112 | } 113 | 114 | func (p *PrivateKeySigner) SignMessage(text []byte) ([]byte, error) { 115 | hash := accounts.TextHash(text) 116 | return crypto.Sign(hash, p.privateKey) 117 | } 118 | 119 | func (p PrivateKeySigner) String() string { 120 | return fmt.Sprintf("address: %v, publicKey: %v", p.address.Hex(), p.PublicKeyString()) 121 | } 122 | -------------------------------------------------------------------------------- /signers/privatekey_signer_test.go: -------------------------------------------------------------------------------- 1 | package signers 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "math/big" 7 | "testing" 8 | 9 | "github.com/ethereum/go-ethereum/common" 10 | "github.com/ethereum/go-ethereum/core/types" 11 | "github.com/openweb3/go-sdk-common/privatekeyhelper" 12 | "github.com/stretchr/testify/assert" 13 | ) 14 | 15 | func TestNewPrivateKeySignerByString(t *testing.T) { 16 | a := assert.New(t) 17 | s, err := NewPrivateKeySignerByString("9ec393923a14eeb557600010ea05d635c667a6995418f8a8f4bdecc63dfe0bb9") 18 | a.NoError(err) 19 | a.Equal(common.HexToAddress("0xe6D148D8398c4cb456196C776D2d9093Dd62C9B0"), s.Address()) 20 | 21 | s, err = NewPrivateKeySignerByString("0x9ec393923a14eeb557600010ea05d635c667a6995418f8a8f4bdecc63dfe0bb9") 22 | a.NoError(err) 23 | a.Equal(common.HexToAddress("0xe6D148D8398c4cb456196C776D2d9093Dd62C9B0"), s.Address()) 24 | 25 | _, err = NewPrivateKeySignerByString("0x123") 26 | a.Error(err, "invalid HEX format of private key") 27 | 28 | _, err = NewPrivateKeySignerByString("") 29 | a.Error(err, "invalid HEX format of private key") 30 | } 31 | 32 | func TestNewPrivateSignerByMnemonic(t *testing.T) { 33 | a := assert.New(t) 34 | _, err := NewPrivateKeySignerByMnemonic("", 0, &privatekeyhelper.MnemonicOption{ 35 | BaseDerivePath: "m/44'/60'/0'/0", 36 | }) 37 | a.EqualError(err, ErrInvalidMnemonic.Error()) 38 | 39 | m := "sister horse tag together deposit lazy wide trust stay vital six napkin" 40 | s, _ := NewPrivateKeySignerByMnemonic(m, 0, &privatekeyhelper.MnemonicOption{BaseDerivePath: "m/44'/60'/0'/0"}) 41 | a.Equal(common.HexToAddress("0xe6D148D8398c4cb456196C776D2d9093Dd62C9B0"), s.Address()) 42 | 43 | s, _ = NewPrivateKeySignerByMnemonic(m, 1, &privatekeyhelper.MnemonicOption{BaseDerivePath: "m/44'/60'/0'/0"}) 44 | a.Equal(common.HexToAddress("0x3a3347C42705C5328012dE9a38b030128eee4F83"), s.Address()) 45 | } 46 | 47 | func TestMarshalText(t *testing.T) { 48 | a := assert.New(t) 49 | s, err := NewPrivateKeySignerByString("9ec393923a14eeb557600010ea05d635c667a6995418f8a8f4bdecc63dfe0bb9") 50 | a.NoError(err) 51 | a.Equal(s.String(), "address: 0xe6D148D8398c4cb456196C776D2d9093Dd62C9B0, publicKey: 0x08b68fb0ff6e47cf278f0bb0879b00b6bb00b69cea9e5c24348bf7bed07f2cc347e3aa1f73f0ae2c9a6ae9213e18938db88fcaef5f3c6c1f8b3cfdd985a19cad") 52 | } 53 | 54 | func TestSignLegacyTransaction(t *testing.T) { 55 | a := assert.New(t) 56 | signer, err := NewPrivateKeySignerByString("9ec393923a14eeb557600010ea05d635c667a6995418f8a8f4bdecc63dfe0bb9") 57 | a.NoError(err) 58 | 59 | tx := types.NewTx(&types.LegacyTx{}) 60 | tx, err = signer.SignTransaction(tx, nil) 61 | a.NoError(err) 62 | 63 | fmt.Printf("tx %s\n", MustJsonMarshalTx(tx)) 64 | 65 | v, r, s := tx.RawSignatureValues() 66 | expectR, _ := big.NewInt(0).SetString("0xbd6870726e062f73f80bd6529fac257f391009c0d95134ac719876ebbb504631", 0) 67 | expectS, _ := big.NewInt(0).SetString("0x4b81c0ca9202115889ac6124e162f3ff304621d26ef156ccf54af861d5f29163", 0) 68 | a.Equal(v, big.NewInt(28)) 69 | a.Equal(r, expectR) 70 | a.Equal(s, expectS) 71 | } 72 | 73 | func TestSignDynamicFeeTx(t *testing.T) { 74 | a := assert.New(t) 75 | signer, err := NewPrivateKeySignerByString("9ec393923a14eeb557600010ea05d635c667a6995418f8a8f4bdecc63dfe0bb9") 76 | a.NoError(err) 77 | 78 | from := signer.Address() 79 | 80 | tx := types.NewTx(&types.DynamicFeeTx{ 81 | To: &from, 82 | Value: big.NewInt(1), 83 | GasFeeCap: big.NewInt(2), 84 | GasTipCap: big.NewInt(1), 85 | Nonce: 0, 86 | Gas: 21000, 87 | ChainID: big.NewInt(3), 88 | }) 89 | tx, err = signer.SignTransaction(tx, big.NewInt(3)) 90 | a.NoError(err) 91 | 92 | fmt.Printf("tx %s\n", MustJsonMarshalTx(tx)) 93 | 94 | marshaled, err := tx.MarshalBinary() 95 | a.NoError(err) 96 | expectMarshaled := "02f8620380010282520894e6d148d8398c4cb456196c776d2d9093dd62c9b00180c001a055e7caac90c8e0135575c851ae8e18693017b42da586b78c8b11d221b0192b77a0663d198301e510c88158375d9fcb953fb49b586fa0c48bdee207f95f038b5281" 97 | a.Equal(fmt.Sprintf("%x", marshaled), expectMarshaled) 98 | } 99 | 100 | func MustJsonMarshalTx(tx *types.Transaction) []byte { 101 | j, err := json.Marshal(tx) 102 | if err != nil { 103 | panic(err) 104 | } 105 | return j 106 | } 107 | -------------------------------------------------------------------------------- /signers/signer_manager.go: -------------------------------------------------------------------------------- 1 | package signers 2 | 3 | import ( 4 | "errors" 5 | "sync" 6 | 7 | "github.com/ethereum/go-ethereum/common" 8 | "github.com/openweb3/go-sdk-common/privatekeyhelper" 9 | "github.com/openweb3/web3go/interfaces" 10 | ) 11 | 12 | type SignerManager struct { 13 | signerMap map[common.Address]interfaces.Signer 14 | signers []interfaces.Signer 15 | mutex sync.Mutex 16 | } 17 | 18 | func NewSignerManager(signers []interfaces.Signer) *SignerManager { 19 | sm := &SignerManager{ 20 | signerMap: make(map[common.Address]interfaces.Signer), 21 | signers: signers, 22 | } 23 | 24 | for _, signer := range signers { 25 | sm.signerMap[signer.Address()] = signer 26 | } 27 | 28 | return sm 29 | } 30 | 31 | func NewSignerManagerByPrivateKeyStrings(privateKeys []string) (*SignerManager, error) { 32 | signers := make([]interfaces.Signer, len(privateKeys)) 33 | for i, p := range privateKeys { 34 | s, err := NewPrivateKeySignerByString(p) 35 | if err != nil { 36 | return nil, err 37 | } 38 | signers[i] = s 39 | } 40 | return NewSignerManager(signers), nil 41 | } 42 | 43 | func MustNewSignerManagerByPrivateKeyStrings(privateKeys []string) *SignerManager { 44 | sm, err := NewSignerManagerByPrivateKeyStrings(privateKeys) 45 | if err != nil { 46 | panic(err) 47 | } 48 | return sm 49 | } 50 | 51 | func NewSignerManagerByMnemonic(mnemonic string, addressNumber int, option *privatekeyhelper.MnemonicOption) (*SignerManager, error) { 52 | signers := make([]interfaces.Signer, addressNumber) 53 | for i := 0; i < addressNumber; i++ { 54 | s, err := NewPrivateKeySignerByMnemonic(mnemonic, i, option) 55 | if err != nil { 56 | return nil, err 57 | } 58 | signers[i] = s 59 | } 60 | return NewSignerManager(signers), nil 61 | } 62 | 63 | func MustNewSignerManagerByMnemonic(mnemonic string, addressNumber int, option *privatekeyhelper.MnemonicOption) *SignerManager { 64 | sm, err := NewSignerManagerByMnemonic(mnemonic, addressNumber, option) 65 | if err != nil { 66 | panic(err) 67 | } 68 | return sm 69 | } 70 | 71 | func (s *SignerManager) Add(signer interfaces.Signer) error { 72 | s.mutex.Lock() 73 | defer s.mutex.Unlock() 74 | 75 | if _, ok := s.signerMap[signer.Address()]; ok { 76 | return errors.New("signer already exists") 77 | } 78 | s.signers = append(s.signers, signer) 79 | s.signerMap[signer.Address()] = signer 80 | return nil 81 | } 82 | 83 | func (s *SignerManager) Remove(addr common.Address) error { 84 | s.mutex.Lock() 85 | defer s.mutex.Unlock() 86 | 87 | if _, err := s.Get(addr); err != nil { 88 | return err 89 | } 90 | 91 | delete(s.signerMap, addr) 92 | for i, signer := range s.signers { 93 | if signer.Address() == addr { 94 | s.signers = append(s.signers[:i], s.signers[i+1:]...) 95 | break 96 | } 97 | } 98 | return nil 99 | } 100 | 101 | func (s *SignerManager) Get(addr common.Address) (interfaces.Signer, error) { 102 | if _, ok := s.signerMap[addr]; !ok { 103 | return nil, errors.New("signer not found") 104 | } 105 | return s.signerMap[addr], nil 106 | } 107 | 108 | func (s *SignerManager) List() []interfaces.Signer { 109 | return s.signers 110 | } 111 | -------------------------------------------------------------------------------- /signers/signer_manager_test.go: -------------------------------------------------------------------------------- 1 | package signers 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestNewSingerManagerByPrivateKeys(t *testing.T) { 11 | sm, err := NewSignerManagerByPrivateKeyStrings([]string{ 12 | "9ec393923a14eeb557600010ea05d635c667a6995418f8a8f4bdecc63dfe0bb9", 13 | "1ab8ec2627e19007d2c62145df6acf51f16b8fd93b0a27c01dae4eb271aadee1", 14 | }) 15 | if err != nil { 16 | t.Fatal(err) 17 | } 18 | a := assert.New(t) 19 | list := sm.List() 20 | a.Equal(2, len(list)) 21 | a.Equal(list[0].Address(), common.HexToAddress("0xe6D148D8398c4cb456196C776D2d9093Dd62C9B0")) 22 | a.Equal(list[1].Address(), common.HexToAddress("0x3a3347C42705C5328012dE9a38b030128eee4F83")) 23 | 24 | signer, err := sm.Get(common.HexToAddress("0xe6D148D8398c4cb456196C776D2d9093Dd62C9B0")) 25 | a.NoError(err) 26 | a.Equal(signer.Address(), common.HexToAddress("0xe6D148D8398c4cb456196C776D2d9093Dd62C9B0")) 27 | } 28 | -------------------------------------------------------------------------------- /types/account_pending_transactions.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/ethereum/go-ethereum/common/hexutil" 7 | "github.com/openweb3/web3go/types/enums" 8 | ) 9 | 10 | type TransactionStatus struct { 11 | Status enums.TransactionStatus 12 | PendingReason enums.PendingReason 13 | } 14 | 15 | func (t TransactionStatus) MarshalJSON() ([]byte, error) { 16 | if t.Status == enums.TransactionStatusPending { 17 | return json.Marshal(struct { 18 | Pending string `json:"pending"` 19 | }{ 20 | Pending: string(t.PendingReason), 21 | }) 22 | } 23 | return json.Marshal(t.Status) 24 | } 25 | 26 | func (t *TransactionStatus) UnmarshalJSON(data []byte) error { 27 | var rawStatus string 28 | if err := json.Unmarshal(data, &rawStatus); err == nil { 29 | t.Status = enums.TransactionStatus(rawStatus) 30 | return nil 31 | } 32 | 33 | var objStatus struct { 34 | Pending string `json:"pending"` 35 | } 36 | if err := json.Unmarshal(data, &objStatus); err != nil { 37 | return err 38 | } 39 | 40 | t.Status = enums.TransactionStatusPending 41 | t.PendingReason = enums.PendingReason(objStatus.Pending) 42 | return nil 43 | } 44 | 45 | //go:generate gencodec -type AccountPendingTransactions -field-override accountPendingTransactionsMarshaling -out gen_account_pending_transactions_json.go 46 | type AccountPendingTransactions struct { 47 | PendingTransactions []Transaction `json:"pendingTransactions"` 48 | FirstTxStatus *TransactionStatus `json:"firstTxStatus,omitempty"` 49 | PendingCount uint64 `json:"pendingCount"` 50 | } 51 | 52 | type accountPendingTransactionsMarshaling struct { 53 | PendingTransactions []Transaction `json:"pendingTransactions"` 54 | FirstTxStatus *TransactionStatus `json:"firstTxStatus,omitempty"` 55 | PendingCount hexutil.Uint64 `json:"pendingCount"` 56 | } 57 | -------------------------------------------------------------------------------- /types/account_pending_transactions_test.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | ) 7 | 8 | func TestMarshalTransactionStatus(t *testing.T) { 9 | testCases := []struct { 10 | name string 11 | status TransactionStatus 12 | expectedJSON string 13 | }{ 14 | { 15 | name: "Packed status", 16 | status: TransactionStatus{Status: "packed"}, 17 | expectedJSON: `"packed"`, 18 | }, 19 | { 20 | name: "Ready status", 21 | status: TransactionStatus{Status: "ready"}, 22 | expectedJSON: `"ready"`, 23 | }, 24 | { 25 | name: "Pending status - future nonce", 26 | status: TransactionStatus{Status: "pending", PendingReason: "futureNonce"}, 27 | expectedJSON: `{"pending":"futureNonce"}`, 28 | }, 29 | { 30 | name: "Pending status - not enough cash", 31 | status: TransactionStatus{Status: "pending", PendingReason: "notEnoughCash"}, 32 | expectedJSON: `{"pending":"notEnoughCash"}`, 33 | }, 34 | } 35 | 36 | for _, tc := range testCases { 37 | t.Run(tc.name, func(t *testing.T) { 38 | result, err := json.Marshal(tc.status) 39 | if err != nil { 40 | t.Fatalf("Failed to marshal: %v", err) 41 | } 42 | if string(result) != tc.expectedJSON { 43 | t.Errorf("Expected %s, got %s", tc.expectedJSON, string(result)) 44 | } 45 | }) 46 | } 47 | } 48 | 49 | func TestUnmarshalTransactionStatus(t *testing.T) { 50 | testCases := []struct { 51 | name string 52 | jsonData string 53 | expectedStatus TransactionStatus 54 | }{ 55 | { 56 | name: "Packed status", 57 | jsonData: `"packed"`, 58 | expectedStatus: TransactionStatus{Status: "packed"}, 59 | }, 60 | { 61 | name: "Ready status", 62 | jsonData: `"ready"`, 63 | expectedStatus: TransactionStatus{Status: "ready"}, 64 | }, 65 | { 66 | name: "Pending status - future nonce", 67 | jsonData: `{"pending":"futureNonce"}`, 68 | expectedStatus: TransactionStatus{Status: "pending", PendingReason: "futureNonce"}, 69 | }, 70 | { 71 | name: "Pending status - not enough cash", 72 | jsonData: `{"pending":"notEnoughCash"}`, 73 | expectedStatus: TransactionStatus{Status: "pending", PendingReason: "notEnoughCash"}, 74 | }, 75 | } 76 | 77 | for _, tc := range testCases { 78 | t.Run(tc.name, func(t *testing.T) { 79 | var result TransactionStatus 80 | err := json.Unmarshal([]byte(tc.jsonData), &result) 81 | if err != nil { 82 | t.Fatalf("Failed to unmarshal: %v", err) 83 | } 84 | if result != tc.expectedStatus { 85 | t.Errorf("Expected %+v, got %+v", tc.expectedStatus, result) 86 | } 87 | }) 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /types/action.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "math/big" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | "github.com/ethereum/go-ethereum/common/hexutil" 8 | ) 9 | 10 | type CallType string 11 | type RewardType string 12 | type CreateType string 13 | 14 | const ( 15 | CALL_NONE CallType = "none" 16 | CALL_CALL CallType = "call" 17 | CALL_CALLCODE CallType = "callCode" 18 | CALL_DELEGATECALL CallType = "delegateCall" 19 | CALL_STATICCALL CallType = "staticCall" 20 | ) 21 | 22 | const ( 23 | CREATE_NONE CreateType = "none" 24 | CREATE_CREATE CreateType = "create" 25 | CREATE_CREATE2 CreateType = "create2" 26 | ) 27 | 28 | const ( 29 | REWARD_BLOCK RewardType = "block" 30 | REWARD_UNCLE RewardType = "uncle" 31 | REWARD_EMPTYSTEP RewardType = "emptyStep" 32 | REWARD_EXTERNAL RewardType = "external" 33 | ) 34 | 35 | //go:generate gencodec -type Call -field-override callMarshaling -out gen_call_json.go 36 | type Call struct { 37 | From common.Address `json:"from"` 38 | To common.Address `json:"to"` 39 | Value *big.Int `json:"value"` 40 | Gas *big.Int `json:"gas"` 41 | Input []byte `json:"input"` 42 | CallType CallType `json:"callType"` 43 | } 44 | 45 | //go:generate gencodec -type Create -field-override createMarshaling -out gen_create_json.go 46 | type Create struct { 47 | From common.Address `json:"from"` 48 | Value *big.Int `json:"value"` 49 | Gas *big.Int `json:"gas"` 50 | Init []byte `json:"init"` 51 | CreateType *CreateType `json:"createType,omitempty"` // omit for openethereum, valid for conflux-espace 52 | } 53 | 54 | //go:generate gencodec -type Suicide -field-override suicideMarshaling -out gen_suicide_json.go 55 | type Suicide struct { 56 | Address common.Address `json:"address"` 57 | RefundAddress common.Address `json:"refundAddress"` 58 | Balance *big.Int `json:"balance"` 59 | } 60 | 61 | //go:generate gencodec -type Reward -field-override rewardMarshaling -out gen_reward_json.go 62 | type Reward struct { 63 | Author common.Address `json:"author"` 64 | Value *big.Int `json:"value"` 65 | RewardType RewardType `json:"rewardType"` 66 | } 67 | 68 | type callMarshaling struct { 69 | From common.Address `json:"from"` 70 | To common.Address `json:"to"` 71 | Value *hexutil.Big `json:"value"` 72 | Gas *hexutil.Big `json:"gas"` 73 | Input hexutil.Bytes `json:"input"` 74 | CallType CallType `json:"callType"` 75 | } 76 | 77 | type createMarshaling struct { 78 | From common.Address `json:"from"` 79 | Value *hexutil.Big `json:"value"` 80 | Gas *hexutil.Big `json:"gas"` 81 | Init hexutil.Bytes `json:"init"` 82 | } 83 | 84 | type suicideMarshaling struct { 85 | Address common.Address `json:"address"` 86 | RefundAddress common.Address `json:"refundAddress"` 87 | Balance *hexutil.Big `json:"balance"` 88 | } 89 | 90 | type rewardMarshaling struct { 91 | Author common.Address `json:"author"` 92 | Value *hexutil.Big `json:"value"` 93 | RewardType RewardType `json:"rewardType"` 94 | } 95 | -------------------------------------------------------------------------------- /types/action_result.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "math/big" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | "github.com/ethereum/go-ethereum/common/hexutil" 8 | ) 9 | 10 | //go:generate gencodec -type CallResult -field-override callResultMarshaling -out gen_call_result_json.go 11 | type CallResult struct { 12 | GasUsed *big.Int `json:"gasUsed"` 13 | Output []byte `json:"output"` 14 | } 15 | 16 | //go:generate gencodec -type CreateResult -field-override createResultMarshaling -out gen_create_result_json.go 17 | type CreateResult struct { 18 | GasUsed *big.Int `json:"gasUsed"` 19 | Code []byte `json:"code"` 20 | Address common.Address `json:"address"` 21 | } 22 | 23 | type callResultMarshaling struct { 24 | GasUsed *hexutil.Big `json:"gasUsed"` 25 | Output hexutil.Bytes `json:"output"` 26 | } 27 | type createResultMarshaling struct { 28 | GasUsed *hexutil.Big `json:"gasUsed"` 29 | Code hexutil.Bytes `json:"code"` 30 | Address common.Address `json:"address"` 31 | } 32 | -------------------------------------------------------------------------------- /types/call_request_json.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | "math/big" 6 | "strconv" 7 | 8 | "github.com/ethereum/go-ethereum/common" 9 | "github.com/ethereum/go-ethereum/common/hexutil" 10 | "github.com/ethereum/go-ethereum/core/types" 11 | ) 12 | 13 | var _ = (*callRequestMarshaling)(nil) 14 | 15 | // MarshalJSON marshals as JSON. 16 | func (c CallRequest) MarshalJSON() ([]byte, error) { 17 | type CallRequest struct { 18 | From *common.Address `json:"from,omitempty"` 19 | To *common.Address `json:"to,omitempty"` 20 | Gas *hexutil.Uint64 `json:"gas,omitempty"` 21 | GasPrice *hexutil.Big `json:"gasPrice,omitempty"` 22 | MaxFeePerGas *hexutil.Big `json:"maxFeePerGas,omitempty"` 23 | MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` 24 | Value *hexutil.Big `json:"value,omitempty"` 25 | Nonce *hexutil.Uint64 `json:"nonce,omitempty"` 26 | Data hexutil.Bytes `json:"data,omitempty"` 27 | Input hexutil.Bytes `json:"input,omitempty"` 28 | AccessList *types.AccessList `json:"accessList,omitempty"` 29 | AuthorizationList []types.SetCodeAuthorization `json:"authorizationList,omitempty"` 30 | ChainID *hexutil.Big `json:"chainId,omitempty"` 31 | Type *hexutil.Uint64 `json:"type,omitempty"` 32 | } 33 | var enc CallRequest 34 | enc.From = c.From 35 | enc.To = c.To 36 | enc.Gas = (*hexutil.Uint64)(c.Gas) 37 | enc.GasPrice = (*hexutil.Big)(c.GasPrice) 38 | enc.MaxFeePerGas = (*hexutil.Big)(c.MaxFeePerGas) 39 | enc.MaxPriorityFeePerGas = (*hexutil.Big)(c.MaxPriorityFeePerGas) 40 | enc.Value = (*hexutil.Big)(c.Value) 41 | enc.Nonce = (*hexutil.Uint64)(c.Nonce) 42 | enc.Data = c.Data 43 | enc.Input = c.Input 44 | enc.AccessList = c.AccessList 45 | enc.AuthorizationList = c.AuthorizationList 46 | enc.ChainID = (*hexutil.Big)(c.ChainID) 47 | enc.Type = (*hexutil.Uint64)(c.Type) 48 | return json.Marshal(&enc) 49 | } 50 | 51 | // UnmarshalJSON unmarshals from JSON. 52 | func (c *CallRequest) UnmarshalJSON(input []byte) error { 53 | type CallRequest struct { 54 | From *common.Address `json:"from,omitempty"` 55 | To *common.Address `json:"to,omitempty"` 56 | Gas *hexutil.Uint64 `json:"gas,omitempty"` 57 | GasPrice *hexutil.Big `json:"gasPrice,omitempty"` 58 | MaxFeePerGas *hexutil.Big `json:"maxFeePerGas,omitempty"` 59 | MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` 60 | Value *hexutil.Big `json:"value,omitempty"` 61 | Nonce *hexutil.Uint64 `json:"nonce,omitempty"` 62 | Data *hexutil.Bytes `json:"data,omitempty"` 63 | Input *hexutil.Bytes `json:"input,omitempty"` 64 | AccessList *types.AccessList `json:"accessList,omitempty"` 65 | AuthorizationList []types.SetCodeAuthorization `json:"authorizationList,omitempty"` 66 | ChainID *hexutil.Big `json:"chainId,omitempty"` 67 | Type *string `json:"type,omitempty"` 68 | } 69 | var dec CallRequest 70 | if err := json.Unmarshal(input, &dec); err != nil { 71 | return err 72 | } 73 | if dec.From != nil { 74 | c.From = dec.From 75 | } 76 | if dec.To != nil { 77 | c.To = dec.To 78 | } 79 | if dec.Gas != nil { 80 | c.Gas = (*uint64)(dec.Gas) 81 | } 82 | if dec.GasPrice != nil { 83 | c.GasPrice = (*big.Int)(dec.GasPrice) 84 | } 85 | if dec.MaxFeePerGas != nil { 86 | c.MaxFeePerGas = (*big.Int)(dec.MaxFeePerGas) 87 | } 88 | if dec.MaxPriorityFeePerGas != nil { 89 | c.MaxPriorityFeePerGas = (*big.Int)(dec.MaxPriorityFeePerGas) 90 | } 91 | if dec.Value != nil { 92 | c.Value = (*big.Int)(dec.Value) 93 | } 94 | if dec.Nonce != nil { 95 | c.Nonce = (*uint64)(dec.Nonce) 96 | } 97 | if dec.Data != nil { 98 | c.Data = *dec.Data 99 | } 100 | if dec.Input != nil { 101 | c.Input = *dec.Input 102 | } 103 | if dec.AccessList != nil { 104 | c.AccessList = dec.AccessList 105 | } 106 | if dec.AuthorizationList != nil { 107 | c.AuthorizationList = dec.AuthorizationList 108 | } 109 | if dec.ChainID != nil { 110 | c.ChainID = (*big.Int)(dec.ChainID) 111 | } 112 | if dec.Type != nil { 113 | valInt64, err := strconv.ParseInt(*dec.Type, 0, 64) 114 | if err != nil { 115 | return err 116 | } 117 | valUint64 := uint64(valInt64) 118 | c.Type = &valUint64 119 | } 120 | return nil 121 | } 122 | -------------------------------------------------------------------------------- /types/enums/geth_debug_builtin_trace.go: -------------------------------------------------------------------------------- 1 | package enums 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type GethDebugBuiltInTracerType int 8 | 9 | const ( 10 | GETH_BUILDIN_TRACER_FOUR_BYTE GethDebugBuiltInTracerType = iota 11 | GETH_BUILDIN_TRACER_CALL 12 | GETH_BUILDIN_TRACER_PRE_STATE 13 | GETH_BUILDIN_TRACER_NOOP 14 | GETH_BUILDIN_TRACER_MUX 15 | ) 16 | 17 | var ( 18 | GethDebugBuiltInTracerTypeV2S map[GethDebugBuiltInTracerType]string 19 | GethDebugBuiltInTracerTypeS2V map[string]GethDebugBuiltInTracerType 20 | ) 21 | 22 | func init() { 23 | GethDebugBuiltInTracerTypeV2S = map[GethDebugBuiltInTracerType]string{ 24 | GETH_BUILDIN_TRACER_FOUR_BYTE: "4byteTracer", 25 | GETH_BUILDIN_TRACER_CALL: "callTracer", 26 | GETH_BUILDIN_TRACER_PRE_STATE: "prestateTracer", 27 | GETH_BUILDIN_TRACER_NOOP: "noopTracer", 28 | GETH_BUILDIN_TRACER_MUX: "muxTracer", 29 | } 30 | 31 | GethDebugBuiltInTracerTypeS2V = make(map[string]GethDebugBuiltInTracerType) 32 | for k, v := range GethDebugBuiltInTracerTypeV2S { 33 | GethDebugBuiltInTracerTypeS2V[v] = k 34 | } 35 | } 36 | 37 | func (t GethDebugBuiltInTracerType) String() string { 38 | if t == 0 { 39 | return "" 40 | } 41 | 42 | v, ok := GethDebugBuiltInTracerTypeV2S[t] 43 | if ok { 44 | return v 45 | } 46 | return "unknown" 47 | } 48 | 49 | func (t GethDebugBuiltInTracerType) MarshalText() ([]byte, error) { 50 | return []byte(t.String()), nil 51 | } 52 | 53 | func (t *GethDebugBuiltInTracerType) UnmarshalText(data []byte) error { 54 | v, ok := GethDebugBuiltInTracerTypeS2V[string(data)] 55 | if ok { 56 | *t = v 57 | return nil 58 | } 59 | return fmt.Errorf("unknown tracer type %v", string(data)) 60 | } 61 | 62 | func ParseGethDebugBuiltInTracerType(str string) (*GethDebugBuiltInTracerType, error) { 63 | v, ok := GethDebugBuiltInTracerTypeS2V[str] 64 | if !ok { 65 | return nil, fmt.Errorf("unknown tracer type %v", str) 66 | } 67 | return &v, nil 68 | } 69 | 70 | func (t GethDebugBuiltInTracerType) ToGethTraceType() GethTraceType { 71 | switch t { 72 | case GETH_BUILDIN_TRACER_FOUR_BYTE: 73 | return GETH_TRACE_FOUR_BYTE 74 | case GETH_BUILDIN_TRACER_CALL: 75 | return GETH_TRACE_CALL 76 | case GETH_BUILDIN_TRACER_PRE_STATE: 77 | return GETH_TRACE_PRE_STATE 78 | case GETH_BUILDIN_TRACER_NOOP: 79 | return GETH_TRACE_NOOP 80 | case GETH_BUILDIN_TRACER_MUX: 81 | return GETH_TRACE_MUX 82 | default: 83 | return GETH_TRACE_JS 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /types/enums/geth_trace.go: -------------------------------------------------------------------------------- 1 | package enums 2 | 3 | type GethTraceType int 4 | 5 | const ( 6 | GETH_TRACE_DEFAULT GethTraceType = iota 7 | GETH_TRACE_CALL 8 | GETH_TRACE_FOUR_BYTE 9 | GETH_TRACE_PRE_STATE 10 | GETH_TRACE_NOOP 11 | GETH_TRACE_MUX 12 | GETH_TRACE_JS 13 | ) 14 | 15 | func ParseGethTraceType(tracer string) GethTraceType { 16 | debugTracerType, err := ParseGethDebugBuiltInTracerType(tracer) 17 | if err != nil { 18 | return GETH_TRACE_JS 19 | } else { 20 | return debugTracerType.ToGethTraceType() 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /types/enums/pending_reason.go: -------------------------------------------------------------------------------- 1 | package enums 2 | 3 | type PendingReason string 4 | 5 | const ( 6 | PENDING_REASON_FUTURE_NONCE PendingReason = "futureNonce" 7 | PENDING_REASON_NOT_ENOUGH_CASH PendingReason = "notEnoughCash" 8 | PENDING_REASON_OLD_EPOCH_HEIGHT PendingReason = "oldEpochHeight" 9 | PENDING_REASON_OUTDATED_STATUS PendingReason = "outdatedStatus" 10 | ) 11 | -------------------------------------------------------------------------------- /types/enums/transaction_status.go: -------------------------------------------------------------------------------- 1 | package enums 2 | 3 | type TransactionStatus string 4 | 5 | const ( 6 | TransactionStatusPacked TransactionStatus = "packed" 7 | TransactionStatusReady TransactionStatus = "ready" 8 | TransactionStatusPending TransactionStatus = "pending" 9 | ) 10 | -------------------------------------------------------------------------------- /types/filter_changes.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | 7 | "github.com/ethereum/go-ethereum/common" 8 | ) 9 | 10 | type FilterChanges struct { 11 | Logs []Log 12 | Hashes []common.Hash 13 | } 14 | 15 | func (f *FilterChanges) UnmarshalJSON(input []byte) error { 16 | logs := []Log{} 17 | if err := json.Unmarshal(input, &logs); err == nil { 18 | f.Logs = logs 19 | return nil 20 | } 21 | 22 | hashes := []common.Hash{} 23 | if err := json.Unmarshal(input, &hashes); err == nil { 24 | f.Hashes = hashes 25 | return nil 26 | } 27 | 28 | return fmt.Errorf("failed to unmarshal filter changes by %x", input) 29 | } 30 | 31 | func (f *FilterChanges) MarshalJSON() ([]byte, error) { 32 | if f.Logs != nil { 33 | return json.Marshal(f.Logs) 34 | } 35 | 36 | if f.Hashes != nil { 37 | return json.Marshal(f.Hashes) 38 | } 39 | 40 | return json.Marshal(nil) 41 | } 42 | -------------------------------------------------------------------------------- /types/filter_query.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | "github.com/ethereum/go-ethereum/eth/filters" 8 | "github.com/pkg/errors" 9 | ) 10 | 11 | // FilterQuery contains options for contract log filtering. 12 | type FilterQuery struct { 13 | BlockHash *common.Hash `json:"blockHash,omitempty"` // used by eth_getLogs, return logs only from block with this hash 14 | FromBlock *BlockNumber `json:"fromBlock,omitempty"` // beginning of the queried range, nil means latest block 15 | ToBlock *BlockNumber `json:"toBlock,omitempty"` // end of the range, nil means latest block 16 | Addresses []common.Address `json:"address,omitempty"` // restricts matches to events created by specific contracts 17 | 18 | // The Topic list restricts matches to particular event topics. Each event has a list 19 | // of topics. Topics matches a prefix of that list. An empty element slice matches any 20 | // topic. Non-empty elements represent an alternative that matches any of the 21 | // contained topics. 22 | // 23 | // Examples: 24 | // {} or nil matches any topic list 25 | // {{A}} matches topic A in first position 26 | // {{}, {B}} matches any topic in first position AND B in second position 27 | // {{A}, {B}} matches topic A in first position AND B in second position 28 | // {{A, B}, {C, D}} matches topic (A OR B) in first position AND (C OR D) in second position 29 | Topics [][]common.Hash `json:"topics,omitempty"` 30 | } 31 | 32 | func (args *FilterQuery) UnmarshalJSON(data []byte) error { 33 | var fc filters.FilterCriteria 34 | if err := json.Unmarshal(data, &fc); err != nil { 35 | return errors.Wrapf(err, "failed to unmarshal filter criteria") 36 | } 37 | 38 | args.BlockHash = fc.BlockHash 39 | args.FromBlock = BigIntToBlockNumber(fc.FromBlock) 40 | args.ToBlock = BigIntToBlockNumber(fc.ToBlock) 41 | args.Addresses = fc.Addresses 42 | args.Topics = fc.Topics 43 | return nil 44 | } 45 | -------------------------------------------------------------------------------- /types/filter_transaction.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "math/big" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | "github.com/ethereum/go-ethereum/common/hexutil" 8 | ) 9 | 10 | type TransactionFilter struct { 11 | From *SenderArgument `json:"from"` 12 | To *ActionArgument `json:"to"` 13 | Gas *ValueFilterArgument `json:"gas"` 14 | GasPrice *ValueFilterArgument `json:"gasPrice"` 15 | Value *ValueFilterArgument `json:"value"` 16 | Nonce *ValueFilterArgument `json:"nonce"` 17 | } 18 | 19 | type SenderArgument struct { 20 | Eq common.Address `json:"eq"` 21 | } 22 | 23 | type ActionArgument struct { 24 | Eq common.Address `json:"eq,omitempty"` 25 | Action string `json:"action,omitempty"` 26 | } 27 | 28 | //go:generate gencodec -type ValueFilterArgument -field-override valueFilterArgumentMarshaling -out gen_value_filter_argument_json.go 29 | type ValueFilterArgument struct { 30 | Eq *big.Int `json:"eq,omitempty"` 31 | Lt *big.Int `json:"lt,omitempty"` 32 | Gt *big.Int `json:"gt,omitempty"` 33 | } 34 | 35 | type valueFilterArgumentMarshaling struct { 36 | Eq *hexutil.Big `json:"eq"` 37 | Lt *hexutil.Big `json:"lt"` 38 | Gt *hexutil.Big `json:"gt"` 39 | } 40 | -------------------------------------------------------------------------------- /types/gas_fee_data.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "math/big" 5 | 6 | "github.com/openweb3/go-rpc-provider" 7 | ) 8 | 9 | type gasFeeData struct { 10 | gasPrice *big.Int 11 | maxFeePerGas *big.Int 12 | maxPriorityFeePerGas *big.Int 13 | } 14 | 15 | func getFeeData(r ReaderForPopulate) (*gasFeeData, error) { 16 | data := &gasFeeData{} 17 | 18 | gasPrice, err := r.GasPrice() 19 | if err != nil { 20 | return nil, err 21 | } 22 | data.gasPrice = gasPrice 23 | 24 | block, err := r.BlockByNumber(rpc.LatestBlockNumber, false) 25 | if err != nil { 26 | return nil, err 27 | } 28 | basefee := block.BaseFeePerGas 29 | 30 | if basefee == nil { 31 | return data, nil 32 | } 33 | 34 | priorityFeePerGas, err := r.MaxPriorityFeePerGas() 35 | if err != nil { 36 | return nil, err 37 | } 38 | 39 | data.maxPriorityFeePerGas = priorityFeePerGas 40 | data.maxFeePerGas = new(big.Int).Mul(basefee, big.NewInt(2)) 41 | data.maxFeePerGas = new(big.Int).Add(data.maxFeePerGas, data.maxPriorityFeePerGas) 42 | return data, nil 43 | } 44 | 45 | func (g gasFeeData) isSupport1559() bool { 46 | return g.maxPriorityFeePerGas != nil && g.maxFeePerGas != nil 47 | } 48 | -------------------------------------------------------------------------------- /types/gen_account_pending_transactions_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/AlexanderMint/gencodec2. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | 8 | "github.com/ethereum/go-ethereum/common/hexutil" 9 | "github.com/ethereum/go-ethereum/core/types" 10 | ) 11 | 12 | var _ = (*accountPendingTransactionsMarshaling)(nil) 13 | 14 | // MarshalJSON marshals as JSON. 15 | func (a AccountPendingTransactions) MarshalJSON() ([]byte, error) { 16 | type AccountPendingTransactions struct { 17 | PendingTransactions []types.Transaction `json:"pendingTransactions"` 18 | FirstTxStatus *TransactionStatus `json:"firstTxStatus,omitempty"` 19 | PendingCount hexutil.Uint64 `json:"pendingCount"` 20 | } 21 | var enc AccountPendingTransactions 22 | enc.PendingTransactions = a.PendingTransactions 23 | enc.FirstTxStatus = a.FirstTxStatus 24 | enc.PendingCount = hexutil.Uint64(a.PendingCount) 25 | return json.Marshal(&enc) 26 | } 27 | 28 | // UnmarshalJSON unmarshals from JSON. 29 | func (a *AccountPendingTransactions) UnmarshalJSON(input []byte) error { 30 | type AccountPendingTransactions struct { 31 | PendingTransactions []types.Transaction `json:"pendingTransactions"` 32 | FirstTxStatus *TransactionStatus `json:"firstTxStatus,omitempty"` 33 | PendingCount *hexutil.Uint64 `json:"pendingCount"` 34 | } 35 | var dec AccountPendingTransactions 36 | if err := json.Unmarshal(input, &dec); err != nil { 37 | return err 38 | } 39 | if dec.PendingTransactions != nil { 40 | a.PendingTransactions = dec.PendingTransactions 41 | } 42 | if dec.FirstTxStatus != nil { 43 | a.FirstTxStatus = dec.FirstTxStatus 44 | } 45 | if dec.PendingCount != nil { 46 | a.PendingCount = uint64(*dec.PendingCount) 47 | } 48 | return nil 49 | } 50 | -------------------------------------------------------------------------------- /types/gen_block_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | "errors" 8 | "math/big" 9 | 10 | "github.com/ethereum/go-ethereum/common" 11 | "github.com/ethereum/go-ethereum/common/hexutil" 12 | "github.com/ethereum/go-ethereum/core/types" 13 | ) 14 | 15 | var _ = (*blockMarshaling)(nil) 16 | 17 | // MarshalJSON marshals as JSON. 18 | func (b Block) MarshalJSON() ([]byte, error) { 19 | type Block struct { 20 | Author *common.Address `json:"author,omitempty"` 21 | BaseFeePerGas *hexutil.Big `json:"baseFeePerGas,omitempty"` 22 | Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` 23 | ExtraData hexutil.Bytes `json:"extraData"` 24 | GasLimit hexutil.Uint64 `json:"gasLimit"` 25 | GasUsed hexutil.Uint64 `json:"gasUsed"` 26 | Hash common.Hash `json:"hash"` 27 | LogsBloom types.Bloom `json:"logsBloom"` 28 | Miner common.Address `json:"miner"` 29 | MixHash *common.Hash `json:"mixHash,omitempty"` 30 | Nonce *types.BlockNonce `json:"nonce,omitempty"` 31 | Number *hexutil.Big `json:"number" gencodec:"required"` 32 | ParentHash common.Hash `json:"parentHash"` 33 | ReceiptsRoot common.Hash `json:"receiptsRoot"` 34 | Size hexutil.Uint64 `json:"size"` 35 | StateRoot common.Hash `json:"stateRoot"` 36 | Timestamp hexutil.Uint64 `json:"timestamp"` 37 | TotalDifficulty *hexutil.Big `json:"totalDifficulty,omitempty"` 38 | Transactions TxOrHashList `json:"transactions"` 39 | TransactionsRoot common.Hash `json:"transactionsRoot"` 40 | Uncles []common.Hash `json:"uncles"` 41 | Sha3Uncles common.Hash `json:"sha3Uncles"` 42 | } 43 | var enc Block 44 | enc.Author = b.Author 45 | enc.BaseFeePerGas = (*hexutil.Big)(b.BaseFeePerGas) 46 | enc.Difficulty = (*hexutil.Big)(b.Difficulty) 47 | enc.ExtraData = b.ExtraData 48 | enc.GasLimit = hexutil.Uint64(b.GasLimit) 49 | enc.GasUsed = hexutil.Uint64(b.GasUsed) 50 | enc.Hash = b.Hash 51 | enc.LogsBloom = b.LogsBloom 52 | enc.Miner = b.Miner 53 | enc.MixHash = b.MixHash 54 | enc.Nonce = b.Nonce 55 | enc.Number = (*hexutil.Big)(b.Number) 56 | enc.ParentHash = b.ParentHash 57 | enc.ReceiptsRoot = b.ReceiptsRoot 58 | enc.Size = hexutil.Uint64(b.Size) 59 | enc.StateRoot = b.StateRoot 60 | enc.Timestamp = hexutil.Uint64(b.Timestamp) 61 | enc.TotalDifficulty = (*hexutil.Big)(b.TotalDifficulty) 62 | enc.Transactions = b.Transactions 63 | enc.TransactionsRoot = b.TransactionsRoot 64 | enc.Uncles = b.Uncles 65 | enc.Sha3Uncles = b.Sha3Uncles 66 | return json.Marshal(&enc) 67 | } 68 | 69 | // UnmarshalJSON unmarshals from JSON. 70 | func (b *Block) UnmarshalJSON(input []byte) error { 71 | type Block struct { 72 | Author *common.Address `json:"author,omitempty"` 73 | BaseFeePerGas *hexutil.Big `json:"baseFeePerGas,omitempty"` 74 | Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` 75 | ExtraData *hexutil.Bytes `json:"extraData"` 76 | GasLimit *hexutil.Uint64 `json:"gasLimit"` 77 | GasUsed *hexutil.Uint64 `json:"gasUsed"` 78 | Hash *common.Hash `json:"hash"` 79 | LogsBloom *types.Bloom `json:"logsBloom"` 80 | Miner *common.Address `json:"miner"` 81 | MixHash *common.Hash `json:"mixHash,omitempty"` 82 | Nonce *types.BlockNonce `json:"nonce,omitempty"` 83 | Number *hexutil.Big `json:"number" gencodec:"required"` 84 | ParentHash *common.Hash `json:"parentHash"` 85 | ReceiptsRoot *common.Hash `json:"receiptsRoot"` 86 | Size *hexutil.Uint64 `json:"size"` 87 | StateRoot *common.Hash `json:"stateRoot"` 88 | Timestamp *hexutil.Uint64 `json:"timestamp"` 89 | TotalDifficulty *hexutil.Big `json:"totalDifficulty,omitempty"` 90 | Transactions *TxOrHashList `json:"transactions"` 91 | TransactionsRoot *common.Hash `json:"transactionsRoot"` 92 | Uncles []common.Hash `json:"uncles"` 93 | Sha3Uncles *common.Hash `json:"sha3Uncles"` 94 | } 95 | var dec Block 96 | if err := json.Unmarshal(input, &dec); err != nil { 97 | return err 98 | } 99 | if dec.Author != nil { 100 | b.Author = dec.Author 101 | } 102 | if dec.BaseFeePerGas != nil { 103 | b.BaseFeePerGas = (*big.Int)(dec.BaseFeePerGas) 104 | } 105 | if dec.Difficulty == nil { 106 | return errors.New("missing required field 'difficulty' for Block") 107 | } 108 | b.Difficulty = (*big.Int)(dec.Difficulty) 109 | if dec.ExtraData != nil { 110 | b.ExtraData = *dec.ExtraData 111 | } 112 | if dec.GasLimit != nil { 113 | b.GasLimit = uint64(*dec.GasLimit) 114 | } 115 | if dec.GasUsed != nil { 116 | b.GasUsed = uint64(*dec.GasUsed) 117 | } 118 | if dec.Hash != nil { 119 | b.Hash = *dec.Hash 120 | } 121 | if dec.LogsBloom != nil { 122 | b.LogsBloom = *dec.LogsBloom 123 | } 124 | if dec.Miner != nil { 125 | b.Miner = *dec.Miner 126 | } 127 | if dec.MixHash != nil { 128 | b.MixHash = dec.MixHash 129 | } 130 | if dec.Nonce != nil { 131 | b.Nonce = dec.Nonce 132 | } 133 | if dec.Number == nil { 134 | return errors.New("missing required field 'number' for Block") 135 | } 136 | b.Number = (*big.Int)(dec.Number) 137 | if dec.ParentHash != nil { 138 | b.ParentHash = *dec.ParentHash 139 | } 140 | if dec.ReceiptsRoot != nil { 141 | b.ReceiptsRoot = *dec.ReceiptsRoot 142 | } 143 | if dec.Size != nil { 144 | b.Size = uint64(*dec.Size) 145 | } 146 | if dec.StateRoot != nil { 147 | b.StateRoot = *dec.StateRoot 148 | } 149 | if dec.Timestamp != nil { 150 | b.Timestamp = uint64(*dec.Timestamp) 151 | } 152 | if dec.TotalDifficulty != nil { 153 | b.TotalDifficulty = (*big.Int)(dec.TotalDifficulty) 154 | } 155 | if dec.Transactions != nil { 156 | b.Transactions = *dec.Transactions 157 | } 158 | if dec.TransactionsRoot != nil { 159 | b.TransactionsRoot = *dec.TransactionsRoot 160 | } 161 | if dec.Uncles != nil { 162 | b.Uncles = dec.Uncles 163 | } 164 | if dec.Sha3Uncles != nil { 165 | b.Sha3Uncles = *dec.Sha3Uncles 166 | } 167 | return nil 168 | } 169 | -------------------------------------------------------------------------------- /types/gen_call_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | "math/big" 8 | 9 | "github.com/ethereum/go-ethereum/common" 10 | "github.com/ethereum/go-ethereum/common/hexutil" 11 | ) 12 | 13 | var _ = (*callMarshaling)(nil) 14 | 15 | // MarshalJSON marshals as JSON. 16 | func (c Call) MarshalJSON() ([]byte, error) { 17 | type Call struct { 18 | From common.Address `json:"from"` 19 | To common.Address `json:"to"` 20 | Value *hexutil.Big `json:"value"` 21 | Gas *hexutil.Big `json:"gas"` 22 | Input hexutil.Bytes `json:"input"` 23 | CallType CallType `json:"callType"` 24 | } 25 | var enc Call 26 | enc.From = c.From 27 | enc.To = c.To 28 | enc.Value = (*hexutil.Big)(c.Value) 29 | enc.Gas = (*hexutil.Big)(c.Gas) 30 | enc.Input = c.Input 31 | enc.CallType = c.CallType 32 | return json.Marshal(&enc) 33 | } 34 | 35 | // UnmarshalJSON unmarshals from JSON. 36 | func (c *Call) UnmarshalJSON(input []byte) error { 37 | type Call struct { 38 | From *common.Address `json:"from"` 39 | To *common.Address `json:"to"` 40 | Value *hexutil.Big `json:"value"` 41 | Gas *hexutil.Big `json:"gas"` 42 | Input *hexutil.Bytes `json:"input"` 43 | CallType *CallType `json:"callType"` 44 | } 45 | var dec Call 46 | if err := json.Unmarshal(input, &dec); err != nil { 47 | return err 48 | } 49 | if dec.From != nil { 50 | c.From = *dec.From 51 | } 52 | if dec.To != nil { 53 | c.To = *dec.To 54 | } 55 | if dec.Value != nil { 56 | c.Value = (*big.Int)(dec.Value) 57 | } 58 | if dec.Gas != nil { 59 | c.Gas = (*big.Int)(dec.Gas) 60 | } 61 | if dec.Input != nil { 62 | c.Input = *dec.Input 63 | } 64 | if dec.CallType != nil { 65 | c.CallType = *dec.CallType 66 | } 67 | return nil 68 | } 69 | -------------------------------------------------------------------------------- /types/gen_call_result_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | "math/big" 8 | 9 | "github.com/ethereum/go-ethereum/common/hexutil" 10 | ) 11 | 12 | var _ = (*callResultMarshaling)(nil) 13 | 14 | // MarshalJSON marshals as JSON. 15 | func (c CallResult) MarshalJSON() ([]byte, error) { 16 | type CallResult struct { 17 | GasUsed *hexutil.Big `json:"gasUsed"` 18 | Output hexutil.Bytes `json:"output"` 19 | } 20 | var enc CallResult 21 | enc.GasUsed = (*hexutil.Big)(c.GasUsed) 22 | enc.Output = c.Output 23 | return json.Marshal(&enc) 24 | } 25 | 26 | // UnmarshalJSON unmarshals from JSON. 27 | func (c *CallResult) UnmarshalJSON(input []byte) error { 28 | type CallResult struct { 29 | GasUsed *hexutil.Big `json:"gasUsed"` 30 | Output *hexutil.Bytes `json:"output"` 31 | } 32 | var dec CallResult 33 | if err := json.Unmarshal(input, &dec); err != nil { 34 | return err 35 | } 36 | if dec.GasUsed != nil { 37 | c.GasUsed = (*big.Int)(dec.GasUsed) 38 | } 39 | if dec.Output != nil { 40 | c.Output = *dec.Output 41 | } 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /types/gen_create_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | "math/big" 8 | 9 | "github.com/ethereum/go-ethereum/common" 10 | "github.com/ethereum/go-ethereum/common/hexutil" 11 | ) 12 | 13 | var _ = (*createMarshaling)(nil) 14 | 15 | // MarshalJSON marshals as JSON. 16 | func (c Create) MarshalJSON() ([]byte, error) { 17 | type Create struct { 18 | From common.Address `json:"from"` 19 | Value *hexutil.Big `json:"value"` 20 | Gas *hexutil.Big `json:"gas"` 21 | Init hexutil.Bytes `json:"init"` 22 | CreateType *CreateType `json:"createType,omitempty"` 23 | } 24 | var enc Create 25 | enc.From = c.From 26 | enc.Value = (*hexutil.Big)(c.Value) 27 | enc.Gas = (*hexutil.Big)(c.Gas) 28 | enc.Init = c.Init 29 | enc.CreateType = c.CreateType 30 | return json.Marshal(&enc) 31 | } 32 | 33 | // UnmarshalJSON unmarshals from JSON. 34 | func (c *Create) UnmarshalJSON(input []byte) error { 35 | type Create struct { 36 | From *common.Address `json:"from"` 37 | Value *hexutil.Big `json:"value"` 38 | Gas *hexutil.Big `json:"gas"` 39 | Init *hexutil.Bytes `json:"init"` 40 | CreateType *CreateType `json:"createType,omitempty"` 41 | } 42 | var dec Create 43 | if err := json.Unmarshal(input, &dec); err != nil { 44 | return err 45 | } 46 | if dec.From != nil { 47 | c.From = *dec.From 48 | } 49 | if dec.Value != nil { 50 | c.Value = (*big.Int)(dec.Value) 51 | } 52 | if dec.Gas != nil { 53 | c.Gas = (*big.Int)(dec.Gas) 54 | } 55 | if dec.Init != nil { 56 | c.Init = *dec.Init 57 | } 58 | if dec.CreateType != nil { 59 | c.CreateType = dec.CreateType 60 | } 61 | return nil 62 | } 63 | -------------------------------------------------------------------------------- /types/gen_create_result_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | "math/big" 8 | 9 | "github.com/ethereum/go-ethereum/common" 10 | "github.com/ethereum/go-ethereum/common/hexutil" 11 | ) 12 | 13 | var _ = (*createResultMarshaling)(nil) 14 | 15 | // MarshalJSON marshals as JSON. 16 | func (c CreateResult) MarshalJSON() ([]byte, error) { 17 | type CreateResult struct { 18 | GasUsed *hexutil.Big `json:"gasUsed"` 19 | Code hexutil.Bytes `json:"code"` 20 | Address common.Address `json:"address"` 21 | } 22 | var enc CreateResult 23 | enc.GasUsed = (*hexutil.Big)(c.GasUsed) 24 | enc.Code = c.Code 25 | enc.Address = c.Address 26 | return json.Marshal(&enc) 27 | } 28 | 29 | // UnmarshalJSON unmarshals from JSON. 30 | func (c *CreateResult) UnmarshalJSON(input []byte) error { 31 | type CreateResult struct { 32 | GasUsed *hexutil.Big `json:"gasUsed"` 33 | Code *hexutil.Bytes `json:"code"` 34 | Address *common.Address `json:"address"` 35 | } 36 | var dec CreateResult 37 | if err := json.Unmarshal(input, &dec); err != nil { 38 | return err 39 | } 40 | if dec.GasUsed != nil { 41 | c.GasUsed = (*big.Int)(dec.GasUsed) 42 | } 43 | if dec.Code != nil { 44 | c.Code = *dec.Code 45 | } 46 | if dec.Address != nil { 47 | c.Address = *dec.Address 48 | } 49 | return nil 50 | } 51 | -------------------------------------------------------------------------------- /types/gen_eth_protocol_info_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | "math/big" 8 | 9 | "github.com/ethereum/go-ethereum/common/hexutil" 10 | ) 11 | 12 | var _ = (*ethProtocolInfoMarshaling)(nil) 13 | 14 | // MarshalJSON marshals as JSON. 15 | func (e EthProtocolInfo) MarshalJSON() ([]byte, error) { 16 | type EthProtocolInfo struct { 17 | Version uint32 `json:"version"` 18 | Difficulty *hexutil.Big `json:"difficulty"` 19 | Head string `json:"head"` 20 | } 21 | var enc EthProtocolInfo 22 | enc.Version = e.Version 23 | enc.Difficulty = (*hexutil.Big)(e.Difficulty) 24 | enc.Head = e.Head 25 | return json.Marshal(&enc) 26 | } 27 | 28 | // UnmarshalJSON unmarshals from JSON. 29 | func (e *EthProtocolInfo) UnmarshalJSON(input []byte) error { 30 | type EthProtocolInfo struct { 31 | Version *uint32 `json:"version"` 32 | Difficulty *hexutil.Big `json:"difficulty"` 33 | Head *string `json:"head"` 34 | } 35 | var dec EthProtocolInfo 36 | if err := json.Unmarshal(input, &dec); err != nil { 37 | return err 38 | } 39 | if dec.Version != nil { 40 | e.Version = *dec.Version 41 | } 42 | if dec.Difficulty != nil { 43 | e.Difficulty = (*big.Int)(dec.Difficulty) 44 | } 45 | if dec.Head != nil { 46 | e.Head = *dec.Head 47 | } 48 | return nil 49 | } 50 | -------------------------------------------------------------------------------- /types/gen_fee_history_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | "math/big" 8 | 9 | "github.com/ethereum/go-ethereum/common/hexutil" 10 | ) 11 | 12 | var _ = (*feeHistoryMarshaling)(nil) 13 | 14 | // MarshalJSON marshals as JSON. 15 | func (f FeeHistory) MarshalJSON() ([]byte, error) { 16 | type FeeHistory struct { 17 | OldestBlock *hexutil.Big `json:"oldestBlock"` 18 | Reward blockRewardsMarshaling `json:"reward,omitempty"` 19 | BaseFee []*hexutil.Big `json:"baseFeePerGas,omitempty"` 20 | GasUsedRatio []float64 `json:"gasUsedRatio"` 21 | BlobBaseFee []*hexutil.Big `json:"baseFeePerBlobGas,omitempty"` 22 | BlobGasUsedRatio []float64 `json:"blobGasUsedRatio,omitempty"` 23 | } 24 | var enc FeeHistory 25 | enc.OldestBlock = (*hexutil.Big)(f.OldestBlock) 26 | enc.Reward = f.Reward 27 | if f.BaseFee != nil { 28 | enc.BaseFee = make([]*hexutil.Big, len(f.BaseFee)) 29 | for k, v := range f.BaseFee { 30 | enc.BaseFee[k] = (*hexutil.Big)(v) 31 | } 32 | } 33 | enc.GasUsedRatio = f.GasUsedRatio 34 | if f.BlobBaseFee != nil { 35 | enc.BlobBaseFee = make([]*hexutil.Big, len(f.BlobBaseFee)) 36 | for k, v := range f.BlobBaseFee { 37 | enc.BlobBaseFee[k] = (*hexutil.Big)(v) 38 | } 39 | } 40 | enc.BlobGasUsedRatio = f.BlobGasUsedRatio 41 | return json.Marshal(&enc) 42 | } 43 | 44 | // UnmarshalJSON unmarshals from JSON. 45 | func (f *FeeHistory) UnmarshalJSON(input []byte) error { 46 | type FeeHistory struct { 47 | OldestBlock *hexutil.Big `json:"oldestBlock"` 48 | Reward *blockRewardsMarshaling `json:"reward,omitempty"` 49 | BaseFee []*hexutil.Big `json:"baseFeePerGas,omitempty"` 50 | GasUsedRatio []float64 `json:"gasUsedRatio"` 51 | BlobBaseFee []*hexutil.Big `json:"baseFeePerBlobGas,omitempty"` 52 | BlobGasUsedRatio []float64 `json:"blobGasUsedRatio,omitempty"` 53 | } 54 | var dec FeeHistory 55 | if err := json.Unmarshal(input, &dec); err != nil { 56 | return err 57 | } 58 | if dec.OldestBlock != nil { 59 | f.OldestBlock = (*big.Int)(dec.OldestBlock) 60 | } 61 | if dec.Reward != nil { 62 | f.Reward = *dec.Reward 63 | } 64 | if dec.BaseFee != nil { 65 | f.BaseFee = make([]*big.Int, len(dec.BaseFee)) 66 | for k, v := range dec.BaseFee { 67 | f.BaseFee[k] = (*big.Int)(v) 68 | } 69 | } 70 | if dec.GasUsedRatio != nil { 71 | f.GasUsedRatio = dec.GasUsedRatio 72 | } 73 | if dec.BlobBaseFee != nil { 74 | f.BlobBaseFee = make([]*big.Int, len(dec.BlobBaseFee)) 75 | for k, v := range dec.BlobBaseFee { 76 | f.BlobBaseFee[k] = (*big.Int)(v) 77 | } 78 | } 79 | if dec.BlobGasUsedRatio != nil { 80 | f.BlobGasUsedRatio = dec.BlobGasUsedRatio 81 | } 82 | return nil 83 | } 84 | -------------------------------------------------------------------------------- /types/gen_histogram_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | "math/big" 8 | 9 | "github.com/ethereum/go-ethereum/common/hexutil" 10 | ) 11 | 12 | var _ = (*histogramMarshaling)(nil) 13 | 14 | // MarshalJSON marshals as JSON. 15 | func (h Histogram) MarshalJSON() ([]byte, error) { 16 | type Histogram struct { 17 | BucketBounds []*hexutil.Big `json:"bucketBounds"` 18 | Counts []uint `json:"counts"` 19 | } 20 | var enc Histogram 21 | if h.BucketBounds != nil { 22 | enc.BucketBounds = make([]*hexutil.Big, len(h.BucketBounds)) 23 | for k, v := range h.BucketBounds { 24 | enc.BucketBounds[k] = (*hexutil.Big)(v) 25 | } 26 | } 27 | enc.Counts = h.Counts 28 | return json.Marshal(&enc) 29 | } 30 | 31 | // UnmarshalJSON unmarshals from JSON. 32 | func (h *Histogram) UnmarshalJSON(input []byte) error { 33 | type Histogram struct { 34 | BucketBounds []*hexutil.Big `json:"bucketBounds"` 35 | Counts []uint `json:"counts"` 36 | } 37 | var dec Histogram 38 | if err := json.Unmarshal(input, &dec); err != nil { 39 | return err 40 | } 41 | if dec.BucketBounds != nil { 42 | h.BucketBounds = make([]*big.Int, len(dec.BucketBounds)) 43 | for k, v := range dec.BucketBounds { 44 | h.BucketBounds[k] = (*big.Int)(v) 45 | } 46 | } 47 | if dec.Counts != nil { 48 | h.Counts = dec.Counts 49 | } 50 | return nil 51 | } 52 | -------------------------------------------------------------------------------- /types/gen_log_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | 8 | "github.com/ethereum/go-ethereum/common" 9 | "github.com/ethereum/go-ethereum/common/hexutil" 10 | ) 11 | 12 | var _ = (*logMarshaling)(nil) 13 | 14 | // MarshalJSON marshals as JSON. 15 | func (l Log) MarshalJSON() ([]byte, error) { 16 | type Log struct { 17 | Address common.Address `json:"address"` 18 | BlockHash common.Hash `json:"blockHash"` 19 | BlockNumber hexutil.Uint64 `json:"blockNumber"` 20 | Data hexutil.Bytes `json:"data"` 21 | Index hexutil.Uint `json:"logIndex"` 22 | LogType *string `json:"logType,omitempty"` 23 | Removed bool `json:"removed"` 24 | Topics []common.Hash `json:"topics"` 25 | TxHash common.Hash `json:"transactionHash"` 26 | TxIndex hexutil.Uint `json:"transactionIndex"` 27 | TransactionLogIndex *hexutil.Uint `json:"transactionLogIndex,omitempty"` 28 | } 29 | var enc Log 30 | enc.Address = l.Address 31 | enc.BlockHash = l.BlockHash 32 | enc.BlockNumber = hexutil.Uint64(l.BlockNumber) 33 | enc.Data = l.Data 34 | enc.Index = hexutil.Uint(l.Index) 35 | enc.LogType = l.LogType 36 | enc.Removed = l.Removed 37 | enc.Topics = l.Topics 38 | enc.TxHash = l.TxHash 39 | enc.TxIndex = hexutil.Uint(l.TxIndex) 40 | enc.TransactionLogIndex = (*hexutil.Uint)(l.TransactionLogIndex) 41 | return json.Marshal(&enc) 42 | } 43 | 44 | // UnmarshalJSON unmarshals from JSON. 45 | func (l *Log) UnmarshalJSON(input []byte) error { 46 | type Log struct { 47 | Address *common.Address `json:"address"` 48 | BlockHash *common.Hash `json:"blockHash"` 49 | BlockNumber *hexutil.Uint64 `json:"blockNumber"` 50 | Data *hexutil.Bytes `json:"data"` 51 | Index *hexutil.Uint `json:"logIndex"` 52 | LogType *string `json:"logType,omitempty"` 53 | Removed *bool `json:"removed"` 54 | Topics []common.Hash `json:"topics"` 55 | TxHash *common.Hash `json:"transactionHash"` 56 | TxIndex *hexutil.Uint `json:"transactionIndex"` 57 | TransactionLogIndex *hexutil.Uint `json:"transactionLogIndex,omitempty"` 58 | } 59 | var dec Log 60 | if err := json.Unmarshal(input, &dec); err != nil { 61 | return err 62 | } 63 | if dec.Address != nil { 64 | l.Address = *dec.Address 65 | } 66 | if dec.BlockHash != nil { 67 | l.BlockHash = *dec.BlockHash 68 | } 69 | if dec.BlockNumber != nil { 70 | l.BlockNumber = uint64(*dec.BlockNumber) 71 | } 72 | if dec.Data != nil { 73 | l.Data = *dec.Data 74 | } 75 | if dec.Index != nil { 76 | l.Index = uint(*dec.Index) 77 | } 78 | if dec.LogType != nil { 79 | l.LogType = dec.LogType 80 | } 81 | if dec.Removed != nil { 82 | l.Removed = *dec.Removed 83 | } 84 | if dec.Topics != nil { 85 | l.Topics = dec.Topics 86 | } 87 | if dec.TxHash != nil { 88 | l.TxHash = *dec.TxHash 89 | } 90 | if dec.TxIndex != nil { 91 | l.TxIndex = uint(*dec.TxIndex) 92 | } 93 | if dec.TransactionLogIndex != nil { 94 | l.TransactionLogIndex = (*uint)(dec.TransactionLogIndex) 95 | } 96 | return nil 97 | } 98 | -------------------------------------------------------------------------------- /types/gen_memory_diff_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | 8 | "github.com/ethereum/go-ethereum/common/hexutil" 9 | ) 10 | 11 | var _ = (*memoryDiffMarshaling)(nil) 12 | 13 | // MarshalJSON marshals as JSON. 14 | func (m MemoryDiff) MarshalJSON() ([]byte, error) { 15 | type MemoryDiff struct { 16 | Off uint `json:"off"` 17 | Data hexutil.Bytes `json:"data"` 18 | } 19 | var enc MemoryDiff 20 | enc.Off = m.Off 21 | enc.Data = m.Data 22 | return json.Marshal(&enc) 23 | } 24 | 25 | // UnmarshalJSON unmarshals from JSON. 26 | func (m *MemoryDiff) UnmarshalJSON(input []byte) error { 27 | type MemoryDiff struct { 28 | Off *uint `json:"off"` 29 | Data *hexutil.Bytes `json:"data"` 30 | } 31 | var dec MemoryDiff 32 | if err := json.Unmarshal(input, &dec); err != nil { 33 | return err 34 | } 35 | if dec.Off != nil { 36 | m.Off = *dec.Off 37 | } 38 | if dec.Data != nil { 39 | m.Data = *dec.Data 40 | } 41 | return nil 42 | } 43 | -------------------------------------------------------------------------------- /types/gen_plain_transaction_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | "errors" 8 | "math/big" 9 | 10 | "github.com/ethereum/go-ethereum/common" 11 | "github.com/ethereum/go-ethereum/common/hexutil" 12 | "github.com/ethereum/go-ethereum/core/types" 13 | ) 14 | 15 | var _ = (*plainTransactionMarshaling)(nil) 16 | 17 | // MarshalJSON marshals as JSON. 18 | func (t TransactionDetail) MarshalJSON() ([]byte, error) { 19 | type TransactionDetail struct { 20 | Accesses types.AccessList `json:"accessList,omitempty"` 21 | AuthorizationList []types.SetCodeAuthorization `json:"authorizationList,omitempty"` 22 | BlockHash *common.Hash `json:"blockHash"` 23 | BlockNumber *hexutil.Big `json:"blockNumber"` 24 | ChainID *hexutil.Big `json:"chainId,omitempty"` 25 | Creates *common.Address `json:"creates,omitempty" testomit:"false"` 26 | From common.Address `json:"from"` 27 | Gas hexutil.Uint64 `json:"gas" gencodec:"required"` 28 | GasPrice *hexutil.Big `json:"gasPrice"` 29 | Hash common.Hash `json:"hash"` 30 | Input hexutil.Bytes `json:"input" gencodec:"required"` 31 | MaxFeePerGas *hexutil.Big `json:"maxFeePerGas,omitempty"` 32 | MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` 33 | Nonce hexutil.Uint64 `json:"nonce" gencodec:"required"` 34 | PublicKey *hexutil.Bytes `json:"publicKey,omitempty" testomit:"false"` 35 | R *hexutil.Big `json:"r" gencodec:"required"` 36 | Raw *hexutil.Bytes `json:"raw,omitempty" testomit:"false"` 37 | S *hexutil.Big `json:"s" gencodec:"required"` 38 | StandardV *hexutil.Big `json:"standardV,omitempty"` 39 | Status *hexutil.Uint64 `json:"status,omitempty"` 40 | To *common.Address `json:"to" rlp:"nil"` 41 | TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` 42 | Type *hexutil.Uint64 `json:"type,omitempty"` 43 | V *hexutil.Big `json:"v" gencodec:"required"` 44 | Value *hexutil.Big `json:"value" gencodec:"required"` 45 | YParity *hexutil.Uint64 `json:"yParity,omitempty"` 46 | } 47 | var enc TransactionDetail 48 | enc.Accesses = t.Accesses 49 | enc.AuthorizationList = t.AuthorizationList 50 | enc.BlockHash = t.BlockHash 51 | enc.BlockNumber = (*hexutil.Big)(t.BlockNumber) 52 | enc.ChainID = (*hexutil.Big)(t.ChainID) 53 | enc.Creates = t.Creates 54 | enc.From = t.From 55 | enc.Gas = hexutil.Uint64(t.Gas) 56 | enc.GasPrice = (*hexutil.Big)(t.GasPrice) 57 | enc.Hash = t.Hash 58 | enc.Input = t.Input 59 | enc.MaxFeePerGas = (*hexutil.Big)(t.MaxFeePerGas) 60 | enc.MaxPriorityFeePerGas = (*hexutil.Big)(t.MaxPriorityFeePerGas) 61 | enc.Nonce = hexutil.Uint64(t.Nonce) 62 | enc.PublicKey = t.PublicKey 63 | enc.R = (*hexutil.Big)(t.R) 64 | enc.Raw = t.Raw 65 | enc.S = (*hexutil.Big)(t.S) 66 | enc.StandardV = (*hexutil.Big)(t.StandardV) 67 | enc.Status = (*hexutil.Uint64)(t.Status) 68 | enc.To = t.To 69 | enc.TransactionIndex = (*hexutil.Uint64)(t.TransactionIndex) 70 | enc.Type = (*hexutil.Uint64)(t.Type) 71 | enc.V = (*hexutil.Big)(t.V) 72 | enc.Value = (*hexutil.Big)(t.Value) 73 | enc.YParity = (*hexutil.Uint64)(t.YParity) 74 | return json.Marshal(&enc) 75 | } 76 | 77 | // UnmarshalJSON unmarshals from JSON. 78 | func (t *TransactionDetail) UnmarshalJSON(input []byte) error { 79 | type TransactionDetail struct { 80 | Accesses *types.AccessList `json:"accessList,omitempty"` 81 | AuthorizationList []types.SetCodeAuthorization `json:"authorizationList,omitempty"` 82 | BlockHash *common.Hash `json:"blockHash"` 83 | BlockNumber *hexutil.Big `json:"blockNumber"` 84 | ChainID *hexutil.Big `json:"chainId,omitempty"` 85 | Creates *common.Address `json:"creates,omitempty" testomit:"false"` 86 | From *common.Address `json:"from"` 87 | Gas *hexutil.Uint64 `json:"gas" gencodec:"required"` 88 | GasPrice *hexutil.Big `json:"gasPrice"` 89 | Hash *common.Hash `json:"hash"` 90 | Input *hexutil.Bytes `json:"input" gencodec:"required"` 91 | MaxFeePerGas *hexutil.Big `json:"maxFeePerGas,omitempty"` 92 | MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` 93 | Nonce *hexutil.Uint64 `json:"nonce" gencodec:"required"` 94 | PublicKey *hexutil.Bytes `json:"publicKey,omitempty" testomit:"false"` 95 | R *hexutil.Big `json:"r" gencodec:"required"` 96 | Raw *hexutil.Bytes `json:"raw,omitempty" testomit:"false"` 97 | S *hexutil.Big `json:"s" gencodec:"required"` 98 | StandardV *hexutil.Big `json:"standardV,omitempty"` 99 | Status *hexutil.Uint64 `json:"status,omitempty"` 100 | To *common.Address `json:"to" rlp:"nil"` 101 | TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` 102 | Type *hexutil.Uint64 `json:"type,omitempty"` 103 | V *hexutil.Big `json:"v" gencodec:"required"` 104 | Value *hexutil.Big `json:"value" gencodec:"required"` 105 | YParity *hexutil.Uint64 `json:"yParity,omitempty"` 106 | } 107 | var dec TransactionDetail 108 | if err := json.Unmarshal(input, &dec); err != nil { 109 | return err 110 | } 111 | if dec.Accesses != nil { 112 | t.Accesses = *dec.Accesses 113 | } 114 | if dec.AuthorizationList != nil { 115 | t.AuthorizationList = dec.AuthorizationList 116 | } 117 | if dec.BlockHash != nil { 118 | t.BlockHash = dec.BlockHash 119 | } 120 | if dec.BlockNumber != nil { 121 | t.BlockNumber = (*big.Int)(dec.BlockNumber) 122 | } 123 | if dec.ChainID != nil { 124 | t.ChainID = (*big.Int)(dec.ChainID) 125 | } 126 | if dec.Creates != nil { 127 | t.Creates = dec.Creates 128 | } 129 | if dec.From != nil { 130 | t.From = *dec.From 131 | } 132 | if dec.Gas == nil { 133 | return errors.New("missing required field 'gas' for TransactionDetail") 134 | } 135 | t.Gas = uint64(*dec.Gas) 136 | if dec.GasPrice != nil { 137 | t.GasPrice = (*big.Int)(dec.GasPrice) 138 | } 139 | if dec.Hash != nil { 140 | t.Hash = *dec.Hash 141 | } 142 | if dec.Input == nil { 143 | return errors.New("missing required field 'input' for TransactionDetail") 144 | } 145 | t.Input = *dec.Input 146 | if dec.MaxFeePerGas != nil { 147 | t.MaxFeePerGas = (*big.Int)(dec.MaxFeePerGas) 148 | } 149 | if dec.MaxPriorityFeePerGas != nil { 150 | t.MaxPriorityFeePerGas = (*big.Int)(dec.MaxPriorityFeePerGas) 151 | } 152 | if dec.Nonce == nil { 153 | return errors.New("missing required field 'nonce' for TransactionDetail") 154 | } 155 | t.Nonce = uint64(*dec.Nonce) 156 | if dec.PublicKey != nil { 157 | t.PublicKey = dec.PublicKey 158 | } 159 | if dec.R == nil { 160 | return errors.New("missing required field 'r' for TransactionDetail") 161 | } 162 | t.R = (*big.Int)(dec.R) 163 | if dec.Raw != nil { 164 | t.Raw = dec.Raw 165 | } 166 | if dec.S == nil { 167 | return errors.New("missing required field 's' for TransactionDetail") 168 | } 169 | t.S = (*big.Int)(dec.S) 170 | if dec.StandardV != nil { 171 | t.StandardV = (*big.Int)(dec.StandardV) 172 | } 173 | if dec.Status != nil { 174 | t.Status = (*uint64)(dec.Status) 175 | } 176 | if dec.To != nil { 177 | t.To = dec.To 178 | } 179 | if dec.TransactionIndex != nil { 180 | t.TransactionIndex = (*uint64)(dec.TransactionIndex) 181 | } 182 | if dec.Type != nil { 183 | t.Type = (*uint64)(dec.Type) 184 | } 185 | if dec.V == nil { 186 | return errors.New("missing required field 'v' for TransactionDetail") 187 | } 188 | t.V = (*big.Int)(dec.V) 189 | if dec.Value == nil { 190 | return errors.New("missing required field 'value' for TransactionDetail") 191 | } 192 | t.Value = (*big.Int)(dec.Value) 193 | if dec.YParity != nil { 194 | t.YParity = (*uint64)(dec.YParity) 195 | } 196 | return nil 197 | } 198 | -------------------------------------------------------------------------------- /types/gen_receipt_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | "math/big" 8 | 9 | "github.com/ethereum/go-ethereum/common" 10 | "github.com/ethereum/go-ethereum/common/hexutil" 11 | "github.com/ethereum/go-ethereum/core/types" 12 | ) 13 | 14 | var _ = (*receiptMarshaling)(nil) 15 | 16 | // MarshalJSON marshals as JSON. 17 | func (r Receipt) MarshalJSON() ([]byte, error) { 18 | type Receipt struct { 19 | BlockHash common.Hash `json:"blockHash"` 20 | BlockNumber hexutil.Uint64 `json:"blockNumber"` 21 | BurntGasFee *hexutil.Big `json:"burntGasFee,omitempty"` 22 | ContractAddress *common.Address `json:"contractAddress"` 23 | CumulativeGasUsed hexutil.Uint64 `json:"cumulativeGasUsed"` 24 | EffectiveGasPrice hexutil.Uint64 `json:"effectiveGasPrice"` 25 | From common.Address `json:"from"` 26 | GasUsed hexutil.Uint64 `json:"gasUsed"` 27 | Logs []*Log `json:"logs"` 28 | LogsBloom types.Bloom `json:"logsBloom"` 29 | Root hexutil.Bytes `json:"root,omitempty"` 30 | Status *hexutil.Uint64 `json:"status,omitempty"` 31 | To *common.Address `json:"to"` 32 | TransactionHash common.Hash `json:"transactionHash"` 33 | TransactionIndex hexutil.Uint64 `json:"transactionIndex"` 34 | TxExecErrorMsg *string `json:"txExecErrorMsg,omitempty" testomit:"false"` 35 | Type *hexutil.Uint64 `json:"type,omitempty"` 36 | } 37 | var enc Receipt 38 | enc.BlockHash = r.BlockHash 39 | enc.BlockNumber = hexutil.Uint64(r.BlockNumber) 40 | enc.BurntGasFee = (*hexutil.Big)(r.BurntGasFee) 41 | enc.ContractAddress = r.ContractAddress 42 | enc.CumulativeGasUsed = hexutil.Uint64(r.CumulativeGasUsed) 43 | enc.EffectiveGasPrice = hexutil.Uint64(r.EffectiveGasPrice) 44 | enc.From = r.From 45 | enc.GasUsed = hexutil.Uint64(r.GasUsed) 46 | enc.Logs = r.Logs 47 | enc.LogsBloom = r.LogsBloom 48 | enc.Root = r.Root 49 | enc.Status = (*hexutil.Uint64)(r.Status) 50 | enc.To = r.To 51 | enc.TransactionHash = r.TransactionHash 52 | enc.TransactionIndex = hexutil.Uint64(r.TransactionIndex) 53 | enc.TxExecErrorMsg = r.TxExecErrorMsg 54 | enc.Type = (*hexutil.Uint64)(r.Type) 55 | return json.Marshal(&enc) 56 | } 57 | 58 | // UnmarshalJSON unmarshals from JSON. 59 | func (r *Receipt) UnmarshalJSON(input []byte) error { 60 | type Receipt struct { 61 | BlockHash *common.Hash `json:"blockHash"` 62 | BlockNumber *hexutil.Uint64 `json:"blockNumber"` 63 | BurntGasFee *hexutil.Big `json:"burntGasFee,omitempty"` 64 | ContractAddress *common.Address `json:"contractAddress"` 65 | CumulativeGasUsed *hexutil.Uint64 `json:"cumulativeGasUsed"` 66 | EffectiveGasPrice *hexutil.Uint64 `json:"effectiveGasPrice"` 67 | From *common.Address `json:"from"` 68 | GasUsed *hexutil.Uint64 `json:"gasUsed"` 69 | Logs []*Log `json:"logs"` 70 | LogsBloom *types.Bloom `json:"logsBloom"` 71 | Root *hexutil.Bytes `json:"root,omitempty"` 72 | Status *hexutil.Uint64 `json:"status,omitempty"` 73 | To *common.Address `json:"to"` 74 | TransactionHash *common.Hash `json:"transactionHash"` 75 | TransactionIndex *hexutil.Uint64 `json:"transactionIndex"` 76 | TxExecErrorMsg *string `json:"txExecErrorMsg,omitempty" testomit:"false"` 77 | Type *hexutil.Uint64 `json:"type,omitempty"` 78 | } 79 | var dec Receipt 80 | if err := json.Unmarshal(input, &dec); err != nil { 81 | return err 82 | } 83 | if dec.BlockHash != nil { 84 | r.BlockHash = *dec.BlockHash 85 | } 86 | if dec.BlockNumber != nil { 87 | r.BlockNumber = uint64(*dec.BlockNumber) 88 | } 89 | if dec.BurntGasFee != nil { 90 | r.BurntGasFee = (*big.Int)(dec.BurntGasFee) 91 | } 92 | if dec.ContractAddress != nil { 93 | r.ContractAddress = dec.ContractAddress 94 | } 95 | if dec.CumulativeGasUsed != nil { 96 | r.CumulativeGasUsed = uint64(*dec.CumulativeGasUsed) 97 | } 98 | if dec.EffectiveGasPrice != nil { 99 | r.EffectiveGasPrice = uint64(*dec.EffectiveGasPrice) 100 | } 101 | if dec.From != nil { 102 | r.From = *dec.From 103 | } 104 | if dec.GasUsed != nil { 105 | r.GasUsed = uint64(*dec.GasUsed) 106 | } 107 | if dec.Logs != nil { 108 | r.Logs = dec.Logs 109 | } 110 | if dec.LogsBloom != nil { 111 | r.LogsBloom = *dec.LogsBloom 112 | } 113 | if dec.Root != nil { 114 | r.Root = *dec.Root 115 | } 116 | if dec.Status != nil { 117 | r.Status = (*uint64)(dec.Status) 118 | } 119 | if dec.To != nil { 120 | r.To = dec.To 121 | } 122 | if dec.TransactionHash != nil { 123 | r.TransactionHash = *dec.TransactionHash 124 | } 125 | if dec.TransactionIndex != nil { 126 | r.TransactionIndex = uint64(*dec.TransactionIndex) 127 | } 128 | if dec.TxExecErrorMsg != nil { 129 | r.TxExecErrorMsg = dec.TxExecErrorMsg 130 | } 131 | if dec.Type != nil { 132 | r.Type = (*uint64)(dec.Type) 133 | } 134 | return nil 135 | } 136 | -------------------------------------------------------------------------------- /types/gen_reward_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | "math/big" 8 | 9 | "github.com/ethereum/go-ethereum/common" 10 | "github.com/ethereum/go-ethereum/common/hexutil" 11 | ) 12 | 13 | var _ = (*rewardMarshaling)(nil) 14 | 15 | // MarshalJSON marshals as JSON. 16 | func (r Reward) MarshalJSON() ([]byte, error) { 17 | type Reward struct { 18 | Author common.Address `json:"author"` 19 | Value *hexutil.Big `json:"value"` 20 | RewardType RewardType `json:"rewardType"` 21 | } 22 | var enc Reward 23 | enc.Author = r.Author 24 | enc.Value = (*hexutil.Big)(r.Value) 25 | enc.RewardType = r.RewardType 26 | return json.Marshal(&enc) 27 | } 28 | 29 | // UnmarshalJSON unmarshals from JSON. 30 | func (r *Reward) UnmarshalJSON(input []byte) error { 31 | type Reward struct { 32 | Author *common.Address `json:"author"` 33 | Value *hexutil.Big `json:"value"` 34 | RewardType *RewardType `json:"rewardType"` 35 | } 36 | var dec Reward 37 | if err := json.Unmarshal(input, &dec); err != nil { 38 | return err 39 | } 40 | if dec.Author != nil { 41 | r.Author = *dec.Author 42 | } 43 | if dec.Value != nil { 44 | r.Value = (*big.Int)(dec.Value) 45 | } 46 | if dec.RewardType != nil { 47 | r.RewardType = *dec.RewardType 48 | } 49 | return nil 50 | } 51 | -------------------------------------------------------------------------------- /types/gen_storage_diff_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | "math/big" 8 | 9 | "github.com/ethereum/go-ethereum/common/hexutil" 10 | ) 11 | 12 | var _ = (*StorageDiffMarshaling)(nil) 13 | 14 | // MarshalJSON marshals as JSON. 15 | func (s StorageDiff) MarshalJSON() ([]byte, error) { 16 | type StorageDiff struct { 17 | Key *hexutil.Big `json:"key"` 18 | Val *hexutil.Big `json:"val"` 19 | } 20 | var enc StorageDiff 21 | enc.Key = (*hexutil.Big)(s.Key) 22 | enc.Val = (*hexutil.Big)(s.Val) 23 | return json.Marshal(&enc) 24 | } 25 | 26 | // UnmarshalJSON unmarshals from JSON. 27 | func (s *StorageDiff) UnmarshalJSON(input []byte) error { 28 | type StorageDiff struct { 29 | Key *hexutil.Big `json:"key"` 30 | Val *hexutil.Big `json:"val"` 31 | } 32 | var dec StorageDiff 33 | if err := json.Unmarshal(input, &dec); err != nil { 34 | return err 35 | } 36 | if dec.Key != nil { 37 | s.Key = (*big.Int)(dec.Key) 38 | } 39 | if dec.Val != nil { 40 | s.Val = (*big.Int)(dec.Val) 41 | } 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /types/gen_suicide_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | "math/big" 8 | 9 | "github.com/ethereum/go-ethereum/common" 10 | "github.com/ethereum/go-ethereum/common/hexutil" 11 | ) 12 | 13 | var _ = (*suicideMarshaling)(nil) 14 | 15 | // MarshalJSON marshals as JSON. 16 | func (s Suicide) MarshalJSON() ([]byte, error) { 17 | type Suicide struct { 18 | Address common.Address `json:"address"` 19 | RefundAddress common.Address `json:"refundAddress"` 20 | Balance *hexutil.Big `json:"balance"` 21 | } 22 | var enc Suicide 23 | enc.Address = s.Address 24 | enc.RefundAddress = s.RefundAddress 25 | enc.Balance = (*hexutil.Big)(s.Balance) 26 | return json.Marshal(&enc) 27 | } 28 | 29 | // UnmarshalJSON unmarshals from JSON. 30 | func (s *Suicide) UnmarshalJSON(input []byte) error { 31 | type Suicide struct { 32 | Address *common.Address `json:"address"` 33 | RefundAddress *common.Address `json:"refundAddress"` 34 | Balance *hexutil.Big `json:"balance"` 35 | } 36 | var dec Suicide 37 | if err := json.Unmarshal(input, &dec); err != nil { 38 | return err 39 | } 40 | if dec.Address != nil { 41 | s.Address = *dec.Address 42 | } 43 | if dec.RefundAddress != nil { 44 | s.RefundAddress = *dec.RefundAddress 45 | } 46 | if dec.Balance != nil { 47 | s.Balance = (*big.Int)(dec.Balance) 48 | } 49 | return nil 50 | } 51 | -------------------------------------------------------------------------------- /types/gen_trace_results_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | 8 | "github.com/ethereum/go-ethereum/common/hexutil" 9 | ) 10 | 11 | var _ = (*traceResultsMarshaling)(nil) 12 | 13 | // MarshalJSON marshals as JSON. 14 | func (t TraceResults) MarshalJSON() ([]byte, error) { 15 | type TraceResults struct { 16 | Output hexutil.Bytes `json:"output"` 17 | Trace []Trace `json:"trace"` 18 | VmTrace *VMTrace `json:"vmTrace"` 19 | StateDiff *StateDiff `json:"stateDiff"` 20 | } 21 | var enc TraceResults 22 | enc.Output = t.Output 23 | enc.Trace = t.Trace 24 | enc.VmTrace = t.VmTrace 25 | enc.StateDiff = t.StateDiff 26 | return json.Marshal(&enc) 27 | } 28 | 29 | // UnmarshalJSON unmarshals from JSON. 30 | func (t *TraceResults) UnmarshalJSON(input []byte) error { 31 | type TraceResults struct { 32 | Output *hexutil.Bytes `json:"output"` 33 | Trace []Trace `json:"trace"` 34 | VmTrace *VMTrace `json:"vmTrace"` 35 | StateDiff *StateDiff `json:"stateDiff"` 36 | } 37 | var dec TraceResults 38 | if err := json.Unmarshal(input, &dec); err != nil { 39 | return err 40 | } 41 | if dec.Output != nil { 42 | t.Output = *dec.Output 43 | } 44 | if dec.Trace != nil { 45 | t.Trace = dec.Trace 46 | } 47 | if dec.VmTrace != nil { 48 | t.VmTrace = dec.VmTrace 49 | } 50 | if dec.StateDiff != nil { 51 | t.StateDiff = dec.StateDiff 52 | } 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /types/gen_trace_results_with_transaction_hash_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | 8 | "github.com/ethereum/go-ethereum/common" 9 | "github.com/ethereum/go-ethereum/common/hexutil" 10 | ) 11 | 12 | var _ = (*traceResultsWithTransactionHashMarshaling)(nil) 13 | 14 | // MarshalJSON marshals as JSON. 15 | func (t TraceResultsWithTransactionHash) MarshalJSON() ([]byte, error) { 16 | type TraceResultsWithTransactionHash struct { 17 | Output hexutil.Bytes `json:"output"` 18 | Trace []Trace `json:"trace"` 19 | VmTrace *VMTrace `json:"vmTrace"` 20 | StateDiff *StateDiff `json:"stateDiff"` 21 | TransactionHash common.Hash `json:"transactionHash"` 22 | } 23 | var enc TraceResultsWithTransactionHash 24 | enc.Output = t.Output 25 | enc.Trace = t.Trace 26 | enc.VmTrace = t.VmTrace 27 | enc.StateDiff = t.StateDiff 28 | enc.TransactionHash = t.TransactionHash 29 | return json.Marshal(&enc) 30 | } 31 | 32 | // UnmarshalJSON unmarshals from JSON. 33 | func (t *TraceResultsWithTransactionHash) UnmarshalJSON(input []byte) error { 34 | type TraceResultsWithTransactionHash struct { 35 | Output *hexutil.Bytes `json:"output"` 36 | Trace []Trace `json:"trace"` 37 | VmTrace *VMTrace `json:"vmTrace"` 38 | StateDiff *StateDiff `json:"stateDiff"` 39 | TransactionHash *common.Hash `json:"transactionHash"` 40 | } 41 | var dec TraceResultsWithTransactionHash 42 | if err := json.Unmarshal(input, &dec); err != nil { 43 | return err 44 | } 45 | if dec.Output != nil { 46 | t.Output = *dec.Output 47 | } 48 | if dec.Trace != nil { 49 | t.Trace = dec.Trace 50 | } 51 | if dec.VmTrace != nil { 52 | t.VmTrace = dec.VmTrace 53 | } 54 | if dec.StateDiff != nil { 55 | t.StateDiff = dec.StateDiff 56 | } 57 | if dec.TransactionHash != nil { 58 | t.TransactionHash = *dec.TransactionHash 59 | } 60 | return nil 61 | } 62 | -------------------------------------------------------------------------------- /types/gen_value_filter_argument_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | "math/big" 8 | 9 | "github.com/ethereum/go-ethereum/common/hexutil" 10 | ) 11 | 12 | var _ = (*valueFilterArgumentMarshaling)(nil) 13 | 14 | // MarshalJSON marshals as JSON. 15 | func (v ValueFilterArgument) MarshalJSON() ([]byte, error) { 16 | type ValueFilterArgument struct { 17 | Eq *hexutil.Big `json:"eq,omitempty"` 18 | Lt *hexutil.Big `json:"lt,omitempty"` 19 | Gt *hexutil.Big `json:"gt,omitempty"` 20 | } 21 | var enc ValueFilterArgument 22 | enc.Eq = (*hexutil.Big)(v.Eq) 23 | enc.Lt = (*hexutil.Big)(v.Lt) 24 | enc.Gt = (*hexutil.Big)(v.Gt) 25 | return json.Marshal(&enc) 26 | } 27 | 28 | // UnmarshalJSON unmarshals from JSON. 29 | func (v *ValueFilterArgument) UnmarshalJSON(input []byte) error { 30 | type ValueFilterArgument struct { 31 | Eq *hexutil.Big `json:"eq,omitempty"` 32 | Lt *hexutil.Big `json:"lt,omitempty"` 33 | Gt *hexutil.Big `json:"gt,omitempty"` 34 | } 35 | var dec ValueFilterArgument 36 | if err := json.Unmarshal(input, &dec); err != nil { 37 | return err 38 | } 39 | if dec.Eq != nil { 40 | v.Eq = (*big.Int)(dec.Eq) 41 | } 42 | if dec.Lt != nil { 43 | v.Lt = (*big.Int)(dec.Lt) 44 | } 45 | if dec.Gt != nil { 46 | v.Gt = (*big.Int)(dec.Gt) 47 | } 48 | return nil 49 | } 50 | -------------------------------------------------------------------------------- /types/gen_vm_executed_operation_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | "math/big" 8 | 9 | "github.com/ethereum/go-ethereum/common/hexutil" 10 | ) 11 | 12 | var _ = (*vMExecutedOperationMarshaling)(nil) 13 | 14 | // MarshalJSON marshals as JSON. 15 | func (v VMExecutedOperation) MarshalJSON() ([]byte, error) { 16 | type VMExecutedOperation struct { 17 | Used uint64 `json:"used"` 18 | Push []*hexutil.Big `json:"push"` 19 | Mem *MemoryDiff `json:"mem"` 20 | Store *StorageDiff `json:"store"` 21 | } 22 | var enc VMExecutedOperation 23 | enc.Used = v.Used 24 | if v.Push != nil { 25 | enc.Push = make([]*hexutil.Big, len(v.Push)) 26 | for k, v := range v.Push { 27 | enc.Push[k] = (*hexutil.Big)(v) 28 | } 29 | } 30 | enc.Mem = v.Mem 31 | enc.Store = v.Store 32 | return json.Marshal(&enc) 33 | } 34 | 35 | // UnmarshalJSON unmarshals from JSON. 36 | func (v *VMExecutedOperation) UnmarshalJSON(input []byte) error { 37 | type VMExecutedOperation struct { 38 | Used *uint64 `json:"used"` 39 | Push []*hexutil.Big `json:"push"` 40 | Mem *MemoryDiff `json:"mem"` 41 | Store *StorageDiff `json:"store"` 42 | } 43 | var dec VMExecutedOperation 44 | if err := json.Unmarshal(input, &dec); err != nil { 45 | return err 46 | } 47 | if dec.Used != nil { 48 | v.Used = *dec.Used 49 | } 50 | if dec.Push != nil { 51 | v.Push = make([]*big.Int, len(dec.Push)) 52 | for k, _v := range dec.Push { 53 | v.Push[k] = (*big.Int)(_v) 54 | } 55 | } 56 | if dec.Mem != nil { 57 | v.Mem = dec.Mem 58 | } 59 | if dec.Store != nil { 60 | v.Store = dec.Store 61 | } 62 | return nil 63 | } 64 | -------------------------------------------------------------------------------- /types/gen_vm_trace_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/fjl/gencodec. DO NOT EDIT. 2 | 3 | package types 4 | 5 | import ( 6 | "encoding/json" 7 | 8 | "github.com/ethereum/go-ethereum/common/hexutil" 9 | ) 10 | 11 | var _ = (*vMTraceMarshaling)(nil) 12 | 13 | // MarshalJSON marshals as JSON. 14 | func (v VMTrace) MarshalJSON() ([]byte, error) { 15 | type VMTrace struct { 16 | Code hexutil.Bytes `json:"code"` 17 | Ops []VMOperation `json:"ops"` 18 | } 19 | var enc VMTrace 20 | enc.Code = v.Code 21 | enc.Ops = v.Ops 22 | return json.Marshal(&enc) 23 | } 24 | 25 | // UnmarshalJSON unmarshals from JSON. 26 | func (v *VMTrace) UnmarshalJSON(input []byte) error { 27 | type VMTrace struct { 28 | Code *hexutil.Bytes `json:"code"` 29 | Ops []VMOperation `json:"ops"` 30 | } 31 | var dec VMTrace 32 | if err := json.Unmarshal(input, &dec); err != nil { 33 | return err 34 | } 35 | if dec.Code != nil { 36 | v.Code = *dec.Code 37 | } 38 | if dec.Ops != nil { 39 | v.Ops = dec.Ops 40 | } 41 | return nil 42 | } 43 | -------------------------------------------------------------------------------- /types/geth_trace.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | "github.com/ethereum/go-ethereum/common/hexutil" 8 | 9 | "github.com/openweb3/web3go/types/enums" 10 | "github.com/pkg/errors" 11 | ) 12 | 13 | type GethTrace struct { 14 | Type enums.GethTraceType 15 | Default *DefaultFrame 16 | CallTracer *CallFrame 17 | FourByteTracer *FourByteFrame 18 | PreStateTracer *PreStateFrame 19 | NoopTracer *NoopFrame 20 | MuxTracer *MuxFrame 21 | Js interface{} 22 | } 23 | 24 | func (g GethTrace) MarshalJSON() ([]byte, error) { 25 | switch g.Type { 26 | case enums.GETH_TRACE_DEFAULT: 27 | return json.Marshal(g.Default) 28 | case enums.GETH_TRACE_CALL: 29 | return json.Marshal(g.CallTracer) 30 | case enums.GETH_TRACE_FOUR_BYTE: 31 | return json.Marshal(g.FourByteTracer) 32 | case enums.GETH_TRACE_PRE_STATE: 33 | return json.Marshal(g.PreStateTracer) 34 | case enums.GETH_TRACE_NOOP: 35 | return json.Marshal(g.NoopTracer) 36 | case enums.GETH_TRACE_MUX: 37 | return json.Marshal(g.MuxTracer) 38 | case enums.GETH_TRACE_JS: 39 | return json.Marshal(g.Js) 40 | default: 41 | return nil, errors.New("unknown trace type") 42 | } 43 | } 44 | 45 | func (g *GethTrace) UnmarshalJSON(data []byte) error { 46 | if g == nil { 47 | return errors.New("must specify the tracer type") 48 | } 49 | switch g.Type { 50 | case enums.GETH_TRACE_DEFAULT: 51 | return json.Unmarshal(data, &g.Default) 52 | case enums.GETH_TRACE_CALL: 53 | return json.Unmarshal(data, &g.CallTracer) 54 | case enums.GETH_TRACE_FOUR_BYTE: 55 | return json.Unmarshal(data, &g.FourByteTracer) 56 | case enums.GETH_TRACE_PRE_STATE: 57 | return json.Unmarshal(data, &g.PreStateTracer) 58 | case enums.GETH_TRACE_NOOP: 59 | return json.Unmarshal(data, &g.NoopTracer) 60 | case enums.GETH_TRACE_MUX: 61 | return json.Unmarshal(data, &g.MuxTracer) 62 | case enums.GETH_TRACE_JS: 63 | return json.Unmarshal(data, &g.Js) 64 | default: 65 | return errors.New("unknown tracer type") 66 | } 67 | } 68 | 69 | type DefaultFrame struct { 70 | Failed bool `json:"failed"` 71 | Gas uint64 `json:"gas"` 72 | ReturnValue string `json:"returnValue"` 73 | StructLogs []*StructLog `json:"structLogs"` 74 | } 75 | 76 | type StructLog struct { 77 | Depth uint64 `json:"depth"` 78 | Error *string `json:"error,omitempty"` 79 | Gas uint64 `json:"gas"` 80 | GasCost uint64 `json:"gasCost"` 81 | Memory []string `json:"memory,omitempty"` 82 | MemSize *uint64 `json:"memSize,omitempty"` 83 | Op string `json:"op"` 84 | Pc uint64 `json:"pc"` 85 | RefundCounter *uint64 `json:"refund,omitempty"` 86 | ReturnData *hexutil.Bytes `json:"returnData,omitempty"` 87 | Stack []*hexutil.Big `json:"stack,omitempty"` 88 | Storage *map[string]string `json:"storage,omitempty"` 89 | } 90 | 91 | type CallFrame struct { 92 | From common.Address `json:"from"` 93 | Gas *hexutil.Big `json:"gas,omitempty"` 94 | GasUsed *hexutil.Big `json:"gasUsed,omitempty"` 95 | To *common.Address `json:"to,omitempty"` 96 | Input *hexutil.Bytes `json:"input"` 97 | Output *hexutil.Bytes `json:"output,omitempty"` 98 | Error *string `json:"error,omitempty"` 99 | RevertReason *string `json:"revertReason,omitempty"` 100 | Calls []CallFrame `json:"calls,omitempty"` 101 | Logs []CallLogFrame `json:"logs,omitempty"` 102 | Value *hexutil.Big `json:"value,omitempty"` 103 | Type string `json:"type"` 104 | } 105 | 106 | type CallLogFrame struct { 107 | Address *common.Address `json:"address,omitempty"` 108 | Topics []common.Hash `json:"topics,omitempty"` 109 | Data *hexutil.Bytes `json:"data,omitempty"` 110 | } 111 | 112 | type FourByteFrame = map[string]uint64 113 | 114 | type PreStateFrame struct { 115 | // The default mode returns the accounts necessary to execute a given transaction. 116 | // 117 | // It re-executes the given transaction and tracks every part of state that is touched. 118 | Default *PreStateMode `json:"Default,omitempty"` 119 | // Diff mode returns the differences between the transaction's pre and post-state (i.e. what 120 | // changed because the transaction happened). 121 | Diff *DiffMode `json:"Diff,omitempty"` 122 | } 123 | 124 | // Includes all the account states necessary to execute a given transaction. 125 | // 126 | // This corresponds to the default mode of the [PreStateConfig]. 127 | // 128 | // The [AccountState]'s storage will include all touched slots of an account. 129 | type PreStateMode struct { 130 | Accounts map[string]AccountState `json:"Accounts"` 131 | } 132 | 133 | // Represents the account states before and after the transaction is executed. 134 | // 135 | // This corresponds to the [DiffMode] of the [PreStateConfig]. 136 | // 137 | // This will only contain changed [AccountState]s, created accounts will not be included in the pre 138 | // state and selfdestructed accounts will not be included in the post state. 139 | type DiffMode struct { 140 | // The account states after the transaction is executed. 141 | Post map[string]AccountState `json:"Post"` 142 | // The account states before the transaction is executed. 143 | Pre map[string]AccountState `json:"Pre"` 144 | } 145 | 146 | type AccountState struct { 147 | Balance *hexutil.Big `json:"balance,omitempty"` 148 | Code hexutil.Bytes `json:"code,omitempty"` 149 | Nonce *uint64 `json:"nonce,omitempty"` 150 | Storage map[common.Hash]common.Hash `json:"storage,omitempty"` 151 | } 152 | 153 | type NoopFrame struct { 154 | } 155 | 156 | type MuxFrame map[enums.GethDebugBuiltInTracerType]GethTrace 157 | -------------------------------------------------------------------------------- /types/geth_trace_option.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import "encoding/json" 4 | 5 | // GethDebugTracingOptions represents the tracing options for Geth debug tracing 6 | type GethDebugTracingOptions struct { 7 | GethDefaultTracingOptions 8 | Tracer string `json:"tracer,omitempty"` 9 | TracerConfig *GethDebugTracerConfig `json:"tracerConfig,omitempty"` 10 | Timeout *string `json:"timeout,omitempty"` 11 | } 12 | 13 | // GethDefaultTracingOptions represents the default tracing options for the struct logger 14 | type GethDefaultTracingOptions struct { 15 | EnableMemory *bool `json:"enableMemory,omitempty"` 16 | DisableMemory *bool `json:"disableMemory,omitempty"` 17 | DisableStack *bool `json:"disableStack,omitempty"` 18 | DisableStorage *bool `json:"disableStorage,omitempty"` 19 | EnableReturnData *bool `json:"enableReturnData,omitempty"` 20 | DisableReturnData *bool `json:"disableReturnData,omitempty"` 21 | Debug *bool `json:"debug,omitempty"` 22 | Limit *uint64 `json:"limit,omitempty"` 23 | } 24 | 25 | // GethDebugTracerConfig is a wrapper around json.RawMessage for tracer configuration 26 | type GethDebugTracerConfig struct { 27 | CallConfig *CallConfig 28 | PreStateConfig *PreStateConfig 29 | } 30 | 31 | func (g GethDebugTracerConfig) MarshalJSON() ([]byte, error) { 32 | if g.CallConfig != nil { 33 | return json.Marshal(g.CallConfig) 34 | } 35 | return json.Marshal(g.PreStateConfig) 36 | } 37 | 38 | func (g *GethDebugTracerConfig) UnmarshalJSON(data []byte) error { 39 | temp := struct { 40 | *CallConfig 41 | *PreStateConfig 42 | }{} 43 | 44 | if err := json.Unmarshal(data, &temp); err != nil { 45 | return err 46 | } 47 | 48 | *g = GethDebugTracerConfig{ 49 | CallConfig: temp.CallConfig, 50 | PreStateConfig: temp.PreStateConfig, 51 | } 52 | return nil 53 | } 54 | 55 | // CallConfig represents the configuration for the call tracer. 56 | type CallConfig struct { 57 | // OnlyTopCall, when set to true, will only trace the primary (top-level) call and not any sub-calls. 58 | // It eliminates the additional processing for each call frame. 59 | OnlyTopCall *bool `json:"onlyTopCall,omitempty"` 60 | 61 | // WithLog, when set to true, will include the logs emitted by the call. 62 | WithLog *bool `json:"withLog,omitempty"` 63 | } 64 | 65 | type PreStateConfig struct { 66 | /// If `diffMode` is set to true, the response frame includes all the account and storage diffs 67 | /// for the transaction. If it's missing or set to false it only returns the accounts and 68 | /// storage necessary to execute the transaction. 69 | DiffMode *bool `json:"diffMode,omitempty"` 70 | } 71 | -------------------------------------------------------------------------------- /types/geth_trace_result.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | "github.com/openweb3/web3go/types/enums" 8 | ) 9 | 10 | type GethTraceResult struct { 11 | TracerType enums.GethTraceType `json:"-"` 12 | Result *GethTrace `json:"result,omitempty"` 13 | Error *string `json:"error,omitempty"` 14 | TxHash *common.Hash `json:"txHash,omitempty"` 15 | } 16 | 17 | func (r *GethTraceResult) UnmarshalJSON(data []byte) error { 18 | 19 | type Alias GethTraceResult 20 | temp := struct { 21 | Alias 22 | Result any `json:"result,omitempty"` 23 | }{} 24 | 25 | if err := json.Unmarshal(data, &temp); err != nil { 26 | return err 27 | } 28 | 29 | if temp.Error != nil { 30 | r.Error = temp.Error 31 | r.TxHash = temp.TxHash 32 | return nil 33 | } else { 34 | r.Result = &GethTrace{Type: r.TracerType} 35 | b, _ := json.Marshal(temp.Result) 36 | return json.Unmarshal(b, &r.Result) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /types/geth_trace_result_test.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestUnmarshalJsonGethTraceResult(t *testing.T) { 11 | input := `{"result":{"failed":false,"gas":7397755,"returnValue":"","structLogs":[{"depth":1,"gas":8856328,"gasCost":3,"op":"PUSH4","pc":447,"stack":["0x16873099","0x16873099"]}]}}` 12 | 13 | var g GethTraceResult 14 | err := json.Unmarshal([]byte(input), &g) 15 | assert.NoError(t, err) 16 | 17 | j, _ := json.Marshal(g) 18 | assert.Equal(t, input, string(j)) 19 | } 20 | -------------------------------------------------------------------------------- /types/header.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | "github.com/ethereum/go-ethereum/common/hexutil" 8 | ethtypes "github.com/ethereum/go-ethereum/core/types" 9 | ) 10 | 11 | //go:generate gencodec -type Header -field-override headerMarshaling -out gen_header_json.go 12 | type Header struct { 13 | ethtypes.Header 14 | HeaderExtra 15 | } 16 | 17 | type HeaderExtra struct { 18 | Author *common.Address `json:"author,omitempty"` 19 | Hash *common.Hash `json:"hash,omitempty"` 20 | } 21 | 22 | func (h *Header) UnmarshalJSON(data []byte) error { 23 | var he HeaderExtra 24 | if err := json.Unmarshal(data, &he); err != nil { 25 | return err 26 | } 27 | 28 | var _h ethtypes.Header 29 | if err := json.Unmarshal(data, &_h); err != nil { 30 | return err 31 | } 32 | 33 | if he.Hash != nil { 34 | h.Header = _h 35 | h.HeaderExtra = he 36 | } else { 37 | h.Header = _h 38 | h.HeaderExtra.Hash = he.Hash 39 | } 40 | 41 | return nil 42 | } 43 | 44 | func (h Header) MarshalJSON() ([]byte, error) { 45 | type Header struct { 46 | ParentHash common.Hash `json:"parentHash" gencodec:"required"` 47 | UncleHash common.Hash `json:"sha3Uncles" gencodec:"required"` 48 | Coinbase common.Address `json:"miner" gencodec:"required"` 49 | Root common.Hash `json:"stateRoot" gencodec:"required"` 50 | TxHash common.Hash `json:"transactionsRoot" gencodec:"required"` 51 | ReceiptHash common.Hash `json:"receiptsRoot" gencodec:"required"` 52 | Bloom ethtypes.Bloom `json:"logsBloom" gencodec:"required"` 53 | Difficulty *hexutil.Big `json:"difficulty" gencodec:"required"` 54 | Number *hexutil.Big `json:"number" gencodec:"required"` 55 | GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` 56 | GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` 57 | Time hexutil.Uint64 `json:"timestamp" gencodec:"required"` 58 | Extra hexutil.Bytes `json:"extraData" gencodec:"required"` 59 | MixDigest common.Hash `json:"mixHash"` 60 | Nonce ethtypes.BlockNonce `json:"nonce"` 61 | BaseFee *hexutil.Big `json:"baseFeePerGas" rlp:"optional"` 62 | Hash *common.Hash `json:"hash,omitempty"` 63 | Author *common.Address `json:"author,omitempty"` 64 | } 65 | var enc Header 66 | enc.ParentHash = h.ParentHash 67 | enc.UncleHash = h.UncleHash 68 | enc.Coinbase = h.Coinbase 69 | enc.Root = h.Root 70 | enc.TxHash = h.TxHash 71 | enc.ReceiptHash = h.ReceiptHash 72 | enc.Bloom = h.Bloom 73 | enc.Difficulty = (*hexutil.Big)(h.Difficulty) 74 | enc.Number = (*hexutil.Big)(h.Number) 75 | enc.GasLimit = hexutil.Uint64(h.GasLimit) 76 | enc.GasUsed = hexutil.Uint64(h.GasUsed) 77 | enc.Time = hexutil.Uint64(h.Time) 78 | enc.Extra = h.Extra 79 | enc.MixDigest = h.MixDigest 80 | enc.Nonce = h.Nonce 81 | enc.BaseFee = (*hexutil.Big)(h.BaseFee) 82 | enc.Author = h.Author 83 | 84 | if h.HeaderExtra.Hash != nil { 85 | enc.Hash = h.HeaderExtra.Hash 86 | } else { 87 | _hash := h.Header.Hash() 88 | enc.Hash = &_hash 89 | } 90 | 91 | return json.Marshal(&enc) 92 | } 93 | -------------------------------------------------------------------------------- /types/header_test.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | func TestMarhsalHeader(t *testing.T) { 11 | expect := `{"parentHash":"0x286a356b438dfa21243799cd31cbd0d9a4f66c1c701ff36aa057ce338b444290","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","miner":"0x166d0ff7691030b0ca33d4e60e842cd300a3010d","stateRoot":"0xcc8d03c2f1f3ff92de2782a87ba538e60bfa185ec83b2b4be743adb7c5f8f73c","transactionsRoot":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","receiptsRoot":"0x09f8709ea9f344a810811a373b30861568f5686e649d6177fd92ea2db7477508","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x36482e1","number":"0x6a95094","gasLimit":"0x1c9c380","gasUsed":"0x0","timestamp":"0x63f2e8c7","extraData":"0x","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000000","baseFeePerGas":null,"hash":"0xce263bf1c206021cdf61bc983c6960ecc036db036a8eceea003563322da14177","author":"0x166d0ff7691030b0ca33d4e60e842cd300a3010d"}` 12 | 13 | var h Header 14 | err := json.Unmarshal([]byte(expect), &h) 15 | assert.NoError(t, err) 16 | 17 | actual, err := json.Marshal(&h) 18 | assert.NoError(t, err) 19 | 20 | assert.Equal(t, expect, string(actual)) 21 | } 22 | -------------------------------------------------------------------------------- /types/parity.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | "math/big" 6 | 7 | "github.com/ethereum/go-ethereum/common" 8 | "github.com/ethereum/go-ethereum/common/hexutil" 9 | ) 10 | 11 | // TODO: missing types: 12 | // LocalTransactionStatus 13 | // RichHeader 14 | // RichBlock 15 | type LocalTransactionStatus interface{} 16 | type RichHeader interface{} 17 | type RichBlock interface{} 18 | 19 | // TODO: struct is better 20 | type SemverVersion string 21 | 22 | // FIXME: need to confirm if the fields be camleCase when json marshal/unmarshal 23 | type ClientVersion struct { 24 | ParityClient ParityClientData `json:"ParityClient,omitempty"` 25 | ParityUnknownFormat string `json:"ParityUnknownFormat,omitempty"` 26 | Other string `json:"Other,omitempty"` 27 | } 28 | 29 | type ParityClientData struct { 30 | Name string `json:"name"` 31 | Identity *string `json:"identity"` 32 | Semver SemverVersion `json:"semver"` 33 | Os string `json:"os"` 34 | Compiler string `json:"compiler"` 35 | CanHandleLargeRequests bool `json:"canHandleLargeRequests"` 36 | } 37 | 38 | type Peers struct { 39 | Active uint `json:"active"` 40 | Connected uint `json:"connected"` 41 | Max uint32 `json:"max"` 42 | Peers []PeerInfo `json:"peers"` 43 | } 44 | type PeerInfo struct { 45 | Id *string `json:"id"` 46 | Name ClientVersion `json:"name"` 47 | Caps []string `json:"caps"` 48 | Network PeerNetworkInfo `json:"network"` 49 | Protocols PeerProtocolsInfo `json:"protocols"` 50 | } 51 | type PeerNetworkInfo struct { 52 | RemoteAddress string `json:"remoteAddress"` 53 | LocalAddress string `json:"localAddress"` 54 | } 55 | type PeerProtocolsInfo struct { 56 | Eth *EthProtocolInfo `json:"eth"` 57 | } 58 | 59 | //go:generate gencodec -type EthProtocolInfo -field-override ethProtocolInfoMarshaling -out gen_eth_protocol_info_json.go 60 | type EthProtocolInfo struct { 61 | Version uint32 `json:"version"` 62 | Difficulty *big.Int `json:"difficulty"` 63 | Head string `json:"head"` 64 | } 65 | 66 | type ethProtocolInfoMarshaling struct { 67 | Version uint32 `json:"version"` 68 | Difficulty *hexutil.Big `json:"difficulty"` 69 | Head string `json:"head"` 70 | } 71 | 72 | type RpcSettings struct { 73 | Enabled bool `json:"enabled"` 74 | Interface string `json:"interface"` 75 | Port uint64 `json:"port"` 76 | } 77 | 78 | //go:generate gencodec -type Histogram -field-override histogramMarshaling -out gen_histogram_json.go 79 | type Histogram struct { 80 | BucketBounds []*big.Int `json:"bucketBounds"` 81 | Counts []uint `json:"counts"` 82 | } 83 | 84 | type histogramMarshaling struct { 85 | BucketBounds []*hexutil.Big `json:"bucketBounds"` 86 | Counts []uint `json:"counts"` 87 | } 88 | 89 | type TransactionStats struct { 90 | FirstSeen uint64 `json:"firstSeen"` 91 | PropagatedTo map[string]uint `json:"propagatedTo"` 92 | } 93 | 94 | type ChainStatus struct { 95 | BlockGap BlockGap `json:"blockGap"` 96 | } 97 | 98 | type BlockGap struct { 99 | First *big.Int 100 | Last *big.Int 101 | } 102 | 103 | func (b BlockGap) MarshalJSON() ([]byte, error) { 104 | return json.Marshal([]interface{}{ 105 | (*hexutil.Big)(b.First), 106 | (*hexutil.Big)(b.Last), 107 | }) 108 | } 109 | 110 | func (b *BlockGap) UnmarshalJSON(data []byte) error { 111 | var fields [2]*hexutil.Big 112 | if err := json.Unmarshal(data, &fields); err != nil { 113 | return err 114 | } 115 | b.First = (*big.Int)(fields[0]) 116 | b.Last = (*big.Int)(fields[1]) 117 | return nil 118 | } 119 | 120 | type NodeKind struct { 121 | Capability string `json:"capability"` 122 | Availability string `json:"availability"` 123 | } 124 | 125 | type RecoveredAccount struct { 126 | Address common.Address `json:"address"` 127 | PublicKey string `json:"publicKey"` 128 | IsValidForCurrentChain bool `json:"isValidForCurrentChain"` 129 | } 130 | -------------------------------------------------------------------------------- /types/sync_status.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/ethereum/go-ethereum/common/hexutil" 7 | ) 8 | 9 | type SyncStatus struct { 10 | IsSyncing bool 11 | SyncInfo *SyncProgress 12 | } 13 | 14 | type SyncProgress struct { 15 | CurrentBlock hexutil.Uint64 `json:"currentBlock"` // Current block number where sync is at 16 | HighestBlock hexutil.Uint64 `json:"highestBlock"` // Highest alleged block number in the chain 17 | StartingBlock hexutil.Uint64 `json:"startingBlock"` // Block number where sync began 18 | } 19 | 20 | func (s *SyncStatus) UnmarshalJSON(data []byte) error { 21 | var isSyncing bool 22 | var e error 23 | if e = json.Unmarshal(data, &isSyncing); e == nil { 24 | s.IsSyncing = isSyncing 25 | return nil 26 | } 27 | 28 | var syncInfo SyncProgress 29 | if e = json.Unmarshal(data, &syncInfo); e == nil { 30 | s.IsSyncing = true 31 | s.SyncInfo = &syncInfo 32 | } 33 | return e 34 | } 35 | 36 | func (s SyncStatus) MarshalJSON() ([]byte, error) { 37 | if s.IsSyncing { 38 | return json.Marshal(s.SyncInfo) 39 | } 40 | return json.Marshal(s.IsSyncing) 41 | } 42 | -------------------------------------------------------------------------------- /types/trace.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "math/big" 7 | 8 | "github.com/ethereum/go-ethereum/common" 9 | "github.com/ethereum/go-ethereum/common/hexutil" 10 | "github.com/pkg/errors" 11 | ) 12 | 13 | type TraceOptions []string 14 | 15 | type TraceType string 16 | 17 | const ( 18 | TRACE_CALL = "call" 19 | TRACE_CREATE = "create" 20 | TRACE_SUICIDE = "suicide" 21 | TRACE_REWARD = "reward" 22 | ) 23 | 24 | type Trace struct { 25 | Type TraceType `json:"type"` 26 | Action interface{} `json:"action"` 27 | Result interface{} `json:"result,omitempty"` 28 | Error *string `json:"error,omitempty"` 29 | TraceAddress []uint `json:"traceAddress"` 30 | Subtraces uint `json:"subtraces"` 31 | } 32 | 33 | type LocalizedTrace struct { 34 | Type TraceType `json:"type"` 35 | Action interface{} `json:"action"` 36 | Result interface{} `json:"result,omitempty"` 37 | Error *string `json:"error,omitempty"` 38 | TraceAddress []uint `json:"traceAddress"` 39 | Subtraces uint `json:"subtraces"` 40 | TransactionPosition *uint `json:"transactionPosition"` 41 | TransactionHash *common.Hash `json:"transactionHash"` 42 | BlockNumber uint64 `json:"blockNumber"` 43 | BlockHash common.Hash `json:"blockHash"` 44 | Valid *bool `json:"valid,omitempty"` // exist in conflux-espace, not in openethereum 45 | } 46 | 47 | type StateDiff map[common.Hash]AccountDiff 48 | 49 | type TraceFilter struct { 50 | FromBlock *BlockNumber `json:"fromBlock"` 51 | ToBlock *BlockNumber `json:"toBlock"` 52 | FromAddress []common.Address `json:"fromAddress"` 53 | ToAddress []common.Address `json:"toAddress"` 54 | After *uint `json:"after"` 55 | Count *uint `json:"count"` 56 | } 57 | 58 | //go:generate gencodec -type TraceResults -field-override traceResultsMarshaling -out gen_trace_results_json.go 59 | type TraceResults struct { 60 | Output []byte `json:"output"` 61 | Trace []Trace `json:"trace"` 62 | VmTrace *VMTrace `json:"vmTrace"` 63 | StateDiff *StateDiff `json:"stateDiff"` 64 | } 65 | 66 | type traceResultsMarshaling struct { 67 | Output hexutil.Bytes `json:"output"` 68 | Trace []Trace `json:"trace"` 69 | VmTrace *VMTrace `json:"vmTrace"` 70 | StateDiff *StateDiff `json:"stateDiff"` 71 | } 72 | 73 | type VMOperation struct { 74 | Pc uint `json:"pc"` 75 | Cost uint64 `json:"cost"` 76 | Ex *VMExecutedOperation `json:"ex"` 77 | Sub *VMTrace `json:"sub"` 78 | } 79 | 80 | // gencodec -type VMExecutedOperation -field-override vMExecutedOperationMarshaling -out gen_vm_executed_operation_json.go 81 | type VMExecutedOperation struct { 82 | Used uint64 `json:"used"` 83 | Push []*big.Int `json:"push"` 84 | Mem *MemoryDiff `json:"mem"` 85 | Store *StorageDiff `json:"store"` 86 | } 87 | 88 | type vMExecutedOperationMarshaling struct { 89 | Used uint64 `json:"used"` 90 | Push []*hexutil.Big `json:"push"` 91 | Mem *MemoryDiff `json:"mem"` 92 | Store *StorageDiff `json:"store"` 93 | } 94 | 95 | //go:generate gencodec -type VMTrace -field-override vMTraceMarshaling -out gen_vm_trace_json.go 96 | type VMTrace struct { 97 | Code []byte `json:"code"` 98 | Ops []VMOperation `json:"ops"` 99 | } 100 | 101 | type vMTraceMarshaling struct { 102 | Code hexutil.Bytes `json:"code"` 103 | Ops []VMOperation `json:"ops"` 104 | } 105 | 106 | //go:generate gencodec -type TraceResultsWithTransactionHash -field-override traceResultsWithTransactionHashMarshaling -out gen_trace_results_with_transaction_hash_json.go 107 | type TraceResultsWithTransactionHash struct { 108 | Output []byte `json:"output"` 109 | Trace []Trace `json:"trace"` 110 | VmTrace *VMTrace `json:"vmTrace"` 111 | StateDiff *StateDiff `json:"stateDiff"` 112 | TransactionHash common.Hash `json:"transactionHash"` 113 | } 114 | 115 | type traceResultsWithTransactionHashMarshaling struct { 116 | Output hexutil.Bytes `json:"output"` 117 | Trace []Trace `json:"trace"` 118 | VmTrace *VMTrace `json:"vmTrace"` 119 | StateDiff *StateDiff `json:"stateDiff"` 120 | TransactionHash common.Hash `json:"transactionHash"` 121 | } 122 | 123 | //go:generate gencodec -type MemoryDiff -field-override memoryDiffMarshaling -out gen_memory_diff_json.go 124 | type MemoryDiff struct { 125 | Off uint `json:"off"` 126 | Data []byte `json:"data"` 127 | } 128 | 129 | type memoryDiffMarshaling struct { 130 | Off uint `json:"off"` 131 | Data hexutil.Bytes `json:"data"` 132 | } 133 | 134 | //go:generate gencodec -type StorageDiff -field-override StorageDiffMarshaling -out gen_storage_diff_json.go 135 | type StorageDiff struct { 136 | Key *big.Int `json:"key"` 137 | Val *big.Int `json:"val"` 138 | } 139 | 140 | type StorageDiffMarshaling struct { 141 | Key *hexutil.Big `json:"key"` 142 | Val *hexutil.Big `json:"val"` 143 | } 144 | 145 | type AccountDiff struct { 146 | Balance string `json:"balance"` 147 | Nonce string `json:"nonce"` 148 | Code string `json:"code"` 149 | Storage map[common.Hash]string `json:"storage"` 150 | } 151 | 152 | // UnmarshalJSON unmarshals Input and Init type from []byte to hexutil.Bytes 153 | func (l *Trace) UnmarshalJSON(data []byte) error { 154 | 155 | type alias Trace 156 | 157 | a := alias{} 158 | err := json.Unmarshal(data, &a) 159 | if err != nil { 160 | return err 161 | } 162 | *l = Trace(a) 163 | 164 | l.Action, l.Result, err = getActionAndResult(data) 165 | return err 166 | } 167 | 168 | func (l *LocalizedTrace) UnmarshalJSON(data []byte) error { 169 | type alias LocalizedTrace 170 | 171 | a := alias{} 172 | err := json.Unmarshal(data, &a) 173 | if err != nil { 174 | return err 175 | } 176 | *l = LocalizedTrace(a) 177 | 178 | l.Action, l.Result, err = getActionAndResult(data) 179 | return err 180 | } 181 | 182 | func getActionAndResult(data []byte) (interface{}, interface{}, error) { 183 | tmp := struct { 184 | Type TraceType `json:"type"` 185 | Action map[string]interface{} `json:"action"` 186 | Result map[string]interface{} `json:"result"` 187 | Error string `json:"error"` 188 | }{} 189 | 190 | err := json.Unmarshal(data, &tmp) 191 | if err != nil { 192 | return nil, nil, err 193 | } 194 | 195 | var action, result interface{} 196 | if action, err = parseAction(tmp.Action, tmp.Type); err != nil { 197 | return nil, nil, err 198 | } 199 | if result, err = parseActionResult(tmp.Result, tmp.Error, tmp.Type); err != nil { 200 | return nil, nil, err 201 | } 202 | 203 | return action, result, nil 204 | } 205 | 206 | func parseAction(actionInMap map[string]interface{}, actionType TraceType) (interface{}, error) { 207 | actionJson, err := json.Marshal(actionInMap) 208 | if err != nil { 209 | return nil, err 210 | } 211 | 212 | var result interface{} 213 | switch actionType { 214 | case TRACE_CALL: 215 | action := Call{} 216 | err = json.Unmarshal(actionJson, &action) 217 | result = action 218 | case TRACE_CREATE: 219 | action := Create{} 220 | err = json.Unmarshal(actionJson, &action) 221 | result = action 222 | case TRACE_SUICIDE: 223 | action := Suicide{} 224 | err = json.Unmarshal(actionJson, &action) 225 | result = action 226 | case TRACE_REWARD: 227 | action := Reward{} 228 | err = json.Unmarshal(actionJson, &action) 229 | result = action 230 | default: 231 | return nil, fmt.Errorf("unknown action type %v", actionType) 232 | } 233 | if err != nil { 234 | return nil, errors.Wrapf(err, "failed to unmarshal %v to %v ", string(actionJson), actionType) 235 | } 236 | return result, nil 237 | } 238 | 239 | // parseActionResult parses action result, result will be nil if actionError not empty 240 | // one-to-one mapping between action result type and action type 241 | // action type TRACE_CALL => CallResult 242 | // action type TRACE_CREATE => CreateResult 243 | // action type TRACE_SUICIDE => uint8(0) 244 | // action type TRACE_REWARD => uint8(0) 245 | func parseActionResult(actionResInMap map[string]interface{}, actionError string, actionType TraceType) (interface{}, error) { 246 | if actionError != "" { 247 | return nil, nil 248 | } 249 | 250 | actionResJson, err := json.Marshal(actionResInMap) 251 | if err != nil { 252 | return nil, err 253 | } 254 | 255 | var result interface{} 256 | switch actionType { 257 | case TRACE_CALL: 258 | action := CallResult{} 259 | err = json.Unmarshal(actionResJson, &action) 260 | result = action 261 | case TRACE_CREATE: 262 | action := CreateResult{} 263 | err = json.Unmarshal(actionResJson, &action) 264 | result = action 265 | case TRACE_SUICIDE: 266 | fallthrough 267 | case TRACE_REWARD: 268 | var action uint8 269 | err = json.Unmarshal(actionResJson, &action) 270 | result = action 271 | 272 | default: 273 | return nil, fmt.Errorf("unknown action type %v", actionType) 274 | } 275 | if err != nil { 276 | return nil, errors.Wrapf(err, "failed to unmarshal %v to %v ", string(actionResJson), actionType) 277 | } 278 | return result, nil 279 | } 280 | -------------------------------------------------------------------------------- /types/transaction_args.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "fmt" 5 | "math/big" 6 | 7 | "github.com/ethereum/go-ethereum/common" 8 | "github.com/ethereum/go-ethereum/common/hexutil" 9 | "github.com/ethereum/go-ethereum/core/types" 10 | 11 | "github.com/openweb3/go-rpc-provider" 12 | 13 | "github.com/pkg/errors" 14 | ) 15 | 16 | type ReaderForPopulate interface { 17 | ChainId() (val *uint64, err error) 18 | GasPrice() (val *big.Int, err error) 19 | MaxPriorityFeePerGas() (val *big.Int, err error) 20 | EstimateGas(callRequest CallRequest, blockNum *BlockNumberOrHash) (val *big.Int, err error) 21 | TransactionCount(addr common.Address, blockNum *BlockNumberOrHash) (val *big.Int, err error) 22 | BlockByNumber(blockNumber BlockNumber, isFull bool) (val *Block, err error) 23 | } 24 | 25 | type TransactionArgs struct { 26 | From *common.Address `json:"from"` 27 | To *common.Address `json:"to"` 28 | Gas *hexutil.Uint64 `json:"gas"` 29 | GasPrice *hexutil.Big `json:"gasPrice,omitempty"` 30 | MaxFeePerGas *hexutil.Big `json:"maxFeePerGas,omitempty"` 31 | MaxPriorityFeePerGas *hexutil.Big `json:"maxPriorityFeePerGas,omitempty"` 32 | Value *hexutil.Big `json:"value"` 33 | Nonce *hexutil.Uint64 `json:"nonce"` 34 | 35 | // use pointer to keep same with go-ethereum behavior, because nil *hexutil.Bytes will be marshaled to nil, 36 | // but nil hexutil.Bytes will be marshaled to '0x' 37 | Data *hexutil.Bytes `json:"data"` 38 | 39 | // Introduced by AccessListTxType transaction. 40 | AccessList *types.AccessList `json:"accessList,omitempty"` 41 | AuthorizationList []types.SetCodeAuthorization `json:"authorizationList,omitempty"` 42 | ChainID *hexutil.Big `json:"chainId,omitempty"` 43 | 44 | TxType *uint8 `json:"type"` 45 | } 46 | 47 | // data retrieves the transaction calldata. Input field is preferred. 48 | func (args *TransactionArgs) data() []byte { 49 | if args.Data != nil { 50 | return *args.Data 51 | } 52 | return nil 53 | } 54 | 55 | // ToTransaction converts the arguments to a transaction. 56 | // This assumes that setDefaults has been called. 57 | func (args *TransactionArgs) ToTransaction() (*types.Transaction, error) { 58 | 59 | if args.Nonce == nil || args.Gas == nil { 60 | return nil, errors.New("nonce and gas are required") 61 | } 62 | 63 | al := types.AccessList{} 64 | if args.AccessList != nil { 65 | al = *args.AccessList 66 | } 67 | 68 | genDynamicFeeTx := func() types.TxData { 69 | return &types.DynamicFeeTx{ 70 | To: args.To, 71 | ChainID: (*big.Int)(args.ChainID), 72 | Nonce: uint64(*args.Nonce), 73 | Gas: uint64(*args.Gas), 74 | GasFeeCap: (*big.Int)(args.MaxFeePerGas), 75 | GasTipCap: (*big.Int)(args.MaxPriorityFeePerGas), 76 | Value: (*big.Int)(args.Value), 77 | Data: args.data(), 78 | AccessList: al, 79 | } 80 | } 81 | 82 | genAccessListTx := func() types.TxData { 83 | return &types.AccessListTx{ 84 | To: args.To, 85 | ChainID: (*big.Int)(args.ChainID), 86 | Nonce: uint64(*args.Nonce), 87 | Gas: uint64(*args.Gas), 88 | GasPrice: (*big.Int)(args.GasPrice), 89 | Value: (*big.Int)(args.Value), 90 | Data: args.data(), 91 | AccessList: al, 92 | } 93 | } 94 | 95 | genLegacyTx := func() types.TxData { 96 | return &types.LegacyTx{ 97 | To: args.To, 98 | Nonce: uint64(*args.Nonce), 99 | Gas: uint64(*args.Gas), 100 | GasPrice: (*big.Int)(args.GasPrice), 101 | Value: (*big.Int)(args.Value), 102 | Data: args.data(), 103 | } 104 | } 105 | 106 | genSetCodeTx := func() types.TxData { 107 | return &types.SetCodeTx{ 108 | ChainID: BigIntToUint256(args.ChainID.ToInt()), 109 | Nonce: uint64(*args.Nonce), 110 | GasTipCap: BigIntToUint256(args.MaxPriorityFeePerGas.ToInt()), 111 | GasFeeCap: BigIntToUint256(args.MaxFeePerGas.ToInt()), 112 | Gas: uint64(*args.Gas), 113 | To: *args.To, 114 | Value: BigIntToUint256(args.Value.ToInt()), 115 | Data: args.data(), 116 | AccessList: al, 117 | AuthList: args.AuthorizationList, 118 | } 119 | } 120 | 121 | switch *args.TxType { 122 | case types.LegacyTxType: 123 | return types.NewTx(genLegacyTx()), nil 124 | case types.AccessListTxType: 125 | return types.NewTx(genAccessListTx()), nil 126 | case types.DynamicFeeTxType: 127 | return types.NewTx(genDynamicFeeTx()), nil 128 | case types.SetCodeTxType: 129 | return types.NewTx(genSetCodeTx()), nil 130 | } 131 | 132 | return nil, errors.New("unknown transaction type") 133 | } 134 | 135 | func (args *TransactionArgs) Populate(reader ReaderForPopulate) error { 136 | 137 | if args.From == nil { 138 | return errors.New("from is required") 139 | } 140 | 141 | if err := args.populateTxtypeAndGasPrice(reader); err != nil { 142 | return errors.Wrap(err, "failed to populate gas price") 143 | } 144 | 145 | if args.Value == nil { 146 | args.Value = new(hexutil.Big) 147 | } 148 | 149 | // try get pending nonce first, if failed, try get nonce of latest block 150 | if args.Nonce == nil { 151 | pending := BlockNumberOrHashWithNumber(PendingBlockNumber) 152 | nonce, err := reader.TransactionCount(*args.From, &pending) 153 | if err != nil { 154 | nonce, err = reader.TransactionCount(*args.From, nil) 155 | if err != nil { 156 | return errors.Wrap(err, "failed to get nonce of both pending and latest block") 157 | } 158 | } 159 | temp := nonce.Uint64() 160 | args.Nonce = (*hexutil.Uint64)(&temp) 161 | } 162 | 163 | if args.To == nil && len(args.data()) == 0 { 164 | return errors.New(`contract creation without any data provided`) 165 | } 166 | // Estimate the gas usage if necessary. 167 | if args.Gas == nil { 168 | // These fields are immutable during the estimation, safe to 169 | // pass the pointer directly. 170 | data := args.data() 171 | callArgs := CallRequest{ 172 | From: args.From, 173 | To: args.To, 174 | GasPrice: (*big.Int)(args.GasPrice), 175 | MaxFeePerGas: (*big.Int)(args.MaxFeePerGas), 176 | MaxPriorityFeePerGas: (*big.Int)(args.MaxPriorityFeePerGas), 177 | Value: (*big.Int)(args.Value), 178 | Data: data, 179 | AccessList: args.AccessList, 180 | } 181 | 182 | latest := BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) 183 | estimated, err := reader.EstimateGas(callArgs, &latest) 184 | if err != nil { 185 | return errors.Wrap(err, "failed to estimate") 186 | } 187 | 188 | temp := estimated.Uint64() 189 | args.Gas = (*hexutil.Uint64)(&temp) 190 | } 191 | if args.ChainID == nil { 192 | id, err := reader.ChainId() 193 | if err != nil { 194 | return errors.Wrap(err, "failed to get chaind") 195 | } 196 | temp := big.NewInt(0).SetUint64(*id) 197 | args.ChainID = (*hexutil.Big)(temp) 198 | } 199 | return nil 200 | } 201 | 202 | func (args *TransactionArgs) populateTxtypeAndGasPrice(reader ReaderForPopulate) error { 203 | if args.GasPrice != nil && (args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil) { 204 | return errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified") 205 | } 206 | 207 | if args.GasPrice != nil && (args.TxType == nil || *args.TxType == types.LegacyTxType) { 208 | args.TxType = TxTypePtr(types.LegacyTxType) 209 | return nil 210 | } 211 | 212 | has1559 := args.MaxFeePerGas != nil || args.MaxPriorityFeePerGas != nil 213 | 214 | // nullType := uint8(255) 215 | // argsTxType := nullType 216 | // if args.TxType != nil { 217 | // argsTxType = uint8(*args.TxType) 218 | // } 219 | 220 | gasFeeData, err := getFeeData(reader) 221 | if err != nil { 222 | return errors.Wrap(err, "failed to get fee data") 223 | } 224 | 225 | // set the txtype according to feeData 226 | // - if support1559, then set txtype to 2 227 | // - if not support1559 228 | // - - if has maxFeePerGas or maxPriorityFeePerGas, then return error 229 | // - - if contains accesslist, set txtype to 1 230 | // - - else set txtype to 0 231 | if args.TxType == nil { 232 | if gasFeeData.isSupport1559() { 233 | args.TxType = TxTypePtr(types.DynamicFeeTxType) 234 | } else { 235 | if has1559 { 236 | return errors.New("not support 1559 but (maxFeePerGas or maxPriorityFeePerGas) specified") 237 | } 238 | 239 | if args.AccessList == nil { 240 | args.TxType = TxTypePtr(types.LegacyTxType) 241 | } else { 242 | args.TxType = TxTypePtr(types.AccessListTxType) 243 | } 244 | } 245 | } 246 | 247 | // if txtype is DynamicFeeTxType that means support 1559, so if gasPrice is not nil, set max... to gasPrice 248 | if *args.TxType == types.DynamicFeeTxType { 249 | if args.GasPrice != nil { 250 | args.MaxFeePerGas = args.GasPrice 251 | args.MaxPriorityFeePerGas = args.GasPrice 252 | args.GasPrice = nil 253 | return nil 254 | } 255 | 256 | if args.MaxPriorityFeePerGas == nil { 257 | args.MaxPriorityFeePerGas = (*hexutil.Big)(gasFeeData.maxPriorityFeePerGas) 258 | } 259 | if args.MaxFeePerGas == nil { 260 | args.MaxFeePerGas = (*hexutil.Big)(gasFeeData.maxFeePerGas) 261 | } 262 | if args.MaxFeePerGas.ToInt().Cmp(args.MaxPriorityFeePerGas.ToInt()) < 0 { 263 | return fmt.Errorf("maxFeePerGas (%v) < maxPriorityFeePerGas (%v)", args.MaxFeePerGas, args.MaxPriorityFeePerGas) 264 | } 265 | return nil 266 | } 267 | 268 | if args.GasPrice != nil { 269 | return nil 270 | } 271 | 272 | args.GasPrice = (*hexutil.Big)(gasFeeData.gasPrice) 273 | return nil 274 | } 275 | 276 | // ToTransaction converts the arguments to a transaction. 277 | // This assumes that Populate has been called. 278 | func (args *TransactionArgs) PopulateAndToTransaction(reader ReaderForPopulate) (*types.Transaction, error) { 279 | if err := args.Populate(reader); err != nil { 280 | return nil, err 281 | } 282 | return args.ToTransaction() 283 | } 284 | 285 | func ConvertTransactionToArgs(from common.Address, tx Transaction) *TransactionArgs { 286 | args := &TransactionArgs{} 287 | 288 | txType := tx.Type() 289 | args.TxType = &txType 290 | 291 | args.From = &from 292 | args.To = tx.To() 293 | 294 | nonce := tx.Nonce() 295 | if nonce != 0 { 296 | args.Nonce = (*hexutil.Uint64)(&nonce) 297 | } 298 | 299 | gas := tx.Gas() 300 | if gas != 0 { 301 | args.Gas = (*hexutil.Uint64)(&gas) 302 | } 303 | 304 | args.Value = (*hexutil.Big)(tx.Value()) 305 | 306 | data := tx.Data() 307 | args.Data = (*hexutil.Bytes)(&data) 308 | 309 | switch tx.Type() { 310 | case types.LegacyTxType: 311 | if tx.GasPrice().Cmp(big.NewInt(0)) != 0 { 312 | args.GasPrice = (*hexutil.Big)(tx.GasPrice()) 313 | } 314 | case types.SetCodeTxType: 315 | 316 | args.AuthorizationList = tx.SetCodeAuthorizations() 317 | fallthrough 318 | case types.DynamicFeeTxType: 319 | if tx.GasTipCap().Cmp(big.NewInt(0)) != 0 { 320 | args.MaxPriorityFeePerGas = (*hexutil.Big)(tx.GasTipCap()) 321 | } 322 | if tx.GasFeeCap().Cmp(big.NewInt(0)) != 0 { 323 | args.MaxFeePerGas = (*hexutil.Big)(tx.GasFeeCap()) 324 | } 325 | fallthrough 326 | case types.AccessListTxType: 327 | al := tx.AccessList() 328 | args.AccessList = &al 329 | if tx.ChainId().Cmp(big.NewInt(0)) != 0 { 330 | args.ChainID = (*hexutil.Big)(tx.ChainId()) 331 | } 332 | } 333 | return args 334 | } 335 | -------------------------------------------------------------------------------- /types/transaction_args_test.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "math/big" 7 | "testing" 8 | 9 | "github.com/ethereum/go-ethereum/common" 10 | "github.com/ethereum/go-ethereum/common/hexutil" 11 | ethrpctypes "github.com/ethereum/go-ethereum/core/types" 12 | "github.com/stretchr/testify/assert" 13 | ) 14 | 15 | type mockPopulateReader struct{} 16 | 17 | func (m *mockPopulateReader) ChainId() (val *uint64, err error) { 18 | chainId := uint64(0x12) //18 19 | return &chainId, nil 20 | } 21 | 22 | func (m *mockPopulateReader) GasPrice() (val *big.Int, err error) { 23 | return big.NewInt(0x1c), nil //28 24 | } 25 | 26 | func (m *mockPopulateReader) MaxPriorityFeePerGas() (val *big.Int, err error) { 27 | return big.NewInt(0x1e), nil //30 28 | } 29 | 30 | func (m *mockPopulateReader) EstimateGas(callRequest CallRequest, blockNum *BlockNumberOrHash) (val *big.Int, err error) { 31 | return big.NewInt(0x26), nil //38 32 | } 33 | 34 | func (m *mockPopulateReader) TransactionCount(addr common.Address, blockNum *BlockNumberOrHash) (val *big.Int, err error) { 35 | return big.NewInt(0x30), nil //48 36 | } 37 | 38 | func (m *mockPopulateReader) BlockByNumber(num BlockNumber, isFull bool) (val *Block, err error) { 39 | return &Block{BaseFeePerGas: big.NewInt(0x3a)}, nil //58 40 | } 41 | 42 | func TestConvertDynamicFeeTxToArgs(t *testing.T) { 43 | dtx := ðrpctypes.DynamicFeeTx{} 44 | 45 | actual := ConvertTransactionToArgs(common.Address{}, *ethrpctypes.NewTx(dtx)) 46 | expect := `{"from":"0x0000000000000000000000000000000000000000","to":null,"gas":null,"value":"0x0","nonce":null,"data":"0x","accessList":[],"type":2}` 47 | 48 | argsJ, _ := json.Marshal(actual) 49 | assert.Equal(t, expect, string(argsJ)) 50 | } 51 | 52 | func TestConvertLegacyTxToArgs(t *testing.T) { 53 | dtx := ðrpctypes.LegacyTx{} 54 | 55 | actual := ConvertTransactionToArgs(common.Address{}, *ethrpctypes.NewTx(dtx)) 56 | expect := `{"from":"0x0000000000000000000000000000000000000000","to":null,"gas":null,"value":"0x0","nonce":null,"data":"0x","type":0}` 57 | 58 | argsJ, _ := json.Marshal(actual) 59 | assert.Equal(t, expect, string(argsJ)) 60 | } 61 | 62 | func TestConvertAccesslistTxToArgs(t *testing.T) { 63 | dtx := ðrpctypes.AccessListTx{} 64 | 65 | actual := ConvertTransactionToArgs(common.Address{}, *ethrpctypes.NewTx(dtx)) 66 | expect := `{"from":"0x0000000000000000000000000000000000000000","to":null,"gas":null,"value":"0x0","nonce":null,"data":"0x","accessList":[],"type":1}` 67 | 68 | argsJ, _ := json.Marshal(actual) 69 | assert.Equal(t, expect, string(argsJ)) 70 | } 71 | 72 | func TestConvertSetCodeTxToArgs(t *testing.T) { 73 | dtx := ðrpctypes.SetCodeTx{AccessList: ethrpctypes.AccessList{}, AuthList: []ethrpctypes.SetCodeAuthorization{}} 74 | 75 | actual := ConvertTransactionToArgs(common.Address{}, *ethrpctypes.NewTx(dtx)) 76 | expect := `{"from":"0x0000000000000000000000000000000000000000","to":"0x0000000000000000000000000000000000000000","gas":null,"value":"0x0","nonce":null,"data":"0x","accessList":[],"type":4}` 77 | 78 | argsJ, err := json.Marshal(actual) 79 | assert.NoError(t, err) 80 | assert.Equal(t, expect, string(argsJ)) 81 | } 82 | 83 | func TestPopulate(t *testing.T) { 84 | ast := assert.New(t) 85 | 86 | table := []struct { 87 | input *TransactionArgs 88 | expectOut string 89 | expectError bool 90 | }{ 91 | { 92 | input: &TransactionArgs{}, 93 | expectError: true, 94 | }, 95 | { 96 | input: &TransactionArgs{From: &common.Address{}, To: &common.Address{}}, 97 | expectOut: `{"from":"0x0000000000000000000000000000000000000000","to":"0x0000000000000000000000000000000000000000","gas":"0x26","maxFeePerGas":"0x92","maxPriorityFeePerGas":"0x1e","value":"0x0","nonce":"0x30","data":null,"chainId":"0x12","type":2}`, 98 | }, 99 | { 100 | input: &TransactionArgs{From: &common.Address{}, To: &common.Address{}, GasPrice: (*hexutil.Big)(big.NewInt(33))}, 101 | expectOut: `{"from":"0x0000000000000000000000000000000000000000","to":"0x0000000000000000000000000000000000000000","gas":"0x26","gasPrice":"0x21","value":"0x0","nonce":"0x30","data":null,"chainId":"0x12","type":0}`, 102 | }, 103 | { 104 | input: &TransactionArgs{From: &common.Address{}, To: &common.Address{}, MaxFeePerGas: (*hexutil.Big)(big.NewInt(44)), MaxPriorityFeePerGas: (*hexutil.Big)(big.NewInt(22))}, 105 | expectOut: `{"from":"0x0000000000000000000000000000000000000000","to":"0x0000000000000000000000000000000000000000","gas":"0x26","maxFeePerGas":"0x2c","maxPriorityFeePerGas":"0x16","value":"0x0","nonce":"0x30","data":null,"chainId":"0x12","type":2}`, 106 | }, 107 | { 108 | input: &TransactionArgs{From: &common.Address{}, To: &common.Address{}, MaxFeePerGas: (*hexutil.Big)(big.NewInt(44))}, 109 | expectOut: `{"from":"0x0000000000000000000000000000000000000000","to":"0x0000000000000000000000000000000000000000","gas":"0x26","maxFeePerGas":"0x2c","maxPriorityFeePerGas":"0x1e","value":"0x0","nonce":"0x30","data":null,"chainId":"0x12","type":2}`, 110 | }, 111 | { 112 | input: &TransactionArgs{From: &common.Address{}, To: &common.Address{}, GasPrice: (*hexutil.Big)(big.NewInt(33)), MaxFeePerGas: (*hexutil.Big)(big.NewInt(44))}, 113 | expectError: true, 114 | }, 115 | } 116 | 117 | for i, item := range table { 118 | err := item.input.Populate(&mockPopulateReader{}) 119 | if item.expectError { 120 | ast.Error(err, i) 121 | continue 122 | } 123 | 124 | ast.NoError(err) 125 | actual, _ := json.Marshal(item.input) 126 | ast.Equal(item.expectOut, string(actual)) 127 | } 128 | } 129 | 130 | func TestJsonMarshalHexBytes(t *testing.T) { 131 | j, _ := json.Marshal((*hexutil.Bytes)(nil)) 132 | fmt.Printf("%s\n", string(j)) 133 | } 134 | -------------------------------------------------------------------------------- /types/tx_or_hash_list.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/ethereum/go-ethereum/common" 7 | "github.com/openweb3/go-sdk-common/rpctest" 8 | ) 9 | 10 | type txListType string 11 | 12 | const ( 13 | TXLIST_TRANSACTION txListType = "transaction" 14 | TXLIST_HASH txListType = "hash" 15 | ) 16 | 17 | type TxOrHashList struct { 18 | vtype txListType 19 | transactions []TransactionDetail 20 | hashes []common.Hash 21 | } 22 | 23 | func NewTxOrHashList(isFull bool) *TxOrHashList { 24 | l := TxOrHashList{} 25 | l.vtype = TxListType(isFull) 26 | return &l 27 | } 28 | 29 | func NewTxOrHashListByTxs(txs []TransactionDetail) *TxOrHashList { 30 | return &TxOrHashList{ 31 | vtype: TXLIST_TRANSACTION, 32 | transactions: txs, 33 | } 34 | } 35 | 36 | func NewTxOrHashListByHashes(hashes []common.Hash) *TxOrHashList { 37 | return &TxOrHashList{ 38 | vtype: TXLIST_HASH, 39 | hashes: hashes, 40 | } 41 | } 42 | 43 | func TxListType(isFull bool) txListType { 44 | if isFull { 45 | return TXLIST_TRANSACTION 46 | } 47 | return TXLIST_HASH 48 | } 49 | 50 | func (l *TxOrHashList) Transactions() []TransactionDetail { 51 | return l.transactions 52 | } 53 | 54 | func (l *TxOrHashList) Hashes() []common.Hash { 55 | return l.hashes 56 | } 57 | 58 | func (l *TxOrHashList) UnmarshalJSON(data []byte) error { 59 | 60 | if l.vtype == TXLIST_TRANSACTION { 61 | var txs []TransactionDetail 62 | e := json.Unmarshal(data, &txs) 63 | l.transactions = txs 64 | return e 65 | } 66 | 67 | if l.vtype == TXLIST_HASH { 68 | var hashes []common.Hash 69 | e := json.Unmarshal(data, &hashes) 70 | l.hashes = hashes 71 | return e 72 | } 73 | 74 | var txs []TransactionDetail 75 | var e error 76 | if e = json.Unmarshal(data, &txs); e == nil { 77 | l.vtype = TXLIST_TRANSACTION 78 | l.transactions = txs 79 | return nil 80 | } 81 | 82 | var hashes []common.Hash 83 | if e = json.Unmarshal(data, &hashes); e == nil { 84 | l.vtype = TXLIST_HASH 85 | l.hashes = hashes 86 | return nil 87 | } 88 | 89 | return e 90 | } 91 | 92 | func (l TxOrHashList) MarshalJSON() ([]byte, error) { 93 | switch l.Type() { 94 | case TXLIST_TRANSACTION: 95 | return json.Marshal(l.transactions) 96 | case TXLIST_HASH: 97 | return json.Marshal(l.hashes) 98 | } 99 | return json.Marshal(nil) 100 | } 101 | 102 | func (l TxOrHashList) MarshalJSONForRPCTest(indent ...bool) ([]byte, error) { 103 | switch l.Type() { 104 | case TXLIST_TRANSACTION: 105 | return rpctest.JsonMarshalForRpcTest(l.transactions, indent...) 106 | case TXLIST_HASH: 107 | return rpctest.JsonMarshalForRpcTest(l.hashes, indent...) 108 | } 109 | return json.Marshal(nil) 110 | } 111 | 112 | func (l *TxOrHashList) Type() txListType { 113 | return l.vtype 114 | } 115 | -------------------------------------------------------------------------------- /types/types_test.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/ethereum/go-ethereum/common" 9 | 10 | "github.com/openweb3/go-rpc-provider" 11 | "github.com/stretchr/testify/assert" 12 | ) 13 | 14 | func TestUnMarshalCallRequest(t *testing.T) { 15 | goods := []CallRequest{ 16 | { 17 | Data: nil, 18 | }, 19 | { 20 | Data: []byte{0x1, 0x2, 0x3}, 21 | }, 22 | { 23 | Data: nil, 24 | }, 25 | } 26 | 27 | for _, item := range goods { 28 | b, e := json.Marshal(item) 29 | if e != nil { 30 | t.Fatal(e) 31 | } 32 | fmt.Printf("marshaled %s\n", b) 33 | 34 | item = CallRequest{} 35 | e = json.Unmarshal(b, &item) 36 | if e != nil { 37 | t.Fatal(e) 38 | } 39 | fmt.Printf("unmarshaled %+v\n", item) 40 | } 41 | } 42 | 43 | func TestBlockNumberOrHashMarshal(t *testing.T) { 44 | latest := rpc.LatestBlockNumber 45 | 46 | table := []struct { 47 | in BlockNumberOrHash 48 | out string 49 | err bool 50 | }{ 51 | { 52 | in: BlockNumberOrHash{BlockNumber: &latest}, 53 | out: `"latest"`, 54 | }, 55 | { 56 | in: BlockNumberOrHash(rpc.BlockNumberOrHashWithNumber(10)), 57 | out: `"0xa"`, 58 | }, 59 | { 60 | in: BlockNumberOrHash(rpc.BlockNumberOrHashWithHash(common.HexToHash("0xae7fbe443ce1e7b7ad867e246f79f4ea316fbcc545f1e6238bbfa697d623b6b9"), true)), 61 | out: `{"blockHash":"0xae7fbe443ce1e7b7ad867e246f79f4ea316fbcc545f1e6238bbfa697d623b6b9","requireCanonical":true}`, 62 | }, 63 | } 64 | 65 | for _, v := range table { 66 | j, e := json.Marshal(v.in) 67 | if v.err { 68 | if e == nil { 69 | t.Fatal("expect error, got nil") 70 | } 71 | continue 72 | } 73 | if e != nil { 74 | t.Fatal(e) 75 | } 76 | assert.EqualValues(t, string(j), v.out) 77 | } 78 | } 79 | 80 | func TestReceiptMarshal(t *testing.T) { 81 | fail := uint64(0) 82 | r := Receipt{ 83 | Status: &fail, 84 | } 85 | 86 | j, _ := json.Marshal(r) 87 | fmt.Printf("%s\n", j) 88 | } 89 | 90 | func TestUnmarshalFilterChanges(t *testing.T) { 91 | var f FilterChanges 92 | 93 | err := json.Unmarshal([]byte(`[ 94 | "0x3236cdebd39cf8470de82dc7b35bab55e29622dd03a941fbaa9de291b8fa6787", 95 | "0xcc9a4e25d1164841ae8ed2424cb2a007b6cb67feb3723366a0459c046c8e132f", 96 | "0xe9f3bd4466b8b8625f76e4adde77aef7cc369086cb325147dff42a5cd8b04a60", 97 | "0x026a7262eaeb9cf63ee4fc51b40b95e49948f791a416245507069607d6882147" 98 | ]`), &f) 99 | assert.NoError(t, err) 100 | assert.Equal(t, 0, len(f.Logs)) 101 | assert.Equal(t, 4, len(f.Hashes)) 102 | 103 | f = FilterChanges{} 104 | logs := []Log{ 105 | { 106 | Address: common.HexToAddress("0x09b5928d6ab3381c7d090b6fbe528db136e0bea3"), 107 | }, 108 | } 109 | j, _ := json.Marshal(logs) 110 | err = json.Unmarshal(j, &f) 111 | assert.NoError(t, err) 112 | assert.Equal(t, 1, len(f.Logs)) 113 | assert.Equal(t, 0, len(f.Hashes)) 114 | } 115 | 116 | func TestUnmarshalRpcID(t *testing.T) { 117 | j, _ := json.Marshal("0x39") 118 | var val *rpc.ID 119 | err := json.Unmarshal(j, &val) 120 | assert.NoError(t, err) 121 | assert.Equal(t, *val, rpc.ID("0x39")) 122 | } 123 | 124 | func TestUnmarshalFeeHistory(t *testing.T) { 125 | expect := `{"oldestBlock":"0x1302340","reward":[["0x989680","0x77359400"],["0x9402a0","0x51a875fa"],["0x55d4a80","0xa9eaec6d"]],"baseFeePerGas":["0x1d31b3ab6","0x1dadaf3bc","0x1e975439b","0x1b0249037"],"gasUsedRatio":[0.5663567666666667,0.6230082666666666,0.03160246666666667]}` 126 | 127 | var feeHistory FeeHistory 128 | err := json.Unmarshal([]byte(expect), &feeHistory) 129 | assert.NoError(t, err) 130 | 131 | j, _ := json.Marshal(feeHistory) 132 | assert.Equal(t, expect, string(j)) 133 | } 134 | -------------------------------------------------------------------------------- /types/util.go: -------------------------------------------------------------------------------- 1 | package types 2 | 3 | import ( 4 | "math/big" 5 | 6 | "github.com/holiman/uint256" 7 | ) 8 | 9 | func BigIntToBlockNumber(input *big.Int) *BlockNumber { 10 | if input == nil { 11 | return nil 12 | } 13 | v := BlockNumber(input.Int64()) 14 | return &v 15 | } 16 | 17 | func BigIntToUint256(input *big.Int) *uint256.Int { 18 | if input == nil { 19 | return nil 20 | } 21 | return uint256.NewInt(0).SetBytes(input.Bytes()) 22 | } 23 | 24 | func Pointer[T any](val T) *T { 25 | return &val 26 | } 27 | --------------------------------------------------------------------------------