Слушайте события блокчейна в js

Я хочу, чтобы все js-клиенты реагировали на новое событие, сохраняемое в блокчейне:

contract MainContract{
    event Evt(address indexed _sender,string jsn);
    function deposit(string jsn) returns (int256) {
        Evt(msg.sender, jsn);
    }
}

Здесь я ожидаю, что обратный вызов часов будет выполнен.

    var contract = web3.eth.contract(abi).at("0xe45866ac5d51067ce292bc656c790e94ddcf0766");
    var myEvent = contract.Evt({},{fromBlock: 0, toBlock: 'latest'});
    myEvent.watch(function(error, result){
        console.log("on watch"); 
        console.log(arguments);
    });
    // this call saves event data successfully!
    contract.deposit('hello there',function (res) {
        console.log(arguments)
    });

Но я не вижу «на часах» в своей консоли. Это возможно? Как я могу это сделать? Любой пример?

ОБНОВЛЕНИЕ: сейчас я думаю, что это проблема metamask.io ( https://github.com/MetaMask/metamask-plugin/issues/792 )

ОБНОВЛЕНИЕ 2: Похоже на ошибку в ядре Эфириума, некоторые люди сообщают о том же: https://github.com/ethereum/go-ethereum/issues/14670

Судя по вашим комментариям, он работает, но вы не видите сообщения «на часах», нет?
Обратный вызов «На дежурстве» не выполняется.
Итак, если «myEvent» не является неопределенным, и вы можете вызвать «.watch», да, возможно, это проблема с event.watch. С filter.watch есть ошибки, очень похожие, но попробуйте поставить if(!error) console.log(result); иначе console.error(ошибка); }) '
myEvent не занижен, у меня нет ошибок js. ошибка не равна нулю, обратный вызов вообще не вызывается.

Ответы (3)

Я решил свою проблему: я использовал неправильный адрес контракта. Обратите внимание, что API не сообщит вам, что адрес контракта неверен !

Если вы используете truffle, развернутый экземпляр должен иметь событие, чтобы вы могли прослушивать изменения:

let Contract = artifacts.require('./Contract.sol');

contract('Contract', accounts => {

    let MyEvent;

    Contract.deployed().then(instance => {
        MyEvent = instance.SolidityEventMethod({});

        MyEvent.watch((error, result) => {
            if (error) {
                console.log(error);
            }

            console.log(result);
        });
    });

    it('should do something and trigger event', () => {
        return Contract.deployed().then(instance => {
            return instance.myEventTriggeringFunction();
        }).then(res => {
            // at this point the MyEvent.watch method should have logged the result
        }).catch(error => {
            console.log(error);
        });
    });
});

Я думаю, что "проблема" связана с асинхронными функциями. Обходной путь может быть таким:

 var contract;
 window.addEventListener('load', function() {
    if (typeof web3 !== 'undefined') {
        window.web3 = new Web3(web3.currentProvider);

        contract = web3.eth.contract(abi).at(contractAddress);
        var myEvent = contract.Evt({},{fromBlock: 0, toBlock: 'latest'});
        myEvent.watch(function(error, result){
            console.log("on watch");
            console.log(result);
            console.log(result.args);
        });

    } else {
        console.log('No web3? You should consider trying MetaMask!')
    }
})


function callDeposit(){
    contract.deposit('hello there',function (error, result) {
            console.log(result);
    });
}

Также в вашем коде аргументы переменной undefined. Надеюсь, это поможет.

Я уже использую такой скелет. И вы можете видеть из моего кода, что я регистрирую обратный вызов watch перед успешным вызовом .deposit().
переменные аргументы не могут быть неопределенными, потому что это стандартная переменная js