Die Funktion des Smart Contract gibt 0 von Web3j zurück

Bitte helfen Sie mir bei diesem Problem. Ich kann meinen Smart Contract erfolgreich mit web3j auf testrpc kompilieren und bereitstellen. Aber wenn ich die Funktion aufrufe, die uint in diesem Vertrag von web3j zurückgibt, erhalte ich immer 0. Ich präsentiere unten meinen Vertrag und mein Java-Programm. 1. Meine 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. Erfolgreiches Kompilieren und Bereitstellen Ich verwende testrpc

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

Wenn ich Smart Contracts kompiliere, erhalte ich 3 *.bin-Dateien und 3 *.abi-Dateien MyContract.bin(abi), parentContract.bin(abi), grandParentContract.bin(abi) Ich setze den Smart Contract erfolgreich mit der Datei MyContract ein. bin und web3j (Beachten Sie, dass ich bei der Bereitstellung dieses Smart Contracts nur den Inhalt dieser MyContract.bin-Datei lade und vor diesem Inhalt kein 0x hinzufüge)

  1. Funktion addNewElement von Java aufrufen und immer 0 (Null) erhalten

    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());
    
            }
        }
    }
    

Ich erhalte immer die Ergebnisse: [0]. Ich habe versucht, maxIdValueMyContract anstelle von ParentContract einzufügen, aber das Ergebnis ist dasselbe

Ich denke, Sie müssen Ihre Frage ordnen
Danke für deine Antwort. Ich möchte nur das genaue Ergebnis meines Funktionsaufrufs von addNewElement im Smart Contract erhalten. Aber ich habe immer das Nullergebnis. Ich möchte wissen, warum und dieses Problem lösen. Ich habe oben meine Smart Contracts und meinen Java-Code vorgestellt

Antworten (1)

Nicht konstante Solidity-Funktionen können keinen Wert zurückgeben.

Dies liegt im Allgemeinen daran, dass Sie den Wert für eine unbestimmte Zeit zur Verarbeitung an das Netzwerk senden müssen. Dies macht es ziemlich schwierig, Daten an Sie, den Absender, zurückzusenden.

Was Sie tun könnten, ist, events zu verwenden oder einfach später mit einem constantFunktionsaufruf fortzufahren.

Vielen Dank für Ihre Antwort. Wie Sie sagten, muss ich die Methode in Solidity wie unten deklarieren? function addNewElement(string _name, string _description) public onlyFromMe() Konstante gibt zurück (uint) {...} Wie Sie sehen, muss ich den Wert des maxIdValue-Attributs dieses Smart Contracts in dieser Funktion ändern. Ich muss auch ein neues Struct-Element erstellen und es in ein Mapping-Attribut dieses Smart Contracts einfügen. Eine konstante Funktion erlaubt mir, solche Änderungen vorzunehmen? Ich verwende auch das Ereignis ElementAddition in addNewElement, aber ich finde nichts in Java, nachdem ich die obigen Java-Funktionen verwendet habe
Nein, die Funktion kann entweder Änderungen an der Blockchain vornehmen oder einen Wert zurückgeben. Es kann nicht beides. Sie können es irgendwie mit Ereignissen umgehen (siehe Link in meiner Antwort) oder eine Funktion hinzufügen, um den gewünschten Wert zurückzugeben, den Sie ausführen können, nachdem die Transaktion durchlaufen wurde.
Danke für deine Antwort. Ich verwende Ereignisse, um den zurückgegebenen Wert zu erhalten