¿Puede filtrar y observar un método de cambio de estado de contratos en web3.js?

Digamos que tengo un contrato muy simple:

 contract basicStorage {
     uint storedData;

     function set(uint x) {
        storedData = x;
     }

     function get() constant returns (uint) {
        return storedData;
     }
 }

Me gustaría ver los cambios en set () que creo que cambia el estado de los contratos, ¿es posible usar filter/watch en web3.js?

Respuestas (1)

Recomendaría usar eventos.

Smart-Contract - Registro de eventos

pragma solidity ^0.4.15;

contract basicStorage {
    uint storedData;

    event SetEvent(
        address indexed _from,
        uint _x
    );

    function set(uint x) {
        storedData = x;

        // Log event
        SetEvent(msg.sender, x);
    }

    function get() constant returns (uint) {
        return storedData;
    }
}

El código anterior registra un evento cada vez que set(x)se ejecuta la función. El registro contiene la dirección del remitente y el argumento x .

Web3 - Ver eventos

var Web3 = require('web3');
var abi = [...];
var address = '0xxxxxxxxxxxxxxxxxxxx'

var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
var basicStorageContract = web3.eth.contract(abi);
var basicStorageContractInstance = basicStorageContract.at(address);

// watch for changes
var myEvent = basicStorageContractInstance.SetEvent({}, {fromBlock: 0, toBlock: 'latest'});

console.log("Start watching events"); 
myEvent.watch(function(error, result){
    if (!error) {
        console.log(result);
    } else {
        console.log(error);  
    }
});



// Send a transaction to call Set
console.log("set(10)"); 
basicStorageContractInstance.set(10, {from: '0xxxxxxxxxxxxxxxxxxxx'});

console.log("set(20)"); 
basicStorageContractInstance.set(20, {from: '0xxxxxxxxxxxxxxxxxxxx'});

Este código compila el contrato y recupera un myEventobjeto que se puede usar para observar un evento (en nuestro caso, que representa un cambio de estado).

Luego envía dos transacciones y verifica si se imprimen algunos registros.

Resultado

{ logIndex: 0,
  transactionIndex: 0,
  transactionHash: '0x0dc9c421f4d15baa00249f8d1d55d75ea267bc4c82b9654e3c24daf69f9c529d',
  blockHash: '0x2814a29a8c3e32d66063472c6e1d9e5c8eee159f7d19d5da6ecc4bdeeeb9449c',
  blockNumber: 22,
  address: '0xa07ddaff6d8b7aabf91ac6f82bf89455eb9784f4',
  type: 'mined',
  event: 'SetEvent',
  args:
   { _from: '0x13a0674c16f6a5789bff26188c63422a764d9a39',
     _x: { [String: '20'] s: 1, e: 1, c: [Array] } } }

{ logIndex: 0,
  transactionIndex: 0,
  transactionHash: '0x62d888d67e4392b7d218cc7a678b7f3168bcdd2fd77b5a51507e2bf62948273d',
  blockHash: '0x737fce60e8a2012f25eca24d8e56a13eeb127641cc89938f5ec3d8764131f7c7',
  blockNumber: 23,
  address: '0xa07ddaff6d8b7aabf91ac6f82bf89455eb9784f4',
  type: 'mined',
  event: 'SetEvent',
  args:
   { _from: '0x13a0674c16f6a5789bff26188c63422a764d9a39',
     _x: { [String: '30'] s: 1, e: 1, c: [Array] } } }

Puedes encontrar más información

Esta es prácticamente la única respuesta. Supongo que es posible sondear el contrato por cambio de estado, pero ¿por qué molestarse?
Debería haber especificado que, aunque estoy al tanto de los eventos, la documentación y otros ejemplos en línea de alguna manera insinúan lo que dice @OneChillDude, sondeando txHash y luego llamando a un captador al configurar. Espero que esta respuesta, si es definitiva, ayude a otros.
@Keno, no tiene ningún sentido para mí usar encuestas sobre eventos. Los eventos se emiten, se pueden buscar/son indexables, mientras que el sondeo es solo más gastos generales que debe administrar por su cuenta
Sí, lo siento por la sección duplicada. Edité la respuesta. Estoy de acuerdo con @OneChillDude cuando dice que son gastos generales para sondear el contrato. Los eventos están aquí específicamente para este propósito.