3

I'm working on a project that allows users to automatically deploy a specific contract that I created. It's important for the system to be able to listen to specific events (for example, new transaction) on ALL deployed contracts.

Note: I'm using nodejs through web3 json rpc to monitor events.

One possible solution I thought of is to use a wrapper contract that tunnels all transaction requests and sends the events itself. This will allow to only listen to events from a single contract but I don't find that solution very elegant.

Is there an efficient and scalable way to accomplish that without creating a listener on each specific contract?

2

It sounds like the concern is listeners could multiply in a way that might not scale. There's no silver bullet that I'm aware of that would let a single listener filter events like you would need. This third way is a variant of the two options I understand you are considering.

Consider handling transactions the way you want to, and adding logically centralized logging functions. For example, the contract factory. Arrange things so factory-created contracts rely on the centralized logging functions instead of internal event emitters.

If you have:

contract Factory { ...
contract Created {
  event LogSomething(bytes32 Id); 
  ...
  LogSomething(Id);

Re-arrange as

contract Hub {
  event LogSomething(address contract, bytes32 Id);
  ...
  function logSomething(bytes32 Id);
    LogSomething(msg.sender, Id); // msg.sender will be the "spoke" that called Hub function.

contract Created{ 
   ...
   function important(bytes32 id) {
      .. 
      Hub.logSomething(Id);

Factory should probably be called Hub in the case that it's relied upon for more than just minting contracts.

Hope it helps.

  • Initially I thought that we'd want to monitor events that are generated by contracts that were deployed outside the system as well but I guess that might be too much and maybe not even necessary. So the solution you suggest might actually work for us. Thanks! – nergall Jan 3 '17 at 13:18
  • Actually now that I put more thought into it, it might still be a problem, because that means that anyone can dispatch events from the hub without the hub's permission. One way to solve that would be to have the hub keep a list of contracts that are 'allowed' to use the hub's logging mechanism, but I'm not sure if that's something that's accepted as a clean solution. Is it? – nergall Jan 3 '17 at 13:27
  • You're right about securing. On further thought, I realized that this is hard to say if your app should use a single contract, a hub & spoke, or something else. I would tend to agree that when it get too convoluted, it's a sign things are off track. – Rob Hitchens - B9lab Jan 3 '17 at 20:16
  • There another way to consider. You can use an upgradable contract structure that pushes data through an data controller contract separate from application logic. Possibility of central point of logging into there. – Rob Hitchens - B9lab Jan 3 '17 at 20:17
  • 1
    You can have a registry of authorized users. It's a natural extension of a factory that keeps track of the contracts created. This hub is pretty close: ethereum.stackexchange.com/questions/10878/…. If we wanted a Hub function that was only accessible by the offspring contracts (Persons in the example), we could have a modifier: modifier onlyPerson() { if(persontIndex[personMap[msg.sender]] != msg.sender) throw; _; // this will be true if the Hub created the msg.sender. } Hope it's helpful. – Rob Hitchens - B9lab Jan 4 '17 at 8:51
2

web3.eth.filter() (the low-level method, not the kind you can get from contract objects) allows one to specify a list of addresses to listen to with one filter. You'll have to manually interpret the topics, but that shouldn't be too difficult.

Watching for when a contract is created (so you know what addresses to listen to) is somewhat harder. You can use the same method without specifying a list of addresses, and then use the topics argument to make sure you're only getting events from contracts claiming to be yours. The distinction is important--anyone can make an event say anything, so it would be wise to verify it came from a contract that has your code.

  • In my specific case, I think it would be reasonable to only intercept events that are generated by contracts that were created through the system, so that should make it easier. It's still not great to have to listen to multiple addresses though, since that can eventually grow and then we have the scalability issue again. – nergall Jan 3 '17 at 13:16

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.