module Eth::Abi
def decode(types, data)
-
(Array)
- the decoded ABI data.
Parameters:
-
data
(String
) -- ABI data to be decoded. -
types
(Array
) -- the ABI to be decoded.
def decode(types, data) # accept hex abi but decode it first data = Util.hex_to_bin data if Util.is_hex? data # parse all types parsed_types = types.map { |t| Type.parse(t) } # prepare output data outputs = [nil] * types.size start_positions = [nil] * types.size + [data.size] pos = 0 parsed_types.each_with_index do |t, i| if t.is_dynamic? # record start position for dynamic type start_positions[i] = Util.deserialize_big_endian_to_int(data[pos, 32]) j = i - 1 while j >= 0 and start_positions[j].nil? start_positions[j] = start_positions[i] j -= 1 end pos += 32 else # get data directly for static types outputs[i] = data[pos, t.size] pos += t.size end end # add start position equal the length of the entire data j = types.size - 1 while j >= 0 and start_positions[j].nil? start_positions[j] = start_positions[types.size] j -= 1 end raise DecodingError, "Not enough data for head" unless pos <= data.size # add dynamic types parsed_types.each_with_index do |t, i| if t.is_dynamic? offset, next_offset = start_positions[i, 2] outputs[i] = data[offset...next_offset] end end # return the decoded ABI types and data return parsed_types.zip(outputs).map { |(type, out)| decode_type(type, out) } end