Cyclone v0.1
  • Overview
    • 🌀Cyclone Chain
      • Vision & Mission
      • Technology overview
      • Consensus Mechanism
      • Security Mechanisms
      • Industry Use Cases
      • Team
  • Gamechanging
    • Coinless Interaction Model
    • Universal Development Adoption
    • 🪙Economics
      • Dynamic Emission Model
      • CYCL coin
      • COT Token & Validators
    • DRNG - Decentralized Random
  • ECOSYSTEM
    • Testnet & Drop
      • Infinity Drop Event
    • Wallets
    • Products
  • 🧰develop
    • Tools & utilities
    • Node Architecture
    • Documentation
      • Technical Specification of Formats
      • Smart Contracts & Virtual Machines
      • Default Virtual Machine
    • Swagger
    • Tutorials
      • Your First Smart Contract
      • Simple contracts: Game of Dice
      • Your First Coin
      • Your First NFT
  • 🖖Community
    • Official links
    • Roles
  • Privacy Policy
    • Privacy Policy Cyclone Wallet
    • Terms of Use for "Cyclone Wallet"
Powered by GitBook
On this page
  1. develop
  2. Tutorials

Simple contracts: Game of Dice

PreviousYour First Smart ContractNextYour First Coin

Last updated 7 months ago

Let's write game of dice simulation. Rules are the following:

  1. There is an usual six-sided dice. Player can can bet some amount of coins on a roll result.

  2. If player tries to bet more coins than he actually has, he will lose all his coins (meaning they'll be transfered to game's contract). Dice roll result will be ignored.

  3. The value that player bets on has to be an integer in range [1,6]. Otherwise, player will be fined double the fee and roll result will be ignored.

  4. If player guesses roll result, he'll get half of his bet on his account.

  5. If he loses, amount of his bet will be transfered to contract's balance.

We'll need to use a couple of pre-build vm functions here:

  • getSender() - returns caller's (player's) wallet hash as a string.

  • addCustomField(key, value) - adds key-value pair to vm's response (tx->vmr->C).

  • getBalance(hash).Int64() - returns integer amount of coins on a balance of a wallet identified by given hash.

  • getContractHash() - returns hash of a contract which calls it.

  • currentFee() - returns integer amount of fee for executing contract. Does not work in a simulation (returns undefined).

  • transfer(hash, amount) - transfers the specified amount of coins to a wallet identified by a given hash from sender's account.

  • transferFromContract(wallet, amount) - transfers the specified amount of coins to a wallet identified by a given hash from current contract's (caller contract) balance.

So we need to write a function, that takes two arguments: roll value player bets on (betOn) and amount of his bet (betAmount). Here's it's code:

function gameOfDice (betOn, betAmount){
    var wallet = getSender();
    var winMult = 1.5;
    var feeMult = 2;
    var diceMin = 1;
    var diceMax = 6;
    var diceRoll = parseInt(Math.random() *(diceMax - diceMin + 1) + diceMin);
    addCustomField('roll', diceRoll); //to display roll's result
    var playerBalance = getBalance(wallet).Int64();
    var message = '';
    if (typeof betOn !== 'number' || parseInt(betOn) != betOn || betOn < diceMin || betOn > diceMax) { //condition 3
        message = 'Bet value is out of expected range [' + diceMin + ', ' + diceMax + '] or not integer';
        transfer(getContractHash(), currentFee() * feeMult);
    }
    else if (playerBalance < betAmount) { //condition 2
        message = 'Insufficient funds';
        transfer(getContractHash(), playerBalance - currentFee());
    }
    else if (diceRoll == betOn){ 
        message = 'You won!';
        var contractBalance = getBalance(getContractHash()).Int64();
        var target = betAmount * (winMult - 1);
        transferFromContract(wallet, contractBalance >= target ? target : contractBalance);
    }
    else { 
       message = 'You lose!';
       transfer(getContractHash(), betAmount);
    }
     ddCustomField('message', message);
}

If simulations went fine, it's time to save your contract (don't forget to remove function call before saving):

To put a few coins from your wallet on a contract's balance:

transfer('f4e481ae740161127561c3455412f1687f9a09b6ce0d9938d528caad82ea7a3d', 100)

Use "deploy" button:

Contract balance can be checked at any time by simulating the following code:

addCustomField('balance', getBalance('f4e481ae740161127561c3455412f1687f9a09b6ce0d9938d528caad82ea7a3d').Int64())

Finally, you can play your game by using callContract() function:

callContract('f4e481ae740161127561c3455412f1687f9a09b6ce0d9938d528caad82ea7a3d', 'gameOfDice', 3, 20)

Run a simulation with a function call before saving contract to avoid unnecessary waste of coins. Before running a simulation, make sure that there are some coins on your wallet's balance. Otherwise you'll get "insufficient balance" error. Free test coins can be gained .

Note that it's better to turn "base64" switch on, or some basic things like comparison operators may not work and cause simulation failure. You can get answers to your questions about Otto js (which is default VM) features and limitations .

You can always find your contract in our Blockchain Explorer in a or in a .

🧰
Pre-build functions docs.
here
here
history of your transactions
transaction search section
cyPlay developer tool
cyPlay developer tool
history of your transactions
transaction search section
cyPlay developer tool
cyPlay developer tool
cyPlay developer tool