Skip to content
This repository was archived by the owner on May 23, 2023. It is now read-only.

Commit 72a7e2c

Browse files
committed
Merge branch 'janx-fix_abi_decint' into develop
2 parents 17e17a9 + fb10eba commit 72a7e2c

File tree

3 files changed

+21
-17
lines changed

3 files changed

+21
-17
lines changed

ethereum/abi.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from ethereum import utils
55
from rlp.utils import decode_hex, encode_hex
66
from ethereum.utils import encode_int, zpad, big_endian_to_int, is_numeric, is_string, ceil32
7-
from ethereum.utils import isnumeric
7+
from ethereum.utils import isnumeric, TT256, TT255
88
import ast
99

1010

@@ -145,35 +145,38 @@ class ValueOutOfBounds(EncodingError):
145145
pass
146146

147147

148-
# Decode an integer
149-
def decint(n):
148+
# Decode an unsigned/signed integer
149+
def decint(n, signed=False):
150150
if isinstance(n, str):
151151
n = utils.to_string(n)
152-
if is_numeric(n) and n < 2**256 and n >= -2**255:
152+
153+
if is_numeric(n):
154+
min, max = (-TT255,TT255-1) if signed else (0,TT256-1)
155+
if n > max or n < min:
156+
raise EncodingError("Number out of range: %r" % n)
153157
return n
154-
elif is_numeric(n):
155-
raise EncodingError("Number out of range: %r" % n)
156-
elif is_string(n) and len(n) == 40:
157-
return big_endian_to_int(decode_hex(n))
158-
elif is_string(n) and len(n) <= 32:
159-
return big_endian_to_int(n)
160-
elif is_string(n) and len(n) > 32:
161-
raise EncodingError("String too long: %r" % n)
158+
elif is_string(n):
159+
if len(n) == 40:
160+
n = decode_hex(n)
161+
if len(n) > 32:
162+
raise EncodingError("String too long: %r" % n)
163+
164+
i = big_endian_to_int(n)
165+
return (i - TT256) if signed and i >= TT255 else i
162166
elif n is True:
163167
return 1
164168
elif n is False or n is None:
165169
return 0
166170
else:
167171
raise EncodingError("Cannot encode integer: %r" % n)
168172

169-
170173
# Encodes a base datum
171174
def encode_single(typ, arg):
172175
base, sub, _ = typ
173176
# Unsigned integers: uint<sz>
174177
if base == 'uint':
175178
sub = int(sub)
176-
i = decint(arg)
179+
i = decint(arg, False)
177180

178181
if not 0 <= i < 2**sub:
179182
raise ValueOutOfBounds(repr(arg))
@@ -185,8 +188,8 @@ def encode_single(typ, arg):
185188
# Signed integers: int<sz>
186189
elif base == 'int':
187190
sub = int(sub)
188-
i = decint(arg)
189-
if not -2**(sub - 1) <= i < 2**sub:
191+
i = decint(arg, True)
192+
if not -2**(sub - 1) <= i < 2**(sub - 1):
190193
raise ValueOutOfBounds(repr(arg))
191194
return zpad(encode_int(i % 2**sub), 32)
192195
# Unsigned reals: ureal<high>x<low>

ethereum/tests/test_abi.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def test_abi_encode_signed_int():
2222

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

2627
assert abi.encode_single(['int', '8', []], -128) == zpad(b'\x80', 32)
2728
with pytest.raises(abi.ValueOutOfBounds):

ethereum/tests/test_contracts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1189,7 +1189,7 @@ def test_types():
11891189

11901190

11911191
ecrecover_code = """
1192-
def test_ecrecover(h, v, r, s):
1192+
def test_ecrecover(h:uint256, v:uint256, r:uint256, s:uint256):
11931193
return(ecrecover(h, v, r, s))
11941194
"""
11951195

0 commit comments

Comments
 (0)