Skip to content
This repository was archived by the owner on Oct 20, 2024. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 8f8d5da

Browse files
committedAug 16, 2021
initial commit
0 parents  commit 8f8d5da

12 files changed

+3124
-0
lines changed
 

‎LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2021 Chris Hager
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

‎README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fork of [ethrpc](https://github.com/onrik/ethrpc) with Flashbots RPC calls.
2+
3+
https://docs.flashbots.net/flashbots-auction/searchers/advanced/rpc-endpoint

‎flashbotsrpc.go

+648
Large diffs are not rendered by default.

‎flashbotsrpc_test.go

+1,177
Large diffs are not rendered by default.

‎go.mod

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module github.com/metachris/flashbots-rpc
2+
3+
go 1.16
4+
5+
require (
6+
github.com/ethereum/go-ethereum v1.10.7
7+
github.com/jarcoal/httpmock v1.0.8
8+
github.com/stretchr/testify v1.7.0
9+
github.com/tidwall/gjson v1.8.1
10+
)

‎go.sum

+540
Large diffs are not rendered by default.

‎helpers.go

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package flashbotsrpc
2+
3+
import (
4+
"bytes"
5+
"fmt"
6+
"math/big"
7+
"strconv"
8+
"strings"
9+
10+
"github.com/ethereum/go-ethereum/core/types"
11+
)
12+
13+
// ParseInt parse hex string value to int
14+
func ParseInt(value string) (int, error) {
15+
i, err := strconv.ParseInt(strings.TrimPrefix(value, "0x"), 16, 64)
16+
if err != nil {
17+
return 0, err
18+
}
19+
20+
return int(i), nil
21+
}
22+
23+
// ParseBigInt parse hex string value to big.Int
24+
func ParseBigInt(value string) (big.Int, error) {
25+
i := big.Int{}
26+
_, err := fmt.Sscan(value, &i)
27+
28+
return i, err
29+
}
30+
31+
// IntToHex convert int to hexadecimal representation
32+
func IntToHex(i int) string {
33+
return fmt.Sprintf("0x%x", i)
34+
}
35+
36+
// BigToHex covert big.Int to hexadecimal representation
37+
func BigToHex(bigInt big.Int) string {
38+
if bigInt.BitLen() == 0 {
39+
return "0x0"
40+
}
41+
42+
return "0x" + strings.TrimPrefix(fmt.Sprintf("%x", bigInt.Bytes()), "0")
43+
}
44+
45+
func TxToRlp(tx *types.Transaction) string {
46+
var buff bytes.Buffer
47+
tx.EncodeRLP(&buff)
48+
return fmt.Sprintf("%x", buff.Bytes())
49+
}

‎helpers_test.go

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package flashbotsrpc
2+
3+
import (
4+
"math/big"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestParseInt(t *testing.T) {
11+
i, err := ParseInt("0x143")
12+
assert.Nil(t, err)
13+
assert.Equal(t, 323, i)
14+
15+
i, err = ParseInt("143")
16+
assert.Nil(t, err)
17+
assert.Equal(t, 323, i)
18+
19+
i, err = ParseInt("0xaaa")
20+
assert.Nil(t, err)
21+
assert.Equal(t, 2730, i)
22+
23+
i, err = ParseInt("1*29")
24+
assert.NotNil(t, err)
25+
assert.Equal(t, 0, i)
26+
}
27+
28+
func TestParseBigInt(t *testing.T) {
29+
i, err := ParseBigInt("0xabc")
30+
assert.Nil(t, err)
31+
assert.Equal(t, int64(2748), i.Int64())
32+
33+
i, err = ParseBigInt("$%1")
34+
assert.NotNil(t, err)
35+
}
36+
37+
func TestIntToHex(t *testing.T) {
38+
assert.Equal(t, "0xde0b6b3a7640000", IntToHex(1000000000000000000))
39+
assert.Equal(t, "0x6f", IntToHex(111))
40+
}
41+
42+
func TestBigToHex(t *testing.T) {
43+
i1, _ := big.NewInt(0).SetString("1000000000000000000", 10)
44+
assert.Equal(t, "0xde0b6b3a7640000", BigToHex(*i1))
45+
46+
i2, _ := big.NewInt(0).SetString("100000000000000000000", 10)
47+
assert.Equal(t, "0x56bc75e2d63100000", BigToHex(*i2))
48+
49+
i3, _ := big.NewInt(0).SetString("0", 10)
50+
assert.Equal(t, "0x0", BigToHex(*i3))
51+
}

‎interface.go

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package flashbotsrpc
2+
3+
import (
4+
"math/big"
5+
)
6+
7+
type EthereumAPI interface {
8+
Web3ClientVersion() (string, error)
9+
Web3Sha3(data []byte) (string, error)
10+
NetVersion() (string, error)
11+
NetListening() (bool, error)
12+
NetPeerCount() (int, error)
13+
EthProtocolVersion() (string, error)
14+
EthSyncing() (*Syncing, error)
15+
EthCoinbase() (string, error)
16+
EthMining() (bool, error)
17+
EthHashrate() (int, error)
18+
EthGasPrice() (big.Int, error)
19+
EthAccounts() ([]string, error)
20+
EthBlockNumber() (int, error)
21+
EthGetBalance(address, block string) (big.Int, error)
22+
EthGetStorageAt(data string, position int, tag string) (string, error)
23+
EthGetTransactionCount(address, block string) (int, error)
24+
EthGetBlockTransactionCountByHash(hash string) (int, error)
25+
EthGetBlockTransactionCountByNumber(number int) (int, error)
26+
EthGetUncleCountByBlockHash(hash string) (int, error)
27+
EthGetUncleCountByBlockNumber(number int) (int, error)
28+
EthGetCode(address, block string) (string, error)
29+
EthSign(address, data string) (string, error)
30+
EthSendTransaction(transaction T) (string, error)
31+
EthSendRawTransaction(data string) (string, error)
32+
EthCall(transaction T, tag string) (string, error)
33+
EthEstimateGas(transaction T) (int, error)
34+
EthGetBlockByHash(hash string, withTransactions bool) (*Block, error)
35+
EthGetBlockByNumber(number int, withTransactions bool) (*Block, error)
36+
EthGetTransactionByHash(hash string) (*Transaction, error)
37+
EthGetTransactionByBlockHashAndIndex(blockHash string, transactionIndex int) (*Transaction, error)
38+
EthGetTransactionByBlockNumberAndIndex(blockNumber, transactionIndex int) (*Transaction, error)
39+
EthGetTransactionReceipt(hash string) (*TransactionReceipt, error)
40+
EthGetCompilers() ([]string, error)
41+
EthNewFilter(params FilterParams) (string, error)
42+
EthNewBlockFilter() (string, error)
43+
EthNewPendingTransactionFilter() (string, error)
44+
EthUninstallFilter(filterID string) (bool, error)
45+
EthGetFilterChanges(filterID string) ([]Log, error)
46+
EthGetFilterLogs(filterID string) ([]Log, error)
47+
EthGetLogs(params FilterParams) ([]Log, error)
48+
}
49+
50+
var _ EthereumAPI = (*FlashbotsRPC)(nil)

‎options.go

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package flashbotsrpc
2+
3+
import (
4+
"io"
5+
"net/http"
6+
)
7+
8+
type httpClient interface {
9+
Post(url string, contentType string, body io.Reader) (*http.Response, error)
10+
}
11+
12+
type logger interface {
13+
Println(v ...interface{})
14+
}
15+
16+
// WithHttpClient set custom http client
17+
func WithHttpClient(client httpClient) func(rpc *FlashbotsRPC) {
18+
return func(rpc *FlashbotsRPC) {
19+
rpc.client = client
20+
}
21+
}
22+
23+
// WithLogger set custom logger
24+
func WithLogger(l logger) func(rpc *FlashbotsRPC) {
25+
return func(rpc *FlashbotsRPC) {
26+
rpc.log = l
27+
}
28+
}
29+
30+
// WithDebug set debug flag
31+
func WithDebug(enabled bool) func(rpc *FlashbotsRPC) {
32+
return func(rpc *FlashbotsRPC) {
33+
rpc.Debug = enabled
34+
}
35+
}

‎types.go

+366
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,366 @@
1+
package flashbotsrpc
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"math/big"
7+
"unsafe"
8+
)
9+
10+
// Syncing - object with syncing data info
11+
type Syncing struct {
12+
IsSyncing bool
13+
StartingBlock int
14+
CurrentBlock int
15+
HighestBlock int
16+
}
17+
18+
// UnmarshalJSON implements the json.Unmarshaler interface.
19+
func (s *Syncing) UnmarshalJSON(data []byte) error {
20+
proxy := new(proxySyncing)
21+
if err := json.Unmarshal(data, proxy); err != nil {
22+
return err
23+
}
24+
25+
proxy.IsSyncing = true
26+
*s = *(*Syncing)(unsafe.Pointer(proxy))
27+
28+
return nil
29+
}
30+
31+
// T - input transaction object
32+
type T struct {
33+
From string
34+
To string
35+
Gas int
36+
GasPrice *big.Int
37+
Value *big.Int
38+
Data string
39+
Nonce int
40+
}
41+
42+
// MarshalJSON implements the json.Unmarshaler interface.
43+
func (t T) MarshalJSON() ([]byte, error) {
44+
params := map[string]interface{}{
45+
"from": t.From,
46+
}
47+
if t.To != "" {
48+
params["to"] = t.To
49+
}
50+
if t.Gas > 0 {
51+
params["gas"] = IntToHex(t.Gas)
52+
}
53+
if t.GasPrice != nil {
54+
params["gasPrice"] = BigToHex(*t.GasPrice)
55+
}
56+
if t.Value != nil {
57+
params["value"] = BigToHex(*t.Value)
58+
}
59+
if t.Data != "" {
60+
params["data"] = t.Data
61+
}
62+
if t.Nonce > 0 {
63+
params["nonce"] = IntToHex(t.Nonce)
64+
}
65+
66+
return json.Marshal(params)
67+
}
68+
69+
// Transaction - transaction object
70+
type Transaction struct {
71+
Hash string
72+
Nonce int
73+
BlockHash string
74+
BlockNumber *int
75+
TransactionIndex *int
76+
From string
77+
To string
78+
Value big.Int
79+
Gas int
80+
GasPrice big.Int
81+
Input string
82+
}
83+
84+
// UnmarshalJSON implements the json.Unmarshaler interface.
85+
func (t *Transaction) UnmarshalJSON(data []byte) error {
86+
proxy := new(proxyTransaction)
87+
if err := json.Unmarshal(data, proxy); err != nil {
88+
return err
89+
}
90+
91+
*t = *(*Transaction)(unsafe.Pointer(proxy))
92+
93+
return nil
94+
}
95+
96+
// Log - log object
97+
type Log struct {
98+
Removed bool
99+
LogIndex int
100+
TransactionIndex int
101+
TransactionHash string
102+
BlockNumber int
103+
BlockHash string
104+
Address string
105+
Data string
106+
Topics []string
107+
}
108+
109+
// UnmarshalJSON implements the json.Unmarshaler interface.
110+
func (log *Log) UnmarshalJSON(data []byte) error {
111+
proxy := new(proxyLog)
112+
if err := json.Unmarshal(data, proxy); err != nil {
113+
return err
114+
}
115+
116+
*log = *(*Log)(unsafe.Pointer(proxy))
117+
118+
return nil
119+
}
120+
121+
// FilterParams - Filter parameters object
122+
type FilterParams struct {
123+
FromBlock string `json:"fromBlock,omitempty"`
124+
ToBlock string `json:"toBlock,omitempty"`
125+
Address []string `json:"address,omitempty"`
126+
Topics [][]string `json:"topics,omitempty"`
127+
}
128+
129+
// TransactionReceipt - transaction receipt object
130+
type TransactionReceipt struct {
131+
TransactionHash string
132+
TransactionIndex int
133+
BlockHash string
134+
BlockNumber int
135+
CumulativeGasUsed int
136+
GasUsed int
137+
ContractAddress string
138+
Logs []Log
139+
LogsBloom string
140+
Root string
141+
Status string
142+
}
143+
144+
// UnmarshalJSON implements the json.Unmarshaler interface.
145+
func (t *TransactionReceipt) UnmarshalJSON(data []byte) error {
146+
proxy := new(proxyTransactionReceipt)
147+
if err := json.Unmarshal(data, proxy); err != nil {
148+
return err
149+
}
150+
151+
*t = *(*TransactionReceipt)(unsafe.Pointer(proxy))
152+
153+
return nil
154+
}
155+
156+
// Block - block object
157+
type Block struct {
158+
Number int
159+
Hash string
160+
ParentHash string
161+
Nonce string
162+
Sha3Uncles string
163+
LogsBloom string
164+
TransactionsRoot string
165+
StateRoot string
166+
Miner string
167+
Difficulty big.Int
168+
TotalDifficulty big.Int
169+
ExtraData string
170+
Size int
171+
GasLimit int
172+
GasUsed int
173+
Timestamp int
174+
Uncles []string
175+
Transactions []Transaction
176+
}
177+
178+
type proxySyncing struct {
179+
IsSyncing bool `json:"-"`
180+
StartingBlock hexInt `json:"startingBlock"`
181+
CurrentBlock hexInt `json:"currentBlock"`
182+
HighestBlock hexInt `json:"highestBlock"`
183+
}
184+
185+
type proxyTransaction struct {
186+
Hash string `json:"hash"`
187+
Nonce hexInt `json:"nonce"`
188+
BlockHash string `json:"blockHash"`
189+
BlockNumber *hexInt `json:"blockNumber"`
190+
TransactionIndex *hexInt `json:"transactionIndex"`
191+
From string `json:"from"`
192+
To string `json:"to"`
193+
Value hexBig `json:"value"`
194+
Gas hexInt `json:"gas"`
195+
GasPrice hexBig `json:"gasPrice"`
196+
Input string `json:"input"`
197+
}
198+
199+
type proxyLog struct {
200+
Removed bool `json:"removed"`
201+
LogIndex hexInt `json:"logIndex"`
202+
TransactionIndex hexInt `json:"transactionIndex"`
203+
TransactionHash string `json:"transactionHash"`
204+
BlockNumber hexInt `json:"blockNumber"`
205+
BlockHash string `json:"blockHash"`
206+
Address string `json:"address"`
207+
Data string `json:"data"`
208+
Topics []string `json:"topics"`
209+
}
210+
211+
type proxyTransactionReceipt struct {
212+
TransactionHash string `json:"transactionHash"`
213+
TransactionIndex hexInt `json:"transactionIndex"`
214+
BlockHash string `json:"blockHash"`
215+
BlockNumber hexInt `json:"blockNumber"`
216+
CumulativeGasUsed hexInt `json:"cumulativeGasUsed"`
217+
GasUsed hexInt `json:"gasUsed"`
218+
ContractAddress string `json:"contractAddress,omitempty"`
219+
Logs []Log `json:"logs"`
220+
LogsBloom string `json:"logsBloom"`
221+
Root string `json:"root"`
222+
Status string `json:"status,omitempty"`
223+
}
224+
225+
type hexInt int
226+
227+
func (i *hexInt) UnmarshalJSON(data []byte) error {
228+
result, err := ParseInt(string(bytes.Trim(data, `"`)))
229+
*i = hexInt(result)
230+
231+
return err
232+
}
233+
234+
type hexBig big.Int
235+
236+
func (i *hexBig) UnmarshalJSON(data []byte) error {
237+
result, err := ParseBigInt(string(bytes.Trim(data, `"`)))
238+
*i = hexBig(result)
239+
240+
return err
241+
}
242+
243+
type proxyBlock interface {
244+
toBlock() Block
245+
}
246+
247+
type proxyBlockWithTransactions struct {
248+
Number hexInt `json:"number"`
249+
Hash string `json:"hash"`
250+
ParentHash string `json:"parentHash"`
251+
Nonce string `json:"nonce"`
252+
Sha3Uncles string `json:"sha3Uncles"`
253+
LogsBloom string `json:"logsBloom"`
254+
TransactionsRoot string `json:"transactionsRoot"`
255+
StateRoot string `json:"stateRoot"`
256+
Miner string `json:"miner"`
257+
Difficulty hexBig `json:"difficulty"`
258+
TotalDifficulty hexBig `json:"totalDifficulty"`
259+
ExtraData string `json:"extraData"`
260+
Size hexInt `json:"size"`
261+
GasLimit hexInt `json:"gasLimit"`
262+
GasUsed hexInt `json:"gasUsed"`
263+
Timestamp hexInt `json:"timestamp"`
264+
Uncles []string `json:"uncles"`
265+
Transactions []proxyTransaction `json:"transactions"`
266+
}
267+
268+
func (proxy *proxyBlockWithTransactions) toBlock() Block {
269+
return *(*Block)(unsafe.Pointer(proxy))
270+
}
271+
272+
type proxyBlockWithoutTransactions struct {
273+
Number hexInt `json:"number"`
274+
Hash string `json:"hash"`
275+
ParentHash string `json:"parentHash"`
276+
Nonce string `json:"nonce"`
277+
Sha3Uncles string `json:"sha3Uncles"`
278+
LogsBloom string `json:"logsBloom"`
279+
TransactionsRoot string `json:"transactionsRoot"`
280+
StateRoot string `json:"stateRoot"`
281+
Miner string `json:"miner"`
282+
Difficulty hexBig `json:"difficulty"`
283+
TotalDifficulty hexBig `json:"totalDifficulty"`
284+
ExtraData string `json:"extraData"`
285+
Size hexInt `json:"size"`
286+
GasLimit hexInt `json:"gasLimit"`
287+
GasUsed hexInt `json:"gasUsed"`
288+
Timestamp hexInt `json:"timestamp"`
289+
Uncles []string `json:"uncles"`
290+
Transactions []string `json:"transactions"`
291+
}
292+
293+
func (proxy *proxyBlockWithoutTransactions) toBlock() Block {
294+
block := Block{
295+
Number: int(proxy.Number),
296+
Hash: proxy.Hash,
297+
ParentHash: proxy.ParentHash,
298+
Nonce: proxy.Nonce,
299+
Sha3Uncles: proxy.Sha3Uncles,
300+
LogsBloom: proxy.LogsBloom,
301+
TransactionsRoot: proxy.TransactionsRoot,
302+
StateRoot: proxy.StateRoot,
303+
Miner: proxy.Miner,
304+
Difficulty: big.Int(proxy.Difficulty),
305+
TotalDifficulty: big.Int(proxy.TotalDifficulty),
306+
ExtraData: proxy.ExtraData,
307+
Size: int(proxy.Size),
308+
GasLimit: int(proxy.GasLimit),
309+
GasUsed: int(proxy.GasUsed),
310+
Timestamp: int(proxy.Timestamp),
311+
Uncles: proxy.Uncles,
312+
}
313+
314+
block.Transactions = make([]Transaction, len(proxy.Transactions))
315+
for i := range proxy.Transactions {
316+
block.Transactions[i] = Transaction{
317+
Hash: proxy.Transactions[i],
318+
}
319+
}
320+
321+
return block
322+
}
323+
324+
type FlashbotsUserStats struct {
325+
IsHighPriority bool `json:"is_high_priority"`
326+
AllTimeMinerPayments string `json:"all_time_miner_payments"`
327+
AllTimeGasSimulated string `json:"all_time_gas_simulated"`
328+
Last7dMinerPayments string `json:"last_7d_miner_payments"`
329+
Last7dGasSimulated string `json:"last_7d_gas_simulated"`
330+
Last1dMinerPayments string `json:"last_1d_miner_payments"`
331+
Last1dGasSimulated string `json:"last_1d_gas_simulated"`
332+
}
333+
334+
type FlashbotsCallBundleParam struct {
335+
Txs []string `json:"txs"` // Array[String], A list of signed transactions to execute in an atomic bundle
336+
BlockNumber string `json:"blockNumber"` // String, a hex encoded block number for which this bundle is valid on
337+
StateBlockNumber string `json:"stateBlockNumber"` // String, either a hex encoded number or a block tag for which state to base this simulation on. Can use "latest"
338+
Timestamp int64 `json:"timestamp,omitempty"` // Number, the timestamp to use for this bundle simulation, in seconds since the unix epoch
339+
Timeout int64 `json:"timeout,omitempty"`
340+
GasLimit uint64 `json:"gasLimit,omitempty"`
341+
Difficulty uint64 `json:"difficulty,omitempty"`
342+
BaseFee uint64 `json:"baseFee,omitempty"`
343+
}
344+
345+
type FlashbotsCallBundleResult struct {
346+
CoinbaseDiff string `json:"coinbaseDiff"` // "2717471092204423",
347+
EthSentToCoinbase string `json:"ethSentToCoinbase"` // "0",
348+
FromAddress string `json:"fromAddress"` // "0x37ff310ab11d1928BB70F37bC5E3cf62Df09a01c",
349+
GasFees string `json:"gasFees"` // "2717471092204423",
350+
GasPrice string `json:"gasPrice"` // "43000001459",
351+
GasUsed int64 `json:"gasUsed"` // 63197,
352+
ToAddress string `json:"toAddress"` // "0xdAC17F958D2ee523a2206206994597C13D831ec7",
353+
TxHash string `json:"txHash"` // "0xe2df005210bdc204a34ff03211606e5d8036740c686e9fe4e266ae91cf4d12df",
354+
Value string `json:"value"` // "0x"
355+
}
356+
357+
type FlashbotsCallBundleResponse struct {
358+
BundleGasPrice string `json:"bundleGasPrice"` // "43000001459",
359+
BundleHash string `json:"bundleHash"` // "0x2ca9c4d2ba00d8144d8e396a4989374443cb20fb490d800f4f883ad4e1b32158",
360+
CoinbaseDiff string `json:"coinbaseDiff"` // "2717471092204423",
361+
EthSentToCoinbase string `json:"ethSentToCoinbase"` // "0",
362+
GasFees string `json:"gasFees"` // "2717471092204423",
363+
Results []FlashbotsCallBundleResult `json:"results"` // [],
364+
StateBlockNumber int64 `json:"stateBlockNumber"` // 12960319,
365+
TotalGasUsed int64 `json:"totalGasUsed"` // 63197
366+
}

‎types_test.go

+174
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
package flashbotsrpc
2+
3+
import (
4+
"encoding/json"
5+
"math/big"
6+
"testing"
7+
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
func TestHexIntUnmarshal(t *testing.T) {
12+
test := struct {
13+
ID hexInt `json:"id"`
14+
}{}
15+
16+
data := []byte(`{"id": "0x1cc348"}`)
17+
err := json.Unmarshal(data, &test)
18+
19+
require.Nil(t, err)
20+
require.Equal(t, hexInt(1885000), test.ID)
21+
}
22+
23+
func TestHexBigUnmarshal(t *testing.T) {
24+
test := struct {
25+
ID hexBig `json:"id"`
26+
}{}
27+
28+
data := []byte(`{"id": "0x51248487c7466b7062d"}`)
29+
err := json.Unmarshal(data, &test)
30+
31+
require.Nil(t, err)
32+
b := big.Int{}
33+
b.SetString("23949082357483433297453", 10)
34+
35+
require.Equal(t, hexBig(b), test.ID)
36+
}
37+
38+
func TestSyncingUnmarshal(t *testing.T) {
39+
syncing := new(Syncing)
40+
err := json.Unmarshal([]byte("0"), syncing)
41+
require.NotNil(t, err)
42+
43+
data := []byte(`{
44+
"startingBlock": "0x384",
45+
"currentBlock": "0x386",
46+
"highestBlock": "0x454"
47+
}`)
48+
49+
err = json.Unmarshal(data, syncing)
50+
require.Nil(t, err)
51+
require.True(t, syncing.IsSyncing)
52+
require.Equal(t, 900, syncing.StartingBlock)
53+
require.Equal(t, 902, syncing.CurrentBlock)
54+
require.Equal(t, 1108, syncing.HighestBlock)
55+
}
56+
57+
func TestTransactionUnmarshal(t *testing.T) {
58+
tx := new(Transaction)
59+
err := json.Unmarshal([]byte("111"), tx)
60+
require.NotNil(t, err)
61+
62+
data := []byte(`{
63+
"blockHash": "0x3003694478c108eaec173afcb55eafbb754a0b204567329f623438727ffa90d8",
64+
"blockNumber": "0x83319",
65+
"from": "0x201354729f8d0f8b64e9a0c353c672c6a66b3857",
66+
"gas": "0x15f90",
67+
"gasPrice": "0x4a817c800",
68+
"hash": "0xfc7dcd42eb0b7898af2f52f7c5af3bd03cdf71ab8b3ed5b3d3a3ff0d91343cbe",
69+
"input": "0xe1fa8e8425f1af44eb895e4900b8be35d9fdc28744a6ef491c46ec8601990e12a58af0ed",
70+
"nonce": "0x6ba1",
71+
"to": "0xd10e3be2bc8f959bc8c41cf65f60de721cf89adf",
72+
"transactionIndex": "0x3",
73+
"value": "0x0"
74+
}`)
75+
76+
err = json.Unmarshal(data, tx)
77+
78+
require.Nil(t, err)
79+
require.Equal(t, "0x3003694478c108eaec173afcb55eafbb754a0b204567329f623438727ffa90d8", tx.BlockHash)
80+
require.Equal(t, 537369, *tx.BlockNumber)
81+
require.Equal(t, "0x201354729f8d0f8b64e9a0c353c672c6a66b3857", tx.From)
82+
require.Equal(t, 90000, tx.Gas)
83+
require.Equal(t, *big.NewInt(20000000000), tx.GasPrice)
84+
require.Equal(t, "0xfc7dcd42eb0b7898af2f52f7c5af3bd03cdf71ab8b3ed5b3d3a3ff0d91343cbe", tx.Hash)
85+
require.Equal(t, "0xe1fa8e8425f1af44eb895e4900b8be35d9fdc28744a6ef491c46ec8601990e12a58af0ed", tx.Input)
86+
require.Equal(t, 27553, tx.Nonce)
87+
require.Equal(t, "0xd10e3be2bc8f959bc8c41cf65f60de721cf89adf", tx.To)
88+
require.Equal(t, 3, *tx.TransactionIndex)
89+
require.Equal(t, *big.NewInt(0), tx.Value)
90+
}
91+
92+
func TestLogUnmarshal(t *testing.T) {
93+
log := new(Log)
94+
err := json.Unmarshal([]byte("111"), log)
95+
require.NotNil(t, err)
96+
97+
data := []byte(`{
98+
"address": "0xd10e3be2bc8f959bc8c41cf65f60de721cf89adf",
99+
"topics": ["0x78e4fc71ff7e525b3b4660a76336a2046232fd9bba9c65abb22fa3d07d6e7066"],
100+
"data": "0x0000000000000000000000000000000000000000000000000000000000000000",
101+
"blockNumber": "0x7f2cd",
102+
"blockHash": "0x3757b6efd7f82e3a832f0ec229b2fa36e622033ae7bad76b95763055a69374f7",
103+
"transactionIndex": "0x1",
104+
"transactionHash": "0xecd8a21609fa852c08249f6c767b7097481da34b9f8d2aae70067918955b4e69",
105+
"logIndex": "0x6",
106+
"removed": false
107+
}`)
108+
109+
err = json.Unmarshal(data, log)
110+
111+
require.Nil(t, err)
112+
require.Equal(t, "0xd10e3be2bc8f959bc8c41cf65f60de721cf89adf", log.Address)
113+
require.Equal(t, []string{"0x78e4fc71ff7e525b3b4660a76336a2046232fd9bba9c65abb22fa3d07d6e7066"}, log.Topics)
114+
require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", log.Data)
115+
require.Equal(t, 520909, log.BlockNumber)
116+
require.Equal(t, "0x3757b6efd7f82e3a832f0ec229b2fa36e622033ae7bad76b95763055a69374f7", log.BlockHash)
117+
require.Equal(t, 1, log.TransactionIndex)
118+
require.Equal(t, "0xecd8a21609fa852c08249f6c767b7097481da34b9f8d2aae70067918955b4e69", log.TransactionHash)
119+
require.Equal(t, 6, log.LogIndex)
120+
require.Equal(t, false, log.Removed)
121+
}
122+
123+
func TestTransactionReceiptUnmarshal(t *testing.T) {
124+
receipt := new(TransactionReceipt)
125+
err := json.Unmarshal([]byte("[1]"), receipt)
126+
require.NotNil(t, err)
127+
128+
data := []byte(`{
129+
"blockHash": "0x3757b6efd7f82e3a832f0ec229b2fa36e622033ae7bad76b95763055a69374f7",
130+
"blockNumber": "0x7f2cd",
131+
"contractAddress": null,
132+
"cumulativeGasUsed": "0x13356",
133+
"gasUsed": "0x6384",
134+
"logs": [{
135+
"address": "0xd10e3be2bc8f959bc8c41cf65f60de721cf89adf",
136+
"topics": ["0x78e4fc71ff7e525b3b4660a76336a2046232fd9bba9c65abb22fa3d07d6e7066"],
137+
"data": "0x0000000000000000000000000000000000000000000000000000000000000000",
138+
"blockNumber": "0x7f2cd",
139+
"blockHash": "0x3757b6efd7f82e3a832f0ec229b2fa36e622033ae7bad76b95763055a69374f7",
140+
"transactionIndex": "0x1",
141+
"transactionHash": "0xecd8a21609fa852c08249f6c767b7097481da34b9f8d2aae70067918955b4e69",
142+
"logIndex": "0x6",
143+
"removed": false
144+
}],
145+
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000020000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000",
146+
"root": "0xe367ea197d629892e7b25ea246fba93cd8ae053d468cc5997a816cc85d660321",
147+
"transactionHash": "0xecd8a21609fa852c08249f6c767b7097481da34b9f8d2aae70067918955b4e69",
148+
"transactionIndex": "0x1"
149+
}`)
150+
151+
err = json.Unmarshal(data, receipt)
152+
153+
require.Nil(t, err)
154+
require.Equal(t, 1, len(receipt.Logs))
155+
require.Equal(t, "0x3757b6efd7f82e3a832f0ec229b2fa36e622033ae7bad76b95763055a69374f7", receipt.BlockHash)
156+
require.Equal(t, 520909, receipt.BlockNumber)
157+
require.Equal(t, "", receipt.ContractAddress)
158+
require.Equal(t, 78678, receipt.CumulativeGasUsed)
159+
require.Equal(t, 25476, receipt.GasUsed)
160+
require.Equal(t, "0x00000000000000000000000000000000000000000000000000000000000020000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000", receipt.LogsBloom)
161+
require.Equal(t, "0xe367ea197d629892e7b25ea246fba93cd8ae053d468cc5997a816cc85d660321", receipt.Root)
162+
require.Equal(t, "0xecd8a21609fa852c08249f6c767b7097481da34b9f8d2aae70067918955b4e69", receipt.TransactionHash)
163+
require.Equal(t, 1, receipt.TransactionIndex)
164+
165+
require.Equal(t, "0xd10e3be2bc8f959bc8c41cf65f60de721cf89adf", receipt.Logs[0].Address)
166+
require.Equal(t, []string{"0x78e4fc71ff7e525b3b4660a76336a2046232fd9bba9c65abb22fa3d07d6e7066"}, receipt.Logs[0].Topics)
167+
require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000000", receipt.Logs[0].Data)
168+
require.Equal(t, 520909, receipt.Logs[0].BlockNumber)
169+
require.Equal(t, "0x3757b6efd7f82e3a832f0ec229b2fa36e622033ae7bad76b95763055a69374f7", receipt.Logs[0].BlockHash)
170+
require.Equal(t, 1, receipt.Logs[0].TransactionIndex)
171+
require.Equal(t, "0xecd8a21609fa852c08249f6c767b7097481da34b9f8d2aae70067918955b4e69", receipt.Logs[0].TransactionHash)
172+
require.Equal(t, 6, receipt.Logs[0].LogIndex)
173+
require.Equal(t, false, receipt.Logs[0].Removed)
174+
}

0 commit comments

Comments
 (0)
This repository has been archived.