eth 0.4.16 → 0.5.1
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 +4 -4
- data/.github/workflows/codeql.yml +15 -5
- data/.github/workflows/docs.yml +26 -0
- data/.github/workflows/spec.yml +52 -0
- data/.gitignore +24 -24
- data/.gitmodules +3 -3
- data/.yardopts +1 -0
- data/AUTHORS.txt +21 -0
- data/CHANGELOG.md +65 -10
- data/Gemfile +13 -2
- data/LICENSE.txt +202 -22
- data/README.md +199 -74
- data/bin/console +4 -4
- data/bin/setup +5 -4
- data/eth.gemspec +34 -29
- data/lib/eth/abi/type.rb +178 -0
- data/lib/eth/abi.rb +396 -0
- data/lib/eth/address.rb +55 -11
- data/lib/eth/api.rb +223 -0
- data/lib/eth/chain.rb +151 -0
- data/lib/eth/client/http.rb +63 -0
- data/lib/eth/client/ipc.rb +47 -0
- data/lib/eth/client.rb +232 -0
- data/lib/eth/constant.rb +71 -0
- data/lib/eth/eip712.rb +184 -0
- data/lib/eth/key/decrypter.rb +121 -88
- data/lib/eth/key/encrypter.rb +178 -99
- data/lib/eth/key.rb +136 -48
- data/lib/eth/rlp/decoder.rb +109 -0
- data/lib/eth/rlp/encoder.rb +78 -0
- data/lib/eth/rlp/sedes/big_endian_int.rb +66 -0
- data/lib/eth/rlp/sedes/binary.rb +97 -0
- data/lib/eth/rlp/sedes/list.rb +84 -0
- data/lib/eth/rlp/sedes.rb +74 -0
- data/lib/eth/rlp.rb +63 -0
- data/lib/eth/signature.rb +163 -0
- data/lib/eth/tx/eip1559.rb +336 -0
- data/lib/eth/tx/eip2930.rb +328 -0
- data/lib/eth/tx/legacy.rb +296 -0
- data/lib/eth/tx.rb +273 -143
- data/lib/eth/unit.rb +49 -0
- data/lib/eth/util.rb +235 -0
- data/lib/eth/version.rb +18 -1
- data/lib/eth.rb +33 -67
- metadata +50 -85
- data/.github/workflows/build.yml +0 -26
- data/lib/eth/gas.rb +0 -9
- data/lib/eth/open_ssl.rb +0 -264
- data/lib/eth/secp256k1.rb +0 -7
- data/lib/eth/sedes.rb +0 -40
- data/lib/eth/utils.rb +0 -130
data/lib/eth/tx.rb
CHANGED
@@ -1,197 +1,327 @@
|
|
1
|
+
# Copyright (c) 2016-2022 The Ruby-Eth Contributors
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require "konstructor"
|
16
|
+
|
17
|
+
require "eth/chain"
|
18
|
+
require "eth/tx/eip1559"
|
19
|
+
require "eth/tx/eip2930"
|
20
|
+
require "eth/tx/legacy"
|
21
|
+
require "eth/unit"
|
22
|
+
|
23
|
+
# Provides the {Eth} module.
|
1
24
|
module Eth
|
2
|
-
class Tx
|
3
25
|
|
4
|
-
|
5
|
-
|
26
|
+
# Provides the `Tx` module supporting various transaction types.
|
27
|
+
module Tx
|
28
|
+
extend self
|
6
29
|
|
7
|
-
|
8
|
-
|
9
|
-
gas_price: big_endian_int,
|
10
|
-
gas_limit: big_endian_int,
|
11
|
-
to: address,
|
12
|
-
value: big_endian_int,
|
13
|
-
data_bin: binary,
|
14
|
-
v: big_endian_int,
|
15
|
-
r: big_endian_int,
|
16
|
-
s: big_endian_int
|
17
|
-
})
|
30
|
+
# Provides a special transaction error if transaction type is unknown.
|
31
|
+
class TransactionTypeError < TypeError; end
|
18
32
|
|
19
|
-
|
33
|
+
# Provides an decoder error if transaction cannot be decoded.
|
34
|
+
class DecoderError < StandardError; end
|
20
35
|
|
21
|
-
|
22
|
-
|
23
|
-
txh = deserialize(RLP.decode data).to_h
|
36
|
+
# Provides a parameter error if parameter types are invalid.
|
37
|
+
class ParameterError < TypeError; end
|
24
38
|
|
25
|
-
|
39
|
+
# The minimum transaction gas limit required for a value transfer.
|
40
|
+
DEFAULT_GAS_LIMIT = 21_000.freeze
|
26
41
|
|
27
|
-
|
28
|
-
|
42
|
+
# The "default" transaction gas price of 20 GWei. Do not use.
|
43
|
+
DEFAULT_GAS_PRICE = (20 * Unit::GWEI).freeze
|
29
44
|
|
30
|
-
|
31
|
-
|
32
|
-
fields[:to] = Utils.normalize_address(fields[:to])
|
45
|
+
# The calldata gas cost of a non-zero byte as per EIP-2028.
|
46
|
+
COST_NON_ZERO_BYTE = 16.freeze
|
33
47
|
|
34
|
-
|
48
|
+
# The calldata gas cost of a zero byte.
|
49
|
+
COST_ZERO_BYTE = 4.freeze
|
35
50
|
|
36
|
-
|
37
|
-
|
38
|
-
fields[:data_bin] = data_bin
|
39
|
-
end
|
40
|
-
serializable_initialize fields
|
51
|
+
# The access list gas cost of a storage key as per EIP-2930.
|
52
|
+
COST_STORAGE_KEY = 1_900.freeze
|
41
53
|
|
42
|
-
|
43
|
-
|
54
|
+
# The access list gas cost of an address as per EIP-2930.
|
55
|
+
COST_ADDRESS = 2_400.freeze
|
44
56
|
|
45
|
-
|
46
|
-
|
47
|
-
RLP.encode(us, sedes: us.sedes)
|
48
|
-
end
|
57
|
+
# The maximum transaction gas limit is bound by the block gas limit.
|
58
|
+
BLOCK_GAS_LIMIT = 25_000_000.freeze
|
49
59
|
|
50
|
-
|
51
|
-
|
52
|
-
end
|
60
|
+
# The legacy transaction type is 0.
|
61
|
+
TYPE_LEGACY = 0x00.freeze
|
53
62
|
|
54
|
-
|
55
|
-
|
56
|
-
end
|
63
|
+
# The EIP-2930 transaction type is 1.
|
64
|
+
TYPE_2930 = 0x01.freeze
|
57
65
|
|
58
|
-
|
59
|
-
|
60
|
-
end
|
66
|
+
# The EIP-1559 transaction type is 2.
|
67
|
+
TYPE_1559 = 0x02.freeze
|
61
68
|
|
62
|
-
|
63
|
-
|
64
|
-
vrs = Utils.v_r_s_for sig
|
65
|
-
self.v = (self.chain_id) ? ((self.chain_id * 2) + vrs[0] + 8) : vrs[0]
|
66
|
-
self.r = vrs[1]
|
67
|
-
self.s = vrs[2]
|
69
|
+
# The zero byte is 0x00.
|
70
|
+
ZERO_BYTE = "\x00".freeze
|
68
71
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
+
# Creates a new transaction of any type for given parameters and chain ID.
|
73
|
+
# Required parameters are (optional in brackets):
|
74
|
+
# - EIP-1559: chain_id, nonce, priority_fee, max_gas_fee, gas_limit(, from, to,
|
75
|
+
# value, data, access_list)
|
76
|
+
# - EIP-2930: chain_id, nonce, gas_price, gas_limit, access_list(, from, to,
|
77
|
+
# value, data)
|
78
|
+
# - Legacy: nonce, gas_price, gas_lmit(, from, to, value, data)
|
79
|
+
#
|
80
|
+
# @param params [Hash] all necessary transaction fields.
|
81
|
+
# @param chain_id [Integer] the EIP-155 Chain ID (legacy transactions only).
|
82
|
+
def new(params, chain_id = Chain::ETHEREUM)
|
72
83
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
84
|
+
# if we deal with max gas fee parameter, attempt EIP-1559
|
85
|
+
unless params[:max_gas_fee].nil?
|
86
|
+
params[:chain_id] = chain_id if params[:chain_id].nil?
|
87
|
+
return Tx::Eip1559.new params
|
77
88
|
end
|
78
|
-
end
|
79
89
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
90
|
+
# if we deal with access list parameter, attempt EIP-2930
|
91
|
+
unless params[:access_list].nil?
|
92
|
+
params[:chain_id] = chain_id if params[:chain_id].nil?
|
93
|
+
return Tx::Eip2930.new params
|
84
94
|
end
|
85
|
-
end
|
86
95
|
|
87
|
-
|
88
|
-
|
89
|
-
|
96
|
+
# if nothing else, go with legacy transactions
|
97
|
+
chain_id = params[:chain_id] if !params[:chain_id].nil? and params[:chain_id] != chain_id
|
98
|
+
return Tx::Legacy.new params, chain_id
|
90
99
|
end
|
91
100
|
|
92
|
-
|
93
|
-
|
101
|
+
# Decodes a transaction hex of any known type (2, 1, or legacy).
|
102
|
+
#
|
103
|
+
# @param hex [String] the raw transaction hex-string.
|
104
|
+
# @return [Eth::Tx] transaction payload.
|
105
|
+
# @raise [TransactionTypeError] if the transaction type is unknown.
|
106
|
+
def decode(hex)
|
107
|
+
hex = Util.remove_hex_prefix hex
|
108
|
+
type = hex[0, 2].to_i(16)
|
109
|
+
case type
|
110
|
+
when TYPE_1559
|
111
|
+
|
112
|
+
# EIP-1559 transaction (type 2)
|
113
|
+
return Tx::Eip1559.decode hex
|
114
|
+
when TYPE_2930
|
115
|
+
|
116
|
+
# EIP-2930 transaction (type 1)
|
117
|
+
return Tx::Eip2930.decode hex
|
118
|
+
else
|
94
119
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
].join
|
120
|
+
# Legacy transaction if first byte is RLP (>= 192)
|
121
|
+
if type >= 0xc0
|
122
|
+
return Tx::Legacy.decode hex
|
123
|
+
else
|
124
|
+
raise TransactionTypeError, "Cannot decode unknown transaction type #{type}!"
|
125
|
+
end
|
102
126
|
end
|
103
127
|
end
|
104
128
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
def
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
129
|
+
# Creates an unsigned copy of any transaction object.
|
130
|
+
#
|
131
|
+
# @param tx [Eth::Tx] any transaction payload.
|
132
|
+
# @return [Eth::Tx] an unsigned transaction payload of the same type.
|
133
|
+
# @raise [TransactionTypeError] if the transaction type is unknown.
|
134
|
+
def unsigned_copy(tx)
|
135
|
+
case tx.type
|
136
|
+
when TYPE_1559
|
137
|
+
|
138
|
+
# EIP-1559 transaction (type 2)
|
139
|
+
return Tx::Eip1559.unsigned_copy tx
|
140
|
+
when TYPE_2930
|
141
|
+
|
142
|
+
# EIP-2930 transaction (type 1)
|
143
|
+
return Tx::Eip2930.unsigned_copy tx
|
144
|
+
when TYPE_LEGACY
|
145
|
+
|
146
|
+
# Legacy transaction ("type 0")
|
147
|
+
return Tx::Legacy.unsigned_copy tx
|
148
|
+
end
|
149
|
+
raise TransactionTypeError, "Cannot copy unknown transaction type #{tx.type}!"
|
120
150
|
end
|
121
151
|
|
122
|
-
|
123
|
-
|
124
|
-
|
152
|
+
# Estimates intrinsic gas for provided call data (EIP-2028) and
|
153
|
+
# access lists (EIP-2930).
|
154
|
+
#
|
155
|
+
# @param data [String] the call data.
|
156
|
+
# @param list [Array] the access list.
|
157
|
+
# @return [Integer] the estimated intrinsic gas cost.
|
158
|
+
def estimate_intrinsic_gas(data = "", list = [])
|
159
|
+
gas = DEFAULT_GAS_LIMIT
|
160
|
+
unless data.nil? or data.empty?
|
161
|
+
data = Util.hex_to_bin data if Util.is_hex? data
|
162
|
+
|
163
|
+
# count zero bytes
|
164
|
+
zero = data.count ZERO_BYTE
|
165
|
+
gas += zero * COST_ZERO_BYTE
|
166
|
+
|
167
|
+
# count non-zero bytes
|
168
|
+
none = data.size - zero
|
169
|
+
gas += none * COST_NON_ZERO_BYTE
|
170
|
+
end
|
171
|
+
unless list.nil? or list.empty?
|
172
|
+
list.each do |entry|
|
125
173
|
|
126
|
-
|
127
|
-
|
128
|
-
end
|
174
|
+
# count addresses
|
175
|
+
gas += COST_ADDRESS
|
129
176
|
|
130
|
-
|
131
|
-
if cid != @chain_id
|
132
|
-
self.v = 0
|
133
|
-
self.r = 0
|
134
|
-
self.s = 0
|
177
|
+
entry.last.each do |key|
|
135
178
|
|
136
|
-
|
179
|
+
# count storage keys
|
180
|
+
gas += COST_STORAGE_KEY
|
181
|
+
end
|
182
|
+
end
|
137
183
|
end
|
138
|
-
|
139
|
-
@chain_id = (cid == 0) ? nil : cid
|
184
|
+
return gas
|
140
185
|
end
|
141
186
|
|
142
|
-
|
143
|
-
|
187
|
+
# Validates the common type-2 transaction fields such as nonce, priority
|
188
|
+
# fee, max gas fee, gas limit, amount, and access list.
|
189
|
+
#
|
190
|
+
# @param fields [Hash] the transaction fields.
|
191
|
+
# @return [Hash] the validated transaction fields.
|
192
|
+
# @raise [ParameterError] if nonce is an invalid integer.
|
193
|
+
# @raise [ParameterError] if priority fee is invalid.
|
194
|
+
# @raise [ParameterError] if max gas fee is invalid.
|
195
|
+
# @raise [ParameterError] if gas limit is invalid.
|
196
|
+
# @raise [ParameterError] if amount is invalid.
|
197
|
+
# @raise [ParameterError] if access list is invalid.
|
198
|
+
def validate_params(fields)
|
199
|
+
if fields[:nonce].nil? or fields[:nonce] < 0
|
200
|
+
raise ParameterError, "Invalid signer nonce #{fields[:nonce]}!"
|
201
|
+
end
|
202
|
+
if fields[:priority_fee].nil? or fields[:priority_fee] < 0
|
203
|
+
raise ParameterError, "Invalid gas priority fee #{fields[:priority_fee]}!"
|
204
|
+
end
|
205
|
+
if fields[:max_gas_fee].nil? or fields[:max_gas_fee] < 0
|
206
|
+
raise ParameterError, "Invalid max gas fee #{fields[:max_gas_fee]}!"
|
207
|
+
end
|
208
|
+
if fields[:gas_limit].nil? or fields[:gas_limit] < DEFAULT_GAS_LIMIT or fields[:gas_limit] > BLOCK_GAS_LIMIT
|
209
|
+
raise ParameterError, "Invalid gas limit #{fields[:gas_limit]}!"
|
210
|
+
end
|
211
|
+
unless fields[:value] >= 0
|
212
|
+
raise ParameterError, "Invalid transaction value #{fields[:value]}!"
|
213
|
+
end
|
214
|
+
unless fields[:access_list].nil? or fields[:access_list].is_a? Array
|
215
|
+
raise ParameterError, "Invalid access list #{fields[:access_list]}!"
|
216
|
+
end
|
217
|
+
return fields
|
144
218
|
end
|
145
219
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
220
|
+
# Validates the common legacy transaction fields such as nonce, gas
|
221
|
+
# price, gas limit, amount, and access list.
|
222
|
+
#
|
223
|
+
# @param fields [Hash] the transaction fields.
|
224
|
+
# @return [Hash] the validated transaction fields.
|
225
|
+
# @raise [ParameterError] if nonce is an invalid integer.
|
226
|
+
# @raise [ParameterError] if gas price is invalid.
|
227
|
+
# @raise [ParameterError] if gas limit is invalid.
|
228
|
+
# @raise [ParameterError] if amount is invalid.
|
229
|
+
# @raise [ParameterError] if access list is invalid.
|
230
|
+
def validate_legacy_params(fields)
|
231
|
+
if fields[:nonce].nil? or fields[:nonce] < 0
|
232
|
+
raise ParameterError, "Invalid signer nonce #{fields[:nonce]}!"
|
233
|
+
end
|
234
|
+
if fields[:gas_price].nil? or fields[:gas_price] < 0
|
235
|
+
raise ParameterError, "Invalid gas price #{fields[:gas_price]}!"
|
236
|
+
end
|
237
|
+
if fields[:gas_limit].nil? or fields[:gas_limit] < DEFAULT_GAS_LIMIT or fields[:gas_limit] > BLOCK_GAS_LIMIT
|
238
|
+
raise ParameterError, "Invalid gas limit #{fields[:gas_limit]}!"
|
239
|
+
end
|
240
|
+
unless fields[:value] >= 0
|
241
|
+
raise ParameterError, "Invalid transaction value #{fields[:value]}!"
|
242
|
+
end
|
243
|
+
unless fields[:access_list].nil? or fields[:access_list].is_a? Array
|
244
|
+
raise ParameterError, "Invalid access list #{fields[:access_list]}!"
|
245
|
+
end
|
246
|
+
return fields
|
151
247
|
end
|
152
248
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
249
|
+
# Populates the transaction chain id field with a serializable default
|
250
|
+
# value (1) in case it is undefined.
|
251
|
+
#
|
252
|
+
# @param id [Integer] the transaction chain id.
|
253
|
+
# @return [Integer] the sanitized transaction chain id.
|
254
|
+
def sanitize_chain(id)
|
255
|
+
id = Chain::ETHEREUM if id.nil?
|
256
|
+
return id
|
157
257
|
end
|
158
258
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
259
|
+
# Populates the transaction destination address with a serializable
|
260
|
+
# empty value in case it is undefined; also ensures the address is
|
261
|
+
# checksummed but not prefixed for consistency.
|
262
|
+
#
|
263
|
+
# @param addr [String] the transaction destination address.
|
264
|
+
# @return [String] the sanitized transaction destination address.
|
265
|
+
def sanitize_address(addr)
|
266
|
+
addr = "" if addr.nil?
|
267
|
+
if addr.is_a? String and !addr.empty?
|
268
|
+
addr = Address.new(addr).to_s
|
269
|
+
addr = Util.remove_hex_prefix addr
|
164
270
|
end
|
271
|
+
return addr
|
165
272
|
end
|
166
273
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
def signature_hash
|
177
|
-
Utils.keccak256 unsigned_encoded
|
274
|
+
# Populates the transaction value field with a serializable empty value
|
275
|
+
# in case it is undefined.
|
276
|
+
#
|
277
|
+
# @param val [Integer] the transaction value.
|
278
|
+
# @return [Integer] the sanitized transaction value.
|
279
|
+
def sanitize_amount(val)
|
280
|
+
val = 0 if val.nil?
|
281
|
+
return val
|
178
282
|
end
|
179
283
|
|
180
|
-
|
181
|
-
|
284
|
+
# Populates the transaction payload field with a serializable empty value
|
285
|
+
# in case it is undefined; also ensures the data is binary not hex.
|
286
|
+
#
|
287
|
+
# @param data [String] the transaction payload data.
|
288
|
+
# @return [String] the sanitized transaction payload data.
|
289
|
+
def sanitize_data(data)
|
290
|
+
data = "" if data.nil?
|
291
|
+
|
292
|
+
# ensure payload to be binary if it's hex, otherwise we'll treat it raw
|
293
|
+
data = Util.hex_to_bin data if Util.is_hex? data
|
294
|
+
return data
|
182
295
|
end
|
183
296
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
297
|
+
# Populates the transaction access list field with a serializable empty
|
298
|
+
# array in case it is undefined; also ensures the nested data is binary
|
299
|
+
# not hex.
|
300
|
+
#
|
301
|
+
# @param list [Array] the transaction access list.
|
302
|
+
# @return [Array] the sanitized transaction access list.
|
303
|
+
def sanitize_list(list)
|
304
|
+
list = [] if list.nil?
|
305
|
+
list.each_with_index do |value, index|
|
306
|
+
if value.is_a? Array
|
307
|
+
|
308
|
+
# recursively check the entire array
|
309
|
+
list[index] = sanitize_list value
|
310
|
+
elsif Util.is_hex? value
|
311
|
+
|
312
|
+
# only modify if we find a hex value
|
313
|
+
list[index] = Util.hex_to_bin value
|
314
|
+
end
|
191
315
|
end
|
316
|
+
return list
|
192
317
|
end
|
193
318
|
|
319
|
+
# Allows to check wether a transaction is signed already.
|
320
|
+
#
|
321
|
+
# @return [Bool] true if transaction is already signed.
|
322
|
+
def is_signed?(tx)
|
323
|
+
!tx.signature_r.nil? and tx.signature_r != 0 and
|
324
|
+
!tx.signature_s.nil? and tx.signature_s != 0
|
325
|
+
end
|
194
326
|
end
|
195
|
-
|
196
|
-
UnsignedTx = Tx.exclude([:v, :r, :s])
|
197
327
|
end
|
data/lib/eth/unit.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# Copyright (c) 2016-2022 The Ruby-Eth Contributors
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require "bigdecimal"
|
16
|
+
|
17
|
+
# Provides the {Eth} module.
|
18
|
+
module Eth
|
19
|
+
|
20
|
+
# Provides constants for common Ethereum units.
|
21
|
+
module Unit
|
22
|
+
extend self
|
23
|
+
|
24
|
+
# Ethereum unit 1 wei := 0.000000000000000001 Ether.
|
25
|
+
WEI = BigDecimal("1e0").freeze
|
26
|
+
|
27
|
+
# Ethereum unit 1 babbage := 0.000000000000001 Ether or 1_000 wei.
|
28
|
+
BABBAGE = BigDecimal("1e3").freeze
|
29
|
+
|
30
|
+
# Ethereum unit 1 lovelace := 0.000000000001 Ether or 1_000_000 wei.
|
31
|
+
LOVELACE = BigDecimal("1e6").freeze
|
32
|
+
|
33
|
+
# Ethereum unit 1 shannon := 0.000000001 Ether or 1_000_000_000 wei.
|
34
|
+
SHANNON = BigDecimal("1e9").freeze
|
35
|
+
|
36
|
+
# Ethereum unit 1 szabo := 0.000_001 Ether or 1_000_000_000_000 wei.
|
37
|
+
SZABO = BigDecimal("1e12").freeze
|
38
|
+
|
39
|
+
# Ethereum unit 1 finney := 0.001 Ether or 1_000_000_000_000_000 wei.
|
40
|
+
FINNEY = BigDecimal("1e15").freeze
|
41
|
+
|
42
|
+
# Ethereum unit 1 Ether := 1_000_000_000_000_000_000 wei.
|
43
|
+
ETHER = BigDecimal("1e18").freeze
|
44
|
+
|
45
|
+
# Ethereum unit 1 Gwei := 0.000000001 Ether or 1_000_000_000 wei.
|
46
|
+
# Same as shannon, but more commonly used (billion wei).
|
47
|
+
GWEI = SHANNON.freeze
|
48
|
+
end
|
49
|
+
end
|