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;
}
}
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)
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, maxIdValue
MyContract anstelle von ParentContract einzufügen, aber das Ergebnis ist dasselbe
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 constant
Funktionsaufruf fortzufahren.
Etherkimist
CD-Tran