class EvmClient::Decoder

Public Instance Methods

decode(type, value, start = 0) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# 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) click to toggle source
# File lib/evm_client/decoder.rb, line 32
def decode_uint(value, subtype = "256", start = 0)
  trim(value, start, bitsize(subtype)).hex
end

Private Instance Methods

bitsize(subtype, default = 256) click to toggle source
# File lib/evm_client/decoder.rb, line 84
def bitsize(subtype, default = 256)
  subtype.present? ? subtype.to_i : default
end
exponent(subtype, default = 128) click to toggle source
# File lib/evm_client/decoder.rb, line 94
def exponent(subtype, default = 128)
  subtype.nil? ? default : /(\d+)x(\d+)/.match(subtype)[2].to_i
end
fixed_bitsize(subtype = nil) click to toggle source
# File lib/evm_client/decoder.rb, line 88
def fixed_bitsize(subtype = nil)
  subtype ||= "128x128"
  _, x, n = /(\d+)x(\d+)/.match(subtype).to_a
  x.to_i + n.to_i
end
trim(value, start, bitsize = 256) click to toggle source
# File lib/evm_client/decoder.rb, line 80
def trim(value, start, bitsize = 256)
  value[start+63-(bitsize/4-1)..start+63]
end