Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue-1184: no distinction between uint and int #1187

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
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ public String getCanonicalName() {
public static SolidityType getType(String typeName) {
if (typeName.contains("[")) return ArrayType.getType(typeName);
if ("bool".equals(typeName)) return new BoolType();
if (typeName.startsWith("int") || typeName.startsWith("uint")) return new IntType(typeName);
if (typeName.startsWith("int")) return new IntType(typeName);
if (typeName.startsWith("uint")) return new UnsignedIntType(typeName);
if ("address".equals(typeName)) return new AddressType();
if ("string".equals(typeName)) return new StringType();
if ("bytes".equals(typeName)) return new BytesType();
Expand Down Expand Up @@ -356,23 +357,14 @@ public Object decode(byte[] encoded, int offset) {
return ByteUtil.bigIntegerToBytes(bi, 20);
}
}

public static class IntType extends SolidityType {
public IntType(String name) {
public static abstract class NumericType extends SolidityType {
public NumericType(String name) {
super(name);
}

@Override
public String getCanonicalName() {
if (getName().equals("int")) return "int256";
if (getName().equals("uint")) return "uint256";
return super.getCanonicalName();
}

@Override
public byte[] encode(Object value) {
BigInteger encodeInternal(Object value) {
BigInteger bigInt;

if (value instanceof String) {
String s = ((String)value).toLowerCase().trim();
int radix = 10;
Expand All @@ -393,14 +385,20 @@ public byte[] encode(Object value) {
} else {
throw new RuntimeException("Invalid value for type '" + this + "': " + value + " (" + value.getClass() + ")");
}
return encodeInt(bigInt);
return bigInt;
}
}

public static class IntType extends NumericType {
public IntType(String name) {
super(name);
}

@Override
public Object decode(byte[] encoded, int offset) {
return decodeInt(encoded, offset);
public String getCanonicalName() {
if (getName().equals("int")) return "int256";
return super.getCanonicalName();
}

public static BigInteger decodeInt(byte[] encoded, int offset) {
return new BigInteger(Arrays.copyOfRange(encoded, offset, offset + 32));
}
Expand All @@ -410,6 +408,48 @@ public static byte[] encodeInt(int i) {
public static byte[] encodeInt(BigInteger bigInt) {
return ByteUtil.bigIntegerToBytesSigned(bigInt, 32);
}
@Override
public Object decode(byte[] encoded, int offset) {
return decodeInt(encoded, offset);
}
@Override
public byte[] encode(Object value) {
BigInteger bigInt = encodeInternal(value);
return encodeInt(bigInt);
}
}

public static class UnsignedIntType extends NumericType {
public UnsignedIntType(String name) {
super(name);
}

@Override
public String getCanonicalName() {
if (getName().equals("uint")) return "uint256";
return super.getCanonicalName();
}
public static BigInteger decodeInt(byte[] encoded, int offset) {
return new BigInteger(1, Arrays.copyOfRange(encoded, offset, offset + 32));
}
public static byte[] encodeInt(int i) {
return encodeInt(new BigInteger("" + i));
zilm13 marked this conversation as resolved.
Show resolved Hide resolved
}
public static byte[] encodeInt(BigInteger bigInt) {
if (bigInt.signum() == -1) {
throw new RuntimeException("Wrong value for uint type: " + bigInt);
}
return ByteUtil.bigIntegerToBytes(bigInt, 32);
}
@Override
public byte[] encode(Object value) {
BigInteger bigInt = encodeInternal(value);
return encodeInt(bigInt);
jondoe1337 marked this conversation as resolved.
Show resolved Hide resolved
}
@Override
public Object decode(byte[] encoded, int offset) {
return decodeInt(encoded, offset);
}
}

public static class BoolType extends IntType {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (c) [2016] [ <ether.camp> ]
* This file is part of the ethereumJ library.
*
* The ethereumJ library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The ethereumJ library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the ethereumJ library. If not, see <http://www.gnu.org/licenses/>.
*/
package org.ethereum.solidity;
jondoe1337 marked this conversation as resolved.
Show resolved Hide resolved
jondoe1337 marked this conversation as resolved.
Show resolved Hide resolved

import static org.junit.Assert.assertEquals;

import java.math.BigInteger;

import org.junit.Test;
import org.spongycastle.util.encoders.Hex;

/**
* Created by Maximilian Schmidt on 25.09.2018.
*/
public class SolidityTypeTest {
@Test
public void ensureUnsignedInteger_isDecodedWithCorrectSignum() {
byte[] bigNumberByteArray = { -13, -75, 19, 86, -119, 67, 112, -4, 118, -86, 98, -46, 103, -42, -126, 63, -60, -15, -87, 57, 43, 11, -17, -52,
0, 3, -65, 14, -67, -40, 65, 119 };
SolidityType testObject = new SolidityType.UnsignedIntType("uint256");
Object decode = testObject.decode(bigNumberByteArray);
assertEquals(decode.getClass(), BigInteger.class);
BigInteger actualBigInteger = (BigInteger) decode;
BigInteger expectedBigInteger = new BigInteger(Hex.toHexString(bigNumberByteArray), 16);
assertEquals(expectedBigInteger, actualBigInteger);
}

@Test
public void ensureSignedInteger_isDecoded() {
byte[] bigNumberByteArray = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 127, -1, -1, -1, -1, -1, -1, -1 };
SolidityType testObject = new SolidityType.IntType("int256");
Object decode = testObject.decode(bigNumberByteArray);
assertEquals(decode.getClass(), BigInteger.class);
BigInteger actualBigInteger = (BigInteger) decode;
BigInteger expectedBigInteger = new BigInteger(bigNumberByteArray);
assertEquals(expectedBigInteger, actualBigInteger);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,28 @@ public void encodeTest1() {
StandaloneBlockchain sb = new StandaloneBlockchain().withAutoblock(true);
SolidityContract a = sb.submitNewContract(
"contract A {" +
" uint public a;" +
" function f(uint a_) {a = a_;}" +
" int public a;" +
" function f(int a_) {a = a_;}" +
"}");
a.callFunction("f", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
BigInteger r = (BigInteger) a.callConstFunction("a")[0];
System.out.println(r.toString(16));
Assert.assertEquals(new BigInteger(Hex.decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")), r);
}

@Test
public void encodeTest2() {
StandaloneBlockchain sb = new StandaloneBlockchain().withAutoblock(true);
SolidityContract a = sb.submitNewContract(
"contract A {" +
" uint public a;" +
" function f(uint a_) {a = a_;}" +
"}");
a.callFunction("f", "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
BigInteger r = (BigInteger) a.callConstFunction("a")[0];
System.out.println(r.toString(16));
Assert.assertEquals(new BigInteger(1, Hex.decode("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")), r);
}

@Test
public void invalidTxTest() {
Expand Down