eth 0.3.2 → 0.3.3
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/README.md +8 -1
- data/bin/console +1 -1
- data/eth.gemspec +1 -1
- data/lib/eth.rb +37 -0
- data/lib/eth/key.rb +1 -1
- data/lib/eth/open_ssl.rb +6 -14
- data/lib/eth/tx.rb +19 -1
- data/lib/eth/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31616ae94a3bcb7936694a979e1789f1e7cdb8be
|
4
|
+
data.tar.gz: 71821aeabc7dbc4ff6add09b97a01e06a7c44338
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3bcafe0df121ace5b627daa94890aa2822db9f2fb73b940b5774cf300ede5499a96ded2a6403c5134ab82e8ce31d39ca64bc408062a28f0f009af02c9679e6d8
|
7
|
+
data.tar.gz: c4fa309b4924c2d21f402b2151d8dbf2170fe4791ddbdba0a6ca7a32a11325cc8e1f39b79692570beee84b8aece89a82c77eb6e492d9630f6f8c5033634ca5b9
|
data/README.md
CHANGED
@@ -48,6 +48,14 @@ Or decode an encoded raw transaction:
|
|
48
48
|
tx = Eth::Tx.decode hex
|
49
49
|
```
|
50
50
|
|
51
|
+
### Configure
|
52
|
+
In order to prevent replay attacks, you must specify which Ethereum chain your transactions are created for. See [EIP 155](https://github.com/ethereum/EIPs/issues/155) for more detail.
|
53
|
+
```
|
54
|
+
Eth.configure do |config|
|
55
|
+
config.chain_id = 18 #defaults to 13
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
51
59
|
Then sign the transaction:
|
52
60
|
```ruby
|
53
61
|
tx.sign key
|
@@ -67,5 +75,4 @@ The gem is available as open source under the terms of the [MIT License](http://
|
|
67
75
|
## TODO
|
68
76
|
- Better test suite.
|
69
77
|
- Expose API for HD keys.
|
70
|
-
- Separate out code pulled from [bitcoin-ruby](https://github.com/lian/bitcoin-ruby) and [ruby-ethereum](github.com/janx/ruby-ethereum) into their own gems to eliminate duplication.
|
71
78
|
- Support signing with [libsecp256k1](https://github.com/bitcoin-core/secp256k1).
|
data/bin/console
CHANGED
data/eth.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_dependency "ethereum-base", "~> 0.1.4"
|
23
23
|
spec.add_dependency "ffi", "~> 1.0"
|
24
24
|
spec.add_dependency "money-tree", "~> 0.9"
|
25
|
-
spec.add_dependency "rlp", "~> 0.7"
|
25
|
+
spec.add_dependency "rlp", "~> 0.7.3"
|
26
26
|
|
27
27
|
spec.add_development_dependency "bundler", "~> 1.12"
|
28
28
|
spec.add_development_dependency "pry", "~> 0.1"
|
data/lib/eth.rb
CHANGED
@@ -5,6 +5,7 @@ require 'money-tree'
|
|
5
5
|
require 'rlp'
|
6
6
|
|
7
7
|
module Eth
|
8
|
+
REPLAYABLE_CHAIN_ID = 13
|
8
9
|
|
9
10
|
autoload :Key, 'eth/key'
|
10
11
|
autoload :OpenSsl, 'eth/open_ssl'
|
@@ -12,4 +13,40 @@ module Eth
|
|
12
13
|
autoload :Tx, 'eth/tx'
|
13
14
|
autoload :Utils, 'eth/utils'
|
14
15
|
|
16
|
+
class << self
|
17
|
+
def configure
|
18
|
+
yield(configuration)
|
19
|
+
end
|
20
|
+
|
21
|
+
def chain_id
|
22
|
+
(configuration.chain_id || REPLAYABLE_CHAIN_ID).to_i
|
23
|
+
end
|
24
|
+
|
25
|
+
def v_base
|
26
|
+
(chain_id * 2) + 1
|
27
|
+
end
|
28
|
+
|
29
|
+
def replayable_v_base
|
30
|
+
(REPLAYABLE_CHAIN_ID * 2) + 1
|
31
|
+
end
|
32
|
+
|
33
|
+
def prevent_replays?
|
34
|
+
chain_id != REPLAYABLE_CHAIN_ID
|
35
|
+
end
|
36
|
+
|
37
|
+
def replayable_v?(v)
|
38
|
+
[replayable_v_base, replayable_v_base + 1].include? v
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def configuration
|
45
|
+
@configuration ||= Configuration.new
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class Configuration
|
50
|
+
attr_accessor :chain_id
|
51
|
+
end
|
15
52
|
end
|
data/lib/eth/key.rb
CHANGED
data/lib/eth/open_ssl.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
# lifted from https://github.com/lian/bitcoin-ruby
|
1
|
+
# originally lifted from https://github.com/lian/bitcoin-ruby
|
2
2
|
# thanks to everyone there for figuring this out
|
3
|
-
# TODO: Pull shared code out into a separate library
|
4
3
|
|
5
4
|
module Eth
|
6
5
|
class OpenSsl
|
@@ -56,13 +55,8 @@ module Eth
|
|
56
55
|
|
57
56
|
def self.BN_num_bytes(ptr); (BN_num_bits(ptr) + 7) / 8; end
|
58
57
|
|
59
|
-
# def self.sign_compact(hash, private_key, public_key_hex = nil, pubkey_compressed = nil)
|
60
58
|
def self.sign_compact(hash, private_key, public_key_hex)
|
61
59
|
private_key = [private_key].pack("H*") if private_key.bytesize >= 64
|
62
|
-
private_key_hex = private_key.unpack("H*")[0]
|
63
|
-
|
64
|
-
# public_key_hex = regenerate_key(private_key_hex).last unless public_key_hex
|
65
|
-
# pubkey_compressed = (public_key_hex[0..1] == "04" ? false : true) unless pubkey_compressed
|
66
60
|
pubkey_compressed = false
|
67
61
|
|
68
62
|
init_ffi_ssl
|
@@ -90,7 +84,7 @@ module Eth
|
|
90
84
|
|
91
85
|
if signature.get_array_of_pointer(0, 2).all?{|i| BN_num_bits(i) <= 256 }
|
92
86
|
4.times{|i|
|
93
|
-
head = [
|
87
|
+
head = [ Eth.v_base + i ].pack("C")
|
94
88
|
if public_key_hex == recover_public_key_from_signature(hash, [head, r, s].join, i, pubkey_compressed)
|
95
89
|
rec_id = i; break
|
96
90
|
end
|
@@ -107,7 +101,6 @@ module Eth
|
|
107
101
|
init_ffi_ssl
|
108
102
|
|
109
103
|
signature = FFI::MemoryPointer.from_string(signature)
|
110
|
-
#signature_bn = BN_bin2bn(signature, 65, BN_new())
|
111
104
|
r = BN_bin2bn(signature[1], 32, BN_new())
|
112
105
|
s = BN_bin2bn(signature[33], 32, BN_new())
|
113
106
|
|
@@ -168,14 +161,13 @@ module Eth
|
|
168
161
|
|
169
162
|
def self.recover_compact(hash, signature)
|
170
163
|
return false if signature.bytesize != 65
|
171
|
-
#i = signature.unpack("C")[0] - 27
|
172
|
-
#pubkey = recover_public_key_from_signature(hash, signature, (i & ~4), i >= 4)
|
173
164
|
|
174
165
|
version = signature.unpack('C')[0]
|
175
|
-
|
166
|
+
v_base = Eth.replayable_v?(version) ? Eth.replayable_v_base : Eth.v_base
|
167
|
+
return false if version < v_base
|
176
168
|
|
177
|
-
compressed =
|
178
|
-
pubkey = recover_public_key_from_signature(hash, signature, version-
|
169
|
+
compressed = false
|
170
|
+
pubkey = recover_public_key_from_signature(hash, signature, (version - v_base), compressed)
|
179
171
|
end
|
180
172
|
|
181
173
|
def self.init_ffi_ssl
|
data/lib/eth/tx.rb
CHANGED
@@ -33,7 +33,11 @@ module Eth
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def unsigned_encoded
|
36
|
-
RLP.encode
|
36
|
+
RLP.encode(unsigned, sedes: sedes)
|
37
|
+
end
|
38
|
+
|
39
|
+
def signing_data
|
40
|
+
Utils.bin_to_hex unsigned_encoded
|
37
41
|
end
|
38
42
|
|
39
43
|
def encoded
|
@@ -104,5 +108,19 @@ module Eth
|
|
104
108
|
Utils.keccak256 unsigned_encoded
|
105
109
|
end
|
106
110
|
|
111
|
+
def unsigned
|
112
|
+
Tx.new to_h.merge(v: Eth.chain_id, r: 0, s: 0)
|
113
|
+
end
|
114
|
+
|
115
|
+
def sedes
|
116
|
+
if Eth.prevent_replays? && !(Eth.replayable_v? v)
|
117
|
+
self.class
|
118
|
+
else
|
119
|
+
UnsignedTx
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
107
123
|
end
|
124
|
+
|
125
|
+
UnsignedTx = Tx.exclude([:v, :r, :s])
|
108
126
|
end
|
data/lib/eth/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Steve Ellis
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ethereum-base
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
61
|
+
version: 0.7.3
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 0.7.3
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -166,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
166
166
|
version: '0'
|
167
167
|
requirements: []
|
168
168
|
rubyforge_project:
|
169
|
-
rubygems_version: 2.
|
169
|
+
rubygems_version: 2.5.1
|
170
170
|
signing_key:
|
171
171
|
specification_version: 4
|
172
172
|
summary: Simple API to sign Ethereum transactions.
|