This is a lottery smart contract in Stacks. Players transfer specific lottery fee(STX) to participate current round lottery when the lottery is open.
And then the smart contract owner can close the lottery and calculate the winner by sending a transation to this smart contract. This smart contract use the vrf-seed of blockchain to generate a pseudorandom number, which is used for calculate the winner of this round lottery.
After the winner is calculated, it transfers the whole jackpots(STX) in this round to the winner. And then the smart contract owner can open the lottery again, starting next round.
To mock the above process, run
cd lottery-contracts
clarinet run --allow-wallets --allow-read --allow-write mock/run-lottery-mock-script.ts
Actually players have to pay for the entry fee. When they pay for the lottery fee(variable fee
) to participate this round, which the entry fee is included in. And the entry fee is up to the variable entry-fee-rate
. Both fee
and entry-fee-rate
can be update by the constract owner, but only when the lottery state in lottery-state-winner-announced
. Since they shouldn't be updated bwteen the time the lottery is open and calculated the winner.
(To more detail, see contract lottery
method: get-fee
/ get-entry-fee-rate
/ get-entry-fee
/ update-fee
/ update-entry-fee-rate
)
The The jackpot for every round is the full fee from the players minus the entry fee. As once as the winner is calculated, the contract transfers the jackpot to this winner address.
(To more detail, see contract lottery
method: get-jackpots
)
- pseudorandom number
This contract use the vrf-seed of blockchain to generate a pseudorandom number, which is use to come out a winner. Since the generator algorithm, it only supports to generate the random number between 0(inclusive) to 256(exclusive), and the random number between 0 to 256 appears with equal probability. - players have the same probability of winning
Winner is the players whose index equals to the remainder of dividing a random number by the count of players.
Since only when the random number between 0 to 256, it appears with equal probability, so to make all the players have the same probability of winning, the contract do these things:- Number of players per round cannot exceed 256
- When the number of players less than 256, the ramdom number must less than
Y
, andY
is the largest integer satisfyingY * (the number of players) < 256
. For example, when the number of players is 100, the ramdom number mush less than 200. That is to ensure every players have the bassically equal probability of winning. - But so it have a probability that the lottery cannot come out a winner since the ramdom number may not fit into. When it happens, the smart contract refund the fee except the entry fee to all the players.
(To more detail, see contractpseudorandom-generator
methondget-random-number
)
- Auth permissions
Except the method
participate-in-lottery
offer to users to participate the lottery, other methods making transations are all only available to the contract owner
This lottery use a pseudorandom number generated by blockchain block info. It cannot satisfy both security and on-chain. But it's quite funny to write this contracts to learn more about the Stacks and Clarity language.
Pointer tutorial: Build a Dex with Stacks
How To Create Random Numbers in Clarity
Stacks document
Clarity of Mind