La función del contrato inteligente devuelve 0 de Web3j

por favor ayúdame en este problema. Logré compilar e implementar mi contrato inteligente usando web3j en testrpc. Pero cuando llamo a la función que devuelve uint en este contrato de web3j, siempre recibo 0. Presento a continuación mi contrato y mi programa Java. 1. Mis contratos inteligentes:

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. Compilar e implementar con éxito Yo uso testrpc

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

Cuando compilo contratos inteligentes, obtengo 3 archivos *.bin y 3 archivos *.abi MyContract.bin(abi), parentContract.bin(abi), grandParentContract.bin(abi) Implemento correctamente el contrato inteligente usando el archivo MyContract. bin y web3j (Tenga en cuenta que, cuando implemento este contrato inteligente, solo cargo el contenido de este archivo MyContract.bin, no agrego 0x antes de este contenido)

  1. Llame a la función addNewElement desde Java y reciba siempre 0 (cero)

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

Siempre recibo los resultados : [0]. Traté de poner maxIdValueMyContract en lugar de ParentContract, pero el resultado es el mismo

creo que necesitas ordenar tu pregunta
Gracias por tu respuesta. Solo quiero recibir el resultado exacto de mi llamada de función para agregarNuevoElemento en el contrato inteligente. Pero siempre el resultado cero. Quiero saber por qué y resolver este problema. Presenté arriba mis contratos inteligentes y código Java

Respuestas (1)

Las funciones de solidez no constantes no pueden devolver un valor.

Esto generalmente se debe a que debe enviar el valor a la red para que se procese durante un período de tiempo indeterminado. Esto hace que sea un poco difícil devolverle los datos a usted, el remitente.

Lo que podría hacer es usar events o simplemente hacer un seguimiento más tarde con una constantllamada de función.

Muchas gracias por tu respuesta. Como dijiste, ¿tengo que declarar el método en Solidity como se muestra a continuación? function addNewElement(string _name, string _description) public onlyFromMe() constante devuelve (uint) {...} Como puede ver, tengo que modificar el valor del atributo maxIdValue de este contrato inteligente en esta función. También tengo que crear un nuevo elemento Struct e insertarlo en un atributo de mapeo de este contrato inteligente. ¿Una función constante me permite hacer tales modificaciones? También uso el evento ElementAddition en addNewElement, pero no encuentro nada en Java después de usar las funciones de Java anteriores
No, la función puede realizar cambios en la cadena de bloques o devolver un valor. No puede hacer ambas cosas. Puede sortearlo con eventos (vea el enlace en mi respuesta) o agregando una función para devolver el valor que desea que pueda ejecutar después de que se realice la transacción.
Gracias por tu respuesta. Uso eventos para obtener el valor devuelto.