3

how can we get all the past events of the contract ? I am trying like this :

on web3.js ( "web3": "^1.0.0-beta.34"):

// Add the web3 node module
var Web3 = require('web3');

// Show web3 where it needs to look for the Ethereum node.
web3 = new Web3(new Web3.providers.WebsocketProvider('wss://mainnet.infura.io/_ws'));

// Define the contract ABI
var abi = 

// Define the contract ABI and Address
var contract = new web3.eth.Contract(abi, '0x5a3c9A1725BB82690ee0959c89abE96fD1b527ee');

// Fun console text, you can ignore this.
console.log('-----------------------------------');
console.log('Matching Smart Contract Events');
console.log('-----------------------------------');

const filter = { fromBlock: 0, toBlock: 'latest'}; // filter for your address
const events = contract.allEvents(filter); // get all events
console.log(events)

// contract.Transfer({}, { fromBlock: 0, toBlock: 'latest' }).get((error, eventResult) => {
//   if (error)
//     console.log('Error in myEvent event handler: ' + error);
//   else
//     console.log('myEvent: ' + JSON.stringify(eventResult.args));
// });

// contract.allEvents(fromBlock: 0, toBlock: 'latest', (e, res) => console.log(res))

on web3.py (web3==4.3.0) :

import requests
from web3 import Web3,WebsocketProvider

def main():
 web3 = Web3(WebsocketProvider("wss://mainnet.infura.io/_ws"))
 print (web3, "web3")
 contract_address = "0x5a3c9A1725BB82690ee0959c89abE96fD1b527ee"
 contract_abi = 
 contract = web3.eth.contract(address=contract_address, abi=contract_abi)
 print (contract, "contract")

 transferEvent = contract.eventFilter('Transfer', {'fromBlock': 0,'toBlock': 'latest'});
 print (transferEvent, "transferEvent")

 eventlist = transferEvent.get_all_entries()
 print(eventlist, "eventlist")


 # transferEvent = contract.eventFilter('Transfer', fromBlock = 0)
 # transferEvent = contract.events.Transfer.createFilter(fromBlock = 0)
 # print (transferEvent.get_all_entries())

if __name__ == "__main__":
 print ("Script has started...")
 main()
 print ("Script has ended...")
12
  • 1
    This seems ok, what error are you getting?
    – Jaime
    Jun 20, 2018 at 7:06
  • on web3.py : *** TypeError: '<=' not supported between instances of 'int' and 'NoneType' Jun 20, 2018 at 7:14
  • on web3.js : TypeError: contract.allEvents is not a function Jun 20, 2018 at 7:14
  • I just came to know , there is a limit on the number of events we can get from infura. Jun 20, 2018 at 7:15
  • is that was the rror consider to add an answer yourself so that the rest know this.
    – Jaime
    Jun 20, 2018 at 7:18

2 Answers 2

6

Here is an answer for web3.py version 5.1

Example:

from web3 import Web3
from .utils import create_contract
from .events import fetch_events


uniswap_factory = '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f'
factory_abi_url = 'https://unpkg.com/@uniswap/[email protected]/build/UniswapV2Factory.json'
erc20_abi_url = 'https://unpkg.com/@uniswap/[email protected]/build/IERC20.json'

