Build & Compile Your WAX RNG Contract

In this example, we’ll create a smart contract that uses the WAX RNG service to generate a random number no larger than 100. This number gets written to a multi_index table, along with an internal Customer ID, the customer’s signing_value, and the checksum256 random_value returned from the WAX RNG oracle.

Create Your Contract

  1. From the command line, navigate to your smart contracts directory. For this example, we’ll use mycontracts.

  2. Use eosio-init with the -project parameter to create your smart contract template.

    eosio-init -project waxrng
  3. From your smart contracts folder, open waxrng/include/waxrng.hpp and paste the following:

    #include <eosio/eosio.hpp>
    #include <string>
    #include <tuple>
    
    CONTRACT waxrng : public eosio::contract {
       public:
          using eosio::contract::contract;
          //this example uses a multi_index table to store user information.
          //in the line below, make sure to define a default constructor for this table 
          waxrng(eosio::name receiver, eosio::name code, eosio::datastream<const char*> ds)
              : contract(receiver, code, ds), rngcustomers(receiver, receiver.value) {}
    
          //actions available for our RNG smart contract
          ACTION getrandom(eosio::name nm, uint64_t customer_id, uint64_t signing_value);
          ACTION receiverand(uint64_t customer_id, const eosio::checksum256& random_value);
    
          //table structure
          TABLE rngcustomers_table{
            eosio::name nm;
            uint64_t customer_id;
            eosio::checksum256 random_value;
            uint64_t finalnumber;
            uint64_t primary_key() const { return customer_id; }
          };
    
          //define table based on table structure
          typedef eosio::multi_index<"rngcustomers"_n, rngcustomers_table> rngcustomers_index;
    
          //action wrappers
          using getrandom_action = eosio::action_wrapper<"getrandom"_n, &waxrng::getrandom>;
          using receiverand_action = eosio::action_wrapper<"receiverand"_n, & waxrng::receiverand>;
    
          //set our table to 'rngcustomers' variable
          rngcustomers_index rngcustomers;
    };
    
  4. Next, open src/waxrng.cpp and paste the following:

    #include <waxrng.hpp>
    
    using namespace eosio;
    
    //call the WAX RNG requestrand action
    ACTION waxrng::getrandom(name nm, uint64_t customer_id, uint64_t signing_value) {
    
        //check if this customer_id exists in the table
        auto itrCustomer = rngcustomers.find(customer_id);
        //if not, insert a new record
        if (itrCustomer == rngcustomers.end()) {
            rngcustomers.emplace(_self, [&](auto& rec) {
                rec.customer_id = customer_id;
                rec.nm = nm;
            });
        }
        
        //call orng.wax
        action(
            { get_self(), "active"_n },
            "orng.wax"_n,
            "requestrand"_n,
            std::tuple{ customer_id, signing_value, get_self() })
            .send();
    }
    
    // Called automatically by 'orng.wax' smart contract when the RNG Oracle
    // has generated the random value. wax.orng, before calling this action,
    // verifies that the generated random value was signed with the
    // provided "signing_value"
    ACTION waxrng::receiverand(uint64_t customer_id, const checksum256& random_value) {
    
        //cast the random_value to a smaller number
        uint64_t max_value = 100;
        auto byte_array = random_value.extract_as_byte_array();
    
        uint64_t random_int = 0;
        for (int i = 0; i < 8; i++) {
            random_int <<= 8;
            random_int |= (uint64_t)byte_array[i];
        }
    
        uint64_t num1 = random_int % max_value;
    
        //find the customer record by customer_id
        auto itrCustomer = rngcustomers.find(customer_id);
        //make sure the record exists
        check(itrCustomer != rngcustomers.end(), "customer table not set");
        //update the random numbers by customer_id
        rngcustomers.modify(itrCustomer, _self, [&](auto& rec) {
            rec.random_value = random_value;
            rec.finalnumber = num1;
        });
    
    }
    
    EOSIO_DISPATCH(waxrng,
    (getrandom)
    (receiverand)
    )
    

Compile Your Contract

  1. From the command line, navigate to waxrng/build and run cmake.

    
    cmake ..
    
  2. Build the scripts.

    
    make
    

You can locate the wax.wasm and wax.abi files in the build/waxrng folder.