eth 0.5.14 → 0.5.16

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.
data/lib/eth/tx/legacy.rb CHANGED
@@ -68,7 +68,7 @@ module Eth
68
68
  # @option params [Integer] :gas_price the gas price.
69
69
  # @option params [Integer] :gas_limit the gas limit.
70
70
  # @option params [Eth::Address] :from the sender address.
71
- # @option params [Eth::Address] :to the reciever address.
71
+ # @option params [Eth::Address] :to the receiver address.
72
72
  # @option params [Integer] :value the transaction value.
73
73
  # @option params [String] :data the transaction data payload.
74
74
  # @param chain_id [Integer] the EIP-155 Chain ID.
@@ -128,18 +128,18 @@ module Eth
128
128
  raise ParameterError, "Transaction missing fields!" if tx.size < 9
129
129
 
130
130
  # populate the 9 fields
131
- nonce = Util.deserialize_big_endian_to_int tx[0]
132
- gas_price = Util.deserialize_big_endian_to_int tx[1]
133
- gas_limit = Util.deserialize_big_endian_to_int tx[2]
131
+ nonce = Util.deserialize_rlp_int tx[0]
132
+ gas_price = Util.deserialize_rlp_int tx[1]
133
+ gas_limit = Util.deserialize_rlp_int tx[2]
134
134
  to = Util.bin_to_hex tx[3]
135
- value = Util.deserialize_big_endian_to_int tx[4]
135
+ value = Util.deserialize_rlp_int tx[4]
136
136
  data = tx[5]
137
137
  v = Util.bin_to_hex tx[6]
138
138
  r = Util.bin_to_hex tx[7]
139
139
  s = Util.bin_to_hex tx[8]
140
140
 
141
141
  # try to recover the chain id from v
142
- chain_id = Chain.to_chain_id Util.deserialize_big_endian_to_int tx[6]
142
+ chain_id = Chain.to_chain_id Util.deserialize_rlp_int tx[6]
143
143
 
144
144
  # populate class attributes
145
145
  @signer_nonce = nonce.to_i
@@ -223,6 +223,30 @@ module Eth
223
223
  return hash
224
224
  end
225
225
 
226
+ # Signs the transaction with a provided signature blob.
227
+ #
228
+ # @param signature [String] the concatenated `r`, `s`, and `v` values.
229
+ # @return [String] a transaction hash.
230
+ # @raise [Signature::SignatureError] if transaction is already signed.
231
+ # @raise [Signature::SignatureError] if sender address does not match signer.
232
+ def sign_with(signature)
233
+ if Tx.signed? self
234
+ raise Signature::SignatureError, "Transaction is already signed!"
235
+ end
236
+
237
+ # ensure the sender address matches the signature
238
+ unless @sender.nil? or sender.empty?
239
+ public_key = Signature.recover(unsigned_hash, signature, @chain_id)
240
+ signer_address = Tx.sanitize_address Util.public_key_to_address(public_key).to_s
241
+ from_address = Tx.sanitize_address @sender
242
+ raise Signature::SignatureError, "Signer does not match sender" unless signer_address == from_address
243
+ end
244
+
245
+ r, s, v = Signature.dissect signature
246
+ send :_set_signature, v, r, s
247
+ return hash
248
+ end
249
+
226
250
  # Encodes a raw transaction object.
227
251
  #
228
252
  # @return [String] a raw, RLP-encoded legacy transaction.
data/lib/eth/tx.rb CHANGED
@@ -17,6 +17,7 @@ require "konstructor"
17
17
  require "eth/chain"
18
18
  require "eth/tx/eip1559"
19
19
  require "eth/tx/eip2930"
20
+ require "eth/tx/eip4844"
20
21
  require "eth/tx/eip7702"
21
22
  require "eth/tx/legacy"
22
23
  require "eth/unit"
@@ -87,6 +88,8 @@ module Eth
87
88
 
88
89
  # Creates a new transaction of any type for given parameters and chain ID.
89
90
  # Required parameters are (optional in brackets):
