diff --git a/client.go b/client.go index e69679a..2199ba6 100644 --- a/client.go +++ b/client.go @@ -166,13 +166,15 @@ func (c *Client) call(module, action string, param map[string]interface{}, outco return } + fixedContent := bytes.ReplaceAll(content.Bytes(), []byte(`"transactionIndex":""`), []byte(`"transactionIndex":"0"`)) + var envelope Envelope - err = json.Unmarshal(content.Bytes(), &envelope) + err = json.Unmarshal(fixedContent, &envelope) if err != nil { err = wrapErr(err, "json unmarshal envelope") return } - if envelope.Status != 1 { + if envelope.Status != "1" { err = fmt.Errorf("etherscan server: %s", envelope.Message) return } diff --git a/contract.go b/contract.go index 11e9e35..3806fb2 100644 --- a/contract.go +++ b/contract.go @@ -26,3 +26,12 @@ func (c *Client) ContractSource(address string) (source []ContractSource, err er err = c.call("contract", "getsourcecode", param, &source) return } + +func (c *Client) ContractCreation(address string) (creation []ContractCreation, err error) { + param := M{ + "contractaddresses": address, + } + + err = c.call("contract", "getcontractcreation", param, &creation) + return +} diff --git a/contract_e2e_test.go b/contract_e2e_test.go index ca577e7..075e53b 100644 --- a/contract_e2e_test.go +++ b/contract_e2e_test.go @@ -8,6 +8,7 @@ package etherscan import ( + "strings" "testing" ) @@ -38,3 +39,18 @@ func TestClient_ContractSource(t *testing.T) { t.Fatalf("api.ContractSource not working, content match failed, got\n%+v", s) } } + +func TestClient_ContractCreation(t *testing.T) { + creation, err := api.ContractCreation("0xBB9bc244D798123fDe783fCc1C72d3Bb8C189413") + noError(t, err, "api.ContractCreation") + + if len(creation) != 1 { + t.Fatalf("api.ContractCreation not working, got len %v, expect 1", len(creation)) + } + c := creation[0] + if !strings.EqualFold(c.ContractCreator, "0x793ea9692Ada1900fBd0B80FFFEc6E431fe8b391") || + c.BlockNumber != 1428757 || + c.TxHash != "0xe9ebfecc2fa10100db51a4408d18193b3ac504584b51a4e55bdef1318f0a30f9" { + t.Fatalf("api.ContractCreation not working, content match failed, got\n%+v", c) + } +} diff --git a/response.go b/response.go index 5c418cf..9abb2c7 100644 --- a/response.go +++ b/response.go @@ -17,7 +17,7 @@ import ( // Envelope is the carrier of nearly every response type Envelope struct { // 1 for good, 0 for error - Status int `json:"status,string"` + Status json.Number `json:"status"` // OK for good, other words when Status equals 0 Message string `json:"message"` // where response lies @@ -166,6 +166,17 @@ type ContractSource struct { SwarmSource string `json:"SwarmSource"` } +// ContractCreation holds info from query for contract creation +type ContractCreation struct { + ContractAddress string `json:"contractAddress"` + ContractCreator string `json:"contractCreator"` + TxHash string `json:"txHash"` + BlockNumber int `json:"blockNumber,string"` + Timestamp Time `json:"timestamp"` + ContractFactory string `json:"contractFactory"` + CreationBytecode string `json:"creationBytecode"` +} + // ExecutionStatus holds info from query for transaction execution status type ExecutionStatus struct { // 0 = pass, 1 = error @@ -200,6 +211,7 @@ type Log struct { Topics []string `json:"topics"` Data string `json:"data"` BlockNumber string `json:"blockNumber"` + Timestamp string `json:"timeStamp"` TransactionHash string `json:"transactionHash"` BlockHash string `json:"blockHash"` LogIndex string `json:"logIndex"` diff --git a/setup_e2e_test.go b/setup_e2e_test.go index 64f2702..ccd111d 100644 --- a/setup_e2e_test.go +++ b/setup_e2e_test.go @@ -32,7 +32,10 @@ func init() { } bucket = NewBucket(500 * time.Millisecond) - api = New(Mainnet, apiKey) + api = NewCustomized(Customization{ + BaseURL: "https://api.etherscan.io/v2/api?chainid=1&", + Key: apiKey, + }) api.Verbose = true api.BeforeRequest = func(module string, action string, param map[string]interface{}) error { bucket.Take()