Skip to content

Commit

Permalink
Bug fix for Int256 decode
Browse files Browse the repository at this point in the history
Signed-off-by: tonykwok1992 <[email protected]>
  • Loading branch information
tonykwok1992 committed Jun 22, 2024
1 parent 488e9a3 commit d2b49a5
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 9 deletions.
15 changes: 6 additions & 9 deletions abi/src/main/java/org/web3j/abi/TypeDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -141,17 +141,14 @@ public static <T extends NumericType> T decodeNumeric(String input, Class<T> typ
try {
byte[] inputByteArray = Numeric.hexStringToByteArray(input);
int typeLengthAsBytes = getTypeLengthInBytes(type);

byte[] resultByteArray = new byte[typeLengthAsBytes + 1];

if (Int.class.isAssignableFrom(type) || Fixed.class.isAssignableFrom(type)) {
resultByteArray[0] = inputByteArray[0]; // take MSB as sign bit
}

int valueOffset = Type.MAX_BYTE_LENGTH - typeLengthAsBytes;
System.arraycopy(inputByteArray, valueOffset, resultByteArray, 1, typeLengthAsBytes);

BigInteger numericValue = new BigInteger(resultByteArray);
BigInteger numericValue;
if (Uint.class.isAssignableFrom(type) || Ufixed.class.isAssignableFrom(type)) {
numericValue = new BigInteger(1, inputByteArray, valueOffset, typeLengthAsBytes);
} else {
numericValue = new BigInteger(inputByteArray, valueOffset, typeLengthAsBytes);
}
return type.getConstructor(BigInteger.class).newInstance(numericValue);

} catch (NoSuchMethodException
Expand Down
53 changes: 53 additions & 0 deletions abi/src/test/java/org/web3j/abi/TypeDecoderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
import org.web3j.abi.datatypes.generated.Uint80;
import org.web3j.abi.datatypes.generated.Uint88;
import org.web3j.abi.datatypes.generated.Uint96;
import org.web3j.utils.Numeric;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
Expand Down Expand Up @@ -858,11 +859,63 @@ public void testIntDecode() throws Exception {
Int256.class),
(new Int256(BigInteger.valueOf(-1))));




assertEquals(
TypeDecoder.decodeNumeric(
TypeEncoder.encodeNumeric(new Int256(BigInteger.TWO.pow(248))),
Int256.class),
new Int256(BigInteger.TWO.pow(248)));

assertEquals(
TypeDecoder.decodeNumeric(
TypeEncoder.encodeNumeric(new Int256(BigInteger.TWO.pow(248).negate().subtract(BigInteger.ONE))),
Int256.class),
new Int256(BigInteger.TWO.pow(248).negate().subtract(BigInteger.ONE)));



assertEquals(
TypeDecoder.decodeNumeric(
"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
Int256.class),
new Int256(new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564819967")));

assertEquals(
TypeDecoder.decodeNumeric(
"0x8000000000000000000000000000000000000000000000000000000000000000",
Int256.class),
new Int256(new BigInteger("-57896044618658097711785492504343953926634992332820282019728792003956564819968")));

assertEquals(TypeDecoder.instantiateType("int", 123), (new Int(BigInteger.valueOf(123))));

assertEquals(TypeDecoder.instantiateType("int", -123), (new Int(BigInteger.valueOf(-123))));
}

@Test
public void testInt16All() throws Exception {
int boundary = (int) Math.pow(2, 16 - 1);
for (int i = -boundary; i < boundary; i++) {
assertEquals(
TypeDecoder.decodeNumeric(
TypeEncoder.encodeNumeric(new Int16(BigInteger.valueOf(i))),
Int16.class),
new Int16(BigInteger.valueOf(i)));
}
}

@Test
public void testUint16All() throws Exception {
int boundary = (int) Math.pow(2, 16);
for (int i = 0; i < boundary; i++) {
assertEquals(
TypeDecoder.decodeNumeric(
TypeEncoder.encodeNumeric(new Uint16(BigInteger.valueOf(i))),
Uint16.class),
new Uint16(BigInteger.valueOf(i)));
}
}
/*
TODO: Enable once Solidity supports fixed types - see
https://github.com/ethereum/solidity/issues/409
Expand Down

0 comments on commit d2b49a5

Please sign in to comment.