etheruby 0.1.0 → 0.9.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 62e7a1ef2415572fb35e1617898576247fabeccb
4
- data.tar.gz: 9f6747ff369f23fe11f3a67c0b815b6a53bbfd72
3
+ metadata.gz: dfed46cee6fdea612e7c4c0c08b0cd634d8746a4
4
+ data.tar.gz: 77c90af3d066a14055b39297c5092705dd22b3e0
5
5
  SHA512:
6
- metadata.gz: b5deae709916778cfd2e39217f22edb24929da0a57054cd5020a0882e8bf222d3b1928d90140a21ce99f9aaeb0eb103f4172031f1d9b857f05aee62ea39e9648
7
- data.tar.gz: f725746f91570b71d37d89b62c241945688603fedaf17f0fb56db178511eb73206edd72d9d45fba75b88ebdb16458765e242166222d81765b7c03649e99b9051
6
+ metadata.gz: 72a01c07b209b5124207a196adb86d9d5207cf9a461265a62822ff74bd55caa6aed3f67ab53b6c33ebe67822bad5beca3ba684db8dbb44141c2aef53856a2ec8
7
+ data.tar.gz: b2960aeab3cb037b99b139aecbef3f350fbc06b8add6ec0ed5aac8c5e3d713d2863ad54dd7d3fc5de81f02162ee549828e25797a5e74756857b9d55aa5109dce
data/lib/etheruby.rb CHANGED
@@ -1,76 +1,4 @@
1
1
  require 'logger'
2
-
3
2
  require_relative 'etheruby/client'
4
- require_relative 'etheruby/contract_method_dsl'
5
- require_relative 'etheruby/arguments_generator'
6
- require_relative 'etheruby/response_parser'
7
-
8
- module Etheruby
9
- class NoContractMethodError < StandardError; end
10
-
11
- def contract
12
- Class.new do
13
- def self.inherited(subclass)
14
- @@c_methods = {}
15
- @@logger = ::Logger.new(STDOUT)
16
- @@logger.level = if ENV.has_key? 'ETHERUBY_DEBUG'
17
- ::Logger::DEBUG
18
- else
19
- ::Logger::WARN
20
- end
21
- @@logger.progname = "Etheruby Contract '#{subclass.name}'"
22
- end
23
-
24
- def self.at_address(address)
25
- @@address = address
26
- end
27
-
28
- def self.method(name, &blk)
29
- cmd = ContractMethodDSL.new(name)
30
- cmd.instance_exec &blk if blk
31
- @@c_methods[name] = cmd.validate!
32
- @@logger.debug("Registred method #{name}")
33
- end
34
-
35
- def self.method_missing(sym, *args)
36
- raise NoContractMethodError.new (
37
- "The method #{sym} does not exist in the #{self.class.to_s} contract."
38
- ) unless @@c_methods.include? sym
39
- execute_contract_method(@@c_methods[sym], args)
40
- end
41
-
42
- def self.execute_contract_method(method_info, args)
43
- arguments = ArgumentsGenerator.new(method_info[:params], args).to_s
44
- data = "#{method_info[:signature]}#{arguments}"
45
- composed_body = { to: self.address, data: data }
46
- [ :gas, :gasPrice, :value, :from ].each { |kw|
47
- composed_body[kw] = method_info[kw] if method_info.has_key? kw
48
- }
49
- @@logger.debug("Calling #{method_info[:name]} with parameters #{composed_body.inspect}")
50
- response = call_api composed_body
51
- if response.has_key? 'error'
52
- @@logger.error("Failed contract execution #{response['error']['message']}")
53
- else
54
- @@logger.debug("Response from API for #{method_info[:name]} : #{response.inspect}")
55
- end
56
- if method_info.has_key? :returns
57
- ResponseParser.new(method_info[:returns], response['result']).parse
58
- else
59
- response['result']
60
- end
61
- end
62
-
63
- def self.call_api(composed_body)
64
- Client.eth.call composed_body, "latest"
65
- end
66
-
67
- def self.address
68
- "0x#{@@address.to_s(16)}"
69
- end
70
- end
71
- end
72
-
73
- module_function :contract
74
-
75
- Contract = Etheruby::contract
76
- end
3
+ require_relative 'etheruby/contract'
4
+ require_relative 'etheruby/railtie' if defined?(Rails)
@@ -18,21 +18,35 @@ module Etheruby
18
18
 
19
19
  def to_s
20
20
  raise ArgumentsCountError.new("Bad number of arguments") unless args.count == params.count
21
- head = ''
21
+ head = []
22
22
  tail = ''
23
- current_tail_position = (params.count*32)
23
+ current_tail_position = 0
24
24
  (0..params.count-1).each do |i|
25
25
  param, arg = params[i], args[i]
26
26
  if Etheruby.is_static_type? param
27
- head += Etheruby.treat_variable(param, arg, :encode).to_s
27
+ head << {final: Etheruby.treat_variable(param, arg, :encode).to_s}
28
28
  else
