Nowadays, there are numerous platforms on the internet where millions of users invest their money to win huge prize money or rewards by giving just a fraction of it. One such example is HypeDrop, where a user can open mystery boxes that may cost anywhere between $1 undefined $20k. These boxes consist of exorbitant rewards, and there might be debate about the chances of getting a fair result. This also applies to your favourite casino if it is fair enough to you or not?
Here comes in the picture Provably Fair Algorithm. Let’s see what is provably fair and how it is implemented on blockchain.
Provably fair is a technique that makes sure that a generated number was truly random without any manipulation done to get this number. It guarantees the user and, enables them to verify that the generated result is randomly generated and not manipulated.
This algorithm takes in the following parameters to make sure the true nature of randomness:
We have seen that Provably Fair itself is a fair method to generate random numbers. However, to add a bit more fairness, we can implement this in Solidity and deploy it on the Ethereum network in the form of a Smart Contract.
A smart contract is a simple program stored on the blockchain and can be accessed using the contract address. Since the smart contract is stored on the blockchain, it is immutable and cannot be modified in the future. This blockchain feature makes sure that the deployed functions are not altered.
The smart contract does not generate its server_seed to minimize the gas fees. This may seem a little skeptical, however, we can add a server to compensate for it.
The first step is to generate the client_seed. We are writing the random string generation code in javascript.
function randomString(length) { const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; let random = ''; for(let i = 0; i undefined length; i++) { random += chars[Math.floor(Math.random() * chars.length)]; } return random; }
We can pass in a length in this function and generate a random string
randomString(30) // jd2X84dcjgUvIacaR4mVWssotfzIe3 randomString(30) // X3X6cWFGhwxAZbgZzldfHYed6ERIzw
Now we have the client_seed.
The same function can be implemented on the server-side as well to generate a random string that can be passed to the contract. Nonce will be available with the server. These parameters will then be passed to the contract.
Let’s have a look at the contract function that we are going to use and see how it generates a random number
function getRandomNumber(string memory client_seed,string memory server_seed, uint nonce) public pure returns(uint) { string memory hashed_server_seed = toHex(sha256(abi.encodePacked(server_seed))); string memory combination = string(abi.encodePacked( uint2str(nonce),'-',client_seed,'-',hashed_server_seed)); bytes memory hashed_combination = bytesToSHA3_512(abi.encodePacked(stringToBytes32(combination))); return getResult(hashed_combination); }
The getRandom() function takes in the parameters; client_seed, server_seed, and nonce. It then performs the following operations:
function getResult(bytes memory hashValue) internal pure returns (uint){ bytes memory result = extractSig(hashValue, 0, 6); uint randomNumber; randomNumber = bytesToUint(result); return (randomNumber%10000)/100; }
We will create a contract.js file to make a connection with our contract. For achieving this, we are going to install the web3 package:
The deployment of this contract has already been done using truffle on the Ropsten network (not covered in this blog)
To install this write:
npm install –save web3
After successful installation of the package, we will import the same and create an instance of web3 by giving it an appropriate provider and creating a variable for our contract address. In our case, we are using Infura as our provider.
var Web3 = require("web3"); let web3 = new Web3(new Web3.providers.HttpProvider('https://ropsten.infura.io/v3/')); var addr = "";
To make a connection with the contract, we will need the contract address as well as the ABI (Application Binary Interface) of the contract.
ABI is a human-readable representation of the program’s interface, which defines the methods used to interact with the contract.
When deployed with truffle, the contract’s ABI can be found within the JSON file of the contract, which can be found in the build/contracts folder of the project.
We now declare a new variable abi and pass the ABI of the contract to it.
var abi = [ { inputs: [ { internalType: "string", name: "client_seed", type: "string", }, { internalType: "string", name: "server_seed", type: "string", }, { internalType: "uint256", name: "nonce", type: "uint256", }, ], name: "getRandomNumber", outputs: [ { internalType: "uint256", name: "", type: "uint256", }, ], stateMutability: "pure", type: "function", constant: true, }, ];
Now let’s make a connection to the contract and call the getRandom() function to generate the random number.
var ProvablyFair = new web3.eth.Contract(abi, addr); ProvablyFair.methods .getRandomNumber( "jd2X84d1jvUvIqcaRFmVWIsot2zIeH", "XaX6MWShOwxAZbggz4dfTYVd6EuIzw", 1 ) .call() .then(console.log);
Then we call the contract.js using the node command and see the final output
Output:
undefined node connection/contract.js undefined 18
With the slightest change in the input parameters, the generated output gets changed. This is what defines the truly random nature of Provably Fair.
In conclusion, Provably Fair is the Golden Standard when it comes to online gambling as it is developed in a way that allows the players to verify the randomly generated number and gives the platform a level of trust as both the site manager and the players know the outcome before the game starts.
We, at Seaflux, are enthusiasts who are helping enterprises worldwide. Have a query or want to discuss Blockchain projects? Schedule a meeting with us here, we'll be happy to talk to you!
Director of Engineering