ruby-ethereum 0.9.1 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c5bb5984fa505665549b339e92d7101d0dfb7df6
4
- data.tar.gz: 929f70cd50796bb629913c9c844d4485a1e1781d
3
+ metadata.gz: 8c18a40778f44a8f514e98f791b5a5238fc5e5f8
4
+ data.tar.gz: 0589c28717d274a533bb50612b6dd0fc14e99e0a
5
5
  SHA512:
6
- metadata.gz: 7d713f2fc56919c88bfbfe00fee13e04944b74d3a290ea6080a4b3cd71491498805f4a39f37c2730ed94670658158613c120b2c7a28543546903b8357140111e
7
- data.tar.gz: 9d477e58606c86fbdd6d56e4b63ef0dcce0d59d80d7f1ce093c1e949689c77970d35ffe229cccc000cedd309ea9c49b2050262ffe7397bd9f00a3c8b9ad82326
6
+ metadata.gz: 889d80e5709de13b79b5877003c943f8d8d114fec8d42788f8835b8c935920535eee15c0be0d899853fba6d5c0075530aa3269bc745f5410f7a238ba084723ad
7
+ data.tar.gz: 9a1b4ba43049ae72d983cf9ba48d551dd21a54c01d5bc481828360b0b4abf6ff2dcdb1f7175673d9805cc8a4e3e30156e603be9a3aef27b31e181b5e95c8d84c
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # ruby-ethereum
2
2
 
