Skip to content
This repository was archived by the owner on May 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 18 additions & 15 deletions ethereum/abi.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from ethereum import utils
from rlp.utils import decode_hex, encode_hex
from ethereum.utils import encode_int, zpad, big_endian_to_int, is_numeric, is_string, ceil32
from ethereum.utils import isnumeric
from ethereum.utils import isnumeric, TT256, TT255
import ast


Expand Down Expand Up @@ -145,35 +145,38 @@ class ValueOutOfBounds(EncodingError):
pass


# Decode an integer
def decint(n):
# Decode an unsigned/signed integer
def decint(n, signed=False):
if isinstance(n, str):
n = utils.to_string(n)
if is_numeric(n) and n < 2**256 and n >= -2**255:

if is_numeric(n):
min, max = (-TT255,TT255-1) if signed else (0,TT256-1)
if n > max or n < min:
raise EncodingError("Number out of range: %r" % n)
return n
elif is_numeric(n):
raise EncodingError("Number out of range: %r" % n)
elif is_string(n) and len(n) == 40:
return big_endian_to_int(decode_hex(n))
elif is_string(n) and len(n) <= 32:
return big_endian_to_int(n)
elif is_string(n) and len(n) > 32:
raise EncodingError("String too long: %r" % n)
elif is_string(n):
if len(n) == 40:
n = decode_hex(n)
if len(n) > 32:
raise EncodingError("String too long: %r" % n)

i = big_endian_to_int(n)
return (i - TT256) if signed and i >= TT255 else i
elif n is True:
return 1
elif n is False or n is None:
return 0
else:
raise EncodingError("Cannot encode integer: %r" % n)


# Encodes a base datum
def encode_single(typ, arg):
base, sub, _ = typ
# Unsigned integers: uint<sz>
if base == 'uint':
sub = int(sub)
i = decint(arg)
i = decint(arg, False)

if not 0 <= i < 2**sub:
raise ValueOutOfBounds(repr(arg))
Expand All @@ -185,7 +188,7 @@ def encode_single(typ, arg):
# Signed integers: int<sz>
elif base == 'int':
sub = int(sub)
i = decint(arg)
i = decint(arg, True)
if not -2**(sub - 1) <= i < 2**(sub - 1):
raise ValueOutOfBounds(repr(arg))
return zpad(encode_int(i % 2**sub), 32)
Expand Down
1 change: 1 addition & 0 deletions ethereum/tests/test_abi.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def test_abi_encode_signed_int():

def test_abi_encode_single_int():
assert abi.encode_single(['int', '256', []], -2**255) == (b'\x80'+b'\x00'*31)
assert abi.encode_single(['int', '256', []], (b'\x80'+b'\x00'*31)) == (b'\x80'+b'\x00'*31)

assert abi.encode_single(['int', '8', []], -128) == zpad(b'\x80', 32)
with pytest.raises(abi.ValueOutOfBounds):
Expand Down
2 changes: 1 addition & 1 deletion ethereum/tests/test_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -1190,7 +1190,7 @@ def test_types():


ecrecover_code = """
def test_ecrecover(h, v, r, s):
def test_ecrecover(h:uint256, v:uint256, r:uint256, s:uint256):
return(ecrecover(h, v, r, s))
"""

Expand Down