eth 0.5.0 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/codeql.yml +4 -0
- data/.github/workflows/spec.yml +14 -3
- data/.yardopts +1 -0
- data/AUTHORS.txt +14 -1
- data/CHANGELOG.md +63 -13
- data/README.md +121 -18
- data/bin/console +2 -1
- data/bin/setup +3 -4
- data/codecov.yml +6 -0
- data/eth.gemspec +5 -7
- data/lib/eth/abi/event.rb +137 -0
- data/lib/eth/abi/type.rb +8 -7
- data/lib/eth/abi.rb +29 -11
- data/lib/eth/address.rb +12 -5
- data/lib/eth/api.rb +223 -0
- data/lib/eth/chain.rb +31 -28
- data/lib/eth/client/http.rb +63 -0
- data/lib/eth/client/ipc.rb +50 -0
- data/lib/eth/client.rb +468 -0
- data/lib/eth/constant.rb +71 -0
- data/lib/eth/contract/event.rb +41 -0
- data/lib/eth/contract/function.rb +56 -0
- data/lib/eth/contract/function_input.rb +36 -0
- data/lib/eth/contract/function_output.rb +32 -0
- data/lib/eth/contract/initializer.rb +46 -0
- data/lib/eth/contract.rb +120 -0
- data/lib/eth/eip712.rb +2 -2
- data/lib/eth/key/decrypter.rb +16 -13
- data/lib/eth/key/encrypter.rb +27 -25
- data/lib/eth/key.rb +21 -16
- data/lib/eth/rlp/decoder.rb +114 -0
- data/lib/eth/rlp/encoder.rb +78 -0
- data/lib/eth/rlp/sedes/big_endian_int.rb +66 -0
- data/lib/eth/rlp/sedes/binary.rb +97 -0
- data/lib/eth/rlp/sedes/list.rb +84 -0
- data/lib/eth/rlp/sedes.rb +74 -0
- data/lib/eth/rlp.rb +63 -0
- data/lib/eth/signature.rb +11 -8
- data/lib/eth/solidity.rb +75 -0
- data/lib/eth/tx/eip1559.rb +22 -14
- data/lib/eth/tx/eip2930.rb +23 -15
- data/lib/eth/tx/legacy.rb +14 -10
- data/lib/eth/tx.rb +28 -34
- data/lib/eth/unit.rb +1 -1
- data/lib/eth/util.rb +68 -11
- data/lib/eth/version.rb +3 -3
- data/lib/eth.rb +15 -2
- metadata +31 -23
- data/lib/eth/abi/constant.rb +0 -63
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0375271f13b257337cbc0ab138c2cdf972de8f8e03cf60bb9b672b2221ac988d
|
4
|
+
data.tar.gz: 19e85a6be34904b5544d9c6845ae19231616d65f27a8146c747f66068f2c23db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5cc31684e8dfbff08b7250436a0bd4a94fa90942fd27b03292806cf2ac190673f1e507d8bcabd80b968a7206401a5210298c75c1ecc7c1d94765a7e94654d0d
|
7
|
+
data.tar.gz: 11b5a667d5cb333848aee384f4276fb3982a69104ae43c9650aec572ec3d093601c44b1b33167029b3ea37bcba6d8fd46da795ada67f6ad50fc39550fd092434
|
data/.github/workflows/spec.yml
CHANGED
@@ -26,11 +26,22 @@ jobs:
|
|
26
26
|
with:
|
27
27
|
ruby-version: ${{ matrix.ruby }}
|
28
28
|
bundler-cache: false
|
29
|
-
- name:
|
29
|
+
- name: MacOs Dependencies
|
30
30
|
run: |
|
31
|
-
brew
|
31
|
+
brew tap ethereum/ethereum
|
32
|
+
brew install --verbose pkg-config automake autogen ethereum solidity
|
32
33
|
if: startsWith(matrix.os, 'macOS')
|
33
|
-
- name:
|
34
|
+
- name: Ubuntu Dependencies
|
35
|
+
run: |
|
36
|
+
sudo add-apt-repository -y ppa:ethereum/ethereum
|
37
|
+
sudo apt-get update
|
38
|
+
sudo apt-get install ethereum solc
|
39
|
+
if: startsWith(matrix.os, 'Ubuntu')
|
40
|
+
- name: Run Geth
|
41
|
+
run: |
|
42
|
+
geth --dev --http --ipcpath /tmp/geth.ipc &
|
43
|
+
disown &
|
44
|
+
- name: Gem Dependencies
|
34
45
|
run: |
|
35
46
|
git submodule update --init
|
36
47
|
bundle install
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--verbose --fail-on-warning --markup markdown --embed-mixins
|
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,7 +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
|
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
|
25
|
+
|
26
|
+
The latest version of the Ruby-Eth gem contains a condensed version of the
|
27
|
+
RLP gem by Jan Xie (@janx) and Zhang Yaning (@u2) licensed under MIT
|
28
|
+
conditions:
|
29
|
+
* https://github.com/cryptape/ruby-rlp
|
data/CHANGELOG.md
CHANGED
@@ -1,25 +1,75 @@
|
|
1
1
|
# Change Log
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
## [0.5.1]
|
5
|
+
### Changed
|
6
|
+
- Docs: update changelog ([#61](https://github.com/q9f/eth.rb/pull/61))
|
7
|
+
- Eth/chain: add sepolia chain id; docs ([#60](https://github.com/q9f/eth.rb/pull/60))
|
8
|
+
- 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
|
+
- Eth/tx: properly serialize signatures ([#58](https://github.com/q9f/eth.rb/pull/58))
|
11
|
+
- Eth/client: fix legacy transfer ([#57](https://github.com/q9f/eth.rb/pull/57))
|
12
|
+
- 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
|
+
- Docs: update changelog ([#53](https://github.com/q9f/eth.rb/pull/53))
|
15
|
+
- Spec: add upstream test fixtures for keystore ([#50](https://github.com/q9f/eth.rb/pull/50))
|
16
|
+
|
17
|
+
## [0.5.0]
|
18
|
+
### Changed
|
19
|
+
- Docs: update readme with features [#49](https://github.com/q9f/eth.rb/pull/49)
|
20
|
+
- Eth/tx: add method to estimate intrinsic gas costs [#48](https://github.com/q9f/eth.rb/pull/48)
|
21
|
+
- Eth/key: allow chain_id empty for signing messages/data [#47](https://github.com/q9f/eth.rb/pull/47)
|
22
|
+
- Gem: prepare for release [#46](https://github.com/q9f/eth.rb/pull/46)
|
23
|
+
- Eth/sig: allow v values > 0xff, fix #30 [#43](https://github.com/q9f/eth.rb/pull/43)
|
24
|
+
- Eth/abi: refactor for maintainability [#42](https://github.com/q9f/eth.rb/pull/42)
|
25
|
+
- Docs: improve readme [#41](https://github.com/q9f/eth.rb/pull/41)
|
26
|
+
- Lib: improve error handling [#39](https://github.com/q9f/eth.rb/pull/39)
|
27
|
+
- Docs: update readme for tx and keys [#40](https://github.com/q9f/eth.rb/pull/40)
|
28
|
+
- 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
|
+
- 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
|
+
- Rename util and chain to singular [#26](https://github.com/q9f/eth.rb/pull/26)
|
34
|
+
- Docs: add some examples to readme [#25](https://github.com/q9f/eth.rb/pull/25)
|
35
|
+
- Key/signature: personal sign and verify [#24](https://github.com/q9f/eth.rb/pull/24)
|
36
|
+
- Ci: only run coverage on CI [#23](https://github.com/q9f/eth.rb/pull/23)
|
37
|
+
- 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
|
+
- Eth/util: public_key_to_address should return an eth::address [#19](https://github.com/q9f/eth.rb/pull/19)
|
40
|
+
- Ci: add docs workflow [#18](https://github.com/q9f/eth.rb/pull/18)
|
41
|
+
- Address class implementation and tests [#13](https://github.com/q9f/eth.rb/pull/13)
|
42
|
+
- Spec: improve util tests [#12](https://github.com/q9f/eth.rb/pull/12)
|
43
|
+
- Spec: improve key tests [#11](https://github.com/q9f/eth.rb/pull/11)
|
44
|
+
- Gems: bump keccak and secp256k1 [#10](https://github.com/q9f/eth.rb/pull/10)
|
45
|
+
- Docs: add code climate badge [#8](https://github.com/q9f/eth.rb/pull/8)
|
46
|
+
- Ci: enable codecov [#7](https://github.com/q9f/eth.rb/pull/7)
|
47
|
+
- Docs: add AUTHORS file [#6](https://github.com/q9f/eth.rb/pull/6)
|
48
|
+
- Lib: implement Eth::Key class [#4](https://github.com/q9f/eth.rb/pull/4)
|
49
|
+
- Ci: add nightly schedule [#2](https://github.com/q9f/eth.rb/pull/2)
|
50
|
+
- Reset gem to point blank [#1](https://github.com/q9f/eth.rb/pull/1)
|
51
|
+
|
52
|
+
## [0.4.18]
|
53
|
+
### Changed
|
54
|
+
- CI: add yard doc and rufo workflows [se3000/ruby-eth#75](https://github.com/se3000/ruby-eth/pull/75)
|
55
|
+
- Gem: run rufo [se3000/ruby-eth#74](https://github.com/se3000/ruby-eth/pull/74)
|
56
|
+
- Gem: dependencies [se3000/ruby-eth#73](https://github.com/se3000/ruby-eth/pull/73)
|
57
|
+
- Lib: fix compatibility with libressl (macos) and openssl 1.1.1k [se3000/ruby-eth#66](https://github.com/se3000/ruby-eth/pull/66)
|
8
58
|
|
9
59
|
## [0.4.17]
|
10
60
|
### Changed
|
11
|
-
- Gems: bump version to 0.4.17 [#70](https://github.com/se3000/ruby-eth/pull/70)
|
12
|
-
- Gems: bump keccak to 1.3.0 [#69](https://github.com/se3000/ruby-eth/pull/69)
|
61
|
+
- Gems: bump version to 0.4.17 [se3000/ruby-eth#70](https://github.com/se3000/ruby-eth/pull/70)
|
62
|
+
- Gems: bump keccak to 1.3.0 [se3000/ruby-eth#69](https://github.com/se3000/ruby-eth/pull/69)
|
13
63
|
|
14
64
|
## [0.4.16]
|
15
65
|
### Changed
|
16
|
-
- Docs: update changelog [#65](https://github.com/se3000/ruby-eth/pull/65)
|
17
|
-
- Gems: bump version to 0.4.16 [#65](https://github.com/se3000/ruby-eth/pull/65)
|
18
|
-
- License: update copyright notice [#64](https://github.com/se3000/ruby-eth/pull/64)
|
19
|
-
- Docs: add badges to readme [#64](https://github.com/se3000/ruby-eth/pull/64)
|
20
|
-
- Git: deprecating master [#63](https://github.com/se3000/ruby-eth/pull/63)
|
21
|
-
- CI: replace travis with github actions [#62](https://github.com/se3000/ruby-eth/pull/62)
|
22
|
-
- Gems: replace digest-sha3-patched with keccak [#58](https://github.com/se3000/ruby-eth/pull/58)
|
66
|
+
- Docs: update changelog [se3000/ruby-eth#65](https://github.com/se3000/ruby-eth/pull/65)
|
67
|
+
- Gems: bump version to 0.4.16 [se3000/ruby-eth#65](https://github.com/se3000/ruby-eth/pull/65)
|
68
|
+
- License: update copyright notice [se3000/ruby-eth#64](https://github.com/se3000/ruby-eth/pull/64)
|
69
|
+
- Docs: add badges to readme [se3000/ruby-eth#64](https://github.com/se3000/ruby-eth/pull/64)
|
70
|
+
- Git: deprecating master [se3000/ruby-eth#63](https://github.com/se3000/ruby-eth/pull/63)
|
71
|
+
- CI: replace travis with github actions [se3000/ruby-eth#62](https://github.com/se3000/ruby-eth/pull/62)
|
72
|
+
- Gems: replace digest-sha3-patched with keccak [se3000/ruby-eth#58](https://github.com/se3000/ruby-eth/pull/58)
|
23
73
|
|
24
74
|
## [0.4.13], [0.4.14], [0.4.15]
|
25
75
|
_Released as [`eth-patched`](https://github.com/q9f/ruby-eth) from a different source tree._
|
data/README.md
CHANGED
@@ -1,16 +1,19 @@
|
|
1
|
-
#
|
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
|
-
[![
|
10
|
-
[![
|
11
|
-
[![
|
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
|
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)
|
@@ -23,11 +26,12 @@ What you get:
|
|
23
26
|
- [x] EIP-2718 Ethereum Transaction Envelopes (and types)
|
24
27
|
- [x] EIP-2930 Ethereum Type-1 Transactions (with access lists)
|
25
28
|
- [x] ABI-Encoder and Decoder (including type parser)
|
29
|
+
- [x] RLP-Encoder and Decoder (including sedes)
|
30
|
+
- [x] RPC-Client (IPC/HTTP) for Execution-Layer APIs
|
31
|
+
- [x] Solidity bindings (compile contracts from Ruby)
|
26
32
|
|
27
33
|
Soon (TM):
|
28
|
-
- [ ]
|
29
|
-
- [ ] RPC-Client (HTTP) for Execution APIs and Consensus APIs
|
30
|
-
- [ ] Smart Contracts and Solidity Support
|
34
|
+
- [ ] Smart Contract Support
|
31
35
|
- [ ] EIP-1271 Smart-Contract Authentification
|
32
36
|
- [ ] HD-Wallets (BIP-32) and Mnemonics (BIP-39)
|
33
37
|
|
@@ -39,13 +43,16 @@ Contents:
|
|
39
43
|
- [2.3. Ethereum Chains (EIP-155)](#23-ethereum-chains-eip-155)
|
40
44
|
- [2.4. Ethereum Transactions (EIP-1559, EIP-2718, EIP-2930)](#24-ethereum-transactions-eip-1559-eip-2718-eip-2930)
|
41
45
|
- [2.5. Ethereum ABI Encoder and Decoder](#25-ethereum-abi-encoder-and-decoder)
|
46
|
+
- [2.6. Ethereum RLP Encoder and Decoder](#26-ethereum-rlp-encoder-and-decoder)
|
47
|
+
- [2.7. Ethereum RPC-Client](#27-ethereum-rpc-client)
|
48
|
+
- [2.8 Solidity Compiler Bindings](#28-solidity-compiler-bindings)
|
49
|
+
- [2.9 Interact with Smart Contract](#29-interact-with-smart-contract)
|
42
50
|
- [3. Documentation](#3-documentation)
|
43
51
|
- [4. Testing](#4-testing)
|
44
52
|
- [5. Contributing](#5-contributing)
|
45
53
|
- [6. License and Credits](#6-license-and-credits)
|
46
54
|
|
47
55
|
## 1. Installation
|
48
|
-
|
49
56
|
Add this line to your application's Gemfile:
|
50
57
|
|
51
58
|
```ruby
|
@@ -59,9 +66,13 @@ gem install eth
|
|
59
66
|
```
|
60
67
|
|
61
68
|
## 2. Usage
|
69
|
+
Check out
|
70
|
+
[![Yard Doc API](https://img.shields.io/badge/documentation-API-blue)](https://q9f.github.io/eth.rb)
|
71
|
+
and
|
72
|
+
[![Usage Wiki](https://img.shields.io/badge/usage-WIKI-blue)](https://github.com/q9f/eth.rb/wiki)
|
73
|
+
for full details.
|
62
74
|
|
63
75
|
### 2.1. Ethereum Keys and Addresses (EIP-55)
|
64
|
-
|
65
76
|
Generate a random Secp256k1 key-pair.
|
66
77
|
|
67
78
|
```ruby
|
@@ -93,7 +104,6 @@ address.checksummed # EIP 55
|
|
93
104
|
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.
|
94
105
|
|
95
106
|
### 2.2. Ethereum Signatures (EIP-191, EIP-712)
|
96
|
-
|
97
107
|
Manage keypairs to sign messages in EIP-191 (`personal_sign`) format or typed data in EIP-712 (`sign_typed_data`) format.
|
98
108
|
|
99
109
|
```ruby
|
@@ -125,7 +135,6 @@ Eth::Signature.verify "Hello World!", signature, address, Eth::Chain::GOERLI
|
|
125
135
|
See `/spec` or [Documentation](https://q9f.github.io/eth.rb/) for signing typed data as per EIP-712.
|
126
136
|
|
127
137
|
### 2.3. Ethereum Chains (EIP-155)
|
128
|
-
|
129
138
|
Manage Ethereum chain IDs for EIP-155 replay protection.
|
130
139
|
|
131
140
|
```ruby
|
@@ -140,7 +149,6 @@ chain_id = Eth::Chain.to_chain_id v
|
|
140
149
|
```
|
141
150
|
|
142
151
|
### 2.4. Ethereum Transactions (EIP-1559, EIP-2718, EIP-2930)
|
143
|
-
|
144
152
|
Create an EIP-1559-conform transaction:
|
145
153
|
|
146
154
|
```ruby
|
@@ -167,7 +175,6 @@ tx.hex
|
|
167
175
|
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.
|
168
176
|
|
169
177
|
### 2.5. Ethereum ABI Encoder and Decoder
|
170
|
-
|
171
178
|
Encode and decode Ethereum application binary interface data (ABI).
|
172
179
|
|
173
180
|
```ruby
|
@@ -177,8 +184,94 @@ Eth::Abi.decode(["string", "address"], "0000000000000000000000000000000000000000
|
|
177
184
|
# => ["Hello, Bob!", "0xd496b23d61f88a8c7758fca7560dcfac7b3b01f9"]
|
178
185
|
```
|
179
186
|
|
180
|
-
|
187
|
+
### 2.6. Ethereum RLP Encoder and Decoder
|
188
|
+
Serialize and deserialize Ethereum recursive-length prefix data (RLP).
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
Eth::Util.bin_to_hex Eth::Rlp.encode ["Hello, Bob!", "0xd496b23d61f88a8c7758fca7560dcfac7b3b01f9"]
|
192
|
+
# => "f78b48656c6c6f2c20426f6221aa307864343936623233643631663838613863373735386663613735363064636661633762336230316639"
|
193
|
+
Eth::Rlp.decode "f78b48656c6c6f2c20426f6221aa307864343936623233643631663838613863373735386663613735363064636661633762336230316639"
|
194
|
+
# => ["Hello, Bob!", "0xd496b23d61f88a8c7758fca7560dcfac7b3b01f9"]
|
195
|
+
```
|
181
196
|
|
197
|
+
Or ;-)
|
198
|
+
|
199
|
+
```ruby
|
200
|
+
Eth::Rlp.decode "c7c0c1c0c3c0c1c0"
|
201
|
+
# => [[], [[]], [[], [[]]]]
|
202
|
+
```
|
203
|
+
|
204
|
+
### 2.7. Ethereum RPC-Client
|
205
|
+
Create an IPC- or HTTP-RPC-API client to seamlessly query the chain state, e.g., Infura over HTTPS with access token:
|
206
|
+
|
207
|
+
```ruby
|
208
|
+
infura = Eth::Client.create "https://mainnet.infura.io/v3/#{access_token}"
|
209
|
+
# => #<Eth::Client::Http:0x000055d43f3ca460 @gas_limit=21000, @host="mainnet.infura.io", @id=0, @max_fee_per_gas=0.2e11, @max_priority_fee_per_gas=0, @port=443, @ssl=true, @uri=#<URI::HTTPS https://mainnet.infura.io/v3/31b...d93>>
|
210
|
+
deposit_contract = Eth::Address.new "0x00000000219ab540356cBB839Cbe05303d7705Fa"
|
211
|
+
# => #<Eth::Address:0x000055d43f381738 @address="0x00000000219ab540356cBB839Cbe05303d7705Fa">
|
212
|
+
infura.get_balance deposit_contract
|
213
|
+
# => 9087314000069000000000069
|
214
|
+
```
|
215
|
+
|
216
|
+
Or set up a local development environment with `geth --dev`:
|
217
|
+
|
218
|
+
```ruby
|
219
|
+
cli = Eth::Client.create "/tmp/geth.ipc"
|
220
|
+
# => #<Eth::Client::Ipc:0x000055d43f51c390 @gas_limit=21000, @id=0, @max_fee_per_gas=0.2e11, @max_priority_fee_per_gas=0, @path="/tmp/geth.ipc">
|
221
|
+
cli.eth_coinbase
|
222
|
+
# => {"jsonrpc"=>"2.0", "id"=>1, "result"=>"0x6868074fb21c48dfad0c448fbabd99383a6598e4"}
|
223
|
+
tx = cli.transfer_and_wait(Eth::Key.new.address, 1337 * Eth::Unit::ETHER)
|
224
|
+
# => "0x141c6dff40df34fe4fce5a65588d2161dab3e0e977fb8049ff7d79bc901034f7"
|
225
|
+
cli.eth_get_transaction_by_hash tx
|
226
|
+
# => {"jsonrpc"=>"2.0", "id"=>8, "result"=> {"blockHash"=>"0x47e742038c75851348dbda87b15fde044d54c442c371f43bea881a44d5589de3", "blockNumber"=>"0x1", "from"=>"0x6868074fb21c48dfad0c448fbabd99383a6598e4", "gas"=>"0x5208", "gasPrice"=>"0x342770c1", "maxFeePerGas"=>"0x77359401", "maxPriorityFeePerGas"=>"0x1", "hash"=>"0x141c6dff40df34fe4fce5a65588d2161dab3e0e977fb8049ff7d79bc901034f7", "input"=>"0x", "nonce"=>"0x0", "to"=>"0x311c61e5dc6123ad016bb7fd687d283c327bcd5f", "transactionIndex"=>"0x0", "value"=>"0x487a9a304539440000", "type"=>"0x2", "accessList"=>[], "chainId"=>"0x539", "v"=>"0x0", "r"=>"0xb42477d69eae65a3a3d91d9cb173e4a45a403fb0a15fa729dbfdc9d13211d7b5", "s"=>"0x4a2f98fc2b61c2d7c907520bc8c6ebe42ea6fe1cb6824f95e4b30e9464395100"}}
|
227
|
+
cli.get_balance "0x311c61e5dc6123ad016bb7fd687d283c327bcd5f"
|
228
|
+
# => 1337000000000000000000
|
229
|
+
cli.get_nonce cli.eth_coinbase["result"]
|
230
|
+
# => 1
|
231
|
+
```
|
232
|
+
|
233
|
+
Check out `Eth::Api` for a list of supported RPC-APIs or consult the [Documentation](https://q9f.github.io/eth.rb/) for more details.
|
234
|
+
|
235
|
+
### 2.8 Solidity Compiler Bindings
|
236
|
+
Link a system-level Solidity compiler (`solc`) to your Ruby library and compile contracts.
|
237
|
+
|
238
|
+
```ruby
|
239
|
+
solc = Eth::Solidity.new
|
240
|
+
# => #<Eth::Solidity:0x000055f05040c6d0 @compiler="/usr/bin/solc">
|
241
|
+
contract = solc.compile "spec/fixtures/contracts/greeter.sol"
|
242
|
+
# => {"Greeter"=>
|
243
|
+
# {"abi"=>
|
244
|
+
# [{"inputs"=>[{"internalType"=>"string", "name"=>"message", "type"=>"string"}], "stateMutability"=>"nonpayable", "type"=>"constructor"},
|
245
|
+
# {"inputs"=>[], "name"=>"greet", "outputs"=>[{"internalType"=>"string", "name"=>"", "type"=>"string"}], "stateMutability"=>"view", "type"=>"function"},
|
246
|
+
# {"inputs"=>[], "name"=>"kill", "outputs"=>[], "stateMutability"=>"nonpayable", "type"=>"function"}],
|
247
|
+
# "bin"=>
|
248
|
+
# "6080604052348015...6c634300080c0033"},
|
249
|
+
# "Mortal"=>
|
250
|
+
# {"abi"=>[{"inputs"=>[], "stateMutability"=>"nonpayable", "type"=>"constructor"}, {"inputs"=>[], "name"=>"kill", "outputs"=>[], "stateMutability"=>"nonpayable", "type"=>"function"}],
|
251
|
+
# "bin"=>
|
252
|
+
# "6080604052348015...6c634300080c0033"}}
|
253
|
+
```
|
254
|
+
|
255
|
+
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.
|
256
|
+
|
257
|
+
### 2.9 Interact with Smart Contract
|
258
|
+
|
259
|
+
Functions to interact with smart contract.
|
260
|
+
|
261
|
+
```ruby
|
262
|
+
contract = Eth::Contract.create(file: 'spec/fixtures/contracts/dummy.sol')
|
263
|
+
# => #<Eth::Contract::Dummy:0x00007fbeee936598>
|
264
|
+
cli = Eth::Client.create "/tmp/geth.ipc"
|
265
|
+
# => #<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">
|
266
|
+
address = cli.deploy_and_wait(contract)
|
267
|
+
# => "0x2f2faa160420cee087ded96bad52475147136bd8"
|
268
|
+
cli.transact_and_wait(contract, "set", 1234)
|
269
|
+
# => "0x49ca4c0a5729da19a1d2574de9a444a9cd3219bdad81745b54f9cf3bb83b6a06"
|
270
|
+
cli.call(contract, "get")
|
271
|
+
# => 1234
|
272
|
+
```
|
273
|
+
|
274
|
+
## 3. Documentation
|
182
275
|
The documentation can be found at: https://q9f.github.io/eth.rb
|
183
276
|
|
184
277
|
For any specific version, docs can be generated by `yard`:
|
@@ -192,8 +285,13 @@ yard doc
|
|
192
285
|
The goal is to have 100% API documentation available.
|
193
286
|
|
194
287
|
## 4. Testing
|
288
|
+
The test suite expects working local HTTP and IPC endpoints with a prefunded developer account, e.g.:
|
289
|
+
|
290
|
+
```shell
|
291
|
+
geth --dev --http --ipcpath /tmp/geth.ipc &
|
292
|
+
```
|
195
293
|
|
196
|
-
To run tests, simply use `rspec`. Note, that the Ethereum
|
294
|
+
To run tests, simply use `rspec`. Note, that the Ethereum test fixtures are also required.
|
197
295
|
|
198
296
|
```shell
|
199
297
|
git submodule update --init --recursive
|
@@ -204,7 +302,6 @@ rspec
|
|
204
302
|
The goal is to have 100% specification coverage for all code inside this gem.
|
205
303
|
|
206
304
|
## 5. Contributing
|
207
|
-
|
208
305
|
Pull requests are welcome! To contribute, please consider the following:
|
209
306
|
* Code should be fully documented. Run `yard doc` and make sure it does not yield any warnings or undocumented sets.
|
210
307
|
* 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%.
|
@@ -217,5 +314,11 @@ The `eth` gem is licensed under the conditions of [Apache 2.0](./LICENSE.txt). P
|
|
217
314
|
This gem is a complete rewrite of the old `eth` gem by Steve Ellis.
|
218
315
|
* https://github.com/se3000/ruby-eth/ (MIT)
|
219
316
|
|
220
|
-
It
|
317
|
+
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.
|
318
|
+
* https://github.com/EthWorks/ethereum.rb (MIT)
|
319
|
+
|
320
|
+
This gem also includes a revised version of the ABI gem by Jan Xie and Zhang Yaning.
|
221
321
|
* https://github.com/cryptape/ruby-ethereum-abi (MIT)
|
322
|
+
|
323
|
+
It also contains a condensed version of the RLP gem by Jan Xie and Zhang Yaning.
|
324
|
+
* https://github.com/cryptape/ruby-rlp (MIT)
|
data/bin/console
CHANGED
data/bin/setup
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
#!/usr/bin/env bash
|
2
2
|
|
3
|
-
set -euo pipefail
|
4
|
-
IFS=$'\n\t'
|
5
|
-
set -vx
|
6
|
-
|
7
3
|
bundle install
|
8
4
|
git submodule update --init --recursive
|
5
|
+
rufo .
|
9
6
|
yard doc
|
10
7
|
rspec
|
8
|
+
|
9
|
+
echo "Tests fail? Run \`geth --dev --http --ipcpath /tmp/geth.ipc\` in background and try again."
|
data/codecov.yml
ADDED
data/eth.gemspec
CHANGED
@@ -18,10 +18,11 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.license = "Apache-2.0"
|
19
19
|
|
20
20
|
spec.metadata = {
|
21
|
-
"homepage_uri" => "https://github.com/q9f/eth.rb",
|
22
|
-
"source_code_uri" => "https://github.com/q9f/eth.rb",
|
23
|
-
"github_repo" => "https://github.com/q9f/eth.rb",
|
24
21
|
"bug_tracker_uri" => "https://github.com/q9f/eth.rb/issues",
|
22
|
+
"changelog_uri" => "https://github.com/q9f/eth.rb/blob/main/CHANGELOG.md",
|
23
|
+
"documentation_uri" => "https://q9f.github.io/eth.rb/",
|
24
|
+
"github_repo" => "https://github.com/q9f/eth.rb",
|
25
|
+
"source_code_uri" => "https://github.com/q9f/eth.rb",
|
25
26
|
}.freeze
|
26
27
|
|
27
28
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
@@ -42,11 +43,8 @@ Gem::Specification.new do |spec|
|
|
42
43
|
# rbsecp256k1 for key-pairs and signatures
|
43
44
|
spec.add_dependency "rbsecp256k1", "~> 5.1"
|
44
45
|
|
45
|
-
# rlp for transaction encoding
|
46
|
-
spec.add_dependency "rlp", "~> 0.7"
|
47
|
-
|
48
46
|
# openssl for encrypted key derivation
|
49
|
-
spec.add_dependency "openssl", "~>
|
47
|
+
spec.add_dependency "openssl", "~> 2.2"
|
50
48
|
|
51
49
|
# scrypt for encrypted key derivation
|
52
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 Applicatoin 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
|