3
+ [![Join the chat at https://gitter.im/janx/ruby-ethereum](https://badges.gitter.im/janx/ruby-ethereum.svg)](https://gitter.im/janx/ruby-ethereum?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4
+
3
5
  A Ruby implementation of [Ethereum](https://ethereum.org).
4
6
 
5
7
  ## Install Secp256k1
@@ -140,12 +140,6 @@ module Ethereum
140
140
  o
141
141
  end
142
142
 
143
- private
144
-
145
- def logger
146
- @logger ||= Logger.new 'eth.abi.contract_translator'
147
- end
148
-
149
143
  def method_id(name, encode_types)
150
144
  Utils.big_endian_to_int Utils.keccak256(get_sig(name, encode_types))[0,4]
151
145
  end
@@ -154,6 +148,12 @@ module Ethereum
154
148
  Utils.big_endian_to_int Utils.keccak256(get_sig(name, encode_types))
155
149
  end
156
150
 
151
+ private
152
+
153
+ def logger
154
+ @logger ||= Logger.new 'eth.abi.contract_translator'
155
+ end
156
+
157
157
  def get_sig(name, encode_types)
158
158
  "#{name}(#{encode_types.map {|x| canonical_name(x) }.join(',')})"
159
159
  end
@@ -38,6 +38,7 @@ module Ethereum
38
38
  blk = RLP.decode env.db.get(hash), sedes: Block, env: env
39
39
  CachedBlock.create_cached blk
40
40
  end
41
+ lru_cache :find, 1024
41
42
 
42
43
  def verify(block, parent)
43
44
  block2 = RLP.decode RLP.encode(block), sedes: Block, env: parent.env, parent: parent
@@ -175,13 +176,17 @@ module Ethereum
175
176
  start_alloc.each do |addr, data|
176
177
  addr = Utils.normalize_address addr
177
178
 
178
- block.set_balance addr, data[:wei] if data[:wei]
179
- block.set_balance addr, data[:balance] if data[:balance]
180
- block.set_code addr, data[:code] if data[:code]
181
- block.set_nonce addr, data[:nonce] if data[:nonce]
179
+ block.set_balance addr, Utils.parse_int_or_hex(data[:wei]) if data[:wei]
180
+ block.set_balance addr, Utils.parse_int_or_hex(data[:balance]) if data[:balance]
181
+ block.set_code addr, Utils.decode_hex(Utils.remove_0x_head(data[:code])) if data[:code]
182
+ block.set_nonce addr, Utils.parse_int_or_hex(data[:nonce]) if data[:nonce]
182
183
 
183
184
  if data[:storage]
184
- data[:storage].each {|k, v| block.set_storage_data addr, k, v }
185
+ data[:storage].each do |k, v|
186
+ k = Utils.big_endian_to_int Utils.decode_hex(Utils.remove_0x_head(k))
187
+ v = Utils.big_endian_to_int Utils.decode_hex(Utils.remove_0x_head(v))
188
+ block.set_storage_data addr, k, v
189
+ end
185
190
  end
186
191
 
187
192
  end
@@ -228,7 +233,7 @@ module Ethereum
228
233
  making = options.has_key?(:making) ? options.delete(:making) : false
229
234
 
230
235
  raise ArgumentError, "No Env object given" unless env.instance_of?(Env)
231
- raise ArgumentError, "No database object given" unless env.db.is_a?(DB::BaseDB)
236
+ raise ArgumentError, "No database object given. db=#{env.db}" unless env.db.is_a?(DB::BaseDB)
232
237
 
233
238
  @env = env
234
239
  @db = env.db
@@ -329,6 +334,10 @@ module Ethereum
329
334
  @transaction_count.times.map {|i| get_transaction(i) }
330
335
  end
331
336
 
337
+ def uncles_hash
338
+ Utils.keccak256_rlp(uncles)
339
+ end
340
+
332
341
  ##
333
342
  # Validate the uncles of this block.
334
343
  #
@@ -810,6 +819,7 @@ module Ethereum
810
819
  loop do
811
820
  begin
812
821
  receipts.push get_receipt(i)
822
+ i += 1
813
823
  rescue IndexError
814
824
  return receipts
815
825
  end
@@ -1105,6 +1115,27 @@ module Ethereum
1105
1115
  end
1106
1116
  alias :inspect :to_s
1107
1117
 
1118
+ def validate_transaction(tx)
1119
+ raise UnsignedTransactionError.new(tx) unless tx.sender
1120
+
1121
+ acct_nonce = get_nonce tx.sender
1122
+ raise InvalidNonce, "#{tx}: nonce actual: #{tx.nonce} target: #{acct_nonce}" if acct_nonce != tx.nonce
1123
+
1124
+ min_gas = get_intrinsic_gas tx
1125
+ raise InsufficientStartGas, "#{tx}: startgas actual: #{tx.startgas} target: #{min_gas}" if tx.startgas < min_gas
1126
+
1127
+ total_cost = tx.value + tx.gasprice * tx.startgas
1128
+ balance = get_balance tx.sender
1129
+ raise InsufficientBalance, "#{tx}: balance actual: #{balance} target: #{total_cost}" if balance < total_cost
1130
+
1131
+ accum_gas = gas_used + tx.startgas
1132
+ raise BlockGasLimitReached, "#{tx}: gaslimit actual: #{accum_gas} target: #{gas_limit}" if accum_gas > gas_limit
1133
+
1134
+ tx.check_low_s if number >= config[:homestead_fork_blknum]
1135
+
1136
+ true
1137
+ end
1138
+
1108
1139
  private
1109
1140
 
1110
1141
  def logger
@@ -1181,28 +1212,7 @@ module Ethereum
1181
1212
  raise ValueError, "Extra data cannot exceed #{config[:max_extradata_length]} bytes" if header.extra_data.size > config[:max_extradata_length]
1182
1213
  raise ValueError, "Coinbase cannot be empty address" if header.coinbase.false?
1183
1214
  raise ValueError, "State merkle root of block #{self} not found in database" unless @state.root_hash_valid?
1184
- raise ValueError, "PoW check failed" if !genesis? && nonce.true? && !header.check_pow
1185
- end
1186
-
1187
- def validate_transaction(tx)
1188
- raise UnsignedTransactionError.new(tx) unless tx.sender
1189
-
1190
- acct_nonce = get_nonce tx.sender
1191
- raise InvalidNonce, "#{tx}: nonce actual: #{tx.nonce} target: #{acct_nonce}" if acct_nonce != tx.nonce
1192
-
1193
- min_gas = get_intrinsic_gas tx
1194
- raise InsufficientStartGas, "#{tx}: startgas actual: #{tx.startgas} target: #{min_gas}" if tx.startgas < min_gas
1195
-
1196
- total_cost = tx.value + tx.gasprice * tx.startgas
1197
- balance = get_balance tx.sender
1198
- raise InsufficientBalance, "#{tx}: balance actual: #{balance} target: #{total_cost}" if balance < total_cost
1199
-
1200
- accum_gas = gas_used + tx.startgas
1201
- raise BlockGasLimitReached, "#{tx}: gaslimit actual: #{accum_gas} target: #{gas_limit}" if accum_gas > gas_limit
1202
-
1203
- tx.check_low_s if number >= config[:homestead_fork_blknum]
1204
-
1205
- true
1215
+ raise InvalidNonce, "PoW check failed" if !genesis? && nonce.true? && !header.check_pow
1206
1216
  end
1207
1217
 
1208
1218
  ##
@@ -1,3 +1,4 @@
1
+ # -*- encoding : ascii-8bit -*-
1
2
  module Ethereum
2
3
  module CachedBlock
3
4
 
@@ -9,7 +9,7 @@ module Ethereum
9
9
 
10
10
  HEAD_KEY = 'HEAD'.freeze
11
11
 
12
- attr :env, :index, :head_candidate
12
+ attr :env, :db, :index, :head_candidate, :genesis
13
13
 
14
14
  ##
15
15
  # @param env [Ethereum::Env] configuration of the chain
@@ -4,3 +4,4 @@ require 'ethereum/db/base_db'
4
4
  require 'ethereum/db/ephem_db'
5
5
  require 'ethereum/db/overlay_db'
6
6
  require 'ethereum/db/refcount_db'
7
+ require 'ethereum/db/level_db'
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Ethereum
4
4
  module DB
5
- class BaseDB
5
+ module BaseDB
6
6
  attr :db
7
7
  end
8
8
  end
@@ -2,14 +2,19 @@
2
2
 
3
3
  module Ethereum
4
4
  module DB
5
- class EphemDB < BaseDB
5
+ class EphemDB
6
+ include BaseDB
6
7
 
7
8
  def initialize
8
9
  @db = {}
9
10
  end
10
11
 
11
12
  def get(k)
12
- @db[k] or raise KeyError, k.inspect
13
+ if has_key?(k)
14
+ @db[k]
15
+ else
16
+ raise KeyError, k.inspect
17
+ end
13
18
  end
14
19
 
15
20
  def put(k, v)
@@ -0,0 +1,129 @@
1
+ # -*- encoding : ascii-8bit -*-
2
+
3
+ require 'leveldb'
4
+
5
+ module Ethereum
6
+ module DB
7
+ class LevelDB
8
+ include BaseDB
9
+
10
+ # FIXME: workaround, because leveldb gem doesn't allow put empty string
11
+ EMPTY_STRING = Utils.keccak256('').freeze
12
+
13
+ def initialize(dbfile)
14
+ logger.info "opening LevelDB", path: dbfile
15
+
16
+ @dbfile = dbfile
17
+ reopen
18
+
19
+ @commit_counter = 0
20
+ @uncommited = {}
21
+ end
22
+
23
+ def reopen
24
+ @db = ::LevelDB::DB.new @dbfile
25
+ end
26
+
27
+ def get(k)
28
+ logger.trace 'getting entry', key: Utils.encode_hex(k)[0,8]
29
+
30
+ if @uncommited.has_key?(k)
31
+ raise KeyError, 'key not in db' unless @uncommited[k]
32
+ logger.trace "from uncommited"
33
+ return @uncommited[k]
34
+ end
35
+
36
+ logger.trace "from db"
37
+ raise KeyError, k.inspect unless @db.exists?(k)
38
+ v = @db.get(k)
39
+ o = decompress v
40
+ @uncommited[k] = o
41
+
42
+ o
43
+ end
44
+
45
+ def put(k, v)
46
+ logger.trace 'putting entry', key: Utils.encode_hex(k)[0,8], size: v.size
47
+ @uncommited[k] = v
48
+ end
49
+
50
+ def commit
51
+ logger.debug "committing", db: self
52
+
53
+ @db.batch do |b|
54
+ @uncommited.each do |k, v|
55
+ if v
56
+ b.put k, compress(v)
57
+ else
58
+ b.delete k
59
+ end
60
+ end
61
+ end
62
+ logger.debug 'committed', db: self, num: @uncommited.size
63
+ @uncommited = {}
64
+ end
65
+
66
+ def delete(k)
67
+ logger.trace 'deleting entry', key: key
68
+ @uncommited[k] = nil
69
+ end
70
+
71
+ def has_key?(k)
72
+ get(k)
73
+ true
74
+ rescue KeyError
75
+ false
76
+ end
77
+ alias :include? :has_key?
78
+
79
+ def ==(other)
80
+ other.instance_of?(self.class) && db == other.db
81
+ end
82
+
83
+ def to_s
84
+ "<DB at #{@db} uncommited=#{@uncommited.size}>"
85
+ end
86
+ alias inspect to_s
87
+
88
+ def inc_refcount(k, v)
89
+ put k, v
90
+ end
91
+
92
+ def dec_refcount(k)
93
+ # do nothing
94
+ end
95
+
96
+ def revert_refcount_changes(epoch)
97
+ # do nothing
98
+ end
99
+
100
+ def commit_refcount_changes(epoch)
101
+ # do nothing
102
+ end
103
+
104
+ def cleanup(epoch)
105
+ # do nothing
106
+ end
107
+
108
+ def put_temporarily(k, v)
109
+ inc_refcount(k, v)
110
+ dec_refcount(k)
111
+ end
112
+
113
+ private
114
+
115
+ def logger
116
+ @logger ||= Logger.new 'db.leveldb'
117
+ end
118
+
119
+ def decompress(x)
120
+ x == EMPTY_STRING ? '' : x
121
+ end
122
+
123
+ def compress(x)
124
+ x.empty? ? EMPTY_STRING : x
125
+ end
126
+
127
+ end
128
+ end
129
+ end
@@ -5,7 +5,8 @@ module Ethereum
5
5
  ##
6
6
  # Used for making temporary objects.
7
7
  #
8
- class OverlayDB < BaseDB
8
+ class OverlayDB
9
+ include BaseDB
9
10
 
10
11
  def initialize(db)
11
12
  @db = db
@@ -2,19 +2,23 @@
2
2
 
3
3
  module Ethereum
4
4
  module DB
5
- class RefcountDB < BaseDB
5
+ class RefcountDB
6
+ include BaseDB
6
7
 
7
8
  DEATH_ROW_OFFSET = 2**62
8
9
 
9
10
  ZERO_ENCODED = Utils.encode_int(0)
10
11
  ONE_ENCODED = Utils.encode_int(1)
11
12
 
13
+ attr_accessor :ttl
14
+
12
15
  def initialize(db)
13
16
  @db = db
14
17
  @journal = []
15
18
  @death_row = []
16
19
  @kv = @db.respond_to?(:kv) ? @db.kv : nil
17
- @ttl = 500
20
+
21
+ self.ttl = 500
18
22
  end
19
23
 
20
24
  ##
@@ -57,7 +61,7 @@ module Ethereum
57
61
  raise AssertError, "refcount must be greater than zero!" unless refcount > 0
58
62
 
59
63
  @journal.push [node_object[0], k]
60
- new_refcount = Utils.encode(refcount-1)
64
+ new_refcount = Utils.encode_int(refcount-1)
61
65
  ref_put k, RLP.encode([new_refcount, node_object[1]])
62
66
 
63
67
  @death_row.push k if new_refcount == ZERO_ENCODED
@@ -100,14 +104,14 @@ module Ethereum
100
104
  logger.debug "#{pruned} nodes successfully pruned"
101
105
 
102
106
  @db.delete "deathrow:#{epoch}" rescue nil
103
- @db.delete "journal:#{epoch-@ttl}" rescue nil
107
+ @db.delete "journal:#{epoch - ttl}" rescue nil
104
108
  end
105
109
 
106
110
  ##
107
111
  # Commit changes to the journal and death row to the database.
108
112
  #
109
113
  def commit_refcount_changes(epoch)
110
- timeout_epoch = epoch + @ttl
114
+ timeout_epoch = epoch + ttl
111
115
  death_row_nodes = RLP.decode(@db.get("deathrow:#{timeout_epoch}")) rescue []
112
116
 
113
117
  @death_row.each do |node_key|
@@ -127,7 +131,7 @@ module Ethereum
127
131
  @db.put "deathrow:#{timeout_epoch}", RLP.encode(death_row_nodes)
128
132
 
129
133
  journal = RLP.decode(@db.get("journal:#{epoch}")) rescue []
130
- journal.extend @journal
134
+ journal.concat @journal
131
135
  @journal = []
132
136
  @db.put "journal:#{epoch}", RLP.encode(journal)
133
137
  end
@@ -136,7 +140,7 @@ module Ethereum
136
140
  # Revert changes made during an epoch
137
141
  #
138
142
  def revert_refcount_changes(epoch)
139
- timeout_epoch = epoch + @ttl
143
+ timeout_epoch = epoch + ttl
140
144
 
141
145
  @db.delete("deathrow:#{timeout_epoch}") rescue nil
142
146
 
@@ -166,7 +170,11 @@ module Ethereum
166
170
  end
167
171
 
168
172
  def ref_get(k)
169
- @db.get ref_key(k)
173
+ if has_key?(k)
174
+ @db.get ref_key(k)
175
+ else
176
+ raise KeyError, k.inspect
177
+ end
170
178
  end
171
179
 
172
180
  def ref_put(k, v)
@@ -67,6 +67,7 @@ module Ethereum
67
67
 
68
68
  c
69
69
  end
70
+ lru_cache :get_cache, 5
70
71
 
71
72
  def hashimoto_light(blknum, cache, mining_hash, bin_nonce)
72
73
  nonce = Utils.big_endian_to_int(bin_nonce)
@@ -1,4 +1,4 @@
1
- # encoding: ascii-8bit
1
+ # -*- encoding : ascii-8bit -*-
2
2
 
3
3
  require 'ffi'
4
4
 
@@ -8,10 +8,18 @@ module Ethereum
8
8
  def all
9
9
  return @all if @all
10
10
 
11
- @all = {
12
- serpent: Serpent,
13
- solidity: SolidityWrapper.solc_path && SolidityWrapper
14
- }
11
+ @all = {}
12
+
13
+ begin
14
+ require 'serpent'
15
+ @all[:serpent] = Serpent
16
+ rescue LoadError
17
+ # do nothing
18
+ end
19
+
20
+ if SolidityWrapper.solc_path
21
+ @all[:solidity] = SolidityWrapper
22
+ end
15
23
 
16
24
  @all
17
25
  end
@@ -38,10 +38,10 @@ module Ethereum
38
38
  names
39
39
  end
40
40
 
41
- def combined(code)
41
+ def combined(code, format='bin')
42
42
  out = Tempfile.new 'solc_output_'
43
43
 
44
- pipe = IO.popen([solc_path, '--add-std', '--optimize', '--combined-json', 'abi,bin,devdoc,userdoc'], 'w', [:out, :err] => out)
44
+ pipe = IO.popen([solc_path, '--add-std', '--optimize', '--combined-json', "abi,#{format},devdoc,userdoc"], 'w', [:out, :err] => out)
45
45
  pipe.write code
46
46
  pipe.close_write
47
47
  raise CompileError, 'compilation failed' unless $?.success?
@@ -66,15 +66,25 @@ module Ethereum
66
66
  ##
67
67
  # Returns binary of last contract in code.
68
68
  #
69
- def compile(code, contract_name='')
70
- sorted_contracts = combined code
69
+ def compile(code, contract_name='', format='bin')
70
+ sorted_contracts = combined code, format
71
71
  if contract_name.true?
72
72
  idx = sorted_contracts.map(&:first).index(contract_name)
73
73
  else
74
74
  idx = -1
75
75
  end
76
76
 
77
- Utils.decode_hex sorted_contracts[idx][1]['bin']
77
+ output = sorted_contracts[idx][1][format]
78
+ case format
79
+ when 'bin'
80
+ Utils.decode_hex output
81
+ when 'asm'
82
+ output['.code']
83
+ when 'opcodes'
84
+ output
85
+ else
86
+ raise ArgumentError
87
+ end
78
88
  end
79
89
 
80
90
  ##
@@ -187,5 +187,27 @@ module Ethereum
187
187
  keccak256_rlp([normalize_address(sender), nonce])[12..-1]
188
188
  end
189
189
 
190
+ def remove_0x_head(s)
191
+ s[0,2] == '0x' ? s[2..-1] : s
192
+ end
193
+
194
+ def parse_int_or_hex(s)
195
+ if s.is_a?(Numeric)
196
+ s
197
+ elsif s[0,2] == '0x'
198
+ big_endian_to_int decode_hex(normalize_hex_without_prefix(s))
199
+ else
200
+ s.to_i
201
+ end
202
+ end
203
+
204
+ def normalize_hex_without_prefix(s)
205
+ if s[0,2] == '0x'
206
+ (s.size % 2 == 1 ? '0' : '') + s[2..-1]
207
+ else
208
+ s
209
+ end
210
+ end
211
+
190
212
  end
191
213
  end
@@ -1,5 +1,5 @@
1
1
  # -*- encoding : ascii-8bit -*-
2
2
 
3
3
  module Ethereum
4
- VERSION = '0.9.1'
4
+ VERSION = '0.9.3'
5
5
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-ethereum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jan Xie
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-19 00:00:00.000000000 Z
11
+ date: 2016-06-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rlp
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: '0.6'
19
+ version: 0.7.3
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: '0.6'
26
+ version: 0.7.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: ethash
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0.3'
47
+ version: '0.4'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0.3'
54
+ version: '0.4'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: lru_redux
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0.1'
111
+ - !ruby/object:Gem::Dependency
112
+ name: leveldb
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '='
116
+ - !ruby/object:Gem::Version
117
+ version: 0.1.9
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '='
123
+ - !ruby/object:Gem::Version
124
+ version: 0.1.9
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: rake
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -164,20 +178,6 @@ dependencies:
164
178
  - - "~>"
165
179
  - !ruby/object:Gem::Version
166
180
  version: '0.3'
167
- - !ruby/object:Gem::Dependency
168
- name: pry-byebug
169
- requirement: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - "~>"
172
- - !ruby/object:Gem::Version
173
- version: '2.0'
174
- type: :development
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - "~>"
179
- - !ruby/object:Gem::Version
180
- version: '2.0'
181
181
  description: Ethereum's implementation in ruby.
182
182
  email:
183
183
  - jan.h.xie@gmail.com
@@ -207,6 +207,7 @@ files:
207
207
  - lib/ethereum/db.rb
208
208
  - lib/ethereum/db/base_db.rb
209
209
  - lib/ethereum/db/ephem_db.rb
210
+ - lib/ethereum/db/level_db.rb
210
211
  - lib/ethereum/db/overlay_db.rb
211
212
  - lib/ethereum/db/refcount_db.rb
212
213
  - lib/ethereum/env.rb
@@ -276,7 +277,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
276
277
  version: '0'
277
278
  requirements: []
278
279
  rubyforge_project:
279
- rubygems_version: 2.4.5.1
280
+ rubygems_version: 2.5.1
280
281
  signing_key:
281
282
  specification_version: 4
282
283
  summary: Core library of the Ethereum project, ruby version.