91
+ # - EIP-4844: chain_id, nonce, priority_fee, max_gas_fee, gas_limit, max_fee_per_blob_gas, blob_versioned_hashes(, from, to,
92
+ # value, data, access_list)
90
93
  # - EIP-1559: chain_id, nonce, priority_fee, max_gas_fee, gas_limit(, from, to,
91
94
  # value, data, access_list)
92
95
  # - EIP-2930: chain_id, nonce, gas_price, gas_limit, access_list(, from, to,
@@ -99,9 +102,10 @@ module Eth
99
102
  # @param chain_id [Integer] the EIP-155 Chain ID (legacy transactions only).
100
103
  def new(params, chain_id = Chain::ETHEREUM)
101
104
 
102
- # if we deal with blobs, attempt EIP-4844 (not implemented)
105
+ # if we deal with blobs, attempt EIP-4844
103
106
  unless params[:max_fee_per_blob_gas].nil?
104
- raise NotimplementedError, "EIP-4844 blob transactions are not implemented"
107
+ params[:chain_id] = chain_id if params[:chain_id].nil?
108
+ return Tx::Eip4844.new params
105
109
  end
106
110
 
107
111
  # if we deal with authorizations, attempt EIP-7702
@@ -148,7 +152,7 @@ module Eth
148
152
  when TYPE_4844
149
153
 
150
154
  # EIP-4844 transaction (type 3)
151
- raise NotimplementedError, "EIP-4844 blob transactions are not implemented"
155
+ return Tx::Eip4844.decode hex
152
156
  when TYPE_7702
153
157
 
154
158
  # EIP-7702 transaction (type 4)
@@ -182,7 +186,7 @@ module Eth
182
186
  when TYPE_4844
183
187
 
184
188
  # EIP-4844 transaction (type 3)
185
- raise NotimplementedError, "EIP-4844 blob transactions are not implemented"
189
+ return Tx::Eip4844.unsigned_copy tx
186
190
  when TYPE_7702
187
191
 
188
192
  # EIP-7702 transaction (type 4)
@@ -278,6 +282,27 @@ module Eth
278
282
  return fields
279
283
  end
280
284
 
285
+ # Validates that the type-3 transaction blob fields are present
286
+ #
287
+ # @param fields [Hash] the transaction fields.
288
+ # @return [Hash] the validated transaction fields.
289
+ # @raise [ParameterError] if max blob fee or blob hashes are invalid or exceed limits.
290
+ def validate_eip4844_params(fields)
291
+ if fields[:max_fee_per_blob_gas].nil? or fields[:max_fee_per_blob_gas] < 0
292
+ raise ParameterError, "Invalid max blob fee #{fields[:max_fee_per_blob_gas]}!"
293
+ end
294
+ if fields[:blob_versioned_hashes].nil? or !fields[:blob_versioned_hashes].is_a? Array or fields[:blob_versioned_hashes].empty?
295
+ raise ParameterError, "Invalid blob versioned hashes #{fields[:blob_versioned_hashes]}!"
296
+ end
297
+ if fields[:blob_versioned_hashes].length > Eip4844::MAX_BLOBS_PER_BLOCK
298
+ raise ParameterError, "Too many blob versioned hashes #{fields[:blob_versioned_hashes].length}!"
299
+ end
300
+ if fields[:to].nil? or fields[:to].empty?
301
+ raise ParameterError, "Invalid destination address #{fields[:to]}!"
302
+ end
303
+ return fields
304
+ end
305
+
281
306
  # Validates that the type-4 transaction field authorization list is present
282
307
  #
283
308
  # @param fields [Hash] the transaction fields.
@@ -372,6 +397,22 @@ module Eth
372
397
  return list
373
398
  end
374
399
 