29
- head += Etheruby::Encoders::Uint.new(current_tail_position).encode
29
+ head << {pointer: current_tail_position}
30
30
  content = Etheruby.treat_variable(param, arg, :encode).to_s
31
31
  current_tail_position += content.length/2
32
32
  tail += content
33
33
  end
34
34
  end
35
- return head + tail
35
+ head_size = head.map { |x|
36
+ if x.has_key?(:pointer)
37
+ 32
38
+ else
39
+ x[:final].length/2
40
+ end
41
+ }.inject(0){|sum,x| sum + x }
42
+ final_head = head.map { |x|
43
+ if x.has_key?(:pointer)
44
+ Etheruby::Encoders::Uint.new(head_size + x[:pointer]).encode
45
+ else
46
+ x[:final]
47
+ end
48
+ }.join
49
+ return final_head + tail
36
50
  end
37
51
 
38
52
  end
@@ -0,0 +1,74 @@
1
+ require_relative 'client'
2
+ require_relative 'contract_method_dsl'
3
+ require_relative 'arguments_generator'
4
+ require_relative 'response_parser'
5
+
6
+ module Etheruby
7
+ class NoContractMethodError < StandardError; end
8
+
9
+ def contract
10
+ Class.new do
11
+ def self.inherited(subclass)
12
+ @@c_methods = {}
13
+ @@logger = ::Logger.new(STDOUT)
14
+ @@logger.level = if ENV.has_key? 'ETHERUBY_DEBUG'
15
+ ::Logger::DEBUG
16
+ else
17
+ ::Logger::WARN
18
+ end
19
+ @@logger.progname = "Etheruby Contract '#{subclass.name}'"
20
+ end
21
+
22
+ def self.at_address(address)
23
+ @@address = address
24
+ end
25
+
26
+ def self.method(name, &blk)
27
+ cmd = ContractMethodDSL.new(name)
28
+ cmd.instance_exec &blk if blk
29
+ @@c_methods[name] = cmd.validate!
30
+ @@logger.debug("Registred method #{name}")
31
+ end
32
+
33
+ def self.method_missing(sym, *args)
34
+ raise NoContractMethodError.new (
35
+ "The method #{sym} does not exist in the #{self.class.to_s} contract."
36
+ ) unless @@c_methods.include? sym
37
+ execute_contract_method(@@c_methods[sym], args)
38
+ end
39
+
40
+ def self.execute_contract_method(method_info, args)
41
+ arguments = ArgumentsGenerator.new(method_info[:params], args).to_s
42
+ data = "#{method_info[:signature]}#{arguments}"
43
+ composed_body = { to: self.address, data: data }
44
+ [ :gas, :gasPrice, :value, :from ].each { |kw|
45
+ composed_body[kw] = method_info[kw] if method_info.has_key? kw
46
+ }
47
+ @@logger.debug("Calling #{method_info[:name]} with parameters #{composed_body.inspect}")
48
+ response = call_api composed_body
49
+ if response.has_key? 'error'
50
+ @@logger.error("Failed contract execution #{response['error']['message']}")
51
+ else
52
+ @@logger.debug("Response from API for #{method_info[:name]} : #{response.inspect}")
53
+ end
54
+ if method_info.has_key? :returns
55
+ ResponseParser.new(method_info[:returns], response['result']).parse
56
+ else
57
+ response['result']
58
+ end
59
+ end
60
+
61
+ def self.call_api(composed_body)
62
+ Client.eth.call composed_body, "latest"
63
+ end
64
+
65
+ def self.address
66
+ "0x#{@@address.to_s(16)}"
67
+ end
68
+ end
69
+ end
70
+
71
+ module_function :contract
72
+
73
+ Contract = Etheruby::contract
74
+ end
@@ -9,7 +9,7 @@ module Etheruby::Encoders
9
9
  end
10
10
 
11
11
  def decode
12
- Uint.new(data).decode[0] == 1
12
+ return Uint.new(data).decode[0] == 1, 32
13
13
  end
14
14
  end
15
15
 
@@ -0,0 +1,26 @@
1
+ require_relative 'base'
2
+ require_relative 'address'
3
+
4
+ module Etheruby::Encoders
5
+
6
+ class Function < Base
7
+
8
+ def encode
9
+ (data[:address].to_s(16) + data[:selector].to_s(16)).ljust(64, '0')
10
+ end
11
+
12
+ def decode
13
+ address, selector = data[0..39], data[40..47]
14
+ return {
15
+ address: Address.new(address).decode[0],
16
+ selector: "0x#{selector}"
17
+ }, 32
18
+ end
19
+
20
+ def to_s
21
+ encode
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,9 @@
1
+ module Etheruby
2
+
3
+ class Railtie < Rails::Railtie
4
+ initializer "etheruby.configure" do |app|
5
+ Etheruby::Client.uri = app.config.etheruby_uri if app.config.respond_to? :etheruby_uri
6
+ end
7
+ end
8
+
9
+ end
@@ -1,4 +1,6 @@
1
1
  require_relative 'type_matchers'
