eth 0.5.1 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 90f2afdedcf09191090c54dbfa45438e5be7d0f94d5badc0b09e0d678d52f9bf
4
- data.tar.gz: 05de6ecc688e5d11a50324d8707e092c91d422c6f11f02a1479a4645bce95c6e
3
+ metadata.gz: af4a4068c445fcbb0ec94375ffdf650894464bf62d69dd7a14af232452c3af3c
4
+ data.tar.gz: a962fe008b6ecb75bdc5a70c9363aa31f95d84f82359da53e7195544bbcb9db2
5
5
  SHA512:
6
- metadata.gz: d2d2eea96edfca3d94d4d23b4eabcb70dbc0ea33fd735ba13929130882d48b973fd8f242caaa39e49a3384f45bba87b39eb86b77ce539c416394c37ce989df97
7
- data.tar.gz: 551c6cc113f279a91b900434ee446abf5fcd2d7ce1efb3cea294fc3531e250f9ef42068f22c57712f827bf756c95fde11ad7a481d53578f64d3631d7a5b2f795
6
+ metadata.gz: d909d4249f0f7a72cae28c0f4208e1aa8c8ba69779149a20ececf4a53cd6186b43062d7a9aa5921e3c3fee9f3e014df8e6dd01586c0651f714d9bca47a4953da
7
+ data.tar.gz: ad74d13143142ab3cf71cadfa79cbd1a7a9cf2628c0b5b6e279edd4385b20764b837e14b0f8f7f24d55884893a7b79b4c1323f89aca66adfa40eb6af8bd4db41
@@ -19,7 +19,7 @@ jobs:
19
19
  fail-fast: false
20
20
  matrix:
21
21
  os: [ubuntu-latest, macos-latest]
22
- ruby: ['2.7', '3.0']
22
+ ruby: ['2.7', '3.1']
23
23
  steps:
24
24
  - uses: actions/checkout@v2
25
25
  - uses: ruby/setup-ruby@v1
@@ -29,13 +29,13 @@ jobs:
29
29
  - name: MacOs Dependencies
30
30
  run: |
31
31
  brew tap ethereum/ethereum
32
- brew install --verbose pkg-config automake autogen ethereum
32
+ brew install --verbose pkg-config automake autogen ethereum solidity
33
33
  if: startsWith(matrix.os, 'macOS')
34
34
  - name: Ubuntu Dependencies
35
35
  run: |
36
36
  sudo add-apt-repository -y ppa:ethereum/ethereum
37
37
  sudo apt-get update
38
- sudo apt-get install ethereum
38
+ sudo apt-get install ethereum solc
39
39
  if: startsWith(matrix.os, 'Ubuntu')
40
40
  - name: Run Geth
41
41
  run: |
data/AUTHORS.txt CHANGED
@@ -2,6 +2,8 @@ The Ruby-Eth Contributors are:
2
2
  * Steve Ellis @se3000
3
3
  * Afri Schoedon @q9f
4
4
  * John Omar @chainoperator
5
+ * Joshua Peek @josh
6
+ * Yuta Kurotaki @kurotaky
5
7
 
6
8
  See also:
7
9
  * https://github.com/q9f/eth.rb/graphs/contributors
@@ -10,12 +12,18 @@ The Ruby-Eth project was maintained 2016-2020 in Steve Ellis's (@se3000)
10
12
  repository licensed under MIT conditions:
11
13
  * https://github.com/se3000/ruby-eth
12
14
 
13
- The latest version of the Ruby-Eth gem contains a revised version the
15
+ The latest Ruby-Eth gem is not only a rewrite of the aforementioned gem
16
+ but also a partial merge of the Ethereum.rb Ruby Ethereum library by
17
+ Marek Kirejczyk (@marekkirejczyk) and Yuta Kurotaki (@kurotaky) licensed
18
+ under MIT conditions:
19
+ * https://github.com/EthWorks/ethereum.rb
20
+
21
+ The latest version of the Ruby-Eth gem includes a revised version of the
14
22
  ABI gem by Jan Xie (@janx) and Zhang Yaning (@u2) licensed under MIT
15
23
  conditions:
16
24
  * https://github.com/cryptape/ruby-ethereum-abi
17
25
 
