los oyentes de eventos truffle/web3 no devuelven nada

Tenemos un evento que se desencadena en un contrato y nuestros oyentes en el cliente no pueden recibir el valor de retorno.

https://gist.github.com/stupeters187/9529b54fe0d48ee606ad06ced6b16031

Actualización: metamask versión 3.12.1 solucionó el problema

Respuestas (2)

Respuesta: su llamada a newbook() no puede devolver un valor en javascript porque cambia de estado.

Explicación: Truffle distingue entre funciones que cambian de estado y funciones que solo leen la cadena de bloques. Cada vez que cambia de estado, debe transmitirlo a la red para que los mineros puedan incorporar el cambio en el siguiente bloque. Además, cada nodo debe actualizar su copia de la cadena de bloques. Por eso los cambios de estado cuestan gasolina. También es por eso que no debe esperar un valor de retorno de una función que cambia de estado porque la operación es asíncrona y podría tardar entre 1 y 2 bloques en completarse.

Por otro lado, las llamadas a funciones que solo leen el estado existente de la cadena de bloques no necesitan molestar a ningún minero o nodo. De hecho, si ejecuta su propio nodo, solo necesita consultar su copia local de la cadena de bloques para ejecutar dicha función. Esta es la razón por la cual las funciones de solo lectura no cuestan gasolina. Para indicarle a truffle que estás llamando a una función libre (es decir, una que no cambia de estado), usas la palabra clave llamada después de la llamada a la función. EG Suponga que tiene una función de solidez llamada getBalance() entonces escribiría

instance.getBalance.call()

en javascript.

En su ejemplo anterior, necesitaría separar el cambio de estado y la recuperación en 2 pasos de la siguiente manera:

ParentContract.deployed().then((instance) => { instance.NewBook().watch((err, res) => { if (err) console.log(err); console.log('contract address', res.address); }); instance.newBook(weiPrice, issues, rateFormatted, {from: window.web3.eth.accounts[0]}).then((res) => { console.log('TX', res); return instance.getLatestBookId.call(); }).then(res=>{ //res will have the id in there somewhere. }) .catch((err) => console.log(err) ); });

Esto supone que tiene una función de solidez llamada getLatestBookId() que se parece a

function getLatestBookId returns (uint id){ //DO NOT PUT STATE CHANGE OPERATIONS }

Solo tenga en cuenta que las asignaciones no tienen un concepto de longitud, por lo que no es posible obtener lo último de una asignación. Es posible que deba modificar un poco sus estructuras de datos para que esto sea posible.

Recuerde también que cuando digo cambio de estado, me refiero solo al almacenamiento en la cadena de bloques. Puede hacer lo que quiera con las variables locales al contenido de su corazón (o del corazón estricto de Solidity) sin incurrir en costos de gasolina.

Metamask Versión 3.12.1

*Tenga en cuenta la actualización inferior (este fue nuestro problema)