eth 0.5.16 → 0.5.18
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 +4 -4
- data/.github/workflows/docs.yml +2 -2
- data/.github/workflows/spec.yml +9 -4
- data/CHANGELOG.md +45 -0
- data/Gemfile +3 -1
- data/README.md +1 -1
- data/eth.gemspec +3 -2
- data/lib/eth/client/http.rb +11 -0
- data/lib/eth/client/ipc.rb +2 -1
- data/lib/eth/client/ws.rb +7 -2
- data/lib/eth/client.rb +26 -4
- data/lib/eth/contract.rb +20 -0
- data/lib/eth/tx/eip7702.rb +45 -21
- data/lib/eth/version.rb +1 -1
- metadata +11 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 760b6de4102268368fd7ef4f0f4f567192b0ddc52353f67ea6e7d5ca95fcba66
|
|
4
|
+
data.tar.gz: 614de2331a7cd3dfd45d036574a2bebef57d14c6f07070edd11ffc95be381b4d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b21c15db4d30b89d829bd8025805171d53485d3c98fc0d72bfaf0b5d2f88b758f542658c78191e3b7f80c9c796a16cf3808dd41c6418862baa1c51694b0ee743
|
|
7
|
+
data.tar.gz: 7bedd93e3e673e8c5710ed4ede25428d30ed5c96cdee707f56a7b3462e45b1ed47fa6e06d5f07f0bcb5619e839e385dfa761d66a53975b6e19e2d1321aec67a4
|
|
@@ -24,15 +24,15 @@ jobs:
|
|
|
24
24
|
- ruby
|
|
25
25
|
steps:
|
|
26
26
|
- name: "Checkout repository"
|
|
27
|
-
uses: actions/checkout@
|
|
27
|
+
uses: actions/checkout@v7
|
|
28
28
|
- name: "Initialize CodeQL"
|
|
29
|
-
uses: github/codeql-action/init@v4
|
|
29
|
+
uses: github/codeql-action/init@v4.38.2
|
|
30
30
|
with:
|
|
31
31
|
languages: "${{ matrix.language }}"
|
|
32
32
|
- name: Autobuild
|
|
33
|
-
uses: github/codeql-action/autobuild@v4
|
|
33
|
+
uses: github/codeql-action/autobuild@v4.38.2
|
|
34
34
|
- name: "Perform CodeQL Analysis"
|
|
35
|
-
uses: github/codeql-action/analyze@v4
|
|
35
|
+
uses: github/codeql-action/analyze@v4.38.2
|
|
36
36
|
- uses: ruby/setup-ruby@v1
|
|
37
37
|
with:
|
|
38
38
|
ruby-version: '3.4'
|
data/.github/workflows/docs.yml
CHANGED
|
@@ -10,7 +10,7 @@ jobs:
|
|
|
10
10
|
docs:
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
steps:
|
|
13
|
-
- uses: actions/checkout@
|
|
13
|
+
- uses: actions/checkout@v7
|
|
14
14
|
- uses: ruby/setup-ruby@v1
|
|
15
15
|
with:
|
|
16
16
|
ruby-version: '3.4'
|
|
@@ -20,7 +20,7 @@ jobs:
|
|
|
20
20
|
gem install yard
|
|
21
21
|
yard doc
|
|
22
22
|
- name: Deploy GH Pages
|
|
23
|
-
uses: JamesIves/github-pages-deploy-action@v4.
|
|
23
|
+
uses: JamesIves/github-pages-deploy-action@v4.9.0
|
|
24
24
|
with:
|
|
25
25
|
branch: gh-pages
|
|
26
26
|
folder: doc/
|
data/.github/workflows/spec.yml
CHANGED
|
@@ -19,9 +19,14 @@ jobs:
|
|
|
19
19
|
fail-fast: false
|
|
20
20
|
matrix:
|
|
21
21
|
os: [ubuntu-latest, macos-latest]
|
|
22
|
-
ruby: [
|
|
22
|
+
ruby: [
|
|
23
|
+
{ version: "3.4", bigdecimal: "~> 3.0" },
|
|
24
|
+
{ version: "4.0", bigdecimal: "~> 4.0" },
|
|
25
|
+
]
|
|
26
|
+
env:
|
|
27
|
+
BIGDECIMAL_VERSION: ${{ matrix.ruby.bigdecimal }}
|
|
23
28
|
steps:
|
|
24
|
-
- uses: actions/checkout@
|
|
29
|
+
- uses: actions/checkout@v7
|
|
25
30
|
- name: MacOs Dependencies
|
|
26
31
|
if: matrix.os == 'macos-latest'
|
|
27
32
|
run: |
|
|
@@ -36,7 +41,7 @@ jobs:
|
|
|
36
41
|
sudo apt-get install -y autoconf automake libtool pkg-config geth solc
|
|
37
42
|
- uses: ruby/setup-ruby@v1
|
|
38
43
|
with:
|
|
39
|
-
ruby-version: ${{ matrix.ruby }}
|
|
44
|
+
ruby-version: ${{ matrix.ruby.version }}
|
|
40
45
|
bundler-cache: true
|
|
41
46
|
- name: Run Geth
|
|
42
47
|
run: |
|
|
@@ -67,7 +72,7 @@ jobs:
|
|
|
67
72
|
tail -n 200 /tmp/geth.log
|
|
68
73
|
fi
|
|
69
74
|
- name: Upload coverage to Codecov
|
|
70
|
-
uses: codecov/codecov-action@
|
|
75
|
+
uses: codecov/codecov-action@v7
|
|
71
76
|
with:
|
|
72
77
|
fail_ci_if_error: true
|
|
73
78
|
token: ${{ secrets.CODECOV_TOKEN }}
|
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,51 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
|
3
3
|
|
|
4
|
+
## [0.5.18]
|
|
5
|
+
### Added
|
|
6
|
+
* Add support for BigDecimal 4.x [#402](https://github.com/q9f/eth.rb/pull/402)
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
* Docs: add SPEC, ACCEPTANCE, and per-domain spec contracts [#405](https://github.com/q9f/eth.rb/pull/405)
|
|
10
|
+
* Build(deps): bump codecov/codecov-action from 6 to 7 [#404](https://github.com/q9f/eth.rb/pull/404)
|
|
11
|
+
* Build(deps): bump actions/checkout from 6 to 7 [#403](https://github.com/q9f/eth.rb/pull/403)
|
|
12
|
+
* Build(deps): bump codecov/codecov-action from 5 to 6 [#400](https://github.com/q9f/eth.rb/pull/400)
|
|
13
|
+
* Build(deps): bump JamesIves/github-pages-deploy-action [#399](https://github.com/q9f/eth.rb/pull/399)
|
|
14
|
+
* Bump version to 0.5.18
|
|
15
|
+
|
|
16
|
+
## [0.5.17]
|
|
17
|
+
### Added
|
|
18
|
+
* Add JSONRPC error code to Client::RpcError [#392](https://github.com/q9f/eth.rb/pull/392)
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
* Update workflow Ruby versions and deploy action [#397](https://github.com/q9f/eth.rb/pull/397)
|
|
22
|
+
* Build(deps): bump JamesIves/github-pages-deploy-action [#395](https://github.com/q9f/eth.rb/pull/395)
|
|
23
|
+
* Build(deps): bump actions/checkout from 5 to 6 [#394](https://github.com/q9f/eth.rb/pull/394)
|
|
24
|
+
* Update README.md [#393](https://github.com/q9f/eth.rb/pull/393)
|
|
25
|
+
* Bump version to 0.5.17 [#398](https://github.com/q9f/eth.rb/pull/398)
|
|
26
|
+
|
|
27
|
+
## [0.5.16]
|
|
28
|
+
### Added
|
|
29
|
+
* Add WebSocket transport to client [#388](https://github.com/q9f/eth.rb/pull/388)
|
|
30
|
+
* Support tuple arrays in ABI coder [#387](https://github.com/q9f/eth.rb/pull/387)
|
|
31
|
+
* Add sign and public key helpers for BLS [#366](https://github.com/q9f/eth.rb/pull/366)
|
|
32
|
+
* Add tuple array ABI support [#369](https://github.com/q9f/eth.rb/pull/369)
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
* Build(deps): bump github/codeql-action from 3 to 4 [#390](https://github.com/q9f/eth.rb/pull/390)
|
|
36
|
+
* Client/ws: fix client origin headers for ws requests [#391](https://github.com/q9f/eth.rb/pull/391)
|
|
37
|
+
* Rename websocket client to Ws and expand websocket tests [#389](https://github.com/q9f/eth.rb/pull/389)
|
|
38
|
+
* Format EIP-4844 transaction constant [#386](https://github.com/q9f/eth.rb/pull/386)
|
|
39
|
+
* Fix ABI tuple handling for ethers test cases [#385](https://github.com/q9f/eth.rb/pull/385)
|
|
40
|
+
* Increase blob throughput limits [#363](https://github.com/q9f/eth.rb/pull/363)
|
|
41
|
+
* Feat: use httpx for http requests [#382](https://github.com/q9f/eth.rb/pull/382)
|
|
42
|
+
* Fix: transform hash keys to strings in encoder for component type compatibility [#378](https://github.com/q9f/eth.rb/pull/378)
|
|
43
|
+
* Fix: improve error handling for missing keys in component encoding [#376](https://github.com/q9f/eth.rb/pull/376)
|
|
44
|
+
* Build(deps): bump actions/checkout from 4 to 5 [#379](https://github.com/q9f/eth.rb/pull/379)
|
|
45
|
+
* Test: add abi decode case for prefixed hex data [#374](https://github.com/q9f/eth.rb/pull/374)
|
|
46
|
+
* Add tests for decoder static arrays and encoder helpers [#373](https://github.com/q9f/eth.rb/pull/373)
|
|
47
|
+
* Chore: bump version to 0.5.16 [#362](https://github.com/q9f/eth.rb/pull/362)
|
|
48
|
+
|
|
4
49
|
## [0.5.15]
|
|
5
50
|
### Added
|
|
6
51
|
* Implement EIP712 array encoding [#361](https://github.com/q9f/eth.rb/pull/361)
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
[](https://github.com/q9f/eth.rb/pulse)
|
|
15
15
|
[](https://q9f.github.io/eth.rb)
|
|
16
16
|
[](https://github.com/q9f/eth.rb/wiki)
|
|
17
|
-
[](LICENSE)
|
|
17
|
+
[](LICENSE.txt)
|
|
18
18
|
[](https://github.com/q9f/eth.rb/issues)
|
|
19
19
|
|
|
20
20
|
A straightforward library to build, sign, and broadcast Ethereum transactions. It allows the separation of key and node management. Sign transactions and handle keys anywhere you can run Ruby and broadcast transactions through any local or remote node. Sign messages and recover signatures for authentication.
|
data/eth.gemspec
CHANGED
|
@@ -22,6 +22,7 @@ Gem::Specification.new do |spec|
|
|
|
22
22
|
"changelog_uri" => "https://github.com/q9f/eth.rb/blob/main/CHANGELOG.md",
|
|
23
23
|
"documentation_uri" => "https://q9f.github.io/eth.rb/",
|
|
24
24
|
"github_repo" => "https://github.com/q9f/eth.rb",
|
|
25
|
+
"rubygems_mfa_required" => "true",
|
|
25
26
|
"source_code_uri" => "https://github.com/q9f/eth.rb",
|
|
26
27
|
}.freeze
|
|
27
28
|
|
|
@@ -32,10 +33,10 @@ Gem::Specification.new do |spec|
|
|
|
32
33
|
spec.test_files = spec.files.grep %r{^(test|spec|features)/}
|
|
33
34
|
|
|
34
35
|
spec.platform = Gem::Platform::RUBY
|
|
35
|
-
spec.required_ruby_version = ">= 3.0", "<
|
|
36
|
+
spec.required_ruby_version = ">= 3.0", "< 5.0"
|
|
36
37
|
|
|
37
38
|
# bigdecimal for big decimals ;)
|
|
38
|
-
spec.add_dependency "bigdecimal", "
|
|
39
|
+
spec.add_dependency "bigdecimal", ">= 3.1", "< 5.0"
|
|
39
40
|
|
|
40
41
|
# forwardable for contracts meta programming
|
|
41
42
|
spec.add_dependency "forwardable", "~> 1.3"
|
data/lib/eth/client/http.rb
CHANGED
|
@@ -69,6 +69,17 @@ module Eth
|
|
|
69
69
|
response = @client.post(@uri, body: payload)
|
|
70
70
|
response.body.to_s
|
|
71
71
|
end
|
|
72
|
+
|
|
73
|
+
# Closes the underlying HTTP session and releases all persistent
|
|
74
|
+
# connections held in its pool. Once closed, the client cannot be
|
|
75
|
+
# used anymore; any subsequent request raises an `IOError`. Safe to
|
|
76
|
+
# call multiple times.
|
|
77
|
+
#
|
|
78
|
+
# @return [void]
|
|
79
|
+
def close
|
|
80
|
+
@closed = true
|
|
81
|
+
@client.close
|
|
82
|
+
end
|
|
72
83
|
end
|
|
73
84
|
|
|
74
85
|
private
|
data/lib/eth/client/ipc.rb
CHANGED
data/lib/eth/client/ws.rb
CHANGED
|
@@ -76,11 +76,16 @@ module Eth
|
|
|
76
76
|
end
|
|
77
77
|
end
|
|
78
78
|
|
|
79
|
-
# Closes the underlying WebSocket connection.
|
|
79
|
+
# Closes the underlying WebSocket connection. Once closed, the
|
|
80
|
+
# client cannot be used anymore; any subsequent request raises an
|
|
81
|
+
# `IOError`. Safe to call multiple times.
|
|
80
82
|
#
|
|
81
83
|
# @return [void]
|
|
82
84
|
def close
|
|
83
|
-
@mutex.synchronize
|
|
85
|
+
@mutex.synchronize do
|
|
86
|
+
@closed = true
|
|
87
|
+
close_socket
|
|
88
|
+
end
|
|
84
89
|
end
|
|
85
90
|
|
|
86
91
|
private
|
data/lib/eth/client.rb
CHANGED
|
@@ -40,25 +40,28 @@ module Eth
|
|
|
40
40
|
# A custom error type if a contract interaction fails.
|
|
41
41
|
class ContractExecutionError < StandardError; end
|
|
42
42
|
|
|
43
|
-
# Raised when an RPC call returns an error. Carries the optional
|
|
43
|
+
# Raised when an RPC call returns an error. Carries the error code and the optional
|
|
44
44
|
# hex-encoded error data to support custom error decoding.
|
|
45
45
|
class RpcError < IOError
|
|
46
46
|
attr_reader :data
|
|
47
|
+
attr_reader :code
|
|
47
48
|
|
|
48
49
|
# Constructor for the {RpcError} class.
|
|
49
50
|
#
|
|
50
51
|
# @param message [String] the error message returned by the RPC.
|
|
51
52
|
# @param data [String] optional hex encoded error data.
|
|
52
|
-
|
|
53
|
+
# @param code [String] optional error code returned by the RPC.
|
|
54
|
+
def initialize(message, data = nil, code = nil)
|
|
53
55
|
super(message)
|
|
54
56
|
@data = data
|
|
57
|
+
@code = code
|
|
55
58
|
end
|
|
56
59
|
end
|
|
57
60
|
|
|
58
61
|
# Creates a new RPC-Client, either by providing an HTTP/S host, WS/S host,
|
|
59
62
|
# or an IPC path. Supports basic authentication with username and password.
|
|
60
63
|
#
|
|
61
|
-
# **Note**, this sets the
|
|
64
|
+
# **Note**, this sets the following gas defaults: {Tx::DEFAULT_PRIORITY_FEE}
|
|
62
65
|
# and {Tx::DEFAULT_GAS_PRICE. Use {#max_priority_fee_per_gas} and
|
|
63
66
|
# {#max_fee_per_gas} to set custom values prior to submitting transactions.
|
|
64
67
|
#
|
|
@@ -78,6 +81,7 @@ module Eth
|
|
|
78
81
|
# use {Client.create} intead.
|
|
79
82
|
def initialize(_)
|
|
80
83
|
@id = 0
|
|
84
|
+
@closed = false
|
|
81
85
|
@max_priority_fee_per_gas = Tx::DEFAULT_PRIORITY_FEE
|
|
82
86
|
@max_fee_per_gas = Tx::DEFAULT_GAS_PRICE
|
|
83
87
|
end
|
|
@@ -375,6 +379,23 @@ module Eth
|
|
|
375
379
|
@id = 0
|
|
376
380
|
end
|
|
377
381
|
|
|
382
|
+
# Closes the client and releases any resources held by the underlying
|
|
383
|
+
# connection, such as persistent HTTP connections or an open WebSocket
|
|
384
|
+
# stream. Once closed, the client cannot be used anymore; any
|
|
385
|
+
# subsequent request raises an `IOError`. Safe to call multiple times.
|
|
386
|
+
#
|
|
387
|
+
# @return [void]
|
|
388
|
+
def close
|
|
389
|
+
@closed = true
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
# Checks whether the client has been closed via {#close}.
|
|
393
|
+
#
|
|
394
|
+
# @return [Boolean] true if the client is closed.
|
|
395
|
+
def closed?
|
|
396
|
+
!!@closed
|
|
397
|
+
end
|
|
398
|
+
|
|
378
399
|
# Checks whether a transaction is mined or not.
|
|
379
400
|
#
|
|
380
401
|
# @param hash [String] the transaction hash.
|
|
@@ -473,6 +494,7 @@ module Eth
|
|
|
473
494
|
|
|
474
495
|
# Prepares parameters and sends the command to the client.
|
|
475
496
|
def send_command(command, args)
|
|
497
|
+
raise IOError, "The client is closed!" if closed?
|
|
476
498
|
@block_number ||= "latest"
|
|
477
499
|
args << block_number if ["eth_getBalance", "eth_call"].include? command
|
|
478
500
|
payload = {
|
|
@@ -483,7 +505,7 @@ module Eth
|
|
|
483
505
|
}
|
|
484
506
|
output = JSON.parse(send_request(payload.to_json))
|
|
485
507
|
if (err = output["error"])
|
|
486
|
-
raise RpcError.new(err["message"], err["data"])
|
|
508
|
+
raise RpcError.new(err["message"], err["data"], err["code"])
|
|
487
509
|
end
|
|
488
510
|
output
|
|
489
511
|
end
|
data/lib/eth/contract.rb
CHANGED
|
@@ -45,6 +45,10 @@ module Eth
|
|
|
45
45
|
@bin = bin
|
|
46
46
|
@abi = abi
|
|
47
47
|
@constructor_inputs, @functions, @events, @errors = parse_abi(abi)
|
|
48
|
+
@sigs2events = {}
|
|
49
|
+
@events.each do |event|
|
|
50
|
+
@sigs2events[event.signature] = event
|
|
51
|
+
end
|
|
48
52
|
end
|
|
49
53
|
|
|
50
54
|
# Creates a contract wrapper from a Solidity file.
|
|
@@ -168,6 +172,7 @@ module Eth
|
|
|
168
172
|
def_delegator :parent, :function
|
|
169
173
|
def_delegator :parent, :error
|
|
170
174
|
def_delegator :parent, :decode_error
|
|
175
|
+
def_delegator :parent, :decode_log
|
|
171
176
|
def_delegator :parent, :constructor_inputs
|
|
172
177
|
define_method :parent do
|
|
173
178
|
parent
|
|
@@ -178,6 +183,21 @@ module Eth
|
|
|
178
183
|
@class_object = class_methods
|
|
179
184
|
end
|
|
180
185
|
|
|
186
|
+
# Decodes an event log by looking up the event signature in the
|
|
187
|
+
# contract ABI.
|
|
188
|
+
#
|
|
189
|
+
# @param topics [Array<String>] the list of log topics, including the
|
|
190
|
+
# event selector.
|
|
191
|
+
# @param data [String] the log data containing non-indexed parameters.
|
|
192
|
+
# @return [Hash] a hash of decoded event parameters.
|
|
193
|
+
# @raise [ArgumentError] if the event is not part of the contract ABI.
|
|
194
|
+
def decode_log(topics, data)
|
|
195
|
+
sig = Eth::Util.remove_hex_prefix(topics[0])
|
|
196
|
+
event = @sigs2events[sig]
|
|
197
|
+
raise ArgumentError, "this event does not exist!" if event.nil?
|
|
198
|
+
event.decode_params(topics, data)
|
|
199
|
+
end
|
|
200
|
+
|
|
181
201
|
private
|
|
182
202
|
|
|
183
203
|
def parse_abi(abi)
|
data/lib/eth/tx/eip7702.rb
CHANGED
|
@@ -27,14 +27,21 @@ module Eth
|
|
|
27
27
|
# code which the signer desires to execute in the context of their EOA.
|
|
28
28
|
class Authorization
|
|
29
29
|
|
|
30
|
+
# The EIP-7702 magic byte, prefixed to the RLP-encoded authorization
|
|
31
|
+
# tuple before hashing so that authorization signatures cannot be
|
|
32
|
+
# replayed as transaction signatures.
|
|
33
|
+
# Ref: https://eips.ethereum.org/EIPS/eip-7702
|
|
34
|
+
MAGIC = 0x05.freeze
|
|
35
|
+
|
|
30
36
|
# The EIP-155 Chain ID.
|
|
31
37
|
# Ref: https://eips.ethereum.org/EIPS/eip-155
|
|
32
38
|
attr_reader :chain_id
|
|
33
39
|
|
|
34
|
-
# The authority
|
|
40
|
+
# The delegation target: the address whose code the authority's
|
|
41
|
+
# account runs. The authority itself is the signer.
|
|
35
42
|
attr_reader :address
|
|
36
43
|
|
|
37
|
-
# The
|
|
44
|
+
# The authority's account nonce this authorization is valid for.
|
|
38
45
|
attr_reader :nonce
|
|
39
46
|
|
|
40
47
|
# The signature's y-parity byte (not v).
|
|
@@ -52,8 +59,8 @@ module Eth
|
|
|
52
59
|
#
|
|
53
60
|
# @param fields [Hash] all necessary transaction fields.
|
|
54
61
|
# @option fields [Integer] :chain_id the chain ID.
|
|
55
|
-
# @option fields [Eth::Address] :address the
|
|
56
|
-
# @option fields [Integer] :nonce the
|
|
62
|
+
# @option fields [Eth::Address] :address the delegation target address.
|
|
63
|
+
# @option fields [Integer] :nonce the authority's account nonce.
|
|
57
64
|
def initialize(fields)
|
|
58
65
|
@chain_id = fields[:chain_id].to_i
|
|
59
66
|
@address = fields[:address].to_s
|
|
@@ -63,46 +70,63 @@ module Eth
|
|
|
63
70
|
@signature_s = fields[:s]
|
|
64
71
|
end
|
|
65
72
|
|
|
66
|
-
# Sign the authorization with a given key.
|
|
73
|
+
# Sign the authorization with a given key. The key's account becomes
|
|
74
|
+
# the authority, delegating to the code at {#address}; any key may
|
|
75
|
+
# sign for any delegation target.
|
|
76
|
+
#
|
|
77
|
+
# The signed authorization is valid on chain {#chain_id}, or on any
|
|
78
|
+
# chain if that is 0. Anyone holding it can submit it while the
|
|
79
|
+
# account's nonce equals {#nonce}; on each chain where it is included,
|
|
80
|
+
# the code at {#address} then acts as the account until the account
|
|
81
|
+
# delegates elsewhere. Sign only for code you trust.
|
|
67
82
|
#
|
|
68
83
|
# @param key [Eth::Key] the key-pair to use for signing.
|
|
69
|
-
# @return [String]
|
|
84
|
+
# @return [String] the hex-encoded hash that was signed, {#unsigned_hash}.
|
|
70
85
|
# @raise [Signature::SignatureError] if authorization is already signed.
|
|
71
|
-
# @raise [
|
|
86
|
+
# @raise [Address::CheckSumError] if {#address} is not a valid address.
|
|
72
87
|
def sign(key)
|
|
73
88
|
if Tx.signed? self
|
|
74
89
|
raise Signature::SignatureError, "Authorization is already signed!"
|
|
75
90
|
end
|
|
76
91
|
|
|
77
|
-
#
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
raise Signature::SignatureError, "Signer does not match sender" unless signer_address == from_address
|
|
82
|
-
end
|
|
92
|
+
# reject a delegation target that is not a valid address: malformed
|
|
93
|
+
# input yields a tuple clients reject, and an EIP-55 checksum
|
|
94
|
+
# mismatch most likely means a typo in the target
|
|
95
|
+
Address.new @address
|
|
83
96
|
|
|
84
|
-
# sign a keccak hash of the
|
|
85
|
-
|
|
97
|
+
# sign a keccak hash of the magic-prefixed, encoded authorization;
|
|
98
|
+
# the chain ID is part of that payload, so the signature carries no
|
|
99
|
+
# EIP-155 v and the y-parity is the raw recovery id
|
|
100
|
+
sign_hash = unsigned_hash
|
|
101
|
+
signature = key.sign(sign_hash)
|
|
86
102
|
r, s, v = Signature.dissect signature
|
|
87
|
-
recovery_id = Chain.to_recovery_id v.to_i(16)
|
|
103
|
+
recovery_id = Chain.to_recovery_id v.to_i(16)
|
|
88
104
|
@signature_y_parity = recovery_id
|
|
89
105
|
@signature_r = r
|
|
90
106
|
@signature_s = s
|
|
91
|
-
return
|
|
107
|
+
return Util.bin_to_hex sign_hash
|
|
92
108
|
end
|
|
93
109
|
|
|
94
|
-
# Encodes the unsigned authorization payload required for signing
|
|
110
|
+
# Encodes the unsigned authorization payload required for signing:
|
|
111
|
+
# the {MAGIC} byte followed by `rlp([chain_id, address, nonce])`.
|
|
95
112
|
#
|
|
96
|
-
# @return [String]
|
|
113
|
+
# @return [String] the magic-prefixed, RLP-encoded authorization tuple.
|
|
97
114
|
def unsigned_encoded
|
|
98
115
|
authorization_data = []
|
|
99
116
|
authorization_data.push Util.serialize_int_to_big_endian @chain_id
|
|
100
117
|
authorization_data.push Util.hex_to_bin @address
|
|
101
118
|
authorization_data.push Util.serialize_int_to_big_endian @nonce
|
|
102
|
-
Rlp.encode authorization_data
|
|
119
|
+
authorization_encoded = Rlp.encode authorization_data
|
|
120
|
+
|
|
121
|
+
# prefix the EIP-7702 magic byte to separate the signing domain
|
|
122
|
+
magic = Util.serialize_int_to_big_endian MAGIC
|
|
123
|
+
|
|
124
|
+
return "#{magic}#{authorization_encoded}"
|
|
103
125
|
end
|
|
104
126
|
|
|
105
|
-
# Gets the sign-hash required to sign
|
|
127
|
+
# Gets the sign-hash required to sign: the Keccak-256 hash of
|
|
128
|
+
# {#unsigned_encoded}, which an EIP-7702 client recovers the
|
|
129
|
+
# authority from.
|
|
106
130
|
#
|
|
107
131
|
# @return [String] a Keccak-256 hash.
|
|
108
132
|
def unsigned_hash
|
data/lib/eth/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: eth
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.18
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Steve Ellis
|
|
@@ -14,16 +14,22 @@ dependencies:
|
|
|
14
14
|
name: bigdecimal
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - "
|
|
17
|
+
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
19
|
version: '3.1'
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '5.0'
|
|
20
23
|
type: :runtime
|
|
21
24
|
prerelease: false
|
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
26
|
requirements:
|
|
24
|
-
- - "
|
|
27
|
+
- - ">="
|
|
25
28
|
- !ruby/object:Gem::Version
|
|
26
29
|
version: '3.1'
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '5.0'
|
|
27
33
|
- !ruby/object:Gem::Dependency
|
|
28
34
|
name: forwardable
|
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -238,6 +244,7 @@ metadata:
|
|
|
238
244
|
changelog_uri: https://github.com/q9f/eth.rb/blob/main/CHANGELOG.md
|
|
239
245
|
documentation_uri: https://q9f.github.io/eth.rb/
|
|
240
246
|
github_repo: https://github.com/q9f/eth.rb
|
|
247
|
+
rubygems_mfa_required: 'true'
|
|
241
248
|
source_code_uri: https://github.com/q9f/eth.rb
|
|
242
249
|
rdoc_options: []
|
|
243
250
|
require_paths:
|
|
@@ -250,7 +257,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
250
257
|
version: '3.0'
|
|
251
258
|
- - "<"
|
|
252
259
|
- !ruby/object:Gem::Version
|
|
253
|
-
version: '
|
|
260
|
+
version: '5.0'
|
|
254
261
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
255
262
|
requirements:
|
|
256
263
|
- - ">="
|