eth 0.4.16 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/codeql.yml +15 -5
  3. data/.github/workflows/docs.yml +26 -0
  4. data/.github/workflows/spec.yml +52 -0
  5. data/.gitignore +24 -24
  6. data/.gitmodules +3 -3
  7. data/.yardopts +1 -0
  8. data/AUTHORS.txt +21 -0
  9. data/CHANGELOG.md +65 -10
  10. data/Gemfile +13 -2
  11. data/LICENSE.txt +202 -22
  12. data/README.md +199 -74
  13. data/bin/console +4 -4
  14. data/bin/setup +5 -4
  15. data/eth.gemspec +34 -29
  16. data/lib/eth/abi/type.rb +178 -0
  17. data/lib/eth/abi.rb +396 -0
  18. data/lib/eth/address.rb +55 -11
  19. data/lib/eth/api.rb +223 -0
  20. data/lib/eth/chain.rb +151 -0
  21. data/lib/eth/client/http.rb +63 -0
  22. data/lib/eth/client/ipc.rb +47 -0
  23. data/lib/eth/client.rb +232 -0
  24. data/lib/eth/constant.rb +71 -0
  25. data/lib/eth/eip712.rb +184 -0
  26. data/lib/eth/key/decrypter.rb +121 -88
  27. data/lib/eth/key/encrypter.rb +178 -99
  28. data/lib/eth/key.rb +136 -48
  29. data/lib/eth/rlp/decoder.rb +109 -0
  30. data/lib/eth/rlp/encoder.rb +78 -0
  31. data/lib/eth/rlp/sedes/big_endian_int.rb +66 -0
  32. data/lib/eth/rlp/sedes/binary.rb +97 -0
  33. data/lib/eth/rlp/sedes/list.rb +84 -0
  34. data/lib/eth/rlp/sedes.rb +74 -0
  35. data/lib/eth/rlp.rb +63 -0
  36. data/lib/eth/signature.rb +163 -0
  37. data/lib/eth/tx/eip1559.rb +336 -0
  38. data/lib/eth/tx/eip2930.rb +328 -0
  39. data/lib/eth/tx/legacy.rb +296 -0
  40. data/lib/eth/tx.rb +273 -143
  41. data/lib/eth/unit.rb +49 -0
  42. data/lib/eth/util.rb +235 -0
  43. data/lib/eth/version.rb +18 -1
  44. data/lib/eth.rb +33 -67
  45. metadata +50 -85
  46. data/.github/workflows/build.yml +0 -26
  47. data/lib/eth/gas.rb +0 -9
  48. data/lib/eth/open_ssl.rb +0 -264
  49. data/lib/eth/secp256k1.rb +0 -7
  50. data/lib/eth/sedes.rb +0 -40
  51. data/lib/eth/utils.rb +0 -130
