eth 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1aa11c555d957c6c8c55d2ea7268609d3f9736f3
4
- data.tar.gz: 73b6328615458f16f7bbd5a5bcaf6720ce5c9178
3
+ metadata.gz: 31616ae94a3bcb7936694a979e1789f1e7cdb8be
4
+ data.tar.gz: 71821aeabc7dbc4ff6add09b97a01e06a7c44338
5
5
  SHA512:
6
- metadata.gz: f199ecb42d65c41df74875767570780f2d92d248fa8c8352203744d8337401883ecb05cad4d09d8886412b9672beb2a320af4adf8c5c83b9a5cc74dc6dc56fb1
7
- data.tar.gz: a90b8616b9ee5812a165ba685e24b8e9e1bfccc724cfb2c6ea5dfab9e9075b0e870a593a5aa0e33e704a61606cd8d8f8df48ece2ac8eac01acf22291a9c681fc
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).
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require "bundler/setup"
4
- require "ethereum-tx"
4
+ require "eth"
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -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
@@ -20,7 +20,7 @@ module Eth
20
20
  public_key.to_hex
21
21
  end
22
22
 
23
- def to_address
23
+ def address
24
24
  Utils.bin_to_hex(Utils.keccak256(public_bytes[1..-1])[-20..-1])
25
25
  end
26
26
 
@@ -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 = [ 27 + i + (pubkey_compressed ? 4 : 0) ].pack("C")
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
- return false if version < 27 or version > 34
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 = (version >= 31) ? (version -= 4; true) : false
178
- pubkey = recover_public_key_from_signature(hash, signature, version-27, compressed)
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
@@ -33,7 +33,11 @@ module Eth
33
33
  end
34
34
 
35
35
  def unsigned_encoded
36
- RLP.encode self, sedes: Tx.exclude([:v, :r, :s])
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
@@ -1,3 +1,3 @@
1
1
  module Eth
2
- VERSION = "0.3.2"
2
+ VERSION = "0.3.3"
3
3
  end
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.2
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-10-18 00:00:00.000000000 Z
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: '0.7'
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: '0.7'
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.4.5.1
169
+ rubygems_version: 2.5.1
170
170
  signing_key:
171
171
  specification_version: 4
172
172
  summary: Simple API to sign Ethereum transactions.