def fetch_uniswap_pairs(web3: Web3):
    """Fetch all trading pairs on Uniswap"""
    factory = create_contract(web3, factory_abi_url, uniswap_factory)
    events = list(fetch_events(factory.events.PairCreated, from_block=0))

    print('Got', len(events), 'events')

    # Each event.args is presented as AttrbuteDict
    # AttributeDict({'args': AttributeDict({'token0': '0x607F4C5BB672230e8672085532f7e901544a7375', 'token1': '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', 'pair': '0x6d57a53A45343187905aaD6AD8eD532D105697c1', '': 94}), 'event': 'PairCreated', 'logIndex': 7, 'transactionIndex': 2, 'transactionHash': HexBytes('0xa0ce4b0db9bbf7887f09c4b35ec1167144b06f69fbbea6d6a163a72db28175d8'), 'address': '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f', 'blockHash': HexBytes('0xf269a89cf729781bfa8e8ec421f8eefbf13e1fecd22b4118c1304d360832ef20'), 'blockNumber': 10092190})
    for ev in events[0:10]:
      token0 = create_contract(web3, erc20_abi_url, ev.args.token0)
      token1 = create_contract(web3, erc20_abi_url, ev.args.token1)
      print(f'Found pair {token0.functions.symbol().call()}-{token1.functions.symbol().call()}')


def run():
    infura = # Your HTTPS infura endpoint URL
    web3 = Web3(Web3.HTTPProvider(infura))
    fetch_uniswap_pairs(web3)


run()

Utils.py:

import requests

from web3 import Web3

_cache = dict()


def get_cached_abi(abi_url):
    """Per process over-the-network ABI file retriever"""
    spec = _cache.get(abi_url)
    if not spec:
      spec = _cache[abi_url] = requests.get(abi_url).json()
    return spec


def create_contract(web3, abi_url, address):
    spec = get_cached_abi(abi_url)
    contract = web3.eth.contract(address, abi=spec['abi'])
    return contract

events.py:

from web3._utils.abi import get_constructor_abi, merge_args_and_kwargs
from web3._utils.events import get_event_data
from web3._utils.filters import construct_event_filter_params
from web3._utils.contracts import encode_abi


def fetch_events(
    event,
    argument_filters=None,
    from_block=None,
    to_block="latest",
    address=None,
    topics=None):
    """Get events using eth_getLogs API.

    This is a stateless method, as opposite to createFilter and works with
    stateless nodes like QuikNode and Infura.

    :param event: Event instance from your contract.events
    :param argument_filters:
    :param from_block: Start block. Use 0 for all history/
    :param to_block: Fetch events until this contract
    :param address:
    :param topics:
    :return:
    """

    if from_block is None:
        raise TypeError("Missing mandatory keyword argument to getLogs: from_Block")

    abi = event._get_event_abi()
    abi_codec = event.web3.codec

    # Set up any indexed event filters if needed
    argument_filters = dict()
    _filters = dict(**argument_filters)

    data_filter_set, event_filter_params = construct_event_filter_params(
        abi,
        abi_codec,
        contract_address=event.address,
        argument_filters=_filters,
        fromBlock=from_block,
        toBlock=to_block,
        address=address,
        topics=topics,
    )

    # Call node over JSON-RPC API
    logs = event.web3.eth.getLogs(event_filter_params)

    # Convert raw binary event data to easily manipulable Python objects
    for entry in logs:
        data = get_event_data(abi_codec, abi, entry)
        yield data
1

web3-ethereum-defi package now has a ultra fast concurrent event reader using thread pools. It can read multiple events over block ranges using concurrency and maximizing the potential performance over JSON-RPC API.

Here is an example how to use:


        json_rpc_url = os.environ["JSON_RPC_URL"]
        web3_factory = TunedWeb3Factory(json_rpc_url)
        web3 = web3_factory(token_cache)
        executor = create_thread_pool_executor(web3_factory, max_workers=16)

        # Get contracts
        Factory = get_contract(web3, "UniswapV2Factory.json")

        # You can scan multiple events once
        events = [
            Factory.events.PairCreated,
        ]

        start_block = 10_000_835  # Uni deployed
        end_block = 10_009_000  # The first pair created before this block

        # Read through the blog ran
        out = []
        for log_result in read_events_concurrent(
            executor,
            start_block,
            end_block,
            events,
            None,
            chunk_size=100,
            context=token_cache,
            extract_timestamps=None,
        ):
            out.append(decode_pair_created(log_result))

See full example.

Your Answer

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

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