The following are examples of patterns that developers could potentially use for dealing with secure random. The goal for each example is to implement a CoinToss
smart contract that is a single purpose contract, where users would bet a FlowVault
and if a random bit would be 1 they would receive a doubled FlowVault
back otherwise they would loose the original flow vault.
I want to illustrate four different possible patterns and their pros/cons.
- Direct usage of randomness where the user sends a single transaction and everything is resolved within that one transaction
- Hidden Result which is very similar to the direct usage, but the user has to unwrap their result in a separate transaction
- Set-Reveal where the user sends the money to the contract and then asks for a result in a separate transaction.
- Scheduled task where the user uses the
CoinToss
to create a task that a third party will run and that task will be the resolution of the random toss.
The CoinToss
contract has a reserve : FlowVault
that is used for collecting losing bets and paying out winning bets.
Example Patterns
Direct usage of randomness
Hidden Result
Commit-Reveal
Scheduled task usage
Conclusions
- Direct usage of randomness
- Anti-pattern! Don’t do this! This is what we want to avoid
- Hidden result
- if the assumption that the result is really hidden holds, than this is the best option
- the developer might still accidentally expose information (like exposing the reserve balance) that allows the user to know (or speculate) about the result.
- Set-Reveal
- requires a contract to hold past sources of randomness, and another contract for pseudorandom.
- escrow is kept in the dapps control, which could cause trust issues if total amount of Flow escrow-ed grows to big
- Scheduled task usage
- requires a complicated bit of on chain infrastructure and community buy in that is the task/scheduling/running