400
+ # Populates the blob versioned hashes field with a serializable empty
401
+ # array in case it is undefined; also ensures the hashes are binary
402
+ # not hex.
403
+ #
404
+ # @param list [Array] the blob versioned hashes.
405
+ # @return [Array] the sanitized blob versioned hashes.
406
+ def sanitize_hashes(list)
407
+ list = [] if list.nil?
408
+ list.each_with_index do |value, index|
409
+ if Util.hex? value
410
+ list[index] = Util.hex_to_bin value
411
+ end
412
+ end
413
+ return list
414
+ end
415
+
375
416
  # Allows to check wether a transaction is signed already.
376
417
  #
377
418
  # @return [Bool] true if transaction is already signed.
data/lib/eth/util.rb CHANGED
@@ -72,8 +72,7 @@ module Eth
72
72
  # @param hex [String] a hex-string to be prefixed.
73
73
  # @return [String] a prefixed hex-string.
74
74
  def prefix_hex(hex)
75
- return hex if prefixed? hex
76
- return "0x#{hex}"
75
+ "0x#{remove_hex_prefix hex}"
77
76
  end
78
77
 
79
78
  # Removes the `0x` prefix of a hexa-decimal string.
@@ -93,12 +92,12 @@ module Eth
93
92
  prefix_hex bin_to_hex bin
94
93
  end
95
94
 
96
- # Checks if a string is hex-adecimal.
95
+ # Checks if a string is hexadecimal.
97
96
  #
98
97
  # @param str [String] a string to be checked.
99
- # @return [String] a match if true; `nil` if not.
98
+ # @return [MatchData, nil] a match if true; `nil` if not.
100
99
  def hex?(str)
101
- return false unless str.is_a? String
100
+ return unless str.is_a? String
102
101
  str = remove_hex_prefix str
103
102
  str.match /\A[0-9a-fA-F]*\z/
104
103
  end
@@ -108,7 +107,7 @@ module Eth
108
107
  # @param hex [String] a string to be checked.
109
108
  # @return [String] a match if true; `nil` if not.
110
109
  def prefixed?(hex)
111
- hex.match /\A0x/
110
+ hex.match /\A0x/i
112
111
  end
113
112
 
114
113
  # Serializes an unsigned integer to big endian.
@@ -129,7 +128,11 @@ module Eth
129
128
  # @param num [Integer] integer to be converted.
130
129
  # @return [String] packed, big-endian integer string.
131
130
  def int_to_big_endian(num)
132
- hex = num.to_s(16) unless hex? num
131
+ hex = if hex? num
132
+ remove_hex_prefix num
133
+ else
134
+ num.to_s(16)
135
+ end
133
136
  hex = "0#{hex}" if hex.size.odd?
134
137
  hex_to_bin hex
135
138
  end
@@ -142,6 +145,15 @@ module Eth
142
145
  Rlp::Sedes.big_endian_int.deserialize str.sub(/\A(\x00)+/, "")
143
146
  end
144
147
 
148
+ # Deserializes an RLP integer, enforcing minimal encoding.
149
+ #
150
+ # @param str [String] serialized big endian integer string.
151
+ # @return [Integer] a deserialized unsigned integer.
152
+ # @raise [Rlp::DeserializationError] if encoding is not minimal.
153
+ def deserialize_rlp_int(str)
154
+ Rlp::Sedes.big_endian_int.deserialize str
155
+ end
156
+
145
157
  # Converts a big endian to an interger.
146
158
  #
147
159
  # @param str [String] big endian to be converted.
data/lib/eth/version.rb CHANGED
@@ -22,7 +22,7 @@ module Eth
22
22
  MINOR = 5.freeze
23
23
 
24
24
  # Defines the patch version of the {Eth} module.
25
- PATCH = 14.freeze
25
+ PATCH = 16.freeze
26
26
 
27
27
  # Defines the version string of the {Eth} module.
28
28
  VERSION = [MAJOR, MINOR, PATCH].join(".").freeze
data/lib/eth.rb CHANGED
@@ -32,5 +32,6 @@ require "eth/solidity"
32
32
  require "eth/tx"
33
33
  require "eth/unit"
34
34
  require "eth/util"
35
+ require "eth/bls"
35
36
  require "eth/ens"
36
37
  require "eth/version"
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eth
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.14
4
+ version: 0.5.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Ellis
8
8
  - Afri Schoedon
