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

openssl rand 32 -hex

Step 2: Generate sha256 hashes

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

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

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@active	

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

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@active

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

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 ) {
} else {

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.