Class: EthereumAbi::Type

Inherits:
Object
  • Object
show all
Defined in:
lib/ethereum_abi/type.rb

Defined Under Namespace

Classes: ParseError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base, sub, dims) ⇒ Type

Returns a new instance of Type.

Parameters:

  • base (String)

    base name of type, e.g. uint for uint256

  • sub (String)

    subscript of type, e.g. 256 for uint256

  • dims (Array[Integer])

    dimensions of array type, e.g. [1,2,0] for uint256[2][], [] for non-array type



67
68
69
70
71
# File 'lib/ethereum_abi/type.rb', line 67

def initialize(base, sub, dims)
  @base = base
  @sub  = sub
  @dims = dims
end

Instance Attribute Details

#baseObject (readonly)

Returns the value of attribute base.



59
60
61
# File 'lib/ethereum_abi/type.rb', line 59

def base
  @base
end

#dimsObject (readonly)

Returns the value of attribute dims.



59
60
61
# File 'lib/ethereum_abi/type.rb', line 59

def dims
  @dims
end

#subObject (readonly)

Returns the value of attribute sub.



59
60
61
# File 'lib/ethereum_abi/type.rb', line 59

def sub
  @sub
end

Class Method Details

.parse(type) ⇒ Object

Crazy regexp to seperate out base type component (eg. uint), size (eg. 256, 128x128, nil), array component (eg. [], [45], nil)

Raises:



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/ethereum_abi/type.rb', line 13

def parse(type)
  _, base, sub, dimension = /([a-z]*)([0-9]*x?[0-9]*)((\[[0-9]*\])*)/.match(type).to_a

  dims = dimension.scan(/\[[0-9]*\]/)
  raise ParseError, "Unknown characters found in array declaration" if dims.join != dimension

  case base
  when "string"
    raise ParseError, "String type must have no suffix or numerical suffix" unless sub.empty?
  when "bytes"
    raise ParseError, "Maximum 32 bytes for fixed-length string or bytes" unless sub.empty? || sub.to_i <= 32
  when "uint", "int"
    raise ParseError, "Integer type must have numerical suffix" unless sub =~ /\A[0-9]+\z/

    size = sub.to_i
    raise ParseError, "Integer size out of bounds" unless size >= 8 && size <= 256
    raise ParseError, "Integer size must be multiple of 8" unless (size % 8).zero?
  when "ureal", "real", "fixed", "ufixed"
    unless sub =~ /\A[0-9]+x[0-9]+\z/
      raise ParseError,
            "Real type must have suffix of form <high>x<low>, e.g. 128x128"
    end

    high, low = sub.split("x").map(&:to_i)
    total = high + low

    raise ParseError, "Real size out of bounds (max 32 bytes)" unless total >= 8 && total <= 256
    raise ParseError, "Real high/low sizes must be multiples of 8" unless (high % 8).zero? && (low % 8).zero?
  when "hash"
    raise ParseError, "Hash type must have numerical suffix" unless sub =~ /\A[0-9]+\z/
  when "address"
    raise ParseError, "Address cannot have suffix" unless sub.empty?
  when "bool"
    raise ParseError, "Bool cannot have suffix" unless sub.empty?
  else
    raise ParseError, "Unrecognized type base: #{base}"
  end

  new(base, sub, dims.map { |x| x[1...-1].to_i })
end

.size_typeObject



54
55
56
# File 'lib/ethereum_abi/type.rb', line 54

def size_type
  @size_type ||= new("uint", 256, [])
end

Instance Method Details

#==(other) ⇒ Object



73
74
75
76
77
# File 'lib/ethereum_abi/type.rb', line 73

def ==(other)
  base == other.base &&
    sub == other.sub &&
    dims == other.dims
end

#dynamic?Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/ethereum_abi/type.rb', line 99

def dynamic?
  size.nil?
end

#sizeInteger, NilClass

Get the static size of a type, or nil if dynamic.

Returns:

  • (Integer, NilClass)

    size of static type, or nil for dynamic type



85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/ethereum_abi/type.rb', line 85

def size
  @size ||= if dims.empty?
              if %w[string bytes].include?(base) && sub.empty?
                nil
              else
                32
              end
            elsif dims.last.zero?
              nil # 0 for dynamic array []
            else
              subtype.dynamic? ? nil : dims.last * subtype.size
            end
end

#subtypeEthereumAbi::Type

Type with one dimension lesser.

Examples:

Type.parse("uint256[2][]").subtype # => Type.new('uint', 256, [2])

Returns:



111
112
113
# File 'lib/ethereum_abi/type.rb', line 111

def subtype
  @subtype ||= self.class.new(base, sub, dims[0...-1])
end