18
- The latest version of the Ruby-Eth gem contains a revised version the
26
+ The latest version of the Ruby-Eth gem contains a condensed version of the
19
27
  RLP gem by Jan Xie (@janx) and Zhang Yaning (@u2) licensed under MIT
20
28
  conditions:
21
29
  * https://github.com/cryptape/ruby-rlp
data/CHANGELOG.md CHANGED
@@ -1,20 +1,47 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [0.5.3]
5
+ ### Added
6
+ - Smart contract support ([#68](https://github.com/q9f/eth.rb/pull/68))
7
+
8
+ ### Changed
9
+ - Eth/abi: decode event log ([#69](https://github.com/q9f/eth.rb/pull/69))
10
+ - Gem: bump version ([#70](https://github.com/q9f/eth.rb/pull/70))
11
+ - Eth/abi/event: batch log decoder ([#71](https://github.com/q9f/eth.rb/pull/71))
12
+
13
+ ## [0.5.2]
14
+ ### Added
15
+ - Eth/solidity: add solidity compiler bindings ([#66](https://github.com/q9f/eth.rb/pull/66))
16
+
17
+ ### Changed
18
+ - Eth: remove duplicated code ([#62](https://github.com/q9f/eth.rb/pull/62))
19
+ - Ci: allow coverage to drop to 99% without failing ([#63](https://github.com/q9f/eth.rb/pull/63))
20
+ - Docs: update readme ([#64](https://github.com/q9f/eth.rb/pull/64))
21
+ - Docs: add wiki to readme ([#65](https://github.com/q9f/eth.rb/pull/65))
22
+
4
23
  ## [0.5.1]
24
+ ### Added
25
+ - Add eth::rlp module ([#52](https://github.com/q9f/eth.rb/pull/52))
26
+ - Eth/client: implement http/ipc ([#37](https://github.com/q9f/eth.rb/pull/37))
27
+
5
28
  ### Changed
6
29
  - Docs: update changelog ([#61](https://github.com/q9f/eth.rb/pull/61))
7
30
  - Eth/chain: add sepolia chain id; docs ([#60](https://github.com/q9f/eth.rb/pull/60))
8
31
  - Eth/rlp: cleanup ([#59](https://github.com/q9f/eth.rb/pull/59))
9
- - Add eth::rlp module ([#52](https://github.com/q9f/eth.rb/pull/52))
10
32
  - Eth/tx: properly serialize signatures ([#58](https://github.com/q9f/eth.rb/pull/58))
11
33
  - Eth/client: fix legacy transfer ([#57](https://github.com/q9f/eth.rb/pull/57))
12
34
  - Gem: relax openssl requirement ([#56](https://github.com/q9f/eth.rb/pull/56))
13
- - Eth/client: implement http/ipc ([#37](https://github.com/q9f/eth.rb/pull/37))
14
35
  - Docs: update changelog ([#53](https://github.com/q9f/eth.rb/pull/53))
15
36
  - Spec: add upstream test fixtures for keystore ([#50](https://github.com/q9f/eth.rb/pull/50))
16
37
 
17
38
  ## [0.5.0]
39
+ ### Added
40
+ - Eth/tx: create legacy, type-1, and type-2 transactions [#33](https://github.com/q9f/eth.rb/pull/33)
41
+ - Signature: implement eip 712 typed structured data signing [#27](https://github.com/q9f/eth.rb/pull/27)
42
+ - Lib: import ABI to eth/abi [#29](https://github.com/q9f/eth.rb/pull/29)
43
+ - Eth/chains: implement eip 155 for replay protection [#20](https://github.com/q9f/eth.rb/pull/20)
44
+
18
45
  ### Changed
19
46
  - Docs: update readme with features [#49](https://github.com/q9f/eth.rb/pull/49)
20
47
  - Eth/tx: add method to estimate intrinsic gas costs [#48](https://github.com/q9f/eth.rb/pull/48)
@@ -26,16 +53,12 @@ All notable changes to this project will be documented in this file.
26
53
  - Lib: improve error handling [#39](https://github.com/q9f/eth.rb/pull/39)
27
54
  - Docs: update readme for tx and keys [#40](https://github.com/q9f/eth.rb/pull/40)
28
55
  - Implement encrypt/decrypt [#22](https://github.com/q9f/eth.rb/pull/22)
29
- - Eth/tx: create legacy, type-1, and type-2 transactions [#33](https://github.com/q9f/eth.rb/pull/33)
30
56
  - Gem: clean up some docs and scripts [#32](https://github.com/q9f/eth.rb/pull/32)
31
- - Signature: implement eip 712 typed structured data signing [#27](https://github.com/q9f/eth.rb/pull/27)
32
- - Lib: import ABI to eth/abi [#29](https://github.com/q9f/eth.rb/pull/29)
33
57
  - Rename util and chain to singular [#26](https://github.com/q9f/eth.rb/pull/26)
34
58
  - Docs: add some examples to readme [#25](https://github.com/q9f/eth.rb/pull/25)
35
59
  - Key/signature: personal sign and verify [#24](https://github.com/q9f/eth.rb/pull/24)
36
60
  - Ci: only run coverage on CI [#23](https://github.com/q9f/eth.rb/pull/23)
37
61
  - Lib/signature: implement personal_recover (eip 191 [#21](https://github.com/q9f/eth.rb/pull/21)
38
- - Eth/chains: implement eip 155 for replay protection [#20](https://github.com/q9f/eth.rb/pull/20)
39
62
  - Eth/util: public_key_to_address should return an eth::address [#19](https://github.com/q9f/eth.rb/pull/19)
40
63
  - Ci: add docs workflow [#18](https://github.com/q9f/eth.rb/pull/18)
41
64
  - Address class implementation and tests [#13](https://github.com/q9f/eth.rb/pull/13)
data/README.md CHANGED
@@ -1,16 +1,19 @@
1
- # Eth for Ruby
1
+ # Ethereum for Ruby
2
2
 
3
3
  [![GitHub Workflow Status](https://img.shields.io/github/workflow/status/q9f/eth.rb/Spec)](https://github.com/q9f/eth.rb/actions)
4
4
  [![GitHub release (latest by date)](https://img.shields.io/github/v/release/q9f/eth.rb)](https://github.com/q9f/eth.rb/releases)
5
5
  [![Gem](https://img.shields.io/gem/v/eth)](https://rubygems.org/gems/eth)
6
6
  [![Gem](https://img.shields.io/gem/dt/eth)](https://rubygems.org/gems/eth)
7
+ [![Visitors](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fq9f%2Feth.rb&count_bg=%2379C83D&title_bg=%23555555&icon=rubygems.svg&icon_color=%23FF0000&title=visitors&edge_flat=false)](https://hits.seeyoufarm.com)
7
8
  [![codecov](https://codecov.io/gh/q9f/eth.rb/branch/main/graph/badge.svg?token=IK7USBPBZY)](https://codecov.io/gh/q9f/eth.rb)
8
9
  [![Maintainability](https://api.codeclimate.com/v1/badges/469e6f66425198ad7614/maintainability)](https://codeclimate.com/github/q9f/eth.rb/maintainability)
9
- [![Yard Doc API](https://img.shields.io/badge/docs-API-blue)](https://q9f.github.io/eth.rb)
10
- [![GitHub top language](https://img.shields.io/github/languages/top/q9f/eth.rb?color=red)](https://github.com/q9f/eth.rb/pulse)
11
- [![GitHub](https://img.shields.io/github/license/q9f/eth.rb)](LICENSE)
10
+ [![Top Language](https://img.shields.io/github/languages/top/q9f/eth.rb?color=red)](https://github.com/q9f/eth.rb/pulse)
11
+ [![Yard Doc API](https://img.shields.io/badge/documentation-API-blue)](https://q9f.github.io/eth.rb)
12
+ [![Usage Wiki](https://img.shields.io/badge/usage-WIKI-blue)](https://github.com/q9f/eth.rb/wiki)
13
+ [![Open-Source License](https://img.shields.io/github/license/q9f/eth.rb)](LICENSE)
14
+ [![Contributions Welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/q9f/eth.rb/issues)
12
15
 
13
- A simple library to build and sign Ethereum transactions. Allows separation of key and node management. Sign transactions and handle keys anywhere you can run ruby, broadcast transactions through any node. Sign messages and recover signatures for authentication.
16
+ 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.
14
17
 
15
18
  What you get:
16
19
  - [x] Secp256k1 Key-Pairs and Encrypted Ethereum Key-Stores (JSON)
@@ -18,6 +21,7 @@ What you get:
18
21
  - [x] EIP-155 Replay protection with Chain IDs (with presets)
19
22
  - [x] EIP-191 Ethereum Signed Messages (with prefix and type)
20
23
  - [x] EIP-712 Ethereum Signed Type Data
24
+ - [x] EIP-1271 Smart-Contract Authentification
21
25
  - [x] EIP-1559 Ethereum Type-2 Transactions (with priority fee and max gas fee)
22
26
  - [x] EIP-2028 Call-data intrinsic gas cost estimates (plus access lists)
23
27
  - [x] EIP-2718 Ethereum Transaction Envelopes (and types)
@@ -25,11 +29,8 @@ What you get:
25
29
  - [x] ABI-Encoder and Decoder (including type parser)
26
30
  - [x] RLP-Encoder and Decoder (including sedes)
27
31
  - [x] RPC-Client (IPC/HTTP) for Execution-Layer APIs
28
-
29
- Soon (TM):
30
- - [ ] Smart Contracts and Solidity Support
31
- - [ ] EIP-1271 Smart-Contract Authentification
32
- - [ ] HD-Wallets (BIP-32) and Mnemonics (BIP-39)
32
+ - [x] Solidity bindings (compile contracts from Ruby)
33
+ - [x] Full smart-contract support (deploy, transact, and call)
33
34
 
34
35
  Contents:
35
36
  - [1. Installation](#1-installation)
@@ -41,13 +42,14 @@ Contents:
41
42
  - [2.5. Ethereum ABI Encoder and Decoder](#25-ethereum-abi-encoder-and-decoder)
42
43
  - [2.6. Ethereum RLP Encoder and Decoder](#26-ethereum-rlp-encoder-and-decoder)
43
44
  - [2.7. Ethereum RPC-Client](#27-ethereum-rpc-client)
45
+ - [2.8. Solidity Compiler Bindings](#28-solidity-compiler-bindings)
46
+ - [2.9. Interact with Smart Contract](#29-interact-with-smart-contract)
44
47
  - [3. Documentation](#3-documentation)
45
48
  - [4. Testing](#4-testing)
46
49
  - [5. Contributing](#5-contributing)
47
50
  - [6. License and Credits](#6-license-and-credits)
48
51
 
49
52
  ## 1. Installation
50
-
51
53
  Add this line to your application's Gemfile:
52
54
 
53
55
  ```ruby
@@ -61,9 +63,13 @@ gem install eth
61
63
  ```
62
64
 
63
65
  ## 2. Usage
66
+ Check out
67
+ [![Yard Doc API](https://img.shields.io/badge/documentation-API-blue)](https://q9f.github.io/eth.rb)
68
+ and
69
+ [![Usage Wiki](https://img.shields.io/badge/usage-WIKI-blue)](https://github.com/q9f/eth.rb/wiki)
70
+ for full details.
64
71
 
65
72
  ### 2.1. Ethereum Keys and Addresses (EIP-55)
66
-
67
73
  Generate a random Secp256k1 key-pair.
68
74
 
69
75
  ```ruby
@@ -95,7 +101,6 @@ address.checksummed # EIP 55
95
101
  See `/spec` or [Documentation](https://q9f.github.io/eth.rb/) for more details about key-pairs, encrypting/decrypting key-stores with a secret, and checksummed addresses.
96
102
 
97
103
  ### 2.2. Ethereum Signatures (EIP-191, EIP-712)
98
-
99
104
  Manage keypairs to sign messages in EIP-191 (`personal_sign`) format or typed data in EIP-712 (`sign_typed_data`) format.
100
105
 
101
106
  ```ruby
@@ -127,7 +132,6 @@ Eth::Signature.verify "Hello World!", signature, address, Eth::Chain::GOERLI
127
132
  See `/spec` or [Documentation](https://q9f.github.io/eth.rb/) for signing typed data as per EIP-712.
128
133
 
129
134
  ### 2.3. Ethereum Chains (EIP-155)
130
-
131
135
  Manage Ethereum chain IDs for EIP-155 replay protection.
132
136
 
133
137
  ```ruby
@@ -142,7 +146,6 @@ chain_id = Eth::Chain.to_chain_id v
142
146
  ```
143
147
 
144
148
  ### 2.4. Ethereum Transactions (EIP-1559, EIP-2718, EIP-2930)
145
-
146
149
  Create an EIP-1559-conform transaction:
147
150
 
148
151
  ```ruby
@@ -169,7 +172,6 @@ tx.hex
169
172
  This gem also supports access lists and ABI-encoded data payloads. See `/spec` or [Documentation](https://q9f.github.io/eth.rb/) for more details about the various supported transaction types (legacy, type-1, type-2), payload parameters, and how to estimate intrinsic gas costs.
170
173
 
171
174
  ### 2.5. Ethereum ABI Encoder and Decoder
172
-
173
175
  Encode and decode Ethereum application binary interface data (ABI).
174
176
 
175
177
  ```ruby
@@ -180,7 +182,6 @@ Eth::Abi.decode(["string", "address"], "0000000000000000000000000000000000000000
180
182
  ```
181
183
 
182
184
  ### 2.6. Ethereum RLP Encoder and Decoder
183
-
184
185
  Serialize and deserialize Ethereum recursive-length prefix data (RLP).
185
186
 
186
187
  ```ruby
@@ -198,7 +199,6 @@ Eth::Rlp.decode "c7c0c1c0c3c0c1c0"
198
199
  ```
199
200
 
200
201
  ### 2.7. Ethereum RPC-Client
201
-
202
202
  Create an IPC- or HTTP-RPC-API client to seamlessly query the chain state, e.g., Infura over HTTPS with access token:
203
203
 
204
204
  ```ruby
@@ -229,8 +229,72 @@ cli.get_nonce cli.eth_coinbase["result"]
229
229
 
230
230
  Check out `Eth::Api` for a list of supported RPC-APIs or consult the [Documentation](https://q9f.github.io/eth.rb/) for more details.
231
231
 
232
- ## 3. Documentation
232
+ ### 2.8. Solidity Compiler Bindings
233
+ Link a system-level Solidity compiler (`solc`) to your Ruby library and compile contracts.
234
+
235
+ ```ruby
236
+ solc = Eth::Solidity.new
237
+ # => #<Eth::Solidity:0x000055f05040c6d0 @compiler="/usr/bin/solc">
238
+ contract = solc.compile "spec/fixtures/contracts/greeter.sol"
239
+ # => {"Greeter"=>
240
+ # {"abi"=>
241
+ # [{"inputs"=>[{"internalType"=>"string", "name"=>"message", "type"=>"string"}], "stateMutability"=>"nonpayable", "type"=>"constructor"},
242
+ # {"inputs"=>[], "name"=>"greet", "outputs"=>[{"internalType"=>"string", "name"=>"", "type"=>"string"}], "stateMutability"=>"view", "type"=>"function"},
243
+ # {"inputs"=>[], "name"=>"kill", "outputs"=>[], "stateMutability"=>"nonpayable", "type"=>"function"}],
244
+ # "bin"=>
245
+ # "6080604052348015...6c634300080c0033"},
246
+ # "Mortal"=>
247
+ # {"abi"=>[{"inputs"=>[], "stateMutability"=>"nonpayable", "type"=>"constructor"}, {"inputs"=>[], "name"=>"kill", "outputs"=>[], "stateMutability"=>"nonpayable", "type"=>"function"}],
248
+ # "bin"=>
249
+ # "6080604052348015...6c634300080c0033"}}
250
+ ```
251
+
252
+ The `contract["Greeter"]["bin"]` could be directly used to deploy the contract as `Eth::Tx` payload. Check out the [Documentation](https://q9f.github.io/eth.rb/) for more details.
253
+
254
+ ### 2.9. Interact with Smart Contract
255
+
256
+ Create, compile, and deploy smart contracts.
257
+
258
+ ```ruby
259
+ contract = Eth::Contract.from_file(file: 'spec/fixtures/contracts/dummy.sol')
260
+ # => #<Eth::Contract::Dummy:0x00007fbeee936598>
261
+ cli = Eth::Client.create "/tmp/geth.ipc"
262
+ # => #<Eth::Client::Ipc:0x00007fbeee946128 @gas_limit=21000, @id=0, @max_fee_per_gas=0.2e11, @max_priority_fee_per_gas=0, @path="/tmp/geth.ipc">
263
+ address = cli.deploy_and_wait(contract)
264
+ # => "0x2f2faa160420cee087ded96bad52475147136bd8"
265
+ ```
233
266
 
267
+ Transact with or call the deployed contract.
268
+
269
+ ```ruby
270
+ cli.transact_and_wait(contract, "set", 1234)
271
+ # => "0x49ca4c0a5729da19a1d2574de9a444a9cd3219bdad81745b54f9cf3bb83b6a06"
272
+ cli.call(contract, "get")
273
+ # => 1234
274
+ ```
275
+
276
+ Or call an existing contract, e.g., the ENS registry:
277
+
278
+ ```ruby
279
+ ens_registry_abi = '[{"inputs":[{"internalType":"contract ENS","name":"_old","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"label","type":"bytes32"},{"indexed":false,"internalType":"address","name":"owner","type":"address"}],"name":"NewOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"address","name":"resolver","type":"address"}],"name":"NewResolver","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"ttl","type":"uint64"}],"name":"NewTTL","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"node","type":"bytes32"},{"indexed":false,"internalType":"address","name":"owner","type":"address"}],"name":"Transfer","type":"event"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"old","outputs":[{"internalType":"contract ENS","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"recordExists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"resolver","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"uint64","name":"ttl","type":"uint64"}],"name":"setRecord","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"address","name":"resolver","type":"address"}],"name":"setResolver","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"label","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"}],"name":"setSubnodeOwner","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"bytes32","name":"label","type":"bytes32"},{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"resolver","type":"address"},{"internalType":"uint64","name":"ttl","type":"uint64"}],"name":"setSubnodeRecord","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"},{"internalType":"uint64","name":"ttl","type":"uint64"}],"name":"setTTL","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"node","type":"bytes32"}],"name":"ttl","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"}]'
280
+ ens_registry_address = "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"
281
+ ens_registry_name = "ENSRegistryWithFallback"
282
+ ens_registry = Eth::Contract.from_abi(name: ens_registry_name, address: ens_registry_address, abi: ens_registry_abi)
283
+ # => #<Eth::Contract::ENSRegistryWithFallback:0x000055bece570980>
284
+ ens_registry.address
285
+ # => "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"
286
+ cli.call(ens_registry, "old")
287
+ # => "0x112234455c3a32fd11230c42e7bccd4a84e02010"
288
+ ```
289
+
290
+ The gem also comes with an EIP-1271 smart-contract authentification interface.
291
+
292
+ ```ruby
293
+ cli.is_valid_signature contract, hash, signature
294
+ # => true
295
+ ```
296
+
297
+ ## 3. Documentation
234
298
  The documentation can be found at: https://q9f.github.io/eth.rb
235
299
 
236
300
  For any specific version, docs can be generated by `yard`:
@@ -244,8 +308,13 @@ yard doc
244
308
  The goal is to have 100% API documentation available.
245
309
 
246
310
  ## 4. Testing
311
+ The test suite expects working local HTTP and IPC endpoints with a prefunded developer account, e.g.:
247
312
 
248
- To run tests, simply use `rspec`. Note, that the Ethereum tests fixtures are required.
313
+ ```shell
314
+ geth --dev --http --ipcpath /tmp/geth.ipc &
315
+ ```
316
+
317
+ To run tests, simply use `rspec`. Note, that the Ethereum test fixtures are also required.
249
318
 
250
319
  ```shell
251
320
  git submodule update --init --recursive
@@ -256,7 +325,6 @@ rspec
256
325
  The goal is to have 100% specification coverage for all code inside this gem.
257
326
 
258
327
  ## 5. Contributing
259
-
260
328
  Pull requests are welcome! To contribute, please consider the following:
261
329
  * Code should be fully documented. Run `yard doc` and make sure it does not yield any warnings or undocumented sets.
262
330
  * Code should be fully covered by tests. Run `rspec` to make sure all tests pass. The CI has an integration that will assis you to identify uncovered lines of code and get coverage up to 100%.
@@ -269,8 +337,11 @@ The `eth` gem is licensed under the conditions of [Apache 2.0](./LICENSE.txt). P
269
337
  This gem is a complete rewrite of the old `eth` gem by Steve Ellis.
270
338
  * https://github.com/se3000/ruby-eth/ (MIT)
271
339
 
272
- It also contains a revised version the ABI gem by Jan Xie and Zhang Yaning.
340
+ It is not only a rewrite of the `eth` gem but also a partial merge of the `ethereum` gem by Marek Kirejczyk and Yuta Kurotaki.
341
+ * https://github.com/EthWorks/ethereum.rb (MIT)
342
+
343
+ This gem also includes a revised version of the ABI gem by Jan Xie and Zhang Yaning.
273
344
  * https://github.com/cryptape/ruby-ethereum-abi (MIT)
274
345
 
275
- It also contains a revised version the RLP gem by Jan Xie and Zhang Yaning.
346
+ It also contains a condensed version of the RLP gem by Jan Xie and Zhang Yaning.
276
347
  * https://github.com/cryptape/ruby-rlp (MIT)
data/codecov.yml ADDED
@@ -0,0 +1,6 @@
1
+ coverage:
2
+ status:
3
+ project:
4
+ default:
5
+ target: 99%
6
+ threshold: 1%
data/eth.gemspec CHANGED
@@ -44,7 +44,7 @@ Gem::Specification.new do |spec|
44
44
  spec.add_dependency "rbsecp256k1", "~> 5.1"
45
45
 
46
46
  # openssl for encrypted key derivation
47
- spec.add_dependency "openssl", "~> 2.2"
47
+ spec.add_dependency "openssl", ">= 2.2", "< 4.0"
48
48
 
49
49
  # scrypt for encrypted key derivation
50
50
  spec.add_dependency "scrypt", "~> 3.0"
@@ -0,0 +1,137 @@
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
+ # -*- 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
+ # Provides a module to decode transaction log events.
24
+ module Event
25
+ extend self
26
+
27
+ # Compute topic for ABI event interface.
28
+ #
29
+ # @param interface [Hash] ABI event interface.
30
+ # @return [String] a hex-string topic.
31
+ def compute_topic(interface)
32
+ sig = Abi.signature(interface)
33
+ Util.prefix_hex(Util.bin_to_hex(Util.keccak256(sig)))
34
+ end
35
+
36
+ # A decoded event log.
37
+ class LogDescription
38
+ # The event ABI interface used to decode the log.
39
+ attr_accessor :event_interface
40
+
41
+ # The the input argument of the event.
42
+ attr_accessor :args
43
+
44
+ # The named input argument of the event.
45
+ attr_accessor :kwargs
46
+
47
+ # The topic hash.
48
+ attr_accessor :topic
49
+
50
+ # Decodes event log argument values.
51
+ #
52
+ # @param event_interface [Hash] event ABI type.
53
+ # @param log [Hash] transaction receipt log
54
+ def initialize(event_interface, log)
55
+ @event_interface = event_interface
56
+
57
+ inputs = event_interface.fetch("inputs")
58
+ data = log.fetch("data")
59
+ topics = log.fetch("topics", [])
60
+ anonymous = event_interface.fetch("anonymous", false)
61
+
62
+ @topic = topics[0] if !anonymous
63
+ @args, @kwargs = Event.decode_log(inputs, data, topics, anonymous)
64
+ end
65
+
66
+ # The event name. (e.g. Transfer)
67
+ def name
68
+ @name ||= event_interface.fetch("name")
69
+ end
70
+
71
+ # The event signature. (e.g. Transfer(address,address,uint256))
72
+ def signature
73
+ @signature ||= Abi.signature(event_interface)
74
+ end
75
+ end
76
+
77
+ # Decodes a stream of receipt logs with a set of ABI interfaces.
78
+ #
79
+ # @param interfaces [Array] event ABI types.
80
+ # @param logs [Array] transaction receipt logs
81
+ # @return [Hash] an enumerator of LogDescription objects.
82
+ def decode_logs(interfaces, logs)
83
+ Enumerator.new do |y|
84
+ topic_to_interfaces = Hash[interfaces.map { |i| [compute_topic(i), i] }]
85
+
86
+ logs.each do |log|
87
+ topic = log.fetch("topics", [])[0]
88
+ if topic && interface = topic_to_interfaces[topic]
89
+ y << [log, LogDescription.new(interface, log)]
90
+ else
91
+ y << [log, nil]
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ # Decodes event log argument values.
98
+ #
99
+ # @param inputs [Array] event ABI types.
100
+ # @param data [String] ABI event data to be decoded.
101
+ # @param topics [Array] ABI event topics to be decoded.
102
+ # @param anonymous [Boolean] If event signature is excluded from topics.
103
+ # @return [[Array, Hash]] decoded positional arguments and decoded keyword arguments.
104
+ # @raise [DecodingError] if decoding fails for type.
105
+ def decode_log(inputs, data, topics, anonymous = false)
106
+ topic_inputs, data_inputs = inputs.partition { |i| i["indexed"] }
107
+
108
+ topic_types = topic_inputs.map { |i| i["type"] }
109
+ data_types = data_inputs.map { |i| i["type"] }
110
+
111
+ # If event is anonymous, all topics are arguments. Otherwise, the first
112
+ # topic will be the event signature.
113
+ if anonymous == false
114
+ topics = topics[1..-1]
115
+ end
116
+
117
+ decoded_topics = topics.map.with_index { |t, i| Abi.decode([topic_types[i]], t)[0] }
118
+ decoded_data = Abi.decode(data_types, data)
119
+
120
+ args = []
121
+ kwargs = {}
122
+
123
+ inputs.each_with_index do |input, index|
124
+ if input["indexed"]
125
+ value = decoded_topics[topic_inputs.index(input)]
126
+ else
127
+ value = decoded_data[data_inputs.index(input)]
128
+ end
129
+ args[index] = value
130
+ kwargs[input["name"].to_sym] = value
131
+ end
132
+
133
+ return args, kwargs
134
+ end
135
+ end
136
+ end
137
+ end
data/lib/eth/abi/type.rb CHANGED
@@ -17,7 +17,7 @@
17
17
  # Provides the {Eth} module.
18
18
  module Eth
19
19
 
20
- # Provides a Ruby implementation of the Ethereum Applicatoin Binary Interface (ABI).
20
+ # Provides a Ruby implementation of the Ethereum Application Binary Interface (ABI).
21
21
  module Abi
22
22
 
23
23
  # Provides a class to handle and parse common ABI types.
data/lib/eth/abi.rb CHANGED
@@ -16,12 +16,13 @@
16
16
 
17
17
  require "konstructor"
18
18
 
19
+ require "eth/abi/event"
19
20
  require "eth/abi/type"
20
21
 
21
22
  # Provides the {Eth} module.
22
23
  module Eth
23
24
 
24
- # Provides a Ruby implementation of the Ethereum Applicatoin Binary Interface (ABI).
25
+ # Provides a Ruby implementation of the Ethereum Application Binary Interface (ABI).
25
26
  # ref: https://docs.soliditylang.org/en/develop/abi-spec.html
26
27
  module Abi
27
28
  extend self
@@ -43,7 +44,7 @@ module Eth
43
44
  # @return [String] the encoded ABI data.
44
45
  def encode(types, args)
45
46
 
46
- # prase all types
47
+ # parse all types
47
48
  parsed_types = types.map { |t| Type.parse(t) }
48
49
 
49
50
  # prepare the "head"
@@ -290,6 +291,17 @@ module Eth
290
291
  end
291
292
  end
292
293
 
294
+ # Build event signature string from ABI interface.
295
+ #
296
+ # @param interface [Hash] ABI event interface.
297
+ # @return [String] interface signature string.
298
+ def signature(interface)
299
+ name = interface.fetch("name")
300
+ inputs = interface.fetch("inputs", [])
301
+ types = inputs.map { |i| i.fetch("type") }
302
+ "#{name}(#{types.join(",")})"
303
+ end
304
+
293
305
  private
294
306
 
295
307
  # Properly encodes unsigned integers.
data/lib/eth/chain.rb CHANGED
@@ -136,7 +136,7 @@ module Eth
136
136
  return v
137
137
  end
138
138
 
139
- # Converst a `v` value into a chain ID. This does not work for legacy signatures
139
+ # Converts a `v` value into a chain ID. This does not work for legacy signatures
140
140
  # with `v < 36` that do not conform with EIP-155.
141
141
  #
142
142
  # @param v [Integer] the signature's `v` value.
@@ -40,6 +40,9 @@ module Eth
40
40
  socket = UNIXSocket.new(@path)
41
41
  socket.puts(payload)
42
42
  read = socket.recvmsg(nil)[0]
43
+ until read.end_with?("\n")
44
+ read = read << socket.recvmsg(nil)[0]
45
+ end
43
46
  socket.close
44
47
  return read
45
48
  end