9
- autorequire:
10
9
  bindir: exe
11
10
  cert_chain: []
12
- date: 2025-04-16 00:00:00.000000000 Z
11
+ date: 1980-01-02 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: bigdecimal
@@ -85,22 +84,30 @@ dependencies:
85
84
  name: openssl
86
85
  requirement: !ruby/object:Gem::Requirement
87
86
  requirements:
88
- - - ">="
89
- - !ruby/object:Gem::Version
90
- version: '2.2'
91
- - - "<"
87
+ - - "~>"
92
88
  - !ruby/object:Gem::Version
93
- version: '4.0'
89
+ version: '3.3'
94
90
  type: :runtime
95
91
  prerelease: false
96
92
  version_requirements: !ruby/object:Gem::Requirement
97
93
  requirements:
98
- - - ">="
94
+ - - "~>"
99
95
  - !ruby/object:Gem::Version
100
- version: '2.2'
101
- - - "<"
96
+ version: '3.3'
97
+ - !ruby/object:Gem::Dependency
98
+ name: base64
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.1'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
102
109
  - !ruby/object:Gem::Version
103
- version: '4.0'
110
+ version: '0.1'
104
111
  - !ruby/object:Gem::Dependency
105
112
  name: scrypt
106
113
  requirement: !ruby/object:Gem::Requirement
@@ -115,6 +122,34 @@ dependencies:
115
122
  - - "~>"
116
123
  - !ruby/object:Gem::Version
117
124
  version: '3.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: bls12-381
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '0.3'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '0.3'
139
+ - !ruby/object:Gem::Dependency
140
+ name: httpx
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '1.6'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '1.6'
118
153
  description: Library to handle Ethereum accounts, messages, and transactions.
119
154
  email:
120
155
  - email@steveell.is
@@ -151,16 +186,20 @@ files:
151
186
  - lib/eth/abi/decoder.rb
152
187
  - lib/eth/abi/encoder.rb
153
188
  - lib/eth/abi/event.rb
189
+ - lib/eth/abi/function.rb
154
190
  - lib/eth/abi/packed/encoder.rb
155
191
  - lib/eth/abi/type.rb
156
192
  - lib/eth/address.rb
157
193
  - lib/eth/api.rb
194
+ - lib/eth/bls.rb
158
195
  - lib/eth/chain.rb
159
196
  - lib/eth/client.rb
160
197
  - lib/eth/client/http.rb
161
198
  - lib/eth/client/ipc.rb
199
+ - lib/eth/client/ws.rb
162
200
  - lib/eth/constant.rb
163
201
  - lib/eth/contract.rb
202
+ - lib/eth/contract/error.rb
164
203
  - lib/eth/contract/event.rb
165
204
  - lib/eth/contract/function.rb
166
205
  - lib/eth/contract/function_input.rb
@@ -185,6 +224,7 @@ files:
185
224
  - lib/eth/tx.rb
186
225
  - lib/eth/tx/eip1559.rb
187
226
  - lib/eth/tx/eip2930.rb
227
+ - lib/eth/tx/eip4844.rb
188
228
  - lib/eth/tx/eip7702.rb
189
229
  - lib/eth/tx/legacy.rb
190
230
  - lib/eth/unit.rb
@@ -199,7 +239,6 @@ metadata:
199
239
  documentation_uri: https://q9f.github.io/eth.rb/
200
240
  github_repo: https://github.com/q9f/eth.rb
201
241
  source_code_uri: https://github.com/q9f/eth.rb
202
- post_install_message:
203
242
  rdoc_options: []
204
243
  require_paths:
205
244
  - lib
@@ -218,8 +257,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
218
257
  - !ruby/object:Gem::Version
219
258
  version: '0'
220
259
  requirements: []
221
- rubygems_version: 3.5.22
222
- signing_key:
260
+ rubygems_version: 3.6.9
223
261
  specification_version: 4
224
262
  summary: Ruby Ethereum library.
225
263
  test_files: []