Smart Contracts

The EOS C++ SDK Developer Hub

Welcome to the EOS C++ SDK developer hub. You'll find comprehensive guides and documentation to help you start working with EOS C++ SDK as quickly as possible, as well as support if you get stuck. Let's jump right in!

Get Started    

Randomization in Contracts

By using openssl, sha256 and checksum256, a value can be produced that is deterministic and effectively random. This can be achieved by hashing (sha256) n number of hashes and their corresponding secrets and then selecting n number of values from the result. The determinism and randomness comes from having an outside source supply a hash and its corresponding secret.

In the example of two users wanting to play a game with 50/50 odds, each player must first submit a hash of their secret. By submitting their hash, they then become eligible to play the game. Once both players have submitted the hash of their secret, they are effectively engaged in the game. It's only when both players reveal their secrets that both of their submitted hashes and recently submitted secrets are hashed. From the result of this hash, two numbers are selected to determine a winner and a loser.

Step 1: Generate Secrets

openssl rand 32 -hex
28349b1d4bcdc9905e4ef9719019e55743c84efa0c5e9a0b077f0b54fcd84905

openssl rand 32 -hex
15fe76d25e124b08feb835f12e00a879bd15666a33786e64b655891fba7d6c12

Step 2: Generate sha256 hashes

echo -n '28349b1d4bcdc9905e4ef9719019e55743c84efa0c5e9a0b077f0b54fcd84905' | xxd -r -p | sha256sum -b | awk '{print $1}'
d533f24d6f28ddcef3f066474f7b8355383e485681ba8e793e037f5cf36e4883

echo -n '15fe76d25e124b08feb835f12e00a879bd15666a33786e64b655891fba7d6c12' | xxd -r -p | sha256sum -b | awk '{print $1}'
50ed53fcdaf27f88d51ea4e835b1055efe779bb87e6cfdff47d28c88ffb27129

Step 3: Submit Hash of Secret

Alice and Bob each submit their hash of their secret.

cleos push action chance submithash '[ "alice", "d533f24d6f28ddcef3f066474f7b8355383e485681ba8e793e037f5cf36e4883" ]' -p alice

cleos push action chance submithash '[ "bob", "50ed53fcdaf27f88d51ea4e835b1055efe779bb87e6cfdff47d28c88ffb27129" ]' -p bob

Step 4: Submit Secret

Alice and Bob each submit the hash of their secret and the secret itself.

cleos push action chance submitboth '[ "d533f24d6f28ddcef3f066474f7b8355383e485681ba8e793e037f5cf36e4883", "28349b1d4bcdc9905e4ef9719019e55743c84efa0c5e9a0b077f0b54fcd84905" ]' -p alice

cleos push action dice submitboth '[ "50ed53fcdaf27f88d51ea4e835b1055efe779bb87e6cfdff47d28c88ffb27129", "15fe76d25e124b08feb835f12e00a879bd15666a33786e64b655891fba7d6c12" ]' -p bob

Step 5: Conclusion

The simplest data type that can be used to store the secret and the hash of the secret is a struct.

struct player {
  checksum256 hash;
  checksum256 secret;
};

When the players of the game are being instantiated, it is important to do so in succession. This is done so that the secrets and hashes for all the players are contiguously stored in memory.

struct game {
	uint64_t id;
  player player1;
  player player2;
}

Once the secret and the hash of the secret are received for all the players, the hashing of it all can be done.

// variable to get result from hashing all players hashes and secrets
checksum256 result;

// hash the contents in memory, starting at game.player1 and spanning for 
// sizeof(player)*2 bytes
sha256( (char *)&game.player1, sizeof(player)*2, &result);

// compares first and second 4 byte chunks in result to determine a winner
int winner = result.hash[1] < result.hash[0] ? 0 : 1;

// report appropriate winner
if( winner ) {
  report_winner(game.player1);
} else {
  report_winner(game.player2);
}

It's important to note that sha256 is 32 bytes and that there are 8 chunks of uint32_t in it. In the above example, the first two are considered, but it could have been any of them.


Randomization in Contracts