28

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.

  • 1
    I think this is a duplicate of ethereum.stackexchange.com/questions/1381/… – Paul S Mar 13 '16 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 '16 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 '16 at 14:07
28

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'.

  • 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 '16 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 '16 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 '16 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 '16 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 '16 at 2:45
11

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
    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. – Bryan Bedard Sep 14 '17 at 18:22
4

You could use the logs generated by the events (fired by your contract functions). As mentioned in a previous answer, you can define a filter and then apply a filter.watch() to get the desired log data, or alternatively using subscriptions (web 1.0).

var sub = web3.eth.subscribe('logs',options); // for example options = {address: '0x123456..',    topics: ['0x12345...']}

//wait for changes

sub.on('data',function(result){
console.log(result);

});

You could also explore the promiseEvents.

NB: Subscription are based on sockets, so if the connection is closed, the subscription is lost.

  • Can you edit your answer and explain more please? (I'm not seeing how this answers the question.) – eth Aug 16 '16 at 1:49
  • 1
    this is in web3.js 1.0 - fyi. That is the eth.subscribe function – Shawn Cicoria May 17 '17 at 23:14
  • 1
    Yes, this is deprecated. – Stepan Yakovenko Jul 12 '17 at 13:34
  • 1
    For past events: contractInstance.getPastEvents('allEvents', {fromBlock: 0, toBlock: 'latest'}, function(e,l){console.log(l)}) – rstormsf Aug 7 '17 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

  • 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 '16 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 '16 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, privacy policy and cookie policy

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