pub fn func_pay_winners(ctx: &ScFuncContext, f: &PayWinnersContext) {

    // Use the built-in random number generator which has been automatically initialized by
    // using the transaction hash as initial entropy data. Note that the pseudo-random number
    // generator will use the next 8 bytes from the hash as its random Int64 number and once
    // it runs out of data it simply hashes the previous hash for a next pseudo-random sequence.
    // Here we determine the winning number for this round in the range of 1 thru MAX_NUMBER.
    let winning_number: i64 = ctx.utility().random(MAX_NUMBER) + 1;

    // Save the last winning number in state storage under 'lastWinningNumber' so that there
    // is (limited) time for people to call the 'getLastWinningNumber' View to verify the last
    // winning number if they wish. Note that this is just a silly example. We could log much
    // more extensive statistics information about each playing round in state storage and
    // make that data available through views for anyone to see.
    f.state.last_winning_number().set_value(winning_number);

    // Gather all winners and calculate some totals at the same time.
    // Keep track of the total bet amount, the total win amount, and all the winners.
    // Note how we decided to keep the winners in a local vector instead of creating
    // yet another array in state storage or having to go through lockedBets again.
    let mut total_bet_amount: i64 = 0_i64;
    let mut total_win_amount: i64 = 0_i64;
    let mut winners: Vec<Bet> = Vec::new();

    // Get the 'lockedBets' array in state storage.
    let locked_bets: ArrayOfMutableBet = f.state.locked_bets();

    // Determine the amount of bets in the 'lockedBets' array.
    let nr_bets: i32 = locked_bets.length();

    // Loop through all indexes of the 'lockedBets' array.
    for i in 0..nr_bets {
        // Retrieve the bet stored at the next index
        let bet: Bet = locked_bets.get_bet(i).value();

        // Add this bet's amount to the running total bet amount
        total_bet_amount += bet.amount;

        // Did this better bet on the winning number?
        if bet.number == winning_number {
            // Yes, add this bet amount to the running total win amount.
            total_win_amount += bet.amount;

            // And save this bet in the winners vector.
            winners.push(bet);
        }
    }

    // Now that we preprocessed all bets we can get rid of the data in state storage so that
    // the 'lockedBets' array becomes available for when the next betting round ends.
    locked_bets.clear();

    // Did we have any winners at all?
    if winners.is_empty() {
        // No winners, log this fact to the log on the host.
        ctx.log("Nobody wins!");
    }

    // Pay out the winners proportionally to their bet amount. Note that we could configure
    // a small percentage that would go to the owner of the smart contract as hosting payment.

    // Keep track of the total payout so we can calculate the remainder after truncation.
    let mut total_payout: i64 = 0_i64;

    // Loop through all winners.
    let size: usize = winners.len();
    for i in 0..size {

        // Get the next winner.
        let bet: &Bet = &winners[i];

        // Determine the proportional win amount (we could take our percentage here)
        let payout: i64 = total_bet_amount * bet.amount / total_win_amount;

        // Anything to pay to the winner?
        if payout != 0 {
            // Yep, keep track of the running total payout
            total_payout += payout;

            // Set up an ScTransfers proxy that transfers the correct amount of iotas.
            // Note that ScTransfers wraps an ScMutableMap of token color/amount combinations
            // in a simpler to use interface. The constructor we use here creates and initializes
            // a single token color transfer in a single statement. The actual color and amount
            // values passed in will be stored in a new map on the host.
            let transfers: ScTransfers = ScTransfers::iotas(payout);

            // Perform the actual transfer of tokens from the smart contract to the address
            // of the winner. The transfer_to_address() method receives the address value and
            // the proxy to the new transfers map on the host, and will call the corresponding
            // host sandbox function with these values.
            ctx.transfer_to_address(&bet.better.address(), transfers);
        }

        // Log who got sent what in the log on the host.
        let text: String = "Pay ".to_string() + &payout.to_string() + " to " + &bet.better.to_string();
        ctx.log(&text);
    }

    // This is where we transfer the remainder after payout to the creator of the smart contract.
    // The bank always wins :-P
    let remainder: i64 = total_bet_amount - total_payout;
    if remainder != 0 {
        // We have a remainder. First create a transfer for the remainder.
        let transfers: ScTransfers = ScTransfers::iotas(remainder);

        // Send the remainder to the contract creator.
        ctx.transfer_to_address(&ctx.contract_creator().address(), transfers);
    }
}
// 'payWinners' is a function whose execution gets initiated by the 'lockBets' function.
// The reason that the 'lockBets' function does not immediately take care of paying the winners
// itself is that we need to introduce some unpredictability in the outcome of the randomizer
// used in selecting the winning number. To prevent people from observing the 'lockBets' request
// and potentially calculating the winning value in advance the 'lockBets' function instead asks
// the 'payWinners' function to do this once the bets have been locked. This will generate a new
// transaction with completely unpredictable transaction hash. This hash is what we will use as
// a deterministic source of entropy for the random number generator. In this way every node in
// the committee will be using the same pseudo-random value sequence, which in turn makes sure
// that all nodes can agree on the outcome.
'payWinners' is a function whose execution gets initiated by the 'lockBets' function.
The reason that the 'lockBets' function does not immediately take care of paying the winners
itself is that we need to introduce some unpredictability in the outcome of the randomizer
used in selecting the winning number.
' payWinners ' is a function whose execution gets initiated by the ' lockBets ' function . The reason that the ' lockBets ' function does not immediately take care of paying the winners itself is that we need to introduce some unpredictability in the outcome of the randomizer used in selecting the winning number .
pub fn func_pay_winners(ctx: &ScFuncContext, f: &PayWinnersContext) {
    // Use the built-in random number generator which has been automatically initialized by
    // using the transaction hash as initial entropy data. Note that the pseudo-random number
    // generator will use the next 8 bytes from the hash as its random Int64 number and once
    // it runs out of data it simply hashes the previous hash for a next pseudo-random sequence.
    // Here we determine the winning number for this round in the range of 1 thru MAX_NUMBER.
    let winning_number: i64 = ctx.utility().random(MAX_NUMBER) + 1;
    // Save the last winning number in state storage under 'lastWinningNumber' so that there
    // is (limited) time for people to call the 'getLastWinningNumber' View to verify the last
    // winning number if they wish. Note that this is just a silly example. We could log much
    // more extensive statistics information about each playing round in state storage and
    // make that data available through views for anyone to see.
    f.state.last_winning_number().set_value(winning_number);
    // Gather all winners and calculate some totals at the same time.
    // Keep track of the total bet amount, the total win amount, and all the winners.
    // Note how we decided to keep the winners in a local vector instead of creating
    // yet another array in state storage or having to go through lockedBets again.
    let mut total_bet_amount: i64 = 0_i64;
    let mut total_win_amount: i64 = 0_i64;
    let mut winners: Vec<Bet> = Vec::new();
    // Get the 'lockedBets' array in state storage.
    let locked_bets: ArrayOfMutableBet = f.state.locked_bets();
    // Determine the amount of bets in the 'lockedBets' array.
    let nr_bets: i32 = locked_bets.length();
    // Loop through all indexes of the 'lockedBets' array.
    for i in 0..nr_bets {
        // Retrieve the bet stored at the next index
        let bet: Bet = locked_bets.get_bet(i).value();
        // Add this bet's amount to the running total bet amount
        total_bet_amount += bet.amount;
        // Did this better bet on the winning number?
        if bet.number == winning_number {
            // Yes, add this bet amount to the running total win amount.
            total_win_amount += bet.amount;
            // And save this bet in the winners vector.
            winners.push(bet);
        }
    }
    // Now that we preprocessed all bets we can get rid of the data in state storage so that
    // the 'lockedBets' array becomes available for when the next betting round ends.
    locked_bets.clear();
    // Did we have any winners at all?
    if winners.is_empty() {
        // No winners, log this fact to the log on the host.
        ctx.log("Nobody wins!");
    }
    // Pay out the winners proportionally to their bet amount. Note that we could configure
    // a small percentage that would go to the owner of the smart contract as hosting payment.
    // Keep track of the total payout so we can calculate the remainder after truncation.
    let mut total_payout: i64 = 0_i64;
    // Loop through all winners.
    let size: usize = winners.len();
    for i in 0..size {
        // Get the next winner.
        let bet: &Bet = &winners[i];
        // Determine the proportional win amount (we could take our percentage here)
        let payout: i64 = total_bet_amount * bet.amount / total_win_amount;
        // Anything to pay to the winner?
        if payout != 0 {
            // Yep, keep track of the running total payout
            total_payout += payout;
            // Set up an ScTransfers proxy that transfers the correct amount of iotas.
            // Note that ScTransfers wraps an ScMutableMap of token color/amount combinations
            // in a simpler to use interface. The constructor we use here creates and initializes
            // a single token color transfer in a single statement. The actual color and amount
            // values passed in will be stored in a new map on the host.
            let transfers: ScTransfers = ScTransfers::iotas(payout);
            // Perform the actual transfer of tokens from the smart contract to the address
            // of the winner. The transfer_to_address() method receives the address value and
            // the proxy to the new transfers map on the host, and will call the corresponding
            // host sandbox function with these values.
            ctx.transfer_to_address(&bet.better.address(), transfers);
        }
        // Log who got sent what in the log on the host.
        let text: String = "Pay ".to_string() + &payout.to_string() + " to " + &bet.better.to_string();
        ctx.log(&text);
    }
    // This is where we transfer the remainder after payout to the creator of the smart contract.
    // The bank always wins :-P
    let remainder: i64 = total_bet_amount - total_payout;
    if remainder != 0 {
        // We have a remainder. First create a transfer for the remainder.
        let transfers: ScTransfers = ScTransfers::iotas(remainder);
        // Send the remainder to the contract creator.
        ctx.transfer_to_address(&ctx.contract_creator().address(), transfers);
    }
}
pub fn func_pay_winners ( ctx : & ScFuncContext , f : & PayWinnersContext ) { // Use the built-in random number generator which has been automatically initialized by // using the transaction hash as initial entropy data. Note that the pseudo-random number // generator will use the next 8 bytes from the hash as its random Int64 number and once // it runs out of data it simply hashes the previous hash for a next pseudo-random sequence. // Here we determine the winning number for this round in the range of 1 thru MAX_NUMBER. let winning_number : i64 = ctx . utility ( ) . random ( MAX_NUMBER ) + 1 ; // Save the last winning number in state storage under 'lastWinningNumber' so that there // is (limited) time for people to call the 'getLastWinningNumber' View to verify the last // winning number if they wish. Note that this is just a silly example. We could log much // more extensive statistics information about each playing round in state storage and // make that data available through views for anyone to see. f . state . last_winning_number ( ) . set_value ( winning_number ) ; // Gather all winners and calculate some totals at the same time. // Keep track of the total bet amount, the total win amount, and all the winners. // Note how we decided to keep the winners in a local vector instead of creating // yet another array in state storage or having to go through lockedBets again. let mut total_bet_amount : i64 = 0_i64 ; let mut total_win_amount : i64 = 0_i64 ; let mut winners : Vec < Bet > = Vec :: new ( ) ; // Get the 'lockedBets' array in state storage. let locked_bets : ArrayOfMutableBet = f . state . locked_bets ( ) ; // Determine the amount of bets in the 'lockedBets' array. let nr_bets : i32 = locked_bets . length ( ) ; // Loop through all indexes of the 'lockedBets' array. for i in 0 .. nr_bets { // Retrieve the bet stored at the next index let bet : Bet = locked_bets . get_bet ( i ) . value ( ) ; // Add this bet's amount to the running total bet amount total_bet_amount += bet . amount ; // Did this better bet on the winning number? if bet . number == winning_number { // Yes, add this bet amount to the running total win amount. total_win_amount += bet . amount ; // And save this bet in the winners vector. winners . push ( bet ) ; } } // Now that we preprocessed all bets we can get rid of the data in state storage so that // the 'lockedBets' array becomes available for when the next betting round ends. locked_bets . clear ( ) ; // Did we have any winners at all? if winners . is_empty ( ) { // No winners, log this fact to the log on the host. ctx . log ( " " ) ; } // Pay out the winners proportionally to their bet amount. Note that we could configure // a small percentage that would go to the owner of the smart contract as hosting payment. // Keep track of the total payout so we can calculate the remainder after truncation. let mut total_payout : i64 = 0_i64 ; // Loop through all winners. let size : usize = winners . len ( ) ; for i in 0 .. size { // Get the next winner. let bet : & Bet = & winners [ i ] ; // Determine the proportional win amount (we could take our percentage here) let payout : i64 = total_bet_amount * bet . amount / total_win_amount ; // Anything to pay to the winner? if payout != 0 { // Yep, keep track of the running total payout total_payout += payout ; // Set up an ScTransfers proxy that transfers the correct amount of iotas. // Note that ScTransfers wraps an ScMutableMap of token color/amount combinations // in a simpler to use interface. The constructor we use here creates and initializes // a single token color transfer in a single statement. The actual color and amount // values passed in will be stored in a new map on the host. let transfers : ScTransfers = ScTransfers :: iotas ( payout ) ; // Perform the actual transfer of tokens from the smart contract to the address // of the winner. The transfer_to_address() method receives the address value and // the proxy to the new transfers map on the host, and will call the corresponding // host sandbox function with these values. ctx . transfer_to_address ( & bet . better . address ( ) , transfers ) ; } // Log who got sent what in the log on the host. let text : String = " " . to_string ( ) + & payout . to_string ( ) + " " + & bet . better . to_string ( ) ; ctx . log ( & text ) ; } // This is where we transfer the remainder after payout to the creator of the smart contract. // The bank always wins :-P let remainder : i64 = total_bet_amount - total_payout ; if remainder != 0 { // We have a remainder. First create a transfer for the remainder. let transfers : ScTransfers = ScTransfers :: iotas ( remainder ) ; // Send the remainder to the contract creator. ctx . transfer_to_address ( & ctx . contract_creator ( ) . address ( ) , transfers ) ; } }
'payWinners' is a function whose execution gets initiated by the 'lockBets' function.
' payWinners ' is a function whose execution gets initiated by the ' lockBets ' function .
ctx
&ScFuncContext
f
&PayWinnersContext
ctx
&ScFuncContext
f
&PayWinnersContext