Last active
February 10, 2021 17:33
-
-
Save gerbrand/cffdc118fef997d9bde6 to your computer and use it in GitHub Desktop.
Using Ethereum as an Event Store. See https://forum.ethereum.org/discussion/3243/events-in-solidity-using-blockchain-as-eventstore#latest
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Creating a Mongo collection to keep track of events | |
EthEvents = new Mongo.Collection('ethEvents'); | |
EthEvents.attachSchema(new SimpleSchema({ | |
contractAddress: { | |
type: String, | |
index: true | |
}, | |
eventName: { | |
type: String, | |
index: true | |
}, | |
blockNumber: { | |
type: Number, | |
min: 0 | |
} | |
})); | |
EthEvents.watchEvent = function (contractInstance, eventName, onEvent) { | |
if (!Contracts.useWeb3) { | |
return; | |
} | |
//What's the blocknumber of the event we've received before the restart? | |
var previous = EthEvents.findOne({ | |
contractAddress: contractInstance.address, | |
eventName: eventName | |
}); | |
//TODO handle forks | |
var fromBlock = previous ? previous.blockNumber + 1 : 0; | |
var options = { | |
'address': contractInstance.address, | |
'fromBlock': fromBlock | |
}; | |
var updateFromBlock = function (err, event) { | |
//First update mongodb, then execute onEvent handler. Should mongo crash or fail, at least we re-receive the latest event | |
EthEvents.upsert({ | |
contractAddress: contractInstance.address, | |
eventName: eventName | |
}, { | |
$set: { | |
blockNumber: event.blockNumber | |
} | |
}, function (dbError) { | |
if (!dbError) { | |
onEvent(err, event); | |
}; | |
}); | |
}; | |
var contractEvent = contractInstance[eventName]; | |
contractEvent({}, options).watch(Meteor.bindEnvironment(updateFromBlock)); | |
console.log("init filter event", eventName, "of contract", contractInstance.address, "from block", fromBlock); | |
}; | |
//TODO add proper error handling. Do something with success and failure returns in the Ethereum contracts also | |
EthEvents.handleCall = function (onSuccess) { | |
return Meteor.bindEnvironment(function (e, tx) { | |
if (!e) { | |
onSuccess(tx); | |
} else { | |
console.log("Failed to call Ethereum", e); | |
} | |
}); | |
}; | |
//You can watch events using the following code: | |
/* | |
EthEvents.watchEvent(MyContracABI, "<EventName>", myHandler); | |
MyContractABI is an contract instance, Eventname is of course the name of the even. MyHandler is a simple function with params (err, event) to handle the event. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment