Monthly Archives: July 2016

An Ethereum Project (5) – Randomness

As mentioned before, randomness in a deterministic system like the blockchain is very hard to achieve and there is a lot of discussion on the Ethereum chats about how best to go about it.
In practical terms, this means that something that in any programming language is as simple as calling a Rand() function, in Solidity turns into a major headache.

Randao

In order to try to get a true random number for our draw, we had a look at Randao.

What is it?

Broadly speaking, it is like a way of crowdsourcing randomness! Here’s my understanding of how it works:

An instance of randao.sol (call it contract C) will exist somewhere in the blockchain.

Random Number Generation then happens in (block) cycles.

In the first cycle (within a certain period of time counted in mined blocks), people who want participate send a given amount of ETH (a pledge) to the contract along with a secure hash (sha3) of a number s.

In the second cycle, those same people have to send the actual number s to the contract. These are verified against their sha3 and stored.

After all secret numbers have been successfully collected, the contract will calculate the random number using all the values s1…sn that it has collected (so in effect s1..sn is a way of collecting entropic values). The result will be written to the storage of C, and the result will be sent to all other contracts that requested the random number.

Contract C will send back the pledge to the participants in the first phase, and the profit is divided into equal parts and sent to all participants as an additional bonus. The profit comes from the fees paid by all the other contracts that consume the random number.

We tried running a test using the instructions provided, but have to confess that we failed. I think it was partly because we were deploying it on the Morden network and not in a private testnet, so the block cycles happened too fast.

In any case, it appears to be a clever, but incredibly complex, way to generate a random number.

Oraclize

Next, we tried Oraclize.

What is it?

Basically a pay-as-you-go service that claims to be a bridge between the Ethereum DApps and the outside world. In particular, for our present use case, they provide a link to Wolfram Alpha which, conveniently, is good at generating a random number.

Oraclize uses the ability of Solidity contracts to inherit from other contracts. All we had to do is import their usingOraclize contract into our own draw contract definition. Then it was just a matter of changing our contract from:

contract draw {

to:

contract draw is usingOraclize {

and voila, we had access to the outside world via Oraclize!

We then used this line (see full documentation here) to go out to Wolfram Alpha and get a random number for our draw:

oraclizeId = oraclize_query("WolframAlpha", "random number between 1 and 1000");

Is that it?

Not quite. What the above line does is to send a call to another Ethereum contract, owned by Oraclize. Oraclize do their magic, get you the random number and then have to call you back to give it to you. So you prepare for that by creating a __callback function in your code, ready to receive it:

function __callback(bytes32 _id, string _result) {
       if (drawn) throw;
       if (oraclizeId ==0 || oraclizeId != _id) throw;
       drawn = true;
       actualDrawDate = now;
       winningNumber = parseInt(_result,10);
       Log_WinningNumberSelected(winningNumber);
    }

And then, that is it! You have your randomly generated winning number and you are good to go.

In effect we have subcontracted the random number generation, for a price, to a third party who can be, at least in theory, audited and proved to be trustworthy for this.

Conclusion (or TL;DR)

Generating random numbers in inside the Ethereum blockchain is hard.
Randao looks clever but it is complicated.
Oraclize cost money, but works perfectly well for our use case. (And, incidentally, they also provide a solution for another problem that is trivial anywhere else but is not supported by Solidity – turning a string into an integer)