As is well known by this point, this formula for churning out random numbers is vulnerable to miner attacks and the like. Block variables can be manipulated and any amount
of complex math can be reverse engineered.
To build a genuine on-chain random number, the random number generated must be a function of values that neither the contract, nor the caller know before the caller calls a random number generator function. Moreover, these 'unknown' values must be terribly hard to manipulate and fix, beforehand.
Tellor helps us accomplish both. This project leverages 1) Tellor's nature as an oracle, providing a periodically updating feed of values not known beforehand, and 2) the security provided by Tellor's proof of work system.
Let's say a protocol like Pool Together wishes to use this RNG. Simply put, the flow will be as follows:
generateRandomNumberwhen the number is available.
generateRandomNumberpost a new price update. I have an express server listening for the
NewValueevent on Tellor's core contract on Rinkeby, here.
A major part of the effort went into the architecture of the random number generator. I spent a long time thinking about wha complicated math formula mixed with block dependent variables and Tellor price feed values would produce a good amount of randomness. As I later realized, this was all futile. I took a deep dive into how miners can perform attacks that manipulate block variables and reverse engineer math formulas that depend on them.
The second biggest challenge was to engineer good UX. Generally, one expects a random number generatos to spit out a random number instantly, upon request. Since the each Tellor block is only mined every 30-40 minutes, as of now, a new source of randomness would only be available every 30-40 minutes.
In the end, I decided that such a periodical andom number generator only makes sense with a random number receiver to go along with it, which it cal call whenever a new source of randomness is available i.e. when a new Tellor update happens.