package org.web3j.abi; import java.math.BigInteger; import org.junit.Test; import org.web3j.abi.datatypes.Address; import org.web3j.abi.datatypes.Bool; import org.web3j.abi.datatypes.Bytes; import org.web3j.abi.datatypes.DynamicArray; import org.web3j.abi.datatypes.DynamicBytes; import org.web3j.abi.datatypes.StaticArray; import org.web3j.abi.datatypes.Utf8String; import org.web3j.abi.datatypes.generated.Bytes1; import org.web3j.abi.datatypes.generated.Bytes4; import org.web3j.abi.datatypes.generated.Bytes6; import org.web3j.abi.datatypes.generated.Int256; import org.web3j.abi.datatypes.generated.Int64; import org.web3j.abi.datatypes.generated.Uint256; import org.web3j.abi.datatypes.generated.Uint64; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.Assert.assertThat; public class TypeDecoderTest { @Test public void testBoolDecode() { assertThat(TypeDecoder.decodeBool( "0000000000000000000000000000000000000000000000000000000000000000", 0), is(new Bool(false))); assertThat(TypeDecoder.decodeBool( "0000000000000000000000000000000000000000000000000000000000000001", 0), is(new Bool(true))); } @Test public void testBoolDecodeGivenOffset() { // Decode second parameter as Bool assertThat(TypeDecoder.decode( "0000000000000000000000000000000000000000000000007fffffffffffffff" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000007fffffffffffffff", 64, Bool.class), is(new Bool(false))); assertThat(TypeDecoder.decode( "0000000000000000000000000000000000000000000000007fffffffffffffff" + "0000000000000000000000000000000000000000000000000000000000000001" + "0000000000000000000000000000000000000000000000007fffffffffffffff", 64, Bool.class), is(new Bool(true))); } @Test public void testUintDecode() { assertThat(TypeDecoder.decodeNumeric( "0000000000000000000000000000000000000000000000000000000000000000", Uint64.class ), is(new Uint64(BigInteger.ZERO))); assertThat(TypeDecoder.decodeNumeric( "0000000000000000000000000000000000000000000000007fffffffffffffff", Uint64.class ), is(new Uint64(BigInteger.valueOf(Long.MAX_VALUE)))); assertThat(TypeDecoder.decodeNumeric( "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", Uint64.class ), is(new Uint64(new BigInteger( "0ffffffffffffffff", 16)))); } @Test public void testIntDecode() { assertThat(TypeDecoder.decodeNumeric( "0000000000000000000000000000000000000000000000000000000000000000", Int64.class ), is(new Int64(BigInteger.ZERO))); assertThat(TypeDecoder.decodeNumeric( "0000000000000000000000000000000000000000000000007fffffffffffffff", Int64.class ), is(new Int64(BigInteger.valueOf(Long.MAX_VALUE)))); assertThat(TypeDecoder.decodeNumeric( "fffffffffffffffffffffffffffffffffffffffffffffff88000000000000000", Int64.class ), is(new Int64(BigInteger.valueOf(Long.MIN_VALUE)))); assertThat(TypeDecoder.decodeNumeric( "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", Int64.class ), is(new Int64(BigInteger.valueOf(-1)))); assertThat(TypeDecoder.decodeNumeric( "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", Int256.class ), is(new Int256(BigInteger.valueOf(-1)))); } /* TODO: Enable once Solidity supports fixed types - see https://github.com/ethereum/solidity/issues/409 @Test public void testUfixedDecode() { assertThat(TypeDecoder.decodeNumeric( "0000000000000000000000000000000000000000000000000000000000000000", Ufixed24x40.class), is(new Ufixed24x40(BigInteger.ZERO))); assertThat(TypeDecoder.decodeNumeric( "0000000000000000000000000000000000000000000000007fffffffffffffff", Ufixed24x40.class), is(new Ufixed24x40(BigInteger.valueOf(Long.MAX_VALUE)))); assertThat(TypeDecoder.decodeNumeric( "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", Ufixed.class), is(new Ufixed( new BigInteger( "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16 )))); } @Test public void testFixedDecode() { assertThat(TypeDecoder.decodeNumeric( "0000000000000000000000000000000000000000000000000000000000000000", Fixed24x40.class), is(new Fixed24x40(BigInteger.ZERO))); assertThat(TypeDecoder.decodeNumeric( "0000000000000000000000000000000000000000000000007fffffffffffffff", Fixed24x40.class), is(new Fixed24x40(BigInteger.valueOf(Long.MAX_VALUE)))); assertThat(TypeDecoder.decodeNumeric( "ffffffffffffffffffffffffffffffffffffffffffffffff8000000000000000", Fixed24x40.class), is(new Fixed24x40(BigInteger.valueOf(Long.MIN_VALUE)))); assertThat(TypeDecoder.decodeNumeric( "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", Fixed.class), is(new Fixed(BigInteger.valueOf(-1)))); } */ @Test public void testStaticBytes() { Bytes6 staticBytes = new Bytes6(new byte[] { 0, 1, 2, 3, 4, 5 }); assertThat(TypeDecoder.decodeBytes( "0001020304050000000000000000000000000000000000000000000000000000", Bytes6.class), is(staticBytes)); Bytes empty = new Bytes1(new byte[] { 0 }); assertThat(TypeDecoder.decodeBytes( "0000000000000000000000000000000000000000000000000000000000000000", Bytes1.class), is(empty)); Bytes dave = new Bytes4("dave".getBytes()); assertThat(TypeDecoder.decodeBytes( "6461766500000000000000000000000000000000000000000000000000000000", Bytes4.class), is(dave)); } @Test public void testDynamicBytes() { DynamicBytes dynamicBytes = new DynamicBytes(new byte[] { 0, 1, 2, 3, 4, 5 }); assertThat(TypeDecoder.decodeDynamicBytes( "0000000000000000000000000000000000000000000000000000000000000006" // length + "0001020304050000000000000000000000000000000000000000000000000000", 0), is(dynamicBytes)); DynamicBytes empty = new DynamicBytes(new byte[] { 0 }); assertThat(TypeDecoder.decodeDynamicBytes( "0000000000000000000000000000000000000000000000000000000000000001" + "0000000000000000000000000000000000000000000000000000000000000000", 0), is(empty)); DynamicBytes dave = new DynamicBytes("dave".getBytes()); assertThat(TypeDecoder.decodeDynamicBytes( "0000000000000000000000000000000000000000000000000000000000000004" + "6461766500000000000000000000000000000000000000000000000000000000", 0), is(dave)); DynamicBytes loremIpsum = new DynamicBytes( ("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " + "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim " + "veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex " + "ea commodo consequat. Duis aute irure dolor in reprehenderit in " + "voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur " + "sint occaecat cupidatat non proident, sunt in culpa qui officia " + "deserunt mollit anim id est laborum.").getBytes()); assertThat(TypeDecoder.decodeDynamicBytes( "00000000000000000000000000000000000000000000000000000000000001bd" + "4c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73" + "656374657475722061646970697363696e6720656c69742c2073656420646f20" + "656975736d6f642074656d706f7220696e6369646964756e74207574206c6162" + "6f726520657420646f6c6f7265206d61676e6120616c697175612e2055742065" + "6e696d206164206d696e696d2076656e69616d2c2071756973206e6f73747275" + "6420657865726369746174696f6e20756c6c616d636f206c61626f726973206e" + "69736920757420616c697175697020657820656120636f6d6d6f646f20636f6e" + "7365717561742e2044756973206175746520697275726520646f6c6f7220696e" + "20726570726568656e646572697420696e20766f6c7570746174652076656c69" + "7420657373652063696c6c756d20646f6c6f726520657520667567696174206e" + "756c6c612070617269617475722e204578636570746575722073696e74206f63" + "63616563617420637570696461746174206e6f6e2070726f6964656e742c2073" + "756e7420696e2063756c706120717569206f666669636961206465736572756e" + "74206d6f6c6c697420616e696d20696420657374206c61626f72756d2e000000", 0), is(loremIpsum)); } @Test public void testAddress() { assertThat(TypeDecoder.decodeAddress( "000000000000000000000000be5422d15f39373eb0a97ff8c10fbd0e40e29338"), is(new Address("0xbe5422d15f39373eb0a97ff8c10fbd0e40e29338"))); } @Test public void testUtf8String() { assertThat(TypeDecoder.decodeUtf8String( "000000000000000000000000000000000000000000000000000000000000000d" // length + "48656c6c6f2c20776f726c642100000000000000000000000000000000000000", 0), is(new Utf8String("Hello, world!"))); } @Test public void testStaticArray() { assertThat(TypeDecoder.decodeStaticArray( "000000000000000000000000000000000000000000000000000000000000000a" + "0000000000000000000000000000000000000000000000007fffffffffffffff", 0, new TypeReference.StaticArrayTypeReference<StaticArray<Uint256>>(2) {}, 2), is(new StaticArray<Uint256>( new Uint256(BigInteger.TEN), new Uint256(BigInteger.valueOf(Long.MAX_VALUE))))); assertThat(TypeDecoder.decodeStaticArray( "000000000000000000000000000000000000000000000000000000000000000d" + "48656c6c6f2c20776f726c642100000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000d" + "776f726c64212048656c6c6f2c00000000000000000000000000000000000000", 0, new TypeReference.StaticArrayTypeReference<StaticArray<Utf8String>>(2){}, 2 ), equalTo(new StaticArray<Utf8String>( new Utf8String("Hello, world!"), new Utf8String("world! Hello,")))); } @Test(expected = UnsupportedOperationException.class) public void testEmptyStaticArray() { assertThat(TypeDecoder.decodeStaticArray( "0000000000000000000000000000000000000000000000000000000000000000", 0, new TypeReference.StaticArrayTypeReference<StaticArray<Uint256>>(0) {}, 0), is("invalid")); } @Test public void testDynamicArray() { assertThat(TypeDecoder.decodeDynamicArray( "0000000000000000000000000000000000000000000000000000000000000000", // length 0, new TypeReference<DynamicArray<Uint256>>() { } ), equalTo(DynamicArray.empty("uint256"))); assertThat(TypeDecoder.decodeDynamicArray( "0000000000000000000000000000000000000000000000000000000000000002" // length + "000000000000000000000000000000000000000000000000000000000000000a" + "0000000000000000000000000000000000000000000000007fffffffffffffff", 0, new TypeReference<DynamicArray<Uint256>>() { } ), equalTo(new DynamicArray<Uint256>( new Uint256(BigInteger.TEN), new Uint256(BigInteger.valueOf(Long.MAX_VALUE))))); assertThat(TypeDecoder.decodeDynamicArray( "0000000000000000000000000000000000000000000000000000000000000002" // length + "000000000000000000000000000000000000000000000000000000000000000d" + "48656c6c6f2c20776f726c642100000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000d" + "776f726c64212048656c6c6f2c00000000000000000000000000000000000000", 0, new TypeReference<DynamicArray<Utf8String>>() { } ), equalTo(new DynamicArray<Utf8String>( new Utf8String("Hello, world!"), new Utf8String("world! Hello,")))); } }