I'm experimenting with plugging Ethereum into a React web application, using this nice tutorial repo as a basis (thanks to uzyn): https://github.com/uzyn/ethereum-webpack-example-dapp

I'm connecting successfully to the local TestRPC 3.0.3 instance, have a Solidity 0.4.8 "MyToken" contract deployed and am mining a contract function called "transfer" successfully. I know the transfer is running just once from the updated account balances but I'm getting two instances of the "Transfer" event coming up in my browser console. If I take out the line emitting the event, I get nothing in the console.

Could anyone suggest why that is? Thanks!

I'm calling this contract function which emits an Event:

/* Send coins */
function transfer(address _to, uint256 _value) {

    if (balanceOf[msg.sender] < _value) throw;           // Check if the sender has enough
    if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
    balanceOf[msg.sender] -= _value;                     // Subtract from the sender
    balanceOf[_to] += _value;                            // Add the same to the recipient

    Transfer(msg.sender, _to, _value);                   // Notify anyone listening that this transfer took place

With this code block:

    (error, result) => {
      if (error) {
        console.log(`Error occurred: ${error}`);

      const accountOneBalance = MyTokenContract.balanceOf(web3.eth.accounts[0]);
      const accountTwoBalance = MyTokenContract.balanceOf(web3.eth.accounts[1]);

      console.log(`accountOneBalance: ${accountOneBalance}`);
      console.log(`accountTwoBalance: ${accountTwoBalance}`);

And I have this Web3 code listening for contract events:

MyTokenContract.allEvents((error, event) => {
if (error) {
  console.log(`Event error: ${error}`);

const eventName = event.event;
const accountFrom = event.args.from;
const accountTo = event.args.to;
const amount = event.args.value;
console.log(`Event '${eventName}' from account ${accountFrom} to ${accountTo} of ${amount}`);


When it runs, I get two events logged in my Chrome console:

accountOneBalance: 249900
accountTwoBalance: 100
Event 'Transfer' from account 0xdd0efd8df206cb598bda146ae567f5d398436226 to 0x7497ac386ae2e1eb58210d08e6c401b56417e04d of 100

Event 'Transfer' from account 0xdd0efd8df206cb598bda146ae567f5d398436226 to 0x7497ac386ae2e1eb58210d08e6c401b56417e04d of 100
  • If you double the line in transfer where it creates the event (thus creating two events) how many events does it now log? Three? Four? I have a hunch this might help you debug. Commented Apr 22, 2017 at 20:06
  • Thanks for the suggestion, it's a good idea. I'm still hoping it's not a stupid logic bug :) So, when I add an extra event and make the logged values "1" and "2" respectively, it prints 1,2,1,2. Maybe it has something to do with the way React loads a page. I'll investigate further when I have time and post an update, unless there's another suggestion. Thanks!
    – John G
    Commented Apr 23, 2017 at 20:59
  • must be a web3 error, did u ever find a way around this?
    – 0TTT0
    Commented Mar 25, 2019 at 17:29

6 Answers 6


I had the same issue and the above solution didn't work in the case that if the testrpc is running and having already triggered some events, then starting the Web3 code the watch returns the latest event that was triggered. What solved the problem and get only new events is:

var latestBlock = web3.eth.blockNumber; //get the latest blocknumber
contractInstance.MyEvent({fromBlock: latestBlock}, (error, event) => { 
    if (error) {
     console.log(error); return; 
    } else {
        if(event.blockNumber != latestBlock) {   //accept only new events
        latestBlock = latestBlock + 1;   //update the latest blockNumber

Hope that helps!


this worked for me

MyTokenContract.allEvents({fromBlock:'latest'}, (error, event) => { if (error) { console.log(Event error: ${error}); return; }

Even though the docs say 'latest' is default, This fixed my duplicate events firing. I wasn't using allEvents. I was watching just one event on the contract.

hope it helps.


I still had this happen in March of 2019, I solved it by making a Set in my javascript and adding blockNumbers to it in my callback to ensure no duplicates were allowed..

var eventBlocks = new Set()

listenCallback = async (error, event, type) => {
  if (error) { console.log(error); }
  else {
    let blockNumber = event.blockNumber;
    if (eventBlocks.has(blockNumber)) return;
    //do everything else you want to do
  • I test with ropsten testnet, and the blockNumber is not the same on 2 duplicate event: 5777243 and 5777244
    – Justin
    Commented Jun 12, 2019 at 4:17

I did exactly what was done above. I was catching my original event like this:

  this.buyEvent = this.$store.state.web3contract.BuyTransaction({},{fromBlock: 0, toBlock: 'latest'});

To fix double firing I put this extra piece of code and it solved my problem.

  this.$store.state.web3contract.allEvents({fromBlock:'latest'}, function (error,event){
    if (error) {
    } else {
      console.log("All Events")

It must be some bug in web3 or I don't know what it is. I am sure I don't register watch function twice. Would be great if somebody can confirm if this is a web3 bug.


I finally figured this one out blockchain bros

I was making a bot to watch buy/sells on Uniswap and kept getting duplicate Transfer events for the same Tx Hash. Not sure if it's a web3 thing, or something with my local Eth node, but it was driving me nuts. I tried to limit to blocks (like if the next block was found, ignore) but I would get multiple events with the same hash in the same block, so that didn't work.

Finally I figured out a way to compare the last Tx Hash to the current one, and if they matched, ignore the rest of the process; if not continue processing transaction:

    async function savetxhash(lasthash) {   //async function to save last tx
        return new Promise((resolve) => {



      var lasthash = ""                     //declare empty at first

     //Here you will have your web3.eth.Transfer() or .allEvents() listener code
     //Then below that you will compare saved hash to new one

       console.log('This hash is '+event.transactionHash+'')
       console.log('Last hash was '+lasthash+'')
       if (lasthash.toLowerCase() == event.transactionHash.toLowerCase()) {
           console.log('Found duplicate tx hash, skipping...')
           } else {
           console.log('No duplicate tx hash found, doing something important...')
       lasthash = await savetxhash(event.transactionHash)   //lastly call the function


I faced the same issue here, using web3 ^1.3.6.

It looks like a problem with the lib itself according to this issue on web3.js repo

My solution was storing the transaction hash of each event and comparing this before executing any logic.

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.