Web3j Contract Invocation – Smart Contract Function Returning 0

contract-invocationgo-ethereumtestrpcweb3j

please help me in this problem.
I am successful to compile and deploy my smart contract using web3j on testrpc. But When I call the function that returns uint in this contract from web3j, I always receive 0. I present below my contract and my Java program.
1. My Smart Contracts:

pragma solidity ^0.4.6;
contract grandParentContract{

  address public myAddr = 0x1005...;

  modifier onlyFromMe() {
    if ((myAddr != address(0)) && (tx.origin != myAddr)) {
        Msg("Permission Error: this function is limited to the my address origin.");
        return;
    }
    _;
  }
}

pragma solidity ^0.4.6;
contract parentContract is grandParentContract {

/**************BEGIN: attributes or properties or dataobjectType**********/ 


 uint public maxIdValue=0;
 uint public minIdValue=0;

 event ElementAddition(uint _id);

 function parentContract() grandParentContract() {
   maxIdValue = 0;
   minIdValue = 0;
 }

}

contract MyContract is parentContract {
  struct MyElement {

    uint id; 
    string name;
    string description;
    uint[] currentForeignKeys;
  }
  mapping(uint => MyElement) public myElementMap; 


  function MyContract() parentContract() {

  }

  function addNewElement(string _name, string _description) public onlyFromMe() returns (uint) {
    uint _id = maxIdValue+1;


    myElementMap[_id].name = _name;
    myElementMap[_id].description = _description;

    maxIdValue = _id;
    ElementAddition(_id);
    return _id;
  }

}
  1. Compile and Deploy successfully
    I use testrpc

    Web3j web3 = Web3j.build(new HttpService("testrpcIp:testrpcPort"));

When I compile smart contracts, I obtains 3 *.bin files and 3 *.abi files
MyContract.bin(abi), parentContract.bin(abi), grandParentContract.bin(abi)
I deploy successfully the smart contract using the file MyContract.bin and web3j
(Note that, when I deploy this smart contract, I only load the content of this MyContract.bin file, not add 0x before this content)

  1. Call addNewElement function from Java and receive always 0 (zero)

    List<String> results= callMyFunction(web3,aCredential,contractAddress, "addNewElement", Arrays.<Type>asList(new Utf8String("name1"),new Utf8String("description of name1")), Arrays.asList(new TypeReference<Uint>() {}));
    System.out.println("results = " + results);
    
    
    public static synchronized List<String> callMyFunction(Web3j web3, Credentials creds, String contractAddress, String functionName, List inputArgs, List outputs) throws Exception {
    
        List<String> results = new ArrayList();
        Function function = new Function(functionName, inputArgs, outputs);
        String encodedFunction = FunctionEncoder.encode(function);
        EthCall response = web3.ethCall(Transaction.createEthCallTransaction(creds.getEcKeyPair().getPrivateKey().toString(16), contractAddress, encodedFunction), DefaultBlockParameterName.LATEST).sendAsync().get();
        if(response.hasError()){
            System.out.println("functionCall: " + response.getError().getMessage());
        }
        convertMyResult((response != null) && (response.getValue() != null) ? FunctionReturnDecoder.decode(response.getValue(), function.getOutputParameters()) : new ArrayList(), results);
        return results;
    }
    
    public static void convertMyResult(List<Type> returns, List<String> results) throws Exception {
        if (returns.size() > 0) {
    
            for(int i=0; i<returns.size(); i++){
    
                    results.add(returns.get(i).getValue().toString());
    
            }
        }
    }
    

I always receive the results : [0].
I tried to put maxIdValue in the MyContract instead of in ParentContract, but the result is the same

Best Answer

Non-constant solidity functions can not return a value.

This is generally because you have to send the value out to the network to be processed for an indeterminate amount of time. This makes it kind of difficult to get any data back to you, the sender.

What you could do, is use events, or just follow up later with a constant function call.

Related Topic