diff --git a/client.go b/client.go index e7422cd..0a9b06a 100644 --- a/client.go +++ b/client.go @@ -74,6 +74,7 @@ func (c *Client) call(module, action string, param map[string]interface{}, outco err = wrapErr(err, "http.NewRequest") return } + req.Header.Set("User-Agent", "etherscan-api(Go)") req.Header.Set("Content-Type", "application/json; charset=utf-8") @@ -129,8 +130,12 @@ func (c *Client) call(module, action string, param map[string]interface{}, outco err = wrapErr(err, "json unmarshal envelope") return } - if envelope.Status != 1 { - err = fmt.Errorf("etherscan server: %s", envelope.Message) + if envelope.Error.Code != 0 { + err = fmt.Errorf("etherscan server: %s", envelope.Error.Message) + return + } + if string(envelope.Result) == "null" { + err = fmt.Errorf("null result") return } diff --git a/geth.go b/geth.go new file mode 100644 index 0000000..9e27bda --- /dev/null +++ b/geth.go @@ -0,0 +1,58 @@ +package etherscan + +import ( + "github.com/ethereum/go-ethereum/common/math" + "math/big" + "strconv" +) + +func (c *Client) GetTransactionCount(address string) (count uint64, err error) { + param := M{ + "address": address, + "tag": "latest", + } + var countString string + err = c.call("proxy", "eth_getTransactionCount", param, &countString) + count, err = strconv.ParseUint(countString, 0, 0) + return +} + +func (c *Client) GetBlockByNumber(blockNum int64) (block Block, err error) { + param := M{ + "boolean": "true", + "tag": strconv.FormatInt(blockNum, 16), + } + + err = c.call("proxy", "eth_getBlockByNumber", param, &block) + return +} + +func (c *Client) GasPrice() (price *big.Int, err error) { + param := M{} + result := "" + err = c.call("proxy", "eth_gasPrice", param, &result) + price, _ = math.ParseBig256(result) + return +} + +func (c *Client) EstimateGas(from, to string, value, gasPrice *big.Int, data []byte) (limit uint64, err error) { + param := M{ + "value": value.Text(16), + "to": to, + "form": from, + "gasPrice": gasPrice.Text(16), + "data": string(data), + } + limitStr := "" + err = c.call("proxy", "eth_estimateGas", param, &limitStr) + limit, err = strconv.ParseUint(limitStr, 0, 0) + return +} + +func (c *Client) SendRawTransaction(hex string) (hash string, err error) { + param := M{ + "hex": hex, + } + err = c.call("proxy", "eth_sendRawTransaction", param, &hash) + return +} diff --git a/response.go b/response.go index b1338d3..1ac4acc 100644 --- a/response.go +++ b/response.go @@ -7,16 +7,57 @@ package etherscan -import "encoding/json" +import ( + "encoding/json" +) // Envelope is the carrier of nearly every response type Envelope struct { - // 1 for good, 0 for error - Status int `json:"status,string"` - // OK for good, other words when Status equals 0 - Message string `json:"message"` - // where response lies Result json.RawMessage `json:"result"` + Error struct { + Code int `json:"code"` + Message string `json:"message"` + } +} + +type Transaction struct { + BlockHash string `json:"blockHash"` + BlockNumber string `json:"blockNumber"` + From string `json:"from"` + Gas string `json:"gas"` + GasPrice string `json:"gasPrice"` + Hash string `json:"hash"` + Input string `json:"input"` + Nonce string `json:"nonce"` + To string `json:"to"` + TransactionIndex string `json:"transactionIndex"` + Value string `json:"value"` + V string `json:"v"` + R string `json:"r"` + S string `json:"s"` +} + +type Block struct { + Difficulty string `json:"difficulty"` + ExtraData string `json:"extraData"` + GasLimit string `json:"gasLimit"` + GasUsed string `json:"gasUsed"` + Hash string `json:"hash"` + LogsBloom string `json:"logsBloom"` + Miner string `json:"miner"` + MixHash string `json:"mixHash"` + Nonce string `json:"nonce"` + Number string `json:"number"` + ParentHash string `json:"parentHash"` + ReceiptsRoot string `json:"receiptsRoot"` + Sha3Uncles string `json:"sha3Uncles"` + Size string `json:"size"` + StateRoot string `json:"stateRoot"` + Timestamp string `json:"timestamp"` + TotalDifficulty string `json:"totalDifficulty"` + Transactions []Transaction `json:"transactions"` + TransactionsRoot string `json:"transactionsRoot"` + Uncles []interface{} `json:"uncles"` } // AccountBalance account and its balance in pair