eth 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|