eth 0.4.18 → 0.5.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 +4 -4
- data/.github/workflows/codeql.yml +2 -2
- data/.github/workflows/docs.yml +1 -1
- data/.github/workflows/{build.yml → spec.yml} +12 -7
- data/.gitignore +24 -24
- data/.gitmodules +3 -3
- data/AUTHORS.txt +16 -0
- data/Gemfile +12 -4
- data/LICENSE.txt +202 -22
- data/README.md +154 -84
- data/bin/console +4 -5
- data/bin/setup +4 -2
- data/eth.gemspec +24 -18
- data/lib/eth/abi/constant.rb +63 -0
- data/lib/eth/abi/type.rb +177 -0
- data/lib/eth/abi.rb +390 -0
- data/lib/eth/address.rb +50 -10
- data/lib/eth/chain.rb +148 -0
- data/lib/eth/eip712.rb +184 -0
- data/lib/eth/key/decrypter.rb +118 -85
- data/lib/eth/key/encrypter.rb +178 -99
- data/lib/eth/key.rb +129 -45
- data/lib/eth/signature.rb +160 -0
- data/lib/eth/tx/eip1559.rb +329 -0
- data/lib/eth/tx/eip2930.rb +321 -0
- data/lib/eth/tx/legacy.rb +293 -0
- data/lib/eth/tx.rb +279 -147
- data/lib/eth/unit.rb +49 -0
- data/lib/eth/util.rb +178 -0
- data/lib/eth/version.rb +18 -1
- data/lib/eth.rb +27 -67
- metadata +35 -84
- data/lib/eth/gas.rb +0 -7
- data/lib/eth/open_ssl.rb +0 -395
- data/lib/eth/secp256k1.rb +0 -5
- data/lib/eth/sedes.rb +0 -39
- data/lib/eth/utils.rb +0 -126
data/lib/eth/open_ssl.rb
DELETED
@@ -1,395 +0,0 @@
|
|
1
|
-
# originally lifted from https://github.com/lian/bitcoin-ruby
|
2
|
-
# thanks to everyone there for figuring this out
|
3
|
-
|
4
|
-
# encoding: ascii-8bit
|
5
|
-
|
6
|
-
require "openssl"
|
7
|
-
require "ffi"
|
8
|
-
|
9
|
-
module Eth
|
10
|
-
class OpenSsl
|
11
|
-
extend FFI::Library
|
12
|
-
|
13
|
-
# Use the library loaded by the extension require above.
|
14
|
-
ffi_lib FFI::CURRENT_PROCESS
|
15
|
-
|
16
|
-
NID_secp256k1 = 714
|
17
|
-
POINT_CONVERSION_COMPRESSED = 2
|
18
|
-
POINT_CONVERSION_UNCOMPRESSED = 4
|
19
|
-
|
20
|
-
# OpenSSL 1.1.0 engine constants, taken from:
|
21
|
-
# https://github.com/openssl/openssl/blob/2be8c56a39b0ec2ec5af6ceaf729df154d784a43/include/openssl/crypto.h
|
22
|
-
OPENSSL_INIT_ENGINE_RDRAND = 0x00000200
|
23
|
-
OPENSSL_INIT_ENGINE_DYNAMIC = 0x00000400
|
24
|
-
OPENSSL_INIT_ENGINE_CRYPTODEV = 0x00001000
|
25
|
-
OPENSSL_INIT_ENGINE_CAPI = 0x00002000
|
26
|
-
OPENSSL_INIT_ENGINE_PADLOCK = 0x00004000
|
27
|
-
OPENSSL_INIT_ENGINE_ALL_BUILTIN = (OPENSSL_INIT_ENGINE_RDRAND |
|
28
|
-
OPENSSL_INIT_ENGINE_DYNAMIC |
|
29
|
-
OPENSSL_INIT_ENGINE_CRYPTODEV |
|
30
|
-
OPENSSL_INIT_ENGINE_CAPI |
|
31
|
-
OPENSSL_INIT_ENGINE_PADLOCK)
|
32
|
-
|
33
|
-
# OpenSSL 1.1.0 load strings constant, taken from:
|
34
|
-
# https://github.com/openssl/openssl/blob/c162c126be342b8cd97996346598ecf7db56130f/include/openssl/ssl.h
|
35
|
-
OPENSSL_INIT_LOAD_SSL_STRINGS = 0x00200000
|
36
|
-
|
37
|
-
# This is the very first function we need to use to determine what version
|
38
|
-
# of OpenSSL we are interacting with.
|
39
|
-
begin
|
40
|
-
attach_function :OpenSSL_version_num, [], :ulong
|
41
|
-
rescue FFI::NotFoundError
|
42
|
-
attach_function :SSLeay, [], :long
|
43
|
-
end
|
44
|
-
|
45
|
-
begin
|
46
|
-
# Initialization procedure for the library was changed in OpenSSL 1.1.0
|
47
|
-
attach_function :OPENSSL_init_ssl, [:uint64, :pointer], :int
|
48
|
-
rescue FFI::NotFoundError
|
49
|
-
attach_function :SSL_library_init, [], :int
|
50
|
-
attach_function :ERR_load_crypto_strings, [], :void
|
51
|
-
attach_function :SSL_load_error_strings, [], :void
|
52
|
-
end
|
53
|
-
|
54
|
-
attach_function :RAND_poll, [], :int
|
55
|
-
|
56
|
-
attach_function :BN_CTX_free, [:pointer], :int
|
57
|
-
attach_function :BN_CTX_new, [], :pointer
|
58
|
-
attach_function :BN_add, %i[pointer pointer pointer], :int
|
59
|
-
attach_function :BN_bin2bn, %i[pointer int pointer], :pointer
|
60
|
-
attach_function :BN_bn2bin, %i[pointer pointer], :int
|
61
|
-
attach_function :BN_cmp, %i[pointer pointer], :int
|
62
|
-
attach_function :BN_dup, [:pointer], :pointer
|
63
|
-
attach_function :BN_free, [:pointer], :int
|
64
|
-
attach_function :BN_mod_inverse, %i[pointer pointer pointer pointer], :pointer
|
65
|
-
attach_function :BN_mod_mul, %i[pointer pointer pointer pointer pointer], :int
|
66
|
-
attach_function :BN_mod_sub, %i[pointer pointer pointer pointer pointer], :int
|
67
|
-
attach_function :BN_mul_word, %i[pointer int], :int
|
68
|
-
attach_function :BN_new, [], :pointer
|
69
|
-
attach_function :BN_rshift, %i[pointer pointer int], :int
|
70
|
-
attach_function :BN_rshift1, %i[pointer pointer], :int
|
71
|
-
attach_function :BN_set_word, %i[pointer int], :int
|
72
|
-
attach_function :BN_sub, %i[pointer pointer pointer], :int
|
73
|
-
attach_function :EC_GROUP_get_curve_GFp, %i[pointer pointer pointer pointer pointer], :int
|
74
|
-
attach_function :EC_GROUP_get_degree, [:pointer], :int
|
75
|
-
attach_function :EC_GROUP_get_order, %i[pointer pointer pointer], :int
|
76
|
-
attach_function :EC_KEY_free, [:pointer], :int
|
77
|
-
attach_function :EC_KEY_get0_group, [:pointer], :pointer
|
78
|
-
attach_function :EC_KEY_get0_private_key, [:pointer], :pointer
|
79
|
-
attach_function :EC_KEY_new_by_curve_name, [:int], :pointer
|
80
|
-
attach_function :EC_KEY_set_conv_form, %i[pointer int], :void
|
81
|
-
attach_function :EC_KEY_set_private_key, %i[pointer pointer], :int
|
82
|
-
attach_function :EC_KEY_set_public_key, %i[pointer pointer], :int
|
83
|
-
attach_function :EC_POINT_free, [:pointer], :int
|
84
|
-
attach_function :EC_POINT_mul, %i[pointer pointer pointer pointer pointer pointer], :int
|
85
|
-
attach_function :EC_POINT_new, [:pointer], :pointer
|
86
|
-
attach_function :EC_POINT_set_compressed_coordinates_GFp,
|
87
|
-
%i[pointer pointer pointer int pointer], :int
|
88
|
-
attach_function :i2o_ECPublicKey, %i[pointer pointer], :uint
|
89
|
-
attach_function :ECDSA_do_sign, %i[pointer uint pointer], :pointer
|
90
|
-
attach_function :BN_num_bits, [:pointer], :int
|
91
|
-
attach_function :ECDSA_SIG_free, [:pointer], :void
|
92
|
-
attach_function :EC_POINT_add, %i[pointer pointer pointer pointer pointer], :int
|
93
|
-
attach_function :EC_POINT_point2hex, %i[pointer pointer int pointer], :string
|
94
|
-
attach_function :EC_POINT_hex2point, %i[pointer string pointer pointer], :pointer
|
95
|
-
attach_function :d2i_ECDSA_SIG, %i[pointer pointer long], :pointer
|
96
|
-
attach_function :i2d_ECDSA_SIG, %i[pointer pointer], :int
|
97
|
-
attach_function :OPENSSL_free, :CRYPTO_free, [:pointer], :void
|
98
|
-
|
99
|
-
def self.BN_num_bytes(ptr) # rubocop:disable Naming/MethodName
|
100
|
-
(BN_num_bits(ptr) + 7) / 8
|
101
|
-
end
|
102
|
-
|
103
|
-
# resolve public from private key, using ffi and libssl.so
|
104
|
-
# example:
|
105
|
-
# keypair = Bitcoin.generate_key; Bitcoin::OpenSSL_EC.regenerate_key(keypair.first) == keypair
|
106
|
-
def self.regenerate_key(private_key)
|
107
|
-
private_key = [private_key].pack("H*") if private_key.bytesize >= (32 * 2)
|
108
|
-
private_key_hex = private_key.unpack("H*")[0]
|
109
|
-
|
110
|
-
group = OpenSSL::PKey::EC::Group.new("secp256k1")
|
111
|
-
key = OpenSSL::PKey::EC.new(group)
|
112
|
-
key.private_key = OpenSSL::BN.new(private_key_hex, 16)
|
113
|
-
key.public_key = group.generator.mul(key.private_key)
|
114
|
-
|
115
|
-
priv_hex = key.private_key.to_bn.to_s(16).downcase.rjust(64, "0")
|
116
|
-
if priv_hex != private_key_hex
|
117
|
-
raise "regenerated wrong private_key, raise here before generating a faulty public_key too!"
|
118
|
-
end
|
119
|
-
|
120
|
-
[priv_hex, key.public_key.to_bn.to_s(16).downcase]
|
121
|
-
end
|
122
|
-
|
123
|
-
# Given the components of a signature and a selector value, recover and
|
124
|
-
# return the public key that generated the signature according to the
|
125
|
-
# algorithm in SEC1v2 section 4.1.6.
|
126
|
-
#
|
127
|
-
# rec_id is an index from 0 to 3 that indicates which of the 4 possible
|
128
|
-
# keys is the correct one. Because the key recovery operation yields
|
129
|
-
# multiple potential keys, the correct key must either be stored alongside
|
130
|
-
# the signature, or you must be willing to try each rec_id in turn until
|
131
|
-
# you find one that outputs the key you are expecting.
|
132
|
-
#
|
133
|
-
# If this method returns nil, it means recovery was not possible and rec_id
|
134
|
-
# should be iterated.
|
135
|
-
#
|
136
|
-
# Given the above two points, a correct usage of this method is inside a
|
137
|
-
# for loop from 0 to 3, and if the output is nil OR a key that is not the
|
138
|
-
# one you expect, you try again with the next rec_id.
|
139
|
-
#
|
140
|
-
# message_hash = hash of the signed message.
|
141
|
-
# signature = the R and S components of the signature, wrapped.
|
142
|
-
# rec_id = which possible key to recover.
|
143
|
-
# is_compressed = whether or not the original pubkey was compressed.
|
144
|
-
def self.recover_public_key_from_signature(message_hash, signature, rec_id, is_compressed)
|
145
|
-
return nil if rec_id < 0 || signature.bytesize != 65
|
146
|
-
init_ffi_ssl
|
147
|
-
|
148
|
-
signature = FFI::MemoryPointer.from_string(signature)
|
149
|
-
# signature_bn = BN_bin2bn(signature, 65, BN_new())
|
150
|
-
r = BN_bin2bn(signature[1], 32, BN_new())
|
151
|
-
s = BN_bin2bn(signature[33], 32, BN_new())
|
152
|
-
|
153
|
-
i = rec_id / 2
|
154
|
-
eckey = EC_KEY_new_by_curve_name(NID_secp256k1)
|
155
|
-
|
156
|
-
EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED) if is_compressed
|
157
|
-
|
158
|
-
group = EC_KEY_get0_group(eckey)
|
159
|
-
order = BN_new()
|
160
|
-
EC_GROUP_get_order(group, order, nil)
|
161
|
-
x = BN_dup(order)
|
162
|
-
BN_mul_word(x, i)
|
163
|
-
BN_add(x, x, r)
|
164
|
-
|
165
|
-
field = BN_new()
|
166
|
-
EC_GROUP_get_curve_GFp(group, field, nil, nil, nil)
|
167
|
-
|
168
|
-
if BN_cmp(x, field) >= 0
|
169
|
-
[r, s, order, x, field].each { |item| BN_free(item) }
|
170
|
-
EC_KEY_free(eckey)
|
171
|
-
return nil
|
172
|
-
end
|
173
|
-
|
174
|
-
big_r = EC_POINT_new(group)
|
175
|
-
EC_POINT_set_compressed_coordinates_GFp(group, big_r, x, rec_id % 2, nil)
|
176
|
-
|
177
|
-
big_q = EC_POINT_new(group)
|
178
|
-
n = EC_GROUP_get_degree(group)
|
179
|
-
e = BN_bin2bn(message_hash, message_hash.bytesize, BN_new())
|
180
|
-
BN_rshift(e, e, 8 - (n & 7)) if 8 * message_hash.bytesize > n
|
181
|
-
|
182
|
-
ctx = BN_CTX_new()
|
183
|
-
zero = BN_new()
|
184
|
-
rr = BN_new()
|
185
|
-
sor = BN_new()
|
186
|
-
eor = BN_new()
|
187
|
-
BN_set_word(zero, 0)
|
188
|
-
BN_mod_sub(e, zero, e, order, ctx)
|
189
|
-
BN_mod_inverse(rr, r, order, ctx)
|
190
|
-
BN_mod_mul(sor, s, rr, order, ctx)
|
191
|
-
BN_mod_mul(eor, e, rr, order, ctx)
|
192
|
-
EC_POINT_mul(group, big_q, eor, big_r, sor, ctx)
|
193
|
-
EC_KEY_set_public_key(eckey, big_q)
|
194
|
-
BN_CTX_free(ctx)
|
195
|
-
|
196
|
-
[r, s, order, x, field, e, zero, rr, sor, eor].each { |item| BN_free(item) }
|
197
|
-
[big_r, big_q].each { |item| EC_POINT_free(item) }
|
198
|
-
|
199
|
-
length = i2o_ECPublicKey(eckey, nil)
|
200
|
-
buf = FFI::MemoryPointer.new(:uint8, length)
|
201
|
-
ptr = FFI::MemoryPointer.new(:pointer).put_pointer(0, buf)
|
202
|
-
pub_hex = buf.read_string(length).unpack("H*")[0] if i2o_ECPublicKey(eckey, ptr) == length
|
203
|
-
|
204
|
-
EC_KEY_free(eckey)
|
205
|
-
|
206
|
-
pub_hex
|
207
|
-
end
|
208
|
-
|
209
|
-
# Regenerate a DER-encoded signature such that the S-value complies with the BIP62
|
210
|
-
# specification.
|
211
|
-
#
|
212
|
-
def self.signature_to_low_s(signature)
|
213
|
-
init_ffi_ssl
|
214
|
-
|
215
|
-
buf = FFI::MemoryPointer.new(:uint8, 34)
|
216
|
-
temp = signature.unpack("C*")
|
217
|
-
length_r = temp[3]
|
218
|
-
length_s = temp[5 + length_r]
|
219
|
-
sig = FFI::MemoryPointer.from_string(signature)
|
220
|
-
|
221
|
-
# Calculate the lower s value
|
222
|
-
s = BN_bin2bn(sig[6 + length_r], length_s, BN_new())
|
223
|
-
eckey = EC_KEY_new_by_curve_name(NID_secp256k1)
|
224
|
-
group = EC_KEY_get0_group(eckey)
|
225
|
-
order = BN_new()
|
226
|
-
halforder = BN_new()
|
227
|
-
ctx = BN_CTX_new()
|
228
|
-
|
229
|
-
EC_GROUP_get_order(group, order, ctx)
|
230
|
-
BN_rshift1(halforder, order)
|
231
|
-
BN_sub(s, order, s) if BN_cmp(s, halforder) > 0
|
232
|
-
|
233
|
-
BN_free(halforder)
|
234
|
-
BN_free(order)
|
235
|
-
BN_CTX_free(ctx)
|
236
|
-
|
237
|
-
length_s = BN_bn2bin(s, buf)
|
238
|
-
# p buf.read_string(length_s).unpack("H*")
|
239
|
-
|
240
|
-
# Re-encode the signature in DER format
|
241
|
-
sig = [0x30, 0, 0x02, length_r]
|
242
|
-
sig.concat(temp.slice(4, length_r))
|
243
|
-
sig << 0x02
|
244
|
-
sig << length_s
|
245
|
-
sig.concat(buf.read_string(length_s).unpack("C*"))
|
246
|
-
sig[1] = sig.size - 2
|
247
|
-
|
248
|
-
BN_free(s)
|
249
|
-
EC_KEY_free(eckey)
|
250
|
-
|
251
|
-
sig.pack("C*")
|
252
|
-
end
|
253
|
-
|
254
|
-
def self.sign_compact(hash, private_key, public_key_hex = nil, pubkey_compressed = nil)
|
255
|
-
msg32 = FFI::MemoryPointer.new(:uchar, 32).put_bytes(0, hash)
|
256
|
-
|
257
|
-
private_key = [private_key].pack("H*") if private_key.bytesize >= 64
|
258
|
-
private_key_hex = private_key.unpack("H*")[0]
|
259
|
-
|
260
|
-
public_key_hex ||= regenerate_key(private_key_hex).last
|
261
|
-
pubkey_compressed ||= public_key_hex[0..1] != "04"
|
262
|
-
|
263
|
-
init_ffi_ssl
|
264
|
-
eckey = EC_KEY_new_by_curve_name(NID_secp256k1)
|
265
|
-
priv_key = BN_bin2bn(private_key, private_key.bytesize, BN_new())
|
266
|
-
|
267
|
-
group = EC_KEY_get0_group(eckey)
|
268
|
-
order = BN_new()
|
269
|
-
ctx = BN_CTX_new()
|
270
|
-
EC_GROUP_get_order(group, order, ctx)
|
271
|
-
|
272
|
-
pub_key = EC_POINT_new(group)
|
273
|
-
EC_POINT_mul(group, pub_key, priv_key, nil, nil, ctx)
|
274
|
-
EC_KEY_set_private_key(eckey, priv_key)
|
275
|
-
EC_KEY_set_public_key(eckey, pub_key)
|
276
|
-
|
277
|
-
signature = ECDSA_do_sign(msg32, msg32.size, eckey)
|
278
|
-
|
279
|
-
BN_free(order)
|
280
|
-
BN_CTX_free(ctx)
|
281
|
-
EC_POINT_free(pub_key)
|
282
|
-
BN_free(priv_key)
|
283
|
-
EC_KEY_free(eckey)
|
284
|
-
|
285
|
-
buf = FFI::MemoryPointer.new(:uint8, 32)
|
286
|
-
head = nil
|
287
|
-
r, s = signature.get_array_of_pointer(0, 2).map do |i|
|
288
|
-
BN_bn2bin(i, buf)
|
289
|
-
buf.read_string(BN_num_bytes(i)).rjust(32, "\x00")
|
290
|
-
end
|
291
|
-
|
292
|
-
rec_id = nil
|
293
|
-
if signature.get_array_of_pointer(0, 2).all? { |i| BN_num_bits(i) <= 256 }
|
294
|
-
4.times do |i|
|
295
|
-
head = [27 + i + (pubkey_compressed ? 4 : 0)].pack("C")
|
296
|
-
recovered_key = recover_public_key_from_signature(
|
297
|
-
msg32.read_string(32), [head, r, s].join, i, pubkey_compressed
|
298
|
-
)
|
299
|
-
if public_key_hex == recovered_key
|
300
|
-
rec_id = i
|
301
|
-
break
|
302
|
-
end
|
303
|
-
end
|
304
|
-
end
|
305
|
-
|
306
|
-
ECDSA_SIG_free(signature)
|
307
|
-
|
308
|
-
[head, [r, s]].join if rec_id
|
309
|
-
end
|
310
|
-
|
311
|
-
def self.recover_compact(hash, signature)
|
312
|
-
return false if signature.bytesize != 65
|
313
|
-
msg32 = FFI::MemoryPointer.new(:uchar, 32).put_bytes(0, hash)
|
314
|
-
|
315
|
-
version = signature.unpack("C")[0]
|
316
|
-
|
317
|
-
# Version of signature should be 27 or 28, but 0 and 1 are also possible versions
|
318
|
-
# which can show up in Ledger hardwallet signings
|
319
|
-
if version < 27
|
320
|
-
version += 27
|
321
|
-
end
|
322
|
-
|
323
|
-
return false if version < 27 || version > 34
|
324
|
-
|
325
|
-
compressed = version >= 31
|
326
|
-
version -= 4 if compressed
|
327
|
-
|
328
|
-
recover_public_key_from_signature(msg32.read_string(32), signature, version - 27, compressed)
|
329
|
-
end
|
330
|
-
|
331
|
-
# lifted from https://github.com/GemHQ/money-tree
|
332
|
-
def self.ec_add(point0, point1)
|
333
|
-
init_ffi_ssl
|
334
|
-
|
335
|
-
eckey = EC_KEY_new_by_curve_name(NID_secp256k1)
|
336
|
-
group = EC_KEY_get0_group(eckey)
|
337
|
-
|
338
|
-
point_0_hex = point0.to_bn.to_s(16)
|
339
|
-
point_0_pt = EC_POINT_hex2point(group, point_0_hex, nil, nil)
|
340
|
-
point_1_hex = point1.to_bn.to_s(16)
|
341
|
-
point_1_pt = EC_POINT_hex2point(group, point_1_hex, nil, nil)
|
342
|
-
|
343
|
-
sum_point = EC_POINT_new(group)
|
344
|
-
EC_POINT_add(group, sum_point, point_0_pt, point_1_pt, nil)
|
345
|
-
hex = EC_POINT_point2hex(group, sum_point, POINT_CONVERSION_UNCOMPRESSED, nil)
|
346
|
-
EC_KEY_free(eckey)
|
347
|
-
EC_POINT_free(sum_point)
|
348
|
-
hex
|
349
|
-
end
|
350
|
-
|
351
|
-
# repack signature for OpenSSL 1.0.1k handling of DER signatures
|
352
|
-
# https://github.com/bitcoin/bitcoin/pull/5634/files
|
353
|
-
def self.repack_der_signature(signature)
|
354
|
-
init_ffi_ssl
|
355
|
-
|
356
|
-
return false if signature.empty?
|
357
|
-
|
358
|
-
# New versions of OpenSSL will reject non-canonical DER signatures. de/re-serialize first.
|
359
|
-
norm_der = FFI::MemoryPointer.new(:pointer)
|
360
|
-
sig_ptr = FFI::MemoryPointer.new(:pointer).put_pointer(
|
361
|
-
0, FFI::MemoryPointer.from_string(signature)
|
362
|
-
)
|
363
|
-
|
364
|
-
norm_sig = d2i_ECDSA_SIG(nil, sig_ptr, signature.bytesize)
|
365
|
-
|
366
|
-
derlen = i2d_ECDSA_SIG(norm_sig, norm_der)
|
367
|
-
ECDSA_SIG_free(norm_sig)
|
368
|
-
return false if derlen <= 0
|
369
|
-
|
370
|
-
ret = norm_der.read_pointer.read_string(derlen)
|
371
|
-
OPENSSL_free(norm_der.read_pointer)
|
372
|
-
|
373
|
-
ret
|
374
|
-
end
|
375
|
-
|
376
|
-
def self.init_ffi_ssl
|
377
|
-
@ssl_loaded ||= false
|
378
|
-
return if @ssl_loaded
|
379
|
-
|
380
|
-
if self.method_defined?(:OPENSSL_init_ssl)
|
381
|
-
OPENSSL_init_ssl(
|
382
|
-
OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_ENGINE_ALL_BUILTIN,
|
383
|
-
nil
|
384
|
-
)
|
385
|
-
else
|
386
|
-
SSL_library_init()
|
387
|
-
ERR_load_crypto_strings()
|
388
|
-
SSL_load_error_strings()
|
389
|
-
end
|
390
|
-
|
391
|
-
RAND_poll()
|
392
|
-
@ssl_loaded = true
|
393
|
-
end
|
394
|
-
end
|
395
|
-
end
|
data/lib/eth/secp256k1.rb
DELETED
data/lib/eth/sedes.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
module Eth
|
2
|
-
module Sedes
|
3
|
-
include RLP::Sedes
|
4
|
-
|
5
|
-
extend self
|
6
|
-
|
7
|
-
def address
|
8
|
-
Binary.fixed_length(20, allow_empty: true)
|
9
|
-
end
|
10
|
-
|
11
|
-
def int20
|
12
|
-
BigEndianInt.new(20)
|
13
|
-
end
|
14
|
-
|
15
|
-
def int32
|
16
|
-
BigEndianInt.new(32)
|
17
|
-
end
|
18
|
-
|
19
|
-
def int256
|
20
|
-
BigEndianInt.new(256)
|
21
|
-
end
|
22
|
-
|
23
|
-
def hash32
|
24
|
-
Binary.fixed_length(32)
|
25
|
-
end
|
26
|
-
|
27
|
-
def trie_root
|
28
|
-
Binary.fixed_length(32, allow_empty: true)
|
29
|
-
end
|
30
|
-
|
31
|
-
def big_endian_int
|
32
|
-
RLP::Sedes.big_endian_int
|
33
|
-
end
|
34
|
-
|
35
|
-
def binary
|
36
|
-
RLP::Sedes.binary
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
data/lib/eth/utils.rb
DELETED
@@ -1,126 +0,0 @@
|
|
1
|
-
module Eth
|
2
|
-
module Utils
|
3
|
-
extend self
|
4
|
-
|
5
|
-
def normalize_address(address)
|
6
|
-
if address.nil? || address == ""
|
7
|
-
""
|
8
|
-
elsif address.size == 40
|
9
|
-
hex_to_bin address
|
10
|
-
elsif address.size == 42 && address[0..1] == "0x"
|
11
|
-
hex_to_bin address[2..-1]
|
12
|
-
else
|
13
|
-
address
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def bin_to_hex(string)
|
18
|
-
RLP::Utils.encode_hex string
|
19
|
-
end
|
20
|
-
|
21
|
-
def hex_to_bin(string)
|
22
|
-
RLP::Utils.decode_hex remove_hex_prefix(string)
|
23
|
-
end
|
24
|
-
|
25
|
-
def base256_to_int(str)
|
26
|
-
RLP::Sedes.big_endian_int.deserialize str.sub(/\A(\x00)+/, "")
|
27
|
-
end
|
28
|
-
|
29
|
-
def int_to_base256(int)
|
30
|
-
RLP::Sedes.big_endian_int.serialize int
|
31
|
-
end
|
32
|
-
|
33
|
-
def v_r_s_for(signature)
|
34
|
-
[
|
35
|
-
signature[0].bytes[0],
|
36
|
-
Utils.base256_to_int(signature[1..32]),
|
37
|
-
Utils.base256_to_int(signature[33..65]),
|
38
|
-
]
|
39
|
-
end
|
40
|
-
|
41
|
-
def prefix_hex(hex)
|
42
|
-
hex.match(/\A0x/) ? hex : "0x#{hex}"
|
43
|
-
end
|
44
|
-
|
45
|
-
def remove_hex_prefix(s)
|
46
|
-
s[0, 2] == "0x" ? s[2..-1] : s
|
47
|
-
end
|
48
|
-
|
49
|
-
def bin_to_prefixed_hex(binary)
|
50
|
-
prefix_hex bin_to_hex(binary)
|
51
|
-
end
|
52
|
-
|
53
|
-
def prefix_message(message)
|
54
|
-
"\x19Ethereum Signed Message:\n#{message.length}#{message}"
|
55
|
-
end
|
56
|
-
|
57
|
-
def public_key_to_address(hex)
|
58
|
-
bytes = hex_to_bin(hex)
|
59
|
-
address_bytes = Utils.keccak256(bytes[1..-1])[-20..-1]
|
60
|
-
format_address bin_to_prefixed_hex(address_bytes)
|
61
|
-
end
|
62
|
-
|
63
|
-
def sha256(x)
|
64
|
-
Digest::SHA256.digest x
|
65
|
-
end
|
66
|
-
|
67
|
-
def keccak256(x)
|
68
|
-
Digest::Keccak.new(256).digest(x)
|
69
|
-
end
|
70
|
-
|
71
|
-
def keccak512(x)
|
72
|
-
Digest::Keccak.new(512).digest(x)
|
73
|
-
end
|
74
|
-
|
75
|
-
def keccak256_rlp(x)
|
76
|
-
keccak256 RLP.encode(x)
|
77
|
-
end
|
78
|
-
|
79
|
-
def ripemd160(x)
|
80
|
-
Digest::RMD160.digest x
|
81
|
-
end
|
82
|
-
|
83
|
-
def hash160(x)
|
84
|
-
ripemd160 sha256(x)
|
85
|
-
end
|
86
|
-
|
87
|
-
def zpad(x, l)
|
88
|
-
lpad x, BYTE_ZERO, l
|
89
|
-
end
|
90
|
-
|
91
|
-
def zunpad(x)
|
92
|
-
x.sub(/\A\x00+/, "")
|
93
|
-
end
|
94
|
-
|
95
|
-
def zpad_int(n, l = 32)
|
96
|
-
zpad encode_int(n), l
|
97
|
-
end
|
98
|
-
|
99
|
-
def zpad_hex(s, l = 32)
|
100
|
-
zpad decode_hex(s), l
|
101
|
-
end
|
102
|
-
|
103
|
-
def valid_address?(address)
|
104
|
-
Address.new(address).valid?
|
105
|
-
end
|
106
|
-
|
107
|
-
def format_address(address)
|
108
|
-
Address.new(address).checksummed
|
109
|
-
end
|
110
|
-
|
111
|
-
private
|
112
|
-
|
113
|
-
def lpad(x, symbol, l)
|
114
|
-
return x if x.size >= l
|
115
|
-
symbol * (l - x.size) + x
|
116
|
-
end
|
117
|
-
|
118
|
-
def encode_int(n)
|
119
|
-
unless n.is_a?(Integer) && n >= 0 && n <= UINT_MAX
|
120
|
-
raise ArgumentError, "Integer invalid or out of range: #{n}"
|
121
|
-
end
|
122
|
-
|
123
|
-
int_to_base256 n
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|