etheruby 0.0.3 → 0.1.0
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/lib/etheruby/arguments_generator.rb +17 -121
- data/lib/etheruby/encoders/address.rb +17 -0
- data/lib/etheruby/encoders/arrays.rb +91 -0
- data/lib/etheruby/encoders/base.rb +28 -0
- data/lib/etheruby/encoders/bool.rb +16 -0
- data/lib/etheruby/encoders/bytes.rb +41 -0
- data/lib/etheruby/encoders/fixed.rb +78 -0
- data/lib/etheruby/encoders/int.rb +41 -0
- data/lib/etheruby/encoders/string.rb +17 -0
- data/lib/etheruby/response_parser.rb +8 -92
- data/lib/etheruby/treat_variable.rb +52 -0
- data/lib/etheruby/type_matchers.rb +1 -1
- data/lib/etheruby.rb +5 -1
- metadata +10 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62e7a1ef2415572fb35e1617898576247fabeccb
|
4
|
+
data.tar.gz: 9f6747ff369f23fe11f3a67c0b815b6a53bbfd72
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b5deae709916778cfd2e39217f22edb24929da0a57054cd5020a0882e8bf222d3b1928d90140a21ce99f9aaeb0eb103f4172031f1d9b857f05aee62ea39e9648
|
7
|
+
data.tar.gz: f725746f91570b71d37d89b62c241945688603fedaf17f0fb56db178511eb73206edd72d9d45fba75b88ebdb16458765e242166222d81765b7c03649e99b9051
|
@@ -1,11 +1,11 @@
|
|
1
1
|
require 'bigdecimal'
|
2
2
|
require_relative 'type_matchers'
|
3
|
+
require_relative 'treat_variable'
|
4
|
+
require_relative 'encoders/int'
|
3
5
|
|
4
6
|
module Etheruby
|
5
7
|
|
6
|
-
class IncorrectTypeError < StandardError; end
|
7
8
|
class ArgumentsCountError < StandardError; end
|
8
|
-
class InvalidFormatForDataError < StandardError; end
|
9
9
|
|
10
10
|
class ArgumentsGenerator
|
11
11
|
|
@@ -16,127 +16,23 @@ module Etheruby
|
|
16
16
|
@args = args
|
17
17
|
end
|
18
18
|
|
19
|
-
def treat_variable(param, arg)
|
20
|
-
if match = TypeMatchers.is_sized_type(param)
|
21
|
-
# Parameter is a sized type, e.g. uint256, byte32 ...
|
22
|
-
send("#{match[1]}_encode".to_sym, match[2].to_i, arg)
|
23
|
-
|
24
|
-
elsif match = TypeMatchers.is_dualsized_type(param)
|
25
|
-
# Parameter is a dual sized array type, e.g. fixed16x16
|
26
|
-
send("#{match[1]}_encode".to_sym, match[2].to_i, match[3].to_i, arg)
|
27
|
-
|
28
|
-
elsif match = TypeMatchers.is_static_array_type(param)
|
29
|
-
# Parameter is a staticly sized array type, e.g. uint256[24]
|
30
|
-
static_array_encode(match[1], match[2].to_i, arg)
|
31
|
-
|
32
|
-
elsif match = TypeMatchers.is_dynamic_array_type(param)
|
33
|
-
# Parameter is a dynamicaly sized array type, e.g. uint256[]
|
34
|
-
dynamic_array_encode(match[1], arg)
|
35
|
-
|
36
|
-
else
|
37
|
-
# Parameter is a single-word type : string, bytes, address etc...
|
38
|
-
send("#{param}_encode".to_sym, arg)
|
39
|
-
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
19
|
def to_s
|
44
|
-
raise ArgumentsCountError.new unless
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
##
|
60
|
-
# uint<X> encoding
|
61
|
-
def uint_encode(size, arg)
|
62
|
-
raise InvalidFormatForDataError.new("unsigned integer #{arg} < 0") if arg < 0
|
63
|
-
int_encode(size, arg)
|
64
|
-
end
|
65
|
-
|
66
|
-
##
|
67
|
-
# ufixed<X> encoding
|
68
|
-
def ufixed_encode(size_i, size_d, arg)
|
69
|
-
raise InvalidFormatForDataError.new("unsigned fixed #{arg} < 0") if arg < 0
|
70
|
-
fixed_encode(size_i, size_d, arg)
|
71
|
-
end
|
72
|
-
|
73
|
-
##
|
74
|
-
# fixed<X> encoding
|
75
|
-
def fixed_encode(size_i, size_d, arg)
|
76
|
-
raise InvalidFormatForDataError.new("Please use BigDecimal !") unless arg.is_a? BigDecimal
|
77
|
-
if arg >= 0
|
78
|
-
int_part, dec_part = arg.to_i, arg - arg.to_i
|
79
|
-
else
|
80
|
-
int_part, dec_part = arg.to_i, (arg + arg.to_i.abs).abs
|
20
|
+
raise ArgumentsCountError.new("Bad number of arguments") unless args.count == params.count
|
21
|
+
head = ''
|
22
|
+
tail = ''
|
23
|
+
current_tail_position = (params.count*32)
|
24
|
+
(0..params.count-1).each do |i|
|
25
|
+
param, arg = params[i], args[i]
|
26
|
+
if Etheruby.is_static_type? param
|
27
|
+
head += Etheruby.treat_variable(param, arg, :encode).to_s
|
28
|
+
else
|
29
|
+
head += Etheruby::Encoders::Uint.new(current_tail_position).encode
|
30
|
+
content = Etheruby.treat_variable(param, arg, :encode).to_s
|
31
|
+
current_tail_position += content.length/2
|
32
|
+
tail += content
|
33
|
+
end
|
81
34
|
end
|
82
|
-
|
83
|
-
decimal_representation(size_d, dec_part)
|
84
|
-
end
|
85
|
-
|
86
|
-
##
|
87
|
-
# Represent the decimal part in hexadimal according to the precision
|
88
|
-
def decimal_representation(precision, value)
|
89
|
-
(0..precision-1).map {
|
90
|
-
int_part, value = (value*2).to_i, (value*2) - (value*2).to_i
|
91
|
-
int_part
|
92
|
-
}.each_slice(8).map { |slice|
|
93
|
-
slice.join.to_i(2).to_s(16).rjust(2,'0')
|
94
|
-
}.join
|
95
|
-
end
|
96
|
-
|
97
|
-
##
|
98
|
-
# Encode a static array
|
99
|
-
def static_array_encode(type, size, arg)
|
100
|
-
raise InvalidFormatForDataError.new(
|
101
|
-
"Array have #{arg.count} items for #{size} sized variable"
|
102
|
-
) unless arg.count == size
|
103
|
-
arg.map { |item| treat_variable(type, item) }.join
|
104
|
-
end
|
105
|
-
|
106
|
-
##
|
107
|
-
# Creates a dynamic array
|
108
|
-
def dynamic_array_encode(type, arg)
|
109
|
-
uint_encode(256, arg.count) + static_array_encode(type, arg.count, arg)
|
110
|
-
end
|
111
|
-
|
112
|
-
##
|
113
|
-
# byte<X> encodeing
|
114
|
-
def byte_encode(size, arg)
|
115
|
-
arg.map{ |b| b.to_s(16).rjust(2,'0') }.join.rjust(size,'0')
|
116
|
-
end
|
117
|
-
|
118
|
-
##
|
119
|
-
# address<X> encoding
|
120
|
-
def address_encode(arg)
|
121
|
-
uint_encode(160, arg)
|
122
|
-
end
|
123
|
-
|
124
|
-
##
|
125
|
-
# string<x> encoding (as bytes)
|
126
|
-
def string_encode(arg)
|
127
|
-
bytes_encode(arg.codepoints)
|
128
|
-
end
|
129
|
-
|
130
|
-
##
|
131
|
-
# bytes (dynamic size) encoding
|
132
|
-
def bytes_encode(arg)
|
133
|
-
uint_encode(256, arg.count) + arg.map{ |b| b.to_s(16).rjust(2,'0') }.join
|
134
|
-
end
|
135
|
-
|
136
|
-
##
|
137
|
-
# boolean encoding (as uint8)
|
138
|
-
def bool_encode(arg)
|
139
|
-
uint_encode(8, arg ? 1 : 0)
|
35
|
+
return head + tail
|
140
36
|
end
|
141
37
|
|
142
38
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
require_relative 'int'
|
3
|
+
|
4
|
+
module Etheruby::Encoders
|
5
|
+
|
6
|
+
class Address < Base
|
7
|
+
def encode
|
8
|
+
Uint.new(data).encode
|
9
|
+
end
|
10
|
+
|
11
|
+
def decode
|
12
|
+
v, s = Uint.new(data).decode
|
13
|
+
return "0x#{v.to_s(16)}", s
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
require_relative 'int'
|
3
|
+
require_relative '../treat_variable'
|
4
|
+
|
5
|
+
module Etheruby::Encoders
|
6
|
+
|
7
|
+
class StaticArray < Base
|
8
|
+
|
9
|
+
attr_reader :type, :size
|
10
|
+
|
11
|
+
def initialize(_type, _size, _data)
|
12
|
+
super(_data)
|
13
|
+
@type = _type
|
14
|
+
@size = _size
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
encode
|
19
|
+
end
|
20
|
+
|
21
|
+
def encode
|
22
|
+
if Etheruby::is_static_type? type
|
23
|
+
data.map{ |d| Etheruby::treat_variable(type, d, :encode) }.join
|
24
|
+
else
|
25
|
+
head_x = ''
|
26
|
+
enc_x = ''
|
27
|
+
c_pos = size * 32
|
28
|
+
data.map { |d|
|
29
|
+
treated = Etheruby::treat_variable(type, d, :encode)
|
30
|
+
{size: treated.length/2, value: treated}
|
31
|
+
}.each { |item|
|
32
|
+
head_x += Uint.new(c_pos).encode
|
33
|
+
c_pos += item[:size]
|
34
|
+
enc_x += item[:value]
|
35
|
+
}
|
36
|
+
head_x + enc_x
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def decode
|
41
|
+
if Etheruby::is_static_type?(type)
|
42
|
+
sub_decode(0, data)
|
43
|
+
else
|
44
|
+
sub_decode(size*32, data[size*2*32..data.length])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def sub_decode(total_taken, real_data)
|
51
|
+
values = []
|
52
|
+
loop do
|
53
|
+
v, s = Etheruby::treat_variable(type, real_data, :decode)
|
54
|
+
v, s = v.decode if v.is_a? StaticArray or v.is_a? DynamicArray
|
55
|
+
values << v
|
56
|
+
total_taken += s
|
57
|
+
break if values.count == size
|
58
|
+
real_data = real_data[s*2..real_data.length]
|
59
|
+
end
|
60
|
+
return values, total_taken
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
class DynamicArray < Base
|
66
|
+
|
67
|
+
attr_reader :type
|
68
|
+
|
69
|
+
def initialize(_type, _data)
|
70
|
+
super(_data)
|
71
|
+
@type = _type
|
72
|
+
end
|
73
|
+
|
74
|
+
def to_s
|
75
|
+
encode
|
76
|
+
end
|
77
|
+
|
78
|
+
def encode
|
79
|
+
Uint.new(data.count).encode + \
|
80
|
+
StaticArray.new(type, data.count, data).encode
|
81
|
+
end
|
82
|
+
|
83
|
+
def decode
|
84
|
+
size, taken = Uint.new(data[0..63]).decode
|
85
|
+
v, s = StaticArray.new(type, size, data[64..data.length]).decode
|
86
|
+
return v, s+taken
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Etheruby
|
2
|
+
|
3
|
+
module Encoders
|
4
|
+
|
5
|
+
class IncorrectTypeError < StandardError; end
|
6
|
+
class InvalidFormatForDataError < StandardError; end
|
7
|
+
|
8
|
+
class Base
|
9
|
+
attr_reader :data
|
10
|
+
|
11
|
+
def initialize(_data)
|
12
|
+
@data = _data
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def determinate_closest_padding(size)
|
18
|
+
if size % 32 == 0
|
19
|
+
size
|
20
|
+
else
|
21
|
+
32*(size/32+1)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
require_relative 'int'
|
3
|
+
|
4
|
+
module Etheruby::Encoders
|
5
|
+
|
6
|
+
class Byte < Base
|
7
|
+
|
8
|
+
attr_reader :size
|
9
|
+
|
10
|
+
def initialize(_size,_data)
|
11
|
+
super(_data)
|
12
|
+
@size = _size
|
13
|
+
end
|
14
|
+
|
15
|
+
def encode
|
16
|
+
data.map{ |b|
|
17
|
+
b.to_s(16).rjust(2,'0')
|
18
|
+
}.join.ljust(determinate_closest_padding(size)*2, '0')
|
19
|
+
end
|
20
|
+
|
21
|
+
def decode
|
22
|
+
return data[0..(size*2)-1].split('').each_slice(2).map{ |b| b.join.to_i(16) },
|
23
|
+
determinate_closest_padding(size)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
class Bytes < Base
|
29
|
+
|
30
|
+
def encode
|
31
|
+
Uint.new(data.length).encode + Byte.new(data.length, data).encode
|
32
|
+
end
|
33
|
+
|
34
|
+
def decode
|
35
|
+
size = Uint.new(data[0..63]).decode[0]
|
36
|
+
return Byte.new(size,data[64..data.length]).decode[0], determinate_closest_padding(size+32)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
require_relative 'int'
|
3
|
+
|
4
|
+
module Etheruby::Encoders
|
5
|
+
|
6
|
+
class FixedBase < Base
|
7
|
+
attr_reader :size_i, :size_d
|
8
|
+
|
9
|
+
def initialize(_size_i, _size_d, _data)
|
10
|
+
super(_data)
|
11
|
+
@size_i = _size_i
|
12
|
+
@size_d = _size_d
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def encode_decimal_representation(value)
|
18
|
+
(0..@size_d-1).map {
|
19
|
+
int_part, value = (value*2).to_i, (value*2) - (value*2).to_i
|
20
|
+
int_part
|
21
|
+
}.each_slice(8).map { |slice|
|
22
|
+
slice.join.to_i(2).to_s(16).rjust(2,'0')
|
23
|
+
}.join
|
24
|
+
end
|
25
|
+
|
26
|
+
def decode_decimal_representation(part)
|
27
|
+
value = 0.0
|
28
|
+
exp = -1
|
29
|
+
bin_rpr = part.to_i(16).to_s(2).rjust(@size_d,'0')
|
30
|
+
bin_rpr.split("").each do |bit|
|
31
|
+
value += 2**exp if bit == '1'
|
32
|
+
exp -= 1
|
33
|
+
end
|
34
|
+
value
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class Fixed < FixedBase
|
39
|
+
|
40
|
+
def encode
|
41
|
+
if data >= 0
|
42
|
+
int_part, dec_part = data.to_i, data - data.to_i
|
43
|
+
else
|
44
|
+
int_part, dec_part = data.to_i, (data + data.to_i.abs).abs
|
45
|
+
end
|
46
|
+
Int.new(int_part).encode(size_i/4) + \
|
47
|
+
encode_decimal_representation(dec_part).ljust((256-size_i)/4,'0')
|
48
|
+
end
|
49
|
+
|
50
|
+
def decode
|
51
|
+
@data = data[0..63]
|
52
|
+
int_part = Int.new(data[0..(size_i/4)-1]).decode[0]
|
53
|
+
dec_part = decode_decimal_representation(data[(size_i / 4)..data.length])
|
54
|
+
if int_part >= 0
|
55
|
+
return (dec_part + int_part), 32
|
56
|
+
else
|
57
|
+
return -(dec_part + int_part.abs), 32
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
class Ufixed < FixedBase
|
64
|
+
|
65
|
+
def encode
|
66
|
+
raise InvalidFormatForDataError.new("Unsigned fixed #{data} < 0") if data < 0
|
67
|
+
Fixed.new(size_i, size_d, data).encode
|
68
|
+
end
|
69
|
+
|
70
|
+
def decode
|
71
|
+
@data = data[0..63]
|
72
|
+
return Uint.new(data[0..(size_i/4)-1]).decode[0] +
|
73
|
+
decode_decimal_representation(data[(size_i / 4)..data.length]), 32
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module Etheruby::Encoders
|
4
|
+
|
5
|
+
class Int < Base
|
6
|
+
|
7
|
+
def encode(pad_to=64)
|
8
|
+
if data >= 0
|
9
|
+
data.to_s(16).rjust(pad_to, '0')
|
10
|
+
else
|
11
|
+
mask = (1 << pad_to*4) - 1
|
12
|
+
(data & mask).to_s(16).rjust(pad_to, 'f')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def decode
|
17
|
+
in_int = data[0..63].to_i(16)
|
18
|
+
in_bin = in_int.to_s(2).rjust(64, '0')
|
19
|
+
if in_bin[0] == '1'
|
20
|
+
return -(in_bin.split("").map{ |i| i == '1' ? '0' : '1' }.join.to_i(2) + 1), 32
|
21
|
+
else
|
22
|
+
return in_int, 32
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
class Uint < Base
|
29
|
+
|
30
|
+
def encode(pad_to=64)
|
31
|
+
raise InvalidFormatForDataError.new("Unsigned integer #{data} < 0") if data < 0
|
32
|
+
Int.new(data).encode(pad_to)
|
33
|
+
end
|
34
|
+
|
35
|
+
def decode
|
36
|
+
return data[0..63].to_i(16), 32
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
require_relative 'bytes'
|
3
|
+
|
4
|
+
module Etheruby::Encoders
|
5
|
+
|
6
|
+
class String < Base
|
7
|
+
def encode
|
8
|
+
Bytes.new(data.codepoints).encode
|
9
|
+
end
|
10
|
+
|
11
|
+
def decode
|
12
|
+
v, s = Bytes.new(data).decode
|
13
|
+
return v.pack('U*'), s
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -4,107 +4,23 @@ module Etheruby
|
|
4
4
|
|
5
5
|
class ResponseParser
|
6
6
|
|
7
|
+
attr_reader :returns, :response
|
8
|
+
|
7
9
|
def initialize(_returns, _response)
|
8
10
|
@returns = _returns
|
9
|
-
@response = _response
|
10
|
-
end
|
11
|
-
|
12
|
-
def treat_variable(param)
|
13
|
-
if match = TypeMatchers.is_sized_type(param)
|
14
|
-
# Parameter is a sized type, e.g. uint256, byte32 ...
|
15
|
-
send("#{match[1]}_decode".to_sym, match[2].to_i)
|
16
|
-
|
17
|
-
elsif match = TypeMatchers.is_dualsized_type(param)
|
18
|
-
# Parameter is a dual sized array type, e.g. fixed16x16
|
19
|
-
send("#{match[1]}_decode".to_sym, match[2].to_i, match[3].to_i)
|
20
|
-
|
21
|
-
elsif match = TypeMatchers.is_static_array_type(param)
|
22
|
-
# Parameter is a staticly sized array type, e.g. uint256[24]
|
23
|
-
static_array_decode(match[1], match[2].to_i)
|
24
|
-
|
25
|
-
elsif match = TypeMatchers.is_dynamic_array_type(param)
|
26
|
-
# Parameter is a dynamicaly sized array type, e.g. uint256[]
|
27
|
-
dynamic_array_decode(match[1])
|
28
|
-
|
29
|
-
else
|
30
|
-
# Parameter is a single-word type : string, bytes, address etc...
|
31
|
-
send("#{param}_decode".to_sym)
|
32
|
-
|
33
|
-
end
|
11
|
+
@response = _response[2.._response.length]
|
34
12
|
end
|
35
13
|
|
36
14
|
def parse
|
37
|
-
if
|
38
|
-
treat_variable(
|
15
|
+
if returns.count == 1
|
16
|
+
Etheruby::treat_variable(returns[0], response, :decode)
|
39
17
|
else
|
40
|
-
|
18
|
+
returns.each do |type|
|
19
|
+
|
20
|
+
end
|
41
21
|
end
|
42
22
|
end
|
43
23
|
|
44
|
-
# Each decode method will receive in parameters the response string remaining
|
45
|
-
# to parse. It will extract the type of the response considering it as the
|
46
|
-
# first thing in the string and returns the string without it. Doing this,
|
47
|
-
# method calls will be chainable easily.
|
48
|
-
|
49
|
-
##
|
50
|
-
# int<X> decoding
|
51
|
-
def int_decode(size)
|
52
|
-
end
|
53
|
-
|
54
|
-
##
|
55
|
-
# uint<X> decoding
|
56
|
-
def uint_decode(size)
|
57
|
-
v, @response = @response[0..(size/4)].to_i(16),
|
58
|
-
@response[(size/4)..@response.length]
|
59
|
-
v
|
60
|
-
end
|
61
|
-
|
62
|
-
##
|
63
|
-
# ufixed<X> decoding
|
64
|
-
def ufixed_decode(size_i, size_d)
|
65
|
-
end
|
66
|
-
|
67
|
-
##
|
68
|
-
# fixed<X> decoding
|
69
|
-
def fixed_decode(size_i, size_d)
|
70
|
-
end
|
71
|
-
|
72
|
-
##
|
73
|
-
# Decodes a static array
|
74
|
-
def static_array_decode(type, size)
|
75
|
-
end
|
76
|
-
|
77
|
-
##
|
78
|
-
# Decodes a dynamic array
|
79
|
-
def dynamic_array_decode(type)
|
80
|
-
end
|
81
|
-
|
82
|
-
##
|
83
|
-
# byte<X> decoding
|
84
|
-
def byte_decode(size)
|
85
|
-
end
|
86
|
-
|
87
|
-
##
|
88
|
-
# address<X> decoding
|
89
|
-
def address_decode
|
90
|
-
end
|
91
|
-
|
92
|
-
##
|
93
|
-
# string<x> decoding (as bytes)
|
94
|
-
def string_decode
|
95
|
-
end
|
96
|
-
|
97
|
-
##
|
98
|
-
# bytes (dynamic size) decoding
|
99
|
-
def bytes_decode
|
100
|
-
end
|
101
|
-
|
102
|
-
##
|
103
|
-
# boolean decoding (as uint8)
|
104
|
-
def bool_decode
|
105
|
-
uint_decode(8) == 1
|
106
|
-
end
|
107
|
-
|
108
24
|
end
|
109
25
|
|
110
26
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require_relative 'encoders/address'
|
2
|
+
require_relative 'encoders/arrays'
|
3
|
+
require_relative 'encoders/bool'
|
4
|
+
require_relative 'encoders/bytes'
|
5
|
+
require_relative 'encoders/fixed'
|
6
|
+
require_relative 'encoders/int'
|
7
|
+
require_relative 'encoders/string'
|
8
|
+
require_relative 'type_matchers'
|
9
|
+
|
10
|
+
module Etheruby
|
11
|
+
|
12
|
+
def is_static_type?(param)
|
13
|
+
!(%w(string bytes).include?(param.to_s) || TypeMatchers.is_dynamic_array_type(param))
|
14
|
+
end
|
15
|
+
|
16
|
+
def is_array?(param)
|
17
|
+
TypeMatchers.is_static_array_type(param) || TypeMatchers.is_dynamic_array_type(param)
|
18
|
+
end
|
19
|
+
|
20
|
+
def treat_variable(param, arg, direction)
|
21
|
+
if match = TypeMatchers.is_sized_type(param)
|
22
|
+
# Parameter is a sized type, e.g. uint256, byte32 ...
|
23
|
+
klass = Etheruby::Encoders.const_get(match[1].capitalize)
|
24
|
+
return case klass
|
25
|
+
when Encoders::Bytes
|
26
|
+
Byte.new(match[2].to_i, arg)
|
27
|
+
else
|
28
|
+
klass.new(arg)
|
29
|
+
end.send(direction)
|
30
|
+
|
31
|
+
elsif match = TypeMatchers.is_dualsized_type(param)
|
32
|
+
# Parameter is a dual sized array type, e.g. fixed16x16, ufixed128x128
|
33
|
+
return Etheruby::Encoders.const_get(match[1].capitalize).
|
34
|
+
new(match[2].to_i, match[3].to_i, arg).send(direction)
|
35
|
+
|
36
|
+
elsif match = TypeMatchers.is_static_array_type(param)
|
37
|
+
# Parameter is a staticly sized array type, e.g. uint256[24]
|
38
|
+
Etheruby::Encoders::StaticArray.new(match[1], match[2].to_i, arg)
|
39
|
+
|
40
|
+
elsif match = TypeMatchers.is_dynamic_array_type(param)
|
41
|
+
# Parameter is a dynamicaly sized array type, e.g. uint256[]
|
42
|
+
Etheruby::Encoders::DynamicArray.new(match[1], arg).send(direction)
|
43
|
+
|
44
|
+
else
|
45
|
+
# Parameter is a single-word type : string, bytes, address etc...
|
46
|
+
Etheruby::Encoders.const_get(param.capitalize).new(arg).send(direction)
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
module_function :treat_variable, :is_static_type?, :is_array?
|
52
|
+
end
|
data/lib/etheruby.rb
CHANGED
@@ -47,7 +47,7 @@ module Etheruby
|
|
47
47
|
composed_body[kw] = method_info[kw] if method_info.has_key? kw
|
48
48
|
}
|
49
49
|
@@logger.debug("Calling #{method_info[:name]} with parameters #{composed_body.inspect}")
|
50
|
-
response =
|
50
|
+
response = call_api composed_body
|
51
51
|
if response.has_key? 'error'
|
52
52
|
@@logger.error("Failed contract execution #{response['error']['message']}")
|
53
53
|
else
|
@@ -60,6 +60,10 @@ module Etheruby
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
+
def self.call_api(composed_body)
|
64
|
+
Client.eth.call composed_body, "latest"
|
65
|
+
end
|
66
|
+
|
63
67
|
def self.address
|
64
68
|
"0x#{@@address.to_s(16)}"
|
65
69
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: etheruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jérémy SEBAN
|
@@ -91,7 +91,16 @@ files:
|
|
91
91
|
- lib/etheruby/arguments_generator.rb
|
92
92
|
- lib/etheruby/client.rb
|
93
93
|
- lib/etheruby/contract_method_dsl.rb
|
94
|
+
- lib/etheruby/encoders/address.rb
|
95
|
+
- lib/etheruby/encoders/arrays.rb
|
96
|
+
- lib/etheruby/encoders/base.rb
|
97
|
+
- lib/etheruby/encoders/bool.rb
|
98
|
+
- lib/etheruby/encoders/bytes.rb
|
99
|
+
- lib/etheruby/encoders/fixed.rb
|
100
|
+
- lib/etheruby/encoders/int.rb
|
101
|
+
- lib/etheruby/encoders/string.rb
|
94
102
|
- lib/etheruby/response_parser.rb
|
103
|
+
- lib/etheruby/treat_variable.rb
|
95
104
|
- lib/etheruby/type_matchers.rb
|
96
105
|
homepage: https://github.com/MechanicalSloth/etheruby
|
97
106
|
licenses:
|