Go-Ethereum

智能合約函式從 Web3j 返回 0

  • July 15, 2017

請幫我解決這個問題。我成功地在 testrpc 上使用 web3j 編譯和部署了我的智能合約。但是當我從 web3j 呼叫返回這個合約中的 uint 的函式時,我總是收到 0。我在我的合約和我的 Java 程序下面顯示。1. 我的智能合約:

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. 編譯和部署成功我使用testrpc

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

當我編譯智能合約時,我獲得了 3 個 *.bin 文件和 3 個 *.abi 文件 MyContract.bin(abi)、parentContract.bin(abi)、grandParentContract.bin(abi) 我使用文件 MyContract 成功部署了智能合約。 bin 和 web3j (注意,當我部署這個智能合約時,我只載入這個 MyContract.bin 文件的內容,而不是在這個內容之前添加 0x)

  1. 從 Java 呼叫 addNewElement 函式並始終接收 0(零)
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());

       }
   }
}

我總是收到結果:[0]。我試圖放入maxIdValueMyContract 而不是 ParentContract,但結果是一樣的

非常量的solidity函式不能返回值。

這通常是因為您必須將值發送到網路以在不確定的時間內進行處理。這使得將任何數據返回給發件人變得有點困難。

您可以做的是使用eventsconstant ,或者稍後使用函式呼叫進行跟進。

引用自:https://ethereum.stackexchange.com/questions/21209