data/lib/eth/api.rb ADDED
@@ -0,0 +1,223 @@
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
+ # Provides the {Eth} module.
16
+ module Eth
17
+
18
+ # Provides the `Eth::Api` module grouping known RPC commands.
19
+ module Api
20
+
21
+ # Implements the available RPC-APIs provided by Geth version 1.10.15.
22
+ COMMANDS = [
23
+ "admin_addPeer",
24
+ "admin_addTrustedPeer",
25
+ "admin_clearHistory",
26
+ "admin_datadir",
27
+ "admin_exportChain",
28
+ "admin_getDatadir",
29
+ "admin_getNodeInfo",
30
+ "admin_getPeers",
31
+ "admin_importChain",
32
+ "admin_nodeInfo",
33
+ "admin_peers",
34
+ "admin_removePeer",
35
+ "admin_removeTrustedPeer",
36
+ "admin_sleep",
37
+ "admin_sleepBlocks",
38
+ "admin_startHTTP",
39
+ "admin_startRPC",
40
+ "admin_startWS",
41
+ "admin_stopHTTP",
42
+ "admin_stopRPC",
43
+ "admin_stopWS",
44
+ "clique_discard",
45
+ "clique_getProposals",
46
+ "clique_getSigner",
47
+ "clique_getSigners",
48
+ "clique_getSignersAtHash",
49
+ "clique_getSnapshot",
50
+ "clique_getSnapshotAtHash",
51
+ "clique_proposals",
52
+ "clique_propose",
53
+ "clique_status",
54
+ "debug_accountRange",
55
+ "debug_backtraceAt",
56
+ "debug_blockProfile",
57
+ "debug_chaindbCompact",
58
+ "debug_chaindbProperty",
59
+ "debug_cpuProfile",
60
+ "debug_dumpBlock",
61
+ "debug_freeOSMemory",
62
+ "debug_freezeClient",
63
+ "debug_gcStats",
64
+ "debug_getAccessibleState",
65
+ "debug_getBadBlocks",
66
+ "debug_getBlockRlp",
67
+ "debug_getHeaderRlp",
68
+ "debug_getModifiedAccountsByHash",
69
+ "debug_getModifiedAccountsByNumber",
70
+ "debug_goTrace",
71
+ "debug_intermediateRoots",
72
+ "debug_memStats",
73
+ "debug_mutexProfile",
74
+ "debug_preimage",
75
+ "debug_printBlock",
76
+ "debug_seedHash",
77
+ "debug_setBlockProfileRate",
78
+ "debug_setGCPercent",
79
+ "debug_setHead",
80
+ "debug_setMutexProfileFraction",
81
+ "debug_stacks",
82
+ "debug_standardTraceBadBlockToFile",
83
+ "debug_standardTraceBlockToFile",
84
+ "debug_startCPUProfile",
85
+ "debug_startGoTrace",
86
+ "debug_stopCPUProfile",
87
+ "debug_stopGoTrace",
88
+ "debug_storageRangeAt",
89
+ "debug_testSignCliqueBlock",
90
+ "debug_traceBadBlock",
91
+ "debug_traceBlock",
92
+ "debug_traceBlockByHash",
93
+ "debug_traceBlockByNumber",
94
+ "debug_traceBlockFromFile",
95
+ "debug_traceCall",
96
+ "debug_traceTransaction",
97
+ "debug_verbosity",
98
+ "debug_vmodule",
99
+ "debug_writeBlockProfile",
100
+ "debug_writeMemProfile",
101
+ "debug_writeMutexProfile",
102
+ "eth_accounts",
103
+ "eth_blockNumber",
104
+ "eth_call",
105
+ "eth_chainId",
106
+ "eth_coinbase",
107
+ "eth_compile",
108
+ "eth_contract",
109
+ "eth_createAccessList",
110
+ "eth_defaultAccount",
111
+ "eth_defaultBlock",
112
+ "eth_estimateGas",
113
+ "eth_feeHistory",
114
+ "eth_fillTransaction",
115
+ "eth_filter",
116
+ "eth_gasPrice",
117
+ "eth_getAccounts",
118
+ "eth_getBalance",
119
+ "eth_getBlock",
120
+ "eth_getBlockByHash",
121
+ "eth_getBlockByNumber",
122
+ "eth_getBlockNumber",
123
+ "eth_getBlockTransactionCount",
124
+ "eth_getBlockTransactionCountByHash",
125
+ "eth_getBlockTransactionCountByNumber",
126
+ "eth_getBlockUncleCount",
127
+ "eth_getCode",
128
+ "eth_getCoinbase",
129
+ "eth_getCompilers",
130
+ "eth_getFilterChanges",
131
+ "eth_getFilterLogs",
132
+ "eth_getGasPrice",
133
+ "eth_getHashrate",
134
+ "eth_getHeaderByHash",
135
+ "eth_getHeaderByNumber",
136
+ "eth_getLogs",
137
+ "eth_getMaxPriorityFeePerGas",
138
+ "eth_getMining",
139
+ "eth_getPendingTransactions",
140
+ "eth_getProof",
141
+ "eth_getProtocolVersion",
142
+ "eth_getRawTransaction",
143
+ "eth_getRawTransactionFromBlock",
144
+ "eth_getStorageAt",
145
+ "eth_getSyncing",
146
+ "eth_getTransaction",
147
+ "eth_getTransactionByBlockHashAndIndex",
148
+ "eth_getTransactionByBlockNumberAndIndex",
149
+ "eth_getTransactionByHash",
150
+ "eth_getTransactionCount",
151
+ "eth_getTransactionFromBlock",
152
+ "eth_getTransactionReceipt",
153
+ "eth_getUncle",
154
+ "eth_getUncleCountByBlockHash",
155
+ "eth_getUncleCountByBlockNumber",
156
+ "eth_getWork",
157
+ "eth_hashrate",
158
+ "eth_iban",
159
+ "eth_icapNamereg",
160
+ "eth_isSyncing",
161
+ "eth_maxPriorityFeePerGas",
162
+ "eth_mining",
163
+ "eth_namereg",
164
+ "eth_newBlockFilter",
165
+ "eth_newFilter",
166
+ "eth_newPendingTransactionFilter",
167
+ "eth_pendingTransactions",
168
+ "eth_protocolVersion",
169
+ "eth_resend",
170
+ "eth_sendIBANTransaction",
171
+ "eth_sendRawTransaction",
172
+ "eth_sendTransaction",
173
+ "eth_sign",
174
+ "eth_signTransaction",
175
+ "eth_submitHashrate",
176
+ "eth_submitTransaction",
177
+ "eth_submitWork",
178
+ "eth_subscribe",
179
+ "eth_syncing",
180
+ "eth_uninstallFilter",
181
+ "eth_unsubscribe",
182
+ "les_addBalance",
183
+ "les_clientInfo",
184
+ "les_getCheckpoint",
185
+ "les_getCheckpointContractAddress",
186
+ "les_latestCheckpoint",
187
+ "les_priorityClientInfo",
188
+ "les_serverInfo",
189
+ "les_setClientParams",
190
+ "les_setDefaultParams",
191
+ "miner_getHashrate",
192
+ "miner_setEtherbase",
193
+ "miner_setExtra",
194
+ "miner_setGasLimit",
195
+ "miner_setGasPrice",
196
+ "miner_start",
197
+ "miner_stop",
198
+ "personal_deriveAccount",
199
+ "personal_ecRecover",
200
+ "personal_getListAccounts",
201
+ "personal_getListWallets",
202
+ "personal_importRawKey",
203
+ "personal_initializeWallet",
204
+ "personal_listAccounts",
205
+ "personal_listWallets",
206
+ "personal_lockAccount",
207
+ "personal_newAccount",
208
+ "personal_openWallet",
209
+ "personal_sendTransaction",
210
+ "personal_sign",
211
+ "personal_signTransaction",
212
+ "personal_unlockAccount",
213
+ "personal_unpair",
214
+ "txpool_content",
215
+ "txpool_contentFrom",
216
+ "txpool_getContent",
217
+ "txpool_getInspect",
218
+ "txpool_getStatus",
219
+ "txpool_inspect",
220
+ "txpool_status",
221
+ ]
222
+ end
223
+ end
data/lib/eth/chain.rb ADDED
@@ -0,0 +1,151 @@
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
+ # Provides the {Eth} module.
16
+ module Eth
17
+
18
+ # Encapsulates {Eth::Chain} IDs and utilities for EIP-155 compatibility.
19
+ # Ref: https://eips.ethereum.org/EIPS/eip-155
20
+ module Chain
21
+ extend self
22
+
23
+ # Provides a special replay protection error if EIP-155 is violated.
24
+ class ReplayProtectionError < StandardError; end
25
+
26
+ # Chain ID for Ethereum mainnet.
27
+ ETHEREUM = 1.freeze
28
+
29
+ # Chain ID for Expanse mainnet.
30
+ EXPANSE = 2.freeze
31
+
32
+ # Chain ID for Optimistic Ethereum mainnet.
33
+ OPTIMISM = 10.freeze
34
+
35
+ # Chain ID for Ethereum Classic mainnet.
36
+ CLASSIC = 61.freeze
37
+
38
+ # Chain ID for POA Network mainnet.
39
+ POA_NET = 99.freeze
40
+
41
+ # Chain ID for Gnosis mainnet.
42
+ XDAI = 100.freeze
43
+
44
+ # Chain ID for Arbitrum mainnet.
45
+ ARBITRUM = 42161.freeze
46
+
47
+ # Chain ID for Morden (Ethereum) testnet.
48
+ MORDEN = 2.freeze
49
+
50
+ # Chain ID for Ropsten testnet.
51
+ ROPSTEN = 3.freeze
52
+
53
+ # Chain ID for Rinkeby testnet.
54
+ RINKEBY = 4.freeze
55
+
56
+ # Chain ID for Goerli testnet.
57
+ GOERLI = 5.freeze
58
+
59
+ # Chain ID for Kotti testnet.
60
+ KOTTI = 6.freeze
61
+
62
+ # Chain ID for Kovan testnet.
63
+ KOVAN = 42.freeze
64
+
65
+ # Chain ID for Morden (Classic) testnet.
66
+ MORDEN_CLASSIC = 62.freeze
67
+
68
+ # Chain ID for Mordor testnet.
69
+ MORDOR = 63.freeze
70
+
71
+ # Chain ID for Optimistik Kovan testnet.
72
+ KOVAN_OPTIMISM = 69.freeze
73
+
74
+ # Chain ID for Arbitrum xDAI testnet.
75
+ XDAI_ARBITRUM = 200.freeze
76
+
77
+ # Chain ID for Optimistic Goerli testnet.
78
+ GOERLI_OPTIMISM = 420.freeze
79
+
80
+ # Chain ID for Arbitrum Rinkeby testnet.
81
+ RINKEBY_ARBITRUM = 421611.freeze
82
+
83
+ # Chain ID for Sepolia testnet.
84
+ SEPOLIA = 11155111.freeze
85
+
86
+ # Chain ID for the geth private network preset.
87
+ PRIVATE_GETH = 1337.freeze
88
+
89
+ # Indicates wether the given `v` indicates a legacy chain value
90
+ # without EIP-155 replay protection.
91
+ #
92
+ # @param v [Integer] the signature's `v` value.
93
+ # @return [Boolean] true if legacy value.
94
+ def is_legacy?(v)
95
+ [27, 28].include? v
96
+ end
97
+
98
+ # Convert a given `v` value to an ECDSA recovery id for the given
99
+ # EIP-155 chain ID.
100
+ #
101
+ # @param v [Integer] the signature's `v` value.
102
+ # @param chain_id [Integer] the chain id the signature was generated on.
103
+ # @return [Integer] the recovery id corresponding to `v`.
104
+ # @raise [ReplayProtectionError] if the given `v` is invalid.
105
+ def to_recovery_id(v, chain_id = ETHEREUM)
106
+ e = 0 + 2 * chain_id + 35
107
+ i = 1 + 2 * chain_id + 35
108
+ if [0, 1].include? v
109
+
110
+ # some wallets are using a `v` of 0 or 1 (ledger)
111
+ return v
112
+ elsif is_legacy? v
113
+
114
+ # this is the pre-EIP-155 legacy case
115
+ return v - 27
116
+ elsif [e, i].include? v
117
+
118
+ # this is the EIP-155 case
119
+ return v - 35 - 2 * chain_id
120
+ else
121
+ raise ReplayProtectionError, "Invalid v #{v} value for chain ID #{chain_id}. Invalid chain ID?"
122
+ end
123
+ end
124
+
125
+ # Converts a recovery ID into the expected `v` on a given chain.
126
+ #
127
+ # @param recovery_id [Integer] signature recovery id.
128
+ # @param chain_id [Integer] the chain id the signature was generated on.
129
+ # @return [Integer] the signature's `v` value.
130
+ def to_v(recovery_id, chain_id = nil)
131
+ if chain_id.nil? or chain_id < 1
132
+ v = 27 + recovery_id
133
+ else
134
+ v = 2 * chain_id + 35 + recovery_id
135
+ end
136
+ return v
137
+ end
138
+
139
+ # Converst a `v` value into a chain ID. This does not work for legacy signatures
140
+ # with `v < 36` that do not conform with EIP-155.
141
+ #
142
+ # @param v [Integer] the signature's `v` value.
143
+ # @return [Integer] the chain id as per EIP-155 or `nil` if there is no replay protection.
144
+ def to_chain_id(v)
145
+ return nil if v < 36
146
+ chain_id = (v - 35) / 2
147
+ return nil if chain_id < 1
148
+ return chain_id
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,63 @@
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 "net/http"
16
+
17
+ # Provides the {Eth} module.
18
+ module Eth
19
+
20
+ # Provides an HTTP/S-RPC client.
21
+ class Client::Http < Client
22
+
23
+ # The host of the HTTP endpoint.
24
+ attr_reader :host
25
+
26
+ # The port of the HTTP endpoint.
27
+ attr_reader :port
28
+
29
+ # The full URI of the HTTP endpoint, including path.
30
+ attr_reader :uri
31
+
32
+ # Attribute indicator for SSL.
33
+ attr_reader :ssl
34
+
35
+ # Constructor for the HTTP Client. Should not be used; use
36
+ # {Client.create} intead.
37
+ #
38
+ # @param host [String] an URI pointing to an HTTP RPC-API.
39
+ def initialize(host)
40
+ super
41
+ uri = URI.parse(host)
42
+ raise ArgumentError, "Unable to parse the HTTP-URI!" unless ["http", "https"].include? uri.scheme
43
+ @host = uri.host
44
+ @port = uri.port
45
+ @ssl = uri.scheme == "https"
46
+ @uri = URI("#{uri.scheme}://#{@host}:#{@port}#{uri.path}")
47
+ end
48
+
49
+ # Sends an RPC request to the connected HTTP client.
50
+ #
51
+ # @param payload [Hash] the RPC request parameters.
52
+ # @return [String] a JSON-encoded response.
53
+ def send(payload)
54
+ http = Net::HTTP.new(@host, @port)
55
+ http.use_ssl = @ssl
56
+ header = { "Content-Type" => "application/json" }
57
+ request = Net::HTTP::Post.new(@uri, header)
58
+ request.body = payload
59
+ response = http.request(request)
60
+ response.body
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,47 @@
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 "socket"
16
+
17
+ # Provides the {Eth} module.
18
+ module Eth
19
+
20
+ # Provides an IPC-RPC client.
21
+ class Client::Ipc < Client
22
+
23
+ # The path of the IPC socket.
24
+ attr_accessor :path
25
+
26
+ # Constructor for the IPC Client. Should not be used; use
27
+ # {Client.create} intead.
28
+ #
29
+ # @param path [String] an URI pointing to an IPC RPC-API.
30
+ def initialize(path)
31
+ super
32
+ @path = path
33
+ end
34
+
35
+ # Sends an RPC request to the connected IPC socket.
36
+ #
37
+ # @param payload [Hash] the RPC request parameters.
38
+ # @return [String] a JSON-encoded response.
39
+ def send(payload)
40
+ socket = UNIXSocket.new(@path)
41
+ socket.puts(payload)
42
+ read = socket.recvmsg(nil)[0]
43
+ socket.close
44
+ return read
45
+ end
46
+ end
47
+ end