diff --git a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java index e5efe5684..d316bb65f 100644 --- a/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java +++ b/sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java @@ -131,11 +131,50 @@ public String encodeMethodById(String ABI, String methodId, List params) throw new ABICodecException(errorMsg); } - public String encodeMethodByInterface(String ABI, String methodInterface, List params) + private ABIDefinition getABIDefinition(String methodInterface) throws ABICodecException { + int start = methodInterface.indexOf("("); + int end = methodInterface.lastIndexOf(")"); + if (start == -1 || end == -1 || start >= end) { + String errorMsg = " error format"; + logger.error(errorMsg); + throw new ABICodecException(errorMsg); + } + String name = methodInterface.substring(0, start); + String type = methodInterface.substring(start + 1, end); + if (type.indexOf("tuple") != -1) { + String errorMsg = " cannot support tuple type"; + logger.error(errorMsg); + throw new ABICodecException(errorMsg); + } + String[] types = type.split(","); + List inputs = new ArrayList(); + for (String s : types) { + ABIDefinition.NamedType input = new ABIDefinition.NamedType("name", s); + inputs.add(input); + } + + return new ABIDefinition(false, inputs, name, null, "function", false, "nonpayable"); + } + + public String encodeMethodByInterface(String methodInterface, List params) throws ABICodecException { - FunctionEncoder functionEncoder = new FunctionEncoder(cryptoSuite); - String methodId = functionEncoder.buildMethodId(methodInterface); - return encodeMethodById(ABI, methodId, params); + ABIDefinition abiDefinition = getABIDefinition(methodInterface); + if (abiDefinition.getInputs().size() == params.size()) { + @SuppressWarnings("static-access") + ABIObject inputABIObject = abiObjectFactory.createInputObject(abiDefinition); + ABICodecObject abiCodecObject = new ABICodecObject(); + try { + String methodId = abiDefinition.getMethodId(cryptoSuite); + return methodId + abiCodecObject.encodeValue(inputABIObject, params).encode(); + } catch (Exception e) { + logger.error( + " exception in encodeMethodByInterfaceFromObject : {}", e.getMessage()); + } + } + + String errorMsg = " cannot encode in encodeMethodByInterfaceFromObject"; + logger.error(errorMsg); + throw new ABICodecException(errorMsg); } public String encodeMethodFromString(String ABI, String methodName, List params) @@ -194,11 +233,25 @@ public String encodeMethodByIdFromString(String ABI, String methodId, List params) throws ABICodecException { - FunctionEncoder functionEncoder = new FunctionEncoder(cryptoSuite); - String methodId = functionEncoder.buildMethodId(methodInterface); - return encodeMethodByIdFromString(ABI, methodId, params); + public String encodeMethodByInterfaceFromString(String methodInterface, List params) + throws ABICodecException { + ABIDefinition abiDefinition = getABIDefinition(methodInterface); + if (abiDefinition.getInputs().size() == params.size()) { + @SuppressWarnings("static-access") + ABIObject inputABIObject = abiObjectFactory.createInputObject(abiDefinition); + ABICodecJsonWrapper abiCodecJsonWrapper = new ABICodecJsonWrapper(); + try { + String methodId = abiDefinition.getMethodId(cryptoSuite); + return methodId + abiCodecJsonWrapper.encode(inputABIObject, params).encode(); + } catch (IOException e) { + logger.error( + " exception in encodeMethodByInterfaceFromString : {}", e.getMessage()); + } + } + + String errorMsg = " cannot encode in encodeMethodByInterfaceFromString"; + logger.error(errorMsg); + throw new ABICodecException(errorMsg); } public List decodeMethod(ABIDefinition abiDefinition, String output) @@ -334,7 +387,10 @@ public List decodeEvent(String ABI, String eventName, EventLog log) ABIObject inputObject = abiObjectFactory.createEventInputObject(abiDefinition); ABICodecObject abiCodecObject = new ABICodecObject(); try { - List params = abiCodecObject.decodeJavaObject(inputObject, log.getData()); + List params = new ArrayList<>(); + if (!log.getData().equals("0x")) { + params = abiCodecObject.decodeJavaObject(inputObject, log.getData()); + } List topics = log.getTopics(); return mergeEventParamsAndTopics(abiDefinition, params, topics); } catch (Exception e) { @@ -355,7 +411,10 @@ public List decodeEventByTopic(String ABI, String eventTopic, EventLog l ABIObject inputObject = abiObjectFactory.createEventInputObject(abiDefinition); ABICodecObject abiCodecObject = new ABICodecObject(); try { - List params = abiCodecObject.decodeJavaObject(inputObject, log.getData()); + List params = new ArrayList<>(); + if (!log.getData().equals("0x")) { + params = abiCodecObject.decodeJavaObject(inputObject, log.getData()); + } List topics = log.getTopics(); return mergeEventParamsAndTopics(abiDefinition, params, topics); } catch (Exception e) { @@ -390,7 +449,10 @@ public List decodeEventToString(String ABI, String eventName, EventLog l ABIObject inputObject = abiObjectFactory.createEventInputObject(abiDefinition); ABICodecJsonWrapper abiCodecJsonWrapper = new ABICodecJsonWrapper(); try { - List params = abiCodecJsonWrapper.decode(inputObject, log.getData()); + List params = new ArrayList<>(); + if (!log.getData().equals("0x")) { + params = abiCodecJsonWrapper.decode(inputObject, log.getData()); + } List topics = log.getTopics(); return mergeEventParamsAndTopicsToString(abiDefinition, params, topics); } catch (Exception e) { @@ -411,7 +473,10 @@ public List decodeEventByTopicToString(String ABI, String eventTopic, Ev ABIObject inputObject = abiObjectFactory.createEventInputObject(abiDefinition); ABICodecJsonWrapper abiCodecJsonWrapper = new ABICodecJsonWrapper(); try { - List params = abiCodecJsonWrapper.decode(inputObject, log.getData()); + List params = new ArrayList<>(); + if (!log.getData().equals("0x")) { + params = abiCodecJsonWrapper.decode(inputObject, log.getData()); + } List topics = log.getTopics(); return mergeEventParamsAndTopicsToString(abiDefinition, params, topics); } catch (Exception e) { diff --git a/sdk-abi/src/test/java/org/fisco/bcos/sdk/test/abi/ABICodecTest.java b/sdk-abi/src/test/java/org/fisco/bcos/sdk/test/abi/ABICodecTest.java index 27b88e5b2..fecd9d12a 100644 --- a/sdk-abi/src/test/java/org/fisco/bcos/sdk/test/abi/ABICodecTest.java +++ b/sdk-abi/src/test/java/org/fisco/bcos/sdk/test/abi/ABICodecTest.java @@ -341,15 +341,33 @@ public void testEncodeFromString() { encodedWithMethodId, abiCodec.encodeMethodById( abiDesc, test.getMethodId(Utils.getCryptoSuite()), abiObjects)); - // MethodByInterface String & JavaObject - Assert.assertEquals( - encodedWithMethodId, - abiCodec.encodeMethodByInterfaceFromString( - abiDesc, test.getMethodSignatureAsString(), args)); - Assert.assertEquals( - encodedWithMethodId, - abiCodec.encodeMethodByInterface( - abiDesc, test.getMethodSignatureAsString(), abiObjects)); + } catch (ABICodecException e) { + Assert.fail(e.getMessage()); + } + } + + @Test + public void testEncodeByInterface() { + ABICodec abiCodec = new ABICodec(Utils.getCryptoSuite()); + List argsObjects = new ArrayList(); + List b1 = new ArrayList(); + b1.add(new BigInteger("100")); + b1.add(new BigInteger("200")); + argsObjects.add(b1); + List b2 = new ArrayList(); + b2.add(new BigInteger("100")); + b2.add(new BigInteger("200")); + b2.add(new BigInteger("300")); + argsObjects.add(b2); + byte[] b = "1234".getBytes(); + argsObjects.add(b); + String a = "0x5678"; + argsObjects.add(a); + try { + String s1 = abiCodec.encodeMethodByInterface("call(uint256[2],uint256[],bytes,address)", argsObjects); + String abi = "[{\"constant\":false,\"inputs\":[{\"name\":\"u1\",\"type\":\"uint256[2]\"},{\"name\":\"u2\",\"type\":\"uint256[]\"},{\"name\":\"b\",\"type\":\"bytes\"},{\"name\":\"a\",\"type\":\"address\"}],\"name\":\"call\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"u\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"a\",\"type\":\"uint256\"},{\"name\":\"s\",\"type\":\"string\"}],\"name\":\"add\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"u\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"LogAdd1\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"u\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"LogAdd2\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"u\",\"type\":\"uint256\"},{\"indexed\":true,\"name\":\"a\",\"type\":\"uint256\"},{\"indexed\":true,\"name\":\"s\",\"type\":\"string\"}],\"name\":\"LogAdd3\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"LogAdd4\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"a\",\"type\":\"uint256\"}],\"name\":\"LogAdd5\",\"type\":\"event\"}]"; + String s2 = abiCodec.encodeMethod(abi, "call", argsObjects); + Assert.assertEquals(s1, s2); } catch (ABICodecException e) { Assert.fail(e.getMessage()); }