From abe054b6bdb0d9316c554661807d76d4b06d7d91 Mon Sep 17 00:00:00 2001 From: chaychen2005 <605966652@qq.com> Date: Thu, 30 Jul 2020 17:29:14 +0800 Subject: [PATCH] add abi UT --- .../bcos/sdk/test/abi/ABIDefinitionTest.java | 160 ++ .../bcos/sdk/test/abi/ABIObjectCodecTest.java | 600 ++++++++ .../sdk/test/abi/ABIObjectFactoryTest.java | 1309 +++++++++++++++++ .../bcos/sdk/test/abi/ABIObjectTest.java | 606 ++++++++ .../bcos/sdk/test/abi/ContractTypeTest.java | 346 +++++ .../fisco/bcos/sdk/test/abi/TableTest.java | 431 ++++++ .../org/fisco/bcos/sdk/test/abi/Utils.java | 33 + 7 files changed, 3485 insertions(+) create mode 100644 src/test/java/org/fisco/bcos/sdk/test/abi/ABIDefinitionTest.java create mode 100644 src/test/java/org/fisco/bcos/sdk/test/abi/ABIObjectCodecTest.java create mode 100644 src/test/java/org/fisco/bcos/sdk/test/abi/ABIObjectFactoryTest.java create mode 100644 src/test/java/org/fisco/bcos/sdk/test/abi/ABIObjectTest.java create mode 100644 src/test/java/org/fisco/bcos/sdk/test/abi/ContractTypeTest.java create mode 100644 src/test/java/org/fisco/bcos/sdk/test/abi/TableTest.java create mode 100644 src/test/java/org/fisco/bcos/sdk/test/abi/Utils.java diff --git a/src/test/java/org/fisco/bcos/sdk/test/abi/ABIDefinitionTest.java b/src/test/java/org/fisco/bcos/sdk/test/abi/ABIDefinitionTest.java new file mode 100644 index 000000000..373dc77e9 --- /dev/null +++ b/src/test/java/org/fisco/bcos/sdk/test/abi/ABIDefinitionTest.java @@ -0,0 +1,160 @@ +package org.fisco.bcos.sdk.test.abi; + +import org.fisco.bcos.sdk.abi.wrapper.ABIDefinition; +import org.junit.Assert; +import org.junit.Test; + +public class ABIDefinitionTest { + @Test + public void typeIntTest() { + ABIDefinition.Type type = new ABIDefinition.Type("int"); + Assert.assertTrue(!type.isList()); + Assert.assertTrue(!type.isFixedList()); + Assert.assertTrue(!type.isDynamicList()); + Assert.assertTrue(type.getRawType().equals("int")); + Assert.assertTrue(type.getType().equals("int")); + Assert.assertTrue(type.getDimensions().isEmpty()); + Assert.assertTrue(type.getLastDimension() == 0); + } + + @Test + public void typeStringTest() { + ABIDefinition.Type type = new ABIDefinition.Type("string"); + Assert.assertTrue(!type.isList()); + Assert.assertTrue(!type.isFixedList()); + Assert.assertTrue(!type.isDynamicList()); + Assert.assertTrue(type.getRawType().equals("string")); + Assert.assertTrue(type.getType().equals("string")); + Assert.assertTrue(type.getDimensions().isEmpty()); + Assert.assertTrue(type.getLastDimension() == 0); + + ABIDefinition.Type type1 = type.reduceDimensionAndGetType(); + Assert.assertTrue(!type1.isList()); + Assert.assertTrue(!type1.isFixedList()); + Assert.assertTrue(!type1.isDynamicList()); + Assert.assertTrue(type1.getRawType().equals("string")); + Assert.assertTrue(type1.getType().equals("string")); + Assert.assertTrue(type1.getDimensions().size() == 0); + Assert.assertTrue(type1.getLastDimension() == 0); + } + + @Test + public void typeStringFixedTest() { + ABIDefinition.Type type = new ABIDefinition.Type("string[5]"); + Assert.assertTrue(type.isList()); + Assert.assertTrue(type.isFixedList()); + Assert.assertTrue(!type.isDynamicList()); + Assert.assertTrue(type.getRawType().equals("string")); + Assert.assertTrue(type.getType().equals("string[5]")); + Assert.assertTrue(type.getDimensions().size() == 1); + Assert.assertTrue(type.getLastDimension() == 5); + + ABIDefinition.Type type1 = type.reduceDimensionAndGetType(); + Assert.assertTrue(!type1.isList()); + Assert.assertTrue(!type1.isFixedList()); + Assert.assertTrue(!type1.isDynamicList()); + Assert.assertTrue(type1.getRawType().equals("string")); + Assert.assertTrue(type1.getType().equals("string")); + Assert.assertTrue(type1.getDimensions().size() == 0); + Assert.assertTrue(type1.getLastDimension() == 0); + } + + @Test + public void typeStringFixedDynamicTest() { + ABIDefinition.Type type = new ABIDefinition.Type("string[5][]"); + Assert.assertTrue(type.isList()); + Assert.assertTrue(!type.isFixedList()); + Assert.assertTrue(type.isDynamicList()); + Assert.assertTrue(type.getRawType().equals("string")); + Assert.assertTrue(type.getType().equals("string[5][]")); + Assert.assertTrue(type.getDimensions().size() == 2); + Assert.assertTrue(type.getLastDimension() == 0); + + ABIDefinition.Type type1 = type.reduceDimensionAndGetType(); + Assert.assertTrue(type1.isList()); + Assert.assertTrue(type1.isFixedList()); + Assert.assertTrue(!type1.isDynamicList()); + Assert.assertTrue(type1.getRawType().equals("string")); + Assert.assertTrue(type1.getType().equals("string[5]")); + Assert.assertTrue(type1.getDimensions().size() == 1); + Assert.assertTrue(type1.getLastDimension() == 5); + } + + @Test + public void typeStringDynamicDynamicDynamicTest() { + ABIDefinition.Type type = new ABIDefinition.Type("string[][][]"); + Assert.assertTrue(type.isList()); + Assert.assertTrue(!type.isFixedList()); + Assert.assertTrue(type.isDynamicList()); + Assert.assertTrue(type.getRawType().equals("string")); + Assert.assertTrue(type.getType().equals("string[][][]")); + Assert.assertTrue(type.getDimensions().size() == 3); + Assert.assertTrue(type.getLastDimension() == 0); + + ABIDefinition.Type type1 = type.reduceDimensionAndGetType(); + Assert.assertTrue(type1.isList()); + Assert.assertTrue(!type1.isFixedList()); + Assert.assertTrue(type1.isDynamicList()); + Assert.assertTrue(type1.getRawType().equals("string")); + Assert.assertTrue(type1.getType().equals("string[][]")); + Assert.assertTrue(type1.getDimensions().size() == 2); + Assert.assertTrue(type1.getLastDimension() == 0); + + ABIDefinition.Type type2 = type1.reduceDimensionAndGetType(); + Assert.assertTrue(type2.isList()); + Assert.assertTrue(!type2.isFixedList()); + Assert.assertTrue(type2.isDynamicList()); + Assert.assertTrue(type2.getRawType().equals("string")); + Assert.assertTrue(type2.getType().equals("string[]")); + Assert.assertTrue(type2.getDimensions().size() == 1); + Assert.assertTrue(type2.getLastDimension() == 0); + + ABIDefinition.Type type3 = type2.reduceDimensionAndGetType(); + Assert.assertTrue(!type3.isList()); + Assert.assertTrue(!type3.isFixedList()); + Assert.assertTrue(!type3.isDynamicList()); + Assert.assertTrue(type3.getRawType().equals("string")); + Assert.assertTrue(type3.getType().equals("string")); + Assert.assertTrue(type3.getDimensions().size() == 0); + Assert.assertTrue(type3.getLastDimension() == 0); + } + + @Test + public void typeStringFixedFixedFixedTest() { + ABIDefinition.Type type = new ABIDefinition.Type("string[8][9][10]"); + Assert.assertTrue(type.isList()); + Assert.assertTrue(type.isFixedList()); + Assert.assertTrue(!type.isDynamicList()); + Assert.assertTrue(type.getRawType().equals("string")); + Assert.assertTrue(type.getType().equals("string[8][9][10]")); + Assert.assertTrue(type.getDimensions().size() == 3); + Assert.assertTrue(type.getLastDimension() == 10); + + ABIDefinition.Type type1 = type.reduceDimensionAndGetType(); + Assert.assertTrue(type1.isList()); + Assert.assertTrue(type1.isFixedList()); + Assert.assertTrue(!type1.isDynamicList()); + Assert.assertTrue(type1.getRawType().equals("string")); + Assert.assertTrue(type1.getType().equals("string[8][9]")); + Assert.assertTrue(type1.getDimensions().size() == 2); + Assert.assertTrue(type1.getLastDimension() == 9); + + ABIDefinition.Type type2 = type1.reduceDimensionAndGetType(); + Assert.assertTrue(type2.isList()); + Assert.assertTrue(type2.isFixedList()); + Assert.assertTrue(!type2.isDynamicList()); + Assert.assertTrue(type2.getRawType().equals("string")); + Assert.assertTrue(type2.getType().equals("string[8]")); + Assert.assertTrue(type2.getDimensions().size() == 1); + Assert.assertTrue(type2.getLastDimension() == 8); + + ABIDefinition.Type type3 = type2.reduceDimensionAndGetType(); + Assert.assertTrue(!type3.isList()); + Assert.assertTrue(!type3.isFixedList()); + Assert.assertTrue(!type3.isDynamicList()); + Assert.assertTrue(type3.getRawType().equals("string")); + Assert.assertTrue(type3.getType().equals("string")); + Assert.assertTrue(type3.getDimensions().size() == 0); + Assert.assertTrue(type3.getLastDimension() == 0); + } +} diff --git a/src/test/java/org/fisco/bcos/sdk/test/abi/ABIObjectCodecTest.java b/src/test/java/org/fisco/bcos/sdk/test/abi/ABIObjectCodecTest.java new file mode 100644 index 000000000..ab3a3c72c --- /dev/null +++ b/src/test/java/org/fisco/bcos/sdk/test/abi/ABIObjectCodecTest.java @@ -0,0 +1,600 @@ +package org.fisco.bcos.sdk.test.abi; + +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import org.fisco.bcos.sdk.abi.wrapper.ABICodecJsonWrapper; +import org.fisco.bcos.sdk.abi.wrapper.ABIDefinition; +import org.fisco.bcos.sdk.abi.wrapper.ABIObject; +import org.fisco.bcos.sdk.abi.wrapper.ABIObjectFactory; +import org.fisco.bcos.sdk.abi.wrapper.ContractABIDefinition; +import org.junit.Assert; +import org.junit.Test; + +public class ABIObjectCodecTest { + String abiDesc = + "[\n" + + " {\n" + + " \"anonymous\": false,\n" + + " \"inputs\": [\n" + + " {\n" + + " \"indexed\": false,\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"a\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"components\": [\n" + + " {\n" + + " \"internalType\": \"string\",\n" + + " \"name\": \"name\",\n" + + " \"type\": \"string\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"count\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"components\": [\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"a\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"b\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"c\",\n" + + " \"type\": \"int256\"\n" + + " }\n" + + " ],\n" + + " \"internalType\": \"struct Proxy.Item[]\",\n" + + " \"name\": \"items\",\n" + + " \"type\": \"tuple[]\"\n" + + " }\n" + + " ],\n" + + " \"indexed\": false,\n" + + " \"internalType\": \"struct Proxy.Info[]\",\n" + + " \"name\": \"b\",\n" + + " \"type\": \"tuple[]\"\n" + + " },\n" + + " {\n" + + " \"indexed\": false,\n" + + " \"internalType\": \"string\",\n" + + " \"name\": \"c\",\n" + + " \"type\": \"string\"\n" + + " }\n" + + " ],\n" + + " \"name\": \"output1\",\n" + + " \"type\": \"event\"\n" + + " },\n" + + " {\n" + + " \"constant\": false,\n" + + " \"inputs\": [\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"a\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"components\": [\n" + + " {\n" + + " \"internalType\": \"string\",\n" + + " \"name\": \"name\",\n" + + " \"type\": \"string\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"count\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"components\": [\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"a\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"b\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"c\",\n" + + " \"type\": \"int256\"\n" + + " }\n" + + " ],\n" + + " \"internalType\": \"struct Proxy.Item[]\",\n" + + " \"name\": \"items\",\n" + + " \"type\": \"tuple[]\"\n" + + " }\n" + + " ],\n" + + " \"internalType\": \"struct Proxy.Info[]\",\n" + + " \"name\": \"b\",\n" + + " \"type\": \"tuple[]\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"string\",\n" + + " \"name\": \"c\",\n" + + " \"type\": \"string\"\n" + + " }\n" + + " ],\n" + + " \"name\": \"test\",\n" + + " \"outputs\": [\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"\",\n" + + " \"type\": \"int256\"\n" + + " }\n" + + " ],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"function\"\n" + + " },\n" + + " {\n" + + " \"constant\": false,\n" + + " \"inputs\": [],\n" + + " \"name\": \"test1\",\n" + + " \"outputs\": [\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"a\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"components\": [\n" + + " {\n" + + " \"internalType\": \"string\",\n" + + " \"name\": \"name\",\n" + + " \"type\": \"string\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"count\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"components\": [\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"a\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"b\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"c\",\n" + + " \"type\": \"int256\"\n" + + " }\n" + + " ],\n" + + " \"internalType\": \"struct Proxy.Item[]\",\n" + + " \"name\": \"items\",\n" + + " \"type\": \"tuple[]\"\n" + + " }\n" + + " ],\n" + + " \"internalType\": \"struct Proxy.Info[]\",\n" + + " \"name\": \"b\",\n" + + " \"type\": \"tuple[]\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"string\",\n" + + " \"name\": \"c\",\n" + + " \"type\": \"string\"\n" + + " }\n" + + " ],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"function\"\n" + + " },\n" + + " {\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"fallback\"\n" + + " }\n" + + "]"; + + // int a, Info[] memory b, string memory c + /* + * { + "0": "int256: a 100", + "1": "tuple(string,int256,tuple(int256,int256,int256)[])[]: b Hello world!,100,1,2,3,Hello world2!,200,5,6,7", + "2": "string: c Hello world!" + } + + struct Item { + int a; + int b; + int c; + } + + struct Info { + string name; + int count; + Item[] items; + } + + event output1(int a, Info[] b, string c); + + function() external { + + } + + function test(int a, Info[] memory b, string memory c) public returns(int) { + // emit output1(a, b, c); + } + */ + String encoded = + "0000000000000000000000000000000000000000000000000000000000000064" + + "0000000000000000000000000000000000000000000000000000000000000060" + + "0000000000000000000000000000000000000000000000000000000000000300" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000040" + + "0000000000000000000000000000000000000000000000000000000000000160" + + "0000000000000000000000000000000000000000000000000000000000000060" + + "0000000000000000000000000000000000000000000000000000000000000064" + + "00000000000000000000000000000000000000000000000000000000000000a0" + + "000000000000000000000000000000000000000000000000000000000000000c" + + "48656c6c6f20776f726c64210000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000003" + + "0000000000000000000000000000000000000000000000000000000000000060" + + "00000000000000000000000000000000000000000000000000000000000000c8" + + "00000000000000000000000000000000000000000000000000000000000000a0" + + "000000000000000000000000000000000000000000000000000000000000000c" + + "48656c6c6f20776f726c64320000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000005" + + "0000000000000000000000000000000000000000000000000000000000000006" + + "0000000000000000000000000000000000000000000000000000000000000007" + + "000000000000000000000000000000000000000000000000000000000000000c" + + "48656c6c6f20776f726c64210000000000000000000000000000000000000000"; + + @Test + public void testLoadABIJSON() { + ContractABIDefinition contractABIDefinition = Utils.getContractABIDefinition(abiDesc); + + Assert.assertEquals(2, contractABIDefinition.getFunctions().size()); + Assert.assertEquals(1, contractABIDefinition.getEvents().size()); + + List functions = contractABIDefinition.getFunctions().get("test"); + ABIObjectFactory abiObjectFactory = new ABIObjectFactory(); + ABIObject inputABIObject = abiObjectFactory.createInputObject(functions.get(0)); + ABIObject obj = inputABIObject.decode(encoded); + ABICodecJsonWrapper abiCodecJsonWrapper = new ABICodecJsonWrapper(); + // List decodeJson = abiCodecJsonWrapper.decode(obj, encoded); + // Assert.assertEquals(Arrays.toString(decodeJson.toArray(new String[0])), "[ [ \"Hello + // world!\", 100, [ [ 1, 2, 3 ] ] ], [ \"Hello world2\", 200, [ [ 5, 6, 7 ] ] ], [ \"Hello + // world!\", 100, [ [ 1, 2, 3 ] ] ], [ \"Hello world2\", 200, [ [ 5, 6, 7 ] ] ] ]"); + String buffer = obj.encode(); + + Assert.assertEquals(encoded, buffer); + } + + @Test + public void testEncodeByJSON() throws Exception { + + ContractABIDefinition contractABIDefinition = Utils.getContractABIDefinition(abiDesc); + + List functions = contractABIDefinition.getFunctions().get("test"); + ABIObjectFactory abiObjectFactory = new ABIObjectFactory(); + ABIObject inputABIObject = abiObjectFactory.createInputObject(functions.get(0)); + + List args = new ArrayList(); + args.add("100"); + + // [{"name": "Hello world!", "count": 100, "items": [{"a": 1, "b": 2, "c": 3}]}, {"name": + // "Hello world2", "count": 200, "items": [{"a": 1, "b": 2, "c": 3}]}] + args.add( + "[{\"name\": \"Hello world!\", \"count\": 100, \"items\": [{\"a\": 1, \"b\": 2, \"c\": 3}]}, {\"name\": \"Hello world2\", \"count\": 200, \"items\": [{\"a\": 5, \"b\": 6, \"c\": 7}]}]"); + args.add("Hello world!"); + + ABICodecJsonWrapper abiCodecJsonWrapper = new ABICodecJsonWrapper(); + ABIObject encodedObj = abiCodecJsonWrapper.encode(inputABIObject, args); + + ABIObject inputABIObject0 = abiObjectFactory.createInputObject(functions.get(0)); + List decodeArgs = abiCodecJsonWrapper.decode(inputABIObject0, encoded); + + // Assert.assertArrayEquals(args.toArray(), decodeArgs.toArray()); + Assert.assertEquals(encoded, encodedObj.encode()); + } + + @Test + public void testBytesEncode() throws Exception { + String proxyDesc = + "[{\n" + + " \"constant\": false,\n" + + " \"inputs\": [{\n" + + " \"name\": \"_args\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"name\": \"commitTransaction\",\n" + + " \"outputs\": [{\n" + + " \"name\": \"\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"function\"\n" + + "}, {\n" + + " \"constant\": false,\n" + + " \"inputs\": [{\n" + + " \"name\": \"_args\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"name\": \"setMaxStep\",\n" + + " \"outputs\": [],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"function\"\n" + + "}, {\n" + + " \"constant\": true,\n" + + " \"inputs\": [{\n" + + " \"name\": \"_args\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"name\": \"getPaths\",\n" + + " \"outputs\": [{\n" + + " \"name\": \"\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"view\",\n" + + " \"type\": \"function\"\n" + + "}, {\n" + + " \"constant\": false,\n" + + " \"inputs\": [{\n" + + " \"name\": \"_args\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"name\": \"rollbackTransaction\",\n" + + " \"outputs\": [{\n" + + " \"name\": \"\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"function\"\n" + + "}, {\n" + + " \"constant\": true,\n" + + " \"inputs\": [],\n" + + " \"name\": \"getLatestTransaction\",\n" + + " \"outputs\": [{\n" + + " \"name\": \"\",\n" + + " \"type\": \"string\"\n" + + " }],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"view\",\n" + + " \"type\": \"function\"\n" + + "}, {\n" + + " \"constant\": false,\n" + + " \"inputs\": [{\n" + + " \"name\": \"_transactionID\",\n" + + " \"type\": \"string\"\n" + + " }, {\n" + + " \"name\": \"_seq\",\n" + + " \"type\": \"uint256\"\n" + + " }, {\n" + + " \"name\": \"_path\",\n" + + " \"type\": \"string\"\n" + + " }, {\n" + + " \"name\": \"_func\",\n" + + " \"type\": \"string\"\n" + + " }, {\n" + + " \"name\": \"_args\",\n" + + " \"type\": \"bytes\"\n" + + " }],\n" + + " \"name\": \"sendTransaction\",\n" + + " \"outputs\": [{\n" + + " \"name\": \"\",\n" + + " \"type\": \"bytes\"\n" + + " }],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"function\"\n" + + "}, {\n" + + " \"constant\": true,\n" + + " \"inputs\": [{\n" + + " \"name\": \"_args\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"name\": \"getVersion\",\n" + + " \"outputs\": [{\n" + + " \"name\": \"\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"pure\",\n" + + " \"type\": \"function\"\n" + + "}, {\n" + + " \"constant\": false,\n" + + " \"inputs\": [{\n" + + " \"name\": \"_args\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"name\": \"rollbackAndDeleteTransaction\",\n" + + " \"outputs\": [{\n" + + " \"name\": \"\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"function\"\n" + + "}, {\n" + + " \"constant\": true,\n" + + " \"inputs\": [],\n" + + " \"name\": \"getLatestTransactionInfo\",\n" + + " \"outputs\": [{\n" + + " \"name\": \"\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"view\",\n" + + " \"type\": \"function\"\n" + + "}, {\n" + + " \"constant\": true,\n" + + " \"inputs\": [{\n" + + " \"name\": \"_str\",\n" + + " \"type\": \"string\"\n" + + " }],\n" + + " \"name\": \"stringToUint256\",\n" + + " \"outputs\": [{\n" + + " \"name\": \"\",\n" + + " \"type\": \"uint256\"\n" + + " }],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"pure\",\n" + + " \"type\": \"function\"\n" + + "}, {\n" + + " \"constant\": false,\n" + + " \"inputs\": [{\n" + + " \"name\": \"_transactionID\",\n" + + " \"type\": \"string\"\n" + + " }, {\n" + + " \"name\": \"_path\",\n" + + " \"type\": \"string\"\n" + + " }, {\n" + + " \"name\": \"_func\",\n" + + " \"type\": \"string\"\n" + + " }, {\n" + + " \"name\": \"_args\",\n" + + " \"type\": \"bytes\"\n" + + " }],\n" + + " \"name\": \"constantCall\",\n" + + " \"outputs\": [{\n" + + " \"name\": \"\",\n" + + " \"type\": \"bytes\"\n" + + " }],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"function\"\n" + + "}, {\n" + + " \"constant\": true,\n" + + " \"inputs\": [{\n" + + " \"name\": \"_args\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"name\": \"getMaxStep\",\n" + + " \"outputs\": [{\n" + + " \"name\": \"\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"view\",\n" + + " \"type\": \"function\"\n" + + "}, {\n" + + " \"constant\": true,\n" + + " \"inputs\": [{\n" + + " \"name\": \"_args\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"name\": \"getTransactionInfo\",\n" + + " \"outputs\": [{\n" + + " \"name\": \"\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"view\",\n" + + " \"type\": \"function\"\n" + + "}, {\n" + + " \"constant\": false,\n" + + " \"inputs\": [{\n" + + " \"name\": \"_args\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"name\": \"addPath\",\n" + + " \"outputs\": [],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"function\"\n" + + "}, {\n" + + " \"constant\": false,\n" + + " \"inputs\": [{\n" + + " \"name\": \"_args\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"name\": \"startTransaction\",\n" + + " \"outputs\": [{\n" + + " \"name\": \"\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"function\"\n" + + "}, {\n" + + " \"constant\": false,\n" + + " \"inputs\": [{\n" + + " \"name\": \"_args\",\n" + + " \"type\": \"string[]\"\n" + + " }],\n" + + " \"name\": \"deletePathList\",\n" + + " \"outputs\": [],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"function\"\n" + + "}, {\n" + + " \"inputs\": [],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"constructor\"\n" + + "}]"; + + // ABIObjectCodecJsonWrapper abiFactory = new ABIObjectCodecJsonWrapper(); + ContractABIDefinition contractABIDefinition = Utils.getContractABIDefinition(proxyDesc); + + List functions = contractABIDefinition.getFunctions().get("constantCall"); + ABIObject inputABIObject = ABIObjectFactory.createInputObject(functions.get(0)); + + List args = new ArrayList(); + args.add("arg112345678901234567890123456789012345678901234567890"); + args.add("arg212345678901234567890123456789012345678901234567890"); + args.add("arg312345678901234567890123456789012345678901234567890"); + + String bytesValue = "0x123456789874321"; + byte[] encode = Base64.getEncoder().encode(bytesValue.getBytes()); + + args.add(new String(encode)); + + ABICodecJsonWrapper abiCodecJsonWrapper = new ABICodecJsonWrapper(); + ABIObject encodedObj = abiCodecJsonWrapper.encode(inputABIObject, args); + String buffer = encodedObj.encode(); + + List decodeArgs = abiCodecJsonWrapper.decode(inputABIObject, buffer); + Assert.assertArrayEquals(args.toArray(), decodeArgs.toArray()); + + List functions0 = + contractABIDefinition.getFunctions().get("commitTransaction"); + ABIObject inputABIObject0 = ABIObjectFactory.createInputObject(functions0.get(0)); + + List args0 = new ArrayList(); + args0.add( + "[\"arg112345678901234567890123456789012345678901234567890\",\"arg112345678901234567890123456789012345678901234567890\",\"arg112345678901234567890123456789012345678901234567890\",\"arg112345678901234567890123456789012345678901234567890\"]"); + + ABIObject encodedObj0 = abiCodecJsonWrapper.encode(inputABIObject0, args0); + String buffer0 = encodedObj0.encode(); + + List decodeArgs0 = abiCodecJsonWrapper.decode(inputABIObject0, buffer0); + + // Assert.assertArrayEquals(decodeArgs.toArray(new String[0]), args0.get(0)); + + for (int i = 0; i < args.size() - 1; i++) { + Assert.assertEquals(args.get(i), decodeArgs.get(i)); + } + + byte[] decode = Base64.getDecoder().decode(decodeArgs.get(args.size() - 1)); + + Assert.assertEquals(new String(decode), bytesValue); + } +} diff --git a/src/test/java/org/fisco/bcos/sdk/test/abi/ABIObjectFactoryTest.java b/src/test/java/org/fisco/bcos/sdk/test/abi/ABIObjectFactoryTest.java new file mode 100644 index 000000000..74bec602f --- /dev/null +++ b/src/test/java/org/fisco/bcos/sdk/test/abi/ABIObjectFactoryTest.java @@ -0,0 +1,1309 @@ +package org.fisco.bcos.sdk.test.abi; + +import static junit.framework.TestCase.assertEquals; +import static junit.framework.TestCase.assertTrue; + +import java.util.Objects; +import org.fisco.bcos.sdk.abi.FunctionEncoder; +import org.fisco.bcos.sdk.abi.wrapper.ABIObject; +import org.fisco.bcos.sdk.abi.wrapper.ABIObjectFactory; +import org.fisco.bcos.sdk.abi.wrapper.ContractABIDefinition; +import org.fisco.bcos.sdk.crypto.CryptoInterface; +import org.junit.Assert; +import org.junit.Test; + +public class ABIObjectFactoryTest { + + @Test + public void buildRawTypeObjectTest() { + Assert.assertTrue( + ABIObjectFactory.buildRawTypeObject("uint").getValueType() + == ABIObject.ValueType.UINT); + Assert.assertTrue( + ABIObjectFactory.buildRawTypeObject("uint256").getValueType() + == ABIObject.ValueType.UINT); + Assert.assertTrue( + ABIObjectFactory.buildRawTypeObject("int").getValueType() + == ABIObject.ValueType.INT); + Assert.assertTrue( + ABIObjectFactory.buildRawTypeObject("int256").getValueType() + == ABIObject.ValueType.INT); + Assert.assertTrue( + ABIObjectFactory.buildRawTypeObject("bool").getValueType() + == ABIObject.ValueType.BOOL); + Assert.assertTrue( + ABIObjectFactory.buildRawTypeObject("address").getValueType() + == ABIObject.ValueType.ADDRESS); + Assert.assertTrue( + ABIObjectFactory.buildRawTypeObject("bytes").getValueType() + == ABIObject.ValueType.DBYTES); + Assert.assertTrue( + ABIObjectFactory.buildRawTypeObject("bytes1").getValueType() + == ABIObject.ValueType.BYTES); + Assert.assertTrue( + ABIObjectFactory.buildRawTypeObject("bytes32").getValueType() + == ABIObject.ValueType.BYTES); + Assert.assertTrue( + ABIObjectFactory.buildRawTypeObject("string").getValueType() + == ABIObject.ValueType.STRING); + } + + @Test + public void testContractABIDefinitionBuildMethodSignature() throws Exception { + + /* + + pragma solidity>=0.4.19 <0.7.0; + pragma experimental ABIEncoderV2; + contract Test{ + struct E { string s;} + struct S { uint a; uint[] b; T[] c;T t;E e;} + struct T { uint x; uint y;} + + function a(E memory e) public {} + function b( T memory t)public {} + function c(T memory t,E memory e) public {} + function d(uint ) public {} + function e(uint, string[]memory, bool) public {} + function f(S memory,T memory,E memory,uint)public {} + function g(S[] memory, T[] memory,E[] memory,uint256 [] memory)public {} + function h(S[4] memory, T[4] memory, E[4] memory, uint256[4] memory) public {} + } + + */ + + /* + { + "d92a9e33": "a((string))", + "5282e79c": "b((uint256,uint256))", + "f332a566": "c((uint256,uint256),(string))", + "7f6b590c": "d(uint256)", + "b45c9d9f": "e(uint256,string[],bool)", + "edb896f9": "f((uint256,uint256[],(uint256,uint256)[],(uint256,uint256),(string)),(uint256,uint256),(string),uint256)", + "adc86690": "g((uint256,uint256[],(uint256,uint256)[],(uint256,uint256),(string))[],(uint256,uint256)[],(string)[],uint256[])", + "7a3093eb": "h((uint256,uint256[],(uint256,uint256)[],(uint256,uint256),(string))[4],(uint256,uint256)[4],(string)[4],uint256[4])" + } + */ + + String abi = + "[{\"constant\":false,\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"internalType\":\"struct Test.E\",\"name\":\"e\",\"type\":\"tuple\"}],\"name\":\"a\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T\",\"name\":\"t\",\"type\":\"tuple\"}],\"name\":\"b\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T\",\"name\":\"t\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"internalType\":\"struct Test.E\",\"name\":\"e\",\"type\":\"tuple\"}],\"name\":\"c\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"d\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"},{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"name\":\"e\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"b\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T[]\",\"name\":\"c\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T\",\"name\":\"t\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"internalType\":\"struct Test.E\",\"name\":\"e\",\"type\":\"tuple\"}],\"internalType\":\"struct Test.S\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"internalType\":\"struct Test.E\",\"name\":\"\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"f\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"b\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T[]\",\"name\":\"c\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T\",\"name\":\"t\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"internalType\":\"struct Test.E\",\"name\":\"e\",\"type\":\"tuple\"}],\"internalType\":\"struct Test.S[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"internalType\":\"struct Test.E[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"name\":\"g\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"b\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T[]\",\"name\":\"c\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T\",\"name\":\"t\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"internalType\":\"struct Test.E\",\"name\":\"e\",\"type\":\"tuple\"}],\"internalType\":\"struct Test.S[4]\",\"name\":\"\",\"type\":\"tuple[4]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T[4]\",\"name\":\"\",\"type\":\"tuple[4]\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"internalType\":\"struct Test.E[4]\",\"name\":\"\",\"type\":\"tuple[4]\"},{\"internalType\":\"uint256[4]\",\"name\":\"\",\"type\":\"uint256[4]\"}],\"name\":\"h\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"}]"; + + ContractABIDefinition contractABIDefinition = Utils.getContractABIDefinition(abi); + CryptoInterface cryptoInterface = Utils.getCryptoInterface(); + FunctionEncoder functionEncoder = new FunctionEncoder(cryptoInterface); + assertEquals( + contractABIDefinition.getFunctions().get("a").get(0).getMethodSignatureAsString(), + "a((string))"); + assertEquals( + functionEncoder.buildMethodId( + contractABIDefinition + .getFunctions() + .get("a") + .get(0) + .getMethodSignatureAsString()), + "0xd92a9e33"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0xd92a9e33"))); + + assertEquals( + contractABIDefinition.getFunctions().get("b").get(0).getMethodSignatureAsString(), + "b((uint256,uint256))"); + assertEquals( + functionEncoder.buildMethodId( + contractABIDefinition + .getFunctions() + .get("b") + .get(0) + .getMethodSignatureAsString()), + "0x5282e79c"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0x5282e79c"))); + + assertEquals( + contractABIDefinition.getFunctions().get("c").get(0).getMethodSignatureAsString(), + "c((uint256,uint256),(string))"); + assertEquals( + functionEncoder.buildMethodId( + contractABIDefinition + .getFunctions() + .get("c") + .get(0) + .getMethodSignatureAsString()), + "0xf332a566"); + + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0xf332a566"))); + + assertEquals( + contractABIDefinition.getFunctions().get("d").get(0).getMethodSignatureAsString(), + "d(uint256)"); + assertEquals( + functionEncoder.buildMethodId( + contractABIDefinition + .getFunctions() + .get("d") + .get(0) + .getMethodSignatureAsString()), + "0x7f6b590c"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0x7f6b590c"))); + + assertEquals( + contractABIDefinition.getFunctions().get("e").get(0).getMethodSignatureAsString(), + "e(uint256,string[],bool)"); + assertEquals( + functionEncoder.buildMethodId( + contractABIDefinition + .getFunctions() + .get("e") + .get(0) + .getMethodSignatureAsString()), + "0xb45c9d9f"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0xb45c9d9f"))); + + assertEquals( + contractABIDefinition.getFunctions().get("f").get(0).getMethodSignatureAsString(), + "f((uint256,uint256[],(uint256,uint256)[],(uint256,uint256),(string)),(uint256,uint256),(string),uint256)"); + assertEquals( + functionEncoder.buildMethodId( + contractABIDefinition + .getFunctions() + .get("f") + .get(0) + .getMethodSignatureAsString()), + "0xedb896f9"); + + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0xedb896f9"))); + + assertEquals( + contractABIDefinition.getFunctions().get("g").get(0).getMethodSignatureAsString(), + "g((uint256,uint256[],(uint256,uint256)[],(uint256,uint256),(string))[],(uint256,uint256)[],(string)[],uint256[])"); + assertEquals( + contractABIDefinition + .getFunctions() + .get("g") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0xadc86690"); + + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0xadc86690"))); + + assertEquals( + contractABIDefinition.getFunctions().get("h").get(0).getMethodSignatureAsString(), + "h((uint256,uint256[],(uint256,uint256)[],(uint256,uint256),(string))[4],(uint256,uint256)[4],(string)[4],uint256[4])"); + assertEquals( + contractABIDefinition + .getFunctions() + .get("h") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0x7a3093eb"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0xadc86690"))); + } + + @Test + public void testContractABIDefinitionDynamic() throws Exception { + + /* + + pragma solidity>=0.4.19 <0.7.0; + pragma experimental ABIEncoderV2; + contract Test{ + struct E { string s;} + struct S { uint a; uint[] b; T[] c;T t;E e;} + struct T { uint x; uint y;} + + function a(E memory e) public {} + function b( T memory t)public {} + function c(T memory t,E memory e) public {} + function d(uint ) public {} + function e(uint, string[]memory, bool) public {} + function f(S memory,T memory,E memory,uint)public {} + function g(S[] memory, T[] memory,E[] memory,uint256 [] memory)public {} + function h(S[4] memory, T[4] memory, E[4] memory, uint256[4] memory) public {} + } + + */ + + /* + { + "d92a9e33": "a((string))", + "5282e79c": "b((uint256,uint256))", + "f332a566": "c((uint256,uint256),(string))", + "7f6b590c": "d(uint256)", + "b45c9d9f": "e(uint256,string[],bool)", + "edb896f9": "f((uint256,uint256[],(uint256,uint256)[],(uint256,uint256),(string)),(uint256,uint256),(string),uint256)", + "adc86690": "g((uint256,uint256[],(uint256,uint256)[],(uint256,uint256),(string))[],(uint256,uint256)[],(string)[],uint256[])", + "7a3093eb": "h((uint256,uint256[],(uint256,uint256)[],(uint256,uint256),(string))[4],(uint256,uint256)[4],(string)[4],uint256[4])" + } + */ + + String abi = + "[{\"constant\":false,\"inputs\":[{\"components\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"internalType\":\"struct Test.E\",\"name\":\"e\",\"type\":\"tuple\"}],\"name\":\"a\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T\",\"name\":\"t\",\"type\":\"tuple\"}],\"name\":\"b\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T\",\"name\":\"t\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"internalType\":\"struct Test.E\",\"name\":\"e\",\"type\":\"tuple\"}],\"name\":\"c\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"d\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"},{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"name\":\"e\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"b\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T[]\",\"name\":\"c\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T\",\"name\":\"t\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"internalType\":\"struct Test.E\",\"name\":\"e\",\"type\":\"tuple\"}],\"internalType\":\"struct Test.S\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T\",\"name\":\"\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"internalType\":\"struct Test.E\",\"name\":\"\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"f\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"b\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T[]\",\"name\":\"c\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T\",\"name\":\"t\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"internalType\":\"struct Test.E\",\"name\":\"e\",\"type\":\"tuple\"}],\"internalType\":\"struct Test.S[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"internalType\":\"struct Test.E[]\",\"name\":\"\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"name\":\"g\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"a\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"b\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T[]\",\"name\":\"c\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T\",\"name\":\"t\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"internalType\":\"struct Test.E\",\"name\":\"e\",\"type\":\"tuple\"}],\"internalType\":\"struct Test.S[4]\",\"name\":\"\",\"type\":\"tuple[4]\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"x\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"y\",\"type\":\"uint256\"}],\"internalType\":\"struct Test.T[4]\",\"name\":\"\",\"type\":\"tuple[4]\"},{\"components\":[{\"internalType\":\"string\",\"name\":\"s\",\"type\":\"string\"}],\"internalType\":\"struct Test.E[4]\",\"name\":\"\",\"type\":\"tuple[4]\"},{\"internalType\":\"uint256[4]\",\"name\":\"\",\"type\":\"uint256[4]\"}],\"name\":\"h\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"}]"; + + ContractABIDefinition contractABIDefinition = Utils.getContractABIDefinition(abi); + ABIObject inputObject0 = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("a").get(0)); + assertTrue(inputObject0.getStructFields().get(0).isDynamic()); + + ABIObject inputObject1 = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("b").get(0)); + assertTrue(!inputObject1.getStructFields().get(0).isDynamic()); + + ABIObject inputObject2 = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("c").get(0)); + assertTrue(!inputObject2.getStructFields().get(0).isDynamic()); + assertTrue(inputObject2.getStructFields().get(1).isDynamic()); + + ABIObject inputObject3 = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("d").get(0)); + assertTrue(!inputObject3.getStructFields().get(0).isDynamic()); + + ABIObject inputObject4 = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("e").get(0)); + assertTrue(!inputObject4.getStructFields().get(0).isDynamic()); + assertTrue(inputObject4.getStructFields().get(1).isDynamic()); + assertTrue(!inputObject4.getStructFields().get(2).isDynamic()); + + ABIObject inputObject5 = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("f").get(0)); + assertTrue(inputObject5.getStructFields().get(0).isDynamic()); + assertTrue(!inputObject5.getStructFields().get(1).isDynamic()); + assertTrue(inputObject5.getStructFields().get(2).isDynamic()); + assertTrue(!inputObject5.getStructFields().get(3).isDynamic()); + + ABIObject inputObject6 = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("g").get(0)); + assertTrue(inputObject6.getStructFields().get(0).isDynamic()); + assertTrue(inputObject6.getStructFields().get(1).isDynamic()); + assertTrue(inputObject6.getStructFields().get(2).isDynamic()); + assertTrue(inputObject6.getStructFields().get(3).isDynamic()); + + ABIObject inputObject7 = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("h").get(0)); + assertTrue(inputObject7.getStructFields().get(0).isDynamic()); + assertTrue(!inputObject7.getStructFields().get(1).isDynamic()); + assertTrue(inputObject7.getStructFields().get(2).isDynamic()); + assertTrue(!inputObject7.getStructFields().get(3).isDynamic()); + } + + @Test + public void testContractABIDefinitionBuildMethodSignature0() throws Exception { + /* +  + pragma solidity >=0.5.0 <0.6.0; + pragma experimental ABIEncoderV2; + + contract Proxy { + struct Item { + int a; + int b; + int c; + } + + struct Info { + string name; + int count; + Item[] items; + } + + event output1(int a, Info[] b, string c); + + // // test(int256,(string,int256,(int256,int256,int256)[])[],string) + function test(int a, Info[] memory b, string memory c) public returns(int) { + // emit output1(a, b, c); + } + + function test_empty() public returns(int a, Info[][] memory b, string memory c) { + + } + } + */ + + /* + "00a3c75d": "test(int256,(string,int256,(int256,int256,int256)[])[],string)", + "6057db30": "test1()" + */ + + String abi = + "[{\"constant\":false,\"inputs\":[{\"name\":\"a\",\"type\":\"int256\"},{\"components\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"count\",\"type\":\"int256\"},{\"components\":[{\"name\":\"a\",\"type\":\"int256\"},{\"name\":\"b\",\"type\":\"int256\"},{\"name\":\"c\",\"type\":\"int256\"}],\"name\":\"items\",\"type\":\"tuple[]\"}],\"name\":\"b\",\"type\":\"tuple[]\"},{\"name\":\"c\",\"type\":\"string\"}],\"name\":\"test\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"test1\",\"outputs\":[{\"name\":\"a\",\"type\":\"int256\"},{\"components\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"count\",\"type\":\"int256\"},{\"components\":[{\"name\":\"a\",\"type\":\"int256\"},{\"name\":\"b\",\"type\":\"int256\"},{\"name\":\"c\",\"type\":\"int256\"}],\"name\":\"items\",\"type\":\"tuple[]\"}],\"name\":\"b\",\"type\":\"tuple[][]\"},{\"name\":\"c\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"a\",\"type\":\"int256\"},{\"components\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"count\",\"type\":\"int256\"},{\"components\":[{\"name\":\"a\",\"type\":\"int256\"},{\"name\":\"b\",\"type\":\"int256\"},{\"name\":\"c\",\"type\":\"int256\"}],\"name\":\"items\",\"type\":\"tuple[]\"}],\"indexed\":false,\"name\":\"b\",\"type\":\"tuple[]\"},{\"indexed\":false,\"name\":\"c\",\"type\":\"string\"}],\"name\":\"output1\",\"type\":\"event\"}]"; + ContractABIDefinition contractABIDefinition = Utils.getContractABIDefinition(abi); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("test") + .get(0) + .getMethodSignatureAsString(), + "test(int256,(string,int256,(int256,int256,int256)[])[],string)"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("test") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0x00a3c75d"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0x00a3c75d"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("test1") + .get(0) + .getMethodSignatureAsString(), + "test1()"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("test1") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0x6b59084d"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0x6b59084d"))); + } + + @Test + public void testContractABIDefinitionDynamic0() throws Exception { + /* +  + pragma solidity >=0.5.0 <0.6.0; + pragma experimental ABIEncoderV2; + + contract Proxy { + struct Item { + int a; + int b; + int c; + } + + struct Info { + string name; + int count; + Item[] items; + } + + event output1(int a, Info[] b, string c); + + // // test(int256,(string,int256,(int256,int256,int256)[])[],string) + function test(int a, Info[] memory b, string memory c) public returns(int) { + // emit output1(a, b, c); + } + + function test_empty() public returns(int a, Info[][] memory b, string memory c) { + + } + } + */ + + /* + "00a3c75d": "test(int256,(string,int256,(int256,int256,int256)[])[],string)", + "6057db30": "test1()" + */ + + String abi = + "[{\"constant\":false,\"inputs\":[{\"name\":\"a\",\"type\":\"int256\"},{\"components\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"count\",\"type\":\"int256\"},{\"components\":[{\"name\":\"a\",\"type\":\"int256\"},{\"name\":\"b\",\"type\":\"int256\"},{\"name\":\"c\",\"type\":\"int256\"}],\"name\":\"items\",\"type\":\"tuple[]\"}],\"name\":\"b\",\"type\":\"tuple[]\"},{\"name\":\"c\",\"type\":\"string\"}],\"name\":\"test\",\"outputs\":[{\"name\":\"\",\"type\":\"int256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[],\"name\":\"test1\",\"outputs\":[{\"name\":\"a\",\"type\":\"int256\"},{\"components\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"count\",\"type\":\"int256\"},{\"components\":[{\"name\":\"a\",\"type\":\"int256\"},{\"name\":\"b\",\"type\":\"int256\"},{\"name\":\"c\",\"type\":\"int256\"}],\"name\":\"items\",\"type\":\"tuple[]\"}],\"name\":\"b\",\"type\":\"tuple[][]\"},{\"name\":\"c\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"a\",\"type\":\"int256\"},{\"components\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"count\",\"type\":\"int256\"},{\"components\":[{\"name\":\"a\",\"type\":\"int256\"},{\"name\":\"b\",\"type\":\"int256\"},{\"name\":\"c\",\"type\":\"int256\"}],\"name\":\"items\",\"type\":\"tuple[]\"}],\"indexed\":false,\"name\":\"b\",\"type\":\"tuple[]\"},{\"indexed\":false,\"name\":\"c\",\"type\":\"string\"}],\"name\":\"output1\",\"type\":\"event\"}]"; + ContractABIDefinition contractABIDefinition = Utils.getContractABIDefinition(abi); + + ABIObject inputObject = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("test").get(0)); + assertTrue(!inputObject.getStructFields().get(0).isDynamic()); + assertTrue(inputObject.getStructFields().get(1).isDynamic()); + assertTrue(inputObject.getStructFields().get(2).isDynamic()); + } + + @Test + public void testContractABIDefinitionBuildMethodSignature2() throws Exception { + /* + + pragma solidity >=0.5.0 <0.6.0; + pragma experimental ABIEncoderV2; + + contract WeCrossProxy { + + string constant version = "v1.0.0-rc4"; + + // per step of transaction + struct TransactionStep { + string path; + uint256 timestamp; + address contractAddress; + string func; + bytes args; + } + + // information of transaction + struct TransactionInfo { + string[] allPaths; // all paths related to this transaction + string[] paths; // paths related to current chain + address[] contractAddresses; // locked addressed in current chain + uint8 status; // 0-Start 1-Commit 2-Rollback + uint256 startTimestamp; + uint256 commitTimestamp; + uint256 rollbackTimestamp; + uint256[] seqs; // sequence of each step + uint256 stepNum; // step number + } + + struct ContractInfo { + bool locked; // isolation control, read-committed + string path; + string transactionID; + } + + constructor() public { + + } + + function getVersion(string[] memory _args) public pure + returns(string[] memory) + { + + } + + function getMaxStep(string[] memory _args) public view + returns(string[] memory) + { + + } + + function setMaxStep(string[] memory _args) public + { + + } + + function addPath(string[] memory _args) public + { + + } + + function getPaths(string[] memory _args) public view + returns (string[] memory) + { + + } + + function deletePathList(string[] memory _args) public + { + + } + + // constant call + function constantCall(string memory _transactionID, string memory _path, string memory _func, bytes memory _args) public + returns(bytes memory) + { + + } + + // non-constant call + function sendTransaction(string memory _transactionID, uint256 _seq, string memory _path, string memory _func, bytes memory _args) public + returns(bytes memory) + { + + } + + function startTransaction(string[] memory _args) public + returns(string[] memory) + { + + } + + + function commitTransaction(string[] memory _args) public + returns(string[] memory) + { + + } + + + function rollbackTransaction(string[] memory _args) public + returns(string[] memory) + { + + } + + + function getTransactionInfo(string[] memory _args) public view + returns(string[] memory) + { + + } + + // called by router to check transaction status + function getLatestTransactionInfo() public view + returns(string[] memory) + { + + } + + function rollbackAndDeleteTransaction(string[] memory _args) public + returns (string[] memory) + { + + } + + function getLatestTransaction() public view + returns (string memory) + { + + } + + function addTransaction(string memory _transactionID) internal + { + + } + + function deleteTransaction(string memory _transactionID) internal + returns (string[] memory) + { + + } + + function callContract(address _contractAddress, string memory _sig, bytes memory _args) internal + returns(bytes memory result) + { + + } + + function getAddressByPath(string memory _path) internal view + returns (address) + { + + } + + + function getNameByPath(string memory _path) internal pure + returns (string memory) + { + + } + + // "transactionSteps": [{"seq": 0, "contract": "0x12","path": "a.b.c","timestamp": "123","func": "test1(string)","args": "aaa"},{"seq": 1, "contract": "0x12","path": "a.b.c","timestamp": "123","func": "test2(string)","args": "bbb"}] + function transactionStepArrayToJson(string memory _transactionID, uint256[] memory _seqs, uint256 _len) internal view + returns(string memory result) + { + + } + + // {"seq": 0, "contract": "0x12","path": "a.b.c","timestamp": "123","func": "test2(string)","args": "bbb"} + function transactionStepToJson(TransactionStep memory _step, uint256 _seq) internal pure + returns(string memory) + { + + } + + + function stringToUint256(string memory _str) public pure + returns (uint256) + { + + } + } + */ + + /* + "e1207bee": "addPath(string[])", + "063ff7ef": "commitTransaction(string[])", + "b54138b0": "constantCall(string,string,string,bytes)", + "f4fa9d03": "deletePathList(string[])", + "6ccc29dc": "getLatestTransaction()", + "9edd3441": "getLatestTransactionInfo()", + "cb797d2f": "getMaxStep(string[])", + "4efcaed0": "getPaths(string[])", + "d55c01f7": "getTransactionInfo(string[])", + "8bc4827c": "getVersion(string[])", + "8c31f9ad": "rollbackAndDeleteTransaction(string[])", + "51cd3824": "rollbackTransaction(string[])", + "772d0b53": "sendTransaction(string,uint256,string,string,bytes)", + "18a56b67": "setMaxStep(string[])", + "e25a0866": "startTransaction(string[])", + "ac5d3723": "stringToUint256(string)" + */ + + String abi = + "[{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"addPath\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"commitTransaction\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_transactionID\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_path\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"_args\",\"type\":\"bytes\"}],\"name\":\"constantCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"deletePathList\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getLatestTransaction\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getLatestTransactionInfo\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"getMaxStep\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"getPaths\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"getTransactionInfo\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"getVersion\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"rollbackAndDeleteTransaction\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"rollbackTransaction\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_transactionID\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_seq\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_path\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"_args\",\"type\":\"bytes\"}],\"name\":\"sendTransaction\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"setMaxStep\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"startTransaction\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_str\",\"type\":\"string\"}],\"name\":\"stringToUint256\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"}]"; + ContractABIDefinition contractABIDefinition = Utils.getContractABIDefinition(abi); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("addPath") + .get(0) + .getMethodSignatureAsString(), + "addPath(string[])"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("addPath") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0xe1207bee"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0xe1207bee"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("commitTransaction") + .get(0) + .getMethodSignatureAsString(), + "commitTransaction(string[])"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("commitTransaction") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0x063ff7ef"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0x063ff7ef"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("constantCall") + .get(0) + .getMethodSignatureAsString(), + "constantCall(string,string,string,bytes)"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("constantCall") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0xb54138b0"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0xb54138b0"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("deletePathList") + .get(0) + .getMethodSignatureAsString(), + "deletePathList(string[])"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("deletePathList") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0xf4fa9d03"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0xf4fa9d03"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("getLatestTransaction") + .get(0) + .getMethodSignatureAsString(), + "getLatestTransaction()"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("getLatestTransaction") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0x6ccc29dc"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0x6ccc29dc"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("getLatestTransactionInfo") + .get(0) + .getMethodSignatureAsString(), + "getLatestTransactionInfo()"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("getLatestTransactionInfo") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0x9edd3441"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0x9edd3441"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("getMaxStep") + .get(0) + .getMethodSignatureAsString(), + "getMaxStep(string[])"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("getMaxStep") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0xcb797d2f"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0xcb797d2f"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("getPaths") + .get(0) + .getMethodSignatureAsString(), + "getPaths(string[])"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("getPaths") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0x4efcaed0"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0x4efcaed0"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("getTransactionInfo") + .get(0) + .getMethodSignatureAsString(), + "getTransactionInfo(string[])"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("getTransactionInfo") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0xd55c01f7"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0xd55c01f7"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("getVersion") + .get(0) + .getMethodSignatureAsString(), + "getVersion(string[])"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("getVersion") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0x8bc4827c"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0x8bc4827c"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("rollbackAndDeleteTransaction") + .get(0) + .getMethodSignatureAsString(), + "rollbackAndDeleteTransaction(string[])"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("rollbackAndDeleteTransaction") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0x8c31f9ad"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0x8c31f9ad"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("sendTransaction") + .get(0) + .getMethodSignatureAsString(), + "sendTransaction(string,uint256,string,string,bytes)"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("sendTransaction") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0x772d0b53"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0x772d0b53"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("rollbackTransaction") + .get(0) + .getMethodSignatureAsString(), + "rollbackTransaction(string[])"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("rollbackTransaction") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0x51cd3824"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0x51cd3824"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("setMaxStep") + .get(0) + .getMethodSignatureAsString(), + "setMaxStep(string[])"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("setMaxStep") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0x18a56b67"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0x18a56b67"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("startTransaction") + .get(0) + .getMethodSignatureAsString(), + "startTransaction(string[])"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("startTransaction") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0xe25a0866"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0xe25a0866"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("stringToUint256") + .get(0) + .getMethodSignatureAsString(), + "stringToUint256(string)"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("stringToUint256") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0xac5d3723"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0xac5d3723"))); + } + + @Test + public void testContractABIDefinitionDynamic1() throws Exception { + /* + + pragma solidity >=0.5.0 <0.6.0; + pragma experimental ABIEncoderV2; + + contract WeCrossProxy { + + string constant version = "v1.0.0-rc4"; + + // per step of transaction + struct TransactionStep { + string path; + uint256 timestamp; + address contractAddress; + string func; + bytes args; + } + + // information of transaction + struct TransactionInfo { + string[] allPaths; // all paths related to this transaction + string[] paths; // paths related to current chain + address[] contractAddresses; // locked addressed in current chain + uint8 status; // 0-Start 1-Commit 2-Rollback + uint256 startTimestamp; + uint256 commitTimestamp; + uint256 rollbackTimestamp; + uint256[] seqs; // sequence of each step + uint256 stepNum; // step number + } + + struct ContractInfo { + bool locked; // isolation control, read-committed + string path; + string transactionID; + } + + constructor() public { + + } + + function getVersion(string[] memory _args) public pure + returns(string[] memory) + { + + } + + function getMaxStep(string[] memory _args) public view + returns(string[] memory) + { + + } + + function setMaxStep(string[] memory _args) public + { + + } + + function addPath(string[] memory _args) public + { + + } + + function getPaths(string[] memory _args) public view + returns (string[] memory) + { + + } + + function deletePathList(string[] memory _args) public + { + + } + + // constant call + function constantCall(string memory _transactionID, string memory _path, string memory _func, bytes memory _args) public + returns(bytes memory) + { + + } + + // non-constant call + function sendTransaction(string memory _transactionID, uint256 _seq, string memory _path, string memory _func, bytes memory _args) public + returns(bytes memory) + { + + } + + function startTransaction(string[] memory _args) public + returns(string[] memory) + { + + } + + + function commitTransaction(string[] memory _args) public + returns(string[] memory) + { + + } + + + function rollbackTransaction(string[] memory _args) public + returns(string[] memory) + { + + } + + + function getTransactionInfo(string[] memory _args) public view + returns(string[] memory) + { + + } + + // called by router to check transaction status + function getLatestTransactionInfo() public view + returns(string[] memory) + { + + } + + function rollbackAndDeleteTransaction(string[] memory _args) public + returns (string[] memory) + { + + } + + function getLatestTransaction() public view + returns (string memory) + { + + } + + function addTransaction(string memory _transactionID) internal + { + + } + + function deleteTransaction(string memory _transactionID) internal + returns (string[] memory) + { + + } + + function callContract(address _contractAddress, string memory _sig, bytes memory _args) internal + returns(bytes memory result) + { + + } + + function getAddressByPath(string memory _path) internal view + returns (address) + { + + } + + + function getNameByPath(string memory _path) internal pure + returns (string memory) + { + + } + + // "transactionSteps": [{"seq": 0, "contract": "0x12","path": "a.b.c","timestamp": "123","func": "test1(string)","args": "aaa"},{"seq": 1, "contract": "0x12","path": "a.b.c","timestamp": "123","func": "test2(string)","args": "bbb"}] + function transactionStepArrayToJson(string memory _transactionID, uint256[] memory _seqs, uint256 _len) internal view + returns(string memory result) + { + + } + + // {"seq": 0, "contract": "0x12","path": "a.b.c","timestamp": "123","func": "test2(string)","args": "bbb"} + function transactionStepToJson(TransactionStep memory _step, uint256 _seq) internal pure + returns(string memory) + { + + } + + + function stringToUint256(string memory _str) public pure + returns (uint256) + { + + } + } + */ + + /* + "e1207bee": "addPath(string[])", + "063ff7ef": "commitTransaction(string[])", + "b54138b0": "constantCall(string,string,string,bytes)", + "f4fa9d03": "deletePathList(string[])", + "6ccc29dc": "getLatestTransaction()", + "9edd3441": "getLatestTransactionInfo()", + "cb797d2f": "getMaxStep(string[])", + "4efcaed0": "getPaths(string[])", + "d55c01f7": "getTransactionInfo(string[])", + "8bc4827c": "getVersion(string[])", + "8c31f9ad": "rollbackAndDeleteTransaction(string[])", + "51cd3824": "rollbackTransaction(string[])", + "772d0b53": "sendTransaction(string,uint256,string,string,bytes)", + "18a56b67": "setMaxStep(string[])", + "e25a0866": "startTransaction(string[])", + "ac5d3723": "stringToUint256(string)" + */ + + String abi = + "[{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"addPath\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"commitTransaction\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_transactionID\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_path\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"_args\",\"type\":\"bytes\"}],\"name\":\"constantCall\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"deletePathList\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getLatestTransaction\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"getLatestTransactionInfo\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"getMaxStep\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"getPaths\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"getTransactionInfo\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"getVersion\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"rollbackAndDeleteTransaction\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"rollbackTransaction\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_transactionID\",\"type\":\"string\"},{\"internalType\":\"uint256\",\"name\":\"_seq\",\"type\":\"uint256\"},{\"internalType\":\"string\",\"name\":\"_path\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_func\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"_args\",\"type\":\"bytes\"}],\"name\":\"sendTransaction\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"setMaxStep\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"string[]\",\"name\":\"_args\",\"type\":\"string[]\"}],\"name\":\"startTransaction\",\"outputs\":[{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"internalType\":\"string\",\"name\":\"_str\",\"type\":\"string\"}],\"name\":\"stringToUint256\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"pure\",\"type\":\"function\"}]"; + + ContractABIDefinition contractABIDefinition = Utils.getContractABIDefinition(abi); + ABIObject inputObject = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("commitTransaction").get(0)); + assertTrue(inputObject.getStructFields().get(0).isDynamic()); + + ABIObject inputObject0 = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("addPath").get(0)); + assertTrue(inputObject0.getStructFields().get(0).isDynamic()); + + ABIObject inputObject1 = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("constantCall").get(0)); + assertTrue(inputObject1.getStructFields().get(0).isDynamic()); + assertTrue(inputObject1.getStructFields().get(1).isDynamic()); + assertTrue(inputObject1.getStructFields().get(2).isDynamic()); + assertTrue(inputObject1.getStructFields().get(3).isDynamic()); + + ABIObject inputObject2 = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("deletePathList").get(0)); + assertTrue(inputObject2.getStructFields().get(0).isDynamic()); + + ABIObject inputObject3 = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("sendTransaction").get(0)); + assertTrue(inputObject3.getStructFields().get(0).isDynamic()); + assertTrue(!inputObject3.getStructFields().get(1).isDynamic()); + assertTrue(inputObject3.getStructFields().get(2).isDynamic()); + assertTrue(inputObject3.getStructFields().get(3).isDynamic()); + assertTrue(inputObject3.getStructFields().get(4).isDynamic()); + } + + @Test + public void testContractABIDefinitionBuildMethodSignature1() throws Exception { + /* + + pragma solidity ^0.4.24; + pragma experimental ABIEncoderV2; + contract TestContract + { + event TestEventSimpleParams(uint256 _u,int256 _i,bool _b,address _addr,bytes32 _bs32, string _s,bytes _bs); + event TestEventDArrayParams(uint256[] _u,int256[] _i,bool[] _b,address[] _addr,bytes32[] _bs32, string[] _s,bytes[] _bs); + event TestEventSArrayParams(uint256[4] _u,int256[4] _i,bool[4] _b,address[4] _addr,bytes32[4] _bs32, string[4] _s,bytes[4] _bs); + + function test0(uint256 _u,int256 _i,bool _b,address _addr,bytes32 _bs32, string _s,bytes _bs) public constant returns (uint256,int256,bool,address,bytes32,string,bytes) { + + } + + function test1(uint256[] _u,int256[] _i,bool[] _b,address[] _addr,bytes32[] _bs32,string[] _s,bytes[] _bs) public constant returns (uint256[],int256[],bool[],address[],bytes32[],string[],bytes[]) { + + } + + function test2(uint256[4] _u,int256[4] _i,bool[4] _b,address[4] _addr,bytes32[4] _bs32,string[4] _s,bytes[4] _bs) public constant returns (uint256[2],int256[2],bool[2],address[2],bytes32[2],string[2],bytes[2]) { + + } + } + */ + + /* + "f92a5e47": "test0(uint256,int256,bool,address,bytes32,string,bytes)", + "70be28d9": "test1(uint256[4],int256[4],bool[4],address[4],bytes32[4],string[4],bytes[4])", + "10c7e4ab": "test2(uint256[],int256[],bool[],address[],bytes32[],string[],bytes[])" + */ + + String abi = + "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_u\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"int256[]\",\"name\":\"_i\",\"type\":\"int256[]\"},{\"indexed\":false,\"internalType\":\"bool[]\",\"name\":\"_b\",\"type\":\"bool[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"_addr\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"bytes32[]\",\"name\":\"_bs32\",\"type\":\"bytes32[]\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"_s\",\"type\":\"string[]\"},{\"indexed\":false,\"internalType\":\"bytes[]\",\"name\":\"_bs\",\"type\":\"bytes[]\"}],\"name\":\"TestEventDArrayParams\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[4]\",\"name\":\"_u\",\"type\":\"uint256[4]\"},{\"indexed\":false,\"internalType\":\"int256[4]\",\"name\":\"_i\",\"type\":\"int256[4]\"},{\"indexed\":false,\"internalType\":\"bool[4]\",\"name\":\"_b\",\"type\":\"bool[4]\"},{\"indexed\":false,\"internalType\":\"address[4]\",\"name\":\"_addr\",\"type\":\"address[4]\"},{\"indexed\":false,\"internalType\":\"bytes32[4]\",\"name\":\"_bs32\",\"type\":\"bytes32[4]\"},{\"indexed\":false,\"internalType\":\"string[4]\",\"name\":\"_s\",\"type\":\"string[4]\"},{\"indexed\":false,\"internalType\":\"bytes[4]\",\"name\":\"_bs\",\"type\":\"bytes[4]\"}],\"name\":\"TestEventSArrayParams\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_u\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"_i\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_b\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_bs32\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_s\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_bs\",\"type\":\"bytes\"}],\"name\":\"TestEventSimpleParams\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_u\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"_i\",\"type\":\"int256\"},{\"internalType\":\"bool\",\"name\":\"_b\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_bs32\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"_s\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"_bs\",\"type\":\"bytes\"}],\"name\":\"test0\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_u\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"_i\",\"type\":\"int256[]\"},{\"internalType\":\"bool[]\",\"name\":\"_b\",\"type\":\"bool[]\"},{\"internalType\":\"address[]\",\"name\":\"_addr\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"_bs32\",\"type\":\"bytes32[]\"},{\"internalType\":\"string[]\",\"name\":\"_s\",\"type\":\"string[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_bs\",\"type\":\"bytes[]\"}],\"name\":\"test1\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"\",\"type\":\"int256[]\"},{\"internalType\":\"bool[]\",\"name\":\"\",\"type\":\"bool[]\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"},{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[4]\",\"name\":\"_u\",\"type\":\"uint256[4]\"},{\"internalType\":\"int256[4]\",\"name\":\"_i\",\"type\":\"int256[4]\"},{\"internalType\":\"bool[4]\",\"name\":\"_b\",\"type\":\"bool[4]\"},{\"internalType\":\"address[4]\",\"name\":\"_addr\",\"type\":\"address[4]\"},{\"internalType\":\"bytes32[4]\",\"name\":\"_bs32\",\"type\":\"bytes32[4]\"},{\"internalType\":\"string[4]\",\"name\":\"_s\",\"type\":\"string[4]\"},{\"internalType\":\"bytes[4]\",\"name\":\"_bs\",\"type\":\"bytes[4]\"}],\"name\":\"test2\",\"outputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"\",\"type\":\"uint256[2]\"},{\"internalType\":\"int256[2]\",\"name\":\"\",\"type\":\"int256[2]\"},{\"internalType\":\"bool[2]\",\"name\":\"\",\"type\":\"bool[2]\"},{\"internalType\":\"address[2]\",\"name\":\"\",\"type\":\"address[2]\"},{\"internalType\":\"bytes32[2]\",\"name\":\"\",\"type\":\"bytes32[2]\"},{\"internalType\":\"string[2]\",\"name\":\"\",\"type\":\"string[2]\"},{\"internalType\":\"bytes[2]\",\"name\":\"\",\"type\":\"bytes[2]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + + ContractABIDefinition contractABIDefinition = Utils.getContractABIDefinition(abi); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("test0") + .get(0) + .getMethodSignatureAsString(), + "test0(uint256,int256,bool,address,bytes32,string,bytes)"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("test0") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0xf92a5e47"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0xf92a5e47"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("test2") + .get(0) + .getMethodSignatureAsString(), + "test2(uint256[4],int256[4],bool[4],address[4],bytes32[4],string[4],bytes[4])"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("test2") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0x10c7e4ab"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0x10c7e4ab"))); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("test1") + .get(0) + .getMethodSignatureAsString(), + "test1(uint256[],int256[],bool[],address[],bytes32[],string[],bytes[])"); + + assertEquals( + contractABIDefinition + .getFunctions() + .get("test1") + .get(0) + .getMethodId(Utils.getCryptoInterface()), + "0x70be28d9"); + assertTrue(Objects.nonNull(contractABIDefinition.getABIDefinitionByMethodId("0x70be28d9"))); + } + + @Test + public void testContractABIDefinitionDynamic2() throws Exception { + /* + + pragma solidity ^0.4.24; + pragma experimental ABIEncoderV2; + contract TestContract + { + event TestEventSimpleParams(uint256 _u,int256 _i,bool _b,address _addr,bytes32 _bs32, string _s,bytes _bs); + event TestEventDArrayParams(uint256[] _u,int256[] _i,bool[] _b,address[] _addr,bytes32[] _bs32, string[] _s,bytes[] _bs); + event TestEventSArrayParams(uint256[4] _u,int256[4] _i,bool[4] _b,address[4] _addr,bytes32[4] _bs32, string[4] _s,bytes[4] _bs); + + function test0(uint256 _u,int256 _i,bool _b,address _addr,bytes32 _bs32, string _s,bytes _bs) public constant returns (uint256,int256,bool,address,bytes32,string,bytes) { + + } + + function test1(uint256[] _u,int256[] _i,bool[] _b,address[] _addr,bytes32[] _bs32,string[] _s,bytes[] _bs) public constant returns (uint256[],int256[],bool[],address[],bytes32[],string[],bytes[]) { + + } + + function test2(uint256[4] _u,int256[4] _i,bool[4] _b,address[4] _addr,bytes32[4] _bs32,string[4] _s,bytes[4] _bs) public constant returns (uint256[2],int256[2],bool[2],address[2],bytes32[2],string[2],bytes[2]) { + + } + } + */ + + /* + "f92a5e47": "test0(uint256,int256,bool,address,bytes32,string,bytes)", + "70be28d9": "test2(uint256[4],int256[4],bool[4],address[4],bytes32[4],string[4],bytes[4])", + "10c7e4ab": "test1(uint256[],int256[],bool[],address[],bytes32[],string[],bytes[])" + */ + + String abi = + "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"_u\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"int256[]\",\"name\":\"_i\",\"type\":\"int256[]\"},{\"indexed\":false,\"internalType\":\"bool[]\",\"name\":\"_b\",\"type\":\"bool[]\"},{\"indexed\":false,\"internalType\":\"address[]\",\"name\":\"_addr\",\"type\":\"address[]\"},{\"indexed\":false,\"internalType\":\"bytes32[]\",\"name\":\"_bs32\",\"type\":\"bytes32[]\"},{\"indexed\":false,\"internalType\":\"string[]\",\"name\":\"_s\",\"type\":\"string[]\"},{\"indexed\":false,\"internalType\":\"bytes[]\",\"name\":\"_bs\",\"type\":\"bytes[]\"}],\"name\":\"TestEventDArrayParams\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256[4]\",\"name\":\"_u\",\"type\":\"uint256[4]\"},{\"indexed\":false,\"internalType\":\"int256[4]\",\"name\":\"_i\",\"type\":\"int256[4]\"},{\"indexed\":false,\"internalType\":\"bool[4]\",\"name\":\"_b\",\"type\":\"bool[4]\"},{\"indexed\":false,\"internalType\":\"address[4]\",\"name\":\"_addr\",\"type\":\"address[4]\"},{\"indexed\":false,\"internalType\":\"bytes32[4]\",\"name\":\"_bs32\",\"type\":\"bytes32[4]\"},{\"indexed\":false,\"internalType\":\"string[4]\",\"name\":\"_s\",\"type\":\"string[4]\"},{\"indexed\":false,\"internalType\":\"bytes[4]\",\"name\":\"_bs\",\"type\":\"bytes[4]\"}],\"name\":\"TestEventSArrayParams\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_u\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"_i\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"_b\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"_bs32\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"string\",\"name\":\"_s\",\"type\":\"string\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"_bs\",\"type\":\"bytes\"}],\"name\":\"TestEventSimpleParams\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_u\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"_i\",\"type\":\"int256\"},{\"internalType\":\"bool\",\"name\":\"_b\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"_addr\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"_bs32\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"_s\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"_bs\",\"type\":\"bytes\"}],\"name\":\"test0\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"},{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"},{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"_u\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"_i\",\"type\":\"int256[]\"},{\"internalType\":\"bool[]\",\"name\":\"_b\",\"type\":\"bool[]\"},{\"internalType\":\"address[]\",\"name\":\"_addr\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"_bs32\",\"type\":\"bytes32[]\"},{\"internalType\":\"string[]\",\"name\":\"_s\",\"type\":\"string[]\"},{\"internalType\":\"bytes[]\",\"name\":\"_bs\",\"type\":\"bytes[]\"}],\"name\":\"test1\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"},{\"internalType\":\"int256[]\",\"name\":\"\",\"type\":\"int256[]\"},{\"internalType\":\"bool[]\",\"name\":\"\",\"type\":\"bool[]\"},{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"},{\"internalType\":\"string[]\",\"name\":\"\",\"type\":\"string[]\"},{\"internalType\":\"bytes[]\",\"name\":\"\",\"type\":\"bytes[]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"internalType\":\"uint256[4]\",\"name\":\"_u\",\"type\":\"uint256[4]\"},{\"internalType\":\"int256[4]\",\"name\":\"_i\",\"type\":\"int256[4]\"},{\"internalType\":\"bool[4]\",\"name\":\"_b\",\"type\":\"bool[4]\"},{\"internalType\":\"address[4]\",\"name\":\"_addr\",\"type\":\"address[4]\"},{\"internalType\":\"bytes32[4]\",\"name\":\"_bs32\",\"type\":\"bytes32[4]\"},{\"internalType\":\"string[4]\",\"name\":\"_s\",\"type\":\"string[4]\"},{\"internalType\":\"bytes[4]\",\"name\":\"_bs\",\"type\":\"bytes[4]\"}],\"name\":\"test2\",\"outputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"\",\"type\":\"uint256[2]\"},{\"internalType\":\"int256[2]\",\"name\":\"\",\"type\":\"int256[2]\"},{\"internalType\":\"bool[2]\",\"name\":\"\",\"type\":\"bool[2]\"},{\"internalType\":\"address[2]\",\"name\":\"\",\"type\":\"address[2]\"},{\"internalType\":\"bytes32[2]\",\"name\":\"\",\"type\":\"bytes32[2]\"},{\"internalType\":\"string[2]\",\"name\":\"\",\"type\":\"string[2]\"},{\"internalType\":\"bytes[2]\",\"name\":\"\",\"type\":\"bytes[2]\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"; + + ContractABIDefinition contractABIDefinition = Utils.getContractABIDefinition(abi); + ABIObject inputObject1 = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("test0").get(0)); + assertTrue(!inputObject1.getStructFields().get(0).isDynamic()); + assertTrue(!inputObject1.getStructFields().get(1).isDynamic()); + assertTrue(!inputObject1.getStructFields().get(2).isDynamic()); + assertTrue(!inputObject1.getStructFields().get(3).isDynamic()); + assertTrue(!inputObject1.getStructFields().get(4).isDynamic()); + assertTrue(inputObject1.getStructFields().get(5).isDynamic()); + assertTrue(inputObject1.getStructFields().get(6).isDynamic()); + + ABIObject inputObject2 = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("test2").get(0)); + assertTrue(!inputObject2.getStructFields().get(0).isDynamic()); + assertTrue(!inputObject2.getStructFields().get(1).isDynamic()); + assertTrue(!inputObject2.getStructFields().get(2).isDynamic()); + assertTrue(!inputObject2.getStructFields().get(3).isDynamic()); + assertTrue(!inputObject2.getStructFields().get(4).isDynamic()); + assertTrue(inputObject2.getStructFields().get(5).isDynamic()); + assertTrue(inputObject2.getStructFields().get(6).isDynamic()); + + ABIObject inputObject3 = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("test1").get(0)); + assertTrue(inputObject3.getStructFields().get(0).isDynamic()); + assertTrue(inputObject3.getStructFields().get(1).isDynamic()); + assertTrue(inputObject3.getStructFields().get(2).isDynamic()); + assertTrue(inputObject3.getStructFields().get(3).isDynamic()); + assertTrue(inputObject3.getStructFields().get(4).isDynamic()); + assertTrue(inputObject3.getStructFields().get(5).isDynamic()); + assertTrue(inputObject3.getStructFields().get(6).isDynamic()); + } +} diff --git a/src/test/java/org/fisco/bcos/sdk/test/abi/ABIObjectTest.java b/src/test/java/org/fisco/bcos/sdk/test/abi/ABIObjectTest.java new file mode 100644 index 000000000..4de4ed31d --- /dev/null +++ b/src/test/java/org/fisco/bcos/sdk/test/abi/ABIObjectTest.java @@ -0,0 +1,606 @@ +package org.fisco.bcos.sdk.test.abi; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import java.math.BigInteger; +import org.fisco.bcos.sdk.abi.datatypes.Address; +import org.fisco.bcos.sdk.abi.datatypes.Bool; +import org.fisco.bcos.sdk.abi.datatypes.Bytes; +import org.fisco.bcos.sdk.abi.datatypes.DynamicBytes; +import org.fisco.bcos.sdk.abi.datatypes.Utf8String; +import org.fisco.bcos.sdk.abi.datatypes.generated.Bytes1; +import org.fisco.bcos.sdk.abi.datatypes.generated.Bytes10; +import org.fisco.bcos.sdk.abi.datatypes.generated.Bytes4; +import org.fisco.bcos.sdk.abi.datatypes.generated.Bytes6; +import org.fisco.bcos.sdk.abi.datatypes.generated.Int256; +import org.fisco.bcos.sdk.abi.datatypes.generated.Uint256; +import org.fisco.bcos.sdk.abi.wrapper.ABIDefinition; +import org.fisco.bcos.sdk.abi.wrapper.ABIObject; +import org.fisco.bcos.sdk.abi.wrapper.ABIObject.ObjectType; +import org.fisco.bcos.sdk.abi.wrapper.ABIObjectFactory; +import org.junit.Assert; +import org.junit.Test; + +public class ABIObjectTest { + + @Test + public void testMixedTypeEncode0() { + // int a, Info[] memory b, string memory c + /* + * { + "0": "int256: a 100", + "1": "tuple(string,int256,tuple(int256,int256,int256)[])[]: b Hello world!,100,1,2,3,Hello world2!,200,5,6,7", + "2": "string: c Hello world!" + } + */ + + String abiDesc = + "[\n" + + " {\n" + + " \"anonymous\": false,\n" + + " \"inputs\": [\n" + + " {\n" + + " \"indexed\": false,\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"a\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"components\": [\n" + + " {\n" + + " \"internalType\": \"string\",\n" + + " \"name\": \"name\",\n" + + " \"type\": \"string\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"count\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"components\": [\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"a\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"b\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"c\",\n" + + " \"type\": \"int256\"\n" + + " }\n" + + " ],\n" + + " \"internalType\": \"struct Proxy.Item[]\",\n" + + " \"name\": \"items\",\n" + + " \"type\": \"tuple[]\"\n" + + " }\n" + + " ],\n" + + " \"indexed\": false,\n" + + " \"internalType\": \"struct Proxy.Info[]\",\n" + + " \"name\": \"b\",\n" + + " \"type\": \"tuple[]\"\n" + + " },\n" + + " {\n" + + " \"indexed\": false,\n" + + " \"internalType\": \"string\",\n" + + " \"name\": \"c\",\n" + + " \"type\": \"string\"\n" + + " }\n" + + " ],\n" + + " \"name\": \"output1\",\n" + + " \"type\": \"event\"\n" + + " },\n" + + " {\n" + + " \"constant\": false,\n" + + " \"inputs\": [\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"a\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"components\": [\n" + + " {\n" + + " \"internalType\": \"string\",\n" + + " \"name\": \"name\",\n" + + " \"type\": \"string\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"count\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"components\": [\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"a\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"b\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"c\",\n" + + " \"type\": \"int256\"\n" + + " }\n" + + " ],\n" + + " \"internalType\": \"struct Proxy.Item[]\",\n" + + " \"name\": \"items\",\n" + + " \"type\": \"tuple[]\"\n" + + " }\n" + + " ],\n" + + " \"internalType\": \"struct Proxy.Info[]\",\n" + + " \"name\": \"b\",\n" + + " \"type\": \"tuple[]\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"string\",\n" + + " \"name\": \"c\",\n" + + " \"type\": \"string\"\n" + + " }\n" + + " ],\n" + + " \"name\": \"test\",\n" + + " \"outputs\": [\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"\",\n" + + " \"type\": \"int256\"\n" + + " }\n" + + " ],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"function\"\n" + + " },\n" + + " {\n" + + " \"constant\": false,\n" + + " \"inputs\": [],\n" + + " \"name\": \"test1\",\n" + + " \"outputs\": [\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"a\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"components\": [\n" + + " {\n" + + " \"internalType\": \"string\",\n" + + " \"name\": \"name\",\n" + + " \"type\": \"string\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"count\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"components\": [\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"a\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"b\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"int256\",\n" + + " \"name\": \"c\",\n" + + " \"type\": \"int256\"\n" + + " }\n" + + " ],\n" + + " \"internalType\": \"struct Proxy.Item[]\",\n" + + " \"name\": \"items\",\n" + + " \"type\": \"tuple[]\"\n" + + " }\n" + + " ],\n" + + " \"internalType\": \"struct Proxy.Info[]\",\n" + + " \"name\": \"b\",\n" + + " \"type\": \"tuple[]\"\n" + + " },\n" + + " {\n" + + " \"internalType\": \"string\",\n" + + " \"name\": \"c\",\n" + + " \"type\": \"string\"\n" + + " }\n" + + " ],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"function\"\n" + + " },\n" + + " {\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"fallback\"\n" + + " }\n" + + "]"; + + ABIObject listParams = new ABIObject(ABIObject.ListType.DYNAMIC); + + ABIObject item1 = new ABIObject(ObjectType.STRUCT); + item1.getStructFields().add(new ABIObject(new Utf8String("Hello world!"))); + item1.getStructFields().add(new ABIObject(new Uint256(100))); + item1.getStructFields().add(new ABIObject(ABIObject.ListType.DYNAMIC)); + + item1.getStructFields().get(2).getListValues().add(new ABIObject(ObjectType.STRUCT)); + + item1.getStructFields() + .get(2) + .getListValues() + .get(0) + .getStructFields() + .add(new ABIObject(new Uint256(1))); + item1.getStructFields() + .get(2) + .getListValues() + .get(0) + .getStructFields() + .add(new ABIObject(new Uint256(2))); + item1.getStructFields() + .get(2) + .getListValues() + .get(0) + .getStructFields() + .add(new ABIObject(new Uint256(3))); + + listParams.getListValues().add(item1); + + ABIObject item2 = new ABIObject(ObjectType.STRUCT); + item2.getStructFields().add(new ABIObject(new Utf8String("Hello world2"))); + item2.getStructFields().add(new ABIObject(new Uint256(200))); + item2.getStructFields().add(new ABIObject(ABIObject.ListType.DYNAMIC)); + + item2.getStructFields().get(2).getListValues().add(new ABIObject(ObjectType.STRUCT)); + + item2.getStructFields() + .get(2) + .getListValues() + .get(0) + .getStructFields() + .add(new ABIObject(new Uint256(5))); + item2.getStructFields() + .get(2) + .getListValues() + .get(0) + .getStructFields() + .add(new ABIObject(new Uint256(6))); + item2.getStructFields() + .get(2) + .getListValues() + .get(0) + .getStructFields() + .add(new ABIObject(new Uint256(7))); + + listParams.getListValues().add(item2); + + ABIObject abiObject = new ABIObject(ObjectType.STRUCT); + + abiObject.getStructFields().add(new ABIObject(new Uint256(100))); + abiObject.getStructFields().add(listParams); + abiObject.getStructFields().add(new ABIObject(new Utf8String("Hello world!"))); + + String encodeHex = abiObject.encode(); + + Assert.assertEquals( + "0000000000000000000000000000000000000000000000000000000000000064" + + "0000000000000000000000000000000000000000000000000000000000000060" + + "0000000000000000000000000000000000000000000000000000000000000300" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000040" + + "0000000000000000000000000000000000000000000000000000000000000160" + + "0000000000000000000000000000000000000000000000000000000000000060" + + "0000000000000000000000000000000000000000000000000000000000000064" + + "00000000000000000000000000000000000000000000000000000000000000a0" + + "000000000000000000000000000000000000000000000000000000000000000c" + + "48656c6c6f20776f726c64210000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000003" + + "0000000000000000000000000000000000000000000000000000000000000060" + + "00000000000000000000000000000000000000000000000000000000000000c8" + + "00000000000000000000000000000000000000000000000000000000000000a0" + + "000000000000000000000000000000000000000000000000000000000000000c" + + "48656c6c6f20776f726c64320000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000005" + + "0000000000000000000000000000000000000000000000000000000000000006" + + "0000000000000000000000000000000000000000000000000000000000000007" + + "000000000000000000000000000000000000000000000000000000000000000c" + + "48656c6c6f20776f726c64210000000000000000000000000000000000000000", + encodeHex); + + ABIDefinition abiDefinition = + Utils.getContractABIDefinition(abiDesc).getFunctions().get("test").get(0); + ABIObject inputObject = ABIObjectFactory.createInputObject(abiDefinition); + ABIObject decodeObject = inputObject.decode(encodeHex); + + Assert.assertEquals(encodeHex, decodeObject.encode()); + + ABIObject newObjectWithoutValue = inputObject.newObjectWithoutValue(); + Assert.assertEquals(encodeHex, newObjectWithoutValue.decode(encodeHex).encode()); + } + + @Test + public void testSingleValue() { + ABIObject abiObject = new ABIObject(new Utf8String("Greetings!")); + ABIObject structObject = new ABIObject(ObjectType.STRUCT); + structObject.getStructFields().add(abiObject); + assertThat( + structObject.encode(), + is( + "0000000000000000000000000000000000000000000000000000000000000020" + + "000000000000000000000000000000000000000000000000000000000000000a" + + "4772656574696e67732100000000000000000000000000000000000000000000")); + } + + @Test + public void testEncode1() { + + ABIObject abiObject = new ABIObject(ObjectType.STRUCT); + abiObject.getStructFields().add(new ABIObject(new Uint256(69))); + abiObject.getStructFields().add(new ABIObject(new Bool(true))); + + assertThat( + abiObject.encode(), + is( + "0000000000000000000000000000000000000000000000000000000000000045" + + "0000000000000000000000000000000000000000000000000000000000000001")); + + abiObject.getStructFields().clear(); + abiObject.getStructFields().add(new ABIObject(new Bytes(3, "abc".getBytes()))); + abiObject.getStructFields().add(new ABIObject(new Bytes(3, "def".getBytes()))); + + assertThat( + abiObject.encode(), + is( + "6162630000000000000000000000000000000000000000000000000000000000" + + "6465660000000000000000000000000000000000000000000000000000000000")); + + abiObject.getStructFields().clear(); + abiObject.getStructFields().add(new ABIObject(new DynamicBytes("dave".getBytes()))); + abiObject.getStructFields().add(new ABIObject(new Bool(true))); + + ABIObject listObject = new ABIObject(ABIObject.ListType.DYNAMIC); + listObject.getListValues().add(new ABIObject(new Uint256(1))); + listObject.getListValues().add(new ABIObject(new Uint256(2))); + listObject.getListValues().add(new ABIObject(new Uint256(3))); + + abiObject.getStructFields().add(listObject); + + assertThat( + abiObject.encode(), + is( + "0000000000000000000000000000000000000000000000000000000000000060" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "00000000000000000000000000000000000000000000000000000000000000a0" + + "0000000000000000000000000000000000000000000000000000000000000004" + + "6461766500000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000003" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000003")); + + abiObject.getStructFields().clear(); + abiObject.getStructFields().add(new ABIObject(new Uint256(0x123))); + + ABIObject listObject0 = new ABIObject(ABIObject.ListType.DYNAMIC); + listObject0.getListValues().add(new ABIObject(new Uint256(0x456))); + listObject0.getListValues().add(new ABIObject(new Uint256(0x789))); + abiObject.getStructFields().add(listObject0); + + abiObject.getStructFields().add(new ABIObject(new Bytes10("1234567890".getBytes()))); + abiObject + .getStructFields() + .add(new ABIObject(new DynamicBytes("Hello, world!".getBytes()))); + + assertThat( + abiObject.encode(), + is( + "0000000000000000000000000000000000000000000000000000000000000123" + + "0000000000000000000000000000000000000000000000000000000000000080" + + "3132333435363738393000000000000000000000000000000000000000000000" + + "00000000000000000000000000000000000000000000000000000000000000e0" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000456" + + "0000000000000000000000000000000000000000000000000000000000000789" + + "000000000000000000000000000000000000000000000000000000000000000d" + + "48656c6c6f2c20776f726c642100000000000000000000000000000000000000")); + + abiObject.getStructFields().clear(); + + ABIObject listObject1 = new ABIObject(ABIObject.ListType.DYNAMIC); + ABIObject listObject1_0 = new ABIObject(ABIObject.ListType.DYNAMIC); + ABIObject listObject1_1 = new ABIObject(ABIObject.ListType.DYNAMIC); + + listObject1_0.getListValues().add(new ABIObject(new Uint256(1))); + listObject1_0.getListValues().add(new ABIObject(new Uint256(2))); + + listObject1_1.getListValues().add(new ABIObject(new Uint256(3))); + + listObject1.getListValues().add(listObject1_0); + listObject1.getListValues().add(listObject1_1); + + ABIObject listObject2 = new ABIObject(ABIObject.ListType.DYNAMIC); + listObject2.getListValues().add(new ABIObject(new Utf8String("one"))); + listObject2.getListValues().add(new ABIObject(new Utf8String("two"))); + listObject2.getListValues().add(new ABIObject(new Utf8String("three"))); + + abiObject.getStructFields().add(listObject1); + abiObject.getStructFields().add(listObject2); + + assertThat( + abiObject.encode(), + is( + "0000000000000000000000000000000000000000000000000000000000000040" + + "0000000000000000000000000000000000000000000000000000000000000140" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000040" + + "00000000000000000000000000000000000000000000000000000000000000a0" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000002" + + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000003" + + "0000000000000000000000000000000000000000000000000000000000000003" + + "0000000000000000000000000000000000000000000000000000000000000060" + + "00000000000000000000000000000000000000000000000000000000000000a0" + + "00000000000000000000000000000000000000000000000000000000000000e0" + + "0000000000000000000000000000000000000000000000000000000000000003" + + "6f6e650000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000003" + + "74776f0000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000005" + + "7468726565000000000000000000000000000000000000000000000000000000")); + } + + @Test + public void testBoolTypeEncode() { + assertThat( + new ABIObject(new Bool(false)).encode(), + is("0000000000000000000000000000000000000000000000000000000000000000")); + assertThat( + new ABIObject(new Bool(true)).encode(), + is("0000000000000000000000000000000000000000000000000000000000000001")); + } + + @Test + public void testIntTypeEncode() { + assertThat( + new ABIObject(new Uint256(BigInteger.ZERO)).encode(), + is("0000000000000000000000000000000000000000000000000000000000000000")); + + assertThat( + new ABIObject(new Int256(BigInteger.ZERO)).encode(), + is("0000000000000000000000000000000000000000000000000000000000000000")); + + assertThat( + new ABIObject(new Uint256(Long.MAX_VALUE)).encode(), + is("0000000000000000000000000000000000000000000000007fffffffffffffff")); + + assertThat( + new ABIObject(new Int256(Long.MAX_VALUE)).encode(), + is("0000000000000000000000000000000000000000000000007fffffffffffffff")); + + assertThat( + new ABIObject( + new Uint256( + new BigInteger( + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe", + 16))) + .encode(), + is("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe")); + } + + @Test + public void testEmptyListEncode() { + + assertThat( + new ABIObject(ABIObject.ListType.DYNAMIC).encode(), + is("0000000000000000000000000000000000000000000000000000000000000000")); + } + + @Test + public void testStringEncode() { + assertThat( + new ABIObject(new Utf8String("Hello, world!")).encode(), + is( + "000000000000000000000000000000000000000000000000000000000000000d" + + "48656c6c6f2c20776f726c642100000000000000000000000000000000000000")); + + assertThat( + new ABIObject(new Utf8String("")).encode(), + is("0000000000000000000000000000000000000000000000000000000000000000")); + } + + @Test + public void testAddressEncode() { + Address address = new Address("0xbe5422d15f39373eb0a97ff8c10fbd0e40e29338"); + assertThat( + new ABIObject(address).encode(), + is("000000000000000000000000be5422d15f39373eb0a97ff8c10fbd0e40e29338")); + } + + @Test + public void testStaticBytesEncode() { + Bytes staticBytes = new Bytes6(new byte[] {0, 1, 2, 3, 4, 5}); + assertThat( + new ABIObject(staticBytes).encode(), + is("0001020304050000000000000000000000000000000000000000000000000000")); + + Bytes empty = new Bytes1(new byte[] {0}); + assertThat( + new ABIObject(empty).encode(), + is("0000000000000000000000000000000000000000000000000000000000000000")); + + Bytes dave = new Bytes4("dave".getBytes()); + assertThat( + new ABIObject(dave).encode(), + is("6461766500000000000000000000000000000000000000000000000000000000")); + } + + @Test + public void testDynamicBytesEncode() { + DynamicBytes dynamicBytes = new DynamicBytes(new byte[] {0, 1, 2, 3, 4, 5}); + assertThat( + new ABIObject(dynamicBytes).encode(), + is( + "0000000000000000000000000000000000000000000000000000000000000006" + + "0001020304050000000000000000000000000000000000000000000000000000")); + + DynamicBytes empty = new DynamicBytes(new byte[] {0}); + assertThat( + new ABIObject(empty).encode(), + is( + "0000000000000000000000000000000000000000000000000000000000000001" + + "0000000000000000000000000000000000000000000000000000000000000000")); + + DynamicBytes dave = new DynamicBytes("dave".getBytes()); + assertThat( + new ABIObject(dave).encode(), + is( + "0000000000000000000000000000000000000000000000000000000000000004" + + "6461766500000000000000000000000000000000000000000000000000000000")); + + 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( + new ABIObject(loremIpsum).encode(), + is( + "00000000000000000000000000000000000000000000000000000000000001bd" + + "4c6f72656d20697073756d20646f6c6f722073697420616d65742c20636f6e73" + + "656374657475722061646970697363696e6720656c69742c2073656420646f20" + + "656975736d6f642074656d706f7220696e6369646964756e74207574206c6162" + + "6f726520657420646f6c6f7265206d61676e6120616c697175612e2055742065" + + "6e696d206164206d696e696d2076656e69616d2c2071756973206e6f73747275" + + "6420657865726369746174696f6e20756c6c616d636f206c61626f726973206e" + + "69736920757420616c697175697020657820656120636f6d6d6f646f20636f6e" + + "7365717561742e2044756973206175746520697275726520646f6c6f7220696e" + + "20726570726568656e646572697420696e20766f6c7570746174652076656c69" + + "7420657373652063696c6c756d20646f6c6f726520657520667567696174206e" + + "756c6c612070617269617475722e204578636570746575722073696e74206f63" + + "63616563617420637570696461746174206e6f6e2070726f6964656e742c2073" + + "756e7420696e2063756c706120717569206f666669636961206465736572756e" + + "74206d6f6c6c697420616e696d20696420657374206c61626f72756d2e000000")); + } +} diff --git a/src/test/java/org/fisco/bcos/sdk/test/abi/ContractTypeTest.java b/src/test/java/org/fisco/bcos/sdk/test/abi/ContractTypeTest.java new file mode 100644 index 000000000..496d8e8d6 --- /dev/null +++ b/src/test/java/org/fisco/bcos/sdk/test/abi/ContractTypeTest.java @@ -0,0 +1,346 @@ +package org.fisco.bcos.sdk.test.abi; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Base64; +import java.util.List; +import org.fisco.bcos.sdk.abi.wrapper.ABICodecJsonWrapper; +import org.fisco.bcos.sdk.abi.wrapper.ABIObject; +import org.fisco.bcos.sdk.abi.wrapper.ABIObjectFactory; +import org.fisco.bcos.sdk.abi.wrapper.ContractABIDefinition; +import org.junit.Assert; +import org.junit.Test; + +public class ContractTypeTest { + String abiDesc = + "[\n" + + "\t{\n" + + "\t\t\"constant\": false,\n" + + "\t\t\"inputs\": [\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_u\",\n" + + "\t\t\t\t\"type\": \"uint256[]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_b\",\n" + + "\t\t\t\t\"type\": \"bool[]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_addr\",\n" + + "\t\t\t\t\"type\": \"address[]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_bs32\",\n" + + "\t\t\t\t\"type\": \"bytes32[]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_s\",\n" + + "\t\t\t\t\"type\": \"string[]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_bs\",\n" + + "\t\t\t\t\"type\": \"bytes[]\"\n" + + "\t\t\t}\n" + + "\t\t],\n" + + "\t\t\"name\": \"setDynamicValue\",\n" + + "\t\t\"outputs\": [],\n" + + "\t\t\"payable\": false,\n" + + "\t\t\"stateMutability\": \"nonpayable\",\n" + + "\t\t\"type\": \"function\"\n" + + "\t},\n" + + "\t{\n" + + "\t\t\"constant\": false,\n" + + "\t\t\"inputs\": [\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_u\",\n" + + "\t\t\t\t\"type\": \"uint256[3]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_b\",\n" + + "\t\t\t\t\"type\": \"bool[3]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_addr\",\n" + + "\t\t\t\t\"type\": \"address[3]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_bs32\",\n" + + "\t\t\t\t\"type\": \"bytes32[3]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_s\",\n" + + "\t\t\t\t\"type\": \"string[3]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_bs\",\n" + + "\t\t\t\t\"type\": \"bytes[3]\"\n" + + "\t\t\t}\n" + + "\t\t],\n" + + "\t\t\"name\": \"setFixedValue\",\n" + + "\t\t\"outputs\": [],\n" + + "\t\t\"payable\": false,\n" + + "\t\t\"stateMutability\": \"nonpayable\",\n" + + "\t\t\"type\": \"function\"\n" + + "\t},\n" + + "\t{\n" + + "\t\t\"constant\": false,\n" + + "\t\t\"inputs\": [\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_u\",\n" + + "\t\t\t\t\"type\": \"uint256\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_b\",\n" + + "\t\t\t\t\"type\": \"bool\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_addr\",\n" + + "\t\t\t\t\"type\": \"address\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_bs32\",\n" + + "\t\t\t\t\"type\": \"bytes32\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_s\",\n" + + "\t\t\t\t\"type\": \"string\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_bs\",\n" + + "\t\t\t\t\"type\": \"bytes\"\n" + + "\t\t\t}\n" + + "\t\t],\n" + + "\t\t\"name\": \"setValue\",\n" + + "\t\t\"outputs\": [],\n" + + "\t\t\"payable\": false,\n" + + "\t\t\"stateMutability\": \"nonpayable\",\n" + + "\t\t\"type\": \"function\"\n" + + "\t},\n" + + "\t{\n" + + "\t\t\"constant\": true,\n" + + "\t\t\"inputs\": [],\n" + + "\t\t\"name\": \"getDynamicValue\",\n" + + "\t\t\"outputs\": [\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_u\",\n" + + "\t\t\t\t\"type\": \"uint256[]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_b\",\n" + + "\t\t\t\t\"type\": \"bool[]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_addr\",\n" + + "\t\t\t\t\"type\": \"address[]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_bs32\",\n" + + "\t\t\t\t\"type\": \"bytes32[]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_s\",\n" + + "\t\t\t\t\"type\": \"string[]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_bs\",\n" + + "\t\t\t\t\"type\": \"bytes[]\"\n" + + "\t\t\t}\n" + + "\t\t],\n" + + "\t\t\"payable\": false,\n" + + "\t\t\"stateMutability\": \"view\",\n" + + "\t\t\"type\": \"function\"\n" + + "\t},\n" + + "\t{\n" + + "\t\t\"constant\": true,\n" + + "\t\t\"inputs\": [],\n" + + "\t\t\"name\": \"getFixedValue\",\n" + + "\t\t\"outputs\": [\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_u\",\n" + + "\t\t\t\t\"type\": \"uint256[3]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_b\",\n" + + "\t\t\t\t\"type\": \"bool[3]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_addr\",\n" + + "\t\t\t\t\"type\": \"address[3]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_bs32\",\n" + + "\t\t\t\t\"type\": \"bytes32[3]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_s\",\n" + + "\t\t\t\t\"type\": \"string[3]\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_bs\",\n" + + "\t\t\t\t\"type\": \"bytes[3]\"\n" + + "\t\t\t}\n" + + "\t\t],\n" + + "\t\t\"payable\": false,\n" + + "\t\t\"stateMutability\": \"view\",\n" + + "\t\t\"type\": \"function\"\n" + + "\t},\n" + + "\t{\n" + + "\t\t\"constant\": true,\n" + + "\t\t\"inputs\": [],\n" + + "\t\t\"name\": \"getValue\",\n" + + "\t\t\"outputs\": [\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_u\",\n" + + "\t\t\t\t\"type\": \"uint256\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_b\",\n" + + "\t\t\t\t\"type\": \"bool\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_addr\",\n" + + "\t\t\t\t\"type\": \"address\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_bs32\",\n" + + "\t\t\t\t\"type\": \"bytes32\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_s\",\n" + + "\t\t\t\t\"type\": \"string\"\n" + + "\t\t\t},\n" + + "\t\t\t{\n" + + "\t\t\t\t\"name\": \"_bs\",\n" + + "\t\t\t\t\"type\": \"bytes\"\n" + + "\t\t\t}\n" + + "\t\t],\n" + + "\t\t\"payable\": false,\n" + + "\t\t\"stateMutability\": \"view\",\n" + + "\t\t\"type\": \"function\"\n" + + "\t}\n" + + "]"; + + /* + { + "20965255": "getValue()", + "ed4d0e39": "getDynamicValue()", + "c1cee39a": "getFixedValue()", + "dfed87e3": "setDynamicValue(uint256[],bool[],address[],bytes32[],string[],bytes[])", + "63e5584b": "setFixedValue(uint256[3],bool[3],address[3],bytes32[3],string[3],bytes[3])", + "11cfbe17": "setValue(uint256,bool,address,bytes32,string,bytes)" + }*/ + + private ContractABIDefinition contractABIDefinition = Utils.getContractABIDefinition(abiDesc); + + @Test + public void ContractFixedTypeCodecTest() throws IOException { + ABIObject inputObject = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("setFixedValue").get(0)); + + ABIObject outObject = + ABIObjectFactory.createOutputObject( + contractABIDefinition.getFunctions().get("getFixedValue").get(0)); + + String bytes1 = Base64.getEncoder().encodeToString("HelloWorld 11111".getBytes()); + String bytes2 = Base64.getEncoder().encodeToString("HelloWorld 22222".getBytes()); + String bytes3 = Base64.getEncoder().encodeToString("HelloWorld 33333".getBytes()); + + List params = + Arrays.asList( + "[1,2,3]", + "[true,false,true]", + "[\"0xa\",\"0xb\",\"0xc\"]", + "[\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\"]", + "[\"a\",\"b\",\"c\"]", + "[\"" + bytes1 + "\",\"" + bytes2 + "\",\"" + bytes3 + "\"]"); + + ABICodecJsonWrapper abiCodecJsonWrapper = new ABICodecJsonWrapper(); + ABIObject encodeObject = abiCodecJsonWrapper.encode(inputObject, params); + + List decodeResult = abiCodecJsonWrapper.decode(outObject, encodeObject.encode()); + + Assert.assertEquals(decodeResult.get(0), "[ 1, 2, 3 ]"); + Assert.assertEquals(decodeResult.get(1), "[ true, false, true ]"); + Assert.assertEquals( + decodeResult.get(2), + "[ \"0x000000000000000000000000000000000000000a\", \"0x000000000000000000000000000000000000000b\", \"0x000000000000000000000000000000000000000c\" ]"); + Assert.assertEquals( + decodeResult.get(3), + "[ \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\" ]"); + + Assert.assertEquals(decodeResult.get(4), "[ \"a\", \"b\", \"c\" ]"); + Assert.assertEquals( + decodeResult.get(5), + "[ \"" + bytes1 + "\", \"" + bytes2 + "\", \"" + bytes3 + "\" ]"); + } + + @Test + public void ContractDynamicTypeCodecTest() throws IOException { + ABIObject inputObject = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("setDynamicValue").get(0)); + + ABIObject outObject = + ABIObjectFactory.createOutputObject( + contractABIDefinition.getFunctions().get("getDynamicValue").get(0)); + + String bytes1 = Base64.getEncoder().encodeToString("HelloWorld 11111".getBytes()); + String bytes2 = Base64.getEncoder().encodeToString("HelloWorld 22222".getBytes()); + String bytes3 = Base64.getEncoder().encodeToString("HelloWorld 33333".getBytes()); + + List params = + Arrays.asList( + "[1,2,3]", + "[true,false,true]", + "[\"0xa\",\"0xb\",\"0xc\"]", + "[\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\",\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\"]", + "[\"a\",\"b\",\"c\"]", + "[\"" + bytes1 + "\",\"" + bytes2 + "\",\"" + bytes3 + "\"]"); + + ABICodecJsonWrapper abiCodecJsonWrapper = new ABICodecJsonWrapper(); + ABIObject encodeObject = abiCodecJsonWrapper.encode(inputObject, params); + + List decodeResult = abiCodecJsonWrapper.decode(outObject, encodeObject.encode()); + + Assert.assertEquals(decodeResult.get(0), "[ 1, 2, 3 ]"); + Assert.assertEquals(decodeResult.get(1), "[ true, false, true ]"); + Assert.assertEquals( + decodeResult.get(2), + "[ \"0x000000000000000000000000000000000000000a\", \"0x000000000000000000000000000000000000000b\", \"0x000000000000000000000000000000000000000c\" ]"); + Assert.assertEquals( + decodeResult.get(3), + "[ \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\", \"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\" ]"); + + Assert.assertEquals(decodeResult.get(4), "[ \"a\", \"b\", \"c\" ]"); + Assert.assertEquals( + decodeResult.get(5), + "[ \"" + bytes1 + "\", \"" + bytes2 + "\", \"" + bytes3 + "\" ]"); + } + + @Test + public void ContractDynamicTypeEmptyParamsCodecTest() throws IOException { + ABIObject inputObject = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("setDynamicValue").get(0)); + + ABIObject outObject = + ABIObjectFactory.createOutputObject( + contractABIDefinition.getFunctions().get("getDynamicValue").get(0)); + + List params = Arrays.asList("[]", "[]", "[]", "[]", "[]", "[]"); + + ABICodecJsonWrapper abiCodecJsonWrapper = new ABICodecJsonWrapper(); + ABIObject encodeObject = abiCodecJsonWrapper.encode(inputObject, params); + + List decodeResult = abiCodecJsonWrapper.decode(outObject, encodeObject.encode()); + + Assert.assertEquals(decodeResult.get(0), "[ ]"); + Assert.assertEquals(decodeResult.get(1), "[ ]"); + Assert.assertEquals(decodeResult.get(2), "[ ]"); + Assert.assertEquals(decodeResult.get(3), "[ ]"); + + Assert.assertEquals(decodeResult.get(4), "[ ]"); + Assert.assertEquals(decodeResult.get(5), "[ ]"); + } +} diff --git a/src/test/java/org/fisco/bcos/sdk/test/abi/TableTest.java b/src/test/java/org/fisco/bcos/sdk/test/abi/TableTest.java new file mode 100644 index 000000000..cb688f477 --- /dev/null +++ b/src/test/java/org/fisco/bcos/sdk/test/abi/TableTest.java @@ -0,0 +1,431 @@ +package org.fisco.bcos.sdk.test.abi; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import org.fisco.bcos.sdk.abi.datatypes.Utf8String; +import org.fisco.bcos.sdk.abi.datatypes.generated.Uint256; +import org.fisco.bcos.sdk.abi.wrapper.ABICodecJsonWrapper; +import org.fisco.bcos.sdk.abi.wrapper.ABIDefinition; +import org.fisco.bcos.sdk.abi.wrapper.ABIObject; +import org.fisco.bcos.sdk.abi.wrapper.ABIObjectFactory; +import org.fisco.bcos.sdk.abi.wrapper.ContractABIDefinition; +import org.junit.Assert; +import org.junit.Test; + +public class TableTest { + /* + pragmasolidity^0.4.24; + pragmaexperimentalABIEncoderV2; + contractTableTest + { + functionselect(stringmemoryname)publicviewreturns(string[]memory,int256[]memory,string[]memory){} + functioninsert(stringmemoryname,int256item_id,stringmemoryitem_name)publicreturns(int256){} + functionupdate(stringmemoryname,int256item_id,stringmemoryitem_name)publicreturns(int256){} + functionremove(stringmemoryname,int256item_id)publicreturns(int256){} + } + */ + + private static final String abiDesc = + "[\n" + + " {\n" + + " \"constant\": false,\n" + + " \"inputs\": [\n" + + " {\n" + + " \"name\": \"name\",\n" + + " \"type\": \"string\"\n" + + " },\n" + + " {\n" + + " \"name\": \"item_id\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"name\": \"item_name\",\n" + + " \"type\": \"string\"\n" + + " }\n" + + " ],\n" + + " \"name\": \"update\",\n" + + " \"outputs\": [\n" + + " {\n" + + " \"name\": \"\",\n" + + " \"type\": \"int256\"\n" + + " }\n" + + " ],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"function\"\n" + + " },\n" + + " {\n" + + " \"constant\": false,\n" + + " \"inputs\": [\n" + + " {\n" + + " \"name\": \"name\",\n" + + " \"type\": \"string\"\n" + + " },\n" + + " {\n" + + " \"name\": \"item_id\",\n" + + " \"type\": \"int256\"\n" + + " }\n" + + " ],\n" + + " \"name\": \"remove\",\n" + + " \"outputs\": [\n" + + " {\n" + + " \"name\": \"\",\n" + + " \"type\": \"int256\"\n" + + " }\n" + + " ],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"function\"\n" + + " },\n" + + " {\n" + + " \"constant\": false,\n" + + " \"inputs\": [\n" + + " {\n" + + " \"name\": \"name\",\n" + + " \"type\": \"string\"\n" + + " },\n" + + " {\n" + + " \"name\": \"item_id\",\n" + + " \"type\": \"int256\"\n" + + " },\n" + + " {\n" + + " \"name\": \"item_name\",\n" + + " \"type\": \"string\"\n" + + " }\n" + + " ],\n" + + " \"name\": \"insert\",\n" + + " \"outputs\": [\n" + + " {\n" + + " \"name\": \"\",\n" + + " \"type\": \"int256\"\n" + + " }\n" + + " ],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"nonpayable\",\n" + + " \"type\": \"function\"\n" + + " },\n" + + " {\n" + + " \"constant\": true,\n" + + " \"inputs\": [\n" + + " {\n" + + " \"name\": \"name\",\n" + + " \"type\": \"string\"\n" + + " }\n" + + " ],\n" + + " \"name\": \"select\",\n" + + " \"outputs\": [\n" + + " {\n" + + " \"name\": \"\",\n" + + " \"type\": \"string[]\"\n" + + " },\n" + + " {\n" + + " \"name\": \"\",\n" + + " \"type\": \"int256[]\"\n" + + " },\n" + + " {\n" + + " \"name\": \"\",\n" + + " \"type\": \"string[]\"\n" + + " }\n" + + " ],\n" + + " \"payable\": false,\n" + + " \"stateMutability\": \"view\",\n" + + " \"type\": \"function\"\n" + + " }\n" + + "]"; + + /* + { + "ebf3b24f": "insert(string,int256,string)", + "c4f41ab3": "remove(string,int256)", + "fcd7e3c1": "select(string)", + "487a5a10": "update(string,int256,string)" + } + */ + + private static final ContractABIDefinition contractABIDefinition = + Utils.getContractABIDefinition(abiDesc); + private static final ABICodecJsonWrapper abiCodecJsonWrapper = new ABICodecJsonWrapper(); + + @Test + public void ABILoadTest() { + ContractABIDefinition contractABIDefinition = Utils.getContractABIDefinition(abiDesc); + ABIDefinition insert = contractABIDefinition.getFunctions().get("insert").get(0); + ABIDefinition update = contractABIDefinition.getFunctions().get("update").get(0); + ABIDefinition remove = contractABIDefinition.getFunctions().get("remove").get(0); + ABIDefinition select = contractABIDefinition.getFunctions().get("select").get(0); + + Assert.assertEquals(insert.getMethodId(Utils.getCryptoInterface()), "0xebf3b24f"); + Assert.assertEquals(remove.getMethodId(Utils.getCryptoInterface()), "0xc4f41ab3"); + Assert.assertEquals(update.getMethodId(Utils.getCryptoInterface()), "0x487a5a10"); + Assert.assertEquals(select.getMethodId(Utils.getCryptoInterface()), "0xfcd7e3c1"); + + Assert.assertEquals(insert.getMethodSignatureAsString(), "insert(string,int256,string)"); + Assert.assertEquals(remove.getMethodSignatureAsString(), "remove(string,int256)"); + Assert.assertEquals(update.getMethodSignatureAsString(), "update(string,int256,string)"); + Assert.assertEquals(select.getMethodSignatureAsString(), "select(string)"); + } + + @Test + public void ABIObjectTest() { + ContractABIDefinition contractABIDefinition = Utils.getContractABIDefinition(abiDesc); + ABIObject insertInputObject = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("insert").get(0)); + ABIObject insertOutputObject = + ABIObjectFactory.createOutputObject( + contractABIDefinition.getFunctions().get("insert").get(0)); + + Assert.assertEquals(insertInputObject.getStructFields().size(), 3); + Assert.assertEquals( + insertInputObject.getStructFields().get(0).getValueType(), + ABIObject.ValueType.STRING); + Assert.assertEquals( + insertInputObject.getStructFields().get(1).getValueType(), ABIObject.ValueType.INT); + Assert.assertEquals( + insertInputObject.getStructFields().get(2).getValueType(), + ABIObject.ValueType.STRING); + + Assert.assertTrue(insertInputObject.getStructFields().get(0).isDynamic()); + Assert.assertTrue(!insertInputObject.getStructFields().get(1).isDynamic()); + Assert.assertTrue(insertInputObject.getStructFields().get(2).isDynamic()); + + Assert.assertEquals(insertOutputObject.getStructFields().size(), 1); + Assert.assertEquals( + insertOutputObject.getStructFields().get(0).getValueType(), + ABIObject.ValueType.INT); + + ABIObject updateInputObject = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("update").get(0)); + ABIObject updateOutputObject = + ABIObjectFactory.createOutputObject( + contractABIDefinition.getFunctions().get("update").get(0)); + + Assert.assertEquals(updateInputObject.getStructFields().size(), 3); + Assert.assertEquals( + updateInputObject.getStructFields().get(0).getValueType(), + ABIObject.ValueType.STRING); + Assert.assertEquals( + updateInputObject.getStructFields().get(1).getValueType(), ABIObject.ValueType.INT); + Assert.assertEquals( + updateInputObject.getStructFields().get(2).getValueType(), + ABIObject.ValueType.STRING); + + Assert.assertTrue(updateInputObject.getStructFields().get(0).isDynamic()); + Assert.assertTrue(!updateInputObject.getStructFields().get(1).isDynamic()); + Assert.assertTrue(updateInputObject.getStructFields().get(2).isDynamic()); + + Assert.assertEquals(updateOutputObject.getStructFields().size(), 1); + Assert.assertEquals( + updateOutputObject.getStructFields().get(0).getValueType(), + ABIObject.ValueType.INT); + + ABIObject removeInputObject = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("remove").get(0)); + ABIObject removeOutputObject = + ABIObjectFactory.createOutputObject( + contractABIDefinition.getFunctions().get("remove").get(0)); + + Assert.assertEquals(removeInputObject.getStructFields().size(), 2); + Assert.assertEquals( + removeInputObject.getStructFields().get(0).getValueType(), + ABIObject.ValueType.STRING); + Assert.assertEquals( + removeInputObject.getStructFields().get(1).getValueType(), ABIObject.ValueType.INT); + + Assert.assertTrue(removeInputObject.getStructFields().get(0).isDynamic()); + Assert.assertTrue(!removeInputObject.getStructFields().get(1).isDynamic()); + + Assert.assertEquals(removeOutputObject.getStructFields().size(), 1); + Assert.assertEquals( + removeOutputObject.getStructFields().get(0).getValueType(), + ABIObject.ValueType.INT); + + ABIObject selectInputObject = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("select").get(0)); + ABIObject selectOutputObject = + ABIObjectFactory.createOutputObject( + contractABIDefinition.getFunctions().get("select").get(0)); + + Assert.assertEquals(selectInputObject.getStructFields().size(), 1); + Assert.assertEquals( + selectInputObject.getStructFields().get(0).getValueType(), + ABIObject.ValueType.STRING); + + Assert.assertTrue(selectInputObject.getStructFields().get(0).isDynamic()); + + Assert.assertEquals(selectOutputObject.getStructFields().size(), 3); + Assert.assertEquals( + selectOutputObject.getStructFields().get(0).getListType(), + ABIObject.ListType.DYNAMIC); + Assert.assertEquals( + selectOutputObject.getStructFields().get(1).getListType(), + ABIObject.ListType.DYNAMIC); + Assert.assertEquals( + selectOutputObject.getStructFields().get(2).getListType(), + ABIObject.ListType.DYNAMIC); + } + + @Test + public void ABIObjectCodecTest() { + ContractABIDefinition contractABIDefinition = Utils.getContractABIDefinition(abiDesc); + ABIObject insertInputObject = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("insert").get(0)); + ABIObject insertOutputObject = + ABIObjectFactory.createOutputObject( + contractABIDefinition.getFunctions().get("insert").get(0)); + + insertInputObject.getStructFields().set(0, new ABIObject(new Utf8String("hello"))); + insertInputObject.getStructFields().set(1, new ABIObject(new Uint256(100))); + insertInputObject.getStructFields().set(2, new ABIObject(new Utf8String("car"))); + String insertInputEncode = insertInputObject.encode(); + String insertEncode = + "0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000568656c6c6f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036361720000000000000000000000000000000000000000000000000000000000"; + Assert.assertEquals(insertInputEncode, insertEncode); + Assert.assertEquals( + insertInputObject.decode(insertInputEncode).encode(), insertInputObject.encode()); + + insertOutputObject.getStructFields().set(0, new ABIObject(new Uint256(1111))); + String insertOutputEncode = insertOutputObject.encode(); + Assert.assertEquals( + insertOutputObject.decode(insertOutputEncode).encode(), insertOutputEncode); + + // ABIObject updateInputObject = + // ABIObjectFactory.createInputObject(contractABIDefinition.getFunctions().get("update").get(0)); + // ABIObject updateOutputObject = + // ABIObjectFactory.createOutputObject(contractABIDefinition.getFunctions().get("update").get(0)); + // + // ABIObject removeInputObject = + // ABIObjectFactory.createInputObject(contractABIDefinition.getFunctions().get("remove").get(0)); + // ABIObject removeOutputObject = + // ABIObjectFactory.createOutputObject(contractABIDefinition.getFunctions().get("remove").get(0)); + + // ABIObject selectInputObject = + // ABIObjectFactory.createInputObject(contractABIDefinition.getFunctions().get("select").get(0)); + // ABIObject selectOutputObject = + // ABIObjectFactory.createOutputObject(contractABIDefinition.getFunctions().get("select").get(0)); + } + + @Test + public void ABIObjectCodecJsonWrapperTest() throws IOException { + ContractABIDefinition contractABIDefinition = Utils.getContractABIDefinition(abiDesc); + + ABIObject insertInputObject = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("insert").get(0)); + ABIObject insertOutputObject = + ABIObjectFactory.createOutputObject( + contractABIDefinition.getFunctions().get("insert").get(0)); + + String encode_i = + abiCodecJsonWrapper + .encode(insertInputObject, Arrays.asList("hello", "100", "car")) + .encode(); + String encoded_i = + "0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000568656c6c6f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036361720000000000000000000000000000000000000000000000000000000000"; + Assert.assertEquals(encode_i, encoded_i); + List json_decode_i = abiCodecJsonWrapper.decode(insertInputObject, encode_i); + Assert.assertEquals(json_decode_i.get(0), "hello"); + Assert.assertEquals(json_decode_i.get(1), "100"); + Assert.assertEquals(json_decode_i.get(2), "car"); + + String encode_o = + abiCodecJsonWrapper.encode(insertOutputObject, Arrays.asList("100")).encode(); + String encoded_o = "0000000000000000000000000000000000000000000000000000000000000064"; + Assert.assertEquals(encode_o, encoded_o); + List json_decode_o = abiCodecJsonWrapper.decode(insertOutputObject, encoded_o); + Assert.assertEquals(json_decode_o.get(0), "100"); + + ABIObject updateInputObject = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("update").get(0)); + ABIObject updateOutputObject = + ABIObjectFactory.createOutputObject( + contractABIDefinition.getFunctions().get("update").get(0)); + + String encode_i_u = + abiCodecJsonWrapper + .encode(updateInputObject, Arrays.asList("hello", "100", "car")) + .encode(); + String encoded_i_u = + "0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000568656c6c6f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036361720000000000000000000000000000000000000000000000000000000000"; + Assert.assertEquals(encode_i_u, encoded_i_u); + + String encode_o_u = + abiCodecJsonWrapper.encode(updateOutputObject, Arrays.asList("100")).encode(); + String encoded_o_u = "0000000000000000000000000000000000000000000000000000000000000064"; + Assert.assertEquals(encode_o_u, encoded_o_u); + + List json_decode_i_o = abiCodecJsonWrapper.decode(updateInputObject, encoded_i_u); + Assert.assertEquals(json_decode_i_o.get(0), "hello"); + Assert.assertEquals(json_decode_i_o.get(1), "100"); + Assert.assertEquals(json_decode_i_o.get(2), "car"); + + List json_decode_o_o = abiCodecJsonWrapper.decode(updateOutputObject, encoded_o_u); + Assert.assertEquals(json_decode_o_o.get(0), "100"); + + ABIObject removeInputObject = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("remove").get(0)); + ABIObject removeOutputObject = + ABIObjectFactory.createOutputObject( + contractABIDefinition.getFunctions().get("remove").get(0)); + + String encode_i_r = + abiCodecJsonWrapper + .encode(removeInputObject, Arrays.asList("hello", "100")) + .encode(); + String encoded_i_r = + "00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000"; + Assert.assertEquals(encode_i_r, encoded_i_r); + + String encode_o_r = + abiCodecJsonWrapper.encode(removeOutputObject, Arrays.asList("100")).encode(); + String encoded_o_r = "0000000000000000000000000000000000000000000000000000000000000064"; + Assert.assertEquals(encode_o_r, encoded_o_r); + + List json_decode_r_i = abiCodecJsonWrapper.decode(removeInputObject, encoded_i_r); + Assert.assertEquals(json_decode_r_i.get(0), "hello"); + List json_decode_r_o = abiCodecJsonWrapper.decode(updateOutputObject, encoded_o_r); + Assert.assertEquals(json_decode_r_o.get(0), "100"); + + ABIObject selectInputObject = + ABIObjectFactory.createInputObject( + contractABIDefinition.getFunctions().get("select").get(0)); + ABIObject selectOutputObject = + ABIObjectFactory.createOutputObject( + contractABIDefinition.getFunctions().get("select").get(0)); + + String encode_i_s = + abiCodecJsonWrapper.encode(selectInputObject, Arrays.asList("hello")).encode(); + String encoded_i_s = + "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000"; + Assert.assertEquals(encode_i_s, encoded_i_s); + + String encode_o_s = + abiCodecJsonWrapper + .encode( + selectOutputObject, + Arrays.asList( + "[\"hello\",\"hello\",\"hello\"]", + "[100,100,100]", + "[\"car\",\"car\",\"car\"]")) + .encode(); + String encoded_o_s = + "000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000002200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000568656c6c6f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000363617200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003636172000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000036361720000000000000000000000000000000000000000000000000000000000"; + Assert.assertEquals(encode_o_s, encoded_o_s); + + List json_decode_s_i = abiCodecJsonWrapper.decode(selectInputObject, encoded_i_s); + Assert.assertEquals(json_decode_s_i.get(0), "hello"); + + List json_decode_s_o = abiCodecJsonWrapper.decode(selectOutputObject, encoded_o_s); + + Assert.assertEquals(json_decode_s_o.get(0), "[ \"hello\", \"hello\", \"hello\" ]"); + Assert.assertEquals(json_decode_s_o.get(1), "[ 100, 100, 100 ]"); + Assert.assertEquals(json_decode_s_o.get(2), "[ \"car\", \"car\", \"car\" ]"); + } +} diff --git a/src/test/java/org/fisco/bcos/sdk/test/abi/Utils.java b/src/test/java/org/fisco/bcos/sdk/test/abi/Utils.java new file mode 100644 index 000000000..971313e29 --- /dev/null +++ b/src/test/java/org/fisco/bcos/sdk/test/abi/Utils.java @@ -0,0 +1,33 @@ +/* + * Copyright 2014-2020 [fisco-dev] + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + * + */ + +package org.fisco.bcos.sdk.test.abi; + +import org.fisco.bcos.sdk.abi.wrapper.ABIDefinitionFactory; +import org.fisco.bcos.sdk.abi.wrapper.ContractABIDefinition; +import org.fisco.bcos.sdk.crypto.CryptoInterface; + +public class Utils { + + public static CryptoInterface getCryptoInterface() { + return new CryptoInterface(CryptoInterface.ECDSA_TYPE); + } + + public static ContractABIDefinition getContractABIDefinition(String abiDesc) { + CryptoInterface cryptoInterface = getCryptoInterface(); + ABIDefinitionFactory abiDefinitionFactory = new ABIDefinitionFactory(cryptoInterface); + return abiDefinitionFactory.loadABI(abiDesc); + } +}