5

I have structure of event in my Solidity code like event test(address investor, uint256 priceinWei).

I make a request to etherscan to get all logs from contract on specific addres and get

{  
   'address':'...',
   'topics':[  
      '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
      '0x0000000000000000000000001111111111111111111111111111111111111111',
      '0x000000000000000000000000409fefe0212a75d8c117ac834123d462bce9635c'
   ],
   'data':'0x000000000000000000000000000000000000000000000012f94bfef30bf32b8d',
   'blockNumber':'...',
   'timeStamp':'....',
   'gasPrice':'0x4a817c800',
   'gasUsed':'0x182b7',
   'logIndex':'0x8',
   'transactionHash':'...',
   'transactionIndex':'0xc'
}

Question: How can I get address and price from it. Should I decode "data"? Instead ... I of course got values, just don't want to show it.

Averin Maxim
  • 293
  • 4
  • 6
  • 1
    Related: https://ethereum.stackexchange.com/questions/1381/how-do-i-parse-the-transaction-receipt-log-with-web3-js – eth Nov 22 '17 at 10:18

2 Answers2

2

For those who want to do it in a hard way, here is an example of Uniswap v2 PairCreated event:

def decode_pair_created(log: LogResult) -> dict:
    """Process a pair created event.
This function does manually optimised high speed decoding of the event.

The event signature is:

.. code-block::

    event PairCreated(address indexed token0, address indexed token1, address pair, uint);
"""

# The raw log result looks like
# {'address': '0x5c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f', 'blockHash': '0x359d1dc4f14f9a07cba3ae8416958978ce98f78ad7b8d505925dad9722081f04', 'blockNumber': '0x98b723', 'data': '0x000000000000000000000000b4e16d0168e52d35cacd2c6185b44281ec28c9dc0000000000000000000000000000000000000000000000000000000000000001', 'logIndex': '0x22', 'removed': False, 'topics': ['0x0d3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9', '0x000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', '0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'], 'transactionHash': '0xd07cbde817318492092cc7a27b3064a69bd893c01cb593d6029683ffd290ab3a', 'transactionIndex': '0x26', 'event': <class 'web3._utils.datatypes.PairCreated'>, 'timestamp': 1588710145}

# Do additional lookup for the token data
web3 = log["event"].web3
token_cache: TokenCache = log["context"]

block_time = datetime.datetime.utcfromtimestamp(log["timestamp"])

# Any indexed Solidity event parameter will be in topics data.
# The first topics (0) is always the event signature.
token0_address = convert_uint256_string_to_address(log["topics"][1])
token1_address = convert_uint256_string_to_address(log["topics"][2])

factory_address = log["address"]

# Chop data blob to byte32 entries
data_entries = decode_data(log["data"])

# Any non-indexed Solidity event parameter will be in the data section.
pair_contract_address = convert_uint256_bytes_to_address(data_entries[0])
pair_count = int.from_bytes(data_entries[1], "big")

# Now enhanche data with token information
token0 = token_cache.get_token_info(web3, token0_address)
token1 = token_cache.get_token_info(web3, token1_address)

data = {
    "block_number": int(log["blockNumber"], 16),
    "timestamp": block_time.isoformat(),
    "tx_hash": log["transactionHash"],
    "log_index": int(log["logIndex"], 16),
    "factory_contract_address": factory_address,
    "pair_contract_address": pair_contract_address,
    "pair_count_index": pair_count,
    "token0_symbol": token0.symbol,
    "token0_address": token0_address,
    "token1_symbol": token1.symbol,
    "token1_address": token1_address,
}
return data

Full example available on web3-ethereum-defi project.

Mikko Ohtamaa
  • 22,269
  • 6
  • 62
  • 127
1

You can create a reference testEvent to the event using

    var testEvent = Contract.test({}, {fromBlock: startBlockNo, toBlock: 'latest'});

and then use watch or get to on this reference to retrieve the events:

testEvent.watch(function(error, result){
    if(!error) {
        // do what you want to do with the event data
    }
});

or

testEvent.get(function(error, result){
    if(!error) {
        // do what you want to do with the event data
    }
});

Within the if(!error) {...}part you can access the data of the event from your question using result.args.investerand result.args.priceinWei.

The difference between watch and get is that getwill only give you past events, while watch will get you past events and watching for new ones.

gisdev_p
  • 1,801
  • 1
  • 9
  • 18