2

My web3 version is [email protected], I am deploying the contract on the localhost:8545.

Here is my contract example.

pragma solidity ^0.4.18;
contract LocalEthereum {

    address public owner;
    event Created(bytes32 _tradeHash);
    function createEvent() onlyOwner external {
        Created(0x01);
    } 
}

and here is my js code

init the contract instance

  var Contract = new this.web3.eth.Contract(abi_json,address);

button click events

  Created(account){
      Contract.methods.Created().send({from: account,gas:210000,gasPrice:5000000000})
                      .on('transactionHash', function(hash){
                          console.log('hash',hash);
                      })
                      .on('receipt', function(receipt){
                          console.log('receipt',receipt);
                      })
                      .on('confirmation', function(confirmationNumber, receipt){
                          console.log('confirmation',confirmationNumber);
                      })
                      .on('error', console.error);
  }

watch events

  this.Contract.events.Created({},{ fromBlock: 0, toBlock: 'latest' }, function(error, event){ console.log(event); })
                        .on('data', function(event){
                              console.log(event);
                        })
                        .on('changed', function(event){
                             console.log('on changed');
                        })
                        .on('error', console.error);

The js app can load the contract and connect the ethereum network, when I click the button, Contract will generate a 'Created' rpc call to the ethereum, the transaction can be received immediately. On the testrpc interface I could also see the transaction as shown below.

  Transaction: 0x2469f2085c8f6f23ad8aa30bc6cf99ade40ea2f0368b9bb008496ba05d927d84
  Gas usage: 21272
  Block Number: 6
  Block Time: Thu Dec 28 2017 20:38:02 GMT+0000 (GMT)

Everything works well, however the event call is never activated after the method call. There is only one time event call in the app intialization but still the

  this.Contract.events.Created({},{ fromBlock: 0, toBlock: 'latest' }, function(error, event){ console.log(event); })
                        .on('data', function(event){
                              console.log(event);
                        })

the console outputs the null.

Wonder what is the problem?


i wonder is it because of web3 provider? currently i am using web http not ws. And currently I am testing on the ganache-cli and testrpc.

this.web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));

is http provider doesn't provide event?

3 Answers 3

2

Actually I found that the HttpProvider doesn't support subscribing to events in web3.js 1.0.0. From https://web3js.readthedocs.io/en/1.0/web3.html#value:

Object - HttpProvider: The HTTP provider is deprecated, as it won’t work for subscriptions.

So I will indeed need to use the WebsocketProvider (or IpcProvider for local nodes).

0

You can filter events only for parameters that are part of the event, and the parameters you want to use in the filter have to be defined as indexed in the event definition of the contract. So in order for your web3.js code to work, you need to add the _from parameter to the event definition, make it indexed and set the parameter to msg.sender whenever you throw an event:

pragma solidity ^0.4.18;
contract LocalEthereum {

    address public owner;
    event Created(adress indexed _from, bytes32 _tradeHash);
    function createEvent() onlyOwner external {
        Created(msg.sender, 0x01);
    } 
}

You can have up to three indexed parameters in an event.

However, looking at your contract code, only the owner of the contract can create event Created. So unless the owner changes, filtering for the _from will not be of much use. So if you do not need this filtering, try

var event = instance.Created({},{fromBlock:0,toBlock:'latest'});

in your javascript code, this should work without making modifications to your contract.

2
  • Thanks, I know the use of indexed. but your js code still doesn't work. Even when I removed onlyOwner in the solidity code . the js code still receive all the past events and doesn't emit a event when the createEvent() executes
    – user824624
    Commented Nov 27, 2017 at 8:28
  • So your js code seems to be correct, that*s a good. Did you check that you are sending the Events from your contract correctly? You can do that easily using etherscan.io, look at one transaction that created the event correctly, and at a later one that didn't and compare the entries on the Events Logs tab
    – gisdev_p
    Commented Nov 29, 2017 at 23:04
0

This is directly taken from the Web3 Docs. This should work.

var event = myContractInstance.MyEvent({valueA: 23} [, additionalFilterObject])

// watch for changes
event.watch(function(error, result){
  if (!error)
    console.log(result);
});

// Or pass a callback to start watching immediately
var event = myContractInstance.MyEvent([{valueA: 23}] [, additionalFilterObject] , function(error, result){
  if (!error)
    console.log(result);
});

Also, looks like this is a beta version. Might be because of that, as there are some breaking changes.

PREVIEW RELEASE This is a beta preview release with breaking changes! The current stable version is 0.20.0

If you use a stable version of web3 i.e. 0.20.0, and try the above code, it should work.

Alternative, if the above method doesn't work, you can use the JSON-RPC method eth_getLogs. Below is the example of how to use it:

let request = require('request);
request.post({
                url: <geth_parity_client_IP_with_port>,
                form: JSON.stringify({
                    "jsonrpc":"2.0",
                    "method":"eth_getLogs",
                    "params":[
                        {
                            "topics": ["<get_your_Event_Hex_replace_this_string>"],
                            "address": <contractAddress>,
                            "fromBlock": "0x"+_fromBlock.toString(16),
                            "toBlock": "0x"+_toBlock.toString(16)
                        }
                    ],
                    "id":3 //Network To connect to (test/Main Net)
                }),
                headers: {
                    'Content-Type': 'application/json'
                }
            }, (error, response)=>{
                if(!error && response.statusCode == 200){
                    let result = JSON.parse(response.body).result;
                    console.log(result); //Prints the event details
                }
            });

Let me know if the above helps.

2
  • do you know how to make it work in web3 1.0
    – user824624
    Commented Dec 29, 2017 at 11:01
  • No. Haven’t got a chance to work with the beta yet. But, did you try using the alternative approach. Commented Dec 29, 2017 at 23:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.