5

My contract has a transaction which fires an event. I was able to catch every event when I was sending transactions manually.

But now I'm sending 100 transactions in cycle and get only 2..5 events. Yes, randomly - which puzzles me the most. I get a random quantity of events and random last event caught every time I run my code. Please see the console output below.

Tried to add a pause between transactions. The longer the pause the more events are caught. This puzzles me too - don't understand why this matters for events.

My .sol contract

contract Example {

    uint32 public value;

    event ValueSet(uint);

    function setValue(uint32 val) {
        value = val;
        ValueSet(val);
    }

}

My python code (sorry for the long code - was afraid to mess it up shortening)

class MyContract:

    address = ""
    filter = ""

    def __init__(self):
        self.c = EthJsonRpc('127.0.0.1', 8545)

    def deploy(self):

        # get contract address
        compiled = '6060604052610.....' # shortening it here.
        contract_tx = self.c.create_contract(self.c.eth_coinbase(), compiled, gas=3000000)
        self.address = self.c.get_contract_address(contract_tx)

        # set new filter
        params = {
            "fromBlock": "0x01",
            "address": self.address
        }
        self.filter = str(self.new_filter(params))


    def send_transaction(self, foo, value):
        tx = self.c.call_with_transaction(self.c.eth_coinbase(), self.address, foo, value)
        return tx

    def new_filter(self, params):
        return self.c.eth_newFilter(params)

    def listen(self):
        return self.c.eth_getFilterLogs(self.filter)



def main():
    my_contract = MyContract()
    my_contract.deploy()

    #sending transactions which trigger events 
    for i in range(100):
        my_contract.send_transaction('setValue(uint32)', [i])
        time.sleep(1) # the more time the more events are caught 

    # retrieve all logs from the filter
    logs = my_contract.listen()

    print repr(logs)
    print "Quantity of events: " + str(len(logs))
    if logs:
        print "Data: " + str(int(logs[-1]['data'], 16))

Console output

[
   {
      u'type':u'mined',
      u'blockHash':u'0xac739ae0feac68eae0cddb5216ef64c7931821cf26db327c85bd3da16f947f44',
      u'transactionHash':u'0x4d2465e9b978a275cca63fb9129a5da8f7a9dcc9b2c6e8b717ecf734be7ab950',
      u'data':u'0x0000000000000000000000000000000000000000000000000000000000000026',
      u'topics':[
         u'0x012c78e2b84325878b1bd9d250d772cfe5bda7722d795f45036fa5e1e6e303fc'
      ],
      u'blockNumber':u'0x0223',
      u'address':u'0x9062a6b9299af4bdb535a5ecdbfeb8a28e6cf4c1',
      u'logIndex':u'0x00',
      u'transactionIndex':u'0x0'
   },
   {
      u'type':u'mined',
      u'blockHash':u'0x1014603151080201cc26990c6b4f1dd01a5b65545b19a570a01c9ad11532c7f2',
      u'transactionHash':u'0xe79af54c765368e73e3c9ca996de667e43363e92856ca234459633fda86c77ca',
      u'data':u'0x000000000000000000000000000000000000000000000000000000000000005f',
      u'topics':[
         u'0x012c78e2b84325878b1bd9d250d772cfe5bda7722d795f45036fa5e1e6e303fc'
      ],
      u'blockNumber':u'0x025c',
      u'address':u'0x9062a6b9299af4bdb535a5ecdbfeb8a28e6cf4c1',
      u'logIndex':u'0x00',
      u'transactionIndex':u'0x0'
   }
]
Quantity of events: 2
Data: 95

Related

How to list transactions from account address?

How can I create a listener for new transaction with Ethereum RPC calls?

Creating eth_newFilter topic listeners with Python

Why asking

I'm trying to write a code which will save contract event to a database in "live" mode (catch new events) and in "retrospective" mode (retrieve all contract events). And just want to understand how events work.

I'm using ethjsonrpc with testrpc (Ethereumjs).

Thank you very much!

1

Just needed to add receipt = self.c.eth_getTransactionReceipt(tx). I guess it insures that the transaction is mined.

Now it catches all 100 events.

I've also tried to add a timer after every transaction. 5 seconds after every transaction was enough to catch all events. But eth_getTransactionReceipt works much faster (couple of seconds for all 100 transactions).

Can anybody please explain this? What the code would look like for the production blockchain?

    def send_transaction(self, foo, value):
        tx = self.c.call_with_transaction(self.c.eth_coinbase(), self.address, foo, value)
        receipt = self.c.eth_getTransactionReceipt(tx)
        return tx

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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