Monday, June 4, 2018

Solidity Pitfalls: Random Number Generation for Ethereum

This article was created in partnership with iOlite. Thank you for supporting the partners who make SitePoint possible.

Solidity is a fairly new language and as no code is perfect, it contains issues related to the code and what you want to accomplish with it. This article will guide you through the best practices and pitfalls when using a random number as input for your Ethereum smart contract.

Solidity Random Number Generation

Solidity is not capable of creating random numbers. Actually, every algorithm for creating random numbers is pseudorandom — no language is capable of creating completely random numbers. The problem with Solidity is that complex algorithms cost too much, so more basic solutions are used. Besides that, Solidity code should be deterministic, as it will run on multiple nodes. We need an algorithm that is able to generate a random number once, and use it on multiple nodes. Things like a clock time are not available for generating random numbers, so we have to look at other options. As a developer, you should be aware of this problem because an attacker is able to predict the result in some specific cases.

One of the most commonly used algorithms is ‘linear congruential generator’ (LCG). It’s one of the oldest algorithms, fast, and easy to understand. LCG is a good option for embedded systems as they have a limited amount of memory. However, it is not well-suited for cryptographically secure applications. Although, this is still being used in smart contracts as a fast algorithm is much cheaper to implement in terms of gas costs.

The algorithm itself performs these steps:

  • Accept input
  • Execute algorithm on the input
  • Take modulus of output (divide by max number in the range you require)
  • Output between 0 and max number in the range you require

Let’s explore the different ways of creating random numbers using a Lottery smart contract example. Users are able to join the Lottery by sending 0.1 Ether to the contract together with an integer between 0 and 250.

1. Block.timestamp & Block.difficulty

A block.timestamp is assigned by the miner whenever he confirms the transaction. No player of our Lottery contract is able to control it. Let’s take a look at this piece of code for creating a random number.

function random() private view returns (uint8) {
       return uint8(uint256(keccak256(block.timestamp, block.difficulty))%251);
   }

Find the Gist here.

This piece of code first hashes a block timestamp and difficulty. Next, we convert the hash to an integer and divide it by 251 to get an integer between 0 and 250. However, the problem with this piece of code is that we shouldn’t trust a miner for picking a winner.

2. Lottery Input - Arbitrary Data

We need more arbitrary data for picking our winner. We can use the addresses of the players that have entered our lottery smart contract, but we have to hide it from other players as they can abuse it. Hiding this information is not possible as it’s all recorded on the blockchain.

The numbers submitted to our lottery smart contract can be used. Users have to hash the number they pick together with their Ethereum address. This gives us a pretty random number.

3. Other Mechanisms

The post Solidity Pitfalls: Random Number Generation for Ethereum appeared first on SitePoint.


by Michiel Mulders via SitePoint

No comments:

Post a Comment