2
+ require_relative 'treat_variable'
3
+ require_relative 'encoders/int'
2
4
 
3
5
  module Etheruby
4
6
 
@@ -13,11 +15,32 @@ module Etheruby
13
15
 
14
16
  def parse
15
17
  if returns.count == 1
16
- Etheruby::treat_variable(returns[0], response, :decode)
18
+ v, s = Etheruby::treat_variable(returns[0], response, :decode)
19
+ v = v.decode if v.is_a? Etheruby::Encoders::DynamicArray or v.is_a? Etheruby::Encoders::StaticArray
20
+ v
17
21
  else
18
- returns.each do |type|
19
-
22
+ real_response = @response
23
+ values = []
24
+ i = 0
25
+ loop do
26
+ return_type = returns[i]
27
+ if Etheruby::is_static_type?(return_type)
28
+ v, s = Etheruby::treat_variable(return_type, real_response, :decode)
29
+ else
30
+ value_position, s = Etheruby::Encoders::Uint.new(real_response).decode
31
+ v, take_size = Etheruby::treat_variable(
32
+ return_type,
33
+ @response[(value_position*2)..response.length],
34
+ :decode
35
+ )
36
+ end
37
+ v = v.decode if v.is_a? Etheruby::Encoders::DynamicArray or v.is_a? Etheruby::Encoders::StaticArray
38
+ values << v
39
+ break if values.count == returns.count
40
+ real_response = real_response[s*2..real_response.length]
41
+ i += 1
20
42
  end
43
+ values
21
44
  end
22
45
  end
23
46
 
@@ -19,11 +19,9 @@ module Etheruby
19
19
 
20
20
  def treat_variable(param, arg, direction)
21
21
  if match = TypeMatchers.is_sized_type(param)
22
- # Parameter is a sized type, e.g. uint256, byte32 ...
23
22
  klass = Etheruby::Encoders.const_get(match[1].capitalize)
24
- return case klass
25
- when Encoders::Bytes
26
- Byte.new(match[2].to_i, arg)
23
+ if match[1] == 'bytes'
24
+ Encoders::Byte.new(match[2].to_i, arg)
27
25
  else
28
26
  klass.new(arg)
29
27
  end.send(direction)
@@ -42,7 +40,7 @@ module Etheruby
42
40
  Etheruby::Encoders::DynamicArray.new(match[1], arg).send(direction)
43
41
 
44
42
  else
45
- # Parameter is a single-word type : string, bytes, address etc...
43
+ # Parameter is a single-word type : string, bytes, address, function etc...
46
44
  Etheruby::Encoders.const_get(param.capitalize).new(arg).send(direction)
47
45
 
48
46
  end
metadata CHANGED
@@ -1,57 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: etheruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jérémy SEBAN
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-17 00:00:00.000000000 Z
11
+ date: 2017-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: digest-sha3
14
+ name: simplecov
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.1'
19
+ version: '0.12'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.1'
26
+ version: '0.12'
27
27
  - !ruby/object:Gem::Dependency
28
- name: simplecov
28
+ name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.12'
33
+ version: '12.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0.12'
40
+ version: '12.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rake
42
+ name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '12.0'
47
+ version: '3.5'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '12.0'
54
+ version: '3.5'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: multi_json
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -67,19 +67,19 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '1.12'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rspec
70
+ name: digest-sha3
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '3.5'
75
+ version: '1.1'
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '3.5'
82
+ version: '1.1'
83
83
  description: Etheruby is a library including a client for the JSON-RPC API and a Object-Contract
84
84
  Mapper to interact with smart-contracts.
85
85
  email: jeremy@seban.eu
@@ -90,6 +90,7 @@ files:
90
90
  - lib/etheruby.rb
91
91
  - lib/etheruby/arguments_generator.rb
92
92
  - lib/etheruby/client.rb
93
+ - lib/etheruby/contract.rb
93
94
  - lib/etheruby/contract_method_dsl.rb
94
95
  - lib/etheruby/encoders/address.rb
95
96
  - lib/etheruby/encoders/arrays.rb
@@ -97,8 +98,10 @@ files:
97
98
  - lib/etheruby/encoders/bool.rb
98
99
  - lib/etheruby/encoders/bytes.rb
99
100
  - lib/etheruby/encoders/fixed.rb
101
+ - lib/etheruby/encoders/function.rb
100
102
  - lib/etheruby/encoders/int.rb
101
103
  - lib/etheruby/encoders/string.rb
104
+ - lib/etheruby/railtie.rb
102
105
  - lib/etheruby/response_parser.rb
103
106
  - lib/etheruby/treat_variable.rb
104
107
  - lib/etheruby/type_matchers.rb
@@ -125,5 +128,5 @@ rubyforge_project:
125
128
  rubygems_version: 2.4.5
126
129
  signing_key:
127
130
  specification_version: 4
128
- summary: 'Etheruby : Ethereum smart-contract classy-describer for Ruby.'
131
+ summary: 'Etheruby : The Ethereum Object-Contract Mapper (OCM) for Ruby.'
129
132
  test_files: []