blockchain-ruby 1.0.0
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 +3 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +41 -0
- data/LICENSE.txt +20 -0
- data/README.md +96 -0
- data/blockchain-ruby.gemspec +27 -0
- data/lib/address.rb +48 -0
- data/lib/block.rb +27 -0
- data/lib/blockchain.rb +35 -0
- data/lib/realtime.rb +53 -0
- data/lib/transaction.rb +59 -0
- data/spec/address_spec.rb +45 -0
- data/spec/block_spec.rb +42 -0
- data/spec/reatime_spec.rb +82 -0
- data/spec/spec_helper.rb +84 -0
- data/spec/transaction_spec.rb +87 -0
- metadata +149 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 741747d1cc360130278facebe80df167706167a2
|
|
4
|
+
data.tar.gz: 6eed1fa2d389cd2e2ddd1d983a2db76dc9bc543d
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a9d07d23a07df7a27941b5242784045ad6045da4fff26d286521173f5b92c843a38ee584140eed0c5c4f9f684750a797c983897709309882c3f20eebb4bcbd4d
|
|
7
|
+
data.tar.gz: 414e3b362df7b07dd800de6168f4e397a5e52dedf85de88b30a92bd09d358f905b2ea279b04a4de01e9cc5d3685c860b86046a8254f432a52b248c3991930ff2
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
blockchain-ruby (1.0.0)
|
|
5
|
+
bitcoin-money (~> 0.5.1)
|
|
6
|
+
monetize (~> 0.3.0)
|
|
7
|
+
money (~> 6.1.1)
|
|
8
|
+
|
|
9
|
+
GEM
|
|
10
|
+
remote: https://rubygems.org/
|
|
11
|
+
specs:
|
|
12
|
+
bitcoin-money (0.5.1)
|
|
13
|
+
diff-lcs (1.2.5)
|
|
14
|
+
fakeweb (1.3.0)
|
|
15
|
+
i18n (0.6.11)
|
|
16
|
+
monetize (0.3.0)
|
|
17
|
+
money (~> 6.1.0.beta1)
|
|
18
|
+
money (6.1.1)
|
|
19
|
+
i18n (~> 0.6.4)
|
|
20
|
+
rake (10.3.2)
|
|
21
|
+
rspec (3.0.0)
|
|
22
|
+
rspec-core (~> 3.0.0)
|
|
23
|
+
rspec-expectations (~> 3.0.0)
|
|
24
|
+
rspec-mocks (~> 3.0.0)
|
|
25
|
+
rspec-core (3.0.1)
|
|
26
|
+
rspec-support (~> 3.0.0)
|
|
27
|
+
rspec-expectations (3.0.1)
|
|
28
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
29
|
+
rspec-support (~> 3.0.0)
|
|
30
|
+
rspec-mocks (3.0.1)
|
|
31
|
+
rspec-support (~> 3.0.0)
|
|
32
|
+
rspec-support (3.0.0)
|
|
33
|
+
|
|
34
|
+
PLATFORMS
|
|
35
|
+
ruby
|
|
36
|
+
|
|
37
|
+
DEPENDENCIES
|
|
38
|
+
blockchain-ruby!
|
|
39
|
+
fakeweb (~> 1.3.0)
|
|
40
|
+
rake
|
|
41
|
+
rspec (~> 3.0.0)
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
blockchain-ruby
|
|
2
|
+
===============
|
|
3
|
+
|
|
4
|
+
Gives Rubyists the ability to traverse the blockchain in a semantic way.
|
|
5
|
+
|
|
6
|
+
The following functionality has been implemented:
|
|
7
|
+
|
|
8
|
+
Addresses
|
|
9
|
+
---------
|
|
10
|
+
Search for addresses with hash160 or address
|
|
11
|
+
|
|
12
|
+
returns `nil` if not found
|
|
13
|
+
~~~ruby
|
|
14
|
+
a = Blockchain::Address.find('143y8gQbhmgePi4QJyL6QBi8zk4PSM5KQr')
|
|
15
|
+
a.hash160 # => '217810f57fd7cdf79274c5d5e4a891fadc74887b'
|
|
16
|
+
a.address # => '143y8gQbhmgePi4QJyL6QBi8zk4PSM5KQr'
|
|
17
|
+
a.n_tx # => 143
|
|
18
|
+
a.n_unredeemed # => 56
|
|
19
|
+
a.total_received # => #<Btc BTC:0.00124124 mBTC:1.24124 uBTC:1241.24 Satoshis:124124.0>
|
|
20
|
+
a.total_sent # => #<Btc BTC:5.829e-05 mBTC:0.05829 uBTC:58.29 Satoshis:5829.0>
|
|
21
|
+
a.final_balance # => #<Btc BTC:0.00090215 mBTC:0.90215 uBTC:902.15 Satoshis:90215.0>
|
|
22
|
+
a.refresh! # refreshes the address
|
|
23
|
+
a.to_s # => '217810f57fd7cdf79274c5d5e4a891fadc74887b'
|
|
24
|
+
a.first_seen # => #<DateTime: 2014-08-22T18:05:32-04:00 ((2456892j,79532s,800786000n),-14400s,2299161j)>
|
|
25
|
+
txs = a.txs
|
|
26
|
+
~~~
|
|
27
|
+
|
|
28
|
+
Transactions
|
|
29
|
+
------------
|
|
30
|
+
Search for transactions with transaction index or hash
|
|
31
|
+
|
|
32
|
+
returns `nil` if not found
|
|
33
|
+
~~~ruby
|
|
34
|
+
t = txs[0]
|
|
35
|
+
t.hsh # => 'bebc1f8db50669d8ab7c7181aa92ffe3f170510d5894cb0a4100af23e335210f'
|
|
36
|
+
t.ver # => 1
|
|
37
|
+
t.vin_sz # => 1
|
|
38
|
+
t.vout_sz # => 2
|
|
39
|
+
t.time # => #<DateTime: 2014-08-22T18:05:32-04:00 ((2456892j,79532s,800786000n),-14400s,2299161j)>
|
|
40
|
+
t.size # => 258
|
|
41
|
+
t.result # => 0
|
|
42
|
+
t.relayed_by # => "127.0.01"
|
|
43
|
+
t.double_spend # => false
|
|
44
|
+
t.block_height # => 317010
|
|
45
|
+
t.tx_index # => 62922222
|
|
46
|
+
|
|
47
|
+
t.txtotalbtcoutput # => #<Btc BTC:0.00124124 mBTC:1.24124 uBTC:1241.24 Satoshis:124124.0>
|
|
48
|
+
t.txtotalbtcinput # => #<Btc BTC:5.829e-05 mBTC:0.05829 uBTC:58.29 Satoshis:5829.0>
|
|
49
|
+
t.txfee # => #<Btc BTC:0.00090215 mBTC:0.90215 uBTC:902.15 Satoshis:90215.0>
|
|
50
|
+
|
|
51
|
+
inputs = t.inputs # array of Blockchain::Transaction::Input
|
|
52
|
+
out = t.out # array of Blockchain::Transaction::Output
|
|
53
|
+
|
|
54
|
+
# INPUTs
|
|
55
|
+
i = inputs[0]
|
|
56
|
+
i.script # => '76a9141f689f046aae32021905eeec37baef94dd591ff588ac'
|
|
57
|
+
i.prev_out # => Blockchain::Transaction.find(62918382) | the tx_index of last tx
|
|
58
|
+
|
|
59
|
+
# OUTPUTs
|
|
60
|
+
o = out[0]
|
|
61
|
+
o.script # => '76a9141f689f046aae32021905eeec37baef94dd591ff588ac'
|
|
62
|
+
o.n # => 0
|
|
63
|
+
o.value # => 10000
|
|
64
|
+
o.addr # => '13s5H9qsCDxsbCuZF5mGbg6rMLziQAnrxr'
|
|
65
|
+
o.tx_index # => 62922222
|
|
66
|
+
o.spent # => true
|
|
67
|
+
o.type # => 0
|
|
68
|
+
~~~
|
|
69
|
+
|
|
70
|
+
Blocks
|
|
71
|
+
------
|
|
72
|
+
Search for blocks with block index or block hash
|
|
73
|
+
|
|
74
|
+
returns `nil` if not found
|
|
75
|
+
~~~ruby
|
|
76
|
+
b = Blockchain::Block.find(458453)
|
|
77
|
+
b.hsh # => '000000000000000024b816f859d85a955dfe8db09e3735d51755cb5f9cf2f63f'
|
|
78
|
+
b.ver # => 2
|
|
79
|
+
b.prev_block # => '00000000000000000894f4f2cbd1dbc8dd0b6d2f3a9a89582f5456516f2bc7d9'
|
|
80
|
+
b.mrkl_root # => 'baab986e40ac0ea11b7fff8f207b9c8cdbcf49b6b58e66829f8fe9cc5c017e09'
|
|
81
|
+
b.time # => #<DateTime: 2014-08-22T22:12:23+00:00 ((2456892j,79943s,0n),+0s,2299161j)>
|
|
82
|
+
b.bits # => 405675096
|
|
83
|
+
b.fee # => #<Btc BTC:0.16328705 mBTC:163.28705 uBTC:163287.05 Satoshis:16328705.0>
|
|
84
|
+
b.nonce # => 2030590116
|
|
85
|
+
b.n_tx # => 979
|
|
86
|
+
b.size # => 539809
|
|
87
|
+
b.block_index # => 458453
|
|
88
|
+
b.main_chain # => true
|
|
89
|
+
b.height # => 317016
|
|
90
|
+
b.received_time # => #<DateTime: 2014-08-22T22:12:23+00:00 ((2456892j,79943s,0n),+0s,2299161j)>
|
|
91
|
+
b.relayed_by # => "193.187.79.76"
|
|
92
|
+
b.tx # => array of Blockchain::Transaction in the block
|
|
93
|
+
~~~
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |gem|
|
|
6
|
+
gem.name = "blockchain-ruby"
|
|
7
|
+
gem.version = "1.0.0"
|
|
8
|
+
gem.authors = ["James Larisch"]
|
|
9
|
+
gem.email = ["root@jameslarisch.com"]
|
|
10
|
+
gem.description = "Convenient wrapper around public Blockchain.info API."
|
|
11
|
+
gem.summary = "Convenient wrapper around public Blockchain.info API."
|
|
12
|
+
gem.homepage = "https://github.com/zenchilabs/blockchain-ruby"
|
|
13
|
+
|
|
14
|
+
gem.files = `git ls-files`.split($/)
|
|
15
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
|
16
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
|
17
|
+
gem.require_paths = ["lib"]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
gem.add_development_dependency "rspec", "~> 3.0.0"
|
|
21
|
+
gem.add_development_dependency "fakeweb", "~> 1.3.0"
|
|
22
|
+
gem.add_development_dependency "rake"
|
|
23
|
+
|
|
24
|
+
gem.add_dependency "money", "~> 6.1.1"
|
|
25
|
+
gem.add_dependency "monetize", "~> 0.3.0"
|
|
26
|
+
gem.add_dependency "bitcoin-money", "~> 0.5.1"
|
|
27
|
+
end
|
data/lib/address.rb
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Blockchain
|
|
2
|
+
class Address
|
|
3
|
+
attr_reader :hash160, :address, :total_received
|
|
4
|
+
attr_reader :total_sent, :final_balance, :txs
|
|
5
|
+
|
|
6
|
+
def self.find(address)
|
|
7
|
+
self.new(Blockchain.rawaddr(address)) rescue nil
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def initialize(a)
|
|
11
|
+
meta_init(a)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private def meta_init(a)
|
|
15
|
+
a.each_key { |k| instance_variable_set("@#{k}", a[k]) }
|
|
16
|
+
@total_received = Btc.from_satoshis(@total_received || 0)
|
|
17
|
+
@total_sent = Btc.from_satoshis(@total_sent || 0)
|
|
18
|
+
@final_balance = Btc.from_satoshis(@final_balance || 0)
|
|
19
|
+
@txs.map! { |t| Blockchain::Transaction.new(t) }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def n_tx
|
|
23
|
+
@n_tx || 0
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def n_unredeemed
|
|
27
|
+
@n_unredeemed || 0
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def firstseen
|
|
31
|
+
DateTime.strptime(Blockchain.q("addressfirstseen/#{@address}"), '%s')
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def to_s
|
|
35
|
+
@address
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def ==(o)
|
|
39
|
+
o.instance_variables == self.instance_variables
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def refresh!
|
|
43
|
+
address = @address
|
|
44
|
+
instance_variables.each { |i| instance_variable_set(i, nil) }
|
|
45
|
+
meta_init(Blockchain.rawaddr(address))
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
data/lib/block.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Blockchain
|
|
2
|
+
class Block
|
|
3
|
+
attr_reader :hsh, :ver, :prev_block, :mrkl_root
|
|
4
|
+
attr_reader :time, :bits, :fee, :nonce, :n_tx, :size
|
|
5
|
+
attr_reader :block_index, :main_chain, :height, :received_time
|
|
6
|
+
attr_reader :relayed_by, :tx
|
|
7
|
+
|
|
8
|
+
# id can be block_hash or block_index
|
|
9
|
+
def self.find(id)
|
|
10
|
+
self.new(Blockchain.rawblock(id)) rescue nil
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize(b)
|
|
14
|
+
@hsh = b.delete('hash') # hash is an unfortunate word
|
|
15
|
+
b.each_key { |k| instance_variable_set("@#{k}", b[k]) }
|
|
16
|
+
@time = DateTime.strptime(@time.to_s, '%s')
|
|
17
|
+
@received_time = DateTime.strptime(@received_time.to_s, '%s')
|
|
18
|
+
@tx.map! { |t| Blockchain::Transaction.new(t) }
|
|
19
|
+
@fee = Btc.from_satoshis(fee)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def previous
|
|
23
|
+
Block.find(@prev_block)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
data/lib/blockchain.rb
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Blockchain
|
|
2
|
+
ROOT = 'https://blockchain.info'
|
|
3
|
+
|
|
4
|
+
def self.get(path)
|
|
5
|
+
response = open("#{ROOT}/#{path}")
|
|
6
|
+
response.read if response.status.first == '200'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.q(path)
|
|
10
|
+
self.get("q/#{path}")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.rawblock(block)
|
|
14
|
+
JSON.parse(self.get("rawblock/#{block}"))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.rawtx(tx)
|
|
18
|
+
JSON.parse(self.get("rawtx/#{tx}"))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.rawaddr(address)
|
|
22
|
+
JSON.parse(self.get("rawaddr/#{address}"))
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
require 'money'
|
|
27
|
+
require 'bigdecimal'
|
|
28
|
+
require 'open-uri'
|
|
29
|
+
require 'date'
|
|
30
|
+
require 'btc'
|
|
31
|
+
require 'realtime'
|
|
32
|
+
require 'transaction'
|
|
33
|
+
require 'address'
|
|
34
|
+
require 'block'
|
|
35
|
+
|
data/lib/realtime.rb
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Blockchain
|
|
2
|
+
def self.difficulty
|
|
3
|
+
BigDecimal.new(self.q('getdifficulty'))
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def self.block_count
|
|
7
|
+
self.q('getblockcount').to_i
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.latest_hash
|
|
11
|
+
self.q('latesthash')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.bc_per_block
|
|
15
|
+
Btc.new(self.q('bcperblock'))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.total
|
|
19
|
+
Btc.new(self.q('totalbc'))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.probability
|
|
23
|
+
BigDecimal.new(self.q('probability'))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.hashes_to_win
|
|
27
|
+
self.q('hashestowin').to_i
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.next_retarget
|
|
31
|
+
self.q('nextretarget').to_i
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.avg_tx_size
|
|
35
|
+
self.q('avgtxsize').to_i
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.avg_tx_value
|
|
39
|
+
self.q('avgtxvalue').to_i
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.interval
|
|
43
|
+
BigDecimal.new(self.q('interval'))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def self.eta
|
|
47
|
+
BigDecimal.new(self.q('eta'))
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def self.avg_tx_number
|
|
51
|
+
self.q('avgtxnumber').to_i
|
|
52
|
+
end
|
|
53
|
+
end
|
data/lib/transaction.rb
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module Blockchain
|
|
2
|
+
class Transaction
|
|
3
|
+
attr_reader :hsh, :ver, :vin_sz, :vout_sz, :time, :size, :result, :double_spend
|
|
4
|
+
attr_reader :relayed_by, :block_height, :tx_index, :inputs, :out
|
|
5
|
+
|
|
6
|
+
def self.find(transaction)
|
|
7
|
+
self.new(Blockchain.rawtx(transaction))
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def initialize(t)
|
|
11
|
+
@hsh = t.delete('hash')
|
|
12
|
+
t.each_key { |k| instance_variable_set("@#{k}", t[k]) }
|
|
13
|
+
@inputs.map! { |i| Input.new(i) }
|
|
14
|
+
@out.map! { |o| Output.new(o) }
|
|
15
|
+
@time = DateTime.strptime(@time.to_s, '%s')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def txtotalbtcoutput
|
|
19
|
+
Btc.from_satoshis(Blockchain.q("txtotalbtcoutput/#{@hsh}"))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def txtotalbtcinput
|
|
23
|
+
Btc.from_satoshis(Blockchain.q("txtotalbtcinput/#{@hsh}"))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def txfee
|
|
27
|
+
Btc.from_satoshis(Blockchain.q("txfee/#{@hsh}"))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def ==(o)
|
|
31
|
+
o.instance_variables == self.instance_variables
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
class Input
|
|
35
|
+
attr_reader :script, :addr, :n, :tx_index
|
|
36
|
+
|
|
37
|
+
def initialize(i)
|
|
38
|
+
@script = i['script']
|
|
39
|
+
@prev_out = i['prev_out']
|
|
40
|
+
@addr = @prev_out['addr']
|
|
41
|
+
@n = @prev_out['n']
|
|
42
|
+
@tx_index = @prev_out['tx_index']
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def prev_out
|
|
46
|
+
Transaction.find(@tx_index)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class Output
|
|
51
|
+
attr_reader :n, :addr, :tx_index, :spent, :type, :script
|
|
52
|
+
|
|
53
|
+
def initialize(o)
|
|
54
|
+
o.each_key { |k| instance_variable_set"@#{k}", o[k] }
|
|
55
|
+
@value = Btc.from_satoshis(@value)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Blockchain::Address do
|
|
4
|
+
|
|
5
|
+
before :all do
|
|
6
|
+
FakeWeb.allow_net_connect = false
|
|
7
|
+
@test = '1AJbsFZ64EpEfS5UAjAfcUG8pH8Jn3rn1F'
|
|
8
|
+
fake_raw(TEST_ADDRESS)
|
|
9
|
+
@a = Blockchain::Address.find(@test)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'should get first seen' do
|
|
13
|
+
fake_q('addressfirstseen', '1331482301')
|
|
14
|
+
expect(@a.firstseen).to eq(DateTime.strptime('1331482301', '%s'))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'should init all fields' do
|
|
18
|
+
expect(@a.hash160).to eq('660d4ef3a743e3e696ad990364e555c271ad504b')
|
|
19
|
+
expect(@a.address).to eq('1AJbsFZ64EpEfS5UAjAfcUG8pH8Jn3rn1F')
|
|
20
|
+
expect(@a.n_tx).to eq(17)
|
|
21
|
+
expect(@a.n_unredeemed).to eq(2)
|
|
22
|
+
expect(@a.total_received).to eq(Btc.from_satoshis(1031350000))
|
|
23
|
+
expect(@a.total_sent).to eq(Btc.from_satoshis(931250000))
|
|
24
|
+
expect(@a.final_balance).to eq(Btc.from_satoshis(100100000))
|
|
25
|
+
expect(@a.txs).to eq([Blockchain::Transaction.new(JSON.parse(TEST_TRANSACTION))])
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'should refresh to same thing' do
|
|
29
|
+
a1 = @a.clone
|
|
30
|
+
@a.refresh!
|
|
31
|
+
expect(@a).to eq(a1)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def fake_q(path, body, address = @test)
|
|
35
|
+
FakeWeb.register_uri(:get,
|
|
36
|
+
"#{Blockchain::ROOT}/q/#{path}/#{address}",
|
|
37
|
+
body: body, status: 200)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def fake_raw(body, address = @test)
|
|
41
|
+
FakeWeb.register_uri(:get,
|
|
42
|
+
"#{Blockchain::ROOT}/rawaddr/#{address}",
|
|
43
|
+
body: body, status: 200)
|
|
44
|
+
end
|
|
45
|
+
end
|
data/spec/block_spec.rb
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Blockchain do
|
|
4
|
+
|
|
5
|
+
before(:each) do
|
|
6
|
+
FakeWeb.allow_net_connect = false
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
describe '.find' do
|
|
10
|
+
it 'should return nil if invalid raw block' do
|
|
11
|
+
FakeWeb.allow_net_connect = true
|
|
12
|
+
expect(Blockchain::Block.find('nonsense')).to be_nil
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'it should init all fields' do
|
|
16
|
+
fake('someid', TEST_BLOCK)
|
|
17
|
+
b = Blockchain::Block.find('someid')
|
|
18
|
+
expect(b.hsh).to eq('0000000000000bae09a7a393a8acded75aa67e46cb81f7acaa5ad94f9eacd103')
|
|
19
|
+
expect(b.ver).to eq(1)
|
|
20
|
+
expect(b.prev_block).to eq('00000000000007d0f98d9edca880a6c124e25095712df8952e0439ac7409738a')
|
|
21
|
+
expect(b.mrkl_root).to eq('935aa0ed2e29a4b81e0c995c39e06995ecce7ddbebb26ed32d550a72e8200bf5')
|
|
22
|
+
expect(b.time).to eq(DateTime.strptime('1322131230', '%s'))
|
|
23
|
+
expect(b.bits).to eq(437129626)
|
|
24
|
+
expect(b.nonce).to eq(2964215930)
|
|
25
|
+
expect(b.n_tx).to eq(22)
|
|
26
|
+
expect(b.size).to eq(9195)
|
|
27
|
+
expect(b.block_index).to eq(818044)
|
|
28
|
+
expect(b.main_chain).to eq(true)
|
|
29
|
+
expect(b.height).to eq(154595)
|
|
30
|
+
expect(b.fee).to eq(Btc.from_satoshis(12345678))
|
|
31
|
+
expect(b.received_time).to eq(DateTime.strptime('1322131301', '%s'))
|
|
32
|
+
expect(b.relayed_by).to eq('108.60.208.156')
|
|
33
|
+
expect(b.tx).to eq([Blockchain::Transaction.new(JSON.parse(TEST_TRANSACTION))])
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def fake(id, body)
|
|
38
|
+
FakeWeb.register_uri(:get, "#{Blockchain::ROOT}/rawblock/#{id}",
|
|
39
|
+
body: body, status: 200)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Blockchain do
|
|
4
|
+
|
|
5
|
+
before :all do
|
|
6
|
+
FakeWeb.allow_net_connect = false
|
|
7
|
+
@test_i = 123456
|
|
8
|
+
@test_i_s = '123456'
|
|
9
|
+
@test_f = 12345.12345
|
|
10
|
+
@test_f_s = '12345.12345'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'should get difficulty' do
|
|
14
|
+
fake('getdifficulty', @test_f_s)
|
|
15
|
+
expect(Blockchain.difficulty.to_f).to eq(@test_f)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'should get blockcount' do
|
|
19
|
+
fake('getblockcount', @test_i_s)
|
|
20
|
+
expect(Blockchain.block_count).to eq(@test_i)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'should get latesthash' do
|
|
24
|
+
fake('latesthash', @test_i_s)
|
|
25
|
+
expect(Blockchain.latest_hash).to eq(@test_i_s)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'should get bcperblock' do
|
|
29
|
+
fake('bcperblock', @test_i_s)
|
|
30
|
+
expect(Blockchain.bc_per_block.btc.to_f).to eq(@test_i.to_f)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'should get total' do
|
|
34
|
+
fake('totalbc', @test_i_s)
|
|
35
|
+
expect(Blockchain.total.btc.to_f).to eq(@test_i.to_f)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'should get probability' do
|
|
39
|
+
fake('probability', @test_f_s)
|
|
40
|
+
expect(Blockchain.probability.to_f).to eq(@test_f)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'should get hashestowin' do
|
|
44
|
+
fake('hashestowin', @test_i_s)
|
|
45
|
+
expect(Blockchain.hashes_to_win).to eq(@test_i)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'should get nextretarget' do
|
|
49
|
+
fake('nextretarget', @test_i_s)
|
|
50
|
+
expect(Blockchain.next_retarget).to eq(@test_i)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it 'should get avg_tx_size' do
|
|
54
|
+
fake('avgtxsize', @test_i_s)
|
|
55
|
+
expect(Blockchain.avg_tx_size).to eq(@test_i)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'should get avg_tx_value' do
|
|
59
|
+
fake('avgtxvalue', @test_i_s)
|
|
60
|
+
expect(Blockchain.avg_tx_value).to eq(@test_i)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it 'should get avg_tx_number' do
|
|
64
|
+
fake('avgtxnumber', @test_i_s)
|
|
65
|
+
expect(Blockchain.avg_tx_number).to eq(@test_i)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'should get interval' do
|
|
69
|
+
fake('interval', @test_f_s)
|
|
70
|
+
expect(Blockchain.interval.to_f).to eq(@test_f)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'should get eta' do
|
|
74
|
+
fake('eta', @test_f_s)
|
|
75
|
+
expect(Blockchain.eta.to_f).to eq(@test_f)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def fake(path, body)
|
|
79
|
+
FakeWeb.register_uri(:get, "#{Blockchain::ROOT}/q/#{path}",
|
|
80
|
+
body: body, status: 200)
|
|
81
|
+
end
|
|
82
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require 'fakeweb'
|
|
2
|
+
require 'blockchain'
|
|
3
|
+
|
|
4
|
+
TEST_TRANSACTION = <<-eos
|
|
5
|
+
{
|
|
6
|
+
"hash":"b6f6991d03df0e2e04dafffcd6bc418aac66049e2cd74b80f14ac86db1e3f0da",
|
|
7
|
+
"ver":1,
|
|
8
|
+
"vin_sz":1,
|
|
9
|
+
"vout_sz":2,
|
|
10
|
+
"time":1408744310,
|
|
11
|
+
"size":258,
|
|
12
|
+
"relayed_by":"64.179.201.80",
|
|
13
|
+
"block_height": 12200,
|
|
14
|
+
"tx_index":"12563028",
|
|
15
|
+
"result": 0,
|
|
16
|
+
"inputs":[
|
|
17
|
+
{
|
|
18
|
+
"prev_out":{
|
|
19
|
+
"n":1,
|
|
20
|
+
"addr":"143y8gQbhmgePi4QJyL6QBi8zk4PSM5KQr",
|
|
21
|
+
"value":"100000000",
|
|
22
|
+
"tx_index":12554260,
|
|
23
|
+
"type":0,
|
|
24
|
+
"script":"76a914641ad5051edd97029a003fe9efb29359fcee409d88ac"
|
|
25
|
+
},
|
|
26
|
+
"script":"76a914641ad5051edd97029a003fe9efb29359fcee409d88ac"
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"out":[
|
|
30
|
+
{
|
|
31
|
+
"n": 0,
|
|
32
|
+
"value": 100000,
|
|
33
|
+
"addr": "13s5H9qsCDxsbCuZF5mGbg6rMLziQAnrxr",
|
|
34
|
+
"tx_index": 62922222,
|
|
35
|
+
"spent": true,
|
|
36
|
+
"type": 0,
|
|
37
|
+
"script": "76a9141f689f046aae32021905eeec37baef94dd591ff588ac"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"n": 1,
|
|
41
|
+
"value": 1883055,
|
|
42
|
+
"addr": "143y8gQbhmgePi4QJyL6QBi8zk4PSM5KQr",
|
|
43
|
+
"tx_index": 62922222,
|
|
44
|
+
"spent": true,
|
|
45
|
+
"type": 0,
|
|
46
|
+
"script": "76a914217810f57fd7cdf79274c5d5e4a891fadc74887b88ac"
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
eos
|
|
51
|
+
|
|
52
|
+
TEST_BLOCK = <<-eos
|
|
53
|
+
{
|
|
54
|
+
"hash":"0000000000000bae09a7a393a8acded75aa67e46cb81f7acaa5ad94f9eacd103",
|
|
55
|
+
"ver":1,
|
|
56
|
+
"prev_block":"00000000000007d0f98d9edca880a6c124e25095712df8952e0439ac7409738a",
|
|
57
|
+
"mrkl_root":"935aa0ed2e29a4b81e0c995c39e06995ecce7ddbebb26ed32d550a72e8200bf5",
|
|
58
|
+
"time":1322131230,
|
|
59
|
+
"bits":437129626,
|
|
60
|
+
"nonce":2964215930,
|
|
61
|
+
"fee":12345678,
|
|
62
|
+
"n_tx":22,
|
|
63
|
+
"size":9195,
|
|
64
|
+
"block_index":818044,
|
|
65
|
+
"main_chain":true,
|
|
66
|
+
"height":154595,
|
|
67
|
+
"received_time":1322131301,
|
|
68
|
+
"relayed_by":"108.60.208.156",
|
|
69
|
+
"tx": [#{TEST_TRANSACTION}]
|
|
70
|
+
}
|
|
71
|
+
eos
|
|
72
|
+
|
|
73
|
+
TEST_ADDRESS = <<-eos
|
|
74
|
+
{
|
|
75
|
+
"hash160":"660d4ef3a743e3e696ad990364e555c271ad504b",
|
|
76
|
+
"address":"1AJbsFZ64EpEfS5UAjAfcUG8pH8Jn3rn1F",
|
|
77
|
+
"n_tx":17,
|
|
78
|
+
"n_unredeemed":2,
|
|
79
|
+
"total_received":1031350000,
|
|
80
|
+
"total_sent":931250000,
|
|
81
|
+
"final_balance":100100000,
|
|
82
|
+
"txs": [#{TEST_TRANSACTION}]
|
|
83
|
+
}
|
|
84
|
+
eos
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
describe Blockchain::Transaction do
|
|
5
|
+
|
|
6
|
+
before :all do
|
|
7
|
+
FakeWeb.allow_net_connect = true
|
|
8
|
+
@test = 'b6f6991d03df0e2e04dafffcd6bc418aac66049e2cd74b80f14ac86db1e3f0da'
|
|
9
|
+
fake(@test, TEST_TRANSACTION)
|
|
10
|
+
@t = Blockchain::Transaction.find(@test)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'should return txtotalbtcoutput' do
|
|
14
|
+
fake_q("txtotalbtcoutput/#{@test}", '12345')
|
|
15
|
+
expect(@t.txtotalbtcoutput).to eq(Btc.from_satoshis('12345'))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'should return txtotalbtcinput' do
|
|
19
|
+
fake_q("txtotalbtcinput/#{@test}", '12345')
|
|
20
|
+
expect(@t.txtotalbtcinput).to eq(Btc.from_satoshis('12345'))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'should return txfee' do
|
|
24
|
+
fake_q("txfee/#{@test}", '12345')
|
|
25
|
+
expect(@t.txfee).to eq(Btc.from_satoshis('12345'))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'should parse and store all basic fields' do
|
|
29
|
+
expect(@t.hsh).to eq('b6f6991d03df0e2e04dafffcd6bc418aac66049e2cd74b80f14ac86db1e3f0da')
|
|
30
|
+
expect(@t.ver).to eq (1)
|
|
31
|
+
expect(@t.vin_sz).to eq(1)
|
|
32
|
+
expect(@t.vout_sz).to eq(2)
|
|
33
|
+
expect(@t.time).to eq(DateTime.strptime('1408744310', '%s'))
|
|
34
|
+
expect(@t.size).to eq(258)
|
|
35
|
+
expect(@t.relayed_by).to eq("64.179.201.80")
|
|
36
|
+
expect(@t.block_height).to eq(12200)
|
|
37
|
+
expect(@t.tx_index).to eq("12563028")
|
|
38
|
+
expect(@t.result).to eq(0)
|
|
39
|
+
expect(@t.double_spend).to be_falsey
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe Blockchain::Transaction::Input do
|
|
43
|
+
before :all do
|
|
44
|
+
@is = @t.inputs
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it 'should assign prev out fields correctly' do
|
|
48
|
+
expect(@is[0].script).to eq('76a914641ad5051edd97029a003fe9efb29359fcee409d88ac')
|
|
49
|
+
expect(@is[0].addr).to eq('143y8gQbhmgePi4QJyL6QBi8zk4PSM5KQr')
|
|
50
|
+
expect(@is[0].n).to eq(1)
|
|
51
|
+
expect(@is[0].tx_index).to eq(12554260)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'should return prevout as a transaction' do
|
|
55
|
+
expect(@is[0].prev_out).to be_a(Blockchain::Transaction)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
describe Blockchain::Transaction::Output do
|
|
61
|
+
before :all do
|
|
62
|
+
@os = @t.out
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'should assign second out correctly' do
|
|
66
|
+
o = @os[1]
|
|
67
|
+
expect(o.n).to eq(1)
|
|
68
|
+
expect(o.addr).to eq('143y8gQbhmgePi4QJyL6QBi8zk4PSM5KQr')
|
|
69
|
+
expect(o.tx_index).to eq(62922222)
|
|
70
|
+
expect(o.spent).to eq(true)
|
|
71
|
+
expect(o.type).to eq(0)
|
|
72
|
+
expect(o.script).to eq('76a914217810f57fd7cdf79274c5d5e4a891fadc74887b88ac')
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def fake(t, body)
|
|
77
|
+
FakeWeb.register_uri(:get,
|
|
78
|
+
"#{Blockchain::ROOT}/rawtx/#{t}",
|
|
79
|
+
body: body, status: 200)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def fake_q(path, body)
|
|
83
|
+
FakeWeb.register_uri(:get,
|
|
84
|
+
"#{Blockchain::ROOT}/q/#{path}",
|
|
85
|
+
body: body, status: 200)
|
|
86
|
+
end
|
|
87
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: blockchain-ruby
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- James Larisch
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2014-08-23 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rspec
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 3.0.0
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: 3.0.0
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: fakeweb
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: 1.3.0
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 1.3.0
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: rake
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: money
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 6.1.1
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: 6.1.1
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: monetize
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: 0.3.0
|
|
76
|
+
type: :runtime
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: 0.3.0
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: bitcoin-money
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: 0.5.1
|
|
90
|
+
type: :runtime
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: 0.5.1
|
|
97
|
+
description: Convenient wrapper around public Blockchain.info API.
|
|
98
|
+
email:
|
|
99
|
+
- root@jameslarisch.com
|
|
100
|
+
executables: []
|
|
101
|
+
extensions: []
|
|
102
|
+
extra_rdoc_files: []
|
|
103
|
+
files:
|
|
104
|
+
- ".gitignore"
|
|
105
|
+
- Gemfile
|
|
106
|
+
- Gemfile.lock
|
|
107
|
+
- LICENSE.txt
|
|
108
|
+
- README.md
|
|
109
|
+
- blockchain-ruby.gemspec
|
|
110
|
+
- lib/address.rb
|
|
111
|
+
- lib/block.rb
|
|
112
|
+
- lib/blockchain.rb
|
|
113
|
+
- lib/realtime.rb
|
|
114
|
+
- lib/transaction.rb
|
|
115
|
+
- spec/address_spec.rb
|
|
116
|
+
- spec/block_spec.rb
|
|
117
|
+
- spec/reatime_spec.rb
|
|
118
|
+
- spec/spec_helper.rb
|
|
119
|
+
- spec/transaction_spec.rb
|
|
120
|
+
homepage: https://github.com/zenchilabs/blockchain-ruby
|
|
121
|
+
licenses: []
|
|
122
|
+
metadata: {}
|
|
123
|
+
post_install_message:
|
|
124
|
+
rdoc_options: []
|
|
125
|
+
require_paths:
|
|
126
|
+
- lib
|
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - ">="
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
|
+
requirements:
|
|
134
|
+
- - ">="
|
|
135
|
+
- !ruby/object:Gem::Version
|
|
136
|
+
version: '0'
|
|
137
|
+
requirements: []
|
|
138
|
+
rubyforge_project:
|
|
139
|
+
rubygems_version: 2.2.2
|
|
140
|
+
signing_key:
|
|
141
|
+
specification_version: 4
|
|
142
|
+
summary: Convenient wrapper around public Blockchain.info API.
|
|
143
|
+
test_files:
|
|
144
|
+
- spec/address_spec.rb
|
|
145
|
+
- spec/block_spec.rb
|
|
146
|
+
- spec/reatime_spec.rb
|
|
147
|
+
- spec/spec_helper.rb
|
|
148
|
+
- spec/transaction_spec.rb
|
|
149
|
+
has_rdoc:
|