Class: EvmClient::Decoder

Inherits:
Object
  • Object
show all
Defined in:
lib/evm_client/decoder.rb

Instance Method Summary collapse

Instance Method Details

#decode(type, value, start = 0) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
# File 'lib/evm_client/decoder.rb', line 4

def decode(type, value, start = 0)
  is_array, arity, array_subtype = Abi::parse_array_type(type)
  if is_array && arity
    decode_static_array(arity, array_subtype, value, start)
  elsif is_array
    decode_dynamic_array(array_subtype, value, start)
  else
    value = value.gsub(/^0x/,'')
    core, subtype = Abi::parse_type(type)
    method_name = "decode_#{core}".to_sym
    self.send(method_name, value, subtype, start)
  end
end

#decode_address(value, _ = nil, start) ⇒ Object

Raises:

  • (ArgumentError)


50
51
52
53
# File 'lib/evm_client/decoder.rb', line 50

def decode_address(value, _ = nil, start)
  raise ArgumentError if value.size-start < 64
  value[start+24..start+63]
end

#decode_arguments(arguments, data) ⇒ Object



73
74
75
76
77
# File 'lib/evm_client/decoder.rb', line 73

def decode_arguments(arguments, data)
  data = data.gsub(/^0x/,'')
  types = arguments.map { |o| o.type }
  types.each.with_index.map { |t , i| decode(t, data, i*64) }
end

#decode_bool(value, _, start) ⇒ Object

Raises:

  • (ArgumentError)


43
44
45
46
47
48
# File 'lib/evm_client/decoder.rb', line 43

def decode_bool(value, _, start)
  value = trim(value, start, 4)
  return true if value == "1"
  return false if value == "0"
  raise ArgumentError
end

#decode_bytes(value, subtype, start) ⇒ Object



55
56
57
# File 'lib/evm_client/decoder.rb', line 55

def decode_bytes(value, subtype, start)
  subtype.present? ? decode_static_bytes(value, subtype, start) : decode_dynamic_bytes(value, start)
end

#decode_dynamic_array(array_subtype, value, start) ⇒ Object



22
23
24
25
26
# File 'lib/evm_client/decoder.rb', line 22

def decode_dynamic_array(array_subtype, value, start)
  location = decode_uint(value[start..(start+63)]) * 2
  size = decode_uint(value[location..location+63])
  (0..size-1).map { |i| decode(array_subtype, value, location + (i+1) * 64) }
end

#decode_dynamic_bytes(value, start = 0) ⇒ Object



63
64
65
66
67
# File 'lib/evm_client/decoder.rb', line 63

def decode_dynamic_bytes(value, start = 0)
  location = decode_uint(value[start..(start+63)]) * 2
  size = decode_uint(value[location..location+63]) * 2
  value[location+64..location+63+size].scan(/.{2}/).collect {|x| x.hex}.pack('C*')
end

#decode_fixed(value, subtype = "128x128", start = 0) ⇒ Object



28
29
30
# File 'lib/evm_client/decoder.rb', line 28

def decode_fixed(value, subtype = "128x128", start = 0)
  decode_int(trim(value, start, fixed_bitsize(subtype))).to_f / 2**exponent(subtype)
end

#decode_int(value, subtype = "256", start = 0) ⇒ Object

Raises:

  • (ArgumentError)


36
37
38
39
40
41
# File 'lib/evm_client/decoder.rb', line 36

def decode_int(value, subtype = "256", start = 0)
  raise ArgumentError if value.nil?
  size = bitsize(subtype)
  value = trim(value, start, size)
  (value[0..1] == "ff") ? (value.hex - (2 ** size)) : value.hex
end

#decode_static_array(arity, array_subtype, value, start) ⇒ Object



18
19
20
# File 'lib/evm_client/decoder.rb', line 18

def decode_static_array(arity, array_subtype, value, start)
  (0..arity-1).map { |i| decode(array_subtype, value, start + i * 64) }
end

#decode_static_bytes(value, subtype = nil, start = 0) ⇒ Object



59
60
61
# File 'lib/evm_client/decoder.rb', line 59

def decode_static_bytes(value, subtype = nil, start = 0)
  trim(value, start, subtype.to_i*8).scan(/.{2}/).collect {|x| x.hex}.pack('C*').strip
end

#decode_string(value, _ = nil, start = 0) ⇒ Object



69
70
71
# File 'lib/evm_client/decoder.rb', line 69

def decode_string(value, _ = nil, start = 0)
  decode_dynamic_bytes(value, start).force_encoding('utf-8')
end

#decode_uint(value, subtype = "256", start = 0) ⇒ Object



32
33
34
# File 'lib/evm_client/decoder.rb', line 32

def decode_uint(value, subtype = "256", start = 0)
  trim(value, start, bitsize(subtype)).hex
end