¿Cómo usar eventos para recuperar datos de una transacción? CADENA PRIVADA

estoy usando GETH para la arquitectura y la implementación de mi contrato en una cadena privada y funciona bastante bien, pero desafortunadamente quiero devolver datos de una función de transacción y esto me vuelve loco. Sé que para leer el valor devuelto de las transacciones es necesario involucrar los eventos de Solidity y luego, a través de WEB3, podemos leerlos. Mostraré mis pasos detallados para leer eventos, pero nada funciona en absoluto. Cualquier tipo de ayuda sería muy apreciada. Este es el código que necesito recopilar:

This is the event declaration right above the contract constructor

event Accessed(string _msg,address _add, uint _time);


function transfer(bytes32 _ID) public returns (address)
{
    // Only the current owner can transfer the token.
    if (ID == _ID)
        {    
                owner = msg.sender;
                taddr.push(msg.sender); //taddr is an array used for storing address of whoever call the
                                        //transfer function
                ttime.push(now);        //same but it stores the timestamp
                Accessed("someone executed the transfer function",owner,now);
                return(owner); 
        } 
}
 function getOwners() view public returns (address[],uint[]) //this should print the two above arrays and return them
{

     return (taddr,ttime);

}

Entonces, lo que quiero es principalmente obtener las 2 matrices como retorno o al menos leer cada llamada de la función de transacción ().

Después de la implementación que uso

var myContract = web3.eth.contract([ABI]);
var meta = myContract.at("address");
var Transfer = meta.Accessed({}, {fromBlock: 0, toBlock: 'latest'});
Transfer.watch(function(err, e) {
   if (err) {
      console.log(err);
} else {
      console.log("new Transfer executed from", e);
}
});

Con este fragmento en cualquier consola de nodo, estoy escuchando cualquier llamada de la función Transfer() pero no sucede nada. Esto es lo que obtengo en respuesta a la observación del evento.

 {
 callbacks: [],
 filterId: "0x1b2e43d107ba5d1426df7243a74e6c04",
 getLogsCallbacks: [],
 implementation: {
 getLogs: function(),
 newFilter: function(),
 poll: function(),
 uninstallFilter: function()
 },
 options: {
 address: "0x18776b68d09660c4ddbfda8e71f67906c7147edf",
 from: undefined,
 fromBlock: "0x0",
 to: undefined,
 toBlock: "latest",
 topics:["0xa938469e072f18fc99f2e[...]", 
 null, null, null]
 },
 pollFilters: [],
 requestManager: {
 polls: {
 0x3ef60ce0d464242fac329bd3e1720427: {
    data: {...},
    id: "0x3ef60ce0d464242fac329bd3e1720427",
    callback: function(error, messages),
    uninstall: function()
  },
  0x80efdb3c4df0b69c53f1f9ce47d527bb: {
    data: {...},
    id: "0x80efdb3c4df0b69c53f1f9ce47d527bb",
    callback: function(error, messages),
    uninstall: function()
  },
  0xb62a9e7d2148f67acf56a96aca3046f2: {
    data: {...},
    id: "0xb62a9e7d2148f67acf56a96aca3046f2",
    callback: function(error, messages),
    uninstall: function()
  },
  0xe63a8aea7e45a2576b0852dd129c37d7: {
    data: {...},
    id: "0xe63a8aea7e45a2576b0852dd129c37d7",
    callback: function(error, messages),
    uninstall: function()
  }
},
provider: {
  newAccount: function(),
  openWallet: function(),
  send: function github.com/ethereum/go-ethereum/console.(*bridge).Send-fm(),
  sendAsync: function github.com/ethereum/go-ethereum/console.(*bridge).Send-fm(),
  sign: function(),
  unlockAccount: function()
},
timeout: {},
poll: function(),
reset: function(keepIsSyncing),
send: function(data),
sendAsync: function(data, callback),
sendBatch: function(data, callback),
setProvider: function(p),
startPolling: function(data, pollId, callback, uninstall),
stopPolling: function(pollId)
},
formatter: function(),
get: function(callback),
stopWatching: function(callback),
watch: function(callback)
}

Lo mismo sucede con event.get()

Entonces, en tu opinión, ¿cuál es el problema? ¿Me estoy perdiendo de algo?

Muchas gracias

Respuestas (2)

contract ExampleContract {
  event ReturnValue(address indexed _from, int256 _value);

function foo(int256 _value) returns (int256) {
    ReturnValue(msg.sender, _value);
    return _value;
  }
}

Una interfaz puede obtener el valor de retorno:

var exampleEvent = exampleContract.ReturnValue({_from: web3.eth.coinbase});
exampleEvent.watch(function(err, result) {
  if (err) {
    console.log(err)
    return;
  }
  console.log(result.args._value)
  // check that result.args._from is web3.eth.coinbase then
  // display result.args._value in the UI and call    
  // exampleEvent.stopWatching()
})


exampleContract.foo.sendTransaction(2, {from: web3.eth.coinbase})

Cuando se extrae la transacción que invoca a foo, se activará la devolución de llamada dentro del reloj. Esto permite que la interfaz obtenga valores de retorno de foo.

En su caso, está imprimiendo directamente el resultado een la consola. Le recomiendo que lo use e.args._addpara imprimir el valor deseado en la consola.

Consulte este artículo para obtener más detalles.

Gracias señor por la aclaración y el ejemplo. Probé tu ejemplo y funcionó, el mismo enfoque aplicado al mío, no lo hace. Esto me llevó a ajustar un poco el código, puede que algo esté mal. Por cierto, su problema es un poco diferente porque su transacción no es una transacción adecuada sino algo más una llamada. No altera el estado del EVM, por lo que el valor de retorno está completamente disponible para ser devuelto. Por el contrario, mi evento se construye dentro de un SET, por lo que no se puede ejecutar el retorno. ¿Tiene alguna sugerencia de que pueda probar mi código para ver si funciona?

Te falta la palabra clave emitdelante de tu evento. Al igual que:

function transfer(bytes32 _ID) public returns (address) {
    // Only the current owner can transfer the token.
    if (ID == _ID) {    
      owner = msg.sender;
      taddr.push(msg.sender);
      ttime.push(now);        //same but it stores the timestamp
      emit Accessed("someone executed the transfer function",owner,now);
      
      return(owner); 
    } 
}

Además, block.timestampgeneralmente debe usarse en lugar de now. nowestá oficialmente en desuso en la versión 0.7.0, pero incluso si usa una versión anterior, el uso block.timestampayudará con la reutilización para otros contratos en el futuro.

La versión de solidez más utilizada en 2018 fue la 0.4, en la que emitno era necesario utilizarla. Si hubo un error fue otra cosa.