Module: Eth::Abi::Function

Extended by:
Function
Included in:
Function
Defined in:
lib/eth/abi/function.rb

Overview

Provides a module to decode transaction input data.

Defined Under Namespace

Classes: CallDescription

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.decode(interfaces, data) ⇒ CallDescription?

Decodes a transaction input with a set of ABI interfaces.

Parameters:

  • interfaces (Array)

    function ABI types.

  • data (String)

    transaction input data.

Returns:

  • (CallDescription, nil)

    a CallDescription object or nil if selector unknown.



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/eth/abi/function.rb', line 104

def decode(interfaces, data)
  data = Util.remove_hex_prefix(data)
  selector = Util.prefix_hex(data[0, 8])
  payload = Util.prefix_hex(data[8..] || "")

  selector_to_interfaces = Hash[interfaces.map { |i| [selector(i), i] }]
  if (interface = selector_to_interfaces[selector])
    inputs = interface.fetch("inputs", [])
    types = inputs.map { |i| type(i) }
    args = Abi.decode(types, payload)
    kwargs = {}
    inputs.each_with_index do |input, i|
      name = input.fetch("name", "")
      kwargs[name.to_sym] = args[i] unless name.empty?
    end
    CallDescription.new(interface, selector, args, kwargs)
  end
end

.selector(interface) ⇒ String

Compute selector for ABI function interface.

Parameters:

  • interface (Hash)

    ABI function interface.

Returns:

  • (String)

    a hex-string selector.



42
43
44
45
# File 'lib/eth/abi/function.rb', line 42

def selector(interface)
  sig = signature(interface)
  Util.prefix_hex(Util.bin_to_hex(Util.keccak256(sig))[0, 8])
end

.signature(interface) ⇒ String

Build function signature string from ABI interface.

Parameters:

  • interface (Hash)

    ABI function interface.

Returns:

  • (String)

    interface signature string.



31
32
33
34
35
36
# File 'lib/eth/abi/function.rb', line 31

def signature(interface)
  name = interface.fetch("name")
  inputs = interface.fetch("inputs", [])
  types = inputs.map { |i| type(i) }
  "#{name}(#{types.join(",")})"
end

.type(input) ⇒ String

Gets the input type for functions.

Parameters:

  • input (Hash)

    function input.

Returns:

  • (String)

    input type.



51
52
53
54
55
56
57
58
59
# File 'lib/eth/abi/function.rb', line 51

def type(input)
  if input["type"] == "tuple"
    "(#{input["components"].map { |c| type(c) }.join(",")})"
  elsif input["type"] == "enum"
    "uint8"
  else
    input["type"]
  end
end

Instance Method Details

#decode(interfaces, data) ⇒ CallDescription?

Decodes a transaction input with a set of ABI interfaces.

Parameters:

  • interfaces (Array)

    function ABI types.

  • data (String)

    transaction input data.

Returns:

  • (CallDescription, nil)

    a CallDescription object or nil if selector unknown.



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/eth/abi/function.rb', line 104

def decode(interfaces, data)
  data = Util.remove_hex_prefix(data)
  selector = Util.prefix_hex(data[0, 8])
  payload = Util.prefix_hex(data[8..] || "")

  selector_to_interfaces = Hash[interfaces.map { |i| [selector(i), i] }]
  if (interface = selector_to_interfaces[selector])
    inputs = interface.fetch("inputs", [])
    types = inputs.map { |i| type(i) }
    args = Abi.decode(types, payload)
    kwargs = {}
    inputs.each_with_index do |input, i|
      name = input.fetch("name", "")
      kwargs[name.to_sym] = args[i] unless name.empty?
    end
    CallDescription.new(interface, selector, args, kwargs)
  end
end

#selector(interface) ⇒ String

Compute selector for ABI function interface.

Parameters:

  • interface (Hash)

    ABI function interface.

Returns:

  • (String)

    a hex-string selector.



42
43
44
45
# File 'lib/eth/abi/function.rb', line 42

def selector(interface)
  sig = signature(interface)
  Util.prefix_hex(Util.bin_to_hex(Util.keccak256(sig))[0, 8])
end

#signature(interface) ⇒ String

Build function signature string from ABI interface.

Parameters:

  • interface (Hash)

    ABI function interface.

Returns:

  • (String)

    interface signature string.



31
32
33
34
35
36
# File 'lib/eth/abi/function.rb', line 31

def signature(interface)
  name = interface.fetch("name")
  inputs = interface.fetch("inputs", [])
  types = inputs.map { |i| type(i) }
  "#{name}(#{types.join(",")})"
end

#type(input) ⇒ String

Gets the input type for functions.

Parameters:

  • input (Hash)

    function input.

Returns:

  • (String)

    input type.



51
52
53
54
55
56
57
58
59
# File 'lib/eth/abi/function.rb', line 51

def type(input)
  if input["type"] == "tuple"
    "(#{input["components"].map { |c| type(c) }.join(",")})"
  elsif input["type"] == "enum"
    "uint8"
  else
    input["type"]
  end
end