etherscan 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/Gemfile +5 -0
- data/README.md +17 -0
- data/Rakefile +10 -0
- data/etherscan.gemspec +34 -0
- data/lib/etherscan.rb +10 -0
- data/lib/etherscan/api.rb +139 -0
- data/lib/etherscan/call.rb +81 -0
- data/spec/api/account/balance_spec.rb +15 -0
- data/spec/api/account/balancemulti_spec.rb +21 -0
- data/spec/api/account/getminedblocks_spec.rb +24 -0
- data/spec/api/account/txlist_internal_spec.rb +28 -0
- data/spec/api/account/txlist_spec.rb +27 -0
- data/spec/api/block_getblockreward_spec.rb +13 -0
- data/spec/api/contract_spec.rb +13 -0
- data/spec/api/transaction_getstatus_spec.rb +13 -0
- data/spec/etehrscanio_call_api_key_spec.rb +14 -0
- data/spec/etherscan_call_params_spec.rb +94 -0
- data/spec/etherscanio_call_spec.rb +31 -0
- data/spec/etherscanio_spec.rb +12 -0
- data/spec/fixtures/account/balance.json +1 -0
- data/spec/fixtures/account/balance_multiple.json +1 -0
- data/spec/fixtures/account/getminedblocks.json +1 -0
- data/spec/fixtures/account/txlist.json +1 -0
- data/spec/fixtures/account/txlist_internal.json +1 -0
- data/spec/fixtures/block_getblockreward.json +1 -0
- data/spec/fixtures/contract_getabi.json +1 -0
- data/spec/fixtures/proxy/eth_blocknumber.json +1 -0
- data/spec/fixtures/proxy/eth_call.json +1 -0
- data/spec/fixtures/proxy/eth_estimategas.json +1 -0
- data/spec/fixtures/proxy/eth_gasprice.json +1 -0
- data/spec/fixtures/proxy/eth_getblockbynumber.json +1 -0
- data/spec/fixtures/proxy/eth_getblocktransactioncountbynumber.json +1 -0
- data/spec/fixtures/proxy/eth_getcode.json +1 -0
- data/spec/fixtures/proxy/eth_getstorageat.json +1 -0
- data/spec/fixtures/proxy/eth_gettransactionbyhash.json +1 -0
- data/spec/fixtures/proxy/eth_gettransactionbynumberandindex.json +1 -0
- data/spec/fixtures/proxy/eth_gettransactioncount.json +1 -0
- data/spec/fixtures/proxy/eth_gettransactionreceipt.json +1 -0
- data/spec/fixtures/proxy/eth_getunclebyblockbynumberandindex.json +1 -0
- data/spec/fixtures/proxy/eth_sendrawtransaction.json +1 -0
- data/spec/fixtures/stats/ethprice.json +1 -0
- data/spec/fixtures/stats/ethsupply.json +1 -0
- data/spec/fixtures/stats/tokensupply.json +1 -0
- data/spec/fixtures/token/tokensupply.json +1 -0
- data/spec/fixtures/transaction_getstatus.json +1 -0
- data/spec/spec_helper.rb +80 -0
- metadata +286 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 22e4fa7464ac88fdc505706394490429a1edbfe8
|
4
|
+
data.tar.gz: 8b88fcd489a48748b35faa0da2be5f9a69f0e38b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ec04cb7c4cf8e97219b4e7d9702d2e1c40ce540d4fed234c6470f947fdf7426f1f0170ede8f0538b762a122ab8e4f8d4c3b3eaaea99c2cb27afc231dd6f713a3
|
7
|
+
data.tar.gz: 9da44af52fe95171f91d1675360046e12b6f0f7074b55db385f98a11d870ab821b97641390ca96516bb59183cbbc3e3b2a188a650abbc8d2f76fe9dab10c4e5b
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# etherscan
|
2
|
+
|
3
|
+
Access to the API of etherscan.io and the ethereum blockchain
|
4
|
+
|
5
|
+
Forked from: https://github.com/sebs/etherscanio-rb
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
etherscanio is published to rubygems.
|
10
|
+
|
11
|
+
Dpl requires ruby with a version greater than 1.9.3
|
12
|
+
* To install: gem install etherscanio
|
13
|
+
|
14
|
+
|
15
|
+
## Work in Progress
|
16
|
+
|
17
|
+
Neither is is this stable, nor secure. Although all releases will be going through rubygems.
|
data/Rakefile
ADDED
data/etherscan.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'etherscan'
|
8
|
+
spec.version = '0.0.6'
|
9
|
+
spec.authors = ['wuminzhe']
|
10
|
+
spec.email = ['wuminzhe@gmail.com']
|
11
|
+
spec.description = '%q{Forked from: https://github.com/sebs/etherscanio-rb. 3rd party using to the API at etherscan.io}'
|
12
|
+
spec.summary = '3rd party using to the API at etherscan.io'
|
13
|
+
spec.homepage = 'https://github.com/wuminzhe/etherscanio-rb'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.extra_rdoc_files = ['README.md']
|
22
|
+
|
23
|
+
spec.add_dependency 'rest-client'
|
24
|
+
spec.add_development_dependency 'bundler'
|
25
|
+
spec.add_development_dependency 'rake'
|
26
|
+
spec.add_development_dependency 'rspec'
|
27
|
+
spec.add_development_dependency 'guard'
|
28
|
+
spec.add_development_dependency 'guard-rspec'
|
29
|
+
spec.add_development_dependency 'rubocop'
|
30
|
+
spec.add_development_dependency 'guard-rubocop'
|
31
|
+
spec.add_development_dependency 'webmock'
|
32
|
+
spec.add_development_dependency 'yard'
|
33
|
+
spec.add_development_dependency 'yard-ghpages'
|
34
|
+
end
|
data/lib/etherscan.rb
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
module Etherscan
|
2
|
+
class << self
|
3
|
+
attr_accessor :api_key, :chain
|
4
|
+
end
|
5
|
+
|
6
|
+
module Account
|
7
|
+
class << self
|
8
|
+
def txlist(address, startblock, endblock, sort = 'desc', page = nil, offset = nil)
|
9
|
+
call = Etherscan::Call.new(Etherscan.chain, 'account', 'txlist')
|
10
|
+
call.api_key = Etherscan.api_key
|
11
|
+
call.address = address
|
12
|
+
call.startblock = startblock
|
13
|
+
call.endblock = endblock
|
14
|
+
call.page = page
|
15
|
+
call.offset = offset
|
16
|
+
call.sort = sort
|
17
|
+
call.fetch
|
18
|
+
end
|
19
|
+
|
20
|
+
def txlistinternal(address, startblock, endblock, sort = 'desc', page = nil, offset = nil)
|
21
|
+
call = Etherscan::Call.new(Etherscan.chain, 'account', 'txlistinternal')
|
22
|
+
call.api_key = Etherscan.api_key
|
23
|
+
call.address = address
|
24
|
+
call.startblock = startblock
|
25
|
+
call.endblock = endblock
|
26
|
+
call.page = page
|
27
|
+
call.offset = offset
|
28
|
+
call.sort = sort
|
29
|
+
call.fetch
|
30
|
+
end
|
31
|
+
|
32
|
+
def txlistinternal_txhash(txhash)
|
33
|
+
call = Etherscan::Call.new(Etherscan.chain, 'account', 'txlistinternal')
|
34
|
+
call.api_key = Etherscan.api_key
|
35
|
+
call.txhash = txhash
|
36
|
+
call.fetch
|
37
|
+
end
|
38
|
+
|
39
|
+
def balance(address, tag)
|
40
|
+
call = Etherscan::Call.new(Etherscan.chain, 'account', 'balance')
|
41
|
+
call.api_key = Etherscan.api_key
|
42
|
+
call.address = address
|
43
|
+
call.tag = tag
|
44
|
+
call.fetch
|
45
|
+
end
|
46
|
+
|
47
|
+
def getminedblocks(address, blocktype, page = nil, offset = nil)
|
48
|
+
call = Etherscan::Call.new(Etherscan.chain, 'account', 'getminedblocks')
|
49
|
+
call.api_key = Etherscan.api_key
|
50
|
+
call.page = page
|
51
|
+
call.offset = offset
|
52
|
+
call.address = address
|
53
|
+
call.blocktype = blocktype
|
54
|
+
call.fetch
|
55
|
+
end
|
56
|
+
|
57
|
+
def balancemulti(address, tag)
|
58
|
+
call = Etherscan::Call.new(Etherscan.chain, 'account', 'balancemulti')
|
59
|
+
call.api_key = Etherscan.api_key
|
60
|
+
call.address = address
|
61
|
+
call.tag = tag
|
62
|
+
call.fetch
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
module Contract
|
68
|
+
class << self
|
69
|
+
def getabi(address)
|
70
|
+
call = Etherscan::Call.new(Etherscan.chain, 'contract', 'getabi')
|
71
|
+
call.api_key = Etherscan.api_key
|
72
|
+
call.address = address
|
73
|
+
call.fetch
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
module Transaction
|
79
|
+
class << self
|
80
|
+
def getstatus(txhash)
|
81
|
+
call = Etherscan::Call.new(Etherscan.chain, 'transaction', 'getstatus')
|
82
|
+
call.api_key = Etherscan.api_key
|
83
|
+
call.txhash = txhash
|
84
|
+
call.fetch
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
module Block
|
90
|
+
class << self
|
91
|
+
def getblockreward(blockno)
|
92
|
+
call = Etherscan::Call.new(Etherscan.chain, 'block', 'getblockreward')
|
93
|
+
call.api_key = Etherscan.api_key
|
94
|
+
call.blockno = blockno
|
95
|
+
call.fetch
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
module Proxy
|
101
|
+
class << self
|
102
|
+
def eth_block_number
|
103
|
+
call = Etherscan::Call.new(Etherscan.chain, 'proxy', 'eth_blockNumber')
|
104
|
+
call.api_key = Etherscan.api_key
|
105
|
+
call.fetch
|
106
|
+
end
|
107
|
+
|
108
|
+
def eth_get_block_by_number(tag, boolean)
|
109
|
+
call = Etherscan::Call.new(Etherscan.chain, 'proxy', 'eth_getBlockByNumber')
|
110
|
+
call.api_key = Etherscan.api_key
|
111
|
+
call.tag = tag
|
112
|
+
call.boolean = boolean
|
113
|
+
call.fetch
|
114
|
+
end
|
115
|
+
|
116
|
+
def eth_send_raw_transaction(hex)
|
117
|
+
call = Etherscan::Call.new(Etherscan.chain, 'proxy', 'eth_sendRawTransaction')
|
118
|
+
call.api_key = Etherscan.api_key
|
119
|
+
call.hex = hex
|
120
|
+
call.fetch
|
121
|
+
end
|
122
|
+
|
123
|
+
def eth_get_transaction_count(address, tag)
|
124
|
+
call = Etherscan::Call.new(Etherscan.chain, 'proxy', 'eth_getTransactionCount')
|
125
|
+
call.api_key = Etherscan.api_key
|
126
|
+
call.address = address
|
127
|
+
call.tag = tag
|
128
|
+
call.fetch
|
129
|
+
end
|
130
|
+
|
131
|
+
def eth_get_transaction_by_hash(txhash)
|
132
|
+
call = Etherscan::Call.new(Etherscan.chain, 'proxy', 'eth_getTransactionByHash')
|
133
|
+
call.api_key = Etherscan.api_key
|
134
|
+
call.txhash = txhash
|
135
|
+
call.fetch
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
module Etherscan
|
3
|
+
class ReturnError < RuntimeError; end
|
4
|
+
|
5
|
+
class Call
|
6
|
+
attr_accessor :chain,
|
7
|
+
:mod,
|
8
|
+
:action,
|
9
|
+
:api_key,
|
10
|
+
:address,
|
11
|
+
:tag,
|
12
|
+
:startblock,
|
13
|
+
:endblock,
|
14
|
+
:sort,
|
15
|
+
:page,
|
16
|
+
:offset,
|
17
|
+
:sort,
|
18
|
+
:blocktype,
|
19
|
+
:txhash,
|
20
|
+
:blockno,
|
21
|
+
:hex,
|
22
|
+
:boolean
|
23
|
+
|
24
|
+
CHAINS = {
|
25
|
+
mainnet: 'http://api.etherscan.io/api?',
|
26
|
+
ropsten: 'https://ropsten.etherscan.io/api?',
|
27
|
+
kovan: 'https://kovan.etherscan.io/api?',
|
28
|
+
rinkeby: 'https://rinkeby.etherscan.io/api?'
|
29
|
+
}
|
30
|
+
|
31
|
+
def initialize(chain, mod, action)
|
32
|
+
@chain = chain.to_sym
|
33
|
+
@base = CHAINS[chain.to_sym]
|
34
|
+
@mod = mod
|
35
|
+
@action = action
|
36
|
+
@api_key = false
|
37
|
+
end
|
38
|
+
|
39
|
+
def fetch
|
40
|
+
query_url = to_s
|
41
|
+
Etherscan.logger.debug query_url
|
42
|
+
res = RestClient.get(query_url, {}).body
|
43
|
+
Etherscan.logger.debug res
|
44
|
+
data = JSON.parse(res)
|
45
|
+
return [:error, data['error']] if data['error']
|
46
|
+
return [:error, data['message']] if (data['status'] && data['status'] != '1')
|
47
|
+
return [:ok, data['result']]
|
48
|
+
rescue => e
|
49
|
+
Etherscan.logger.error "Error: #{e}"
|
50
|
+
Etherscan.logger.error e.backtrace[0, 20].join("\n")
|
51
|
+
return [:error, e.message]
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_s
|
55
|
+
uri = 'module=' + mod + '&action=' + action
|
56
|
+
uri += '&apikey=' + api_key if api_key
|
57
|
+
uri += address_fragment
|
58
|
+
uri += '&startblock=' + startblock.to_s if startblock
|
59
|
+
uri += '&endblock=' + endblock.to_s if endblock
|
60
|
+
uri += '&blocktype=' + blocktype if blocktype
|
61
|
+
uri += '&txhash=' + txhash if txhash
|
62
|
+
uri += '&blockno=' + blockno.to_s if blockno
|
63
|
+
uri += '&offset=' + offset.to_s if offset
|
64
|
+
uri += '&sort=' + sort if sort
|
65
|
+
uri += '&page=' + page.to_s if page
|
66
|
+
uri += '&tag=' + tag if tag
|
67
|
+
uri += '&hex=' + hex if hex
|
68
|
+
uri += '&boolean=' + boolean if boolean
|
69
|
+
@base + uri
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def address_fragment
|
75
|
+
res = ''
|
76
|
+
res += '&address=' + address if (address && !address.is_a?(Array))
|
77
|
+
res += '&address=' + address.join(',') if (address && address.is_a?(Array))
|
78
|
+
res
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Etherscanio::Api do
|
4
|
+
describe 'account_balance' do
|
5
|
+
subject { Etherscanio::Api.new(apikey).account_balance(address, tag) }
|
6
|
+
|
7
|
+
context 'one address' do
|
8
|
+
subject { Etherscanio::Api.new(apikey).account_balance(address, tag) }
|
9
|
+
let(:apikey) { 'YourApiKeyToken' }
|
10
|
+
let(:address) { '0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae' }
|
11
|
+
let(:tag) { 'latest' }
|
12
|
+
it { is_expected.to be_a(Object) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Etherscanio::Api do
|
4
|
+
describe 'account_balancemulti' do
|
5
|
+
|
6
|
+
context 'multiple address' do
|
7
|
+
subject { Etherscanio::Api.new(apikey).account_balancemulti(address, tag) }
|
8
|
+
let(:apikey) { 'YourApiKeyToken' }
|
9
|
+
let(:address) do
|
10
|
+
%w(
|
11
|
+
0xddbd2b932c763ba5b1b7ae3b362eac3e8d40121a
|
12
|
+
0x63a9975ba31b0b9626b34300f7f627147df1f526
|
13
|
+
0x198ef1ec325a96cc354c7266a038be8b5c558f67
|
14
|
+
)
|
15
|
+
end
|
16
|
+
let(:tag) { 'latest' }
|
17
|
+
it { is_expected.to be_a(Object) }
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Etherscanio::Api do
|
4
|
+
describe 'account_getminedblocks' do
|
5
|
+
subject { Etherscanio::Api.new(apikey).account_getminedblocks(address, blocktype) }
|
6
|
+
|
7
|
+
context 'no paging' do
|
8
|
+
let(:apikey) { 'YourApiKeyToken' }
|
9
|
+
let(:address) { '0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae' }
|
10
|
+
let(:blocktype) { 'block' }
|
11
|
+
it { is_expected.to be_a(Object) }
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'paging' do
|
15
|
+
subject { Etherscanio::Api.new(apikey).account_getminedblocks(address, blocktype, page, offset) }
|
16
|
+
let(:apikey) { 'YourApiKeyToken' }
|
17
|
+
let(:address) { '0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae' }
|
18
|
+
let(:page) { 1 }
|
19
|
+
let(:offset) { 10 }
|
20
|
+
let(:blocktype) { 'block' }
|
21
|
+
it { is_expected.to be_a(Object) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Etherscanio::Api do
|
4
|
+
describe 'account_txlistinternal' do
|
5
|
+
subject { Etherscanio::Api.new(apikey).account_txlistinternal(address, startblock, endblock, sort) }
|
6
|
+
|
7
|
+
context 'no paging' do
|
8
|
+
let(:apikey) { 'YourApiKeyToken' }
|
9
|
+
let(:address) { '0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae' }
|
10
|
+
let(:startblock) { 0 }
|
11
|
+
let(:endblock) { 99_999_999 }
|
12
|
+
let(:sort) { 'desc' }
|
13
|
+
it { is_expected.to be_a(Object) }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'paging' do
|
17
|
+
subject { Etherscanio::Api.new(apikey).account_txlistinternal(address, startblock, endblock, sort, page, offset) }
|
18
|
+
let(:apikey) { 'YourApiKeyToken' }
|
19
|
+
let(:address) { '0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae' }
|
20
|
+
let(:startblock) { 0 }
|
21
|
+
let(:endblock) { 99_999_999 }
|
22
|
+
let(:sort) { 'desc' }
|
23
|
+
let(:page) { 1 }
|
24
|
+
let(:offset) { 10 }
|
25
|
+
it { is_expected.to be_a(Object) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Etherscanio::Api do
|
4
|
+
describe 'account_txlist' do
|
5
|
+
subject { Etherscanio::Api.new(apikey).account_txlist(address, startblock, endblock, sort) }
|
6
|
+
|
7
|
+
context 'no paging' do
|
8
|
+
let(:apikey) { 'YourApiKeyToken' }
|
9
|
+
let(:address) { '0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae' }
|
10
|
+
let(:startblock) { 0 }
|
11
|
+
let(:endblock) { 99_999_999 }
|
12
|
+
let(:sort) { 'desc' }
|
13
|
+
it { is_expected.to be_a(Object) }
|
14
|
+
end
|
15
|
+
context 'paging' do
|
16
|
+
# subject { Etherscanio::Api.new(apikey).account_txlist(address, startblock, endblock, sort, page, offset) }
|
17
|
+
let(:apikey) { 'YourApiKeyToken' }
|
18
|
+
let(:address) { '0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae' }
|
19
|
+
let(:startblock) { 0 }
|
20
|
+
let(:endblock) { 99_999_999 }
|
21
|
+
let(:sort) { 'desc' }
|
22
|
+
let(:page) { 1 }
|
23
|
+
let(:offset) { 10 }
|
24
|
+
it { is_expected.to be_a(Object) }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|