ethereum-tx 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bd0ee3551841f532a5ecc0dfc7524205f09e269c
4
+ data.tar.gz: 9f088bb9d3999be31aaf706bd8164555cd9d11f8
5
+ SHA512:
6
+ metadata.gz: 1ac7d61b2b9d4e85c7da5c741e69a387dd8ef90d886ddbaa473bbf389400e124b160e0c45af90adebb2840f3275645e82b71920ecd5614d2791d53837a0eef95
7
+ data.tar.gz: 776246ca9d84893139a8f1567fdd3f217e4532ff992e0ad84da2266203181a5f3adb607804b57a6c8714b99ff734aa9df40e6b2fab75353d19150577f03d36aa
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --require pry
2
+ --require spec_helper
3
+ --format documentation
4
+ --color
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ before_install: gem install bundler -v 1.12.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ethereum-tx.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Steve Ellis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,41 @@
1
+ # Ethereum::Tx
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/ethereum/tx`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'ethereum-tx'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install ethereum-tx
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/ethereum-tx.
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
41
+
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ethereum"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ require "pry"
10
+ Pry.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ethereum/tx/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ethereum-tx"
8
+ spec.version = Ethereum::Tx::VERSION
9
+ spec.authors = ["Steve Ellis"]
10
+ spec.email = ["email@steveell.is"]
11
+
12
+ spec.summary = %q{Simple API to sign Ethereum transactions.}
13
+ spec.description = %q{Library to build, parse, and sign Ethereum transactions.}
14
+ spec.homepage = "https://github.com/se3000/ethereum-tx"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency('digest-sha3', '~> 1.1')
23
+ spec.add_dependency "ffi", "~> 1.0"
24
+ spec.add_dependency "money-tree", "~> 0.9"
25
+ spec.add_dependency "rlp", "~> 0.7"
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.12"
28
+ spec.add_development_dependency "pry", "~> 0.1"
29
+ spec.add_development_dependency "rake", "~> 10.0"
30
+ spec.add_development_dependency "rspec", "~> 3.0"
31
+ end
@@ -0,0 +1,25 @@
1
+ require 'digest/sha3'
2
+ require 'ffi'
3
+ require 'money-tree'
4
+ require 'rlp'
5
+
6
+ module Ethereum
7
+
8
+ BYTE_ZERO = "\x00".freeze
9
+ GTXCOST = 21000 # TX BASE GAS COST
10
+ GTXDATANONZERO = 68 # TX DATA NON ZERO BYTE GAS COST
11
+ GTXDATAZERO = 4 # TX DATA ZERO BYTE GAS COST
12
+ SECP256K1_N = 115792089237316195423570985008687907852837564279074904382605163141518161494337
13
+ UINT_MAX = 2**256 - 1
14
+
15
+ autoload :Key, 'ethereum/key'
16
+ autoload :OpenSsl, 'ethereum/open_ssl'
17
+ autoload :Sedes, 'ethereum/sedes'
18
+ autoload :Tx, 'ethereum/tx'
19
+ autoload :Utils, 'ethereum/utils'
20
+ autoload :VERSION, 'ethereum/version'
21
+
22
+ class ValidationError < StandardError; end
23
+ class InvalidTransaction < ValidationError; end
24
+
25
+ end
@@ -0,0 +1,53 @@
1
+ module Ethereum
2
+ class Key
3
+
4
+ attr_reader :private_key, :public_key
5
+
6
+ def initialize(priv: nil)
7
+ @private_key = MoneyTree::PrivateKey.new key: priv
8
+ @public_key = MoneyTree::PublicKey.new private_key, compressed: false
9
+ end
10
+
11
+ def private_hex
12
+ private_key.to_hex
13
+ end
14
+
15
+ def public_bytes
16
+ public_key.to_bytes
17
+ end
18
+
19
+ def public_hex
20
+ public_key.to_hex
21
+ end
22
+
23
+ def to_address
24
+ Utils.bin_to_hex(Utils.keccak256(public_bytes[1..-1])[-20..-1])
25
+ end
26
+
27
+ def sign(message)
28
+ hash = message_hash(message)
29
+ loop do
30
+ signature = OpenSsl.sign_compact hash, private_hex, public_hex
31
+ return signature if valid_s? signature
32
+ end
33
+ end
34
+
35
+ def verify_signature(message, signature)
36
+ hash = message_hash(message)
37
+ public_hex == OpenSsl.recover_compact(hash, signature)
38
+ end
39
+
40
+
41
+ private
42
+
43
+ def message_hash(message)
44
+ Utils.keccak256 message
45
+ end
46
+
47
+ def valid_s?(signature)
48
+ s_value = Utils.v_r_s_for(signature).last
49
+ s_value <= SECP256K1_N/2 && s_value != 0
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,191 @@
1
+ # lifted from https://github.com/lian/bitcoin-ruby
2
+ # thanks to everyone there for figuring this out
3
+ # TODO: Pull shared code out into a separate library
4
+
5
+ module Ethereum
6
+ class OpenSsl
7
+ extend FFI::Library
8
+
9
+ if FFI::Platform.windows?
10
+ ffi_lib 'libeay32', 'ssleay32'
11
+ else
12
+ ffi_lib 'ssl'
13
+ end
14
+
15
+ NID_secp256k1 = 714
16
+ POINT_CONVERSION_COMPRESSED = 2
17
+ POINT_CONVERSION_UNCOMPRESSED = 4
18
+
19
+ attach_function :SSL_library_init, [], :int
20
+ attach_function :ERR_load_crypto_strings, [], :void
21
+ attach_function :SSL_load_error_strings, [], :void
22
+ attach_function :RAND_poll, [], :int
23
+
24
+ attach_function :BN_CTX_free, [:pointer], :int
25
+ attach_function :BN_CTX_new, [], :pointer
26
+ attach_function :BN_add, [:pointer, :pointer, :pointer], :int
27
+ attach_function :BN_bin2bn, [:pointer, :int, :pointer], :pointer
28
+ attach_function :BN_bn2bin, [:pointer, :pointer], :int
29
+ attach_function :BN_cmp, [:pointer, :pointer], :int
30
+ attach_function :BN_dup, [:pointer], :pointer
31
+ attach_function :BN_free, [:pointer], :int
32
+ attach_function :BN_mod_inverse, [:pointer, :pointer, :pointer, :pointer], :pointer
33
+ attach_function :BN_mod_mul, [:pointer, :pointer, :pointer, :pointer, :pointer], :int
34
+ attach_function :BN_mod_sub, [:pointer, :pointer, :pointer, :pointer, :pointer], :int
35
+ attach_function :BN_mul_word, [:pointer, :int], :int
36
+ attach_function :BN_new, [], :pointer
37
+ attach_function :BN_num_bits, [:pointer], :int
38
+ attach_function :BN_rshift, [:pointer, :pointer, :int], :int
39
+ attach_function :BN_set_word, [:pointer, :int], :int
40
+ attach_function :ECDSA_SIG_free, [:pointer], :void
41
+ attach_function :ECDSA_do_sign, [:pointer, :uint, :pointer], :pointer
42
+ attach_function :EC_GROUP_get_curve_GFp, [:pointer, :pointer, :pointer, :pointer, :pointer], :int
43
+ attach_function :EC_GROUP_get_degree, [:pointer], :int
44
+ attach_function :EC_GROUP_get_order, [:pointer, :pointer, :pointer], :int
45
+ attach_function :EC_KEY_free, [:pointer], :int
46
+ attach_function :EC_KEY_get0_group, [:pointer], :pointer
47
+ attach_function :EC_KEY_new_by_curve_name, [:int], :pointer
48
+ attach_function :EC_KEY_set_conv_form, [:pointer, :int], :void
49
+ attach_function :EC_KEY_set_private_key, [:pointer, :pointer], :int
50
+ attach_function :EC_KEY_set_public_key, [:pointer, :pointer], :int
51
+ attach_function :EC_POINT_free, [:pointer], :int
52
+ attach_function :EC_POINT_mul, [:pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :int
53
+ attach_function :EC_POINT_new, [:pointer], :pointer
54
+ attach_function :EC_POINT_set_compressed_coordinates_GFp, [:pointer, :pointer, :pointer, :int, :pointer], :int
55
+ attach_function :i2o_ECPublicKey, [:pointer, :pointer], :uint
56
+
57
+ def self.BN_num_bytes(ptr); (BN_num_bits(ptr) + 7) / 8; end
58
+
59
+ # def self.sign_compact(hash, private_key, public_key_hex = nil, pubkey_compressed = nil)
60
+ def self.sign_compact(hash, private_key, public_key_hex)
61
+ 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
+ pubkey_compressed = false
67
+
68
+ init_ffi_ssl
69
+ eckey = EC_KEY_new_by_curve_name(NID_secp256k1)
70
+ priv_key = BN_bin2bn(private_key, private_key.bytesize, BN_new())
71
+
72
+ group, order, ctx = EC_KEY_get0_group(eckey), BN_new(), BN_CTX_new()
73
+ EC_GROUP_get_order(group, order, ctx)
74
+
75
+ pub_key = EC_POINT_new(group)
76
+ EC_POINT_mul(group, pub_key, priv_key, nil, nil, ctx)
77
+ EC_KEY_set_private_key(eckey, priv_key)
78
+ EC_KEY_set_public_key(eckey, pub_key)
79
+
80
+ signature = ECDSA_do_sign(hash, hash.bytesize, eckey)
81
+
82
+ BN_free(order)
83
+ BN_CTX_free(ctx)
84
+ EC_POINT_free(pub_key)
85
+ BN_free(priv_key)
86
+ EC_KEY_free(eckey)
87
+
88
+ buf, rec_id, head = FFI::MemoryPointer.new(:uint8, 32), nil, nil
89
+ r, s = signature.get_array_of_pointer(0, 2).map{|i| BN_bn2bin(i, buf); buf.read_string(BN_num_bytes(i)).rjust(32, "\x00") }
90
+
91
+ if signature.get_array_of_pointer(0, 2).all?{|i| BN_num_bits(i) <= 256 }
92
+ 4.times{|i|
93
+ head = [ 27 + i + (pubkey_compressed ? 4 : 0) ].pack("C")
94
+ if public_key_hex == recover_public_key_from_signature(hash, [head, r, s].join, i, pubkey_compressed)
95
+ rec_id = i; break
96
+ end
97
+ }
98
+ end
99
+
100
+ ECDSA_SIG_free(signature)
101
+
102
+ [ head, [r,s] ].join if rec_id
103
+ end
104
+
105
+ def self.recover_public_key_from_signature(message_hash, signature, rec_id, is_compressed)
106
+ return nil if rec_id < 0 or signature.bytesize != 65
107
+ init_ffi_ssl
108
+
109
+ signature = FFI::MemoryPointer.from_string(signature)
110
+ #signature_bn = BN_bin2bn(signature, 65, BN_new())
111
+ r = BN_bin2bn(signature[1], 32, BN_new())
112
+ s = BN_bin2bn(signature[33], 32, BN_new())
113
+
114
+ n, i = 0, rec_id / 2
115
+ eckey = EC_KEY_new_by_curve_name(NID_secp256k1)
116
+
117
+ EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED) if is_compressed
118
+
119
+ group = EC_KEY_get0_group(eckey)
120
+ order = BN_new()
121
+ EC_GROUP_get_order(group, order, nil)
122
+ x = BN_dup(order)
123
+ BN_mul_word(x, i)
124
+ BN_add(x, x, r)
125
+
126
+ field = BN_new()
127
+ EC_GROUP_get_curve_GFp(group, field, nil, nil, nil)
128
+
129
+ if BN_cmp(x, field) >= 0
130
+ [r, s, order, x, field].each{|i| BN_free(i) }
131
+ EC_KEY_free(eckey)
132
+ return nil
133
+ end
134
+
135
+ big_r = EC_POINT_new(group)
136
+ EC_POINT_set_compressed_coordinates_GFp(group, big_r, x, rec_id % 2, nil)
137
+
138
+ big_q = EC_POINT_new(group)
139
+ n = EC_GROUP_get_degree(group)
140
+ e = BN_bin2bn(message_hash, message_hash.bytesize, BN_new())
141
+ BN_rshift(e, e, 8 - (n & 7)) if 8 * message_hash.bytesize > n
142
+
143
+ ctx = BN_CTX_new()
144
+ zero, rr, sor, eor = BN_new(), BN_new(), BN_new(), BN_new()
145
+ BN_set_word(zero, 0)
146
+ BN_mod_sub(e, zero, e, order, ctx)
147
+ BN_mod_inverse(rr, r, order, ctx)
148
+ BN_mod_mul(sor, s, rr, order, ctx)
149
+ BN_mod_mul(eor, e, rr, order, ctx)
150
+ EC_POINT_mul(group, big_q, eor, big_r, sor, ctx)
151
+ EC_KEY_set_public_key(eckey, big_q)
152
+ BN_CTX_free(ctx)
153
+
154
+ [r, s, order, x, field, e, zero, rr, sor, eor].each{|i| BN_free(i) }
155
+ [big_r, big_q].each{|i| EC_POINT_free(i) }
156
+
157
+ length = i2o_ECPublicKey(eckey, nil)
158
+ buf = FFI::MemoryPointer.new(:uint8, length)
159
+ ptr = FFI::MemoryPointer.new(:pointer).put_pointer(0, buf)
160
+ pub_hex = if i2o_ECPublicKey(eckey, ptr) == length
161
+ buf.read_string(length).unpack("H*")[0]
162
+ end
163
+
164
+ EC_KEY_free(eckey)
165
+
166
+ pub_hex
167
+ end
168
+
169
+ def self.recover_compact(hash, signature)
170
+ 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
+
174
+ version = signature.unpack('C')[0]
175
+ return false if version < 27 or version > 34
176
+
177
+ compressed = (version >= 31) ? (version -= 4; true) : false
178
+ pubkey = recover_public_key_from_signature(hash, signature, version-27, compressed)
179
+ end
180
+
181
+ def self.init_ffi_ssl
182
+ return if @ssl_loaded
183
+ SSL_library_init()
184
+ ERR_load_crypto_strings()
185
+ SSL_load_error_strings()
186
+ RAND_poll()
187
+ @ssl_loaded = true
188
+ end
189
+
190
+ end
191
+ end
@@ -0,0 +1,40 @@
1
+ module Ethereum
2
+ module Sedes
3
+ include RLP::Sedes
4
+
5
+ extend self
6
+
7
+ def address
8
+ Binary.fixed_length(20, allow_empty: true)
9
+ end
10
+
11
+ def int20
12
+ BigEndianInt.new(20)
13
+ end
14
+
15
+ def int32
16
+ BigEndianInt.new(32)
17
+ end
18
+
19
+ def int256
20
+ BigEndianInt.new(256)
21
+ end
22
+
23
+ def hash32
24
+ Binary.fixed_length(32)
25
+ end
26
+
27
+ def trie_root
28
+ Binary.fixed_length(32, allow_empty: true)
29
+ end
30
+
31
+ def big_endian_int
32
+ RLP::Sedes.big_endian_int
33
+ end
34
+
35
+ def binary
36
+ RLP::Sedes.binary
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,76 @@
1
+ #lifted from https://github.com/janx/ruby-ethereum
2
+ #TODO: try to extract gem for common behavior
3
+
4
+ module Ethereum
5
+ class Tx
6
+
7
+ include RLP::Sedes::Serializable
8
+ extend Sedes
9
+
10
+ set_serializable_fields({
11
+ nonce: big_endian_int,
12
+ gas_price: big_endian_int,
13
+ gas_limit: big_endian_int,
14
+ to: address,
15
+ value: big_endian_int,
16
+ data: binary,
17
+ v: big_endian_int,
18
+ r: big_endian_int,
19
+ s: big_endian_int
20
+ })
21
+
22
+ attr_reader :signature
23
+
24
+ def initialize(*args)
25
+ fields = {v: 0, r: 0, s: 0}.merge parse_field_args(args)
26
+ fields[:to] = Utils.normalize_address(fields[:to])
27
+
28
+ serializable_initialize fields
29
+
30
+ check_transaction_validity
31
+ end
32
+
33
+ def unsigned_encoded
34
+ RLP.encode self, sedes: Tx.exclude([:v, :r, :s])
35
+ end
36
+
37
+ def encoded
38
+ RLP.encode self
39
+ end
40
+
41
+ def sign(key)
42
+ self.signature = key.sign(unsigned_encoded)
43
+ self.vrs = Utils.v_r_s_for signature
44
+
45
+ self
46
+ end
47
+
48
+
49
+ private
50
+
51
+ attr_writer :signature
52
+
53
+ def check_transaction_validity
54
+ if [gas_price, gas_limit, value, nonce].max > UINT_MAX
55
+ raise InvalidTransaction, "Values way too high!"
56
+ elsif gas_limit < intrinsic_gas_used
57
+ raise InvalidTransaction, "Gas limit too low"
58
+ end
59
+ end
60
+
61
+ def vrs=(vrs)
62
+ self.v = vrs[0]
63
+ self.r = vrs[1]
64
+ self.s = vrs[2]
65
+ end
66
+
67
+ def intrinsic_gas_used
68
+ num_zero_bytes = data.count(BYTE_ZERO)
69
+ num_non_zero_bytes = data.size - num_zero_bytes
70
+
71
+ GTXCOST + GTXDATAZERO * num_zero_bytes +
72
+ GTXDATANONZERO * num_non_zero_bytes
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,5 @@
1
+ module Ethereum
2
+ class Tx
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,46 @@
1
+ module Ethereum
2
+ module Utils
3
+
4
+ extend self
5
+
6
+ def keccak256(message)
7
+ Digest::SHA3.new(256).digest(message)
8
+ end
9
+
10
+ def normalize_address(address)
11
+ if address.nil? || address == ''
12
+ ''
13
+ elsif address.size == 40
14
+ hex_to_bin address
15
+ elsif address.size == 42 && address[0..1] == '0x'
16
+ hex_to_bin address[2..-1]
17
+ else
18
+ address
19
+ end
20
+ end
21
+
22
+ def bin_to_hex(string)
23
+ string.unpack("H*")[0]
24
+ end
25
+
26
+ def hex_to_bin(string)
27
+ [string].pack("H*")
28
+ end
29
+
30
+ def base256_to_int(string)
31
+ string.bytes.inject do |result, byte|
32
+ result *= 256
33
+ result + byte
34
+ end
35
+ end
36
+
37
+ def v_r_s_for(signature)
38
+ [
39
+ signature[0].bytes[0],
40
+ Utils.base256_to_int(signature[1..32]),
41
+ Utils.base256_to_int(signature[33..65]),
42
+ ]
43
+ end
44
+
45
+ end
46
+ end
metadata ADDED
@@ -0,0 +1,174 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ethereum-tx
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Steve Ellis
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-05-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: digest-sha3
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: ffi
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: money-tree
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.9'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.9'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rlp
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.7'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.7'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.12'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.12'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.1'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.1'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '10.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '10.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.0'
125
+ description: Library to build, parse, and sign Ethereum transactions.
126
+ email:
127
+ - email@steveell.is
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".gitignore"
133
+ - ".rspec"
134
+ - ".travis.yml"
135
+ - Gemfile
136
+ - LICENSE.txt
137
+ - README.md
138
+ - Rakefile
139
+ - bin/console
140
+ - bin/setup
141
+ - ethereum-tx.gemspec
142
+ - lib/ethereum.rb
143
+ - lib/ethereum/key.rb
144
+ - lib/ethereum/open_ssl.rb
145
+ - lib/ethereum/sedes.rb
146
+ - lib/ethereum/tx.rb
147
+ - lib/ethereum/tx/version.rb
148
+ - lib/ethereum/utils.rb
149
+ homepage: https://github.com/se3000/ethereum-tx
150
+ licenses:
151
+ - MIT
152
+ metadata: {}
153
+ post_install_message:
154
+ rdoc_options: []
155
+ require_paths:
156
+ - lib
157
+ required_ruby_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ required_rubygems_version: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ requirements: []
168
+ rubyforge_project:
169
+ rubygems_version: 2.5.1
170
+ signing_key:
171
+ specification_version: 4
172
+ summary: Simple API to sign Ethereum transactions.
173
+ test_files: []
174
+ has_rdoc: