{"id":19610683,"url":"https://github.com/onflow/random-coin-toss","last_synced_at":"2026-03-02T16:33:43.369Z","repository":{"id":203789878,"uuid":"700098941","full_name":"onflow/random-coin-toss","owner":"onflow","description":"An example repo demonstrating safe use of onchain randomness","archived":false,"fork":false,"pushed_at":"2024-11-22T23:06:20.000Z","size":457,"stargazers_count":7,"open_issues_count":1,"forks_count":4,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-01-09T10:03:47.798Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Cadence","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/onflow.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-10-04T00:09:43.000Z","updated_at":"2024-12-27T00:24:20.000Z","dependencies_parsed_at":"2024-06-21T14:26:02.838Z","dependency_job_id":"87fdb7c2-8649-4b57-9020-00e3c505a72d","html_url":"https://github.com/onflow/random-coin-toss","commit_stats":null,"previous_names":["onflow/random-coin-toss"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onflow%2Frandom-coin-toss","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onflow%2Frandom-coin-toss/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onflow%2Frandom-coin-toss/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/onflow%2Frandom-coin-toss/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/onflow","download_url":"https://codeload.github.com/onflow/random-coin-toss/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240899083,"owners_count":19875308,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T10:31:58.359Z","updated_at":"2026-03-02T16:33:38.345Z","avatar_url":"https://github.com/onflow.png","language":"Cadence","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Random Coin Toss\n\n\u003e :information_source: This repository contains demonstrations for safe usage of Flow's protocol-native secure randomness in both Cadence and Solidity smart contracts.\n\nOn Flow, there are two routes to get a random value. While both are backed by Flow's Random Beacon,\nit is important for developers to mindfully choose between `revertibleRandom`\nor seeding their own PRNG utilizing the `RandomBeaconHistory` smart contract:\n\n- When using `revertibleRandom` a developer is relying on randomness generation controlled by the transaction,\n  which also has the power to abort and revert based on `revertibleRandom`'s outputs. Therefore,\n  `revertibleRandom` is only suitable for smart contract functions that exclusively run within credibly-neutral transactions which a developer can trust won't revert based on undesirable random outputs.\n- In contrast, using the `RandomBeaconHistory` allows developers to use a committed random source (or seed) that can't be reverted. \n  The `RandomBeaconHistory` is key for effectively implementing a commit-and-reveal scheme which is itself a pattern that prevents users from gaming a transaction based on the result of randomness.\n  During the commit phase, the user commits to proceed with a **future** source of randomness\n  which is revealed after the commit transaction concludes.\n  For each block, the `RandomBeaconHistory` automatically stores the subsequently generated source of randomness in the final transaction of that block. This source of randomness is committed by Flow's protocol service account.\n\n\u003e 🚨 A transaction can atomically revert the entirety of its action based on results exposed within the scope of that transaction.\n\u003e Therefore, it is possible for a transaction calling into your smart contract to post-select favorable\n\u003e results and revert the transaction for unfavorable results.\n\u003e \n\u003e 💡 Post-selection - the ability for transactions to reject results they don't like - is inherent to any\n\u003e smart contract platform that allows transactions to roll back atomically. See this very similar\n\u003e [Ethereum example](https://consensys.github.io/smart-contract-best-practices/development-recommendations/general/public-data/).\n\u003e \n\u003e ✅ Utilizing a commit-and-reveal scheme is important for developers to protect their smart contracts from transaction post-selection attacks.\n\nVia a commit-and-reveal scheme, Flow's protocol-native secure randomness can be safely used within both Cadence and Solidity smart contracts \nwhen contracts are transacted on by untrusted parties. \nBy providing examples of commit-reveal implementations we hope to foster a more secure ecosystem of decentralized\napplications and encourage developers to build with best practices.\n\n## Commit-Reveal Scheme\n\nThe contracts contained in this repo demonstrate how to use Flow's onchain randomness safely\nin contracts that are transacted on by untrusted parties. Safe randomness here meaning non-revertible randomness, \ni.e. mitigating post-selection attacks via a commit-and-reveal scheme.\n\nRandom sources are committed to the [`RandomBeaconHistory` contract](https://github.com/onflow/flow-core-contracts/blob/master/contracts/RandomBeaconHistory.cdc) by the service\naccount at the end of every block. The RandomBeaconHistory contract provides a convenient archive, where for each past\nblock height (starting Nov 2023) the respective 'source of randomness' can be retrieved.\n\nWhen used naively, `revertibleRandom` as well as the [`RandomBeaconHistory` contract](https://github.com/onflow/flow-core-contracts/blob/master/contracts/RandomBeaconHistory.cdc)\nare subject to post-selection attacks from transactions.\nIn simple terms, using the random source in your contract without\nthe protection of a commit-reveal mechanism would enable non-trusted callers to condition their interactions with your contract on the\nrandom result. In the context of a random coin toss, I could revert my transaction if I didn't win - not a very fair\ngame.\n\nTo achieve non-revertible randomness, the contract should be structured to resolve in two phases:\n\n1. **Commit** - Caller commits to the resolution of their bet with some yet unknown source of randomness (i.e. in the\n  future)\n2. **Reveal** - Caller can then resolve the result of their bet once the source of randomness is available in the `RandomBeaconHistory` with a separate transaction.\n  From a technical perspective, this could also be called a \"resolving transaction\", because the transaction simply executes the smart contract with the locked-in\n  inputs, whose output all parties committed to accept in the previous phase.\n\nThough a caller could still condition the revealing transaction on the coin flip result, all the inputs influencing the bet's outcome\nhave already been fixed (the source of randomness being the last one that is only generated after the commit transaction concluded).\nConceptually, this corresponds to owning a winning (or loosing) lottery ticket, where the numbers have already been published,\nbut the ticket has not been handed in to the lottery company to affirm the win (or loss).\nAll that the resolving transaction (reveal phase) is doing is affirming the win or loss.\nThe ticket owner could revert their resolving transaction. Though that does not change whether the ticket won or lost. Furthermore, the player has already\nincurred the cost of their bet and gains nothing by reverting the reveal step.\n\nGiven that Flow has both Cadence and EVM runtimes, commit-reveal patterns covering Cadence and Solidity are found in this repo as well as transactions demonstrating how Flow accounts can interact with EVM implementations from the Cadence runtime via COAs.\n\n## Deployments\n\n|Contract|Testnet|Mainnet|\n|---|---|---|\n|[CoinToss.cdc](./contracts/CoinToss.cdc)|[0xb6c99d7ff216a684](https://contractbrowser.com/A.b6c99d7ff216a684.CoinToss)|N/A|\n|[Xorshift128plus.cdc](./contracts/Xorshift128plus.cdc)|[0xed24dbe901028c5c](https://contractbrowser.com/A.ed24dbe901028c5c.Xorshift128plus)|[0x45caec600164c9e6](https://contractbrowser.com/A.45caec600164c9e6.Xorshift128plus)|\n|[RandomConsumer.cdc](./contracts/RandomConsumer.cdc)|[0xed24dbe901028c5c](https://contractbrowser.com/A.ed24dbe901028c5c.RandomConsumer)|[0x45caec600164c9e6](https://contractbrowser.com/A.45caec600164c9e6.RandomConsumer)|\n|[CoinToss.sol](./contracts/CoinToss.sol)|[0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1](https://evm-testnet.flowscan.io/address/0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1?tab=contract_code)|N/A|\n\n\u003e :information_source: To use the Solidity dependencies demonstrated in the `CoinToss.sol` example, see the [`@onflow/flow-sol-utils` repository](https://github.com/onflow/flow-sol-utils).\n\n## Further Reading\n\n\n- We recommend the **Flow developer documentation** [**_Advanced Concepts → Flow VRF_**](https://developers.flow.com/build/advanced-concepts/randomness)\n  for important concepts and context on safely using Flow's VRF.  \n- Flow Forum post [_Secure random number generator for Flow’s smart contracts_](https://forum.onflow.org/t/secure-random-number-generator-for-flow-s-smart-contracts/5110)\n  summarizes the weaknesses of prevalent approaches to random number generation in other blockchains (such as using block hashes) and explains the details behind Flow's secure solution.\n- [Pull request introducing the `RandomBeaconHistory` system smart contract.](https://github.com/onflow/flow-core-contracts/pull/375) \n- [FLIP 123: _On-Chain randomness history for commit-reveal schemes_](https://github.com/onflow/flips/pull/123) describes the need for a commit-and-reveal scheme and \n  discusses ideas for additional convenience functionality to further optimize the developer experience in the future.\n- For more on Cadence Arch pre-compiles and accessing random values from EVM on Flow, see documentation on the [Cadence Arch precompiled contracts](https://developers.flow.com/evm/how-it-works#precompiled-contracts).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonflow%2Frandom-coin-toss","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fonflow%2Frandom-coin-toss","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fonflow%2Frandom-coin-toss/lists"}