How to generate random numbers in solidity?
Generating truly random numbers in Solidity is difficult. There isn’t any dedicated function that returns random numbers, and even if there were, like in other programming languages, those numbers would only be pseudorandom because no language is capable of generating completely random numbers. In smart contracts, we’ll use the classical way of generating a random number in Solidity. Don’t use it blindly in applications that involve real money because once you have written the contract code, it can’t be altered. You can experiment with the Goerli testnets. So, we’ll create our own function called “random,” which will return a very big pseudorandom integer.
pubilc random view returns(uint)
Keccak Algorithm
We declare the function as being public so it can be easily called from Remix, but it can be internal as well. It returns a random unit number. Now we’ll call the keccak256() function that will compute the hash of the input using the keccak256 hash algorithm. This function takes a single argument of type bytes, and since we want my random number to be computed based on more random values, we will call another function called abi.encode.Packed() is the function that will perform packed encoding of the given arguments and return a variable of type bytes. The function’s arguments are: (msg. sender), (block. timestamp), and our variable, which can also include (block. difficulty) with other global variables to make it more complex.
“block. difficulty” is the proof of work difficulty of the current block; “block. timestamp” is the Unix timestamp of the current block; it returns the number of seconds since January 19, 1970, called the UNIX epoch; “msg. sender” is the person; it’s the contract that is calling that function. By using the Keccak algorithm, which converts from byte code to hash code, it returns 64 digits as a hexadecimal number and makes it more random. But the problem is that the hash code also contains some random characters, so for that we use a unit function to remove them. The blockchain is constantly growing, so all of these values will be random for each call. So for the demo, we will use the remix IDE for Solidity. We will create a file named “Random.so” and then we will write the code in it.
//SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.7;
contract RandomNumber {
uint randNo = 0;
function setNumber() external {
randNo= uint (keccak256(abi.encodePacked (msg.sender, block.timestamp, randNo)));
}
function getNumber() external view returns (uint) {
return randNo;
}
}
Code language: JavaScript (javascript)
Output:
uint256: 80271414388527399068529281752425538401261731779851136523706403025547299486379
Code language: HTTP (http)
So, once deployed, we click getNumber, which returns zero by default, then we click setNumber, which returns a large number, and we can see it by clicking getNumber, as shown in the image below.
So we have a random number from zero to thousand, which we can get by using the modulo operator.
function setNumber() external {
randNo= uint (keccak256(abi.encodePacked (msg.sender, block.timestamp, randNo)))%1000;
}
Code language: JavaScript (javascript)
Output:
We have gotten a 962 number using the modulo operator; in this way, we can generate random numbers in solidity.
Conclusion
A random number system needs to be strong enough that even if an attacker knows exactly how you are creating the random numbers, the system remains unpredictable. In order to generate a truly random number in Solidity, a seed must be sent to an off-chain resource, such as an oracle, which must then return the generated random number and verifiable proof to the smart contract. In smart contracts, the recommended way of generating random numbers that deal with large amounts of ether is to use something called Chainlink VRF.
Sharing is caring
Did you like what Nithin Reddy wrote? Thank them for their work by sharing it on social media.
No comments so far
Curious about this topic? Continue your journey with these coding courses: