Barbooth.Bet
Search…
⌃K

# Provably Fairness

### Provably Fair

It's easy for a casino to cheat your game. For that reason "Provably Fair" solutions used for a trustless and transparent environement. Provably fair basically means, If a player can reach the same result that the casino does by calculations made by the casino.

### Is BarboothGame Provably Fair and How ?

BarboothGame is a provably fair game. Because of the nature of BSC network every transactions and calls to the contract is transparent and also contract's state can be readable from anywhere in the world. So you can query any room info that you want to calculate just by going to one of the BarboothGame contract at bscscan.
Querying a finished game result
When you query a room info there is a `rngResult` field in the contract. This number is used to calculate the game result.
This is how smart contract calculates of a room result:
uint256 turn = 0; // 0 => creator, 1 => opponent
uint8 nonce = 0;
uint256 randomNumber = _rooms[roomId].rngResult;
uint8[2] memory healths = [3, 3]; //healths[0] => creator, healths[1] => opponent
uint8[2] memory dices = [0, 0]; // Rolled dice for that turn
while (healths[0] > 0 && healths[1] > 0) {
dices[0] = uint8(randomNumber.div(6).mod(6).add(1)); // First dice number that rolled
dices[1] = uint8(randomNumber.div(6**6).mod(6).add(1)); // Second dice number that rolled
if (dices[0] == 6 && dices[1] == 6) healths[(turn + 1) % 2] = 0;
else if (dices[0] == 5 && dices[1] == 5)
healths[(turn + 1) % 2] = 0;
else if (dices[0] == 3 && dices[1] == 3)
healths[(turn + 1) % 2] = 0;
else if (dices[0] == 4 && dices[1] == 4) healths[turn] = 0;
else if (dices[0] == 2 && dices[1] == 2) healths[turn] = 0;
else if (dices[0] == 1 && dices[1] == 1) healths[turn] = 0;
else if (
(dices[0] == 6 && dices[1] == 5) ||
(dices[0] == 5 && dices[1] == 6)
) healths[(turn + 1) % 2]--;
else if (
(dices[0] == 2 && dices[1] == 1) ||
(dices[0] == 1 && dices[1] == 2)
) healths[turn]--;
turn = (turn + 1) % 2;
randomNumber = uint256(
keccak256(abi.encode(randomNumber + uint256(nonce)))
);
nonce++;
}
Basically this code block increases `nonce` value for each turn and generates a new `randomNumber` based on `rngResult + nonce` and calculates dice numbers based on that generated `randomNumber`.

### How rngResult field is calculated ?

RNG Result field is calculated based on two things. Room seed and the algorithm of the RNG Source that requested.

#### Room Seed

Room seed is generated by the players that participate in a room. Firstly room creator's randomly generated seed (by the browser he/she uses) written in to room info. After a opponent joins room creator's and opponent seeds added side by side and hashed with keccak256 algorithm. Result of this keccak256 algorithm converted to an uint32 number.
// _createRoom function
Room memory room =
Room(
creator,
RoomStatus.WAITING,
seed, // Creator seed
0,
roomType
);
_rooms.push(room);
// _joinRoom function
uint256 bigSeed = uint256( // Convert the result of keccak256 to a uint256 seed
keccak256( // Convert them to a keccak256 hash
abi.encodePacked( // Add them side by side
room.seed, // Room's creator seed
seed // Opponent seed comes from function's argument
)
)
);
room.seed = uint32(bigSeed); // Convert the bigseed to an uint32 number for reducing gas fee
Rng source takes this room.seed as a parameter and makes a calculation of the final result of the room.