Module: Eth::Abi::Encoder
Overview
Provides a utility module to assist encoding ABIs.
Class Method Summary collapse
-
.primitive_type(type, arg) ⇒ String
Encodes primitive types.
-
.type(type, arg) ⇒ String
Encodes a specific value, either static or dynamic.
Instance Method Summary collapse
-
#primitive_type(type, arg) ⇒ String
Encodes primitive types.
-
#type(type, arg) ⇒ String
Encodes a specific value, either static or dynamic.
Class Method Details
.primitive_type(type, arg) ⇒ String
Encodes primitive types.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/eth/abi/encoder.rb', line 96 def primitive_type(type, arg) case type.base_type when "uint" uint arg, type when "int" int arg, type when "bool" bool arg when "ureal", "ufixed" ufixed arg, type when "real", "fixed" fixed arg, type when "string", "bytes" bytes arg, type when "tuple" tuple arg, type when "hash" hash arg, type when "address" address arg else raise EncodingError, "Unhandled type: #{type.base_type} #{type.sub_type}" end end |
.type(type, arg) ⇒ String
Encodes a specific value, either static or dynamic.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/eth/abi/encoder.rb', line 33 def type(type, arg) if %w(string bytes).include? type.base_type and type.sub_type.empty? and type.dimensions.empty? raise EncodingError, "Argument must be a String" unless arg.instance_of? String # encodes strings and bytes size = type Type.size_type, arg.size padding = Constant::BYTE_ZERO * (Util.ceil32(arg.size) - arg.size) "#{size}#{arg}#{padding}" elsif type.base_type == "tuple" && type.dimensions.size == 1 && type.dimensions[0] != 0 result = "" result += struct_offsets(type.nested_sub, arg) result += arg.map { |x| type(type.nested_sub, x) }.join result elsif type.dynamic? && arg.is_a?(Array) # encodes dynamic-sized arrays head, tail = "", "" head += type(Type.size_type, arg.size) nested_sub = type.nested_sub # calculate offsets if %w(string bytes).include?(type.base_type) && type.sub_type.empty? offset = 0 arg.size.times do |i| if i == 0 offset = arg.size * 32 else number_of_words = ((arg[i - 1].size + 32 - 1) / 32).floor total_bytes_length = number_of_words * 32 offset += total_bytes_length + 32 end head += type(Type.size_type, offset) end elsif nested_sub.base_type == "tuple" && nested_sub.dynamic? head += struct_offsets(nested_sub, arg) end arg.size.times do |i| head += type nested_sub, arg[i] end "#{head}#{tail}" else if type.dimensions.empty? # encode a primitive type primitive_type type, arg else # encode static-size arrays arg.map { |x| type(type.nested_sub, x) }.join end end end |
Instance Method Details
#primitive_type(type, arg) ⇒ String
Encodes primitive types.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/eth/abi/encoder.rb', line 96 def primitive_type(type, arg) case type.base_type when "uint" uint arg, type when "int" int arg, type when "bool" bool arg when "ureal", "ufixed" ufixed arg, type when "real", "fixed" fixed arg, type when "string", "bytes" bytes arg, type when "tuple" tuple arg, type when "hash" hash arg, type when "address" address arg else raise EncodingError, "Unhandled type: #{type.base_type} #{type.sub_type}" end end |
#type(type, arg) ⇒ String
Encodes a specific value, either static or dynamic.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/eth/abi/encoder.rb', line 33 def type(type, arg) if %w(string bytes).include? type.base_type and type.sub_type.empty? and type.dimensions.empty? raise EncodingError, "Argument must be a String" unless arg.instance_of? String # encodes strings and bytes size = type Type.size_type, arg.size padding = Constant::BYTE_ZERO * (Util.ceil32(arg.size) - arg.size) "#{size}#{arg}#{padding}" elsif type.base_type == "tuple" && type.dimensions.size == 1 && type.dimensions[0] != 0 result = "" result += struct_offsets(type.nested_sub, arg) result += arg.map { |x| type(type.nested_sub, x) }.join result elsif type.dynamic? && arg.is_a?(Array) # encodes dynamic-sized arrays head, tail = "", "" head += type(Type.size_type, arg.size) nested_sub = type.nested_sub # calculate offsets if %w(string bytes).include?(type.base_type) && type.sub_type.empty? offset = 0 arg.size.times do |i| if i == 0 offset = arg.size * 32 else number_of_words = ((arg[i - 1].size + 32 - 1) / 32).floor total_bytes_length = number_of_words * 32 offset += total_bytes_length + 32 end head += type(Type.size_type, offset) end elsif nested_sub.base_type == "tuple" && nested_sub.dynamic? head += struct_offsets(nested_sub, arg) end arg.size.times do |i| head += type nested_sub, arg[i] end "#{head}#{tail}" else if type.dimensions.empty? # encode a primitive type primitive_type type, arg else # encode static-size arrays arg.map { |x| type(type.nested_sub, x) }.join end end end |