eth 0.5.0 → 0.5.1
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 +5 -0
- data/CHANGELOG.md +63 -13
- data/README.md +57 -2
- data/bin/console +2 -1
- data/bin/setup +3 -4
- data/eth.gemspec +5 -7
- data/lib/eth/abi/type.rb +8 -7
- data/lib/eth/abi.rb +17 -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 +47 -0
- data/lib/eth/client.rb +232 -0
- data/lib/eth/constant.rb +71 -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 +109 -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/tx/eip1559.rb +21 -14
- data/lib/eth/tx/eip2930.rb +22 -15
- data/lib/eth/tx/legacy.rb +13 -10
- data/lib/eth/tx.rb +9 -10
- 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 +8 -2
- metadata +22 -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: 90f2afdedcf09191090c54dbfa45438e5be7d0f94d5badc0b09e0d678d52f9bf
|
4
|
+
data.tar.gz: 05de6ecc688e5d11a50324d8707e092c91d422c6f11f02a1479a4645bce95c6e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d2d2eea96edfca3d94d4d23b4eabcb70dbc0ea33fd735ba13929130882d48b973fd8f242caaa39e49a3384f45bba87b39eb86b77ce539c416394c37ce989df97
|
7
|
+
data.tar.gz: 551c6cc113f279a91b900434ee446abf5fcd2d7ce1efb3cea294fc3531e250f9ef42068f22c57712f827bf756c95fde11ad7a481d53578f64d3631d7a5b2f795
|
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
|
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
|
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
@@ -14,3 +14,8 @@ The latest version of the Ruby-Eth gem contains a revised version the
|
|
14
14
|
ABI gem by Jan Xie (@janx) and Zhang Yaning (@u2) licensed under MIT
|
15
15
|
conditions:
|
16
16
|
* https://github.com/cryptape/ruby-ethereum-abi
|
17
|
+
|
18
|
+
The latest version of the Ruby-Eth gem contains a revised version the
|
19
|
+
RLP gem by Jan Xie (@janx) and Zhang Yaning (@u2) licensed under MIT
|
20
|
+
conditions:
|
21
|
+
* 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
@@ -23,10 +23,10 @@ What you get:
|
|
23
23
|
- [x] EIP-2718 Ethereum Transaction Envelopes (and types)
|
24
24
|
- [x] EIP-2930 Ethereum Type-1 Transactions (with access lists)
|
25
25
|
- [x] ABI-Encoder and Decoder (including type parser)
|
26
|
+
- [x] RLP-Encoder and Decoder (including sedes)
|
27
|
+
- [x] RPC-Client (IPC/HTTP) for Execution-Layer APIs
|
26
28
|
|
27
29
|
Soon (TM):
|
28
|
-
- [ ] RLP-Encoder and Decoder (including sedes)
|
29
|
-
- [ ] RPC-Client (HTTP) for Execution APIs and Consensus APIs
|
30
30
|
- [ ] Smart Contracts and Solidity Support
|
31
31
|
- [ ] EIP-1271 Smart-Contract Authentification
|
32
32
|
- [ ] HD-Wallets (BIP-32) and Mnemonics (BIP-39)
|
@@ -39,6 +39,8 @@ Contents:
|
|
39
39
|
- [2.3. Ethereum Chains (EIP-155)](#23-ethereum-chains-eip-155)
|
40
40
|
- [2.4. Ethereum Transactions (EIP-1559, EIP-2718, EIP-2930)](#24-ethereum-transactions-eip-1559-eip-2718-eip-2930)
|
41
41
|
- [2.5. Ethereum ABI Encoder and Decoder](#25-ethereum-abi-encoder-and-decoder)
|
42
|
+
- [2.6. Ethereum RLP Encoder and Decoder](#26-ethereum-rlp-encoder-and-decoder)
|
43
|
+
- [2.7. Ethereum RPC-Client](#27-ethereum-rpc-client)
|
42
44
|
- [3. Documentation](#3-documentation)
|
43
45
|
- [4. Testing](#4-testing)
|
44
46
|
- [5. Contributing](#5-contributing)
|
@@ -177,6 +179,56 @@ Eth::Abi.decode(["string", "address"], "0000000000000000000000000000000000000000
|
|
177
179
|
# => ["Hello, Bob!", "0xd496b23d61f88a8c7758fca7560dcfac7b3b01f9"]
|
178
180
|
```
|
179
181
|
|
182
|
+
### 2.6. Ethereum RLP Encoder and Decoder
|
183
|
+
|
184
|
+
Serialize and deserialize Ethereum recursive-length prefix data (RLP).
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
Eth::Util.bin_to_hex Eth::Rlp.encode ["Hello, Bob!", "0xd496b23d61f88a8c7758fca7560dcfac7b3b01f9"]
|
188
|
+
# => "f78b48656c6c6f2c20426f6221aa307864343936623233643631663838613863373735386663613735363064636661633762336230316639"
|
189
|
+
Eth::Rlp.decode "f78b48656c6c6f2c20426f6221aa307864343936623233643631663838613863373735386663613735363064636661633762336230316639"
|
190
|
+
# => ["Hello, Bob!", "0xd496b23d61f88a8c7758fca7560dcfac7b3b01f9"]
|
191
|
+
```
|
192
|
+
|
193
|
+
Or ;-)
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
Eth::Rlp.decode "c7c0c1c0c3c0c1c0"
|
197
|
+
# => [[], [[]], [[], [[]]]]
|
198
|
+
```
|
199
|
+
|
200
|
+
### 2.7. Ethereum RPC-Client
|
201
|
+
|
202
|
+
Create an IPC- or HTTP-RPC-API client to seamlessly query the chain state, e.g., Infura over HTTPS with access token:
|
203
|
+
|
204
|
+
```ruby
|
205
|
+
infura = Eth::Client.create "https://mainnet.infura.io/v3/#{access_token}"
|
206
|
+
# => #<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>>
|
207
|
+
deposit_contract = Eth::Address.new "0x00000000219ab540356cBB839Cbe05303d7705Fa"
|
208
|
+
# => #<Eth::Address:0x000055d43f381738 @address="0x00000000219ab540356cBB839Cbe05303d7705Fa">
|
209
|
+
infura.get_balance deposit_contract
|
210
|
+
# => 9087314000069000000000069
|
211
|
+
```
|
212
|
+
|
213
|
+
Or set up a local development environment with `geth --dev`:
|
214
|
+
|
215
|
+
```ruby
|
216
|
+
cli = Eth::Client.create "/tmp/geth.ipc"
|
217
|
+
# => #<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">
|
218
|
+
cli.eth_coinbase
|
219
|
+
# => {"jsonrpc"=>"2.0", "id"=>1, "result"=>"0x6868074fb21c48dfad0c448fbabd99383a6598e4"}
|
220
|
+
tx = cli.transfer_and_wait(Eth::Key.new.address, 1337 * Eth::Unit::ETHER)
|
221
|
+
# => "0x141c6dff40df34fe4fce5a65588d2161dab3e0e977fb8049ff7d79bc901034f7"
|
222
|
+
cli.eth_get_transaction_by_hash tx
|
223
|
+
# => {"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"}}
|
224
|
+
cli.get_balance "0x311c61e5dc6123ad016bb7fd687d283c327bcd5f"
|
225
|
+
# => 1337000000000000000000
|
226
|
+
cli.get_nonce cli.eth_coinbase["result"]
|
227
|
+
# => 1
|
228
|
+
```
|
229
|
+
|
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
|
+
|
180
232
|
## 3. Documentation
|
181
233
|
|
182
234
|
The documentation can be found at: https://q9f.github.io/eth.rb
|
@@ -219,3 +271,6 @@ This gem is a complete rewrite of the old `eth` gem by Steve Ellis.
|
|
219
271
|
|
220
272
|
It also contains a revised version the ABI gem by Jan Xie and Zhang Yaning.
|
221
273
|
* https://github.com/cryptape/ruby-ethereum-abi (MIT)
|
274
|
+
|
275
|
+
It also contains a revised version the RLP gem by Jan Xie and Zhang Yaning.
|
276
|
+
* 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/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"
|
data/lib/eth/abi/type.rb
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
|
15
15
|
# -*- encoding : ascii-8bit -*-
|
16
16
|
|
17
|
-
# Provides the
|
17
|
+
# Provides the {Eth} module.
|
18
18
|
module Eth
|
19
19
|
|
20
20
|
# Provides a Ruby implementation of the Ethereum Applicatoin Binary Interface (ABI).
|
@@ -26,7 +26,7 @@ module Eth
|
|
26
26
|
# Provides a specific parser error if type cannot be determined.
|
27
27
|
class ParseError < StandardError; end
|
28
28
|
|
29
|
-
# The base attribute, e.g., `string` or `bytes
|
29
|
+
# The base attribute, e.g., `string` or `bytes`.
|
30
30
|
attr :base_type
|
31
31
|
|
32
32
|
# The sub-type attribute, e.g., `256` as size of an uint256.
|
@@ -36,7 +36,7 @@ module Eth
|
|
36
36
|
attr :dimensions
|
37
37
|
|
38
38
|
# Create a new Type object for base types, sub types, and dimensions.
|
39
|
-
# Should use
|
39
|
+
# Should not be used; use {Type.parse} instead.
|
40
40
|
#
|
41
41
|
# @param base_type [String] the base-type attribute.
|
42
42
|
# @param sub_type [String] the sub-type attribute.
|
@@ -75,7 +75,7 @@ module Eth
|
|
75
75
|
@dimensions = dims.map { |x| x[1...-1].to_i }
|
76
76
|
end
|
77
77
|
|
78
|
-
#
|
78
|
+
# Creates a new uint256 type used for size.
|
79
79
|
#
|
80
80
|
# @return [Eth::Abi::Type] a uint256 size type.
|
81
81
|
def self.size_type
|
@@ -85,7 +85,7 @@ module Eth
|
|
85
85
|
# Compares two types for their attributes.
|
86
86
|
#
|
87
87
|
# @param another_type [Eth::Abi::Type] another type to be compared.
|
88
|
-
# @return [
|
88
|
+
# @return [Boolean] true if all attributes match.
|
89
89
|
def ==(another_type)
|
90
90
|
base_type == another_type.base_type and
|
91
91
|
sub_type == another_type.sub_type and
|
@@ -111,9 +111,9 @@ module Eth
|
|
111
111
|
@size ||= s
|
112
112
|
end
|
113
113
|
|
114
|
-
#
|
114
|
+
# Helpes to determine whether array is of dynamic size.
|
115
115
|
#
|
116
|
-
# @return [
|
116
|
+
# @return [Boolean] true if array is of dynamic size.
|
117
117
|
def is_dynamic?
|
118
118
|
size.nil?
|
119
119
|
end
|
@@ -127,6 +127,7 @@ module Eth
|
|
127
127
|
|
128
128
|
private
|
129
129
|
|
130
|
+
# Validates all known base types and raises if an issue occurs.
|
130
131
|
def validate_base_type(base_type, sub_type)
|
131
132
|
case base_type
|
132
133
|
when "string"
|
data/lib/eth/abi.rb
CHANGED
@@ -16,17 +16,15 @@
|
|
16
16
|
|
17
17
|
require "konstructor"
|
18
18
|
|
19
|
-
require "eth/abi/constant"
|
20
19
|
require "eth/abi/type"
|
21
20
|
|
22
|
-
# Provides the
|
21
|
+
# Provides the {Eth} module.
|
23
22
|
module Eth
|
24
23
|
|
25
24
|
# Provides a Ruby implementation of the Ethereum Applicatoin Binary Interface (ABI).
|
26
25
|
# ref: https://docs.soliditylang.org/en/develop/abi-spec.html
|
27
26
|
module Abi
|
28
27
|
extend self
|
29
|
-
include Constant
|
30
28
|
|
31
29
|
# Provides a special encoding error if anything fails to encode.
|
32
30
|
class EncodingError < StandardError; end
|
@@ -71,7 +69,7 @@ module Eth
|
|
71
69
|
# Encodes a specific value, either static or dynamic.
|
72
70
|
#
|
73
71
|
# @param type [Eth::Abi::Type] type to be encoded.
|
74
|
-
# @param arg [String
|
72
|
+
# @param arg [String|Number] value to be encoded.
|
75
73
|
# @return [String] the encoded type.
|
76
74
|
# @raise [EncodingError] if value does not match type.
|
77
75
|
def encode_type(type, arg)
|
@@ -80,7 +78,7 @@ module Eth
|
|
80
78
|
|
81
79
|
# encodes strings and bytes
|
82
80
|
size = encode_type Type.size_type, arg.size
|
83
|
-
padding = BYTE_ZERO * (Util.ceil32(arg.size) - arg.size)
|
81
|
+
padding = Constant::BYTE_ZERO * (Util.ceil32(arg.size) - arg.size)
|
84
82
|
return "#{size}#{arg}#{padding}"
|
85
83
|
elsif type.is_dynamic?
|
86
84
|
raise EncodingError, "Argument must be an Array" unless arg.instance_of? Array
|
@@ -113,7 +111,7 @@ module Eth
|
|
113
111
|
# Encodes primitive types.
|
114
112
|
#
|
115
113
|
# @param type [Eth::Abi::Type] type to be encoded.
|
116
|
-
# @param arg [String
|
114
|
+
# @param arg [String|Number] value to be encoded.
|
117
115
|
# @return [String] the encoded primitive type.
|
118
116
|
# @raise [EncodingError] if value does not match type.
|
119
117
|
# @raise [ValueOutOfBounds] if value is out of bounds for type.
|
@@ -286,7 +284,7 @@ module Eth
|
|
286
284
|
when "bool"
|
287
285
|
|
288
286
|
# decoded boolean
|
289
|
-
return data[-1] == BYTE_ONE
|
287
|
+
return data[-1] == Constant::BYTE_ONE
|
290
288
|
else
|
291
289
|
raise DecodingError, "Unknown primitive type: #{type.base_type}"
|
292
290
|
end
|
@@ -294,33 +292,38 @@ module Eth
|
|
294
292
|
|
295
293
|
private
|
296
294
|
|
295
|
+
# Properly encodes unsigned integers.
|
297
296
|
def encode_uint(arg, type)
|
298
|
-
raise ValueOutOfBounds, "Number out of range: #{arg}" if arg > UINT_MAX or arg < UINT_MIN
|
297
|
+
raise ValueOutOfBounds, "Number out of range: #{arg}" if arg > Constant::UINT_MAX or arg < Constant::UINT_MIN
|
299
298
|
real_size = type.sub_type.to_i
|
300
299
|
i = arg.to_i
|
301
300
|
raise ValueOutOfBounds, arg unless i >= 0 and i < 2 ** real_size
|
302
301
|
return Util.zpad_int i
|
303
302
|
end
|
304
303
|
|
304
|
+
# Properly encodes signed integers.
|
305
305
|
def encode_int(arg, type)
|
306
|
-
raise ValueOutOfBounds, "Number out of range: #{arg}" if arg > INT_MAX or arg < INT_MIN
|
306
|
+
raise ValueOutOfBounds, "Number out of range: #{arg}" if arg > Constant::INT_MAX or arg < Constant::INT_MIN
|
307
307
|
real_size = type.sub_type.to_i
|
308
308
|
i = arg.to_i
|
309
309
|
raise ValueOutOfBounds, arg unless i >= -2 ** (real_size - 1) and i < 2 ** (real_size - 1)
|
310
310
|
return Util.zpad_int(i % 2 ** type.sub_type.to_i)
|
311
311
|
end
|
312
312
|
|
313
|
+
# Properly encodes booleans.
|
313
314
|
def encode_bool(arg)
|
314
315
|
raise EncodingError, "Argument is not bool: #{arg}" unless arg.instance_of? TrueClass or arg.instance_of? FalseClass
|
315
316
|
return Util.zpad_int(arg ? 1 : 0)
|
316
317
|
end
|
317
318
|
|
319
|
+
# Properly encodes unsigned fixed-point numbers.
|
318
320
|
def encode_ufixed(arg, type)
|
319
321
|
high, low = type.sub_type.split("x").map(&:to_i)
|
320
322
|
raise ValueOutOfBounds, arg unless arg >= 0 and arg < 2 ** high
|
321
323
|
return Util.zpad_int((arg * 2 ** low).to_i)
|
322
324
|
end
|
323
325
|
|
326
|
+
# Properly encodes signed fixed-point numbers.
|
324
327
|
def encode_fixed(arg, type)
|
325
328
|
high, low = type.sub_type.split("x").map(&:to_i)
|
326
329
|
raise ValueOutOfBounds, arg unless arg >= -2 ** (high - 1) and arg < 2 ** (high - 1)
|
@@ -328,23 +331,25 @@ module Eth
|
|
328
331
|
return Util.zpad_int(i % 2 ** (high + low))
|
329
332
|
end
|
330
333
|
|
334
|
+
# Properly encodes byte-strings.
|
331
335
|
def encode_bytes(arg, type)
|
332
336
|
raise EncodingError, "Expecting String: #{arg}" unless arg.instance_of? String
|
333
337
|
if type.sub_type.empty?
|
334
338
|
size = Util.zpad_int arg.size
|
335
|
-
padding = BYTE_ZERO * (Util.ceil32(arg.size) - arg.size)
|
339
|
+
padding = Constant::BYTE_ZERO * (Util.ceil32(arg.size) - arg.size)
|
336
340
|
|
337
341
|
# variable length string/bytes
|
338
342
|
return "#{size}#{arg}#{padding}"
|
339
343
|
else
|
340
344
|
raise ValueOutOfBounds, arg unless arg.size <= type.sub_type.to_i
|
341
|
-
padding = BYTE_ZERO * (32 - arg.size)
|
345
|
+
padding = Constant::BYTE_ZERO * (32 - arg.size)
|
342
346
|
|
343
347
|
# fixed length string/bytes
|
344
348
|
return "#{arg}#{padding}"
|
345
349
|
end
|
346
350
|
end
|
347
351
|
|
352
|
+
# Properly encodes hash-strings.
|
348
353
|
def encode_hash(arg, type)
|
349
354
|
size = type.sub_type.to_i
|
350
355
|
raise EncodingError, "Argument too long: #{arg}" unless size > 0 and size <= 32
|
@@ -365,6 +370,7 @@ module Eth
|
|
365
370
|
end
|
366
371
|
end
|
367
372
|
|
373
|
+
# Properly encodes addresses.
|
368
374
|
def encode_address(arg)
|
369
375
|
if arg.is_a? Integer
|
370
376
|
|
data/lib/eth/address.rb
CHANGED
@@ -12,10 +12,10 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
# Provides the
|
15
|
+
# Provides the {Eth} module.
|
16
16
|
module Eth
|
17
17
|
|
18
|
-
# The
|
18
|
+
# The {Eth::Address} class to handle checksummed Ethereum addresses.
|
19
19
|
class Address
|
20
20
|
|
21
21
|
# Provides a special checksum error if EIP-55 is violated.
|
@@ -24,7 +24,7 @@ module Eth
|
|
24
24
|
# The prefixed and checksummed Ethereum address.
|
25
25
|
attr_reader :address
|
26
26
|
|
27
|
-
# Constructor of the
|
27
|
+
# Constructor of the {Eth::Address} class. Creates a new hex
|
28
28
|
# prefixed address.
|
29
29
|
#
|
30
30
|
# @param address [String] hex string representing an ethereum address.
|
@@ -38,9 +38,9 @@ module Eth
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
#
|
41
|
+
# Checks that the address is valid.
|
42
42
|
#
|
43
|
-
# @return [
|
43
|
+
# @return [Boolean] true if valid address.
|
44
44
|
def valid?
|
45
45
|
if !matches_any_format?
|
46
46
|
false
|
@@ -68,30 +68,37 @@ module Eth
|
|
68
68
|
|
69
69
|
private
|
70
70
|
|
71
|
+
# Checks whether the address checksum matches.
|
71
72
|
def checksum_matches?
|
72
73
|
address == checksummed
|
73
74
|
end
|
74
75
|
|
76
|
+
# Checks whether the address is not checksummed.
|
75
77
|
def not_checksummed?
|
76
78
|
all_uppercase? || all_lowercase?
|
77
79
|
end
|
78
80
|
|
81
|
+
# Checks whether the address is all upper-case.
|
79
82
|
def all_uppercase?
|
80
83
|
address.match /(?:0[xX])[A-F0-9]{40}/
|
81
84
|
end
|
82
85
|
|
86
|
+
# Checks whether the address is all lower-case.
|
83
87
|
def all_lowercase?
|
84
88
|
address.match /(?:0[xX])[a-f0-9]{40}/
|
85
89
|
end
|
86
90
|
|
91
|
+
# Checks whether the address matches any known format.
|
87
92
|
def matches_any_format?
|
88
93
|
address.match /\A(?:0[xX])[a-fA-F0-9]{40}\z/
|
89
94
|
end
|
90
95
|
|
96
|
+
# Computes the checksum of the address.
|
91
97
|
def checksum
|
92
98
|
Util.bin_to_hex Util.keccak256 unprefixed.downcase
|
93
99
|
end
|
94
100
|
|
101
|
+
# Removes the hex prefix.
|
95
102
|
def unprefixed
|
96
103
|
Util.remove_hex_prefix address
|
97
104
|
end
|