1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
| package etherscan
import ( "context" "encoding/json" "fmt" "github.com/ethereum/go-ethereum/accounts/abi" "log" "net/url" "os" "strings" )
func GetTransactionList(address, startBlock string, endBlock string) ([]*Transaction, error) { txsResponse, err := fetchTransactionList(context.Background(), address, startBlock, endBlock) if err != nil { return nil, err } return txsResponse.Result, nil }
func GetContractABI(address string) (*abi.ABI, error) { contractABIResponse, err := fetchContractABI(context.Background(), address) if err != nil { return nil, err } contractABI, err := abi.JSON(strings.NewReader(*contractABIResponse.Result)) if err != nil { return nil, err } return &contractABI, nil }
func fetchTransactionList(ctx context.Context, address, startBlock string, endBlock string) (*TransactionListResponse, error) { data, err := fetch(ctx, map[string]string{ "module": "account", "action": "txlist", "address": address, "startblock": startBlock, "endblock": endBlock, "apikey": os.Getenv("ETHERSCAN_API_KEY"), }) if err != nil { return nil, err } resp := TransactionListResponse{} if err := json.Unmarshal(data, &resp); err != nil { return nil, fmt.Errorf("fetch transaction list failed: %s", string(data)) } log.Printf("Fetching transaction list from %s to %s", startBlock, endBlock) return &resp, err }
func fetchContractABI(ctx context.Context, address string) (*ContractABIResponse, error) { b, err := fetch(ctx, map[string]string{ "module": "contract", "action": "getabi", "address": address, "apikey": os.Getenv("ETHERSCAN_API_KEY"), }) if err != nil { return nil, err } resp := ContractABIResponse{} if err := json.Unmarshal(b, &resp); err != nil { return nil, fmt.Errorf("fetch contract ABI failed: %s", string(b)) } log.Printf("Fetching contract ABI: %s", address) return &resp, nil }
func fetch(ctx context.Context, params map[string]string) ([]byte, error) { ref, err := url.Parse("/api/") if err != nil { log.Fatal(err) } q := ref.Query() for k, v := range params { q.Set(k, v) } ref.RawQuery = q.Encode() base, err := url.Parse(os.Getenv("ETHERSCAN_URL")) if err != nil { log.Fatal(err) } target := base.ResolveReference(ref).String() return client.Get(ctx, target) }
type ContractABIResponse struct { Status *string `json:"status"` Message *string `json:"message"` Result *string `json:"result"` }
type TransactionListResponse struct { Status *string `json:"status"` Message *string `json:"message"` Result []*Transaction `json:"result"` }
type Transaction struct { BlockNumber string `json:"blockNumber"` TimeStamp string `json:"timeStamp"` Hash string `json:"hash"` Nonce string `json:"nonce"` BlockHash string `json:"blockHash"` TransactionIndex string `json:"transactionIndex"` From string `json:"from"` To string `json:"to"` Value string `json:"value"` Gas string `json:"gas"` GasPrice string `json:"gasPrice"` IsError string `json:"isError"` TxreceiptStatus string `json:"txreceipt_status"` Input string `json:"input"` ContractAddress string `json:"contractAddress"` CumulativeGasUsed string `json:"cumulativeGasUsed"` GasUsed string `json:"gasUsed"` Confirmations string `json:"confirmations"` }
|