eth 0.5.13 → 0.5.14
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 +1 -1
- data/.github/workflows/docs.yml +2 -2
- data/.github/workflows/spec.yml +1 -3
- data/LICENSE.txt +1 -1
- data/README.md +1 -3
- data/eth.gemspec +3 -0
- data/lib/eth/abi/decoder.rb +2 -2
- data/lib/eth/abi/encoder.rb +4 -5
- data/lib/eth/abi/event.rb +5 -1
- data/lib/eth/abi/packed/encoder.rb +196 -0
- data/lib/eth/abi/type.rb +12 -12
- data/lib/eth/abi.rb +27 -2
- data/lib/eth/address.rb +3 -1
- data/lib/eth/api.rb +1 -1
- data/lib/eth/chain.rb +6 -1
- data/lib/eth/client/http.rb +7 -3
- data/lib/eth/client/ipc.rb +1 -1
- data/lib/eth/client.rb +1 -1
- data/lib/eth/constant.rb +1 -1
- data/lib/eth/contract/event.rb +69 -16
- data/lib/eth/contract/function.rb +1 -1
- data/lib/eth/contract/function_input.rb +1 -1
- data/lib/eth/contract/function_output.rb +1 -1
- data/lib/eth/contract/initializer.rb +1 -1
- data/lib/eth/contract.rb +1 -1
- data/lib/eth/eip712.rb +3 -2
- data/lib/eth/ens/coin_type.rb +1 -1
- data/lib/eth/ens/resolver.rb +1 -1
- data/lib/eth/ens.rb +1 -1
- data/lib/eth/key/decrypter.rb +1 -1
- data/lib/eth/key/encrypter.rb +1 -1
- data/lib/eth/key.rb +1 -1
- data/lib/eth/rlp/decoder.rb +1 -1
- data/lib/eth/rlp/encoder.rb +1 -1
- data/lib/eth/rlp/sedes/big_endian_int.rb +1 -1
- data/lib/eth/rlp/sedes/binary.rb +1 -1
- data/lib/eth/rlp/sedes/list.rb +1 -1
- data/lib/eth/rlp/sedes.rb +1 -1
- data/lib/eth/rlp.rb +1 -1
- data/lib/eth/signature.rb +1 -1
- data/lib/eth/solidity.rb +1 -1
- data/lib/eth/tx/eip1559.rb +1 -1
- data/lib/eth/tx/eip2930.rb +1 -1
- data/lib/eth/tx/eip7702.rb +495 -0
- data/lib/eth/tx/legacy.rb +1 -1
- data/lib/eth/tx.rb +50 -1
- data/lib/eth/unit.rb +1 -1
- data/lib/eth/util.rb +1 -1
- data/lib/eth/version.rb +2 -2
- data/lib/eth.rb +1 -1
- metadata +19 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c5f56a3acb3981d3087e8125660e5670b8ba8bf6a5255e2742e439498327cd82
|
4
|
+
data.tar.gz: c54057d9b851ad567e846e390949927afe1986387eaba95fc8facb0aa3fef20d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee0dacd29dde60d8368c382a8d0fdf444895a66f2795689961112f34e752fced4a350e26b255d5bc4b1872e7c423c5780cc35487bd2b349f984ac0f75facbfd8
|
7
|
+
data.tar.gz: ca7fbe6c973aceb5dcc56031dbfa03903392ba9ad2ff0aa90d29c4c6311cc899961954e606c9c400df523305815eb89b26bc1fed2c0d65fcb042b59f0b63064f
|
data/.github/workflows/docs.yml
CHANGED
@@ -13,14 +13,14 @@ jobs:
|
|
13
13
|
- uses: actions/checkout@v4
|
14
14
|
- uses: ruby/setup-ruby@v1
|
15
15
|
with:
|
16
|
-
ruby-version: '3.
|
16
|
+
ruby-version: '3.4'
|
17
17
|
bundler-cache: true
|
18
18
|
- name: Run Yard Doc
|
19
19
|
run: |
|
20
20
|
gem install yard
|
21
21
|
yard doc
|
22
22
|
- name: Deploy GH Pages
|
23
|
-
uses: JamesIves/github-pages-deploy-action@v4.7.
|
23
|
+
uses: JamesIves/github-pages-deploy-action@v4.7.3
|
24
24
|
with:
|
25
25
|
branch: gh-pages
|
26
26
|
folder: doc/
|
data/.github/workflows/spec.yml
CHANGED
@@ -19,7 +19,7 @@ jobs:
|
|
19
19
|
fail-fast: false
|
20
20
|
matrix:
|
21
21
|
os: [ubuntu-latest, macos-latest]
|
22
|
-
ruby: ['3.
|
22
|
+
ruby: ['3.3', '3.4']
|
23
23
|
steps:
|
24
24
|
- uses: actions/checkout@v4
|
25
25
|
- uses: ruby/setup-ruby@v1
|
@@ -48,8 +48,6 @@ jobs:
|
|
48
48
|
- name: Run Tests
|
49
49
|
run: |
|
50
50
|
bundle exec rspec
|
51
|
-
env:
|
52
|
-
INFURA_TOKEN: ${{ secrets.INFURA_TOKEN }}
|
53
51
|
- name: Upload coverage to Codecov
|
54
52
|
uses: codecov/codecov-action@v5
|
55
53
|
with:
|
data/LICENSE.txt
CHANGED
@@ -187,7 +187,7 @@
|
|
187
187
|
same "printed page" as the copyright notice for easier
|
188
188
|
identification within third-party archives.
|
189
189
|
|
190
|
-
Copyright (c) 2016-
|
190
|
+
Copyright (c) 2016-2025 The Ruby-Eth Contributors
|
191
191
|
|
192
192
|
Licensed under the Apache License, Version 2.0 (the "License");
|
193
193
|
you may not use this file except in compliance with the License.
|
data/README.md
CHANGED
@@ -80,8 +80,6 @@ The test suite expects working local HTTP and IPC endpoints with a prefunded dev
|
|
80
80
|
geth --dev --http --ipcpath /tmp/geth.ipc &
|
81
81
|
```
|
82
82
|
|
83
|
-
It also expects an `$INFURA_TOKEN` in environment to test some ENS queries on mainnet.
|
84
|
-
|
85
83
|
To run tests, simply use `rspec`. Note, that the Ethereum test fixtures are also required.
|
86
84
|
|
87
85
|
```shell
|
@@ -95,7 +93,7 @@ The goal is to have 100% specification coverage for all code inside this gem.
|
|
95
93
|
## Contributing
|
96
94
|
Pull requests are welcome! To contribute, please consider the following:
|
97
95
|
* Code should be fully documented. Run `yard doc` and make sure it does not yield any warnings or undocumented sets.
|
98
|
-
* Code should be fully covered by tests. Run `rspec` to make sure all tests pass. The CI has an integration that will
|
96
|
+
* Code should be fully covered by tests. Run `rspec` to make sure all tests pass. The CI has an integration that will assist you to identify uncovered lines of code and get coverage up to 100%.
|
99
97
|
* Code should be formatted properly. Try to eliminate the most common issues such as trailing white-spaces or duplicate new-lines. Usage of the `rufo` gem is recommended.
|
100
98
|
* Submit pull requests, questions, or issues to Github: <https://github.com/q9f/eth.rb>
|
101
99
|
|
data/eth.gemspec
CHANGED
@@ -34,6 +34,9 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.platform = Gem::Platform::RUBY
|
35
35
|
spec.required_ruby_version = ">= 3.0", "< 4.0"
|
36
36
|
|
37
|
+
# bigdecimal for big decimals ;)
|
38
|
+
spec.add_dependency "bigdecimal", "~> 3.1"
|
39
|
+
|
37
40
|
# forwardable for contracts meta programming
|
38
41
|
spec.add_dependency "forwardable", "~> 1.3"
|
39
42
|
|
data/lib/eth/abi/decoder.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2016-
|
1
|
+
# Copyright (c) 2016-2025 The Ruby-Eth Contributors
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -102,7 +102,7 @@ module Eth
|
|
102
102
|
when "address"
|
103
103
|
|
104
104
|
# decoded address with 0x-prefix
|
105
|
-
|
105
|
+
Address.new(Util.bin_to_hex data[12..-1]).to_s.downcase
|
106
106
|
when "string", "bytes"
|
107
107
|
if type.sub_type.empty?
|
108
108
|
size = Util.deserialize_big_endian_to_int data[0, 32]
|
data/lib/eth/abi/encoder.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2016-
|
1
|
+
# Copyright (c) 2016-2025 The Ruby-Eth Contributors
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -49,7 +49,6 @@ module Eth
|
|
49
49
|
head, tail = "", ""
|
50
50
|
head += type(Type.size_type, arg.size)
|
51
51
|
nested_sub = type.nested_sub
|
52
|
-
nested_sub_size = type.nested_sub.size
|
53
52
|
|
54
53
|
# calculate offsets
|
55
54
|
if %w(string bytes).include?(type.base_type) && type.sub_type.empty?
|
@@ -93,15 +92,15 @@ module Eth
|
|
93
92
|
# @return [String] the encoded primitive type.
|
94
93
|
# @raise [EncodingError] if value does not match type.
|
95
94
|
# @raise [ValueOutOfBounds] if value is out of bounds for type.
|
96
|
-
# @raise [
|
95
|
+
# @raise [ArgumentError] if encoding fails for type.
|
97
96
|
def primitive_type(type, arg)
|
98
97
|
case type.base_type
|
99
98
|
when "uint"
|
100
99
|
uint arg, type
|
101
|
-
when "bool"
|
102
|
-
bool arg
|
103
100
|
when "int"
|
104
101
|
int arg, type
|
102
|
+
when "bool"
|
103
|
+
bool arg
|
105
104
|
when "ureal", "ufixed"
|
106
105
|
ufixed arg, type
|
107
106
|
when "real", "fixed"
|
data/lib/eth/abi/event.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2016-
|
1
|
+
# Copyright (c) 2016-2025 The Ruby-Eth Contributors
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -44,6 +44,10 @@ module Eth
|
|
44
44
|
"#{name}(#{types.join(",")})"
|
45
45
|
end
|
46
46
|
|
47
|
+
# Gets the input type for events.
|
48
|
+
#
|
49
|
+
# @param input [Hash] events input.
|
50
|
+
# @return [String] input type.
|
47
51
|
def type(input)
|
48
52
|
if input["type"] == "tuple"
|
49
53
|
"(#{input["components"].map { |c| type(c) }.join(",")})"
|
@@ -0,0 +1,196 @@
|
|
1
|
+
# Copyright (c) 2016-2025 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
|
+
# -*- encoding : ascii-8bit -*-
|
16
|
+
|
17
|
+
# Provides the {Eth} module.
|
18
|
+
module Eth
|
19
|
+
|
20
|
+
# Provides a Ruby implementation of the Ethereum Application Binary Interface (ABI).
|
21
|
+
module Abi
|
22
|
+
|
23
|
+
# Encapsulates the module for non-standard packed encoding used in Solidity.
|
24
|
+
module Packed
|
25
|
+
|
26
|
+
# Provides a utility module to assist encoding ABIs.
|
27
|
+
module Encoder
|
28
|
+
extend self
|
29
|
+
|
30
|
+
# Encodes a specific value, either static or dynamic in non-standard
|
31
|
+
# packed encoding mode.
|
32
|
+
#
|
33
|
+
# @param type [Eth::Abi::Type] type to be encoded.
|
34
|
+
# @param arg [String|Number] value to be encoded.
|
35
|
+
# @return [String] the packed encoded type.
|
36
|
+
# @raise [EncodingError] if value does not match type.
|
37
|
+
# @raise [ArgumentError] if encoding fails for type.
|
38
|
+
def type(type, arg)
|
39
|
+
case type
|
40
|
+
when /^uint(\d+)$/
|
41
|
+
uint(arg, $1.to_i / 8)
|
42
|
+
when /^int(\d+)$/
|
43
|
+
int(arg, $1.to_i / 8)
|
44
|
+
when "bool"
|
45
|
+
bool(arg)
|
46
|
+
when /^ureal(\d+)x(\d+)$/, /^ufixed(\d+)x(\d+)$/
|
47
|
+
ufixed(arg, $1.to_i / 8, $2.to_i)
|
48
|
+
when /^real(\d+)x(\d+)$/, /^fixed(\d+)x(\d+)$/
|
49
|
+
fixed(arg, $1.to_i / 8, $2.to_i)
|
50
|
+
when "string"
|
51
|
+
string(arg)
|
52
|
+
when /^bytes(\d+)$/
|
53
|
+
bytes(arg, $1.to_i)
|
54
|
+
when "bytes"
|
55
|
+
string(arg)
|
56
|
+
when /^tuple\((.+)\)$/
|
57
|
+
tuple($1.split(","), arg)
|
58
|
+
when /^hash(\d+)$/
|
59
|
+
hash(arg, $1.to_i / 8)
|
60
|
+
when "address"
|
61
|
+
address(arg)
|
62
|
+
when /^(.+)\[\]$/
|
63
|
+
array($1, arg)
|
64
|
+
when /^(.+)\[(\d+)\]$/
|
65
|
+
fixed_array($1, arg, $2.to_i)
|
66
|
+
else
|
67
|
+
raise EncodingError, "Unhandled type: #{type}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
# Properly encodes signed integers.
|
74
|
+
def uint(value, byte_size)
|
75
|
+
raise ArgumentError, "Don't know how to handle this input." unless value.is_a? Numeric
|
76
|
+
raise ValueOutOfBounds, "Number out of range: #{value}" if value > Constant::UINT_MAX or value < Constant::UINT_MIN
|
77
|
+
i = value.to_i
|
78
|
+
Util.zpad_int i, byte_size
|
79
|
+
end
|
80
|
+
|
81
|
+
# Properly encodes signed integers.
|
82
|
+
def int(value, byte_size)
|
83
|
+
raise ArgumentError, "Don't know how to handle this input." unless value.is_a? Numeric
|
84
|
+
raise ValueOutOfBounds, "Number out of range: #{value}" if value > Constant::INT_MAX or value < Constant::INT_MIN
|
85
|
+
real_size = byte_size * 8
|
86
|
+
i = value.to_i % 2 ** real_size
|
87
|
+
Util.zpad_int i, byte_size
|
88
|
+
end
|
89
|
+
|
90
|
+
# Properly encodes booleans.
|
91
|
+
def bool(value)
|
92
|
+
raise EncodingError, "Argument is not bool: #{value}" unless value.instance_of? TrueClass or value.instance_of? FalseClass
|
93
|
+
(value ? "\x01" : "\x00").b
|
94
|
+
end
|
95
|
+
|
96
|
+
# Properly encodes unsigned fixed-point numbers.
|
97
|
+
def ufixed(value, byte_size, decimals)
|
98
|
+
raise ArgumentError, "Don't know how to handle this input." unless value.is_a? Numeric
|
99
|
+
raise ValueOutOfBounds, value unless value >= 0 and value < 2 ** decimals
|
100
|
+
scaled_value = (value * (10 ** decimals)).to_i
|
101
|
+
uint(scaled_value, byte_size)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Properly encodes signed fixed-point numbers.
|
105
|
+
def fixed(value, byte_size, decimals)
|
106
|
+
raise ArgumentError, "Don't know how to handle this input." unless value.is_a? Numeric
|
107
|
+
raise ValueOutOfBounds, value unless value >= -2 ** (decimals - 1) and value < 2 ** (decimals - 1)
|
108
|
+
scaled_value = (value * (10 ** decimals)).to_i
|
109
|
+
int(scaled_value, byte_size)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Properly encodes byte(-string)s.
|
113
|
+
def bytes(value, length)
|
114
|
+
raise EncodingError, "Expecting String: #{value}" unless value.instance_of? String
|
115
|
+
value = handle_hex_string value, length
|
116
|
+
raise ArgumentError, "Value must be a string of length #{length}" unless value.is_a?(String) && value.bytesize == length
|
117
|
+
value.b
|
118
|
+
end
|
119
|
+
|
120
|
+
# Properly encodes (byte-)strings.
|
121
|
+
def string(value)
|
122
|
+
raise ArgumentError, "Value must be a string" unless value.is_a?(String)
|
123
|
+
value.b
|
124
|
+
end
|
125
|
+
|
126
|
+
# Properly encodes tuples.
|
127
|
+
def tuple(types, values)
|
128
|
+
Abi.solidity_packed(types, values)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Properly encodes hash-strings.
|
132
|
+
def hash(value, byte_size)
|
133
|
+
raise EncodingError, "Argument too long: #{value}" unless byte_size > 0 and byte_size <= 32
|
134
|
+
hash_bytes = handle_hex_string value, byte_size
|
135
|
+
hash_bytes.b
|
136
|
+
end
|
137
|
+
|
138
|
+
# Properly encodes addresses.
|
139
|
+
def address(value)
|
140
|
+
if value.is_a? Address
|
141
|
+
|
142
|
+
# from checksummed address with 0x prefix
|
143
|
+
Util.zpad_hex value.to_s[2..-1], 20
|
144
|
+
elsif value.is_a? Integer
|
145
|
+
|
146
|
+
# address from integer
|
147
|
+
Util.zpad_int value, 20
|
148
|
+
elsif value.size == 20
|
149
|
+
|
150
|
+
# address from encoded address
|
151
|
+
Util.zpad value, 20
|
152
|
+
elsif value.size == 40
|
153
|
+
|
154
|
+
# address from hexadecimal address
|
155
|
+
Util.zpad_hex value, 20
|
156
|
+
elsif value.size == 42 and value[0, 2] == "0x"
|
157
|
+
|
158
|
+
# address from hexadecimal address with 0x prefix
|
159
|
+
Util.zpad_hex value[2..-1], 20
|
160
|
+
else
|
161
|
+
raise EncodingError, "Could not parse address: #{value}"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# Properly encodes dynamic-sized arrays.
|
166
|
+
def array(type, values)
|
167
|
+
values.map { |value| type(type, value) }.join.b
|
168
|
+
end
|
169
|
+
|
170
|
+
# Properly encodes fixed-size arrays.
|
171
|
+
def fixed_array(type, values, size)
|
172
|
+
raise ArgumentError, "Array size does not match" unless values.size == size
|
173
|
+
array(type, values)
|
174
|
+
end
|
175
|
+
|
176
|
+
# The ABI encoder needs to be able to determine between a hex `"123"`
|
177
|
+
# and a binary `"123"` string.
|
178
|
+
def handle_hex_string(val, len)
|
179
|
+
if Util.prefixed? val or
|
180
|
+
(len === val.size / 2 and Util.hex? val)
|
181
|
+
|
182
|
+
# There is no way telling whether a string is hex or binary with certainty
|
183
|
+
# in Ruby. Therefore, we assume a `0x` prefix to indicate a hex string.
|
184
|
+
# Additionally, if the string size is exactly the double of the expected
|
185
|
+
# binary size, we can assume a hex value.
|
186
|
+
Util.hex_to_bin val
|
187
|
+
else
|
188
|
+
|
189
|
+
# Everything else will be assumed binary or raw string.
|
190
|
+
val.b
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
data/lib/eth/abi/type.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2016-
|
1
|
+
# Copyright (c) 2016-2025 The Ruby-Eth Contributors
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -94,7 +94,7 @@ module Eth
|
|
94
94
|
@base_type = base_type
|
95
95
|
@sub_type = sub_type
|
96
96
|
@dimensions = dims.map { |x| x[1...-1].to_i }
|
97
|
-
@components = components.map { |component| Abi::Type.parse(component["type"], component.dig("components"), component.dig("name")) }
|
97
|
+
@components = components.map { |component| Abi::Type.parse(component["type"], component.dig("components"), component.dig("name")) } if components&.any?
|
98
98
|
@name = component_name
|
99
99
|
end
|
100
100
|
|
@@ -123,10 +123,10 @@ module Eth
|
|
123
123
|
if dimensions.empty?
|
124
124
|
if !(["string", "bytes", "tuple"].include?(base_type) and sub_type.empty?)
|
125
125
|
s = 32
|
126
|
-
elsif base_type == "tuple"
|
126
|
+
elsif base_type == "tuple" and components.none?(&:dynamic?)
|
127
127
|
s = components.sum(&:size)
|
128
128
|
end
|
129
|
-
elsif dimensions.last != 0
|
129
|
+
elsif dimensions.last != 0 and !nested_sub.dynamic?
|
130
130
|
s = dimensions.last * nested_sub.size
|
131
131
|
end
|
132
132
|
@size ||= s
|
@@ -153,7 +153,7 @@ module Eth
|
|
153
153
|
if base_type == "tuple"
|
154
154
|
"(" + components.map(&:to_s).join(",") + ")" + (dimensions.size > 0 ? dimensions.map { |x| "[#{x == 0 ? "" : x}]" }.join : "")
|
155
155
|
elsif dimensions.empty?
|
156
|
-
if %w[string bytes].include?(base_type)
|
156
|
+
if %w[string bytes].include?(base_type) and sub_type.empty?
|
157
157
|
base_type
|
158
158
|
else
|
159
159
|
"#{base_type}#{sub_type}"
|
@@ -175,7 +175,7 @@ module Eth
|
|
175
175
|
when "bytes"
|
176
176
|
|
177
177
|
# bytes can be no longer than 32 bytes
|
178
|
-
raise ParseError, "Maximum 32 bytes for fixed-length string or bytes" unless sub_type.empty?
|
178
|
+
raise ParseError, "Maximum 32 bytes for fixed-length string or bytes" unless sub_type.empty? or (sub_type.to_i <= 32 and sub_type.to_i > 0)
|
179
179
|
when "tuple"
|
180
180
|
|
181
181
|
# tuples can not have any suffix
|
@@ -187,16 +187,16 @@ module Eth
|
|
187
187
|
|
188
188
|
# integer size must be valid
|
189
189
|
size = sub_type.to_i
|
190
|
-
raise ParseError, "Integer size out of bounds" unless size >= 8
|
190
|
+
raise ParseError, "Integer size out of bounds" unless size >= 8 and size <= 256
|
191
191
|
raise ParseError, "Integer size must be multiple of 8" unless size % 8 == 0
|
192
192
|
when "ureal", "real", "fixed", "ufixed"
|
193
193
|
|
194
194
|
# floats must have valid dimensional suffix
|
195
|
-
raise ParseError, "Real type must have suffix of form <
|
196
|
-
|
197
|
-
total =
|
198
|
-
raise ParseError, "Real size out of bounds (max 32 bytes)" unless total >= 8
|
199
|
-
raise ParseError, "Real
|
195
|
+
raise ParseError, "Real type must have suffix of form <size>x<decimals>, e.g. 128x128" unless sub_type =~ /\A[0-9]+x[0-9]+\z/
|
196
|
+
size, decimals = sub_type.split("x").map(&:to_i)
|
197
|
+
total = size + decimals
|
198
|
+
raise ParseError, "Real size out of bounds (max 32 bytes)" unless total >= 8 and total <= 256
|
199
|
+
raise ParseError, "Real size must be multiples of 8" unless size % 8 == 0
|
200
200
|
when "hash"
|
201
201
|
|
202
202
|
# hashs must have numerical suffix
|
data/lib/eth/abi.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2016-
|
1
|
+
# Copyright (c) 2016-2025 The Ruby-Eth Contributors
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -38,8 +38,12 @@ module Eth
|
|
38
38
|
#
|
39
39
|
# @param types [Array] types to be ABI-encoded.
|
40
40
|
# @param args [Array] values to be ABI-encoded.
|
41
|
+
# @param packed [Bool] set true to return packed encoding (default: `false`).
|
41
42
|
# @return [String] the encoded ABI data.
|
42
|
-
def encode(types, args)
|
43
|
+
def encode(types, args, packed = false)
|
44
|
+
return solidity_packed(types, args) if packed
|
45
|
+
types = [types] unless types.instance_of? Array
|
46
|
+
args = [args] unless args.instance_of? Array
|
43
47
|
|
44
48
|
# parse all types
|
45
49
|
parsed_types = types.map { |t| Type === t ? t : Type.parse(t) }
|
@@ -64,6 +68,26 @@ module Eth
|
|
64
68
|
"#{head}#{tail}"
|
65
69
|
end
|
66
70
|
|
71
|
+
# Encodes Application Binary Interface (ABI) data in non-standard packed mode.
|
72
|
+
# It accepts multiple arguments and encodes using the head/tail mechanism.
|
73
|
+
#
|
74
|
+
# @param types [Array] types to be ABI-encoded.
|
75
|
+
# @param args [Array] values to be ABI-encoded.
|
76
|
+
# @return [String] the encoded packed ABI data.
|
77
|
+
# @raise [ArgumentError] if types and args are of different size.
|
78
|
+
def solidity_packed(types, args)
|
79
|
+
raise ArgumentError, "Types and values must be the same length" if types.length != args.length
|
80
|
+
|
81
|
+
# We do not use the type system for packed encoding but want to call the parser once
|
82
|
+
# to enforce the type validation.
|
83
|
+
_ = types.map { |t| Type === t ? t : Type.parse(t) }
|
84
|
+
|
85
|
+
packed = types.zip(args).map do |type, arg|
|
86
|
+
Abi::Packed::Encoder.type(type, arg)
|
87
|
+
end.join
|
88
|
+
packed.force_encoding(Encoding::ASCII_8BIT)
|
89
|
+
end
|
90
|
+
|
67
91
|
# Decodes Application Binary Interface (ABI) data. It accepts multiple
|
68
92
|
# arguments and decodes using the head/tail mechanism.
|
69
93
|
#
|
@@ -123,6 +147,7 @@ module Eth
|
|
123
147
|
end
|
124
148
|
end
|
125
149
|
|
150
|
+
require "eth/abi/packed/encoder"
|
126
151
|
require "eth/abi/decoder"
|
127
152
|
require "eth/abi/encoder"
|
128
153
|
require "eth/abi/event"
|
data/lib/eth/address.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2016-
|
1
|
+
# Copyright (c) 2016-2025 The Ruby-Eth Contributors
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -17,6 +17,8 @@ module Eth
|
|
17
17
|
|
18
18
|
# The {Eth::Address} class to handle checksummed Ethereum addresses.
|
19
19
|
class Address
|
20
|
+
|
21
|
+
# The literal zero address 0x0.
|
20
22
|
ZERO = "0x0000000000000000000000000000000000000000"
|
21
23
|
|
22
24
|
# Provides a special checksum error if EIP-55 is violated.
|
data/lib/eth/api.rb
CHANGED
data/lib/eth/chain.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2016-
|
1
|
+
# Copyright (c) 2016-2025 The Ruby-Eth Contributors
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -149,11 +149,16 @@ module Eth
|
|
149
149
|
# Chain ID for Arbitrum Goerli testnet.
|
150
150
|
GOERLI_ARBITRUM = 421613.freeze
|
151
151
|
|
152
|
+
# Chain ID for Hoodi testnet.
|
153
|
+
HOODI = 560048.freeze
|
154
|
+
|
152
155
|
# Chain ID for Sepolia testnet.
|
153
156
|
SEPOLIA = 11155111.freeze
|
154
157
|
|
155
158
|
# Chain ID for Holesovice testnet.
|
156
159
|
HOLESOVICE = 11166111.freeze
|
160
|
+
|
161
|
+
# Chain ID for Holesovice testnet.
|
157
162
|
HOLESKY = HOLESOVICE
|
158
163
|
|
159
164
|
# Chain ID for the geth private network preset.
|
data/lib/eth/client/http.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2016-
|
1
|
+
# Copyright (c) 2016-2025 The Ruby-Eth Contributors
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -49,9 +49,13 @@ module Eth
|
|
49
49
|
if !(uri.user.nil? && uri.password.nil?)
|
50
50
|
@user = uri.user
|
51
51
|
@password = uri.password
|
52
|
-
|
52
|
+
if uri.query
|
53
|
+
@uri = URI("#{uri.scheme}://#{uri.user}:#{uri.password}@#{@host}:#{@port}#{uri.path}?#{uri.query}")
|
54
|
+
else
|
55
|
+
@uri = URI("#{uri.scheme}://#{uri.user}:#{uri.password}@#{@host}:#{@port}#{uri.path}")
|
56
|
+
end
|
53
57
|
else
|
54
|
-
@uri =
|
58
|
+
@uri = uri
|
55
59
|
end
|
56
60
|
end
|
57
61
|
|
data/lib/eth/client/ipc.rb
CHANGED
data/lib/eth/client.rb
CHANGED
data/lib/eth/constant.rb
CHANGED