eth 0.5.2 → 0.5.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +18 -0
- data/.github/workflows/codeql.yml +4 -4
- data/.github/workflows/docs.yml +2 -2
- data/.github/workflows/spec.yml +2 -2
- data/AUTHORS.txt +2 -0
- data/CHANGELOG.md +42 -6
- data/README.md +48 -7
- data/eth.gemspec +1 -1
- data/lib/eth/abi/event.rb +137 -0
- data/lib/eth/abi/type.rb +1 -1
- data/lib/eth/abi.rb +34 -2
- data/lib/eth/chain.rb +7 -1
- data/lib/eth/client.rb +252 -1
- data/lib/eth/contract/event.rb +42 -0
- data/lib/eth/contract/function.rb +57 -0
- data/lib/eth/contract/function_input.rb +37 -0
- data/lib/eth/contract/function_output.rb +37 -0
- data/lib/eth/contract/initializer.rb +47 -0
- data/lib/eth/contract.rb +143 -0
- data/lib/eth/rlp/sedes/binary.rb +2 -2
- data/lib/eth/tx.rb +4 -1
- data/lib/eth/version.rb +1 -1
- data/lib/eth.rb +1 -2
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62da01e731dd3a73a356760ac971250f193142090876e62567d73cbb5664213d
|
4
|
+
data.tar.gz: 8a951b1b585acd7b58dc327f122dbdd4787145fefbe09d71f1aa4d127787e99e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd1ca2d9f89a545f20cf23a9cff62a83bfe20514b69cb14aac88f08cd101a8bb9e26ba700539259c16d64ee2a3cbae46adf7bedd18b66835785ad701fd515681
|
7
|
+
data.tar.gz: a1f51f0dac47d8ce7a4ccd3df0d3decfdb0847df36a4b16587b5dd9ae217aee7375e952207d00611bcb487647ff152d958d4709ebf8b429ec0235220f45d35bd
|
@@ -0,0 +1,18 @@
|
|
1
|
+
---
|
2
|
+
updates:
|
3
|
+
-
|
4
|
+
directory: /
|
5
|
+
labels:
|
6
|
+
- dependencies
|
7
|
+
package-ecosystem: bundler
|
8
|
+
schedule:
|
9
|
+
interval: weekly
|
10
|
+
versioning-strategy: increase
|
11
|
+
-
|
12
|
+
directory: /
|
13
|
+
labels:
|
14
|
+
- operations
|
15
|
+
package-ecosystem: github-actions
|
16
|
+
schedule:
|
17
|
+
interval: monthly
|
18
|
+
version: 2
|
@@ -24,15 +24,15 @@ jobs:
|
|
24
24
|
- ruby
|
25
25
|
steps:
|
26
26
|
- name: "Checkout repository"
|
27
|
-
uses: actions/checkout@
|
27
|
+
uses: actions/checkout@v3
|
28
28
|
- name: "Initialize CodeQL"
|
29
|
-
uses: github/codeql-action/init@
|
29
|
+
uses: github/codeql-action/init@v2
|
30
30
|
with:
|
31
31
|
languages: "${{ matrix.language }}"
|
32
32
|
- name: Autobuild
|
33
|
-
uses: github/codeql-action/autobuild@
|
33
|
+
uses: github/codeql-action/autobuild@v2
|
34
34
|
- name: "Perform CodeQL Analysis"
|
35
|
-
uses: github/codeql-action/analyze@
|
35
|
+
uses: github/codeql-action/analyze@v2
|
36
36
|
- uses: ruby/setup-ruby@v1
|
37
37
|
with:
|
38
38
|
ruby-version: '2.7'
|
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@v3
|
14
14
|
- uses: ruby/setup-ruby@v1
|
15
15
|
with:
|
16
16
|
ruby-version: '2.7'
|
@@ -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@
|
23
|
+
uses: JamesIves/github-pages-deploy-action@v4.3.3
|
24
24
|
with:
|
25
25
|
branch: gh-pages
|
26
26
|
folder: doc/
|
data/.github/workflows/spec.yml
CHANGED
@@ -19,9 +19,9 @@ jobs:
|
|
19
19
|
fail-fast: false
|
20
20
|
matrix:
|
21
21
|
os: [ubuntu-latest, macos-latest]
|
22
|
-
ruby: ['2.7', '3.
|
22
|
+
ruby: ['2.7', '3.1']
|
23
23
|
steps:
|
24
|
-
- uses: actions/checkout@
|
24
|
+
- uses: actions/checkout@v3
|
25
25
|
- uses: ruby/setup-ruby@v1
|
26
26
|
with:
|
27
27
|
ruby-version: ${{ matrix.ruby }}
|
data/AUTHORS.txt
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,20 +1,60 @@
|
|
1
1
|
# Change Log
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## [0.5.4]
|
5
|
+
### Added
|
6
|
+
- Eth/client: method for eip-1271 ([#80](https://github.com/q9f/eth.rb/pull/80))
|
7
|
+
|
8
|
+
### Changed
|
9
|
+
- Docs: update changelog ([#77](https://github.com/q9f/eth.rb/pull/77))
|
10
|
+
- Gem: bump version to 0.5.4 ([#78](https://github.com/q9f/eth.rb/pull/78))
|
11
|
+
- Ci: bump ruby version to 3.1 on ci ([#79](https://github.com/q9f/eth.rb/pull/79))
|
12
|
+
- Fix typos ([#81](https://github.com/q9f/eth.rb/pull/81))
|
13
|
+
- Eth/contract: allow creating from file, abi, bin ([#83](https://github.com/q9f/eth.rb/pull/83))
|
14
|
+
- Eth/client: fix account requirement for client.call() ([#85](https://github.com/q9f/eth.rb/pull/85))
|
15
|
+
- Add dependency support for openssl 2.2 and greater, including 3.x ([#88](https://github.com/q9f/eth.rb/pull/88))
|
16
|
+
|
17
|
+
## [0.5.3]
|
18
|
+
### Added
|
19
|
+
- Smart contract support ([#68](https://github.com/q9f/eth.rb/pull/68))
|
20
|
+
|
21
|
+
### Changed
|
22
|
+
- Eth/abi: decode event log ([#69](https://github.com/q9f/eth.rb/pull/69))
|
23
|
+
- Gem: bump version ([#70](https://github.com/q9f/eth.rb/pull/70))
|
24
|
+
- Eth/abi/event: batch log decoder ([#71](https://github.com/q9f/eth.rb/pull/71))
|
25
|
+
|
26
|
+
## [0.5.2]
|
27
|
+
### Added
|
28
|
+
- Eth/solidity: add solidity compiler bindings ([#66](https://github.com/q9f/eth.rb/pull/66))
|
29
|
+
|
30
|
+
### Changed
|
31
|
+
- Eth: remove duplicated code ([#62](https://github.com/q9f/eth.rb/pull/62))
|
32
|
+
- Ci: allow coverage to drop to 99% without failing ([#63](https://github.com/q9f/eth.rb/pull/63))
|
33
|
+
- Docs: update readme ([#64](https://github.com/q9f/eth.rb/pull/64))
|
34
|
+
- Docs: add wiki to readme ([#65](https://github.com/q9f/eth.rb/pull/65))
|
35
|
+
|
4
36
|
## [0.5.1]
|
37
|
+
### Added
|
38
|
+
- Add eth::rlp module ([#52](https://github.com/q9f/eth.rb/pull/52))
|
39
|
+
- Eth/client: implement http/ipc ([#37](https://github.com/q9f/eth.rb/pull/37))
|
40
|
+
|
5
41
|
### Changed
|
6
42
|
- Docs: update changelog ([#61](https://github.com/q9f/eth.rb/pull/61))
|
7
43
|
- Eth/chain: add sepolia chain id; docs ([#60](https://github.com/q9f/eth.rb/pull/60))
|
8
44
|
- 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
45
|
- Eth/tx: properly serialize signatures ([#58](https://github.com/q9f/eth.rb/pull/58))
|
11
46
|
- Eth/client: fix legacy transfer ([#57](https://github.com/q9f/eth.rb/pull/57))
|
12
47
|
- 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
48
|
- Docs: update changelog ([#53](https://github.com/q9f/eth.rb/pull/53))
|
15
49
|
- Spec: add upstream test fixtures for keystore ([#50](https://github.com/q9f/eth.rb/pull/50))
|
16
50
|
|
17
51
|
## [0.5.0]
|
52
|
+
### Added
|
53
|
+
- Eth/tx: create legacy, type-1, and type-2 transactions [#33](https://github.com/q9f/eth.rb/pull/33)
|
54
|
+
- Signature: implement eip 712 typed structured data signing [#27](https://github.com/q9f/eth.rb/pull/27)
|
55
|
+
- Lib: import ABI to eth/abi [#29](https://github.com/q9f/eth.rb/pull/29)
|
56
|
+
- Eth/chains: implement eip 155 for replay protection [#20](https://github.com/q9f/eth.rb/pull/20)
|
57
|
+
|
18
58
|
### Changed
|
19
59
|
- Docs: update readme with features [#49](https://github.com/q9f/eth.rb/pull/49)
|
20
60
|
- Eth/tx: add method to estimate intrinsic gas costs [#48](https://github.com/q9f/eth.rb/pull/48)
|
@@ -26,16 +66,12 @@ All notable changes to this project will be documented in this file.
|
|
26
66
|
- Lib: improve error handling [#39](https://github.com/q9f/eth.rb/pull/39)
|
27
67
|
- Docs: update readme for tx and keys [#40](https://github.com/q9f/eth.rb/pull/40)
|
28
68
|
- 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
69
|
- 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
70
|
- Rename util and chain to singular [#26](https://github.com/q9f/eth.rb/pull/26)
|
34
71
|
- Docs: add some examples to readme [#25](https://github.com/q9f/eth.rb/pull/25)
|
35
72
|
- Key/signature: personal sign and verify [#24](https://github.com/q9f/eth.rb/pull/24)
|
36
73
|
- Ci: only run coverage on CI [#23](https://github.com/q9f/eth.rb/pull/23)
|
37
74
|
- 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
75
|
- Eth/util: public_key_to_address should return an eth::address [#19](https://github.com/q9f/eth.rb/pull/19)
|
40
76
|
- Ci: add docs workflow [#18](https://github.com/q9f/eth.rb/pull/18)
|
41
77
|
- Address class implementation and tests [#13](https://github.com/q9f/eth.rb/pull/13)
|
data/README.md
CHANGED
@@ -21,6 +21,7 @@ What you get:
|
|
21
21
|
- [x] EIP-155 Replay protection with Chain IDs (with presets)
|
22
22
|
- [x] EIP-191 Ethereum Signed Messages (with prefix and type)
|
23
23
|
- [x] EIP-712 Ethereum Signed Type Data
|
24
|
+
- [x] EIP-1271 Smart-Contract Authentification
|
24
25
|
- [x] EIP-1559 Ethereum Type-2 Transactions (with priority fee and max gas fee)
|
25
26
|
- [x] EIP-2028 Call-data intrinsic gas cost estimates (plus access lists)
|
26
27
|
- [x] EIP-2718 Ethereum Transaction Envelopes (and types)
|
@@ -29,11 +30,7 @@ What you get:
|
|
29
30
|
- [x] RLP-Encoder and Decoder (including sedes)
|
30
31
|
- [x] RPC-Client (IPC/HTTP) for Execution-Layer APIs
|
31
32
|
- [x] Solidity bindings (compile contracts from Ruby)
|
32
|
-
|
33
|
-
Soon (TM):
|
34
|
-
- [ ] Smart Contract Support
|
35
|
-
- [ ] EIP-1271 Smart-Contract Authentification
|
36
|
-
- [ ] HD-Wallets (BIP-32) and Mnemonics (BIP-39)
|
33
|
+
- [x] Full smart-contract support (deploy, transact, and call)
|
37
34
|
|
38
35
|
Contents:
|
39
36
|
- [1. Installation](#1-installation)
|
@@ -45,7 +42,8 @@ Contents:
|
|
45
42
|
- [2.5. Ethereum ABI Encoder and Decoder](#25-ethereum-abi-encoder-and-decoder)
|
46
43
|
- [2.6. Ethereum RLP Encoder and Decoder](#26-ethereum-rlp-encoder-and-decoder)
|
47
44
|
- [2.7. Ethereum RPC-Client](#27-ethereum-rpc-client)
|
48
|
-
- [2.8 Solidity Compiler Bindings](#28-solidity-compiler-bindings)
|
45
|
+
- [2.8. Solidity Compiler Bindings](#28-solidity-compiler-bindings)
|
46
|
+
- [2.9. Interact with Smart Contract](#29-interact-with-smart-contract)
|
49
47
|
- [3. Documentation](#3-documentation)
|
50
48
|
- [4. Testing](#4-testing)
|
51
49
|
- [5. Contributing](#5-contributing)
|
@@ -231,7 +229,7 @@ cli.get_nonce cli.eth_coinbase["result"]
|
|
231
229
|
|
232
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.
|
233
231
|
|
234
|
-
### 2.8 Solidity Compiler Bindings
|
232
|
+
### 2.8. Solidity Compiler Bindings
|
235
233
|
Link a system-level Solidity compiler (`solc`) to your Ruby library and compile contracts.
|
236
234
|
|
237
235
|
```ruby
|
@@ -253,6 +251,49 @@ contract = solc.compile "spec/fixtures/contracts/greeter.sol"
|
|
253
251
|
|
254
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.
|
255
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
|
+
```
|
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
|
+
|
256
297
|
## 3. Documentation
|
257
298
|
The documentation can be found at: https://q9f.github.io/eth.rb
|
258
299
|
|
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", "
|
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
|
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
|
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
|
-
#
|
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.
|
@@ -334,6 +346,8 @@ module Eth
|
|
334
346
|
# Properly encodes byte-strings.
|
335
347
|
def encode_bytes(arg, type)
|
336
348
|
raise EncodingError, "Expecting String: #{arg}" unless arg.instance_of? String
|
349
|
+
arg = handle_hex_string arg, type
|
350
|
+
|
337
351
|
if type.sub_type.empty?
|
338
352
|
size = Util.zpad_int arg.size
|
339
353
|
padding = Constant::BYTE_ZERO * (Util.ceil32(arg.size) - arg.size)
|
@@ -392,5 +406,23 @@ module Eth
|
|
392
406
|
raise EncodingError, "Could not parse address: #{arg}"
|
393
407
|
end
|
394
408
|
end
|
409
|
+
|
410
|
+
# The ABI encoder needs to be able to determine between a hex `"123"`
|
411
|
+
# and a binary `"123"` string.
|
412
|
+
def handle_hex_string(arg, type)
|
413
|
+
if Util.is_prefixed? arg or
|
414
|
+
(arg.size === type.sub_type.to_i * 2 and Util.is_hex? arg)
|
415
|
+
|
416
|
+
# There is no way telling whether a string is hex or binary with certainty
|
417
|
+
# in Ruby. Therefore, we assume a `0x` prefix to indicate a hex string.
|
418
|
+
# Additionally, if the string size is exactly the double of the expected
|
419
|
+
# binary size, we can assume a hex value.
|
420
|
+
return Util.hex_to_bin arg
|
421
|
+
else
|
422
|
+
|
423
|
+
# Everything else will be assumed binary or raw string.
|
424
|
+
return arg.b
|
425
|
+
end
|
426
|
+
end
|
395
427
|
end
|
396
428
|
end
|
data/lib/eth/chain.rb
CHANGED
@@ -41,6 +41,9 @@ module Eth
|
|
41
41
|
# Chain ID for Gnosis mainnet.
|
42
42
|
XDAI = 100.freeze
|
43
43
|
|
44
|
+
# Chain ID for the Polygon Matic mainnet.
|
45
|
+
MATIC = 137.freeze
|
46
|
+
|
44
47
|
# Chain ID for Arbitrum mainnet.
|
45
48
|
ARBITRUM = 42161.freeze
|
46
49
|
|
@@ -77,6 +80,9 @@ module Eth
|
|
77
80
|
# Chain ID for Optimistic Goerli testnet.
|
78
81
|
GOERLI_OPTIMISM = 420.freeze
|
79
82
|
|
83
|
+
# Chain ID for the Polygon Mumbai testnet.
|
84
|
+
MUMBAI = 80001.freeze
|
85
|
+
|
80
86
|
# Chain ID for Arbitrum Rinkeby testnet.
|
81
87
|
RINKEBY_ARBITRUM = 421611.freeze
|
82
88
|
|
@@ -136,7 +142,7 @@ module Eth
|
|
136
142
|
return v
|
137
143
|
end
|
138
144
|
|
139
|
-
#
|
145
|
+
# Converts a `v` value into a chain ID. This does not work for legacy signatures
|
140
146
|
# with `v < 36` that do not conform with EIP-155.
|
141
147
|
#
|
142
148
|
# @param v [Integer] the signature's `v` value.
|
data/lib/eth/client.rb
CHANGED
@@ -149,6 +149,204 @@ module Eth
|
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
152
|
+
# Deploys a contract and waits for it to be mined. Uses
|
153
|
+
# `eth_coinbase` or external signer if no sender key is provided.
|
154
|
+
#
|
155
|
+
# @overload deploy(contract)
|
156
|
+
# @param contract [Eth::Contract] contracts to deploy.
|
157
|
+
# @overload deploy(contract, *args, **kwargs)
|
158
|
+
# @param contract [Eth::Contract] contracts to deploy.
|
159
|
+
# *args Optional variable constructor parameter list
|
160
|
+
# **sender_key [Eth::Key] the sender private key.
|
161
|
+
# **legacy [Boolean] enables legacy transactions (pre-EIP-1559).
|
162
|
+
# @return [String] the contract address.
|
163
|
+
def deploy_and_wait(contract, *args, **kwargs)
|
164
|
+
hash = wait_for_tx(deploy(contract, *args, **kwargs))
|
165
|
+
addr = eth_get_transaction_receipt(hash)["result"]["contractAddress"]
|
166
|
+
contract.address = Address.new(addr).to_s
|
167
|
+
end
|
168
|
+
|
169
|
+
# Deploys a contract. Uses `eth_coinbase` or external signer
|
170
|
+
# if no sender key is provided.
|
171
|
+
#
|
172
|
+
# @overload deploy(contract)
|
173
|
+
# @param contract [Eth::Contract] contracts to deploy.
|
174
|
+
# @overload deploy(contract, *args, **kwargs)
|
175
|
+
# @param contract [Eth::Contract] contracts to deploy.
|
176
|
+
# *args Optional variable constructor parameter list
|
177
|
+
# **sender_key [Eth::Key] the sender private key.
|
178
|
+
# **legacy [Boolean] enables legacy transactions (pre-EIP-1559).
|
179
|
+
# @return [String] the transaction hash.
|
180
|
+
# @raise [ArgumentError] in case the contract does not have any source.
|
181
|
+
def deploy(contract, *args, **kwargs)
|
182
|
+
raise ArgumentError, "Cannot deploy contract without source or binary!" if contract.bin.nil?
|
183
|
+
raise ArgumentError, "Missing contract constructor params!" if contract.constructor_inputs.length != args.length
|
184
|
+
gas_limit = Tx.estimate_intrinsic_gas(contract.bin) + Tx::CREATE_GAS
|
185
|
+
data = contract.bin
|
186
|
+
unless args.empty?
|
187
|
+
data += encode_constructor_params(contract, args)
|
188
|
+
end
|
189
|
+
params = {
|
190
|
+
value: 0,
|
191
|
+
gas_limit: gas_limit,
|
192
|
+
chain_id: chain_id,
|
193
|
+
data: data,
|
194
|
+
}
|
195
|
+
if kwargs[:legacy]
|
196
|
+
params.merge!({
|
197
|
+
gas_price: max_fee_per_gas,
|
198
|
+
})
|
199
|
+
else
|
200
|
+
params.merge!({
|
201
|
+
priority_fee: max_priority_fee_per_gas,
|
202
|
+
max_gas_fee: max_fee_per_gas,
|
203
|
+
})
|
204
|
+
end
|
205
|
+
unless kwargs[:sender_key].nil?
|
206
|
+
# Uses the provided key as sender and signer
|
207
|
+
params.merge!({
|
208
|
+
from: kwargs[:sender_key].address,
|
209
|
+
nonce: get_nonce(kwargs[:sender_key].address),
|
210
|
+
})
|
211
|
+
tx = Eth::Tx.new(params)
|
212
|
+
tx.sign kwargs[:sender_key]
|
213
|
+
return eth_send_raw_transaction(tx.hex)["result"]
|
214
|
+
else
|
215
|
+
# Uses the default account as sender and external signer
|
216
|
+
params.merge!({
|
217
|
+
from: default_account,
|
218
|
+
nonce: get_nonce(default_account),
|
219
|
+
})
|
220
|
+
return eth_send_transaction(params)["result"]
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# Calls a contract function without executing it
|
225
|
+
# (non-transactional contract read).
|
226
|
+
#
|
227
|
+
# @overload call(contract, function_name)
|
228
|
+
# @param contract [Eth::Contract] subject contract to call.
|
229
|
+
# @param function_name [String] method name to be called.
|
230
|
+
# @overload call(contract, function_name, value)
|
231
|
+
# @param contract [Eth::Contract] subject contract to call.
|
232
|
+
# @param function_name [String] method name to be called.
|
233
|
+
# @param value [Integer|String] function arguments.
|
234
|
+
# @overload call(contract, function_name, value, sender_key, legacy)
|
235
|
+
# @param contract [Eth::Contract] subject contract to call.
|
236
|
+
# @param function_name [String] method name to be called.
|
237
|
+
# @param value [Integer|String] function arguments.
|
238
|
+
# @param sender_key [Eth::Key] the sender private key.
|
239
|
+
# @param legacy [Boolean] enables legacy transactions (pre-EIP-1559).
|
240
|
+
# @return [Object] returns the result of the call.
|
241
|
+
def call(contract, function_name, *args, **kwargs)
|
242
|
+
func = contract.functions.select { |func| func.name == function_name }[0]
|
243
|
+
raise ArgumentError, "function_name does not exist!" if func.nil?
|
244
|
+
output = call_raw(contract, func, *args, **kwargs)
|
245
|
+
if output&.length == 1
|
246
|
+
return output[0]
|
247
|
+
else
|
248
|
+
return output
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
# Executes a contract function with a transaction (transactional
|
253
|
+
# contract read/write).
|
254
|
+
#
|
255
|
+
# @overload transact(contract, function_name)
|
256
|
+
# @param contract [Eth::Contract] subject contract to call.
|
257
|
+
# @param function_name [String] method name to be called.
|
258
|
+
# @overload transact(contract, function_name, value)
|
259
|
+
# @param contract [Eth::Contract] subject contract to call.
|
260
|
+
# @param function_name [String] method name to be called.
|
261
|
+
# @param value [Integer|String] function arguments.
|
262
|
+
# @overload transact(contract, function_name, value, sender_key, legacy, address)
|
263
|
+
# @param contract [Eth::Contract] subject contract to call.
|
264
|
+
# @param function_name [String] method name to be called.
|
265
|
+
# @param value [Integer|String] function arguments.
|
266
|
+
# @param sender_key [Eth::Key] the sender private key.
|
267
|
+
# @param legacy [Boolean] enables legacy transactions (pre-EIP-1559).
|
268
|
+
# @param address [String] contract address.
|
269
|
+
# @return [Object] returns the result of the call.
|
270
|
+
def transact(contract, function_name, *args, **kwargs)
|
271
|
+
gas_limit = Tx.estimate_intrinsic_gas(contract.bin) + Tx::CREATE_GAS
|
272
|
+
fun = contract.functions.select { |func| func.name == function_name }[0]
|
273
|
+
params = {
|
274
|
+
value: 0,
|
275
|
+
gas_limit: gas_limit,
|
276
|
+
chain_id: chain_id,
|
277
|
+
to: kwargs[:address] || contract.address,
|
278
|
+
data: call_payload(fun, args),
|
279
|
+
}
|
280
|
+
if kwargs[:legacy]
|
281
|
+
params.merge!({
|
282
|
+
gas_price: max_fee_per_gas,
|
283
|
+
})
|
284
|
+
else
|
285
|
+
params.merge!({
|
286
|
+
priority_fee: max_priority_fee_per_gas,
|
287
|
+
max_gas_fee: max_fee_per_gas,
|
288
|
+
})
|
289
|
+
end
|
290
|
+
unless kwargs[:sender_key].nil?
|
291
|
+
# use the provided key as sender and signer
|
292
|
+
params.merge!({
|
293
|
+
from: kwargs[:sender_key].address,
|
294
|
+
nonce: get_nonce(kwargs[:sender_key].address),
|
295
|
+
})
|
296
|
+
tx = Eth::Tx.new(params)
|
297
|
+
tx.sign kwargs[:sender_key]
|
298
|
+
return eth_send_raw_transaction(tx.hex)["result"]
|
299
|
+
else
|
300
|
+
# use the default account as sender and external signer
|
301
|
+
params.merge!({
|
302
|
+
from: default_account,
|
303
|
+
nonce: get_nonce(default_account),
|
304
|
+
})
|
305
|
+
return eth_send_transaction(params)["result"]
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
# Executes a contract function with a transaction and waits for it
|
310
|
+
# to be mined (transactional contract read/write).
|
311
|
+
#
|
312
|
+
# @overload transact_and_wait(contract, function_name)
|
313
|
+
# @param contract [Eth::Contract] subject contract to call.
|
314
|
+
# @param function_name [String] method name to be called.
|
315
|
+
# @overload transact_and_wait(contract, function_name, value)
|
316
|
+
# @param contract [Eth::Contract] subject contract to call.
|
317
|
+
# @param function_name [String] method name to be called.
|
318
|
+
# @param value [Integer|String] function arguments.
|
319
|
+
# @overload transact_and_wait(contract, function_name, value, sender_key, legacy, address)
|
320
|
+
# @param contract [Eth::Contract] subject contract to call.
|
321
|
+
# @param function_name [String] method name to be called.
|
322
|
+
# @param value [Integer|String] function arguments.
|
323
|
+
# @param sender_key [Eth::Key] the sender private key.
|
324
|
+
# @param legacy [Boolean] enables legacy transactions (pre-EIP-1559).
|
325
|
+
# @param address [String] contract address.
|
326
|
+
# @return [Object] returns the result of the call.
|
327
|
+
def transact_and_wait(contract, function_name, *args, **kwargs)
|
328
|
+
wait_for_tx(transact(contract, function_name, *args, **kwargs))
|
329
|
+
end
|
330
|
+
|
331
|
+
# Provides an interface to call `isValidSignature` as per EIP-1271 on a given
|
332
|
+
# smart contract to verify the given hash and signature matching the magic
|
333
|
+
# value.
|
334
|
+
#
|
335
|
+
# @param contract [Eth::Contract] a deployed contract implementing EIP-1271.
|
336
|
+
# @param hash [String] the message hash to be checked against the signature.
|
337
|
+
# @param signature [String] the signature to be recovered by the contract.
|
338
|
+
# @param magic [String] the expected magic value (defaults to `1626ba7e`).
|
339
|
+
# @return [Boolean] true if magic matches and signature is valid.
|
340
|
+
# @raise [ArgumentError] in case the contract cannot be called yet.
|
341
|
+
def is_valid_signature(contract, hash, signature, magic = "1626ba7e")
|
342
|
+
raise ArgumentError, "Contract not deployed yet." if contract.address.nil?
|
343
|
+
hash = Util.hex_to_bin hash if Util.is_hex? hash
|
344
|
+
signature = Util.hex_to_bin signature if Util.is_hex? signature
|
345
|
+
magic = Util.hex_to_bin magic if Util.is_hex? magic
|
346
|
+
result = call(contract, "isValidSignature", hash, signature)
|
347
|
+
return result === magic
|
348
|
+
end
|
349
|
+
|
152
350
|
# Gives control over resetting the RPC request ID back to zero.
|
153
351
|
# Usually not needed.
|
154
352
|
#
|
@@ -169,7 +367,7 @@ module Eth
|
|
169
367
|
# Waits for an transaction to be mined by the connected chain.
|
170
368
|
#
|
171
369
|
# @param hash [String] the transaction hash.
|
172
|
-
# @return [String] the
|
370
|
+
# @return [String] the transaction hash once the transaction is mined.
|
173
371
|
# @raise [Timeout::Error] if it's not mined within 5 minutes.
|
174
372
|
def wait_for_tx(hash)
|
175
373
|
start_time = Time.now
|
@@ -193,6 +391,55 @@ module Eth
|
|
193
391
|
|
194
392
|
private
|
195
393
|
|
394
|
+
# Non-transactional function call called from call().
|
395
|
+
def call_raw(contract, func, *args, **kwargs)
|
396
|
+
gas_limit = Tx.estimate_intrinsic_gas(contract.bin) + Tx::CREATE_GAS
|
397
|
+
params = {
|
398
|
+
gas_limit: gas_limit,
|
399
|
+
chain_id: chain_id,
|
400
|
+
data: call_payload(func, args),
|
401
|
+
}
|
402
|
+
if kwargs[:address] || contract.address
|
403
|
+
params.merge!({ to: kwargs[:address] || contract.address })
|
404
|
+
end
|
405
|
+
if kwargs[:legacy]
|
406
|
+
params.merge!({
|
407
|
+
gas_price: max_fee_per_gas,
|
408
|
+
})
|
409
|
+
else
|
410
|
+
params.merge!({
|
411
|
+
priority_fee: max_priority_fee_per_gas,
|
412
|
+
max_gas_fee: max_fee_per_gas,
|
413
|
+
})
|
414
|
+
end
|
415
|
+
unless kwargs[:sender_key].nil?
|
416
|
+
# Uses the provided key as sender and signer
|
417
|
+
params.merge!({
|
418
|
+
from: kwargs[:sender_key].address,
|
419
|
+
nonce: get_nonce(kwargs[:sender_key].address),
|
420
|
+
})
|
421
|
+
tx = Eth::Tx.new(params)
|
422
|
+
tx.sign kwargs[:sender_key]
|
423
|
+
end
|
424
|
+
raw_result = eth_call(params)["result"]
|
425
|
+
types = func.outputs.map { |i| i.type }
|
426
|
+
return nil if raw_result == "0x"
|
427
|
+
Eth::Abi.decode(types, raw_result)
|
428
|
+
end
|
429
|
+
|
430
|
+
# Encodes function call payloads.
|
431
|
+
def call_payload(fun, args)
|
432
|
+
types = fun.inputs.map { |i| i.type }
|
433
|
+
encoded_str = Util.bin_to_hex(Eth::Abi.encode(types, args))
|
434
|
+
"0x" + fun.signature + (encoded_str.empty? ? "0" * 64 : encoded_str)
|
435
|
+
end
|
436
|
+
|
437
|
+
# Encodes constructor params
|
438
|
+
def encode_constructor_params(contract, args)
|
439
|
+
types = contract.constructor_inputs.map { |input| input.type }
|
440
|
+
Util.bin_to_hex(Eth::Abi.encode(types, args))
|
441
|
+
end
|
442
|
+
|
196
443
|
# Prepares parameters and sends the command to the client.
|
197
444
|
def send_command(command, args)
|
198
445
|
args << "latest" if ["eth_getBalance", "eth_call"].include? command
|
@@ -230,3 +477,7 @@ module Eth
|
|
230
477
|
end
|
231
478
|
end
|
232
479
|
end
|
480
|
+
|
481
|
+
# Load the client/* libraries
|
482
|
+
require "eth/client/http"
|
483
|
+
require "eth/client/ipc"
|
@@ -0,0 +1,42 @@
|
|
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
|
+
# Provide classes for contract event.
|
21
|
+
class Contract::Event
|
22
|
+
attr_accessor :name, :signature, :input_types, :inputs, :event_string, :address
|
23
|
+
|
24
|
+
# Constructor of the {Eth::Contract::Event} class.
|
25
|
+
#
|
26
|
+
# @param data [Hash] contract event data.
|
27
|
+
def initialize(data)
|
28
|
+
@name = data["name"]
|
29
|
+
@input_types = data["inputs"].collect { |x| x["type"] }
|
30
|
+
@inputs = data["inputs"].collect { |x| x["name"] }
|
31
|
+
@event_string = "#{@name}(#{@input_types.join(",")})"
|
32
|
+
@signature = Digest::Keccak.hexdigest(@event_string, 256)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Set the address of the smart contract
|
36
|
+
#
|
37
|
+
# @param address [String] contract address.
|
38
|
+
def set_address(address)
|
39
|
+
@address = address.nil? ? nil : Eth::Address.new(address).address
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,57 @@
|
|
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 the methods for smart contract function.
|
21
|
+
class Contract::Function
|
22
|
+
attr_accessor :name, :inputs, :outputs, :signature, :constant, :function_string
|
23
|
+
|
24
|
+
# Constructor of the {Eth::Function} class.
|
25
|
+
#
|
26
|
+
# @param data [Hash] function input and output data.
|
27
|
+
def initialize(data)
|
28
|
+
@name = data["name"]
|
29
|
+
@constant = data["constant"]
|
30
|
+
@inputs = data["inputs"].map do |input|
|
31
|
+
Eth::Contract::FunctionInput.new(input)
|
32
|
+
end
|
33
|
+
@outputs = data["outputs"].collect do |output|
|
34
|
+
Eth::Contract::FunctionOutput.new(output)
|
35
|
+
end
|
36
|
+
@function_string = self.class.calc_signature(@name, @inputs)
|
37
|
+
@signature = self.class.encoded_function_signature(@function_string)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Creates function strings.
|
41
|
+
#
|
42
|
+
# @param name [String] function name.
|
43
|
+
# @param inputs [Array<Eth::Contract::FunctionInput>] function input class list.
|
44
|
+
# @return [String] function string.
|
45
|
+
def self.calc_signature(name, inputs)
|
46
|
+
"#{name}(#{inputs.collect { |x| x.type }.join(",")})"
|
47
|
+
end
|
48
|
+
|
49
|
+
# Encodes a function signature.
|
50
|
+
#
|
51
|
+
# @param signature [String] function signature.
|
52
|
+
# @return [String] encoded function signature string.
|
53
|
+
def self.encoded_function_signature(signature)
|
54
|
+
Util.bin_to_hex Util.keccak256(signature)[0..3]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,37 @@
|
|
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
|
+
# Provide classes for contract function input.
|
21
|
+
class Contract::FunctionInput
|
22
|
+
attr_accessor :type, :name
|
23
|
+
|
24
|
+
# Constructor of the {Eth::Contract::FunctionInput} class.
|
25
|
+
#
|
26
|
+
# @param data [Hash] contract abi data.
|
27
|
+
def initialize(data)
|
28
|
+
@type = Eth::Abi::Type.parse(data["type"])
|
29
|
+
@name = data["name"]
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns complete types with subtypes, e.g., `uint256`.
|
33
|
+
def type
|
34
|
+
@type.base_type + @type.sub_type
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,37 @@
|
|
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
|
+
# Provide classes for contract function output.
|
21
|
+
class Contract::FunctionOutput
|
22
|
+
attr_accessor :type, :name
|
23
|
+
|
24
|
+
# Constructor of the {Eth::Contract::FunctionOutput} class.
|
25
|
+
#
|
26
|
+
# @param data [Hash] contract abi data.
|
27
|
+
def initialize(data)
|
28
|
+
@type = Eth::Abi::Type.parse(data["type"])
|
29
|
+
@name = data["name"]
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns complete types with subtypes, e.g., `uint256`.
|
33
|
+
def type
|
34
|
+
@type.base_type + @type.sub_type
|
35
|
+
end
|
36
|
+
end
|
37
|
+
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
|
+
# -*- encoding : ascii-8bit -*-
|
16
|
+
|
17
|
+
# Provides the {Eth} module.
|
18
|
+
module Eth
|
19
|
+
|
20
|
+
# Provide classes for contract initializer.
|
21
|
+
class Contract::Initializer
|
22
|
+
attr_accessor :contracts, :file
|
23
|
+
|
24
|
+
# Constructor of the {Eth::Contract::Initializer} class.
|
25
|
+
#
|
26
|
+
# @param file [String] file path to solidity code.
|
27
|
+
def initialize(file)
|
28
|
+
sol_output = Eth::Solidity.new.compile(file)
|
29
|
+
contracts = sol_output.keys
|
30
|
+
|
31
|
+
@contracts = []
|
32
|
+
contracts.each do |contract|
|
33
|
+
abi = sol_output[contract]["abi"]
|
34
|
+
name = contract
|
35
|
+
code = sol_output[contract]["bin"]
|
36
|
+
@contracts << Contract.new(name, code, abi)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Builds and returns all contracts.
|
41
|
+
def build_all
|
42
|
+
@contracts.each do |contract|
|
43
|
+
contract.build
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/eth/contract.rb
ADDED
@@ -0,0 +1,143 @@
|
|
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 classes to access smart contracts
|
21
|
+
class Contract
|
22
|
+
attr_reader :address
|
23
|
+
attr_accessor :key
|
24
|
+
attr_accessor :gas_limit, :gas_price, :max_fee_per_gas, :max_priority_fee_per_gas, :nonce
|
25
|
+
attr_accessor :bin, :name, :abi, :class_object
|
26
|
+
attr_accessor :events, :functions, :constructor_inputs
|
27
|
+
|
28
|
+
# Constructor of the {Eth::Contract} class.
|
29
|
+
#
|
30
|
+
# @param name [String] contract name.
|
31
|
+
# @param bin [String] contract bin string.
|
32
|
+
# @param abi [String] contract abi string.
|
33
|
+
def initialize(name, bin, abi)
|
34
|
+
@name = name
|
35
|
+
@bin = bin
|
36
|
+
@abi = abi
|
37
|
+
@constructor_inputs, @functions, @events = parse_abi(abi)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Creates a contract wrapper from a Solidity file.
|
41
|
+
#
|
42
|
+
# @param file [String] solidity file path.
|
43
|
+
# @param contract_index [Number] specify contract.
|
44
|
+
# @return [Eth::Contract::Object] Returns the class of the smart contract.
|
45
|
+
# @raise [ArgumentError] if the file path is empty or no contracts were compiled.
|
46
|
+
def self.from_file(file:, contract_index: 0)
|
47
|
+
raise ArgumentError, "Cannot find the contract at #{file.to_s}!" if !File.exist?(file.to_s)
|
48
|
+
contracts = Eth::Contract::Initializer.new(file).build_all
|
49
|
+
raise ArgumentError, "No contracts compiled." if contracts.empty?
|
50
|
+
contracts[contract_index].class_object.new
|
51
|
+
end
|
52
|
+
|
53
|
+
# Creates a contract wrapper from ABI and address.
|
54
|
+
#
|
55
|
+
# @param abi [String] contract abi string.
|
56
|
+
# @param address [String] contract address.
|
57
|
+
# @param name [String] name of contract.
|
58
|
+
# @return [Eth::Contract::Object] Returns the class of the smart contract.
|
59
|
+
# @raise [JSON::ParserError] if the json format is wrong.
|
60
|
+
# @raise [ArgumentError] if ABI, address, or name is missing.
|
61
|
+
def self.from_abi(abi:, address:, name:)
|
62
|
+
abi = abi.is_a?(Array) ? abi : JSON.parse(abi)
|
63
|
+
contract = Eth::Contract.new(name, nil, abi)
|
64
|
+
contract.build
|
65
|
+
contract = contract.class_object.new
|
66
|
+
contract.address = address
|
67
|
+
contract
|
68
|
+
end
|
69
|
+
|
70
|
+
# Creates a contract wrapper from binary and ABI.
|
71
|
+
#
|
72
|
+
# @param bin [String] contract bin string.
|
73
|
+
# @param abi [String] contract abi string.
|
74
|
+
# @param name [String] name of contract.
|
75
|
+
# @return [Eth::Contract::Object] Returns the class of the smart contract.
|
76
|
+
# @raise [JSON::ParserError] if the json format is wrong.
|
77
|
+
# @raise [ArgumentError] if ABI, binary, or name is missing.
|
78
|
+
def self.from_bin(bin:, abi:, name:)
|
79
|
+
abi = abi.is_a?(Array) ? abi : JSON.parse(abi)
|
80
|
+
contract = Eth::Contract.new(name, bin, abi)
|
81
|
+
contract.build
|
82
|
+
contract.class_object.new
|
83
|
+
end
|
84
|
+
|
85
|
+
# Sets the address of the smart contract.
|
86
|
+
#
|
87
|
+
# @param addr [String|Eth::Address] contract address string.
|
88
|
+
def address=(addr)
|
89
|
+
if addr.is_a? Eth::Address
|
90
|
+
@address = addr.to_s
|
91
|
+
else
|
92
|
+
@address = Eth::Address.new(addr).to_s
|
93
|
+
end
|
94
|
+
@events.each do |event|
|
95
|
+
event.set_address(@address)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Create meta classes for smart contracts.
|
100
|
+
def build
|
101
|
+
class_name = @name
|
102
|
+
parent = self
|
103
|
+
class_methods = Class.new do
|
104
|
+
extend Forwardable
|
105
|
+
def_delegators :parent, :key, :key=
|
106
|
+
def_delegators :parent, :name, :abi, :bin
|
107
|
+
def_delegators :parent, :gas_limit, :gas_price, :gas_limit=, :gas_price=, :nonce, :nonce=
|
108
|
+
def_delegators :parent, :max_fee_per_gas, :max_fee_per_gas=, :max_priority_fee_per_gas, :max_priority_fee_per_gas=
|
109
|
+
def_delegators :parent, :events
|
110
|
+
def_delegators :parent, :address, :address=
|
111
|
+
def_delegator :parent, :functions
|
112
|
+
def_delegator :parent, :constructor_inputs
|
113
|
+
define_method :parent do
|
114
|
+
parent
|
115
|
+
end
|
116
|
+
end
|
117
|
+
Eth::Contract.send(:remove_const, class_name) if Eth::Contract.const_defined?(class_name, false)
|
118
|
+
Eth::Contract.const_set(class_name, class_methods)
|
119
|
+
@class_object = class_methods
|
120
|
+
end
|
121
|
+
|
122
|
+
private
|
123
|
+
|
124
|
+
def parse_abi(abi)
|
125
|
+
constructor = abi.detect { |x| x["type"] == "constructor" }
|
126
|
+
if !constructor.nil?
|
127
|
+
constructor_inputs = constructor["inputs"].map { |input| Eth::Contract::FunctionInput.new(input) }
|
128
|
+
else
|
129
|
+
constructor_inputs = []
|
130
|
+
end
|
131
|
+
functions = abi.select { |x| x["type"] == "function" }.map { |fun| Eth::Contract::Function.new(fun) }
|
132
|
+
events = abi.select { |x| x["type"] == "event" }.map { |evt| Eth::Contract::Event.new(evt) }
|
133
|
+
[constructor_inputs, functions, events]
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
# Load the contract/* libraries
|
139
|
+
require "eth/contract/event"
|
140
|
+
require "eth/contract/function"
|
141
|
+
require "eth/contract/function_input"
|
142
|
+
require "eth/contract/function_output"
|
143
|
+
require "eth/contract/initializer"
|
data/lib/eth/rlp/sedes/binary.rb
CHANGED
@@ -29,7 +29,7 @@ module Eth
|
|
29
29
|
# A singleton class for binary values of fixed length.
|
30
30
|
class << self
|
31
31
|
|
32
|
-
# Create a serializable
|
32
|
+
# Create a serializable binary of fixed size.
|
33
33
|
#
|
34
34
|
# @param l [Integer] the fixed size of the binary.
|
35
35
|
# @param allow_empty [Boolean] indicator wether empty binaries should be allowed.
|
@@ -47,7 +47,7 @@ module Eth
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
# Create a serializable
|
50
|
+
# Create a serializable binary of variable size.
|
51
51
|
#
|
52
52
|
# @param min_length [Integer] the minimum size of the binary.
|
53
53
|
# @param max_length [Integer] the maximum size of the binary.
|
data/lib/eth/tx.rb
CHANGED
@@ -69,13 +69,16 @@ module Eth
|
|
69
69
|
# The zero byte is 0x00.
|
70
70
|
ZERO_BYTE = "\x00".freeze
|
71
71
|
|
72
|
+
# Smart contract transaction gas cost
|
73
|
+
CREATE_GAS = 32_000.freeze
|
74
|
+
|
72
75
|
# Creates a new transaction of any type for given parameters and chain ID.
|
73
76
|
# Required parameters are (optional in brackets):
|
74
77
|
# - EIP-1559: chain_id, nonce, priority_fee, max_gas_fee, gas_limit(, from, to,
|
75
78
|
# value, data, access_list)
|
76
79
|
# - EIP-2930: chain_id, nonce, gas_price, gas_limit, access_list(, from, to,
|
77
80
|
# value, data)
|
78
|
-
# - Legacy: nonce, gas_price,
|
81
|
+
# - Legacy: nonce, gas_price, gas_limit(, from, to, value, data)
|
79
82
|
#
|
80
83
|
# @param params [Hash] all necessary transaction fields.
|
81
84
|
# @param chain_id [Integer] the EIP-155 Chain ID (legacy transactions only).
|
data/lib/eth/version.rb
CHANGED
data/lib/eth.rb
CHANGED
@@ -22,9 +22,8 @@ require "eth/api"
|
|
22
22
|
require "eth/address"
|
23
23
|
require "eth/chain"
|
24
24
|
require "eth/constant"
|
25
|
+
require "eth/contract"
|
25
26
|
require "eth/client"
|
26
|
-
require "eth/client/http"
|
27
|
-
require "eth/client/ipc"
|
28
27
|
require "eth/eip712"
|
29
28
|
require "eth/key"
|
30
29
|
require "eth/rlp"
|
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.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Ellis
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-
|
12
|
+
date: 2022-05-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: keccak
|
@@ -57,16 +57,22 @@ dependencies:
|
|
57
57
|
name: openssl
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
59
59
|
requirements:
|
60
|
-
- - "
|
60
|
+
- - ">="
|
61
61
|
- !ruby/object:Gem::Version
|
62
62
|
version: '2.2'
|
63
|
+
- - "<"
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '4.0'
|
63
66
|
type: :runtime
|
64
67
|
prerelease: false
|
65
68
|
version_requirements: !ruby/object:Gem::Requirement
|
66
69
|
requirements:
|
67
|
-
- - "
|
70
|
+
- - ">="
|
68
71
|
- !ruby/object:Gem::Version
|
69
72
|
version: '2.2'
|
73
|
+
- - "<"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '4.0'
|
70
76
|
- !ruby/object:Gem::Dependency
|
71
77
|
name: scrypt
|
72
78
|
requirement: !ruby/object:Gem::Requirement
|
@@ -89,6 +95,7 @@ executables: []
|
|
89
95
|
extensions: []
|
90
96
|
extra_rdoc_files: []
|
91
97
|
files:
|
98
|
+
- ".github/dependabot.yml"
|
92
99
|
- ".github/workflows/codeql.yml"
|
93
100
|
- ".github/workflows/docs.yml"
|
94
101
|
- ".github/workflows/spec.yml"
|
@@ -108,6 +115,7 @@ files:
|
|
108
115
|
- eth.gemspec
|
109
116
|
- lib/eth.rb
|
110
117
|
- lib/eth/abi.rb
|
118
|
+
- lib/eth/abi/event.rb
|
111
119
|
- lib/eth/abi/type.rb
|
112
120
|
- lib/eth/address.rb
|
113
121
|
- lib/eth/api.rb
|
@@ -116,6 +124,12 @@ files:
|
|
116
124
|
- lib/eth/client/http.rb
|
117
125
|
- lib/eth/client/ipc.rb
|
118
126
|
- lib/eth/constant.rb
|
127
|
+
- lib/eth/contract.rb
|
128
|
+
- lib/eth/contract/event.rb
|
129
|
+
- lib/eth/contract/function.rb
|
130
|
+
- lib/eth/contract/function_input.rb
|
131
|
+
- lib/eth/contract/function_output.rb
|
132
|
+
- lib/eth/contract/initializer.rb
|
119
133
|
- lib/eth/eip712.rb
|
120
134
|
- lib/eth/key.rb
|
121
135
|
- lib/eth/key/decrypter.rb
|