Skip to content

Commit

Permalink
eth/abi: add a testcase for handling hex and bin strings (#101)
Browse files Browse the repository at this point in the history
* eth/abi: fix handling of hex values for byte strings

* eth/abi: add a testcase for handling hex and bin strings

* eth/abi: fix handling of hex values for byte strings

* spec: run rufo
  • Loading branch information
q9f authored May 19, 2022
1 parent bbbb8ff commit 5eee050
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
24 changes: 19 additions & 5 deletions lib/eth/abi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -346,11 +346,7 @@ def encode_fixed(arg, type)
# Properly encodes byte-strings.
def encode_bytes(arg, type)
raise EncodingError, "Expecting String: #{arg}" unless arg.instance_of? String

if Util.is_prefixed? arg
arg = Util.remove_hex_prefix arg
arg = Util.hex_to_bin arg
end
arg = handle_hex_string arg, type

if type.sub_type.empty?
size = Util.zpad_int arg.size
Expand Down Expand Up @@ -410,5 +406,23 @@ def encode_address(arg)
raise EncodingError, "Could not parse address: #{arg}"
end
end

# The ABI encoder needs to be able to determine between a hex `"123"`
# and a binary `"123"` string.
def handle_hex_string(arg, type)
if Util.is_prefixed? arg or
(arg.size === type.sub_type.to_i * 2 and Util.is_hex? arg)

# There is no way telling whether a string is hex or binary with certainty
# in Ruby. Therefore, we assume a `0x` prefix to indicate a hex string.
# Additionally, if the string size is exactly the double of the expected
# binary size, we can assume a hex value.
return Util.hex_to_bin arg
else

# Everything else will be assumed binary or raw string.
return arg.b
end
end
end
end
5 changes: 5 additions & 0 deletions spec/eth/abi_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,11 @@

it "can handle hex-strings for bytes types" do
expect(Abi.encode ["bytes4"], ["0x80ac58cd"]).to eq "\x80\xACX\xCD#{"\x00" * 28}"
expect(Abi.encode ["bytes4"], ["80ac58cd"]).to eq "\x80\xACX\xCD#{"\x00" * 28}"

# But don't break binary strings
expect(Abi.encode ["bytes4"], ["\x80\xACX\xCD"]).to eq "\x80\xACX\xCD#{"\x00" * 28}"
expect(Util.bin_to_hex Abi.encode ["bytes10"], ["1234567890".b]).to eq "3132333435363738393000000000000000000000000000000000000000000000"
end

it "can decode types" do
Expand Down

0 comments on commit 5eee050

Please sign in to comment.