Events in Solidity, using blockchain as eventstore

gerbrandvdgerbrandvd Member Posts: 10

I just started using Ethereum and Solidity. For convenience use the events as provided in Solidity a lot, rather then return values in functions.
Our front-end application (Javascript, using web3) subscribes to the events. Since on startup all events since the beginning are re-emitted the current state can be derived.
We just realized we don't have to actually store very little, and probably no state in the contracts itself. So the ethereum-blockchain would in fact become a event-store.
What are other people experience on using the event feature in Solidity? Are there plans to extent the functionality? Maybe allowing contracts to subscribe to events as well, besides emitting them?


  • BronzetankBronzetank Houston, TXMember Posts: 15 ✭✭
    Could you help me understand events better? I want to use them for proof of publication, but I can't seem to wrap my head around how they work.

    If you could walk me through a simple scenario I would really appreciate it. Say for instance, I want to submit a thousand transactions each containing a small text string of metadata to a contract (each of these transactions are originating from a different address). How could the metadata be translated into an event/s? How would I aggregate and search through the discrete metadata entries later?

    Is there any benefit to using an event tied to a contract over just sending transactions to a specific address and then using a block explorer to search through all the transactions that went to the address? In the case mentioned above I don't have any way to search for the transactions other than they were all sent to the same address.

    Thanks for your help!
  • sillytunasillytuna Member Posts: 38 ✭✭
    edited August 2015
    In a contract have something like:
    event AddMsg(address indexed sender, bytes32 msg);
    In a contract function may be:
    AddMsg(msg.sender, "Short message");
    And in javascript:
    var event = ContractManager.AddMsg( {}, function(error, result) {
    if (!error) {
    var msg = "AddMsg: " + hex2a(result.args.msg) + " from " result.args.sender + " (block:" + result.blockNumber + ")";
    This should catch all the AddMsg events as they're added to the chain, but you can pass other parameters in (where the {} is) to do a search or filter, e.g. from/to block, source address. e.g. { sender: '1234' }

    You can filter by the indexed items in AddMsg, of which you can have up to 3.

    hex2a is just a quick func to turn the bytes32 into a string since I wasn't passing string msgs.
  • ultrastanultrastan Member Posts: 4
    Thanks for taking the time to share this. Very helpful.

    Two small typos:
    " from " + result.args.sender …
  • sillytunasillytuna Member Posts: 38 ✭✭
    edited August 2015
    Live coding FTW! And the bugs!

    Also - use web3.toAscii rather than a custom hex2a. Didn't spot that until yesterday :)
  • ultrastanultrastan Member Posts: 4
    This is what I was building:
  • sillytunasillytuna Member Posts: 38 ✭✭
    edited August 2015
    That's quite fun. Been thinking about such things myself, but note that it's quite exploitable by miners. I'd consider using a block count rather than timestamp (see Ethereum's timestamp notes) or maybe a combination of both. Augur uses block count IIRC due to the risks of using internal clocks.

    Also, if you use indexed arguments in your log you can search for specific items rather than making a node return all the logs.
  • ultrastanultrastan Member Posts: 4
    Thanks for the info on timestamp. Note I'm just using "now", but I guess that has the same issues.

    I have a question ... when monitoring logs, I want to stop monitoring when I hit the current block (and then, in a few minutes, run a script again to catch up from where I left off).

    I'm trying to figure out how to know when to stop.
  • sillytunasillytuna Member Posts: 38 ✭✭
    When filtering you can specify which block range to use, including ending with the current block. If using the current block, I think you'll get new updates as new events occur. You can also elect to unwatch if you want to.

    Be aware that the blockchain can reorganise itself so the results may not be 'true' or could change somewhat underneath you.
  • MetalMetal Member Posts: 17
    About those events, are they permanent, or can they be expected to disappear at some point?

    I had initially assumed they would stay put, but the recent mention of old block data becoming inaccessible is making me wonder.
  • gerbrandvdgerbrandvd Member Posts: 10
    Thanks for the replies all, I neglected to login to the forum for a while after my initial posting.

    Blocks could become invalid because of forks. So maybe the clients should handle invalidation of events too, when a certain block (number) becomes invalid. Not certain how to implement that.
  • gerbrandvdgerbrandvd Member Posts: 10
    edited September 2015
    @Metal as far as I know events should be permanent, else that would imply the history of Ethereum-blockchain changes. When you start listing using web3 api for all events starting from block 0 you'll get all events again.
    In our (still in development-phase) code, each clients tracks for each event the blocknumber of the last received event. When the client restarts, it'll start listening from that blocknumber to avoid getting all old events again. We haven't added anything to handle forks though.

    I've created a gist with our (very preliminary) event handling:
    In our implementation the events are typed, rather than having a general message type as in @sillytuna example. I guess untyped messages are more convenient, as message in various event-libraries are usually untyped too.

    Might be interesting to convert into a OS project. Something like Ether Event Store?
  • sillytunasillytuna Member Posts: 38 ✭✭
    I confirmed with Vitalik and since confirmed by Chris that events are permanent. In future, some nodes may prune historic data.

    @gerbrandvd In my code I'm actually using typed messages based on a bytes32 string.

    re: Block changes. I haven't coded for this yet and I'm not entirely sure of the best way to catch inappropriate blocks. In general terms, I wouldn't consider a block valid for 12 blocks, so anything in the interim is pending data.

    This implications if you're sending ordered transactions to a contract because I guess they can be accepted in any order, the order could change if the chain you were on is superseded, and you need e.g. 12 blocks to be sufficiently sure.

    Does anyone know what happens with event reporting if the event was first reported on chain 1, then that chain becomes superseded and a more recent block has the same 'event'? I guess you get the same event again although it'll only be in the blockchain once.

    My colleague just suggested only looking for events and calling contracts 12 blocks away from the current block if providing accurate results, and using the most recent block for pending results.

  • gerbrandvdgerbrandvd Member Posts: 10
    @sillytuna not wanting to start a discussion on static/stong/dynamic types :smile: I mean a general type, rather then a specific type per type of message

    I guess the 12 blocks is arbitrary? I guess for each new block, the chance a certain block in the past gets exponentially smaller. What would the chance be 12 blocks in the past would be a fork?
  • gerbrandvdgerbrandvd Member Posts: 10
    edited September 2015
    As a related remark, I ran into an unfortunately problem of missing events suddenly, related to what's discussed at

    *Update in case someone later reads this message: Reason was nonce was not always unique for call-transactions. Not certain what the root cause is, might be related to web3. Back on topic
    Post edited by gerbrandvd on
  • sillytunasillytuna Member Posts: 38 ✭✭
    On the topic of confirmation, it's worth reading about ghost's different way of dealing with it:
Sign In or Register to comment.