35

How can I access a log stored in one of the tx of the contract via web3?

Code example:

event newtest(string indexed name, uint indexed idlevel,string indexed multib, string objmulti, uint objnm);

and

newtest('test',5,'testj','obj2',30);

Let's say contract address is 0x00. How do I get all the logs that are stored in this contract address with web3?

P.s. I don't need to listen on events in real time. I just need to get all the logs of a contract, based on filters when I need it.

4
  • 1
    I think this is a duplicate of ethereum.stackexchange.com/questions/1381/…
    – Paul S
    Mar 13, 2016 at 1:42
  • that question ask for parsing logs and assume you that you have already the receipt of the tx, instead i'm looking on how i can get the logs knowing only the contract address, thank you anyway
    – b1818762
    Mar 13, 2016 at 10:14
  • Sorry, misunderstood a bit. You'll need that answer once you find the transaction looking you are looking for. Well, I don't know how to code this, but I know where to find the answer. The blockchain explorers have this capability, and there's some open source examples here: ethereum.stackexchange.com/questions/404/…
    – Paul S
    Mar 13, 2016 at 14:07
  • How do we do this in 1.0 now that filter is gone?
    – Andrew
    Feb 5, 2020 at 17:57

5 Answers 5

35

Take a look at web3.eth.filter and watch.

Something like this:

const filter = web3.eth.filter({
  fromBlock: 0,
  toBlock: 'latest',
  address: contractAddress,
  topics: [web3.sha3('newtest(string,uint256,string,string,uint256)')]
})

filter.watch((error, result) => {
   //
})

Note the part that "In Solidity: The first topic is the hash of the signature of the event." Canonical types, such as uint256 have to be used in signatures.

EDIT: Per @plingamp's comment web3.sha3 now includes the '0x'.

5
  • 1
    thank you for the answer, i didn't know about the signature on the first topic this solved the issue! however i found that you need to put "0x" before the signature so "0x"+web3.sha3('newtest(string,uint256,string,string,uint256)')
    – b1818762
    Mar 13, 2016 at 18:14
  • last thing, i was looking on how to parse logs data and found the previous linked question useful ( ethereum.stackexchange.com/questions/1381/… )but i cannot import the coder.js script via require() because i'm making a static page, do you know how to use the decodeParams function with web3?
    – b1818762
    Mar 13, 2016 at 20:21
  • Glad your issue is solved and I'll update to include the 0x. I haven't looked at decodeParams much, but there's usually tests in web3.js and they can help figure out how APIs can be used.
    – eth
    Mar 14, 2016 at 3:42
  • I don't have enough reputation to leave a comment, but @eth's answer is slightly out of date now. The '0x' is included in web3.sha3() now. var filter = web3.eth.filter({fromBlock:0, toBlock: 'latest', address: contractAddress, 'topics':[web3.sha3('newtest(string,uint256,string,string,uint256)')]}); filter.watch(function(error, result) { ... }) Hope this helps.
    – plingamp
    Dec 23, 2016 at 20:35
  • @plingamp Thanks! Updated the answer. (Not sure if permissions allow you to click "edit" and it might be another option to try.)
    – eth
    Dec 24, 2016 at 2:45
13

Use .get instead of .watch with web3.eth.filter:

contractAddress = "0x00.."
web3.eth.filter({
  address: contractAddress,
  from: 1,
  to: 'latest'
}).get(function (err, result) {
  // callback code here
})
1
  • 1
    I think this answer answers the actual question about how to get the events after that fact without listening in real time. .get does this while .watch is for listening in real time. Sep 14, 2017 at 18:22
5

In web3 1.0 you can use getPastEvents as follows

 var contractInstance = new web3.eth.Contract(contractAbi, contractAddress);

  contractInstance.getPastEvents('EventName', {
      filter: {id: id},  
      fromBlock: 0,
      toBlock: 'latest'
  }, (error, events) => { 

      if (!error){
        var obj=JSON.parse(JSON.stringify(events));
        var array = Object.keys(obj)

        console.log("returned values",obj[array[0]].returnValues);

      }
      else {
        console.log(error)
      }})
4
  • Can you edit your answer and explain more please? (I'm not seeing how this answers the question.)
    – eth
    Aug 16, 2016 at 1:49
  • 1
    this is in web3.js 1.0 - fyi. That is the eth.subscribe function May 17, 2017 at 23:14
  • 1
    Yes, this is deprecated. Jul 12, 2017 at 13:34
  • 1
    For past events: contractInstance.getPastEvents('allEvents', {fromBlock: 0, toBlock: 'latest'}, function(e,l){console.log(l)})
    – rstormsf
    Aug 7, 2017 at 21:27
2

Yes, one way to go is write all of your conditions in a .js file and load these script to console when you need.

loadScript -> Loads a JavaScript file and executes it.

loadScript example

2
  • Thank you for the reply, however this is not what i was looking for, i have troubles with getting logs from a contract address via web3
    – b1818762
    Mar 13, 2016 at 10:07
  • web3 is supposed to work. please do post the code snippet so that the community will help you more on this.
    – niksmac
    Mar 13, 2016 at 13:12
1

If you what to filter for multiple events you must pass in a list within a list. For the following two events emitted in a Solidity contract:

event event1(uint256 indexed anumb)
event event2(uint256 indexed anothernumb)
event event3(uint256 indexed yetanothernumb)

Use the following to filter for events1 and event2 only:

const filter = web3.eth.filter({
  fromBlock: 0,
  toBlock: 'latest',
  address: contractAddress,
  topics: [[web3.sha3('event1(uint256)'),web3.sha3('event2(uint256)')]]
})

filter.get((error, result) => {
   // gets all prior results
})

From the docs:

topics: Array of Strings - An array of values which must each appear in the log entries. The order is important, if you want to leave topics out use null, e.g. [null, '0x00...']. You can also pass another array for each topic with options for that topic e.g. [null, ['option1', 'option2']]

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.