Skip to content

Commit

Permalink
Constructor input parser & add test cases of input parse (#361)
Browse files Browse the repository at this point in the history
* add test of input parser

* add test

* fix ci problems
  • Loading branch information
dalaocu authored Oct 11, 2021
1 parent 54757b9 commit 3343bd7
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 7 deletions.
31 changes: 31 additions & 0 deletions sdk-abi/src/main/java/org/fisco/bcos/sdk/abi/ABICodec.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.fisco.bcos.sdk.abi.wrapper.ABICodecJsonWrapper;
import org.fisco.bcos.sdk.abi.wrapper.ABICodecObject;
Expand Down Expand Up @@ -323,6 +324,36 @@ public Pair<List<Object>, List<ABIObject>> decodeTransactionInput(String ABI, St
return decodeDataByMethodId(ABI, methodId, input.substring(10), false);
}

public Pair<List<Object>, List<ABIObject>> decodeMethodInput(
String ABI, String input, String methodName, String code) throws ABICodecException {
ContractABIDefinition contractABIDefinition = abiDefinitionFactory.loadABI(ABI);
List<ABIDefinition> methods;
ABICodecObject abiCodecObject = new ABICodecObject();
ABIObjectFactory abiObjectFactory = new ABIObjectFactory();
if (StringUtils.equals(methodName, "constructor")) {
String lastCode = StringUtils.substring(code, code.length() - 32, code.length());
String paramsInput = StringUtils.substringAfter(input, lastCode);
// remove methodId of input
return abiCodecObject.decodeJavaObjectAndOutputObject(
abiObjectFactory.createInputObject(contractABIDefinition.getConstructor()),
paramsInput);
} else {
methods = contractABIDefinition.getFunctions().get(methodName);
}
for (ABIDefinition abiDefinition : methods) {
ABIObject outputABIObject = abiObjectFactory.createInputObject(abiDefinition);
try {
return abiCodecObject.decodeJavaObjectAndOutputObject(
outputABIObject, input.substring(10));
} catch (Exception e) {
logger.warn(" exception in decodeMethodInput : {}", e.getMessage());
}
}
String errorMsg = " cannot decode in decodeMethodInput with appropriate interface ABI";
logger.error(errorMsg);
throw new ABICodecException(errorMsg);
}

public Pair<List<Object>, List<ABIObject>> decodeDataByMethodId(
String ABI, String methodId, String data, boolean isOutput) throws ABICodecException {
ContractABIDefinition contractABIDefinition = abiDefinitionFactory.loadABI(ABI);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,18 @@ public TransactionResponse decodeReceiptWithoutValues(
String abi, TransactionReceipt transactionReceipt)
throws TransactionException, IOException, ABICodecException;

/**
* parse the transaction information from receipt without return values, but with input values
*
* @param abi contract abi
* @param transactionReceipt transaction receipt
* @param constructorCode decode for constructor
* @return the resolved status and other transaction detail
*/
public TransactionResponse decodeReceiptWithoutOutputValues(
String abi, TransactionReceipt transactionReceipt, String constructorCode)
throws TransactionException, IOException, ABICodecException;

/**
* parse the transaction events from receipt logs
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,24 @@ public TransactionResponse decodeReceiptWithoutValues(
return response;
}

@Override
public TransactionResponse decodeReceiptWithoutOutputValues(
String abi, TransactionReceipt transactionReceipt, String constructorCode)
throws TransactionException, IOException, ABICodecException {
TransactionResponse response = decodeReceiptWithoutValues(abi, transactionReceipt);
// parse the input
if (transactionReceipt.getInput() != null && transactionReceipt.isStatusOK()) {
Pair<List<Object>, List<ABIObject>> inputObject =
abiCodec.decodeMethodInput(
abi, transactionReceipt.getInput(), "constructor", constructorCode);
String inputValues = JsonUtils.toJson(inputObject.getLeft());
response.setInputData(inputValues);
response.setInputObject(inputObject.getLeft());
response.setInputABIObject(inputObject.getRight());
}
return response;
}

@Override
public TransactionResponse decodeReceiptStatus(TransactionReceipt receipt) {
TransactionResponse response = new TransactionResponse();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,9 @@ public TransactionReceipt deployAndGetReceipt(String data) {
@Override
public TransactionResponse deployAndGetResponse(String abi, String signedData) {
TransactionReceipt receipt = transactionPusher.push(signedData);
String code = client.getCode(receipt.getContractAddress()).getCode();
try {
return transactionDecoder.decodeReceiptWithoutValues(abi, receipt);
return transactionDecoder.decodeReceiptWithoutOutputValues(abi, receipt, code);
} catch (TransactionException | IOException | ABICodecException e) {
log.error("deploy exception: {}", e.getMessage());
return new TransactionResponse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ public void testDecode() throws Exception {
return;
}
String contractAddress = response.getContractAddress();
Assert.assertEquals(2, response.getInputObject().size());
// System.out.println(JsonUtils.toJson(response));

// increment
TransactionReceipt transactionReceipt =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ public void test1HelloWorld() throws Exception {
transactionProcessor.sendTransactionAndGetResponseByContractLoader(
"HelloWorld", helloWorldAddrss, "set", params);
Assert.assertEquals("0x0", res.getTransactionReceipt().getStatus());
Assert.assertEquals("test", res.getInputObject().get(0));
// System.out.println(JsonUtils.toJson(res));

// test call by contract loader
CallResponse callResponse2 =
Expand Down Expand Up @@ -293,7 +295,6 @@ public void onResponse(TransactionReceipt receipt) {
abi,
"getUint256",
Lists.newArrayList());
// System.out.println(JsonUtils.toJson(callResponse3));
Assert.assertEquals("Success", callResponse3.getReturnMessage());
} catch (TransactionBaseException | ABICodecException e) {
System.out.println(e.getMessage());
Expand All @@ -313,6 +314,7 @@ public void test6ComplexSetValues() throws Exception {
params.add("test2");
TransactionResponse response =
transactionProcessor.deployByContractLoader("ComplexSol", params);
// System.out.println(JsonUtils.toJson(response));
if (!response.getTransactionReceipt().getStatus().equals("0x0")) {
return;
}
Expand All @@ -322,14 +324,14 @@ public void test6ComplexSetValues() throws Exception {
String[] o = {"0x1", "0x2", "0x3"};
List<String> a = Arrays.asList(o);
paramsSetValues.add(a);
paramsSetValues.add("set values 字符串");
paramsSetValues.add("set values 字符");
TransactionResponse transactionResponse =
transactionProcessor.sendTransactionAndGetResponse(
contractAddress, abi, "setValues", paramsSetValues);
// System.out.println(JsonUtils.toJson(transactionResponse));
Map<String, List<List<Object>>> eventsMap = transactionResponse.getEventResultMap();
Assert.assertEquals(1, eventsMap.size());
Assert.assertEquals("set values 字符串", eventsMap.get("LogSetValues").get(0).get(2));
Assert.assertEquals("set values 字符", eventsMap.get("LogSetValues").get(0).get(2));
}

@Test
Expand Down Expand Up @@ -401,4 +403,31 @@ public void test8ComplexSetBytesFuture() throws Exception {
Assert.assertEquals("0x0", response.getTransactionReceipt().getStatus());
});
}

@Test
public void test9ComplexIncrementInputParser() throws Exception {
AssembleTransactionProcessor transactionProcessor =
TransactionProcessorFactory.createAssembleTransactionProcessor(
client, cryptoKeyPair, abiFile, binFile);
// deploy
List<Object> params = Lists.newArrayList();
params.add(1);
params.add("test2");
TransactionResponse response =
transactionProcessor.deployByContractLoader("ComplexSol", params);
if (!response.getTransactionReceipt().getStatus().equals("0x0")) {
return;
}
Assert.assertEquals(2, response.getInputABIObject().size());
Assert.assertEquals("test2", response.getInputObject().get(1));
String contractAddress = response.getContractAddress();
// increment v
TransactionResponse transactionResponse =
transactionProcessor.sendTransactionAndGetResponse(
contractAddress,
abi,
"incrementUint256",
Lists.newArrayList(BigInteger.valueOf(10)));
Assert.assertEquals(BigInteger.valueOf(10), transactionResponse.getInputObject().get(0));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public class AssembleTransactionWithRemoteSignProcessorTest {
private static final String abiFile = "src/integration-test/resources/abi/";
private static final String binFile = "src/integration-test/resources/bin/";
private List<Object> params = Lists.newArrayList("test");
// prepare sdk read from the config file
// prepare sdk, read from the config file
private BcosSDK sdk = BcosSDK.build(configFile);
// set the group number 1
private Client client = sdk.getClient(Integer.valueOf(1));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ public RemoteSignCallbackMock(
}

/**
* 签名结果回调的实现
* callback of sign transaction
*
* @param signatureStr 签名服务回调返回的签名结果串
* @return *
*/
@Override
public int handleSignedTransaction(SignatureResult signatureStr) {
System.out.println(System.currentTimeMillis() + " SignatureResult: " + signatureStr);
// 完成了交易签名后,将其发送出去
// after sign, send it
TransactionReceipt tr =
assembleTransactionWithRemoteSignProcessor.signAndPush(
rawTransaction, signatureStr.convertToString());
Expand Down

0 comments on commit 3343bd7

Please sign in to comment.